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