134514Smarc /*
235355Sbostic * Copyright (c) 1988 Regents of the University of California.
335355Sbostic * All rights reserved.
434514Smarc *
544548Sbostic * %sccs.include.redist.c%
634514Smarc *
7*45803Sbostic * @(#)qdcons.c 7.5 (Berkeley) 12/16/90
835355Sbostic */
935355Sbostic
1035355Sbostic /*
1134514Smarc * derived from: @(#)qdcons.c 4.1 (ULTRIX 11/23/87
1234514Smarc */
1334514Smarc
1434514Smarc /************************************************************************
1534514Smarc *
1634514Smarc * ULTRIX QDSS STANDALONE BOOT DEVICE DRIVER...
1734514Smarc * device driver to boot system with QDSS as console
1834514Smarc *
1934514Smarc *************************************************************************/
2034514Smarc /************************************************************************
2134514Smarc * *
2234514Smarc * Copyright (c) 1985 by *
2334514Smarc * Digital Equipment Corporation, Maynard, MA *
2434514Smarc * All rights reserved. *
2534514Smarc * *
2634514Smarc * This software is furnished under a license and may be used and *
2734514Smarc * copied only in accordance with the terms of such license and *
2834514Smarc * with the inclusion of the above copyright notice. This *
2934514Smarc * software or any other copies thereof may not be provided or *
3034514Smarc * otherwise made available to any other person. No title to and *
3134514Smarc * ownership of the software is hereby transferred. *
3234514Smarc * *
3334514Smarc * The information in this software is subject to change without *
3434514Smarc * notice and should not be construed as a commitment by Digital *
3534514Smarc * Equipment Corporation. *
3634514Smarc * *
3734514Smarc * Digital assumes no responsibility for the use or reliability *
3834514Smarc * of its software on equipment which is not supplied by Digital. *
3934514Smarc * *
4034514Smarc *************************************************************************
4134659Smarc * revision history: (should be moved into sccs comments)
4234514Smarc *************************************************************************
4334514Smarc *
4434514Smarc * 09 oct 85 longo added uVAXII console ROM cursor reset to bottom of
4534514Smarc * the screen. Also spruced up qdputc() & scroll_up()
4634514Smarc * 02 oct 85 longo changed references to ADDRESS to be ADDRESS_COMPLETE
4734514Smarc * 23 aug 85 longo changed I/O page CSR address to be 0x1F00
4834514Smarc * 20 aug 85 longo created
4934514Smarc *
5034514Smarc ************************************************************************/
5134514Smarc
52*45803Sbostic #include "sys/types.h"
53*45803Sbostic #include "../include/cpu.h"
5434514Smarc #define KERNEL
55*45803Sbostic #include "../uba/qdioctl.h"
56*45803Sbostic #include "../uba/qevent.h"
57*45803Sbostic #include "../uba/qduser.h"
58*45803Sbostic #include "../uba/qdreg.h"
5934514Smarc #undef KERNEL
6034514Smarc
6134514Smarc /*-----------------------------------------------------------------------
6234514Smarc * constants used to set VAX ROM's cursor to bottom the of the screen */
6334514Smarc
6434514Smarc #define NVR_ADRS 0x200B8024
6534514Smarc
6634514Smarc #define CURRENT_ROW 0x4C /* these are offsets to the ROM's scratch.. */
6734514Smarc #define ROW_MIN 0x4D /* ..RAM start adrs as picked up out of NVR */
6834514Smarc #define ROW_MAX 0x4E
6934514Smarc #define CURRENT_COL 0x50
7034514Smarc #define COL_MIN 0x51
7134514Smarc #define COL_MAX 0x52
7234514Smarc
7334514Smarc /*----------------------------------------
7434514Smarc * LK201 keyboard state tracking struct */
7534514Smarc
7634514Smarc struct q_keyboard {
7734514Smarc
7834514Smarc int shift; /* state variables */
7934514Smarc int cntrl;
8034514Smarc int lock;
8134514Smarc char last; /* last character */
8234514Smarc
8334514Smarc } q_keyboard;
8434514Smarc
8534514Smarc int qdputc(), qdgetc();
8634514Smarc
8734514Smarc extern (*v_putc)(),(*v_getc)();
8834514Smarc
8934514Smarc /*----------------------------
9034514Smarc * general purpose defines */
9134514Smarc
9234514Smarc #define BAD -1
9334514Smarc #define GOOD 0
9434514Smarc
9534514Smarc /*----------------------------------------------
9634514Smarc * console cursor bitmap (block cursor type) */
9734514Smarc
9834514Smarc short cons_cursor[32] = { /* white block cursor */
9934514Smarc
10034514Smarc /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
10134514Smarc 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
10234514Smarc /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
10334514Smarc 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
10434514Smarc
10534514Smarc };
10634514Smarc
10734514Smarc /*-------------------------------------
10834514Smarc * constants used in font operations */
10934514Smarc
11034514Smarc #define CHARS 95 /* # of chars in the font */
11134514Smarc #define CHAR_HEIGHT 15 /* char height in pixels */
11234514Smarc #define CHAR_WIDTH 8 /* char width in pixels*/
11334514Smarc #define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */
11434514Smarc #define ROWS CHAR_HEIGHT
11534514Smarc
11634514Smarc #define FONT_X 0 /* font's off screen adrs */
11734514Smarc #define FONT_Y (2047 - CHAR_HEIGHT)
11834514Smarc /*
11934514Smarc #define FONT_Y 200
12034514Smarc */
12134514Smarc
12234514Smarc extern char q_font[]; /* reference font object code */
12334514Smarc
12434514Smarc extern char q_key[]; /* reference key xlation tables */
12534514Smarc extern char q_shift_key[];
12634514Smarc extern char *q_special[];
12734514Smarc
12834514Smarc /*----------------------------
12934514Smarc * console cursor structure */
13034514Smarc
13134514Smarc struct cons_cur {
13234514Smarc int x;
13334514Smarc int y;
13434514Smarc } cursor;
13534514Smarc
13634514Smarc /*------------------------------------------
13734514Smarc * MicroVAX-II q-bus addressing constants */
13834514Smarc
13934514Smarc #define QMEMBASE 0x30000000
14034514Smarc #define QDSSCSR 0x20001F00
14134514Smarc
14234514Smarc #define CHUNK (64 * 1024)
14334514Smarc #define QMEMSIZE (1024 * 1024 * 4)
14434514Smarc #define QDBASE (QMEMBASE + QMEMSIZE - CHUNK)
14534514Smarc
14634514Smarc /*------------------------------------------------------------------
14734514Smarc * QDSS register address offsets from start of QDSS address space */
14834514Smarc
14934514Smarc #define QDSIZE (52 * 1024) /* size of entire QDSS foot print */
15034514Smarc
15134514Smarc #define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */
15234514Smarc #define TMPSTART 0x8000 /* offset of template RAM from base adrs */
15334514Smarc
15434514Smarc #define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */
15534514Smarc #define REGSTART 0xC000 /* offset of reg pages from base adrs */
15634514Smarc
15734514Smarc #define ADDER (REGSTART+0x000)
15834514Smarc #define DGA (REGSTART+0x200)
15934514Smarc #define DUART (REGSTART+0x400)
16034514Smarc #define MEMCSR (REGSTART+0x800)
16134514Smarc
16234514Smarc #define CLRSIZE (3 * 512) /* color map size */
16334514Smarc #define CLRSTART (REGSTART+0xA00) /* color map start offset from base */
16434514Smarc /* 0x0C00 really */
16534514Smarc #define RED (CLRSTART+0x000)
16634514Smarc #define BLUE (CLRSTART+0x200)
16734514Smarc #define GREEN (CLRSTART+0x400)
16834514Smarc
16934514Smarc /*---------------------------------------
17034514Smarc * QDSS register address map structure */
17134514Smarc
17234514Smarc struct qdmap qdmap;
17334514Smarc
17434514Smarc /************************************************************************
17534514Smarc *************************************************************************
17634514Smarc *************************************************************************
17734514Smarc *
17834514Smarc * EXTERNALLY CALLED ROUTINES START HERE:
17934514Smarc *
18034514Smarc *************************************************************************
18134514Smarc *************************************************************************
18234514Smarc ************************************************************************/
18334514Smarc
18434514Smarc /************************************************************************
18534514Smarc *
18634514Smarc * qd_init()... init the QDSS into a physical memory system
18734514Smarc *
18834514Smarc ************************************************************************/
18934514Smarc
qd_init()19034514Smarc qd_init()
19134514Smarc {
19234514Smarc register char *ROM_console;
19334514Smarc register short *NVR;
19434514Smarc register int i;
19534514Smarc
19634514Smarc caddr_t qdaddr;
19734514Smarc struct dga *dga;
19835402Stef extern int cpu;
19934514Smarc
20034514Smarc qdaddr = (caddr_t) QDSSCSR;
20134514Smarc if (badaddr(qdaddr, sizeof(short)))
20234514Smarc return(0);
20334514Smarc
20434514Smarc *(short *)qdaddr = (short) (QDBASE >> 16);
20534514Smarc
20634514Smarc /*----------------------------------------------------------------------
20734514Smarc * load qdmap struct with the physical addresses of the QDSS elements */
20834514Smarc
20934514Smarc qdmap.template = (caddr_t) QDBASE + TMPSTART;
21034514Smarc qdmap.adder = (caddr_t) QDBASE + ADDER;
21134514Smarc qdmap.dga = (caddr_t) QDBASE + DGA;
21234514Smarc qdmap.duart = (caddr_t) QDBASE + DUART;
21334514Smarc qdmap.memcsr = (caddr_t) QDBASE + MEMCSR;
21434514Smarc qdmap.red = (caddr_t) QDBASE + RED;
21534514Smarc qdmap.blue = (caddr_t) QDBASE + BLUE;
21634514Smarc qdmap.green = (caddr_t) QDBASE + GREEN;
21734514Smarc
21834514Smarc /*--------------------------
21934514Smarc * no interrupts allowed! */
22034514Smarc
22134514Smarc dga = (struct dga *) qdmap.dga;
22234514Smarc dga->csr = HALT;
22334514Smarc dga->csr |= CURS_ENB;
22434514Smarc
22534514Smarc /*----------------------------
22634514Smarc * init the default values */
22734514Smarc
22834514Smarc q_keyboard.shift = 0; /* init keyboard state tracking */
22934514Smarc q_keyboard.lock = 0;
23034514Smarc q_keyboard.cntrl = 0;
23134514Smarc q_keyboard.last = 0;
23234514Smarc
23334514Smarc cursor.x = 0; /* init cursor to top left */
23434514Smarc cursor.y = 0;
23534514Smarc
23634514Smarc set_defaults(); /* setup the default device */
23734514Smarc ldfont(); /* PtoB the font into off-screen */
23834514Smarc
23934514Smarc /*--------------------------------------------------------------------
24034514Smarc * tell the VAX ROM that the cursor is at the bottom of the screen */
24134514Smarc
24235402Stef if (cpu == VAX_630) {
24335402Stef NVR = (short *) NVR_ADRS;
24434514Smarc
24535402Stef i = *NVR++ & 0xFF;
24635402Stef i |= (*NVR++ & 0xFF) << 8;
24735402Stef i |= (*NVR++ & 0xFF) << 16;
24835402Stef i |= (*NVR++ & 0xFF) << 24;
24934514Smarc
25035402Stef ROM_console = (char *) i;
25134514Smarc
25235402Stef ROM_console[CURRENT_COL] = ROM_console[COL_MIN];
25335402Stef ROM_console[CURRENT_ROW] = ROM_console[ROW_MAX];
25435402Stef }
25534514Smarc
25634514Smarc /*----------------------------------------------------------
25734514Smarc * smash system virtual console service routine addresses */
25834514Smarc
25935402Stef printf("switching console to QDSS display...\n");
26034514Smarc v_getc = qdgetc;
26134514Smarc v_putc = qdputc;
26234514Smarc
26334514Smarc return(1);
26434514Smarc
26534514Smarc } /* qd_init */
26634514Smarc
26734514Smarc /*******************************************************************
26834514Smarc *
26934514Smarc * qdputc()... output a character to the QDSS screen
27034514Smarc *
27134514Smarc ********************************************************************
27234514Smarc *
27334514Smarc * calling convention:
27434514Smarc *
27534514Smarc * qdputc(chr);
27634514Smarc * char chr; ;character to be displayed
27734514Smarc *
27834514Smarc ********/
27934514Smarc
qdputc(chr)28034514Smarc qdputc(chr)
28134514Smarc char chr;
28234514Smarc {
28334514Smarc register struct adder *adder;
28434514Smarc register struct dga *dga;
28534514Smarc register int i;
28634514Smarc
28734514Smarc short x;
28834514Smarc
28934514Smarc adder = (struct adder *) qdmap.adder;
29034514Smarc dga = (struct dga *) qdmap.dga;
29134514Smarc
29234514Smarc /*---------------------------
29334514Smarc * non display character? */
29434514Smarc
29534514Smarc chr &= 0x7F;
29634514Smarc
29734514Smarc switch (chr) {
29834514Smarc
29934514Smarc case '\r': /* return char */
30034514Smarc cursor.x = 0;
30134514Smarc dga->x_cursor = TRANX(cursor.x);
30234514Smarc return(0);
30334514Smarc
30434514Smarc case '\t': /* tab char */
30534514Smarc
30634514Smarc for (i = 8 - ((cursor.x >> 3) & 0x07); i > 0; --i) {
30734514Smarc qdputc(' ');
30834514Smarc }
30934514Smarc return(0);
31034514Smarc
31134514Smarc case '\n': /* line feed char */
31234514Smarc
31334514Smarc if ((cursor.y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) {
31434514Smarc cursor.y -= CHAR_HEIGHT;
31534514Smarc scroll_up(adder);
31634514Smarc }
31734514Smarc dga->y_cursor = TRANY(cursor.y);
31834514Smarc return(0);
31934514Smarc
32034514Smarc case '\b': /* backspace char */
32134514Smarc if (cursor.x > 0) {
32234514Smarc cursor.x -= CHAR_WIDTH;
32334514Smarc qdputc(' ');
32434514Smarc cursor.x -= CHAR_WIDTH;
32534514Smarc dga->x_cursor = TRANX(cursor.x);
32634514Smarc }
32734514Smarc return(0);
32834514Smarc
32934514Smarc default:
33034514Smarc if (chr < ' ' || chr > '~') {
33134514Smarc return(0);
33234514Smarc }
33334514Smarc }
33434514Smarc
33534514Smarc /*------------------------------------------
33634514Smarc * setup VIPER operand control registers */
33734514Smarc
33834514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */
33934514Smarc write_ID(adder, SRC1_OCR_B,
34034514Smarc EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);
34134514Smarc
34234514Smarc write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */
34334514Smarc write_ID(adder, SRC1_OCR_B,
34434514Smarc EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY);
34534514Smarc
34634514Smarc write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */
34734514Smarc write_ID(adder, DST_OCR_B,
34834514Smarc EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
34934514Smarc
35034514Smarc write_ID(adder, MASK_1, 0xFFFF);
35134514Smarc write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1);
35234514Smarc write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
35334514Smarc
35434514Smarc /*----------------------------------------
35534514Smarc * load DESTINATION origin and vectors */
35634514Smarc
35734514Smarc adder->fast_dest_dy = 0;
35834514Smarc adder->slow_dest_dx = 0;
35934514Smarc adder->error_1 = 0;
36034514Smarc adder->error_2 = 0;
36134514Smarc
36234514Smarc adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;
36334514Smarc
36434514Smarc wait_status(adder, RASTEROP_COMPLETE);
36534514Smarc
36634514Smarc adder->destination_x = cursor.x;
36734514Smarc adder->fast_dest_dx = CHAR_WIDTH;
36834514Smarc
36934514Smarc adder->destination_y = cursor.y;
37034514Smarc adder->slow_dest_dy = CHAR_HEIGHT;
37134514Smarc
37234514Smarc /*-----------------------------------
37334514Smarc * load SOURCE origin and vectors */
37434514Smarc
37534514Smarc adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH);
37634514Smarc adder->source_1_y = FONT_Y;
37734514Smarc
37834514Smarc adder->source_1_dx = CHAR_WIDTH;
37934514Smarc adder->source_1_dy = CHAR_HEIGHT;
38034514Smarc
38134514Smarc write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
38234514Smarc adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;
38334514Smarc
38434514Smarc /*-------------------------------------
38534514Smarc * update console cursor coordinates */
38634514Smarc
38734514Smarc cursor.x += CHAR_WIDTH;
38834514Smarc dga->x_cursor = TRANX(cursor.x);
38934514Smarc
39034514Smarc if (cursor.x > (1024 - CHAR_WIDTH)) {
39134514Smarc qdputc('\r');
39234514Smarc qdputc('\n');
39334514Smarc }
39434514Smarc
39534514Smarc } /* qdputc */
39634514Smarc
39734514Smarc /*******************************************************************
39834514Smarc *
39934514Smarc * qdgetc()... get a character from the LK201
40034514Smarc *
40134514Smarc *******************************************************************/
40234514Smarc
qdgetc()40334514Smarc qdgetc()
40434514Smarc {
40534514Smarc register short key;
40634514Smarc register char chr;
40734514Smarc register struct duart *duart;
40834514Smarc
40934514Smarc u_int status;
41034514Smarc
41134514Smarc duart = (struct duart *) qdmap.duart;
41234514Smarc
41334514Smarc /*--------------------------------------
41434514Smarc * Get a character from the keyboard. */
41534514Smarc
41634514Smarc LOOP:
41734514Smarc while (!((status = duart->statusA) & RCV_RDY))
41834514Smarc ;
41934514Smarc
42034514Smarc key = duart->dataA;
42134514Smarc key &= 0xFF;
42234514Smarc
42334514Smarc /*--------------------------------------
42434514Smarc * Check for various keyboard errors */
42534514Smarc
42634514Smarc if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR ||
42734514Smarc key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) {
42834514Smarc printf("Keyboard error, code = %x\n", key);
42934514Smarc return(0);
43034514Smarc }
43134514Smarc
43234514Smarc if (key < LK_LOWEST)
43334514Smarc return(0);
43434514Smarc
43534514Smarc /*---------------------------------
43634514Smarc * See if its a state change key */
43734514Smarc
43834514Smarc switch (key) {
43934514Smarc
44034514Smarc case LOCK:
44134514Smarc q_keyboard.lock ^= 0xffff; /* toggle */
44234514Smarc if (q_keyboard.lock)
44334514Smarc led_control(LK_LED_ENABLE, LK_LED_LOCK);
44434514Smarc else
44534514Smarc led_control(LK_LED_DISABLE, LK_LED_LOCK);
44634514Smarc goto LOOP;
44734514Smarc
44834514Smarc case SHIFT:
44934514Smarc q_keyboard.shift ^= 0xFFFF;
45034514Smarc goto LOOP;
45134514Smarc
45234514Smarc case CNTRL:
45334514Smarc q_keyboard.cntrl ^= 0xFFFF;
45434514Smarc goto LOOP;
45534514Smarc
45634514Smarc case ALLUP:
45734514Smarc q_keyboard.cntrl = 0;
45834514Smarc q_keyboard.shift = 0;
45934514Smarc goto LOOP;
46034514Smarc
46134514Smarc case REPEAT:
46234514Smarc chr = q_keyboard.last;
46334514Smarc break;
46434514Smarc
46534514Smarc /*-------------------------------------------------------
46634514Smarc * Test for cntrl characters. If set, see if the character
46734514Smarc * is elligible to become a control character. */
46834514Smarc
46934514Smarc default:
47034514Smarc
47134514Smarc if (q_keyboard.cntrl) {
47234514Smarc chr = q_key[key];
47334514Smarc if (chr >= ' ' && chr <= '~')
47434514Smarc chr &= 0x1F;
47534514Smarc }
47634514Smarc else if ( q_keyboard.lock || q_keyboard.shift )
47734514Smarc chr = q_shift_key[key];
47834514Smarc else
47934514Smarc chr = q_key[key];
48034514Smarc break;
48134514Smarc }
48234514Smarc
48334514Smarc if (chr < ' ' && chr > '~') /* if input is non-displayable */
48434514Smarc return(0); /* ..then pitch it! */
48534514Smarc
48634514Smarc q_keyboard.last = chr;
48734514Smarc
48834514Smarc /*-----------------------------------
48934514Smarc * Check for special function keys */
49034514Smarc
49134514Smarc if (chr & 0x80) /* pitch the function keys */
49234514Smarc return(0);
49334514Smarc else
49434514Smarc return(chr);
49534514Smarc
49634514Smarc } /* qdgetc */
49734514Smarc
49834514Smarc /************************************************************************
49934514Smarc *************************************************************************
50034514Smarc *************************************************************************
50134514Smarc *
50234514Smarc * INTERNALLY USED ROUTINES START HERE:
50334514Smarc *
50434514Smarc *************************************************************************
50534514Smarc *************************************************************************
50634514Smarc ************************************************************************/
50734514Smarc
50834514Smarc /********************************************************************
50934514Smarc *
51034514Smarc * ldcursor()... load the mouse cursor's template RAM bitmap
51134514Smarc *
51234514Smarc ********************************************************************/
51334514Smarc
ldcursor()51434514Smarc ldcursor()
51534514Smarc {
51634514Smarc register struct dga *dga;
51734514Smarc register short *temp;
51834514Smarc register int i;
51934514Smarc
52034514Smarc int cursor;
52134514Smarc
52234514Smarc dga = (struct dga *) qdmap.dga;
52334514Smarc temp = (short *) qdmap.template;
52434514Smarc
52534514Smarc temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */
52634514Smarc /* ..of the 8k WORD template space */
52734514Smarc for (i = 0; i < 32; ++i)
52834514Smarc *temp++ = cons_cursor[i];
52934514Smarc
53034514Smarc return(0);
53134514Smarc
53234514Smarc } /* ldcursor */
53334514Smarc
53434514Smarc /**********************************************************************
53534514Smarc *
53634514Smarc * ldfont()... put the console font in the QDSS off-screen memory
53734514Smarc *
53834514Smarc **********************************************************************/
53934514Smarc
ldfont()54034514Smarc ldfont()
54134514Smarc {
54234514Smarc register struct adder *adder;
54334514Smarc
54434514Smarc int i; /* scratch variables */
54534514Smarc int j;
54634514Smarc int k;
54734514Smarc short packed;
54834514Smarc
54934514Smarc adder = (struct adder *) qdmap.adder;
55034514Smarc
55134514Smarc /*------------------------------------------
55234514Smarc * setup VIPER operand control registers */
55334514Smarc
55434514Smarc write_ID(adder, MASK_1, 0xFFFF);
55534514Smarc write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
55634514Smarc write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
55734514Smarc
55834514Smarc write_ID(adder, SRC1_OCR_B,
55934514Smarc EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY);
56034514Smarc write_ID(adder, SRC2_OCR_B,
56134514Smarc EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY);
56234514Smarc write_ID(adder, DST_OCR_B,
56334514Smarc EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
56434514Smarc
56534514Smarc adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL;
56634514Smarc
56734514Smarc /*--------------------------
56834514Smarc * load destination data */
56934514Smarc
57034514Smarc wait_status(adder, RASTEROP_COMPLETE);
57134514Smarc
57234514Smarc adder->destination_x = FONT_X;
57334514Smarc adder->destination_y = FONT_Y;
57434514Smarc adder->fast_dest_dx = FONT_WIDTH;
57534514Smarc adder->slow_dest_dy = CHAR_HEIGHT;
57634514Smarc
57734514Smarc /*---------------------------------------
57834514Smarc * setup for processor to bitmap xfer */
57934514Smarc
58034514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0001);
58134514Smarc adder->cmd = PBT | OCRB | 2 | DTE | 2;
58234514Smarc
58334514Smarc /*-----------------------------------------------
58434514Smarc * iteratively do the processor to bitmap xfer */
58534514Smarc
58634514Smarc for (i = 0; i < ROWS; ++i) {
58734514Smarc
58834514Smarc /* PTOB a scan line */
58934514Smarc
59034514Smarc for (j = 0, k = i; j < 48; ++j) {
59134514Smarc
59234514Smarc /* PTOB one scan of a char cell */
59334514Smarc
59434514Smarc packed = q_font[k];
59534514Smarc k += ROWS;
59634514Smarc packed |= ((short)q_font[k] << 8);
59734514Smarc k += ROWS;
59834514Smarc
59934514Smarc wait_status(adder, TX_READY);
60034514Smarc adder->id_data = packed;
60134514Smarc }
60234514Smarc }
60334514Smarc
60434514Smarc } /* ldfont */
60534514Smarc
60634514Smarc /*********************************************************************
60734514Smarc *
60834514Smarc * led_control()... twiddle LK-201 LED's
60934514Smarc *
61034514Smarc **********************************************************************
61134514Smarc *
61234514Smarc * led_control(cmd, led_mask);
61334514Smarc * int cmd; LED enable/disable command
61434514Smarc * int led_mask; which LED(s) to twiddle
61534514Smarc *
61634514Smarc *************/
61734514Smarc
led_control(cmd,led_mask)61834514Smarc led_control(cmd, led_mask)
61934514Smarc int cmd;
62034514Smarc int led_mask;
62134514Smarc {
62234514Smarc register int i;
62334514Smarc register int status;
62434514Smarc register struct duart *duart;
62534514Smarc
62634514Smarc duart = (struct duart *) qdmap.duart;
62734514Smarc
62834514Smarc for (i = 1000; i > 0; --i) {
62934514Smarc if ((status = duart->statusA) & XMT_RDY) {
63034514Smarc duart->dataA = cmd;
63134514Smarc break;
63234514Smarc }
63334514Smarc }
63434514Smarc
63534514Smarc for (i = 1000; i > 0; --i) {
63634514Smarc if ((status = duart->statusA) & XMT_RDY) {
63734514Smarc duart->dataA = led_mask;
63834514Smarc break;
63934514Smarc }
64034514Smarc }
64134514Smarc
64234514Smarc if (i == 0)
64334514Smarc return(BAD);
64434514Smarc
64534514Smarc return(GOOD);
64634514Smarc
64734514Smarc } /* led_control */
64834514Smarc
64934514Smarc /*******************************************************************
65034514Smarc *
65134514Smarc * scroll_up()... move the screen up one character height
65234514Smarc *
65334514Smarc ********************************************************************
65434514Smarc *
65534514Smarc * calling convention:
65634514Smarc *
65734514Smarc * scroll_up(adder);
65834514Smarc * struct adder *adder; ;address of adder
65934514Smarc *
66034514Smarc ********/
66134514Smarc
scroll_up(adder)66234514Smarc scroll_up(adder)
66334514Smarc register struct adder *adder;
66434514Smarc {
66534514Smarc
66634514Smarc /*------------------------------------------
66734514Smarc * setup VIPER operand control registers */
66834514Smarc
66934514Smarc wait_status(adder, ADDRESS_COMPLETE);
67034514Smarc
67134514Smarc write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */
67234514Smarc
67334514Smarc write_ID(adder, MASK_1, 0xFFFF);
67434514Smarc write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
67534514Smarc write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
67634514Smarc
67734514Smarc write_ID(adder, SRC1_OCR_B,
67834514Smarc EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY);
67934514Smarc write_ID(adder, DST_OCR_B,
68034514Smarc EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY);
68134514Smarc
68234514Smarc /*----------------------------------------
68334514Smarc * load DESTINATION origin and vectors */
68434514Smarc
68534514Smarc adder->fast_dest_dy = 0;
68634514Smarc adder->slow_dest_dx = 0;
68734514Smarc adder->error_1 = 0;
68834514Smarc adder->error_2 = 0;
68934514Smarc
69034514Smarc adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL;
69134514Smarc
69234514Smarc adder->destination_x = 0;
69334514Smarc adder->fast_dest_dx = 1024;
69434514Smarc
69534514Smarc adder->destination_y = 0;
69634514Smarc adder->slow_dest_dy = 864 - CHAR_HEIGHT;
69734514Smarc
69834514Smarc /*-----------------------------------
69934514Smarc * load SOURCE origin and vectors */
70034514Smarc
70134514Smarc adder->source_1_x = 0;
70234514Smarc adder->source_1_dx = 1024;
70334514Smarc
70434514Smarc adder->source_1_y = 0 + CHAR_HEIGHT;
70534514Smarc adder->source_1_dy = 864 - CHAR_HEIGHT;
70634514Smarc
70734514Smarc write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
70834514Smarc adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE;
70934514Smarc
71034514Smarc /*--------------------------------------------
71134514Smarc * do a rectangle clear of last screen line */
71234514Smarc
71334514Smarc write_ID(adder, MASK_1, 0xffff);
71434514Smarc write_ID(adder, SOURCE, 0xffff);
71534514Smarc write_ID(adder,DST_OCR_B,
71634514Smarc (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY));
71734514Smarc write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0);
71834514Smarc adder->error_1 = 0;
71934514Smarc adder->error_2 = 0;
72034514Smarc adder->slow_dest_dx = 0; /* set up the width of */
72134514Smarc adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */
72234514Smarc
72334514Smarc adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ;
72434514Smarc wait_status(adder, RASTEROP_COMPLETE);
72534514Smarc adder->destination_x = 0;
72634514Smarc adder->destination_y = 864 - CHAR_HEIGHT;
72734514Smarc
72834514Smarc adder->fast_dest_dx = 1024; /* set up the height */
72934514Smarc adder->fast_dest_dy = 0; /* of rectangle */
73034514Smarc
73134514Smarc write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE));
73234514Smarc adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ;
73334514Smarc
73434514Smarc } /* scroll_up */
73534514Smarc
73634514Smarc /**********************************************************************
73734514Smarc *
73834514Smarc * set_defaults()... init the QDSS device and driver defaults
73934514Smarc *
74034514Smarc **********************************************************************/
74134514Smarc
set_defaults()74234514Smarc set_defaults()
74334514Smarc {
74434514Smarc setup_input(); /* init the DUART */
74534514Smarc setup_dragon(); /* init the ADDER/VIPER stuff */
74634514Smarc ldcursor(); /* load default cursor map */
74734514Smarc
74834514Smarc } /* set_defaults */
74934514Smarc
75034514Smarc /*********************************************************************
75134514Smarc *
75234514Smarc * setup_dragon()... init the ADDER, VIPER, bitmaps, & color map
75334514Smarc *
75434514Smarc *********************************************************************/
75534514Smarc
setup_dragon()75634514Smarc setup_dragon()
75734514Smarc {
75834514Smarc
75934514Smarc register struct adder *adder;
76034514Smarc register struct dga *dga;
76134514Smarc short *memcsr;
76234514Smarc
76334514Smarc int i; /* general purpose variables */
76434514Smarc int status;
76534514Smarc
76634514Smarc short top; /* clipping/scrolling boundaries */
76734514Smarc short bottom;
76834514Smarc short right;
76934514Smarc short left;
77034514Smarc
77134514Smarc short *red; /* color map pointers */
77234514Smarc short *green;
77334514Smarc short *blue;
77434514Smarc
77534514Smarc /*------------------
77634514Smarc * init for setup */
77734514Smarc
77834514Smarc adder = (struct adder *) qdmap.adder;
77934514Smarc dga = (struct dga *) qdmap.dga;
78034514Smarc memcsr = (short *) qdmap.memcsr;
78134514Smarc
78234514Smarc *memcsr = SYNC_ON; /* blank screen and turn off LED's */
78334514Smarc adder->command = CANCEL;
78434514Smarc
78534514Smarc /*----------------------
78634514Smarc * set monitor timing */
78734514Smarc
78834514Smarc adder->x_scan_count_0 = 0x2800;
78934514Smarc adder->x_scan_count_1 = 0x1020;
79034514Smarc adder->x_scan_count_2 = 0x003A;
79134514Smarc adder->x_scan_count_3 = 0x38F0;
79234514Smarc adder->x_scan_count_4 = 0x6128;
79334514Smarc adder->x_scan_count_5 = 0x093A;
79434514Smarc adder->x_scan_count_6 = 0x313C;
79534514Smarc adder->sync_phase_adj = 0x0100;
79634514Smarc adder->x_scan_conf = 0x00C8;
79734514Smarc
79834514Smarc /*---------------------------------------------------------
79934514Smarc * got a bug in secound pass ADDER! lets take care of it */
80034514Smarc
80134514Smarc /* normally, just use the code in the following bug fix code, but to
80234514Smarc * make repeated demos look pretty, load the registers as if there was
80334514Smarc * no bug and then test to see if we are getting sync */
80434514Smarc
80534514Smarc adder->y_scan_count_0 = 0x135F;
80634514Smarc adder->y_scan_count_1 = 0x3363;
80734514Smarc adder->y_scan_count_2 = 0x2366;
80834514Smarc adder->y_scan_count_3 = 0x0388;
80934514Smarc
81034514Smarc /* if no sync, do the bug fix code */
81134514Smarc
81234514Smarc if (wait_status(adder, VSYNC) == BAD) {
81334514Smarc
81434514Smarc /* first load all Y scan registers with very short frame and
81534514Smarc * wait for scroll service. This guarantees at least one SYNC
81634514Smarc * to fix the pass 2 Adder initialization bug (synchronizes
81734514Smarc * XCINCH with DMSEEDH) */
81834514Smarc
81934514Smarc adder->y_scan_count_0 = 0x01;
82034514Smarc adder->y_scan_count_1 = 0x01;
82134514Smarc adder->y_scan_count_2 = 0x01;
82234514Smarc adder->y_scan_count_3 = 0x01;
82334514Smarc
82434514Smarc wait_status(adder, VSYNC); /* delay at least 1 full frame time */
82534514Smarc wait_status(adder, VSYNC);
82634514Smarc
82734514Smarc /* now load the REAL sync values (in reverse order just to
82834514Smarc * be safe. */
82934514Smarc
83034514Smarc adder->y_scan_count_3 = 0x0388;
83134514Smarc adder->y_scan_count_2 = 0x2366;
83234514Smarc adder->y_scan_count_1 = 0x3363;
83334514Smarc adder->y_scan_count_0 = 0x135F;
83434514Smarc }
83534514Smarc
83634514Smarc /*----------------------------
83734514Smarc * zero the index registers */
83834514Smarc
83934514Smarc adder->x_index_pending = 0;
84034514Smarc adder->y_index_pending = 0;
84134514Smarc adder->x_index_new = 0;
84234514Smarc adder->y_index_new = 0;
84334514Smarc adder->x_index_old = 0;
84434514Smarc adder->y_index_old = 0;
84534514Smarc
84634514Smarc adder->pause = 0;
84734514Smarc
84834514Smarc /*----------------------------------------
84934514Smarc * set rasterop mode to normal pen down */
85034514Smarc
85134514Smarc adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL;
85234514Smarc
85334514Smarc /*--------------------------------------------------
85434514Smarc * set the rasterop registers to a default values */
85534514Smarc
85634514Smarc adder->source_1_dx = 1;
85734514Smarc adder->source_1_dy = 1;
85834514Smarc adder->source_1_x = 0;
85934514Smarc adder->source_1_y = 0;
86034514Smarc adder->destination_x = 0;
86134514Smarc adder->destination_y = 0;
86234514Smarc adder->fast_dest_dx = 1;
86334514Smarc adder->fast_dest_dy = 0;
86434514Smarc adder->slow_dest_dx = 0;
86534514Smarc adder->slow_dest_dy = 1;
86634514Smarc adder->error_1 = 0;
86734514Smarc adder->error_2 = 0;
86834514Smarc
86934514Smarc /*------------------------
87034514Smarc * scale factor = unity */
87134514Smarc
87234514Smarc adder->fast_scale = UNITY;
87334514Smarc adder->slow_scale = UNITY;
87434514Smarc
87534514Smarc /*-------------------------------
87634514Smarc * set the source 2 parameters */
87734514Smarc
87834514Smarc adder->source_2_x = 0;
87934514Smarc adder->source_2_y = 0;
88034514Smarc adder->source_2_size = 0x0022;
88134514Smarc
88234514Smarc /*-----------------------------------------------
88334514Smarc * initialize plane addresses for eight vipers */
88434514Smarc
88534514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0001);
88634514Smarc write_ID(adder, PLANE_ADDRESS, 0x0000);
88734514Smarc
88834514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0002);
88934514Smarc write_ID(adder, PLANE_ADDRESS, 0x0001);
89034514Smarc
89134514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0004);
89234514Smarc write_ID(adder, PLANE_ADDRESS, 0x0002);
89334514Smarc
89434514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0008);
89534514Smarc write_ID(adder, PLANE_ADDRESS, 0x0003);
89634514Smarc
89734514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0010);
89834514Smarc write_ID(adder, PLANE_ADDRESS, 0x0004);
89934514Smarc
90034514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0020);
90134514Smarc write_ID(adder, PLANE_ADDRESS, 0x0005);
90234514Smarc
90334514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0040);
90434514Smarc write_ID(adder, PLANE_ADDRESS, 0x0006);
90534514Smarc
90634514Smarc write_ID(adder, CS_UPDATE_MASK, 0x0080);
90734514Smarc write_ID(adder, PLANE_ADDRESS, 0x0007);
90834514Smarc
90934514Smarc /* initialize the external registers. */
91034514Smarc
91134514Smarc write_ID(adder, CS_UPDATE_MASK, 0x00FF);
91234514Smarc write_ID(adder, CS_SCROLL_MASK, 0x00FF);
91334514Smarc
91434514Smarc /* initialize resolution mode */
91534514Smarc
91634514Smarc write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */
91734514Smarc write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */
91834514Smarc
91934514Smarc /* initialize viper registers */
92034514Smarc
92134514Smarc write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP);
92234514Smarc write_ID(adder, SCROLL_FILL, 0x0000);
92334514Smarc
92434514Smarc /*----------------------------------------------------
92534514Smarc * set clipping and scrolling limits to full screen */
92634514Smarc
92734514Smarc for ( i = 1000, adder->status = 0
92834514Smarc ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE)
92934514Smarc ; --i);
93034514Smarc
93134514Smarc if (i == 0)
93234514Smarc printf("timeout trying to setup clipping\n");
93334514Smarc
93434514Smarc top = 0;
93534514Smarc bottom = 2048;
93634514Smarc left = 0;
93734514Smarc right = 1024;
93834514Smarc
93934514Smarc adder->x_clip_min = left;
94034514Smarc adder->x_clip_max = right;
94134514Smarc adder->y_clip_min = top;
94234514Smarc adder->y_clip_max = bottom;
94334514Smarc
94434514Smarc adder->scroll_x_min = left;
94534514Smarc adder->scroll_x_max = right;
94634514Smarc adder->scroll_y_min = top;
94734514Smarc adder->scroll_y_max = bottom;
94834514Smarc
94934514Smarc wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */
95034514Smarc wait_status(adder, VSYNC);
95134514Smarc
95234514Smarc adder->x_index_pending = left;
95334514Smarc adder->y_index_pending = top;
95434514Smarc adder->x_index_new = left;
95534514Smarc adder->y_index_new = top;
95634514Smarc adder->x_index_old = left;
95734514Smarc adder->y_index_old = top;
95834514Smarc
95934514Smarc for ( i = 1000, adder->status = 0
96034514Smarc ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE)
96134514Smarc ; --i);
96234514Smarc
96334514Smarc if (i == 0)
96434514Smarc printf("timeout waiting for ADDRESS_COMPLETE bit\n");
96534514Smarc
96634514Smarc write_ID(adder, LEFT_SCROLL_MASK, 0x0000);
96734514Smarc write_ID(adder, RIGHT_SCROLL_MASK, 0x0000);
96834514Smarc
96934514Smarc /*------------------------------------------------------------
97034514Smarc * set source and the mask register to all ones (ie: white) */
97134514Smarc
97234514Smarc write_ID(adder, SOURCE, 0xFFFF);
97334514Smarc write_ID(adder, MASK_1, 0xFFFF);
97434514Smarc write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255);
97534514Smarc write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0);
97634514Smarc
97734514Smarc /*--------------------------------------------------------------
97834514Smarc * initialize Operand Control Register banks for fill command */
97934514Smarc
98034514Smarc write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT);
98134514Smarc write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT);
98234514Smarc write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT);
98334514Smarc
98434514Smarc write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT);
98534514Smarc write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT);
98634514Smarc write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT);
98734514Smarc
98834514Smarc /*------------------------------------------------------------------
98934514Smarc * init Logic Unit Function registers, (these are just common values,
99034514Smarc * and may be changed as required). */
99134514Smarc
99234514Smarc write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE);
99334514Smarc write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2);
99434514Smarc write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S);
99534514Smarc write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S);
99634514Smarc
99734514Smarc /*----------------------------------------
99834514Smarc * load the color map for black & white */
99934514Smarc
100034514Smarc for ( i = 0, adder->status = 0
100134514Smarc ; i < 10000 && !((status = adder->status) & VSYNC)
100234514Smarc ; ++i);
100334514Smarc
100434514Smarc if (i == 0)
100534514Smarc printf("timeout waiting for VSYNC bit\n");
100634514Smarc
100734514Smarc red = (short *) qdmap.red;
100834514Smarc green = (short *) qdmap.green;
100934514Smarc blue = (short *) qdmap.blue;
101034514Smarc
101134514Smarc *red++ = 0x00; /* black */
101234514Smarc *green++ = 0x00;
101334514Smarc *blue++ = 0x00;
101434514Smarc
101534514Smarc *red-- = 0xFF; /* white */
101634514Smarc *green-- = 0xFF;
101734514Smarc *blue-- = 0xFF;
101834514Smarc
101934514Smarc /*----------------------------------
102034514Smarc * set color map for mouse cursor */
102134514Smarc
102234514Smarc red += 254;
102334514Smarc green += 254;
102434514Smarc blue += 254;
102534514Smarc
102634514Smarc *red++ = 0x00; /* black */
102734514Smarc *green++ = 0x00;
102834514Smarc *blue++ = 0x00;
102934514Smarc
103034514Smarc *red = 0xFF; /* white */
103134514Smarc *green = 0xFF;
103234514Smarc *blue = 0xFF;
103334514Smarc
103434514Smarc /*---------------------------------------------------------------------------
103534514Smarc * clear the bitmap a piece at a time. Since the fast scroll clear only clears
103634514Smarc * the current displayed portion of the bitmap put a temporary value in the y
103734514Smarc * limit register so we can access whole bitmap */
103834514Smarc
103934514Smarc adder->x_limit = 1024;
104034514Smarc adder->y_limit = 2048 - CHAR_HEIGHT;
104134514Smarc adder->y_offset_pending = 0;
104234514Smarc
104334514Smarc wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */
104434514Smarc wait_status(adder, VSYNC);
104534514Smarc
104634514Smarc adder->y_scroll_constant = SCROLL_ERASE;
104734514Smarc
104834514Smarc wait_status(adder, VSYNC);
104934514Smarc wait_status(adder, VSYNC);
105034514Smarc
105134514Smarc adder->y_offset_pending = 864;
105234514Smarc
105334514Smarc wait_status(adder, VSYNC);
105434514Smarc wait_status(adder, VSYNC);
105534514Smarc
105634514Smarc adder->y_scroll_constant = SCROLL_ERASE;
105734514Smarc
105834514Smarc wait_status(adder, VSYNC);
105934514Smarc wait_status(adder, VSYNC);
106034514Smarc
106134514Smarc adder->y_offset_pending = 1728;
106234514Smarc
106334514Smarc wait_status(adder, VSYNC);
106434514Smarc wait_status(adder, VSYNC);
106534514Smarc
106634514Smarc adder->y_scroll_constant = SCROLL_ERASE;
106734514Smarc
106834514Smarc wait_status(adder, VSYNC);
106934514Smarc wait_status(adder, VSYNC);
107034514Smarc
107134514Smarc adder->y_offset_pending = 0; /* back to normal */
107234514Smarc
107334514Smarc wait_status(adder, VSYNC);
107434514Smarc wait_status(adder, VSYNC);
107534514Smarc
107634514Smarc adder->x_limit = MAX_SCREEN_X;
107734514Smarc adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT;
107834514Smarc
107934514Smarc *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */
108034514Smarc return(0);
108134514Smarc
108234514Smarc } /* setup_dragon */
108334514Smarc
108434514Smarc /******************************************************************
108534514Smarc *
108634514Smarc * setup_input()... init the DUART and set defaults in input
108734514Smarc * devices
108834514Smarc *
108934514Smarc ******************************************************************/
109034514Smarc
setup_input()109134514Smarc setup_input()
109234514Smarc {
109334514Smarc register struct duart *duart; /* DUART register structure pointer */
109434514Smarc register int bits;
109534514Smarc int i, j; /* scratch variables */
109634514Smarc
109734514Smarc short status;
109834514Smarc
109934514Smarc /*---------------
110034514Smarc * init stuff */
110134514Smarc
110234514Smarc duart = (struct duart *) qdmap.duart;
110334514Smarc
110434514Smarc /*---------------------------------------------
110534514Smarc * setup the DUART for kbd & pointing device */
110634514Smarc
110734514Smarc duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */
110834514Smarc duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */
110934514Smarc /* no RTS control,char error mode */
111034514Smarc duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */
111134514Smarc /* no RTS control,no echo or loop */
111234514Smarc duart->auxctl = 0x00; /* baud rate set 1 */
111334514Smarc
111434514Smarc duart->clkselA = 0x99; /* 4800 baud for kbd */
111534514Smarc
111634514Smarc /* reset everything for keyboard */
111734514Smarc
111834514Smarc for (bits = RESET_M; bits < START_BREAK; bits += 0x10)
111934514Smarc duart->cmdA = bits;
112034514Smarc
112134514Smarc duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */
112234514Smarc
112334514Smarc /*--------------------------
112434514Smarc * init keyboard defaults */
112534514Smarc /*
112634514Smarc for (i = 500; i > 0; --i) {
112734514Smarc if ((status = duart->statusA) & XMT_RDY) {
112834514Smarc duart->dataA = LK_DEFAULTS;
112934514Smarc break;
113034514Smarc }
113134514Smarc }
113234514Smarc
113334514Smarc for (j = 0; j < 3; ++j) {
113434514Smarc for (i = 50000; i > 0; --i) {
113534514Smarc if ((status = duart->statusA) & RCV_RDY) {
113634514Smarc status = duart->dataA;
113734514Smarc break;
113834514Smarc }
113934514Smarc }
114034514Smarc }
114134514Smarc
114234514Smarc if (i == 0)
114334514Smarc printf("LK-201 init error\n");
114434514Smarc */
114534514Smarc
114634514Smarc /*--------
114734514Smarc * exit */
114834514Smarc
114934514Smarc return(0);
115034514Smarc
115134514Smarc } /* setup_input */
115234514Smarc
115334514Smarc /**********************************************************************
115434514Smarc *
115534514Smarc * wait_status()... delay for at least one display frame time
115634514Smarc *
115734514Smarc ***********************************************************************
115834514Smarc *
115934514Smarc * calling convention:
116034514Smarc *
116134514Smarc * wait_status(adder, mask);
116234514Smarc * struct *adder adder;
116334514Smarc * int mask;
116434514Smarc *
116534514Smarc * return: BAD means that we timed out without ever seeing the
116634514Smarc * vertical sync status bit
116734514Smarc * GOOD otherwise
116834514Smarc *
116934514Smarc **************/
117034514Smarc
wait_status(adder,mask)117134514Smarc wait_status(adder, mask)
117234514Smarc register struct adder *adder;
117334514Smarc register int mask;
117434514Smarc {
117534514Smarc register short status;
117634514Smarc int i;
117734514Smarc
117834514Smarc for ( i = 10000, adder->status = 0
117934514Smarc ; i > 0 && !((status = adder->status) & mask)
118034514Smarc ; --i);
118134514Smarc
118234514Smarc if (i == 0) {
118334514Smarc printf("timeout polling for 0x%x in adder->status\n", mask);
118434514Smarc return(BAD);
118534514Smarc }
118634514Smarc
118734514Smarc return(GOOD);
118834514Smarc
118934514Smarc } /* wait_status */
119034514Smarc
119134514Smarc /**********************************************************************
119234514Smarc *
119334514Smarc * write_ID()... write out onto the ID bus
119434514Smarc *
119534514Smarc ***********************************************************************
119634514Smarc *
119734514Smarc * calling convention:
119834514Smarc *
119934514Smarc * struct *adder adder; ;pntr to ADDER structure
120034514Smarc * short adrs; ;VIPER address
120134514Smarc * short data; ;data to be written
120234514Smarc * write_ID(adder);
120334514Smarc *
120434514Smarc * return: BAD means that we timed out waiting for status bits
120534514Smarc * VIPER-access-specific status bits
120634514Smarc * GOOD otherwise
120734514Smarc *
120834514Smarc **************/
120934514Smarc
write_ID(adder,adrs,data)121034514Smarc write_ID(adder, adrs, data)
121134514Smarc register struct adder *adder;
121234514Smarc register short adrs;
121334514Smarc register short data;
121434514Smarc {
121534514Smarc int i;
121634514Smarc short status;
121734514Smarc
121834514Smarc for ( i = 100000, adder->status = 0
121934514Smarc ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE)
122034514Smarc ; --i);
122134514Smarc
122234514Smarc if (i == 0)
122334514Smarc goto ERR;
122434514Smarc
122534514Smarc for ( i = 100000, adder->status = 0
122634514Smarc ; i > 0 && !((status = adder->status) & TX_READY)
122734514Smarc ; --i);
122834514Smarc
122934514Smarc if (i > 0) {
123034514Smarc adder->id_data = data;
123134514Smarc adder->command = ID_LOAD | adrs;
123234514Smarc return(GOOD);
123334514Smarc }
123434514Smarc
123534514Smarc ERR:
123634514Smarc printf("timeout trying to write to VIPER\n");
123734514Smarc return(BAD);
123834514Smarc
123934514Smarc } /* write_ID */
1240