home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (c) 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)qdcons.c 7.5 (Berkeley) 12/16/90
- */
-
- /*
- * 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: (should be 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 "sys/types.h"
- #include "../include/cpu.h"
- #define KERNEL
- #include "../uba/qdioctl.h"
- #include "../uba/qevent.h"
- #include "../uba/qduser.h"
- #include "../uba/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;
- extern int cpu;
-
- 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 */
-
- if (cpu == VAX_630) {
- 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 */
-
- printf("switching console to QDSS display...\n");
- 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 */
-