From: Marc Teitelbaum Date: Sat, 28 May 1988 05:56:43 +0000 (-0800) Subject: date and time created 88/05/27 14:56:43 by marc X-Git-Tag: BSD-4_3_Net_1-Snapshot-Development~1660 X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/commitdiff_plain/2e73d67497d45dfd92c9dc03da0da669d9ecd7d1 date and time created 88/05/27 14:56:43 by marc SCCS-vsn: sys/vax/stand/qdcons.c 1.1 --- diff --git a/usr/src/sys/vax/stand/qdcons.c b/usr/src/sys/vax/stand/qdcons.c new file mode 100644 index 0000000000..c14e896ba1 --- /dev/null +++ b/usr/src/sys/vax/stand/qdcons.c @@ -0,0 +1,1232 @@ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * @(#)qdcons.c 1.1 Berkeley %G% + * + * derived from: @(#)qdcons.c 4.1 (ULTRIX 11/23/87 + */ + +/************************************************************************ +* +* ULTRIX QDSS STANDALONE BOOT DEVICE DRIVER... +* device driver to boot system with QDSS as console +* +*************************************************************************/ +/************************************************************************ +* * +* Copyright (c) 1985 by * +* Digital Equipment Corporation, Maynard, MA * +* All rights reserved. * +* * +* This software is furnished under a license and may be used and * +* copied only in accordance with the terms of such license and * +* with the inclusion of the above copyright notice. This * +* software or any other copies thereof may not be provided or * +* otherwise made available to any other person. No title to and * +* ownership of the software is hereby transferred. * +* * +* The information in this software is subject to change without * +* notice and should not be construed as a commitment by Digital * +* Equipment Corporation. * +* * +* Digital assumes no responsibility for the use or reliability * +* of its software on equipment which is not supplied by Digital. * +* * +************************************************************************* +* revision history: (moved into sccs comments) +************************************************************************* +* +* 09 oct 85 longo added uVAXII console ROM cursor reset to bottom of +* the screen. Also spruced up qdputc() & scroll_up() +* 02 oct 85 longo changed references to ADDRESS to be ADDRESS_COMPLETE +* 23 aug 85 longo changed I/O page CSR address to be 0x1F00 +* 20 aug 85 longo created +* +************************************************************************/ + +#include "../h/types.h" +#include "../vax/cpu.h" +#define KERNEL +#include "../ultrix/qdioctl.h" +#include "../ultrix/qevent.h" +#include "../ultrix/qduser.h" +#include "../ultrix/qdreg.h" +#undef KERNEL + +/*----------------------------------------------------------------------- +* constants used to set VAX ROM's cursor to bottom the of the screen */ + +#define NVR_ADRS 0x200B8024 + +#define CURRENT_ROW 0x4C /* these are offsets to the ROM's scratch.. */ +#define ROW_MIN 0x4D /* ..RAM start adrs as picked up out of NVR */ +#define ROW_MAX 0x4E +#define CURRENT_COL 0x50 +#define COL_MIN 0x51 +#define COL_MAX 0x52 + +/*---------------------------------------- +* LK201 keyboard state tracking struct */ + + struct q_keyboard { + + int shift; /* state variables */ + int cntrl; + int lock; + char last; /* last character */ + + } q_keyboard; + + int qdputc(), qdgetc(); + + extern (*v_putc)(),(*v_getc)(); + +/*---------------------------- +* general purpose defines */ + +#define BAD -1 +#define GOOD 0 + +/*---------------------------------------------- +* console cursor bitmap (block cursor type) */ + + short cons_cursor[32] = { /* white block cursor */ + + /* A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, + 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, + /* B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, + 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF + + }; + +/*------------------------------------- +* constants used in font operations */ + +#define CHARS 95 /* # of chars in the font */ +#define CHAR_HEIGHT 15 /* char height in pixels */ +#define CHAR_WIDTH 8 /* char width in pixels*/ +#define FONT_WIDTH (CHAR_WIDTH * CHARS) /* font width in pixels */ +#define ROWS CHAR_HEIGHT + +#define FONT_X 0 /* font's off screen adrs */ +#define FONT_Y (2047 - CHAR_HEIGHT) +/* +#define FONT_Y 200 +*/ + + extern char q_font[]; /* reference font object code */ + + extern char q_key[]; /* reference key xlation tables */ + extern char q_shift_key[]; + extern char *q_special[]; + +/*---------------------------- +* console cursor structure */ + + struct cons_cur { + int x; + int y; + } cursor; + +/*------------------------------------------ +* MicroVAX-II q-bus addressing constants */ + +#define QMEMBASE 0x30000000 +#define QDSSCSR 0x20001F00 + +#define CHUNK (64 * 1024) +#define QMEMSIZE (1024 * 1024 * 4) +#define QDBASE (QMEMBASE + QMEMSIZE - CHUNK) + +/*------------------------------------------------------------------ +* QDSS register address offsets from start of QDSS address space */ + +#define QDSIZE (52 * 1024) /* size of entire QDSS foot print */ + +#define TMPSIZE (16 * 1024) /* template RAM is 8k SHORT WORDS */ +#define TMPSTART 0x8000 /* offset of template RAM from base adrs */ + +#define REGSIZE (5 * 512) /* regs touch 2.5k (5 pages) of addr space */ +#define REGSTART 0xC000 /* offset of reg pages from base adrs */ + +#define ADDER (REGSTART+0x000) +#define DGA (REGSTART+0x200) +#define DUART (REGSTART+0x400) +#define MEMCSR (REGSTART+0x800) + +#define CLRSIZE (3 * 512) /* color map size */ +#define CLRSTART (REGSTART+0xA00) /* color map start offset from base */ + /* 0x0C00 really */ +#define RED (CLRSTART+0x000) +#define BLUE (CLRSTART+0x200) +#define GREEN (CLRSTART+0x400) + +/*--------------------------------------- +* QDSS register address map structure */ + + struct qdmap qdmap; + +/************************************************************************ +************************************************************************* +************************************************************************* +* +* EXTERNALLY CALLED ROUTINES START HERE: +* +************************************************************************* +************************************************************************* +************************************************************************/ + +/************************************************************************ +* +* qd_init()... init the QDSS into a physical memory system +* +************************************************************************/ + +qd_init() +{ + register char *ROM_console; + register short *NVR; + register int i; + + caddr_t qdaddr; + struct dga *dga; + + qdaddr = (caddr_t) QDSSCSR; + if (badaddr(qdaddr, sizeof(short))) + return(0); + + *(short *)qdaddr = (short) (QDBASE >> 16); + +/*---------------------------------------------------------------------- +* load qdmap struct with the physical addresses of the QDSS elements */ + + qdmap.template = (caddr_t) QDBASE + TMPSTART; + qdmap.adder = (caddr_t) QDBASE + ADDER; + qdmap.dga = (caddr_t) QDBASE + DGA; + qdmap.duart = (caddr_t) QDBASE + DUART; + qdmap.memcsr = (caddr_t) QDBASE + MEMCSR; + qdmap.red = (caddr_t) QDBASE + RED; + qdmap.blue = (caddr_t) QDBASE + BLUE; + qdmap.green = (caddr_t) QDBASE + GREEN; + +/*-------------------------- +* no interrupts allowed! */ + + dga = (struct dga *) qdmap.dga; + dga->csr = HALT; + dga->csr |= CURS_ENB; + +/*---------------------------- +* init the default values */ + + q_keyboard.shift = 0; /* init keyboard state tracking */ + q_keyboard.lock = 0; + q_keyboard.cntrl = 0; + q_keyboard.last = 0; + + cursor.x = 0; /* init cursor to top left */ + cursor.y = 0; + + set_defaults(); /* setup the default device */ + ldfont(); /* PtoB the font into off-screen */ + +/*-------------------------------------------------------------------- +* tell the VAX ROM that the cursor is at the bottom of the screen */ + + NVR = (short *) NVR_ADRS; + + i = *NVR++ & 0xFF; + i |= (*NVR++ & 0xFF) << 8; + i |= (*NVR++ & 0xFF) << 16; + i |= (*NVR++ & 0xFF) << 24; + + ROM_console = (char *) i; + + ROM_console[CURRENT_COL] = ROM_console[COL_MIN]; + ROM_console[CURRENT_ROW] = ROM_console[ROW_MAX]; + +/*---------------------------------------------------------- +* smash system virtual console service routine addresses */ + + v_getc = qdgetc; + v_putc = qdputc; + + return(1); + +} /* qd_init */ + +/******************************************************************* +* +* qdputc()... output a character to the QDSS screen +* +******************************************************************** +* +* calling convention: +* +* qdputc(chr); +* char chr; ;character to be displayed +* +********/ + +qdputc(chr) +char chr; +{ + register struct adder *adder; + register struct dga *dga; + register int i; + + short x; + + adder = (struct adder *) qdmap.adder; + dga = (struct dga *) qdmap.dga; + +/*--------------------------- +* non display character? */ + + chr &= 0x7F; + + switch (chr) { + + case '\r': /* return char */ + cursor.x = 0; + dga->x_cursor = TRANX(cursor.x); + return(0); + + case '\t': /* tab char */ + + for (i = 8 - ((cursor.x >> 3) & 0x07); i > 0; --i) { + qdputc(' '); + } + return(0); + + case '\n': /* line feed char */ + + if ((cursor.y += CHAR_HEIGHT) > (863 - CHAR_HEIGHT)) { + cursor.y -= CHAR_HEIGHT; + scroll_up(adder); + } + dga->y_cursor = TRANY(cursor.y); + return(0); + + case '\b': /* backspace char */ + if (cursor.x > 0) { + cursor.x -= CHAR_WIDTH; + qdputc(' '); + cursor.x -= CHAR_WIDTH; + dga->x_cursor = TRANX(cursor.x); + } + return(0); + + default: + if (chr < ' ' || chr > '~') { + return(0); + } + } + +/*------------------------------------------ +* setup VIPER operand control registers */ + + write_ID(adder, CS_UPDATE_MASK, 0x0001); /* select plane #0 */ + write_ID(adder, SRC1_OCR_B, + EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); + + write_ID(adder, CS_UPDATE_MASK, 0x00FE); /* select other planes */ + write_ID(adder, SRC1_OCR_B, + EXT_SOURCE | INT_NONE | NO_ID | BAR_SHIFT_DELAY); + + write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ + write_ID(adder, DST_OCR_B, + EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); + + write_ID(adder, MASK_1, 0xFFFF); + write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 1); + write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); + +/*---------------------------------------- +* load DESTINATION origin and vectors */ + + adder->fast_dest_dy = 0; + adder->slow_dest_dx = 0; + adder->error_1 = 0; + adder->error_2 = 0; + + adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; + + wait_status(adder, RASTEROP_COMPLETE); + + adder->destination_x = cursor.x; + adder->fast_dest_dx = CHAR_WIDTH; + + adder->destination_y = cursor.y; + adder->slow_dest_dy = CHAR_HEIGHT; + +/*----------------------------------- +* load SOURCE origin and vectors */ + + adder->source_1_x = FONT_X + ((chr - ' ') * CHAR_WIDTH); + adder->source_1_y = FONT_Y; + + adder->source_1_dx = CHAR_WIDTH; + adder->source_1_dy = CHAR_HEIGHT; + + write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); + adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; + +/*------------------------------------- +* update console cursor coordinates */ + + cursor.x += CHAR_WIDTH; + dga->x_cursor = TRANX(cursor.x); + + if (cursor.x > (1024 - CHAR_WIDTH)) { + qdputc('\r'); + qdputc('\n'); + } + +} /* qdputc */ + +/******************************************************************* +* +* qdgetc()... get a character from the LK201 +* +*******************************************************************/ + +qdgetc() +{ + register short key; + register char chr; + register struct duart *duart; + + u_int status; + + duart = (struct duart *) qdmap.duart; + + /*-------------------------------------- + * Get a character from the keyboard. */ + +LOOP: + while (!((status = duart->statusA) & RCV_RDY)) + ; + + key = duart->dataA; + key &= 0xFF; + + /*-------------------------------------- + * Check for various keyboard errors */ + + if( key == LK_POWER_ERROR || key == LK_KDOWN_ERROR || + key == LK_INPUT_ERROR || key == LK_OUTPUT_ERROR) { + printf("Keyboard error, code = %x\n", key); + return(0); + } + + if (key < LK_LOWEST) + return(0); + + /*--------------------------------- + * See if its a state change key */ + + switch (key) { + + case LOCK: + q_keyboard.lock ^= 0xffff; /* toggle */ + if (q_keyboard.lock) + led_control(LK_LED_ENABLE, LK_LED_LOCK); + else + led_control(LK_LED_DISABLE, LK_LED_LOCK); + goto LOOP; + + case SHIFT: + q_keyboard.shift ^= 0xFFFF; + goto LOOP; + + case CNTRL: + q_keyboard.cntrl ^= 0xFFFF; + goto LOOP; + + case ALLUP: + q_keyboard.cntrl = 0; + q_keyboard.shift = 0; + goto LOOP; + + case REPEAT: + chr = q_keyboard.last; + break; + + /*------------------------------------------------------- + * Test for cntrl characters. If set, see if the character + * is elligible to become a control character. */ + + default: + + if (q_keyboard.cntrl) { + chr = q_key[key]; + if (chr >= ' ' && chr <= '~') + chr &= 0x1F; + } + else if ( q_keyboard.lock || q_keyboard.shift ) + chr = q_shift_key[key]; + else + chr = q_key[key]; + break; + } + + if (chr < ' ' && chr > '~') /* if input is non-displayable */ + return(0); /* ..then pitch it! */ + + q_keyboard.last = chr; + + /*----------------------------------- + * Check for special function keys */ + + if (chr & 0x80) /* pitch the function keys */ + return(0); + else + return(chr); + +} /* qdgetc */ + +/************************************************************************ +************************************************************************* +************************************************************************* +* +* INTERNALLY USED ROUTINES START HERE: +* +************************************************************************* +************************************************************************* +************************************************************************/ + +/******************************************************************** +* +* ldcursor()... load the mouse cursor's template RAM bitmap +* +********************************************************************/ + +ldcursor() +{ + register struct dga *dga; + register short *temp; + register int i; + + int cursor; + + dga = (struct dga *) qdmap.dga; + temp = (short *) qdmap.template; + + temp += (8 * 1024) - 32; /* cursor is 32 WORDS from the end */ + /* ..of the 8k WORD template space */ + for (i = 0; i < 32; ++i) + *temp++ = cons_cursor[i]; + + return(0); + +} /* ldcursor */ + +/********************************************************************** +* +* ldfont()... put the console font in the QDSS off-screen memory +* +**********************************************************************/ + +ldfont() +{ + register struct adder *adder; + + int i; /* scratch variables */ + int j; + int k; + short packed; + + adder = (struct adder *) qdmap.adder; + +/*------------------------------------------ +* setup VIPER operand control registers */ + + write_ID(adder, MASK_1, 0xFFFF); + write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); + write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); + + write_ID(adder, SRC1_OCR_B, + EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); + write_ID(adder, SRC2_OCR_B, + EXT_NONE | INT_NONE | ID | BAR_SHIFT_DELAY); + write_ID(adder, DST_OCR_B, + EXT_SOURCE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); + + adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; + +/*-------------------------- +* load destination data */ + + wait_status(adder, RASTEROP_COMPLETE); + + adder->destination_x = FONT_X; + adder->destination_y = FONT_Y; + adder->fast_dest_dx = FONT_WIDTH; + adder->slow_dest_dy = CHAR_HEIGHT; + +/*--------------------------------------- +* setup for processor to bitmap xfer */ + + write_ID(adder, CS_UPDATE_MASK, 0x0001); + adder->cmd = PBT | OCRB | 2 | DTE | 2; + +/*----------------------------------------------- +* iteratively do the processor to bitmap xfer */ + + for (i = 0; i < ROWS; ++i) { + + /* PTOB a scan line */ + + for (j = 0, k = i; j < 48; ++j) { + + /* PTOB one scan of a char cell */ + + packed = q_font[k]; + k += ROWS; + packed |= ((short)q_font[k] << 8); + k += ROWS; + + wait_status(adder, TX_READY); + adder->id_data = packed; + } + } + +} /* ldfont */ + +/********************************************************************* +* +* led_control()... twiddle LK-201 LED's +* +********************************************************************** +* +* led_control(cmd, led_mask); +* int cmd; LED enable/disable command +* int led_mask; which LED(s) to twiddle +* +*************/ + +led_control(cmd, led_mask) +int cmd; +int led_mask; +{ + register int i; + register int status; + register struct duart *duart; + + duart = (struct duart *) qdmap.duart; + + for (i = 1000; i > 0; --i) { + if ((status = duart->statusA) & XMT_RDY) { + duart->dataA = cmd; + break; + } + } + + for (i = 1000; i > 0; --i) { + if ((status = duart->statusA) & XMT_RDY) { + duart->dataA = led_mask; + break; + } + } + + if (i == 0) + return(BAD); + + return(GOOD); + +} /* led_control */ + +/******************************************************************* +* +* scroll_up()... move the screen up one character height +* +******************************************************************** +* +* calling convention: +* +* scroll_up(adder); +* struct adder *adder; ;address of adder +* +********/ + +scroll_up(adder) +register struct adder *adder; +{ + +/*------------------------------------------ +* setup VIPER operand control registers */ + + wait_status(adder, ADDRESS_COMPLETE); + + write_ID(adder, CS_UPDATE_MASK, 0x00FF); /* select all planes */ + + write_ID(adder, MASK_1, 0xFFFF); + write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); + write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); + + write_ID(adder, SRC1_OCR_B, + EXT_NONE | INT_SOURCE | ID | BAR_SHIFT_DELAY); + write_ID(adder, DST_OCR_B, + EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY); + +/*---------------------------------------- +* load DESTINATION origin and vectors */ + + adder->fast_dest_dy = 0; + adder->slow_dest_dx = 0; + adder->error_1 = 0; + adder->error_2 = 0; + + adder->rasterop_mode = DST_WRITE_ENABLE | NORMAL; + + adder->destination_x = 0; + adder->fast_dest_dx = 1024; + + adder->destination_y = 0; + adder->slow_dest_dy = 864 - CHAR_HEIGHT; + +/*----------------------------------- +* load SOURCE origin and vectors */ + + adder->source_1_x = 0; + adder->source_1_dx = 1024; + + adder->source_1_y = 0 + CHAR_HEIGHT; + adder->source_1_dy = 864 - CHAR_HEIGHT; + + write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); + adder->cmd = RASTEROP | OCRB | 0 | S1E | DTE; + +/*-------------------------------------------- +* do a rectangle clear of last screen line */ + + write_ID(adder, MASK_1, 0xffff); + write_ID(adder, SOURCE, 0xffff); + write_ID(adder,DST_OCR_B, + (EXT_NONE | INT_NONE | NO_ID | NO_BAR_SHIFT_DELAY)); + write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 0); + adder->error_1 = 0; + adder->error_2 = 0; + adder->slow_dest_dx = 0; /* set up the width of */ + adder->slow_dest_dy = CHAR_HEIGHT; /* rectangle */ + + adder->rasterop_mode = (NORMAL | DST_WRITE_ENABLE) ; + wait_status(adder, RASTEROP_COMPLETE); + adder->destination_x = 0; + adder->destination_y = 864 - CHAR_HEIGHT; + + adder->fast_dest_dx = 1024; /* set up the height */ + adder->fast_dest_dy = 0; /* of rectangle */ + + write_ID(adder, LU_FUNCTION_R2, (FULL_SRC_RESOLUTION | LF_SOURCE)); + adder->cmd = (RASTEROP | OCRB | LF_R2 | DTE ) ; + +} /* scroll_up */ + +/********************************************************************** +* +* set_defaults()... init the QDSS device and driver defaults +* +**********************************************************************/ + +set_defaults() +{ + setup_input(); /* init the DUART */ + setup_dragon(); /* init the ADDER/VIPER stuff */ + ldcursor(); /* load default cursor map */ + +} /* set_defaults */ + +/********************************************************************* +* +* setup_dragon()... init the ADDER, VIPER, bitmaps, & color map +* +*********************************************************************/ + +setup_dragon() +{ + + register struct adder *adder; + register struct dga *dga; + short *memcsr; + + int i; /* general purpose variables */ + int status; + + short top; /* clipping/scrolling boundaries */ + short bottom; + short right; + short left; + + short *red; /* color map pointers */ + short *green; + short *blue; + +/*------------------ +* init for setup */ + + adder = (struct adder *) qdmap.adder; + dga = (struct dga *) qdmap.dga; + memcsr = (short *) qdmap.memcsr; + + *memcsr = SYNC_ON; /* blank screen and turn off LED's */ + adder->command = CANCEL; + +/*---------------------- +* set monitor timing */ + + adder->x_scan_count_0 = 0x2800; + adder->x_scan_count_1 = 0x1020; + adder->x_scan_count_2 = 0x003A; + adder->x_scan_count_3 = 0x38F0; + adder->x_scan_count_4 = 0x6128; + adder->x_scan_count_5 = 0x093A; + adder->x_scan_count_6 = 0x313C; + adder->sync_phase_adj = 0x0100; + adder->x_scan_conf = 0x00C8; + +/*--------------------------------------------------------- +* got a bug in secound pass ADDER! lets take care of it */ + + /* normally, just use the code in the following bug fix code, but to + * make repeated demos look pretty, load the registers as if there was + * no bug and then test to see if we are getting sync */ + + adder->y_scan_count_0 = 0x135F; + adder->y_scan_count_1 = 0x3363; + adder->y_scan_count_2 = 0x2366; + adder->y_scan_count_3 = 0x0388; + + /* if no sync, do the bug fix code */ + + if (wait_status(adder, VSYNC) == BAD) { + + /* first load all Y scan registers with very short frame and + * wait for scroll service. This guarantees at least one SYNC + * to fix the pass 2 Adder initialization bug (synchronizes + * XCINCH with DMSEEDH) */ + + adder->y_scan_count_0 = 0x01; + adder->y_scan_count_1 = 0x01; + adder->y_scan_count_2 = 0x01; + adder->y_scan_count_3 = 0x01; + + wait_status(adder, VSYNC); /* delay at least 1 full frame time */ + wait_status(adder, VSYNC); + + /* now load the REAL sync values (in reverse order just to + * be safe. */ + + adder->y_scan_count_3 = 0x0388; + adder->y_scan_count_2 = 0x2366; + adder->y_scan_count_1 = 0x3363; + adder->y_scan_count_0 = 0x135F; + } + +/*---------------------------- +* zero the index registers */ + + adder->x_index_pending = 0; + adder->y_index_pending = 0; + adder->x_index_new = 0; + adder->y_index_new = 0; + adder->x_index_old = 0; + adder->y_index_old = 0; + + adder->pause = 0; + +/*---------------------------------------- +* set rasterop mode to normal pen down */ + + adder->rasterop_mode = DST_WRITE_ENABLE | DST_INDEX_ENABLE | NORMAL; + +/*-------------------------------------------------- +* set the rasterop registers to a default values */ + + adder->source_1_dx = 1; + adder->source_1_dy = 1; + adder->source_1_x = 0; + adder->source_1_y = 0; + adder->destination_x = 0; + adder->destination_y = 0; + adder->fast_dest_dx = 1; + adder->fast_dest_dy = 0; + adder->slow_dest_dx = 0; + adder->slow_dest_dy = 1; + adder->error_1 = 0; + adder->error_2 = 0; + +/*------------------------ +* scale factor = unity */ + + adder->fast_scale = UNITY; + adder->slow_scale = UNITY; + +/*------------------------------- +* set the source 2 parameters */ + + adder->source_2_x = 0; + adder->source_2_y = 0; + adder->source_2_size = 0x0022; + +/*----------------------------------------------- +* initialize plane addresses for eight vipers */ + + write_ID(adder, CS_UPDATE_MASK, 0x0001); + write_ID(adder, PLANE_ADDRESS, 0x0000); + + write_ID(adder, CS_UPDATE_MASK, 0x0002); + write_ID(adder, PLANE_ADDRESS, 0x0001); + + write_ID(adder, CS_UPDATE_MASK, 0x0004); + write_ID(adder, PLANE_ADDRESS, 0x0002); + + write_ID(adder, CS_UPDATE_MASK, 0x0008); + write_ID(adder, PLANE_ADDRESS, 0x0003); + + write_ID(adder, CS_UPDATE_MASK, 0x0010); + write_ID(adder, PLANE_ADDRESS, 0x0004); + + write_ID(adder, CS_UPDATE_MASK, 0x0020); + write_ID(adder, PLANE_ADDRESS, 0x0005); + + write_ID(adder, CS_UPDATE_MASK, 0x0040); + write_ID(adder, PLANE_ADDRESS, 0x0006); + + write_ID(adder, CS_UPDATE_MASK, 0x0080); + write_ID(adder, PLANE_ADDRESS, 0x0007); + + /* initialize the external registers. */ + + write_ID(adder, CS_UPDATE_MASK, 0x00FF); + write_ID(adder, CS_SCROLL_MASK, 0x00FF); + + /* initialize resolution mode */ + + write_ID(adder, MEMORY_BUS_WIDTH, 0x000C); /* bus width = 16 */ + write_ID(adder, RESOLUTION_MODE, 0x0000); /* one bit/pixel */ + + /* initialize viper registers */ + + write_ID(adder, SCROLL_CONSTANT, SCROLL_ENABLE|VIPER_LEFT|VIPER_UP); + write_ID(adder, SCROLL_FILL, 0x0000); + +/*---------------------------------------------------- +* set clipping and scrolling limits to full screen */ + + for ( i = 1000, adder->status = 0 + ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) + ; --i); + + if (i == 0) + printf("timeout trying to setup clipping\n"); + + top = 0; + bottom = 2048; + left = 0; + right = 1024; + + adder->x_clip_min = left; + adder->x_clip_max = right; + adder->y_clip_min = top; + adder->y_clip_max = bottom; + + adder->scroll_x_min = left; + adder->scroll_x_max = right; + adder->scroll_y_min = top; + adder->scroll_y_max = bottom; + + wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ + wait_status(adder, VSYNC); + + adder->x_index_pending = left; + adder->y_index_pending = top; + adder->x_index_new = left; + adder->y_index_new = top; + adder->x_index_old = left; + adder->y_index_old = top; + + for ( i = 1000, adder->status = 0 + ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) + ; --i); + + if (i == 0) + printf("timeout waiting for ADDRESS_COMPLETE bit\n"); + + write_ID(adder, LEFT_SCROLL_MASK, 0x0000); + write_ID(adder, RIGHT_SCROLL_MASK, 0x0000); + +/*------------------------------------------------------------ +* set source and the mask register to all ones (ie: white) */ + + write_ID(adder, SOURCE, 0xFFFF); + write_ID(adder, MASK_1, 0xFFFF); + write_ID(adder, VIPER_Z_LOAD | FOREGROUND_COLOR_Z, 255); + write_ID(adder, VIPER_Z_LOAD | BACKGROUND_COLOR_Z, 0); + +/*-------------------------------------------------------------- +* initialize Operand Control Register banks for fill command */ + + write_ID(adder, SRC1_OCR_A, EXT_NONE | INT_M1_M2 | NO_ID | WAIT); + write_ID(adder, SRC2_OCR_A, EXT_NONE | INT_SOURCE | NO_ID | NO_WAIT); + write_ID(adder, DST_OCR_A, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); + + write_ID(adder, SRC1_OCR_B, EXT_NONE | INT_SOURCE | NO_ID | WAIT); + write_ID(adder, SRC2_OCR_B, EXT_NONE | INT_M1_M2 | NO_ID | NO_WAIT); + write_ID(adder, DST_OCR_B, EXT_NONE | INT_NONE | NO_ID | NO_WAIT); + +/*------------------------------------------------------------------ +* init Logic Unit Function registers, (these are just common values, +* and may be changed as required). */ + + write_ID(adder, LU_FUNCTION_R1, FULL_SRC_RESOLUTION | LF_SOURCE); + write_ID(adder, LU_FUNCTION_R2, FULL_SRC_RESOLUTION | LF_SOURCE | INV_M1_M2); + write_ID(adder, LU_FUNCTION_R3, FULL_SRC_RESOLUTION | LF_D_OR_S); + write_ID(adder, LU_FUNCTION_R4, FULL_SRC_RESOLUTION | LF_D_XOR_S); + +/*---------------------------------------- +* load the color map for black & white */ + + for ( i = 0, adder->status = 0 + ; i < 10000 && !((status = adder->status) & VSYNC) + ; ++i); + + if (i == 0) + printf("timeout waiting for VSYNC bit\n"); + + red = (short *) qdmap.red; + green = (short *) qdmap.green; + blue = (short *) qdmap.blue; + + *red++ = 0x00; /* black */ + *green++ = 0x00; + *blue++ = 0x00; + + *red-- = 0xFF; /* white */ + *green-- = 0xFF; + *blue-- = 0xFF; + + /*---------------------------------- + * set color map for mouse cursor */ + + red += 254; + green += 254; + blue += 254; + + *red++ = 0x00; /* black */ + *green++ = 0x00; + *blue++ = 0x00; + + *red = 0xFF; /* white */ + *green = 0xFF; + *blue = 0xFF; + +/*--------------------------------------------------------------------------- +* clear the bitmap a piece at a time. Since the fast scroll clear only clears +* the current displayed portion of the bitmap put a temporary value in the y +* limit register so we can access whole bitmap */ + + adder->x_limit = 1024; + adder->y_limit = 2048 - CHAR_HEIGHT; + adder->y_offset_pending = 0; + + wait_status(adder, VSYNC); /* wait at LEAST 1 full frame */ + wait_status(adder, VSYNC); + + adder->y_scroll_constant = SCROLL_ERASE; + + wait_status(adder, VSYNC); + wait_status(adder, VSYNC); + + adder->y_offset_pending = 864; + + wait_status(adder, VSYNC); + wait_status(adder, VSYNC); + + adder->y_scroll_constant = SCROLL_ERASE; + + wait_status(adder, VSYNC); + wait_status(adder, VSYNC); + + adder->y_offset_pending = 1728; + + wait_status(adder, VSYNC); + wait_status(adder, VSYNC); + + adder->y_scroll_constant = SCROLL_ERASE; + + wait_status(adder, VSYNC); + wait_status(adder, VSYNC); + + adder->y_offset_pending = 0; /* back to normal */ + + wait_status(adder, VSYNC); + wait_status(adder, VSYNC); + + adder->x_limit = MAX_SCREEN_X; + adder->y_limit = MAX_SCREEN_Y + FONT_HEIGHT; + + *memcsr = SYNC_ON | UNBLANK; /* turn off leds and turn on video */ + return(0); + +} /* setup_dragon */ + +/****************************************************************** +* +* setup_input()... init the DUART and set defaults in input +* devices +* +******************************************************************/ + +setup_input() +{ + register struct duart *duart; /* DUART register structure pointer */ + register int bits; + int i, j; /* scratch variables */ + + short status; + +/*--------------- +* init stuff */ + + duart = (struct duart *) qdmap.duart; + +/*--------------------------------------------- +* setup the DUART for kbd & pointing device */ + + duart->cmdA = RESET_M; /* reset mode reg ptr for kbd */ + duart->modeA = 0x13; /* 8 bits, no parity, rcv IE, */ + /* no RTS control,char error mode */ + duart->modeA = 0x07; /* 1 stop bit,CTS does not IE XMT */ + /* no RTS control,no echo or loop */ + duart->auxctl = 0x00; /* baud rate set 1 */ + + duart->clkselA = 0x99; /* 4800 baud for kbd */ + + /* reset everything for keyboard */ + + for (bits = RESET_M; bits < START_BREAK; bits += 0x10) + duart->cmdA = bits; + + duart->cmdA = EN_RCV | EN_XMT; /* enbl xmt & rcv for kbd */ + +/*-------------------------- +* init keyboard defaults */ +/* + for (i = 500; i > 0; --i) { + if ((status = duart->statusA) & XMT_RDY) { + duart->dataA = LK_DEFAULTS; + break; + } + } + + for (j = 0; j < 3; ++j) { + for (i = 50000; i > 0; --i) { + if ((status = duart->statusA) & RCV_RDY) { + status = duart->dataA; + break; + } + } + } + + if (i == 0) + printf("LK-201 init error\n"); +*/ + +/*-------- +* exit */ + + return(0); + +} /* setup_input */ + +/********************************************************************** +* +* wait_status()... delay for at least one display frame time +* +*********************************************************************** +* +* calling convention: +* +* wait_status(adder, mask); +* struct *adder adder; +* int mask; +* +* return: BAD means that we timed out without ever seeing the +* vertical sync status bit +* GOOD otherwise +* +**************/ + +wait_status(adder, mask) +register struct adder *adder; +register int mask; +{ + register short status; + int i; + + for ( i = 10000, adder->status = 0 + ; i > 0 && !((status = adder->status) & mask) + ; --i); + + if (i == 0) { + printf("timeout polling for 0x%x in adder->status\n", mask); + return(BAD); + } + + return(GOOD); + +} /* wait_status */ + +/********************************************************************** +* +* write_ID()... write out onto the ID bus +* +*********************************************************************** +* +* calling convention: +* +* struct *adder adder; ;pntr to ADDER structure +* short adrs; ;VIPER address +* short data; ;data to be written +* write_ID(adder); +* +* return: BAD means that we timed out waiting for status bits +* VIPER-access-specific status bits +* GOOD otherwise +* +**************/ + +write_ID(adder, adrs, data) +register struct adder *adder; +register short adrs; +register short data; +{ + int i; + short status; + + for ( i = 100000, adder->status = 0 + ; i > 0 && !((status = adder->status) & ADDRESS_COMPLETE) + ; --i); + + if (i == 0) + goto ERR; + + for ( i = 100000, adder->status = 0 + ; i > 0 && !((status = adder->status) & TX_READY) + ; --i); + + if (i > 0) { + adder->id_data = data; + adder->command = ID_LOAD | adrs; + return(GOOD); + } + +ERR: + printf("timeout trying to write to VIPER\n"); + return(BAD); + +} /* write_ID */