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