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