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