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