Commit | Line | Data |
---|---|---|
12d43ee5 KM |
1 | /* |
2 | * Copyright (c) 1992 Regents of the University of California. | |
3 | * All rights reserved. | |
4 | * | |
5 | * This code is derived from software contributed to Berkeley by | |
6 | * Ralph Campbell. | |
7 | * | |
8 | * %sccs.include.redist.c% | |
9 | * | |
46a3a9ac | 10 | * @(#)pm.c 7.4 (Berkeley) %G% |
12d43ee5 KM |
11 | * |
12 | * devGraphics.c -- | |
13 | * | |
14 | * This file contains machine-dependent routines for the graphics device. | |
15 | * | |
16 | * Copyright (C) 1989 Digital Equipment Corporation. | |
17 | * Permission to use, copy, modify, and distribute this software and | |
18 | * its documentation for any purpose and without fee is hereby granted, | |
19 | * provided that the above copyright notice appears in all copies. | |
20 | * Digital Equipment Corporation makes no representations about the | |
21 | * suitability of this software for any purpose. It is provided "as is" | |
22 | * without express or implied warranty. | |
23 | * | |
24 | * from: $Header: /sprite/src/kernel/dev/ds3100.md/RCS/devGraphics.c, | |
25 | * v 9.2 90/02/13 22:16:24 shirriff Exp $ SPRITE (DECWRL)"; | |
26 | */ | |
27 | ||
28 | #include "pm.h" | |
29 | #if NPM > 0 | |
30 | ||
31 | #include "param.h" | |
32 | #include "time.h" | |
33 | #include "kernel.h" | |
34 | #include "ioctl.h" | |
35 | #include "file.h" | |
36 | #include "errno.h" | |
37 | #include "proc.h" | |
38 | #include "mman.h" | |
39 | #include "vm/vm.h" | |
40 | ||
41 | #include "machine/machConst.h" | |
42 | #include "machine/machMon.h" | |
43 | #include "machine/dc7085cons.h" | |
44 | #include "machine/pmioctl.h" | |
12d43ee5 KM |
45 | |
46 | #include "device.h" | |
bd53ca78 | 47 | #include "pmreg.h" |
12d43ee5 KM |
48 | #include "font.c" |
49 | ||
bd53ca78 RC |
50 | #define MAX_ROW 56 |
51 | #define MAX_COL 80 | |
52 | ||
12d43ee5 KM |
53 | /* |
54 | * Macro to translate from a time struct to milliseconds. | |
55 | */ | |
56 | #define TO_MS(tv) ((tv.tv_sec * 1000) + (tv.tv_usec / 1000)) | |
57 | ||
58 | static u_short curReg; /* copy of PCCRegs.cmdr since it's read only */ | |
59 | static int isMono; /* true if B&W frame buffer */ | |
60 | static int initialized; /* true if 'probe' was successful */ | |
61 | static int GraphicsOpen; /* true if the graphics device is open */ | |
bd53ca78 | 62 | static int row, col; /* row and col for console cursor */ |
86e31fc2 | 63 | static struct selinfo pm_selp;/* process waiting for select */ |
12d43ee5 KM |
64 | |
65 | /* | |
66 | * These need to be mapped into user space. | |
67 | */ | |
68 | static struct pmuaccess { | |
69 | PM_Info scrInfo; | |
70 | pmEvent events[PM_MAXEVQ]; | |
71 | pmTimeCoord tcs[MOTION_BUFFER_SIZE]; | |
72 | } pmu; | |
73 | ||
12d43ee5 KM |
74 | /* |
75 | * Font mask bits used by Blitc(). | |
76 | */ | |
77 | static unsigned int fontmaskBits[16] = { | |
78 | 0x00000000, | |
79 | 0x00000001, | |
80 | 0x00000100, | |
81 | 0x00000101, | |
82 | 0x00010000, | |
83 | 0x00010001, | |
84 | 0x00010100, | |
85 | 0x00010101, | |
86 | 0x01000000, | |
87 | 0x01000001, | |
88 | 0x01000100, | |
89 | 0x01000101, | |
90 | 0x01010000, | |
91 | 0x01010001, | |
92 | 0x01010100, | |
93 | 0x01010101 | |
94 | }; | |
95 | ||
96 | /* | |
97 | * Forward references. | |
98 | */ | |
bd53ca78 RC |
99 | static void Scroll(); |
100 | static void Blitc(); | |
101 | ||
12d43ee5 KM |
102 | static void ScreenInit(); |
103 | static void LoadCursor(); | |
104 | static void RestoreCursorColor(); | |
105 | static void CursorColor(); | |
bd53ca78 | 106 | static void PosCursor(); |
12d43ee5 KM |
107 | static void InitColorMap(); |
108 | static void VDACInit(); | |
109 | static void LoadColorMap(); | |
bd53ca78 RC |
110 | static void EnableVideo(); |
111 | static void DisableVideo(); | |
12d43ee5 KM |
112 | |
113 | extern void dcKBDPutc(); | |
bd53ca78 RC |
114 | extern void (*dcDivertXInput)(); |
115 | extern void (*dcMouseEvent)(); | |
116 | extern void (*dcMouseButtons)(); | |
12d43ee5 KM |
117 | |
118 | int pmprobe(); | |
119 | struct driver pmdriver = { | |
120 | "pm", pmprobe, 0, 0, | |
121 | }; | |
122 | ||
123 | /* | |
124 | * Test to see if device is present. | |
125 | * Return true if found and initialized ok. | |
126 | */ | |
127 | /*ARGSUSED*/ | |
128 | pmprobe(cp) | |
129 | register struct pmax_ctlr *cp; | |
130 | { | |
131 | ||
132 | if (!initialized && !pminit()) | |
133 | return (0); | |
134 | if (isMono) | |
135 | printf("pm0 (monochrome display)\n"); | |
136 | else | |
137 | printf("pm0 (color display)\n"); | |
138 | return (1); | |
139 | } | |
140 | ||
141 | /* | |
bd53ca78 | 142 | *---------------------------------------------------------------------- |
12d43ee5 | 143 | * |
bd53ca78 | 144 | * pmKbdEvent -- |
12d43ee5 | 145 | * |
bd53ca78 | 146 | * Process a received character. |
12d43ee5 KM |
147 | * |
148 | * Results: | |
149 | * None. | |
150 | * | |
151 | * Side effects: | |
bd53ca78 | 152 | * Events added to the queue. |
12d43ee5 | 153 | * |
bd53ca78 | 154 | *---------------------------------------------------------------------- |
12d43ee5 | 155 | */ |
bd53ca78 RC |
156 | void |
157 | pmKbdEvent(ch) | |
158 | int ch; | |
12d43ee5 | 159 | { |
bd53ca78 RC |
160 | register pmEvent *eventPtr; |
161 | int i; | |
162 | ||
163 | if (!GraphicsOpen) | |
164 | return; | |
12d43ee5 KM |
165 | |
166 | /* | |
bd53ca78 | 167 | * See if there is room in the queue. |
12d43ee5 | 168 | */ |
bd53ca78 RC |
169 | i = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); |
170 | if (i == pmu.scrInfo.qe.eHead) | |
171 | return; | |
12d43ee5 KM |
172 | |
173 | /* | |
bd53ca78 | 174 | * Add the event to the queue. |
12d43ee5 | 175 | */ |
bd53ca78 RC |
176 | eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; |
177 | eventPtr->type = BUTTON_RAW_TYPE; | |
178 | eventPtr->device = KEYBOARD_DEVICE; | |
179 | eventPtr->x = pmu.scrInfo.mouse.x; | |
180 | eventPtr->y = pmu.scrInfo.mouse.y; | |
181 | eventPtr->time = TO_MS(time); | |
182 | eventPtr->key = ch; | |
183 | pmu.scrInfo.qe.eTail = i; | |
184 | selwakeup(&pm_selp); | |
12d43ee5 KM |
185 | } |
186 | ||
187 | /* | |
bd53ca78 | 188 | *---------------------------------------------------------------------- |
12d43ee5 | 189 | * |
bd53ca78 | 190 | * pmMouseEvent -- |
12d43ee5 | 191 | * |
bd53ca78 | 192 | * Process a mouse event. |
12d43ee5 KM |
193 | * |
194 | * Results: | |
195 | * None. | |
196 | * | |
197 | * Side effects: | |
bd53ca78 | 198 | * An event is added to the event queue. |
12d43ee5 | 199 | * |
bd53ca78 | 200 | *---------------------------------------------------------------------- |
12d43ee5 | 201 | */ |
bd53ca78 RC |
202 | void |
203 | pmMouseEvent(newRepPtr) | |
204 | register MouseReport *newRepPtr; | |
12d43ee5 | 205 | { |
bd53ca78 RC |
206 | unsigned milliSec; |
207 | int i; | |
208 | pmEvent *eventPtr; | |
12d43ee5 | 209 | |
bd53ca78 RC |
210 | if (!GraphicsOpen) |
211 | return; | |
212 | ||
213 | milliSec = TO_MS(time); | |
214 | ||
215 | /* | |
216 | * Check to see if we have to accelerate the mouse | |
217 | */ | |
218 | if (pmu.scrInfo.mscale >= 0) { | |
219 | if (newRepPtr->dx >= pmu.scrInfo.mthreshold) { | |
220 | newRepPtr->dx += | |
221 | (newRepPtr->dx - pmu.scrInfo.mthreshold) * | |
222 | pmu.scrInfo.mscale; | |
223 | } | |
224 | if (newRepPtr->dy >= pmu.scrInfo.mthreshold) { | |
225 | newRepPtr->dy += | |
226 | (newRepPtr->dy - pmu.scrInfo.mthreshold) * | |
227 | pmu.scrInfo.mscale; | |
228 | } | |
12d43ee5 | 229 | } |
bd53ca78 RC |
230 | |
231 | /* | |
232 | * Update mouse position | |
233 | */ | |
234 | if (newRepPtr->state & MOUSE_X_SIGN) { | |
235 | pmu.scrInfo.mouse.x += newRepPtr->dx; | |
236 | if (pmu.scrInfo.mouse.x > pmu.scrInfo.max_cur_x) | |
237 | pmu.scrInfo.mouse.x = pmu.scrInfo.max_cur_x; | |
238 | } else { | |
239 | pmu.scrInfo.mouse.x -= newRepPtr->dx; | |
240 | if (pmu.scrInfo.mouse.x < pmu.scrInfo.min_cur_x) | |
241 | pmu.scrInfo.mouse.x = pmu.scrInfo.min_cur_x; | |
242 | } | |
243 | if (newRepPtr->state & MOUSE_Y_SIGN) { | |
244 | pmu.scrInfo.mouse.y -= newRepPtr->dy; | |
245 | if (pmu.scrInfo.mouse.y < pmu.scrInfo.min_cur_y) | |
246 | pmu.scrInfo.mouse.y = pmu.scrInfo.min_cur_y; | |
247 | } else { | |
248 | pmu.scrInfo.mouse.y += newRepPtr->dy; | |
249 | if (pmu.scrInfo.mouse.y > pmu.scrInfo.max_cur_y) | |
250 | pmu.scrInfo.mouse.y = pmu.scrInfo.max_cur_y; | |
251 | } | |
252 | ||
253 | /* | |
254 | * Move the hardware cursor. | |
255 | */ | |
256 | PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); | |
257 | ||
258 | /* | |
259 | * Store the motion event in the motion buffer. | |
260 | */ | |
261 | pmu.tcs[pmu.scrInfo.qe.tcNext].time = milliSec; | |
262 | pmu.tcs[pmu.scrInfo.qe.tcNext].x = pmu.scrInfo.mouse.x; | |
263 | pmu.tcs[pmu.scrInfo.qe.tcNext].y = pmu.scrInfo.mouse.y; | |
264 | if (++pmu.scrInfo.qe.tcNext >= MOTION_BUFFER_SIZE) | |
265 | pmu.scrInfo.qe.tcNext = 0; | |
266 | if (pmu.scrInfo.mouse.y < pmu.scrInfo.mbox.bottom && | |
267 | pmu.scrInfo.mouse.y >= pmu.scrInfo.mbox.top && | |
268 | pmu.scrInfo.mouse.x < pmu.scrInfo.mbox.right && | |
269 | pmu.scrInfo.mouse.x >= pmu.scrInfo.mbox.left) | |
270 | return; | |
271 | ||
272 | pmu.scrInfo.mbox.bottom = 0; | |
273 | if (PM_EVROUND(pmu.scrInfo.qe.eTail + 1) == pmu.scrInfo.qe.eHead) | |
274 | return; | |
275 | ||
276 | i = PM_EVROUND(pmu.scrInfo.qe.eTail - 1); | |
277 | if ((pmu.scrInfo.qe.eTail != pmu.scrInfo.qe.eHead) && | |
278 | (i != pmu.scrInfo.qe.eHead)) { | |
279 | pmEvent *eventPtr; | |
280 | ||
281 | eventPtr = &pmu.events[i]; | |
282 | if (eventPtr->type == MOTION_TYPE) { | |
283 | eventPtr->x = pmu.scrInfo.mouse.x; | |
284 | eventPtr->y = pmu.scrInfo.mouse.y; | |
285 | eventPtr->time = milliSec; | |
286 | eventPtr->device = MOUSE_DEVICE; | |
287 | return; | |
288 | } | |
289 | } | |
290 | /* | |
291 | * Put event into queue and wakeup any waiters. | |
292 | */ | |
293 | eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; | |
294 | eventPtr->type = MOTION_TYPE; | |
295 | eventPtr->time = milliSec; | |
296 | eventPtr->x = pmu.scrInfo.mouse.x; | |
297 | eventPtr->y = pmu.scrInfo.mouse.y; | |
298 | eventPtr->device = MOUSE_DEVICE; | |
299 | pmu.scrInfo.qe.eTail = PM_EVROUND(pmu.scrInfo.qe.eTail + 1); | |
300 | selwakeup(&pm_selp); | |
12d43ee5 KM |
301 | } |
302 | ||
303 | /* | |
bd53ca78 | 304 | *---------------------------------------------------------------------- |
12d43ee5 | 305 | * |
bd53ca78 | 306 | * pmMouseButtons -- |
12d43ee5 | 307 | * |
bd53ca78 | 308 | * Process mouse buttons. |
12d43ee5 KM |
309 | * |
310 | * Results: | |
311 | * None. | |
312 | * | |
313 | * Side effects: | |
314 | * None. | |
315 | * | |
bd53ca78 | 316 | *---------------------------------------------------------------------- |
12d43ee5 | 317 | */ |
bd53ca78 RC |
318 | void |
319 | pmMouseButtons(newRepPtr) | |
320 | MouseReport *newRepPtr; | |
12d43ee5 | 321 | { |
bd53ca78 RC |
322 | static char temp, oldSwitch, newSwitch; |
323 | int i, j; | |
324 | pmEvent *eventPtr; | |
325 | static MouseReport lastRep; | |
12d43ee5 | 326 | |
bd53ca78 RC |
327 | if (!GraphicsOpen) |
328 | return; | |
12d43ee5 | 329 | |
bd53ca78 RC |
330 | newSwitch = newRepPtr->state & 0x07; |
331 | oldSwitch = lastRep.state & 0x07; | |
12d43ee5 | 332 | |
bd53ca78 RC |
333 | temp = oldSwitch ^ newSwitch; |
334 | if (temp == 0) | |
335 | return; | |
336 | for (j = 1; j < 8; j <<= 1) { | |
337 | if ((j & temp) == 0) | |
338 | continue; | |
339 | ||
340 | /* | |
341 | * Check for room in the queue | |
342 | */ | |
343 | i = PM_EVROUND(pmu.scrInfo.qe.eTail+1); | |
344 | if (i == pmu.scrInfo.qe.eHead) | |
345 | return; | |
346 | ||
347 | /* | |
348 | * Put event into queue. | |
349 | */ | |
350 | eventPtr = &pmu.events[pmu.scrInfo.qe.eTail]; | |
351 | ||
352 | switch (j) { | |
353 | case RIGHT_BUTTON: | |
354 | eventPtr->key = EVENT_RIGHT_BUTTON; | |
355 | break; | |
356 | ||
357 | case MIDDLE_BUTTON: | |
358 | eventPtr->key = EVENT_MIDDLE_BUTTON; | |
359 | break; | |
360 | ||
361 | case LEFT_BUTTON: | |
362 | eventPtr->key = EVENT_LEFT_BUTTON; | |
363 | } | |
364 | if (newSwitch & j) | |
365 | eventPtr->type = BUTTON_DOWN_TYPE; | |
366 | else | |
367 | eventPtr->type = BUTTON_UP_TYPE; | |
368 | eventPtr->device = MOUSE_DEVICE; | |
369 | ||
370 | eventPtr->time = TO_MS(time); | |
371 | eventPtr->x = pmu.scrInfo.mouse.x; | |
372 | eventPtr->y = pmu.scrInfo.mouse.y; | |
12d43ee5 | 373 | } |
bd53ca78 RC |
374 | pmu.scrInfo.qe.eTail = i; |
375 | selwakeup(&pm_selp); | |
376 | ||
377 | lastRep = *newRepPtr; | |
378 | pmu.scrInfo.mswitches = newSwitch; | |
12d43ee5 KM |
379 | } |
380 | ||
381 | /* | |
bd53ca78 | 382 | *---------------------------------------------------------------------- |
12d43ee5 | 383 | * |
bd53ca78 | 384 | * Scroll -- |
12d43ee5 | 385 | * |
bd53ca78 | 386 | * Scroll the screen. |
12d43ee5 KM |
387 | * |
388 | * Results: | |
389 | * None. | |
390 | * | |
391 | * Side effects: | |
392 | * None. | |
393 | * | |
bd53ca78 | 394 | *---------------------------------------------------------------------- |
12d43ee5 KM |
395 | */ |
396 | static void | |
bd53ca78 | 397 | Scroll() |
12d43ee5 | 398 | { |
bd53ca78 RC |
399 | register int *dest, *src; |
400 | register int *end; | |
401 | register int temp0, temp1, temp2, temp3; | |
402 | register int i, scanInc, lineCount; | |
403 | int line; | |
12d43ee5 | 404 | |
bd53ca78 RC |
405 | /* |
406 | * If the mouse is on we don't scroll so that the bit map remains sane. | |
407 | */ | |
408 | if (GraphicsOpen) { | |
409 | row = 0; | |
410 | return; | |
411 | } | |
12d43ee5 | 412 | |
bd53ca78 RC |
413 | /* |
414 | * The following is an optimization to cause the scrolling | |
415 | * of text to be memory limited. Basically the writebuffer is | |
416 | * 4 words (32 bits ea.) long so to achieve maximum speed we | |
417 | * read and write in multiples of 4 words. We also limit the | |
418 | * size to be MAX_COL characters for more speed. | |
419 | */ | |
420 | if (isMono) { | |
421 | lineCount = 5; | |
422 | line = 1920 * 2; | |
423 | scanInc = 44; | |
424 | } else { | |
425 | lineCount = 40; | |
426 | scanInc = 96; | |
427 | line = 1920 * 8; | |
428 | } | |
429 | src = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + line); | |
430 | dest = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR); | |
431 | end = (int *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + (60 * line) - line); | |
432 | do { | |
433 | i = 0; | |
434 | do { | |
435 | temp0 = src[0]; | |
436 | temp1 = src[1]; | |
437 | temp2 = src[2]; | |
438 | temp3 = src[3]; | |
439 | dest[0] = temp0; | |
440 | dest[1] = temp1; | |
441 | dest[2] = temp2; | |
442 | dest[3] = temp3; | |
443 | dest += 4; | |
444 | src += 4; | |
445 | i++; | |
446 | } while (i < lineCount); | |
447 | src += scanInc; | |
448 | dest += scanInc; | |
449 | } while (src < end); | |
12d43ee5 | 450 | |
bd53ca78 RC |
451 | /* |
452 | * Now zero out the last two lines | |
453 | */ | |
454 | bzero(MACH_UNCACHED_FRAME_BUFFER_ADDR + (row * line), 3 * line); | |
12d43ee5 KM |
455 | } |
456 | ||
457 | /* | |
bd53ca78 | 458 | *---------------------------------------------------------------------- |
12d43ee5 | 459 | * |
bd53ca78 | 460 | * pmPutc -- |
12d43ee5 | 461 | * |
bd53ca78 | 462 | * Write a character to the console. |
12d43ee5 KM |
463 | * |
464 | * Results: | |
465 | * None. | |
466 | * | |
467 | * Side effects: | |
bd53ca78 | 468 | * None. |
12d43ee5 | 469 | * |
bd53ca78 | 470 | *---------------------------------------------------------------------- |
12d43ee5 | 471 | */ |
bd53ca78 RC |
472 | pmPutc(c) |
473 | register int c; | |
12d43ee5 | 474 | { |
bd53ca78 | 475 | int s; |
12d43ee5 | 476 | |
bd53ca78 RC |
477 | s = splhigh(); /* in case we do any printf's at interrupt time */ |
478 | if (initialized) { | |
479 | #ifdef DEBUG | |
480 | /* | |
481 | * If the HELP key is pressed, wait for another | |
482 | * HELP key press to start/stop output. | |
483 | */ | |
484 | if (dcDebugGetc() == LK_HELP) { | |
485 | while (dcDebugGetc() != LK_HELP) | |
486 | ; | |
12d43ee5 | 487 | } |
bd53ca78 RC |
488 | #endif |
489 | Blitc(c); | |
12d43ee5 | 490 | } else { |
bd53ca78 | 491 | void (*f)() = (void (*)())MACH_MON_PUTCHAR; |
12d43ee5 | 492 | |
bd53ca78 | 493 | (*f)(c); |
12d43ee5 | 494 | } |
bd53ca78 | 495 | splx(s); |
12d43ee5 KM |
496 | } |
497 | ||
498 | /* | |
bd53ca78 | 499 | *---------------------------------------------------------------------- |
12d43ee5 | 500 | * |
bd53ca78 | 501 | * Blitc -- |
12d43ee5 | 502 | * |
bd53ca78 | 503 | * Write a character to the screen. |
12d43ee5 KM |
504 | * |
505 | * Results: | |
506 | * None. | |
507 | * | |
508 | * Side effects: | |
509 | * None. | |
510 | * | |
bd53ca78 | 511 | *---------------------------------------------------------------------- |
12d43ee5 KM |
512 | */ |
513 | static void | |
bd53ca78 RC |
514 | Blitc(c) |
515 | register int c; | |
12d43ee5 | 516 | { |
bd53ca78 RC |
517 | register char *bRow, *fRow; |
518 | register int i; | |
519 | register int ote = isMono ? 256 : 1024; /* offset to table entry */ | |
520 | int colMult = isMono ? 1 : 8; | |
12d43ee5 | 521 | |
bd53ca78 | 522 | c &= 0xff; |
12d43ee5 | 523 | |
bd53ca78 RC |
524 | switch (c) { |
525 | case '\t': | |
526 | for (i = 8 - (col & 0x7); i > 0; i--) | |
527 | Blitc(' '); | |
528 | break; | |
12d43ee5 | 529 | |
bd53ca78 RC |
530 | case '\r': |
531 | col = 0; | |
532 | break; | |
12d43ee5 | 533 | |
bd53ca78 RC |
534 | case '\b': |
535 | col--; | |
536 | if (col < 0) | |
537 | col = 0; | |
538 | break; | |
12d43ee5 | 539 | |
bd53ca78 RC |
540 | case '\n': |
541 | if (row + 1 >= MAX_ROW) | |
542 | Scroll(); | |
543 | else | |
544 | row++; | |
545 | col = 0; | |
546 | break; | |
547 | ||
548 | case '\007': | |
549 | dcKBDPutc(LK_RING_BELL); | |
550 | break; | |
551 | ||
552 | default: | |
553 | /* | |
554 | * 0xA1 to 0xFD are the printable characters added with 8-bit | |
555 | * support. | |
556 | */ | |
557 | if (c < ' ' || c > '~' && c < 0xA1 || c > 0xFD) | |
558 | break; | |
559 | /* | |
560 | * If the next character will wrap around then | |
561 | * increment row counter or scroll screen. | |
562 | */ | |
563 | if (col >= MAX_COL) { | |
564 | col = 0; | |
565 | if (row + 1 >= MAX_ROW) | |
566 | Scroll(); | |
567 | else | |
568 | row++; | |
569 | } | |
570 | bRow = (char *)(MACH_UNCACHED_FRAME_BUFFER_ADDR + | |
571 | (row * 15 & 0x3ff) * ote + col * colMult); | |
572 | i = c - ' '; | |
573 | /* | |
574 | * This is to skip the (32) 8-bit | |
575 | * control chars, as well as DEL | |
576 | * and 0xA0 which aren't printable | |
577 | */ | |
578 | if (c > '~') | |
579 | i -= 34; | |
580 | i *= 15; | |
581 | fRow = (char *)((int)pmFont + i); | |
12d43ee5 | 582 | |
bd53ca78 RC |
583 | /* inline expansion for speed */ |
584 | if (isMono) { | |
585 | *bRow = *fRow++; bRow += ote; | |
586 | *bRow = *fRow++; bRow += ote; | |
587 | *bRow = *fRow++; bRow += ote; | |
588 | *bRow = *fRow++; bRow += ote; | |
589 | *bRow = *fRow++; bRow += ote; | |
590 | *bRow = *fRow++; bRow += ote; | |
591 | *bRow = *fRow++; bRow += ote; | |
592 | *bRow = *fRow++; bRow += ote; | |
593 | *bRow = *fRow++; bRow += ote; | |
594 | *bRow = *fRow++; bRow += ote; | |
595 | *bRow = *fRow++; bRow += ote; | |
596 | *bRow = *fRow++; bRow += ote; | |
597 | *bRow = *fRow++; bRow += ote; | |
598 | *bRow = *fRow++; bRow += ote; | |
599 | *bRow = *fRow++; bRow += ote; | |
600 | } else { | |
601 | register int j; | |
602 | register unsigned int *pInt; | |
603 | ||
604 | pInt = (unsigned int *)bRow; | |
605 | for (j = 0; j < 15; j++) { | |
606 | /* | |
607 | * fontmaskBits converts a nibble | |
608 | * (4 bytes) to a long word | |
609 | * containing 4 pixels corresponding | |
610 | * to each bit in the nibble. Thus | |
611 | * we write two longwords for each | |
612 | * byte in font. | |
613 | * | |
614 | * Remember the font is 8 bits wide | |
615 | * and 15 bits high. | |
616 | * | |
617 | * We add 256 to the pointer to | |
618 | * point to the pixel on the | |
619 | * next scan line | |
620 | * directly below the current | |
621 | * pixel. | |
622 | */ | |
623 | pInt[0] = fontmaskBits[(*fRow) & 0xf]; | |
624 | pInt[1] = fontmaskBits[((*fRow) >> 4) & 0xf]; | |
625 | fRow++; | |
626 | pInt += 256; | |
627 | } | |
628 | } | |
629 | col++; /* increment column counter */ | |
630 | } | |
12d43ee5 | 631 | if (!GraphicsOpen) |
bd53ca78 RC |
632 | PosCursor(col * 8, row * 15); |
633 | } | |
12d43ee5 | 634 | |
bd53ca78 RC |
635 | /*ARGSUSED*/ |
636 | pmopen(dev, flag) | |
637 | dev_t dev; | |
638 | int flag; | |
639 | { | |
640 | ||
641 | if (!initialized) | |
642 | return (ENXIO); | |
643 | if (GraphicsOpen) | |
644 | return (EBUSY); | |
12d43ee5 | 645 | |
bd53ca78 RC |
646 | GraphicsOpen = 1; |
647 | if (!isMono) | |
648 | InitColorMap(); | |
12d43ee5 | 649 | /* |
bd53ca78 | 650 | * Set up event queue for later |
12d43ee5 | 651 | */ |
bd53ca78 RC |
652 | pmu.scrInfo.qe.eSize = PM_MAXEVQ; |
653 | pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; | |
654 | pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; | |
655 | pmu.scrInfo.qe.tcNext = 0; | |
656 | pmu.scrInfo.qe.timestamp_ms = TO_MS(time); | |
657 | return (0); | |
12d43ee5 KM |
658 | } |
659 | ||
bd53ca78 RC |
660 | /*ARGSUSED*/ |
661 | pmclose(dev, flag) | |
662 | dev_t dev; | |
663 | int flag; | |
12d43ee5 | 664 | { |
46a3a9ac | 665 | int s; |
12d43ee5 KM |
666 | |
667 | if (!GraphicsOpen) | |
bd53ca78 | 668 | return (EBADF); |
12d43ee5 | 669 | |
bd53ca78 RC |
670 | GraphicsOpen = 0; |
671 | if (!isMono) | |
672 | InitColorMap(); | |
46a3a9ac RC |
673 | s = spltty(); |
674 | dcDivertXInput = (void (*)())0; | |
675 | dcMouseEvent = (void (*)())0; | |
676 | dcMouseButtons = (void (*)())0; | |
677 | splx(s); | |
bd53ca78 RC |
678 | ScreenInit(); |
679 | vmUserUnmap(); | |
680 | bzero((caddr_t)MACH_UNCACHED_FRAME_BUFFER_ADDR, | |
681 | (isMono ? 1024 / 8 : 1024) * 864); | |
682 | PosCursor(col * 8, row * 15); | |
683 | return (0); | |
684 | } | |
12d43ee5 | 685 | |
bd53ca78 RC |
686 | /*ARGSUSED*/ |
687 | pmioctl(dev, cmd, data, flag) | |
688 | dev_t dev; | |
689 | caddr_t data; | |
690 | { | |
691 | register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; | |
46a3a9ac | 692 | int s; |
12d43ee5 | 693 | |
bd53ca78 RC |
694 | switch (cmd) { |
695 | case QIOCGINFO: | |
696 | { | |
697 | caddr_t addr; | |
698 | extern caddr_t vmUserMap(); | |
12d43ee5 | 699 | |
bd53ca78 RC |
700 | /* |
701 | * Map the all the data the user needs access to into | |
702 | * user space. | |
703 | */ | |
704 | addr = vmUserMap(sizeof(pmu), (unsigned)&pmu); | |
705 | if (addr == (caddr_t)0) | |
706 | goto mapError; | |
707 | *(PM_Info **)data = &((struct pmuaccess *)addr)->scrInfo; | |
708 | pmu.scrInfo.qe.events = ((struct pmuaccess *)addr)->events; | |
709 | pmu.scrInfo.qe.tcs = ((struct pmuaccess *)addr)->tcs; | |
710 | /* | |
711 | * Map the plane mask into the user's address space. | |
712 | */ | |
713 | addr = vmUserMap(4, (unsigned)MACH_PLANE_MASK_ADDR); | |
714 | if (addr == (caddr_t)0) | |
715 | goto mapError; | |
716 | pmu.scrInfo.planemask = (char *)addr; | |
717 | /* | |
718 | * Map the frame buffer into the user's address space. | |
719 | */ | |
720 | addr = vmUserMap(isMono ? 256*1024 : 1024*1024, | |
721 | (unsigned)MACH_UNCACHED_FRAME_BUFFER_ADDR); | |
722 | if (addr == (caddr_t)0) | |
723 | goto mapError; | |
724 | pmu.scrInfo.bitmap = (char *)addr; | |
725 | break; | |
12d43ee5 | 726 | |
bd53ca78 RC |
727 | mapError: |
728 | vmUserUnmap(); | |
729 | printf("Cannot map shared data structures\n"); | |
730 | return (EIO); | |
731 | } | |
12d43ee5 | 732 | |
bd53ca78 RC |
733 | case QIOCPMSTATE: |
734 | /* | |
735 | * Set mouse state. | |
736 | */ | |
737 | pmu.scrInfo.mouse = *(pmCursor *)data; | |
738 | PosCursor(pmu.scrInfo.mouse.x, pmu.scrInfo.mouse.y); | |
739 | break; | |
12d43ee5 | 740 | |
bd53ca78 RC |
741 | case QIOCINIT: |
742 | /* | |
743 | * Initialize the screen. | |
744 | */ | |
745 | ScreenInit(); | |
746 | break; | |
12d43ee5 | 747 | |
bd53ca78 RC |
748 | case QIOCKPCMD: |
749 | { | |
750 | pmKpCmd *kpCmdPtr; | |
751 | unsigned char *cp; | |
12d43ee5 | 752 | |
bd53ca78 RC |
753 | kpCmdPtr = (pmKpCmd *)data; |
754 | if (kpCmdPtr->nbytes == 0) | |
755 | kpCmdPtr->cmd |= 0x80; | |
756 | if (!GraphicsOpen) | |
757 | kpCmdPtr->cmd |= 1; | |
758 | dcKBDPutc((int)kpCmdPtr->cmd); | |
759 | cp = &kpCmdPtr->par[0]; | |
760 | for (; kpCmdPtr->nbytes > 0; cp++, kpCmdPtr->nbytes--) { | |
761 | if (kpCmdPtr->nbytes == 1) | |
762 | *cp |= 0x80; | |
763 | dcKBDPutc((int)*cp); | |
764 | } | |
765 | break; | |
766 | } | |
12d43ee5 | 767 | |
bd53ca78 RC |
768 | case QIOCADDR: |
769 | *(PM_Info **)data = &pmu.scrInfo; | |
770 | break; | |
12d43ee5 | 771 | |
bd53ca78 RC |
772 | case QIOWCURSOR: |
773 | LoadCursor((unsigned short *)data); | |
774 | break; | |
12d43ee5 | 775 | |
bd53ca78 RC |
776 | case QIOWCURSORCOLOR: |
777 | CursorColor((unsigned int *)data); | |
778 | break; | |
12d43ee5 | 779 | |
bd53ca78 RC |
780 | case QIOSETCMAP: |
781 | LoadColorMap((ColorMap *)data); | |
782 | break; | |
12d43ee5 | 783 | |
bd53ca78 | 784 | case QIOKERNLOOP: |
46a3a9ac | 785 | s = spltty(); |
bd53ca78 RC |
786 | dcDivertXInput = pmKbdEvent; |
787 | dcMouseEvent = pmMouseEvent; | |
788 | dcMouseButtons = pmMouseButtons; | |
46a3a9ac | 789 | splx(s); |
bd53ca78 | 790 | break; |
12d43ee5 | 791 | |
bd53ca78 | 792 | case QIOKERNUNLOOP: |
46a3a9ac | 793 | s = spltty(); |
bd53ca78 RC |
794 | dcDivertXInput = (void (*)())0; |
795 | dcMouseEvent = (void (*)())0; | |
796 | dcMouseButtons = (void (*)())0; | |
46a3a9ac | 797 | splx(s); |
bd53ca78 | 798 | break; |
12d43ee5 | 799 | |
bd53ca78 RC |
800 | case QIOVIDEOON: |
801 | if (!isMono) | |
802 | RestoreCursorColor(); | |
803 | curReg |= PCC_ENPA; | |
804 | curReg &= ~PCC_FOPB; | |
805 | pcc->cmdr = curReg; | |
806 | break; | |
12d43ee5 | 807 | |
bd53ca78 RC |
808 | case QIOVIDEOOFF: |
809 | if (!isMono) | |
810 | VDACInit(); | |
811 | curReg |= PCC_FOPB; | |
812 | curReg &= ~PCC_ENPA; | |
813 | pcc->cmdr = curReg; | |
814 | break; | |
815 | ||
816 | default: | |
817 | printf("pm0: Unknown ioctl command %x\n", cmd); | |
818 | return (EINVAL); | |
12d43ee5 | 819 | } |
bd53ca78 RC |
820 | return (0); |
821 | } | |
12d43ee5 | 822 | |
bd53ca78 RC |
823 | pmselect(dev, flag, p) |
824 | dev_t dev; | |
825 | int flag; | |
826 | struct proc *p; | |
827 | { | |
828 | ||
829 | switch (flag) { | |
830 | case FREAD: | |
831 | if (pmu.scrInfo.qe.eHead != pmu.scrInfo.qe.eTail) | |
832 | return (1); | |
833 | selrecord(p, &pm_selp); | |
834 | break; | |
835 | } | |
836 | ||
837 | return (0); | |
12d43ee5 KM |
838 | } |
839 | ||
bd53ca78 RC |
840 | static u_char bg_RGB[3]; /* background color for the cursor */ |
841 | static u_char fg_RGB[3]; /* foreground color for the cursor */ | |
842 | ||
12d43ee5 | 843 | /* |
bd53ca78 | 844 | * The default cursor. |
12d43ee5 | 845 | */ |
bd53ca78 RC |
846 | unsigned short defCursor[32] = { |
847 | /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, | |
848 | 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, | |
849 | /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, | |
850 | 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF | |
851 | ||
852 | }; | |
853 | ||
854 | /* | |
855 | * Test to see if device is present. | |
856 | * Return true if found and initialized ok. | |
857 | */ | |
858 | pminit() | |
12d43ee5 KM |
859 | { |
860 | register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; | |
861 | ||
bd53ca78 RC |
862 | isMono = *(u_short *)MACH_SYS_CSR_ADDR & MACH_CSR_MONO; |
863 | if (isMono) { | |
864 | /* check for no frame buffer */ | |
865 | if (badaddr((char *)MACH_UNCACHED_FRAME_BUFFER_ADDR, 4)) | |
866 | return (0); | |
867 | } | |
868 | ||
869 | /* | |
870 | * Initialize the screen. | |
871 | */ | |
872 | pcc->cmdr = PCC_FOPB | PCC_VBHI; | |
873 | ||
874 | /* | |
875 | * Initialize the cursor register. | |
876 | */ | |
877 | pcc->cmdr = curReg = PCC_ENPA | PCC_ENPB; | |
878 | ||
879 | /* | |
880 | * Initialize screen info. | |
881 | */ | |
882 | pmu.scrInfo.max_row = 56; | |
883 | pmu.scrInfo.max_col = 80; | |
884 | pmu.scrInfo.max_x = 1024; | |
885 | pmu.scrInfo.max_y = 864; | |
886 | pmu.scrInfo.max_cur_x = 1023; | |
887 | pmu.scrInfo.max_cur_y = 863; | |
888 | pmu.scrInfo.version = 11; | |
889 | pmu.scrInfo.mthreshold = 4; | |
890 | pmu.scrInfo.mscale = 2; | |
891 | pmu.scrInfo.min_cur_x = -15; | |
892 | pmu.scrInfo.min_cur_y = -15; | |
893 | pmu.scrInfo.qe.timestamp_ms = TO_MS(time); | |
894 | pmu.scrInfo.qe.eSize = PM_MAXEVQ; | |
895 | pmu.scrInfo.qe.eHead = pmu.scrInfo.qe.eTail = 0; | |
896 | pmu.scrInfo.qe.tcSize = MOTION_BUFFER_SIZE; | |
897 | pmu.scrInfo.qe.tcNext = 0; | |
898 | ||
899 | /* | |
900 | * Initialize the color map, the screen, and the mouse. | |
901 | */ | |
902 | InitColorMap(); | |
903 | ScreenInit(); | |
904 | Scroll(); | |
905 | ||
906 | initialized = 1; | |
907 | return (1); | |
908 | } | |
12d43ee5 KM |
909 | |
910 | /* | |
bd53ca78 | 911 | * ---------------------------------------------------------------------------- |
12d43ee5 | 912 | * |
bd53ca78 | 913 | * ScreenInit -- |
12d43ee5 | 914 | * |
bd53ca78 | 915 | * Initialize the screen. |
12d43ee5 KM |
916 | * |
917 | * Results: | |
918 | * None. | |
919 | * | |
920 | * Side effects: | |
bd53ca78 | 921 | * The screen is initialized. |
12d43ee5 | 922 | * |
bd53ca78 | 923 | * ---------------------------------------------------------------------------- |
12d43ee5 KM |
924 | */ |
925 | static void | |
bd53ca78 | 926 | ScreenInit() |
12d43ee5 | 927 | { |
12d43ee5 | 928 | |
bd53ca78 RC |
929 | /* |
930 | * Home the cursor. | |
931 | * We want an LSI terminal emulation. We want the graphics | |
932 | * terminal to scroll from the bottom. So start at the bottom. | |
933 | */ | |
934 | row = 55; | |
935 | col = 0; | |
12d43ee5 | 936 | |
bd53ca78 RC |
937 | /* |
938 | * Load the cursor with the default values | |
939 | * | |
12d43ee5 | 940 | */ |
bd53ca78 | 941 | LoadCursor(defCursor); |
12d43ee5 KM |
942 | } |
943 | ||
944 | /* | |
bd53ca78 | 945 | * ---------------------------------------------------------------------------- |
12d43ee5 | 946 | * |
bd53ca78 | 947 | * LoadCursor -- |
12d43ee5 | 948 | * |
bd53ca78 | 949 | * Routine to load the cursor Sprite pattern. |
12d43ee5 KM |
950 | * |
951 | * Results: | |
952 | * None. | |
953 | * | |
954 | * Side effects: | |
bd53ca78 | 955 | * The cursor is loaded into the hardware cursor. |
12d43ee5 | 956 | * |
bd53ca78 | 957 | * ---------------------------------------------------------------------------- |
12d43ee5 | 958 | */ |
bd53ca78 RC |
959 | static void |
960 | LoadCursor(cur) | |
961 | unsigned short *cur; | |
12d43ee5 | 962 | { |
bd53ca78 RC |
963 | register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; |
964 | register int i; | |
12d43ee5 | 965 | |
bd53ca78 RC |
966 | curReg |= PCC_LODSA; |
967 | pcc->cmdr = curReg; | |
968 | for (i = 0; i < 32; i++) { | |
969 | pcc->memory = cur[i]; | |
970 | MachEmptyWriteBuffer(); | |
12d43ee5 | 971 | } |
bd53ca78 RC |
972 | curReg &= ~PCC_LODSA; |
973 | pcc->cmdr = curReg; | |
12d43ee5 KM |
974 | } |
975 | ||
976 | /* | |
bd53ca78 | 977 | * ---------------------------------------------------------------------------- |
12d43ee5 | 978 | * |
bd53ca78 | 979 | * RestoreCursorColor -- |
12d43ee5 | 980 | * |
bd53ca78 | 981 | * Routine to restore the color of the cursor. |
12d43ee5 KM |
982 | * |
983 | * Results: | |
984 | * None. | |
985 | * | |
986 | * Side effects: | |
987 | * None. | |
988 | * | |
bd53ca78 | 989 | * ---------------------------------------------------------------------------- |
12d43ee5 KM |
990 | */ |
991 | static void | |
bd53ca78 | 992 | RestoreCursorColor() |
12d43ee5 | 993 | { |
bd53ca78 | 994 | register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; |
12d43ee5 | 995 | register int i; |
12d43ee5 | 996 | |
bd53ca78 RC |
997 | vdac->overWA = 0x04; |
998 | MachEmptyWriteBuffer(); | |
999 | for (i = 0; i < 3; i++) { | |
1000 | vdac->over = bg_RGB[i]; | |
1001 | MachEmptyWriteBuffer(); | |
12d43ee5 | 1002 | } |
12d43ee5 | 1003 | |
bd53ca78 RC |
1004 | vdac->overWA = 0x08; |
1005 | MachEmptyWriteBuffer(); | |
1006 | vdac->over = 0x00; | |
1007 | MachEmptyWriteBuffer(); | |
1008 | vdac->over = 0x00; | |
1009 | MachEmptyWriteBuffer(); | |
1010 | vdac->over = 0x7f; | |
1011 | MachEmptyWriteBuffer(); | |
12d43ee5 | 1012 | |
bd53ca78 RC |
1013 | vdac->overWA = 0x0c; |
1014 | MachEmptyWriteBuffer(); | |
1015 | for (i = 0; i < 3; i++) { | |
1016 | vdac->over = fg_RGB[i]; | |
1017 | MachEmptyWriteBuffer(); | |
1018 | } | |
1019 | } | |
12d43ee5 | 1020 | |
bd53ca78 RC |
1021 | /* |
1022 | * ---------------------------------------------------------------------------- | |
1023 | * | |
1024 | * CursorColor -- | |
1025 | * | |
1026 | * Set the color of the cursor. | |
1027 | * | |
1028 | * Results: | |
1029 | * None. | |
1030 | * | |
1031 | * Side effects: | |
1032 | * None. | |
1033 | * | |
1034 | * ---------------------------------------------------------------------------- | |
1035 | */ | |
1036 | static void | |
1037 | CursorColor(color) | |
1038 | unsigned int color[]; | |
1039 | { | |
1040 | register int i, j; | |
12d43ee5 | 1041 | |
bd53ca78 RC |
1042 | for (i = 0; i < 3; i++) |
1043 | bg_RGB[i] = (u_char)(color[i] >> 8); | |
12d43ee5 | 1044 | |
bd53ca78 RC |
1045 | for (i = 3, j = 0; i < 6; i++, j++) |
1046 | fg_RGB[j] = (u_char)(color[i] >> 8); | |
12d43ee5 | 1047 | |
bd53ca78 RC |
1048 | RestoreCursorColor(); |
1049 | } | |
12d43ee5 | 1050 | |
bd53ca78 RC |
1051 | /* |
1052 | * ---------------------------------------------------------------------------- | |
1053 | * | |
1054 | * InitColorMap -- | |
1055 | * | |
1056 | * Initialize the color map. | |
1057 | * | |
1058 | * Results: | |
1059 | * None. | |
1060 | * | |
1061 | * Side effects: | |
1062 | * The colormap is initialized appropriately whether it is color or | |
1063 | * monochrome. | |
1064 | * | |
1065 | * ---------------------------------------------------------------------------- | |
1066 | */ | |
1067 | static void | |
1068 | InitColorMap() | |
1069 | { | |
1070 | register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; | |
1071 | register int i; | |
12d43ee5 | 1072 | |
bd53ca78 RC |
1073 | *(char *)MACH_PLANE_MASK_ADDR = 0xff; |
1074 | MachEmptyWriteBuffer(); | |
12d43ee5 | 1075 | |
bd53ca78 RC |
1076 | if (isMono) { |
1077 | vdac->mapWA = 0; MachEmptyWriteBuffer(); | |
1078 | for (i = 0; i < 256; i++) { | |
1079 | vdac->map = (i < 128) ? 0x00 : 0xff; | |
1080 | MachEmptyWriteBuffer(); | |
1081 | vdac->map = (i < 128) ? 0x00 : 0xff; | |
1082 | MachEmptyWriteBuffer(); | |
1083 | vdac->map = (i < 128) ? 0x00 : 0xff; | |
1084 | MachEmptyWriteBuffer(); | |
1085 | } | |
1086 | } else { | |
1087 | vdac->mapWA = 0; MachEmptyWriteBuffer(); | |
1088 | vdac->map = 0; MachEmptyWriteBuffer(); | |
1089 | vdac->map = 0; MachEmptyWriteBuffer(); | |
1090 | vdac->map = 0; MachEmptyWriteBuffer(); | |
12d43ee5 | 1091 | |
bd53ca78 RC |
1092 | for (i = 1; i < 256; i++) { |
1093 | vdac->map = 0xff; MachEmptyWriteBuffer(); | |
1094 | vdac->map = 0xff; MachEmptyWriteBuffer(); | |
1095 | vdac->map = 0xff; MachEmptyWriteBuffer(); | |
1096 | } | |
1097 | } | |
12d43ee5 | 1098 | |
bd53ca78 RC |
1099 | for (i = 0; i < 3; i++) { |
1100 | bg_RGB[i] = 0x00; | |
1101 | fg_RGB[i] = 0xff; | |
1102 | } | |
1103 | RestoreCursorColor(); | |
1104 | } | |
12d43ee5 | 1105 | |
bd53ca78 RC |
1106 | /* |
1107 | * ---------------------------------------------------------------------------- | |
1108 | * | |
1109 | * VDACInit -- | |
1110 | * | |
1111 | * Initialize the VDAC. | |
1112 | * | |
1113 | * Results: | |
1114 | * None. | |
1115 | * | |
1116 | * Side effects: | |
1117 | * None. | |
1118 | * | |
1119 | * ---------------------------------------------------------------------------- | |
1120 | */ | |
1121 | static void | |
1122 | VDACInit() | |
1123 | { | |
1124 | register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; | |
12d43ee5 | 1125 | |
bd53ca78 RC |
1126 | /* |
1127 | * | |
1128 | * Initialize the VDAC | |
1129 | */ | |
1130 | vdac->overWA = 0x04; MachEmptyWriteBuffer(); | |
1131 | vdac->over = 0x00; MachEmptyWriteBuffer(); | |
1132 | vdac->over = 0x00; MachEmptyWriteBuffer(); | |
1133 | vdac->over = 0x00; MachEmptyWriteBuffer(); | |
1134 | vdac->overWA = 0x08; MachEmptyWriteBuffer(); | |
1135 | vdac->over = 0x00; MachEmptyWriteBuffer(); | |
1136 | vdac->over = 0x00; MachEmptyWriteBuffer(); | |
1137 | vdac->over = 0x7f; MachEmptyWriteBuffer(); | |
1138 | vdac->overWA = 0x0c; MachEmptyWriteBuffer(); | |
1139 | vdac->over = 0xff; MachEmptyWriteBuffer(); | |
1140 | vdac->over = 0xff; MachEmptyWriteBuffer(); | |
1141 | vdac->over = 0xff; MachEmptyWriteBuffer(); | |
1142 | } | |
12d43ee5 | 1143 | |
bd53ca78 RC |
1144 | /* |
1145 | * ---------------------------------------------------------------------------- | |
1146 | * | |
1147 | * LoadColorMap -- | |
1148 | * | |
1149 | * Load the color map. | |
1150 | * | |
1151 | * Results: | |
1152 | * None. | |
1153 | * | |
1154 | * Side effects: | |
1155 | * The color map is loaded. | |
1156 | * | |
1157 | * ---------------------------------------------------------------------------- | |
1158 | */ | |
1159 | static void | |
1160 | LoadColorMap(ptr) | |
1161 | ColorMap *ptr; | |
1162 | { | |
1163 | register VDACRegs *vdac = (VDACRegs *)MACH_COLOR_MAP_ADDR; | |
12d43ee5 | 1164 | |
bd53ca78 RC |
1165 | if (ptr->index > 256) |
1166 | return; | |
1167 | ||
1168 | vdac->mapWA = ptr->index; MachEmptyWriteBuffer(); | |
1169 | vdac->map = ptr->Entry.red; MachEmptyWriteBuffer(); | |
1170 | vdac->map = ptr->Entry.green; MachEmptyWriteBuffer(); | |
1171 | vdac->map = ptr->Entry.blue; MachEmptyWriteBuffer(); | |
12d43ee5 KM |
1172 | } |
1173 | ||
bd53ca78 RC |
1174 | /* |
1175 | *---------------------------------------------------------------------- | |
1176 | * | |
1177 | * PosCursor -- | |
1178 | * | |
1179 | * Postion the cursor. | |
1180 | * | |
1181 | * Results: | |
1182 | * None. | |
1183 | * | |
1184 | * Side effects: | |
1185 | * None. | |
1186 | * | |
1187 | *---------------------------------------------------------------------- | |
1188 | */ | |
1189 | static void | |
1190 | PosCursor(x, y) | |
1191 | register int x, y; | |
12d43ee5 | 1192 | { |
bd53ca78 | 1193 | register PCCRegs *pcc = (PCCRegs *)MACH_CURSOR_REG_ADDR; |
12d43ee5 | 1194 | |
bd53ca78 RC |
1195 | if (y < pmu.scrInfo.min_cur_y || y > pmu.scrInfo.max_cur_y) |
1196 | y = pmu.scrInfo.max_cur_y; | |
1197 | if (x < pmu.scrInfo.min_cur_x || x > pmu.scrInfo.max_cur_x) | |
1198 | x = pmu.scrInfo.max_cur_x; | |
1199 | pmu.scrInfo.cursor.x = x; /* keep track of real cursor */ | |
1200 | pmu.scrInfo.cursor.y = y; /* position, indep. of mouse */ | |
1201 | pcc->xpos = PCC_X_OFFSET + x; | |
1202 | pcc->ypos = PCC_Y_OFFSET + y; | |
12d43ee5 | 1203 | } |
12d43ee5 | 1204 | #endif |