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