|
|
1.1 root 1: /*
2: * Copyright (c) 1982, 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)qdcons.c 1.3 Berkeley 6/29/88
7: *
8: * derived from: @(#)qdcons.c 4.1 (ULTRIX 11/23/87
9: */
10:
11: /************************************************************************
12: *
13: * ULTRIX QDSS STANDALONE BOOT DEVICE DRIVER...
14: * device driver to boot system with QDSS as console
15: *
16: *************************************************************************/
17: /************************************************************************
18: * *
19: * Copyright (c) 1985 by *
20: * Digital Equipment Corporation, Maynard, MA *
21: * All rights reserved. *
22: * *
23: * This software is furnished under a license and may be used and *
24: * copied only in accordance with the terms of such license and *
25: * with the inclusion of the above copyright notice. This *
26: * software or any other copies thereof may not be provided or *
27: * otherwise made available to any other person. No title to and *
28: * ownership of the software is hereby transferred. *
29: * *
30: * The information in this software is subject to change without *
31: * notice and should not be construed as a commitment by Digital *
32: * Equipment Corporation. *
33: * *
34: * Digital assumes no responsibility for the use or reliability *
35: * of its software on equipment which is not supplied by Digital. *
36: * *
37: *************************************************************************
38: * revision history: (should be moved into sccs comments)
39: *************************************************************************
40: *
41: * 09 oct 85 longo added uVAXII console ROM cursor reset to bottom of
42: * the screen. Also spruced up qdputc() & scroll_up()
43: * 02 oct 85 longo changed references to ADDRESS to be ADDRESS_COMPLETE
44: * 23 aug 85 longo changed I/O page CSR address to be 0x1F00
45: * 20 aug 85 longo created
46: *
47: ************************************************************************/
48:
49: #include "../h/types.h"
50: #include "../vax/cpu.h"
51: #define KERNEL
52: #include "../vaxuba/qdioctl.h"
53: #include "../vaxuba/qevent.h"
54: #include "../vaxuba/qduser.h"
55: #include "../vaxuba/qdreg.h"
56: #undef KERNEL
57:
58: /*-----------------------------------------------------------------------
59: * constants used to set VAX ROM's cursor to bottom the of the screen */
60:
61: #define NVR_ADRS 0x200B8024
62:
63: #define CURRENT_ROW 0x4C /* these are offsets to the ROM's scratch.. */
64: #define ROW_MIN 0x4D /* ..RAM start adrs as picked up out of NVR */
65: #define ROW_MAX 0x4E
66: #define CURRENT_COL 0x50
67: #define COL_MIN 0x51
68: #define COL_MAX 0x52
69:
70: /*----------------------------------------
71: * LK201 keyboard state tracking struct */
72:
73: struct q_keyboard {
74:
75: int shift; /* state variables */
76: int cntrl;
77: int lock;
78: char last; /* last character */
79:
80: } q_keyboard;
81:
82: int qdputc(), qdgetc();
83:
84: extern (*v_putc)(),(*v_getc)();
85:
86: /*----------------------------
87: * general purpose defines */
88:
89: #define BAD -1
90: #define GOOD 0
91:
92: /*----------------------------------------------
93: * console cursor bitmap (block cursor type) */
94:
95: short cons_cursor[32] = { /* white block cursor */
96:
97: /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
98: 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
99: /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
100: 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
101:
102: };
103:
104: /*-------------------------------------
105: * constants used in font operations */
106:
107: #define CHARS 95 /* # of chars in the font */
108: #define CHAR_HEIGHT 15 /* char height in pixels */
109: #define CHAR_WIDTH 8 /* char width in pixels*/
110: #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */
111: #define ROWS CHAR_HEIGHT
112:
113: #define FONT_X 0 /* font's off screen adrs */
114: #define FONT_Y (2047 - CHAR_HEIGHT)
115: /*
116: #define FONT_Y 200
117: */
118:
119: extern char q_font[]; /* reference font object code */
120:
121: extern char q_key[]; /* reference key xlation tables */
122: extern char q_shift_key[];
123: extern char *q_special[];
124:
125: /*----------------------------
126: * console cursor structure */
127:
128: struct cons_cur {
129: int x;
130: int y;
131: } cursor;
132:
133: /*------------------------------------------
134: * MicroVAX-II q-bus addressing constants */
135:
136: #define QMEMBASE 0x30000000
137: #define QDSSCSR 0x20001F00
138:
139: #define CHUNK (64 * 1024)
140: #define QMEMSIZE (1024 * 1024 * 4)
141: #define QDBASE (QMEMBASE + QMEMSIZE - CHUNK)
142:
143: /*------------------------------------------------------------------
144: * QDSS register address offsets from start of QDSS address space */
145:
146: #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */
147:
148: #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */
149: #define TMPSTART 0x8000 /* offset of template RAM from base adrs */
150:
151: #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */
152: #define REGSTART 0xC000 /* offset of reg pages from base adrs */
153:
154: #define ADDER (REGSTART+0x000)
155: #define DGA (REGSTART+0x200)
156: #define DUART (REGSTART+0x400)
157: #define MEMCSR (REGSTART+0x800)
158:
159: #define CLRSIZE (3 * 512) /* color map size */
160: #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */
161: /* 0x0C00 really */
162: #define RED (CLRSTART+0x000)
163: #define BLUE (CLRSTART+0x200)
164: #define GREEN (CLRSTART+0x400)
165:
166: /*---------------------------------------
167: * QDSS register address map structure */
168:
169: struct qdmap qdmap;
170:
171: /************************************************************************
172: *************************************************************************
173: *************************************************************************
174: *
175: * EXTERNALLY CALLED ROUTINES START HERE:
176: *
177: *************************************************************************
178: *************************************************************************
179: ************************************************************************/
180:
181: /************************************************************************
182: *
183: * qd_init()... init the QDSS into a physical memory system
184: *
185: ************************************************************************/
186:
187: qd_init()
188: {
189: register char *ROM_console;
190: register short *NVR;
191: register int i;
192:
193: caddr_t qdaddr;
194: struct dga *dga;
195:
196: qdaddr = (caddr_t) QDSSCSR;
197: if (badaddr(qdaddr, sizeof(short)))
198: return(0);
199:
200: *(short *)qdaddr = (short) (QDBASE >> 16);
201:
202: /*----------------------------------------------------------------------
203: * load qdmap struct with the physical addresses of the QDSS elements */
204:
205: qdmap.template = (caddr_t) QDBASE + TMPSTART;
206: qdmap.adder = (caddr_t) QDBASE + ADDER;
207: qdmap.dga = (caddr_t) QDBASE + DGA;
208: qdmap.duart = (caddr_t) QDBASE + DUART;
209: qdmap.memcsr = (caddr_t) QDBASE + MEMCSR;
210: qdmap.red = (caddr_t) QDBASE + RED;
211: qdmap.blue = (caddr_t) QDBASE + BLUE;
212: qdmap.green = (caddr_t) QDBASE + GREEN;
213:
214: /*--------------------------
215: * no interrupts allowed! */
216:
217: dga = (struct dga *) qdmap.dga;
218: dga->csr = HALT;
219: dga->csr |= CURS_ENB;
220:
221: /*----------------------------
222: * init the default values */
223:
224: q_keyboard.shift = 0; /* init keyboard state tracking */
225: q_keyboard.lock = 0;
226: q_keyboard.cntrl = 0;
227: q_keyboard.last = 0;
228:
229: cursor.x = 0; /* init cursor to top left */
230: cursor.y = 0;
231:
232: set_defaults(); /* setup the default device */
233: ldfont(); /* PtoB the font into off-screen */
234:
235: /*--------------------------------------------------------------------
236: * tell the VAX ROM that the cursor is at the bottom of the screen */
237:
238: NVR = (short *) NVR_ADRS;
239:
240: i = *NVR++ & 0xFF;
241: i |= (*NVR++ & 0xFF) << 8;
242: i |= (*NVR++ & 0xFF) << 16;
243: i |= (*NVR++ & 0xFF) << 24;
244:
245: ROM_console = (char *) i;
246:
247: ROM_console[CURRENT_COL] = ROM_console[COL_MIN];
248: ROM_console[CURRENT_ROW] = ROM_console[ROW_MAX];
249:
250: /*----------------------------------------------------------
251: * smash system virtual console service routine addresses */
252:
253: v_getc = qdgetc;
254: v_putc = qdputc;
255:
256: return(1);
257:
258: } /* qd_init */
259:
260: /*******************************************************************
261: *
262: * qdputc()... output a character to the QDSS screen
263: *
264: ********************************************************************
265: *
266: * calling convention:
267: *
268: * qdputc(chr);
269: * char chr; ;character to be displayed
270: *
271: ********/
272:
273: qdputc(chr)
274: char chr;
275: {
276: register struct adder *adder;
277: register struct dga *dga;
278: register int i;
279:
280: short x;
281:
282: adder = (struct adder *) qdmap.adder;
283: dga = (struct dga *) qdmap.dga;
284:
285: /*---------------------------
286: * non display character? */
287:
288: chr &= 0x7F;
289:
290: switch (chr) {
291:
292: case '\r': /* return char */
293: cursor.x = 0;
294: dga->x_cursor = TRANX(cursor.x);
295: return(0);
296:
297: case '\t': /* tab char */
298:
299: for (i = 8 - ((cursor.x >> 3) & 0x07); i > 0; --i) {
300: qdputc(' ');
301: }
302: return(0);
303:
304: case '\n': /* line feed char */
305:
306: if ((cursor.y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) {
307: cursor.y -= CHAR_HEIGHT;
308: scroll_up(adder);
309: }
310: dga->y_cursor = TRANY(cursor.y);
311: return(0);
312:
313: case '\b': /* backspace char */
314: if (cursor.x > 0) {
315: cursor.x -= CHAR_WIDTH;
316: qdputc(' ');
317: cursor.x -= CHAR_WIDTH;
318: dga->x_cursor = TRANX(cursor.x);
319: }
320: return(0);
321:
322: default:
323: if (chr < ' ' || chr > '~') {
324: return(0);
325: }
326: }
327:
328: /*------------------------------------------
329: * setup VIPER operand control registers */
330:
331: write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */
332: write_ID(adder, SRC1_OCR_B,
333: EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);
334:
335: write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */
336: write_ID(adder, SRC1_OCR_B,
337: EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY);
338:
339: write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */
340: write_ID(adder, DST_OCR_B,
341: EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
342:
343: write_ID(adder, MASK_1, 0xFFFF);
344: write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1);
345: write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
346:
347: /*----------------------------------------
348: * load DESTINATION origin and vectors */
349:
350: adder->fast_dest_dy = 0;
351: adder->slow_dest_dx = 0;
352: adder->error_1 = 0;
353: adder->error_2 = 0;
354:
355: adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;
356:
357: wait_status(adder, RASTEROP_COMPLETE);
358:
359: adder->destination_x = cursor.x;
360: adder->fast_dest_dx = CHAR_WIDTH;
361:
362: adder->destination_y = cursor.y;
363: adder->slow_dest_dy = CHAR_HEIGHT;
364:
365: /*-----------------------------------
366: * load SOURCE origin and vectors */
367:
368: adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH);
369: adder->source_1_y = FONT_Y;
370:
371: adder->source_1_dx = CHAR_WIDTH;
372: adder->source_1_dy = CHAR_HEIGHT;
373:
374: write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
375: adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;
376:
377: /*-------------------------------------
378: * update console cursor coordinates */
379:
380: cursor.x += CHAR_WIDTH;
381: dga->x_cursor = TRANX(cursor.x);
382:
383: if (cursor.x > (1024 - CHAR_WIDTH)) {
384: qdputc('\r');
385: qdputc('\n');
386: }
387:
388: } /* qdputc */
389:
390: /*******************************************************************
391: *
392: * qdgetc()... get a character from the LK201
393: *
394: *******************************************************************/
395:
396: qdgetc()
397: {
398: register short key;
399: register char chr;
400: register struct duart *duart;
401:
402: u_int status;
403:
404: duart = (struct duart *) qdmap.duart;
405:
406: /*--------------------------------------
407: * Get a character from the keyboard. */
408:
409: LOOP:
410: while (!((status = duart->statusA) & RCV_RDY))
411: ;
412:
413: key = duart->dataA;
414: key &= 0xFF;
415:
416: /*--------------------------------------
417: * Check for various keyboard errors */
418:
419: if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR ||
420: key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) {
421: printf("Keyboard error, code = %x\n", key);
422: return(0);
423: }
424:
425: if (key < LK_LOWEST)
426: return(0);
427:
428: /*---------------------------------
429: * See if its a state change key */
430:
431: switch (key) {
432:
433: case LOCK:
434: q_keyboard.lock ^= 0xffff; /* toggle */
435: if (q_keyboard.lock)
436: led_control(LK_LED_ENABLE, LK_LED_LOCK);
437: else
438: led_control(LK_LED_DISABLE, LK_LED_LOCK);
439: goto LOOP;
440:
441: case SHIFT:
442: q_keyboard.shift ^= 0xFFFF;
443: goto LOOP;
444:
445: case CNTRL:
446: q_keyboard.cntrl ^= 0xFFFF;
447: goto LOOP;
448:
449: case ALLUP:
450: q_keyboard.cntrl = 0;
451: q_keyboard.shift = 0;
452: goto LOOP;
453:
454: case REPEAT:
455: chr = q_keyboard.last;
456: break;
457:
458: /*-------------------------------------------------------
459: * Test for cntrl characters. If set, see if the character
460: * is elligible to become a control character. */
461:
462: default:
463:
464: if (q_keyboard.cntrl) {
465: chr = q_key[key];
466: if (chr >= ' ' && chr <= '~')
467: chr &= 0x1F;
468: }
469: else if ( q_keyboard.lock || q_keyboard.shift )
470: chr = q_shift_key[key];
471: else
472: chr = q_key[key];
473: break;
474: }
475:
476: if (chr < ' ' && chr > '~') /* if input is non-displayable */
477: return(0); /* ..then pitch it! */
478:
479: q_keyboard.last = chr;
480:
481: /*-----------------------------------
482: * Check for special function keys */
483:
484: if (chr & 0x80) /* pitch the function keys */
485: return(0);
486: else
487: return(chr);
488:
489: } /* qdgetc */
490:
491: /************************************************************************
492: *************************************************************************
493: *************************************************************************
494: *
495: * INTERNALLY USED ROUTINES START HERE:
496: *
497: *************************************************************************
498: *************************************************************************
499: ************************************************************************/
500:
501: /********************************************************************
502: *
503: * ldcursor()... load the mouse cursor's template RAM bitmap
504: *
505: ********************************************************************/
506:
507: ldcursor()
508: {
509: register struct dga *dga;
510: register short *temp;
511: register int i;
512:
513: int cursor;
514:
515: dga = (struct dga *) qdmap.dga;
516: temp = (short *) qdmap.template;
517:
518: temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */
519: /* ..of the 8k WORD template space */
520: for (i = 0; i < 32; ++i)
521: *temp++ = cons_cursor[i];
522:
523: return(0);
524:
525: } /* ldcursor */
526:
527: /**********************************************************************
528: *
529: * ldfont()... put the console font in the QDSS off-screen memory
530: *
531: **********************************************************************/
532:
533: ldfont()
534: {
535: register struct adder *adder;
536:
537: int i; /* scratch variables */
538: int j;
539: int k;
540: short packed;
541:
542: adder = (struct adder *) qdmap.adder;
543:
544: /*------------------------------------------
545: * setup VIPER operand control registers */
546:
547: write_ID(adder, MASK_1, 0xFFFF);
548: write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
549: write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
550:
551: write_ID(adder, SRC1_OCR_B,
552: EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY);
553: write_ID(adder, SRC2_OCR_B,
554: EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY);
555: write_ID(adder, DST_OCR_B,
556: EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
557:
558: adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL;
559:
560: /*--------------------------
561: * load destination data */
562:
563: wait_status(adder, RASTEROP_COMPLETE);
564:
565: adder->destination_x = FONT_X;
566: adder->destination_y = FONT_Y;
567: adder->fast_dest_dx = FONT_WIDTH;
568: adder->slow_dest_dy = CHAR_HEIGHT;
569:
570: /*---------------------------------------
571: * setup for processor to bitmap xfer */
572:
573: write_ID(adder, CS_UPDATE_MASK, 0x0001);
574: adder->cmd = PBT | OCRB | 2 | DTE | 2;
575:
576: /*-----------------------------------------------
577: * iteratively do the processor to bitmap xfer */
578:
579: for (i = 0; i < ROWS; ++i) {
580:
581: /* PTOB a scan line */
582:
583: for (j = 0, k = i; j < 48; ++j) {
584:
585: /* PTOB one scan of a char cell */
586:
587: packed = q_font[k];
588: k += ROWS;
589: packed |= ((short)q_font[k] << 8);
590: k += ROWS;
591:
592: wait_status(adder, TX_READY);
593: adder->id_data = packed;
594: }
595: }
596:
597: } /* ldfont */
598:
599: /*********************************************************************
600: *
601: * led_control()... twiddle LK-201 LED's
602: *
603: **********************************************************************
604: *
605: * led_control(cmd, led_mask);
606: * int cmd; LED enable/disable command
607: * int led_mask; which LED(s) to twiddle
608: *
609: *************/
610:
611: led_control(cmd, led_mask)
612: int cmd;
613: int led_mask;
614: {
615: register int i;
616: register int status;
617: register struct duart *duart;
618:
619: duart = (struct duart *) qdmap.duart;
620:
621: for (i = 1000; i > 0; --i) {
622: if ((status = duart->statusA) & XMT_RDY) {
623: duart->dataA = cmd;
624: break;
625: }
626: }
627:
628: for (i = 1000; i > 0; --i) {
629: if ((status = duart->statusA) & XMT_RDY) {
630: duart->dataA = led_mask;
631: break;
632: }
633: }
634:
635: if (i == 0)
636: return(BAD);
637:
638: return(GOOD);
639:
640: } /* led_control */
641:
642: /*******************************************************************
643: *
644: * scroll_up()... move the screen up one character height
645: *
646: ********************************************************************
647: *
648: * calling convention:
649: *
650: * scroll_up(adder);
651: * struct adder *adder; ;address of adder
652: *
653: ********/
654:
655: scroll_up(adder)
656: register struct adder *adder;
657: {
658:
659: /*------------------------------------------
660: * setup VIPER operand control registers */
661:
662: wait_status(adder, ADDRESS_COMPLETE);
663:
664: write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */
665:
666: write_ID(adder, MASK_1, 0xFFFF);
667: write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
668: write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
669:
670: write_ID(adder, SRC1_OCR_B,
671: EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);
672: write_ID(adder, DST_OCR_B,
673: EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
674:
675: /*----------------------------------------
676: * load DESTINATION origin and vectors */
677:
678: adder->fast_dest_dy = 0;
679: adder->slow_dest_dx = 0;
680: adder->error_1 = 0;
681: adder->error_2 = 0;
682:
683: adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;
684:
685: adder->destination_x = 0;
686: adder->fast_dest_dx = 1024;
687:
688: adder->destination_y = 0;
689: adder->slow_dest_dy = 864 - CHAR_HEIGHT;
690:
691: /*-----------------------------------
692: * load SOURCE origin and vectors */
693:
694: adder->source_1_x = 0;
695: adder->source_1_dx = 1024;
696:
697: adder->source_1_y = 0 + CHAR_HEIGHT;
698: adder->source_1_dy = 864 - CHAR_HEIGHT;
699:
700: write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
701: adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;
702:
703: /*--------------------------------------------
704: * do a rectangle clear of last screen line */
705:
706: write_ID(adder, MASK_1, 0xffff);
707: write_ID(adder, SOURCE, 0xffff);
708: write_ID(adder,DST_OCR_B,
709: (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY));
710: write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0);
711: adder->error_1 = 0;
712: adder->error_2 = 0;
713: adder->slow_dest_dx = 0; /* set up the width of */
714: adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */
715:
716: adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ;
717: wait_status(adder, RASTEROP_COMPLETE);
718: adder->destination_x = 0;
719: adder->destination_y = 864 - CHAR_HEIGHT;
720:
721: adder->fast_dest_dx = 1024; /* set up the height */
722: adder->fast_dest_dy = 0; /* of rectangle */
723:
724: write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE));
725: adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ;
726:
727: } /* scroll_up */
728:
729: /**********************************************************************
730: *
731: * set_defaults()... init the QDSS device and driver defaults
732: *
733: **********************************************************************/
734:
735: set_defaults()
736: {
737: setup_input(); /* init the DUART */
738: setup_dragon(); /* init the ADDER/VIPER stuff */
739: ldcursor(); /* load default cursor map */
740:
741: } /* set_defaults */
742:
743: /*********************************************************************
744: *
745: * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map
746: *
747: *********************************************************************/
748:
749: setup_dragon()
750: {
751:
752: register struct adder *adder;
753: register struct dga *dga;
754: short *memcsr;
755:
756: int i; /* general purpose variables */
757: int status;
758:
759: short top; /* clipping/scrolling boundaries */
760: short bottom;
761: short right;
762: short left;
763:
764: short *red; /* color map pointers */
765: short *green;
766: short *blue;
767:
768: /*------------------
769: * init for setup */
770:
771: adder = (struct adder *) qdmap.adder;
772: dga = (struct dga *) qdmap.dga;
773: memcsr = (short *) qdmap.memcsr;
774:
775: *memcsr = SYNC_ON; /* blank screen and turn off LED's */
776: adder->command = CANCEL;
777:
778: /*----------------------
779: * set monitor timing */
780:
781: adder->x_scan_count_0 = 0x2800;
782: adder->x_scan_count_1 = 0x1020;
783: adder->x_scan_count_2 = 0x003A;
784: adder->x_scan_count_3 = 0x38F0;
785: adder->x_scan_count_4 = 0x6128;
786: adder->x_scan_count_5 = 0x093A;
787: adder->x_scan_count_6 = 0x313C;
788: adder->sync_phase_adj = 0x0100;
789: adder->x_scan_conf = 0x00C8;
790:
791: /*---------------------------------------------------------
792: * got a bug in secound pass ADDER! lets take care of it */
793:
794: /* normally, just use the code in the following bug fix code, but to
795: * make repeated demos look pretty, load the registers as if there was
796: * no bug and then test to see if we are getting sync */
797:
798: adder->y_scan_count_0 = 0x135F;
799: adder->y_scan_count_1 = 0x3363;
800: adder->y_scan_count_2 = 0x2366;
801: adder->y_scan_count_3 = 0x0388;
802:
803: /* if no sync, do the bug fix code */
804:
805: if (wait_status(adder, VSYNC) == BAD) {
806:
807: /* first load all Y scan registers with very short frame and
808: * wait for scroll service. This guarantees at least one SYNC
809: * to fix the pass 2 Adder initialization bug (synchronizes
810: * XCINCH with DMSEEDH) */
811:
812: adder->y_scan_count_0 = 0x01;
813: adder->y_scan_count_1 = 0x01;
814: adder->y_scan_count_2 = 0x01;
815: adder->y_scan_count_3 = 0x01;
816:
817: wait_status(adder, VSYNC); /* delay at least 1 full frame time */
818: wait_status(adder, VSYNC);
819:
820: /* now load the REAL sync values (in reverse order just to
821: * be safe. */
822:
823: adder->y_scan_count_3 = 0x0388;
824: adder->y_scan_count_2 = 0x2366;
825: adder->y_scan_count_1 = 0x3363;
826: adder->y_scan_count_0 = 0x135F;
827: }
828:
829: /*----------------------------
830: * zero the index registers */
831:
832: adder->x_index_pending = 0;
833: adder->y_index_pending = 0;
834: adder->x_index_new = 0;
835: adder->y_index_new = 0;
836: adder->x_index_old = 0;
837: adder->y_index_old = 0;
838:
839: adder->pause = 0;
840:
841: /*----------------------------------------
842: * set rasterop mode to normal pen down */
843:
844: adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL;
845:
846: /*--------------------------------------------------
847: * set the rasterop registers to a default values */
848:
849: adder->source_1_dx = 1;
850: adder->source_1_dy = 1;
851: adder->source_1_x = 0;
852: adder->source_1_y = 0;
853: adder->destination_x = 0;
854: adder->destination_y = 0;
855: adder->fast_dest_dx = 1;
856: adder->fast_dest_dy = 0;
857: adder->slow_dest_dx = 0;
858: adder->slow_dest_dy = 1;
859: adder->error_1 = 0;
860: adder->error_2 = 0;
861:
862: /*------------------------
863: * scale factor = unity */
864:
865: adder->fast_scale = UNITY;
866: adder->slow_scale = UNITY;
867:
868: /*-------------------------------
869: * set the source 2 parameters */
870:
871: adder->source_2_x = 0;
872: adder->source_2_y = 0;
873: adder->source_2_size = 0x0022;
874:
875: /*-----------------------------------------------
876: * initialize plane addresses for eight vipers */
877:
878: write_ID(adder, CS_UPDATE_MASK, 0x0001);
879: write_ID(adder, PLANE_ADDRESS, 0x0000);
880:
881: write_ID(adder, CS_UPDATE_MASK, 0x0002);
882: write_ID(adder, PLANE_ADDRESS, 0x0001);
883:
884: write_ID(adder, CS_UPDATE_MASK, 0x0004);
885: write_ID(adder, PLANE_ADDRESS, 0x0002);
886:
887: write_ID(adder, CS_UPDATE_MASK, 0x0008);
888: write_ID(adder, PLANE_ADDRESS, 0x0003);
889:
890: write_ID(adder, CS_UPDATE_MASK, 0x0010);
891: write_ID(adder, PLANE_ADDRESS, 0x0004);
892:
893: write_ID(adder, CS_UPDATE_MASK, 0x0020);
894: write_ID(adder, PLANE_ADDRESS, 0x0005);
895:
896: write_ID(adder, CS_UPDATE_MASK, 0x0040);
897: write_ID(adder, PLANE_ADDRESS, 0x0006);
898:
899: write_ID(adder, CS_UPDATE_MASK, 0x0080);
900: write_ID(adder, PLANE_ADDRESS, 0x0007);
901:
902: /* initialize the external registers. */
903:
904: write_ID(adder, CS_UPDATE_MASK, 0x00FF);
905: write_ID(adder, CS_SCROLL_MASK, 0x00FF);
906:
907: /* initialize resolution mode */
908:
909: write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */
910: write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */
911:
912: /* initialize viper registers */
913:
914: write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP);
915: write_ID(adder, SCROLL_FILL, 0x0000);
916:
917: /*----------------------------------------------------
918: * set clipping and scrolling limits to full screen */
919:
920: for ( i = 1000, adder->status = 0
921: ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE)
922: ; --i);
923:
924: if (i == 0)
925: printf("timeout trying to setup clipping\n");
926:
927: top = 0;
928: bottom = 2048;
929: left = 0;
930: right = 1024;
931:
932: adder->x_clip_min = left;
933: adder->x_clip_max = right;
934: adder->y_clip_min = top;
935: adder->y_clip_max = bottom;
936:
937: adder->scroll_x_min = left;
938: adder->scroll_x_max = right;
939: adder->scroll_y_min = top;
940: adder->scroll_y_max = bottom;
941:
942: wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */
943: wait_status(adder, VSYNC);
944:
945: adder->x_index_pending = left;
946: adder->y_index_pending = top;
947: adder->x_index_new = left;
948: adder->y_index_new = top;
949: adder->x_index_old = left;
950: adder->y_index_old = top;
951:
952: for ( i = 1000, adder->status = 0
953: ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE)
954: ; --i);
955:
956: if (i == 0)
957: printf("timeout waiting for ADDRESS_COMPLETE bit\n");
958:
959: write_ID(adder, LEFT_SCROLL_MASK, 0x0000);
960: write_ID(adder, RIGHT_SCROLL_MASK, 0x0000);
961:
962: /*------------------------------------------------------------
963: * set source and the mask register to all ones (ie: white) */
964:
965: write_ID(adder, SOURCE, 0xFFFF);
966: write_ID(adder, MASK_1, 0xFFFF);
967: write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
968: write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
969:
970: /*--------------------------------------------------------------
971: * initialize Operand Control Register banks for fill command */
972:
973: write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT);
974: write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT);
975: write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT);
976:
977: write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT);
978: write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT);
979: write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT);
980:
981: /*------------------------------------------------------------------
982: * init Logic Unit Function registers, (these are just common values,
983: * and may be changed as required). */
984:
985: write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
986: write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2);
987: write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S);
988: write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S);
989:
990: /*----------------------------------------
991: * load the color map for black & white */
992:
993: for ( i = 0, adder->status = 0
994: ; i < 10000 && !((status = adder->status) & VSYNC)
995: ; ++i);
996:
997: if (i == 0)
998: printf("timeout waiting for VSYNC bit\n");
999:
1000: red = (short *) qdmap.red;
1001: green = (short *) qdmap.green;
1002: blue = (short *) qdmap.blue;
1003:
1004: *red++ = 0x00; /* black */
1005: *green++ = 0x00;
1006: *blue++ = 0x00;
1007:
1008: *red-- = 0xFF; /* white */
1009: *green-- = 0xFF;
1010: *blue-- = 0xFF;
1011:
1012: /*----------------------------------
1013: * set color map for mouse cursor */
1014:
1015: red += 254;
1016: green += 254;
1017: blue += 254;
1018:
1019: *red++ = 0x00; /* black */
1020: *green++ = 0x00;
1021: *blue++ = 0x00;
1022:
1023: *red = 0xFF; /* white */
1024: *green = 0xFF;
1025: *blue = 0xFF;
1026:
1027: /*---------------------------------------------------------------------------
1028: * clear the bitmap a piece at a time. Since the fast scroll clear only clears
1029: * the current displayed portion of the bitmap put a temporary value in the y
1030: * limit register so we can access whole bitmap */
1031:
1032: adder->x_limit = 1024;
1033: adder->y_limit = 2048 - CHAR_HEIGHT;
1034: adder->y_offset_pending = 0;
1035:
1036: wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */
1037: wait_status(adder, VSYNC);
1038:
1039: adder->y_scroll_constant = SCROLL_ERASE;
1040:
1041: wait_status(adder, VSYNC);
1042: wait_status(adder, VSYNC);
1043:
1044: adder->y_offset_pending = 864;
1045:
1046: wait_status(adder, VSYNC);
1047: wait_status(adder, VSYNC);
1048:
1049: adder->y_scroll_constant = SCROLL_ERASE;
1050:
1051: wait_status(adder, VSYNC);
1052: wait_status(adder, VSYNC);
1053:
1054: adder->y_offset_pending = 1728;
1055:
1056: wait_status(adder, VSYNC);
1057: wait_status(adder, VSYNC);
1058:
1059: adder->y_scroll_constant = SCROLL_ERASE;
1060:
1061: wait_status(adder, VSYNC);
1062: wait_status(adder, VSYNC);
1063:
1064: adder->y_offset_pending = 0; /* back to normal */
1065:
1066: wait_status(adder, VSYNC);
1067: wait_status(adder, VSYNC);
1068:
1069: adder->x_limit = MAX_SCREEN_X;
1070: adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT;
1071:
1072: *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */
1073: return(0);
1074:
1075: } /* setup_dragon */
1076:
1077: /******************************************************************
1078: *
1079: * setup_input()... init the DUART and set defaults in input
1080: * devices
1081: *
1082: ******************************************************************/
1083:
1084: setup_input()
1085: {
1086: register struct duart *duart; /* DUART register structure pointer */
1087: register int bits;
1088: int i, j; /* scratch variables */
1089:
1090: short status;
1091:
1092: /*---------------
1093: * init stuff */
1094:
1095: duart = (struct duart *) qdmap.duart;
1096:
1097: /*---------------------------------------------
1098: * setup the DUART for kbd & pointing device */
1099:
1100: duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */
1101: duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */
1102: /* no RTS control,char error mode */
1103: duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */
1104: /* no RTS control,no echo or loop */
1105: duart->auxctl = 0x00; /* baud rate set 1 */
1106:
1107: duart->clkselA = 0x99; /* 4800 baud for kbd */
1108:
1109: /* reset everything for keyboard */
1110:
1111: for (bits = RESET_M; bits < START_BREAK; bits += 0x10)
1112: duart->cmdA = bits;
1113:
1114: duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */
1115:
1116: /*--------------------------
1117: * init keyboard defaults */
1118: /*
1119: for (i = 500; i > 0; --i) {
1120: if ((status = duart->statusA) & XMT_RDY) {
1121: duart->dataA = LK_DEFAULTS;
1122: break;
1123: }
1124: }
1125:
1126: for (j = 0; j < 3; ++j) {
1127: for (i = 50000; i > 0; --i) {
1128: if ((status = duart->statusA) & RCV_RDY) {
1129: status = duart->dataA;
1130: break;
1131: }
1132: }
1133: }
1134:
1135: if (i == 0)
1136: printf("LK-201 init error\n");
1137: */
1138:
1139: /*--------
1140: * exit */
1141:
1142: return(0);
1143:
1144: } /* setup_input */
1145:
1146: /**********************************************************************
1147: *
1148: * wait_status()... delay for at least one display frame time
1149: *
1150: ***********************************************************************
1151: *
1152: * calling convention:
1153: *
1154: * wait_status(adder, mask);
1155: * struct *adder adder;
1156: * int mask;
1157: *
1158: * return: BAD means that we timed out without ever seeing the
1159: * vertical sync status bit
1160: * GOOD otherwise
1161: *
1162: **************/
1163:
1164: wait_status(adder, mask)
1165: register struct adder *adder;
1166: register int mask;
1167: {
1168: register short status;
1169: int i;
1170:
1171: for ( i = 10000, adder->status = 0
1172: ; i > 0 && !((status = adder->status) & mask)
1173: ; --i);
1174:
1175: if (i == 0) {
1176: printf("timeout polling for 0x%x in adder->status\n", mask);
1177: return(BAD);
1178: }
1179:
1180: return(GOOD);
1181:
1182: } /* wait_status */
1183:
1184: /**********************************************************************
1185: *
1186: * write_ID()... write out onto the ID bus
1187: *
1188: ***********************************************************************
1189: *
1190: * calling convention:
1191: *
1192: * struct *adder adder; ;pntr to ADDER structure
1193: * short adrs; ;VIPER address
1194: * short data; ;data to be written
1195: * write_ID(adder);
1196: *
1197: * return: BAD means that we timed out waiting for status bits
1198: * VIPER-access-specific status bits
1199: * GOOD otherwise
1200: *
1201: **************/
1202:
1203: write_ID(adder, adrs, data)
1204: register struct adder *adder;
1205: register short adrs;
1206: register short data;
1207: {
1208: int i;
1209: short status;
1210:
1211: for ( i = 100000, adder->status = 0
1212: ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE)
1213: ; --i);
1214:
1215: if (i == 0)
1216: goto ERR;
1217:
1218: for ( i = 100000, adder->status = 0
1219: ; i > 0 && !((status = adder->status) & TX_READY)
1220: ; --i);
1221:
1222: if (i > 0) {
1223: adder->id_data = data;
1224: adder->command = ID_LOAD | adrs;
1225: return(GOOD);
1226: }
1227:
1228: ERR:
1229: printf("timeout trying to write to VIPER\n");
1230: return(BAD);
1231:
1232: } /* write_ID */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.