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