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