1 /* $NetBSD: grf_rh.c,v 1.4 1994/12/01 17:25:04 chopps Exp $ */ 2 3 #include "grfrh.h" 4 #if NGRFRH > 0 5 6 /* 7 * Graphics routines for the Retina BLT Z3 board, 8 * using the NCR 77C32BLT VGA controller. 9 */ 10 11 #include <sys/param.h> 12 #include <sys/errno.h> 13 #include <sys/ioctl.h> 14 #include <sys/device.h> 15 #include <sys/malloc.h> 16 #include <machine/cpu.h> 17 #include <amiga/amiga/device.h> 18 #include <amiga/dev/grfioctl.h> 19 #include <amiga/dev/grfvar.h> 20 #include <amiga/dev/grf_rhreg.h> 21 #include <amiga/dev/zthreebusvar.h> 22 23 int rh_mondefok __P((struct MonDef *)); 24 25 u_short CompFQ __P((u_int fq)); 26 int rh_load_mon __P((struct grf_softc *gp, struct MonDef *md)); 27 int rh_getvmode __P((struct grf_softc *gp, struct grfvideo_mode *vm)); 28 int rh_setvmode __P((struct grf_softc *gp, unsigned int mode, int txtonly)); 29 30 31 extern unsigned char kernel_font_8x8_width, kernel_font_8x8_height; 32 extern unsigned char kernel_font_8x8_lo, kernel_font_8x8_hi; 33 extern unsigned char kernel_font_8x8[]; 34 #ifdef KFONT_8X11 35 extern unsigned char kernel_font_8x11_width, kernel_font_8x11_height; 36 extern unsigned char kernel_font_8x11_lo, kernel_font_8x11_hi; 37 extern unsigned char kernel_font_8x11[]; 38 #endif 39 40 41 /* 42 * NOTE: this driver for the MacroSystem Retina board was only possible, 43 * because MacroSystem provided information about the pecularities 44 * of the board. THANKS! Competition in Europe among gfx board 45 * manufacturers is rather tough, so Lutz Vieweg, who wrote the 46 * initial driver, has made an agreement with MS not to document 47 * the driver source (see also his Copyright disclaimer below). 48 * -> ALL comments after 49 * -> "/* -------------- START OF CODE -------------- * /" 50 * -> have been added by myself (mw) from studying the publically 51 * -> available "NCR 77C32BLT" Data Manual 52 * 53 * Lutz' original driver source (without any of my comments) is 54 * available on request. 55 */ 56 57 /* This code offers low-level routines to access the Retina BLT Z3 58 * graphics-board manufactured by MS MacroSystem GmbH from within NetBSD 59 * for the Amiga. * No warranties for any kind of function at all - this 60 * code may crash your hardware and scratch your harddisk. Use at your 61 * own risk. Freely distributable. 62 * 63 * Written by Lutz Vieweg 02/94 64 * 65 * Thanks to MacroSystem for providing me with the neccessary information 66 * to create theese routines. The sparse documentation of this code 67 * results from the agreements between MS and me. 68 */ 69 70 71 72 #define MDF_DBL 1 73 #define MDF_LACE 2 74 #define MDF_CLKDIV2 4 75 76 77 /* -------------- START OF CODE -------------- */ 78 79 /* Convert big-endian long into little-endian long. */ 80 81 #define M2I(val) \ 82 asm volatile (" rorw #8,%0 ; \ 83 swap %0 ; \ 84 rorw #8,%0 ; " : "=d" (val) : "0" (val)); 85 86 #define M2INS(val) \ 87 asm volatile (" rorw #8,%0 ; \ 88 swap %0 ; \ 89 rorw #8,%0 ; \ 90 swap %0 ; " : "=d" (val) : "0" (val)); 91 92 #define ACM_OFFSET (0x00b00000) 93 #define LM_OFFSET (0x00c00000) 94 95 static unsigned char optab[] = { 96 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 97 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 98 }; 99 static char optabs[] = { 100 0, -1, -1, -1, -1, 0, -1, -1, 101 -1, -1, 0, -1, -1, -1, -1, 0 102 }; 103 104 void 105 RZ3DisableHWC(gp) 106 struct grf_softc *gp; 107 { 108 volatile void *ba = gp->g_regkva; 109 110 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, 0x00); 111 } 112 113 void 114 RZ3SetupHWC(gp, col1, col2, hsx, hsy, data) 115 struct grf_softc *gp; 116 unsigned char col1; 117 unsigned col2; 118 unsigned char hsx; 119 unsigned char hsy; 120 const unsigned long *data; 121 { 122 volatile unsigned char *ba = gp->g_regkva; 123 unsigned long *c = (unsigned long *)(ba + LM_OFFSET + HWC_MEM_OFF); 124 const unsigned long *s = data; 125 struct MonDef *MonitorDef = (struct MonDef *) gp->g_data; 126 short x = (HWC_MEM_SIZE / (4*4)) - 1; 127 /* copy only, if there is a data pointer. */ 128 if (data) do { 129 *c++ = *s++; 130 *c++ = *s++; 131 *c++ = *s++; 132 *c++ = *s++; 133 } while (x-- > 0); 134 135 WSeq(ba, SEQ_ID_CURSOR_COLOR1, col1); 136 WSeq(ba, SEQ_ID_CURSOR_COLOR0, col2); 137 if (MonitorDef->DEP < 16) 138 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x85); 139 else 140 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xa5); 141 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, 0x00); 142 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, 0x00); 143 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, 0x00); 144 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, 0x00); 145 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, hsx); 146 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, hsy); 147 WSeq(ba, SEQ_ID_CURSOR_STORE_HI, 0x00); 148 WSeq(ba, SEQ_ID_CURSOR_STORE_LO, ((HWC_MEM_OFF / 4) & 0x0000f)); 149 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_HI, (((HWC_MEM_OFF / 4) & 0xff000) >> 12)); 150 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_LO, (((HWC_MEM_OFF / 4) & 0x00ff0) >> 4)); 151 WSeq(ba, SEQ_ID_CURSOR_PIXELMASK, 0xff); 152 } 153 154 void 155 RZ3AlphaErase (gp, xd, yd, w, h) 156 struct grf_softc *gp; 157 unsigned short xd; 158 unsigned short yd; 159 unsigned short w; 160 unsigned short h; 161 { 162 const struct MonDef * md = (struct MonDef *) gp->g_data; 163 RZ3AlphaCopy(gp, xd, yd+md->TY, xd, yd, w, h); 164 } 165 166 void 167 RZ3AlphaCopy (gp, xs, ys, xd, yd, w, h) 168 struct grf_softc *gp; 169 unsigned short xs; 170 unsigned short ys; 171 unsigned short xd; 172 unsigned short yd; 173 unsigned short w; 174 unsigned short h; 175 { 176 volatile unsigned char *ba = gp->g_regkva; 177 const struct MonDef *md = (struct MonDef *) gp->g_data; 178 volatile unsigned long *acm = (unsigned long *) (ba + ACM_OFFSET); 179 unsigned short mod; 180 181 xs *= 4; 182 ys *= 4; 183 xd *= 4; 184 yd *= 4; 185 w *= 4; 186 187 { 188 /* anyone got Windoze GDI opcodes handy?... */ 189 unsigned long tmp = 0x0000ca00; 190 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 191 } 192 193 mod = 0xc0c2; 194 195 { 196 unsigned long pat = 8 * PAT_MEM_OFF; 197 unsigned long dst = 8 * (xd + yd * md->TX); 198 199 unsigned long src = 8 * (xs + ys * md->TX); 200 201 if (xd > xs) { 202 mod &= ~0x8000; 203 src += 8 * (w - 1); 204 dst += 8 * (w - 1); 205 pat += 8 * 2; 206 } 207 if (yd > ys) { 208 mod &= ~0x4000; 209 src += 8 * (h - 1) * md->TX * 4; 210 dst += 8 * (h - 1) * md->TX * 4; 211 pat += 8 * 4; 212 } 213 214 M2I(src); 215 *(acm + ACM_SOURCE/4) = src; 216 217 M2I(pat); 218 *(acm + ACM_PATTERN/4) = pat; 219 220 M2I(dst); 221 *(acm + ACM_DESTINATION/4) = dst; 222 } 223 { 224 225 unsigned long tmp = mod << 16; 226 *(acm + ACM_CONTROL/4) = tmp; 227 } 228 { 229 230 unsigned long tmp = w | (h << 16); 231 M2I(tmp); 232 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 233 } 234 235 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 236 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 237 238 while ((*(((volatile unsigned char *)acm) + 239 (ACM_START_STATUS + 2)) & 1) == 0); 240 } 241 242 void 243 RZ3BitBlit (gp, gbb) 244 struct grf_softc *gp; 245 struct grf_bitblt * gbb; 246 { 247 volatile unsigned char *ba = gp->g_regkva; 248 volatile unsigned char *lm = ba + LM_OFFSET; 249 volatile unsigned long *acm = (unsigned long *) (ba + ACM_OFFSET); 250 const struct MonDef *md = (struct MonDef *) gp->g_data; 251 unsigned short mod; 252 253 { 254 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF); 255 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16); 256 *pt++ = tmp; 257 *pt = tmp; 258 } 259 260 { 261 262 unsigned long tmp = optab[ gbb->op ] << 8; 263 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 264 } 265 266 mod = 0xc0c2; 267 268 { 269 unsigned long pat = 8 * PAT_MEM_OFF; 270 unsigned long dst = 8 * (gbb->dst_x + gbb->dst_y * md->TX); 271 272 if (optabs[gbb->op]) { 273 unsigned long src = 8 * (gbb->src_x + gbb->src_y * md->TX); 274 275 if (gbb->dst_x > gbb->src_x) { 276 mod &= ~0x8000; 277 src += 8 * (gbb->w - 1); 278 dst += 8 * (gbb->w - 1); 279 pat += 8 * 2; 280 } 281 if (gbb->dst_y > gbb->src_y) { 282 mod &= ~0x4000; 283 src += 8 * (gbb->h - 1) * md->TX; 284 dst += 8 * (gbb->h - 1) * md->TX; 285 pat += 8 * 4; 286 } 287 288 M2I(src); 289 *(acm + ACM_SOURCE/4) = src; 290 } 291 292 M2I(pat); 293 *(acm + ACM_PATTERN/4) = pat; 294 295 M2I(dst); 296 *(acm + ACM_DESTINATION/4) = dst; 297 } 298 { 299 300 unsigned long tmp = mod << 16; 301 *(acm + ACM_CONTROL/4) = tmp; 302 } 303 { 304 unsigned long tmp = gbb->w | (gbb->h << 16); 305 M2I(tmp); 306 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 307 } 308 309 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 310 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 311 312 while ((*(((volatile unsigned char *)acm) + 313 (ACM_START_STATUS + 2)) & 1) == 0); 314 } 315 316 void 317 RZ3BitBlit16 (gp, gbb) 318 struct grf_softc *gp; 319 struct grf_bitblt * gbb; 320 { 321 volatile unsigned char *ba = gp->g_regkva; 322 volatile unsigned char *lm = ba + LM_OFFSET; 323 volatile unsigned long * acm = (unsigned long *) (ba + ACM_OFFSET); 324 const struct MonDef * md = (struct MonDef *) gp->g_data; 325 unsigned short mod; 326 327 { 328 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF); 329 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16); 330 *pt++ = tmp; 331 *pt++ = tmp; 332 *pt++ = tmp; 333 *pt = tmp; 334 } 335 336 { 337 338 unsigned long tmp = optab[ gbb->op ] << 8; 339 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 340 } 341 342 mod = 0xc0c2; 343 344 { 345 unsigned long pat = 8 * PAT_MEM_OFF; 346 unsigned long dst = 8 * 2 * (gbb->dst_x + gbb->dst_y * md->TX); 347 348 if (optabs[gbb->op]) { 349 unsigned long src = 8 * 2 * (gbb->src_x + gbb->src_y * md->TX); 350 351 if (gbb->dst_x > gbb->src_x) { 352 mod &= ~0x8000; 353 src += 8 * 2 * (gbb->w); 354 dst += 8 * 2 * (gbb->w); 355 pat += 8 * 2 * 2; 356 } 357 if (gbb->dst_y > gbb->src_y) { 358 mod &= ~0x4000; 359 src += 8 * 2 * (gbb->h - 1) * md->TX; 360 dst += 8 * 2 * (gbb->h - 1) * md->TX; 361 pat += 8 * 4 * 2; 362 } 363 364 M2I(src); 365 *(acm + ACM_SOURCE/4) = src; 366 } 367 368 M2I(pat); 369 *(acm + ACM_PATTERN/4) = pat; 370 371 M2I(dst); 372 *(acm + ACM_DESTINATION/4) = dst; 373 } 374 { 375 376 unsigned long tmp = mod << 16; 377 *(acm + ACM_CONTROL/4) = tmp; 378 } 379 { 380 381 unsigned long tmp = gbb->w | (gbb->h << 16); 382 M2I(tmp); 383 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 384 } 385 386 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 387 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 388 389 while ((*(((volatile unsigned char *)acm) + 390 (ACM_START_STATUS+ 2)) & 1) == 0); 391 } 392 393 void 394 RZ3SetCursorPos (gp, pos) 395 struct grf_softc *gp; 396 unsigned short pos; 397 { 398 volatile unsigned char *ba = gp->g_regkva; 399 400 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, (unsigned char)pos); 401 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (unsigned char)(pos >> 8)); 402 403 } 404 405 void 406 RZ3LoadPalette (gp, pal, firstcol, colors) 407 struct grf_softc *gp; 408 unsigned char * pal; 409 unsigned char firstcol; 410 unsigned char colors; 411 { 412 volatile unsigned char *ba = gp->g_regkva; 413 414 if (colors == 0) 415 return; 416 417 vgaw(ba, VDAC_ADDRESS_W, firstcol); 418 419 { 420 421 short x = colors-1; 422 const unsigned char * col = pal; 423 do { 424 425 vgaw(ba, VDAC_DATA, (*col++ >> 2)); 426 vgaw(ba, VDAC_DATA, (*col++ >> 2)); 427 vgaw(ba, VDAC_DATA, (*col++ >> 2)); 428 429 } while (x-- > 0); 430 431 } 432 } 433 434 void 435 RZ3SetPalette (gp, colornum, red, green, blue) 436 struct grf_softc *gp; 437 unsigned char colornum; 438 unsigned char red, green, blue; 439 { 440 volatile unsigned char *ba = gp->g_regkva; 441 442 vgaw(ba, VDAC_ADDRESS_W, colornum); 443 444 vgaw(ba, VDAC_DATA, (red >> 2)); 445 vgaw(ba, VDAC_DATA, (green >> 2)); 446 vgaw(ba, VDAC_DATA, (blue >> 2)); 447 448 } 449 450 /* XXXXXXXXX !! */ 451 static unsigned short xpan; 452 static unsigned short ypan; 453 454 void 455 RZ3SetPanning (gp, xoff, yoff) 456 struct grf_softc *gp; 457 unsigned short xoff, yoff; 458 { 459 volatile unsigned char *ba = gp->g_regkva; 460 const struct MonDef * md = (struct MonDef *) gp->g_data; 461 unsigned long off; 462 463 xpan = xoff; 464 ypan = yoff; 465 466 467 if (md->DEP > 8) 468 xoff *= 2; 469 470 vgar(ba, ACT_ADDRESS_RESET); 471 WAttr(ba, ACT_ID_HOR_PEL_PANNING, (unsigned char)((xoff << 1) & 0x07)); 472 /* have the color lookup function normally again */ 473 vgaw(ba, ACT_ADDRESS_W, 0x20); 474 475 if (md->DEP == 8) 476 off = ((yoff * md->TX)/ 4) + (xoff >> 2); 477 else 478 off = ((yoff * md->TX * 2)/ 4) + (xoff >> 2); 479 480 WCrt(ba, CRT_ID_START_ADDR_LOW, ((unsigned char)off)); 481 482 off >>= 8; 483 484 WCrt(ba, CRT_ID_START_ADDR_HIGH, ((unsigned char)off)); 485 486 off >>= 8; 487 488 WCrt(ba, CRT_ID_EXT_START_ADDR, 489 ((RCrt(ba, CRT_ID_EXT_START_ADDR) & 0xf0) | (off & 0x0f))); 490 491 492 } 493 494 void 495 RZ3SetHWCloc (gp, x, y) 496 struct grf_softc *gp; 497 unsigned short x, y; 498 { 499 volatile unsigned char *ba = gp->g_regkva; 500 const struct MonDef *md = (struct MonDef *) gp->g_data; 501 volatile unsigned char *acm = ba + ACM_OFFSET; 502 503 if (x < xpan) 504 RZ3SetPanning(gp, x, ypan); 505 506 if (x >= (xpan+md->MW)) 507 RZ3SetPanning(gp, (1 + x - md->MW) , ypan); 508 509 if (y < ypan) 510 RZ3SetPanning(gp, xpan, y); 511 512 if (y >= (ypan+md->MH)) 513 RZ3SetPanning(gp, xpan, (1 + y - md->MH)); 514 515 x -= xpan; 516 y -= ypan; 517 518 *(acm + (ACM_CURSOR_POSITION+0)) = x & 0xff; 519 *(acm + (ACM_CURSOR_POSITION+1)) = x >> 8; 520 *(acm + (ACM_CURSOR_POSITION+2)) = y & 0xff; 521 *(acm + (ACM_CURSOR_POSITION+3)) = y >> 8; 522 } 523 524 u_short 525 CompFQ(fq) 526 u_int fq; 527 { 528 /* yuck... this sure could need some explanation.. */ 529 530 unsigned long f = fq; 531 long n2 = 3; 532 long abw = 0x7fffffff; 533 long n1 = 3; 534 unsigned long m; 535 unsigned short erg = 0; 536 537 f *= 8; 538 539 do { 540 541 if (f <= 250000000) 542 break; 543 f /= 2; 544 545 } while (n2-- > 0); 546 547 if (n2 < 0) 548 return(0); 549 550 551 do { 552 long tmp; 553 554 f = fq; 555 f >>= 3; 556 f <<= n2; 557 f >>= 7; 558 559 m = (f * n1) / (14318180/1024); 560 561 if (m > 129) 562 break; 563 564 tmp = (((m * 14318180) >> n2) / n1) - fq; 565 if (tmp < 0) 566 tmp = -tmp; 567 568 if (tmp < abw) { 569 abw = tmp; 570 erg = (((n2 << 5) | (n1-2)) << 8) | (m-2); 571 } 572 573 } while ( (++n1) <= 21); 574 575 return(erg); 576 } 577 578 int 579 rh_mondefok(mdp) 580 struct MonDef *mdp; 581 { 582 switch(mdp->DEP) { 583 case 8: 584 case 16: 585 return(1); 586 case 4: 587 if (mdp->FX == 4 || (mdp->FX >= 7 && mdp->FX <= 16)) 588 return(1); 589 /*FALLTHROUGH*/ 590 default: 591 return(0); 592 } 593 } 594 595 596 int 597 rh_load_mon(gp, md) 598 struct grf_softc *gp; 599 struct MonDef *md; 600 { 601 struct grfinfo *gi = &gp->g_display; 602 volatile unsigned char *ba; 603 volatile unsigned char *fb; 604 short FW, clksel, HDE, VDE; 605 unsigned short *c, z; 606 const unsigned char *f; 607 608 ba = gp->g_regkva;; 609 fb = gp->g_fbkva; 610 611 /* provide all needed information in grf device-independant 612 * locations */ 613 gp->g_data = (caddr_t) md; 614 gi->gd_regaddr = (caddr_t) kvtop (ba); 615 gi->gd_regsize = LM_OFFSET; 616 gi->gd_fbaddr = (caddr_t) kvtop (fb); 617 gi->gd_fbsize = MEMSIZE *1024*1024; 618 #ifdef BANKEDDEVPAGER 619 /* we're not using banks NO MORE! */ 620 gi->gd_bank_size = 0; 621 #endif 622 gi->gd_colors = 1 << md->DEP; 623 gi->gd_planes = md->DEP; 624 625 if (md->DEP == 4) { 626 gi->gd_fbwidth = md->MW; 627 gi->gd_fbheight = md->MH; 628 gi->gd_fbx = 0; 629 gi->gd_fby = 0; 630 gi->gd_dwidth = md->TX * md->FX; 631 gi->gd_dheight = md->TY * md->FY; 632 gi->gd_dx = 0; 633 gi->gd_dy = 0; 634 } else { 635 gi->gd_fbwidth = md->TX; 636 gi->gd_fbheight = md->TY; 637 gi->gd_fbx = 0; 638 gi->gd_fby = 0; 639 gi->gd_dwidth = md->MW; 640 gi->gd_dheight = md->MH; 641 gi->gd_dx = 0; 642 gi->gd_dy = 0; 643 } 644 645 FW =0; 646 if (md->DEP == 4) { /* XXX some text-mode! */ 647 switch (md->FX) { 648 case 4: 649 FW = 0; 650 break; 651 case 7: 652 FW = 1; 653 break; 654 case 8: 655 FW = 2; 656 break; 657 case 9: 658 FW = 3; 659 break; 660 case 10: 661 FW = 4; 662 break; 663 case 11: 664 FW = 5; 665 break; 666 case 12: 667 FW = 6; 668 break; 669 case 13: 670 FW = 7; 671 break; 672 case 14: 673 FW = 8; 674 break; 675 case 15: 676 FW = 9; 677 break; 678 case 16: 679 FW = 11; 680 break; 681 default: 682 return(0); 683 break; 684 } 685 } 686 687 if (md->DEP == 4) 688 HDE = (md->MW+md->FX-1)/md->FX; 689 else if (md->DEP == 8) 690 HDE = (md->MW+3)/4; 691 else if (md->DEP == 16) 692 HDE = (md->MW*2+3)/4; 693 694 VDE = md->MH-1; 695 696 clksel = 0; 697 698 vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04)); 699 vgaw(ba, GREG_FEATURE_CONTROL_W, 0x00); 700 701 WSeq(ba, SEQ_ID_RESET, 0x00); 702 WSeq(ba, SEQ_ID_RESET, 0x03); 703 WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8)); 704 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 705 WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00); 706 WSeq(ba, SEQ_ID_MEMORY_MODE, 0x06); 707 WSeq(ba, SEQ_ID_RESET, 0x01); 708 WSeq(ba, SEQ_ID_RESET, 0x03); 709 710 WSeq(ba, SEQ_ID_EXTENDED_ENABLE, 0x05); 711 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x00); 712 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00); 713 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00); 714 WSeq(ba, SEQ_ID_LINEAR_0, 0x4a); 715 WSeq(ba, SEQ_ID_LINEAR_1, 0x00); 716 717 WSeq(ba, SEQ_ID_SEC_HOST_OFF_HI, 0x00); 718 WSeq(ba, SEQ_ID_SEC_HOST_OFF_LO, 0x00); 719 WSeq(ba, SEQ_ID_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); 720 WSeq(ba, SEQ_ID_EXT_CLOCK_MODE, 0x10 | (FW & 0x0f)); 721 WSeq(ba, SEQ_ID_EXT_VIDEO_ADDR, 0x03); 722 if (md->DEP == 4) { 723 /* 8bit pixel, no gfx byte path */ 724 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x00); 725 } else if (md->DEP == 8) { 726 /* 8bit pixel, gfx byte path */ 727 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x01); 728 } else if (md->DEP == 16) { 729 /* 16bit pixel, gfx byte path */ 730 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x11); 731 } 732 WSeq(ba, SEQ_ID_BUS_WIDTH_FEEDB, 0x04); 733 WSeq(ba, SEQ_ID_COLOR_EXP_WFG, 0x01); 734 WSeq(ba, SEQ_ID_COLOR_EXP_WBG, 0x00); 735 WSeq(ba, SEQ_ID_EXT_RW_CONTROL, 0x00); 736 WSeq(ba, SEQ_ID_MISC_FEATURE_SEL, (0x51 | (clksel & 8))); 737 WSeq(ba, SEQ_ID_COLOR_KEY_CNTL, 0x40); 738 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH0, 0x00); 739 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH1, 0x00); 740 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH2, 0x00); 741 WSeq(ba, SEQ_ID_CRC_CONTROL, 0x00); 742 WSeq(ba, SEQ_ID_PERF_SELECT, 0x10); 743 WSeq(ba, SEQ_ID_ACM_APERTURE_1, 0x00); 744 WSeq(ba, SEQ_ID_ACM_APERTURE_2, 0x30); 745 WSeq(ba, SEQ_ID_ACM_APERTURE_3, 0x00); 746 WSeq(ba, SEQ_ID_MEMORY_MAP_CNTL, 0x07); 747 748 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x20); 749 WCrt(ba, CRT_ID_HOR_TOTAL, md->HT & 0xff); 750 WCrt(ba, CRT_ID_HOR_DISP_ENA_END, (HDE-1) & 0xff); 751 WCrt(ba, CRT_ID_START_HOR_BLANK, md->HBS & 0xff); 752 WCrt(ba, CRT_ID_END_HOR_BLANK, (md->HBE & 0x1f) | 0x80); 753 754 WCrt(ba, CRT_ID_START_HOR_RETR, md->HSS & 0xff); 755 WCrt(ba, CRT_ID_END_HOR_RETR, 756 (md->HSE & 0x1f) | 757 ((md->HBE & 0x20)/ 0x20 * 0x80)); 758 WCrt(ba, CRT_ID_VER_TOTAL, (md->VT & 0xff)); 759 WCrt(ba, CRT_ID_OVERFLOW, 760 ((md->VSS & 0x200) / 0x200 * 0x80) | 761 ((VDE & 0x200) / 0x200 * 0x40) | 762 ((md->VT & 0x200) / 0x200 * 0x20) | 763 0x10 | 764 ((md->VBS & 0x100) / 0x100 * 8) | 765 ((md->VSS & 0x100) / 0x100 * 4) | 766 ((VDE & 0x100) / 0x100 * 2) | 767 ((md->VT & 0x100) / 0x100)); 768 WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00); 769 770 if (md->DEP == 4) { 771 WCrt(ba, CRT_ID_MAX_SCAN_LINE, 772 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) | 773 0x40 | 774 ((md->VBS & 0x200)/0x200*0x20) | 775 ((md->FY-1) & 0x1f)); 776 } else { 777 WCrt(ba, CRT_ID_MAX_SCAN_LINE, 778 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) | 779 0x40 | 780 ((md->VBS & 0x200)/0x200*0x20) | 781 (0 & 0x1f)); 782 } 783 784 /* I prefer "_" cursor to "block" cursor.. */ 785 #if 1 786 WCrt(ba, CRT_ID_CURSOR_START, (md->FY & 0x1f) - 2); 787 WCrt(ba, CRT_ID_CURSOR_END, (md->FY & 0x1f) - 1); 788 #else 789 WCrt(ba, CRT_ID_CURSOR_START, 0x00); 790 WCrt(ba, CRT_ID_CURSOR_END, md->FY & 0x1f); 791 #endif 792 793 WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00); 794 WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00); 795 796 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00); 797 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00); 798 799 WCrt(ba, CRT_ID_START_VER_RETR, md->VSS & 0xff); 800 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x80 | 0x20); 801 WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE & 0xff); 802 803 if (md->DEP == 4) 804 WCrt(ba, CRT_ID_OFFSET, (HDE / 2) & 0xff); 805 else if (md->DEP == 8) 806 WCrt(ba, CRT_ID_OFFSET, (md->TX / 8) & 0xff); 807 else 808 WCrt(ba, CRT_ID_OFFSET, (md->TX / 4) & 0xff); 809 810 WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->FY-1) & 0x1f); 811 WCrt(ba, CRT_ID_START_VER_BLANK, md->VBS & 0xff); 812 WCrt(ba, CRT_ID_END_VER_BLANK, md->VBE & 0xff); 813 WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3); 814 WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); 815 816 WCrt(ba, CRT_ID_EXT_HOR_TIMING1, 817 0 | 0x20 | 818 ((md->FLG & MDF_LACE) / MDF_LACE * 0x10) | 819 ((md->HT & 0x100) / 0x100) | 820 (((HDE-1) & 0x100) / 0x100 * 2) | 821 ((md->HBS & 0x100) / 0x100 * 4) | 822 ((md->HSS & 0x100) / 0x100 * 8)); 823 824 if (md->DEP == 4) 825 WCrt(ba, CRT_ID_EXT_START_ADDR, 826 (((HDE / 2) & 0x100)/0x100 * 16)); 827 else if (md->DEP == 8) 828 WCrt(ba, CRT_ID_EXT_START_ADDR, 829 (((md->TX / 8) & 0x100)/0x100 * 16)); 830 else 831 WCrt(ba, CRT_ID_EXT_START_ADDR, 832 (((md->TX / 4) & 0x100)/0x100 * 16)); 833 834 WCrt(ba, CRT_ID_EXT_HOR_TIMING2, 835 ((md->HT & 0x200)/ 0x200) | 836 (((HDE-1) & 0x200)/ 0x200 * 2 ) | 837 ((md->HBS & 0x200)/ 0x200 * 4 ) | 838 ((md->HSS & 0x200)/ 0x200 * 8 ) | 839 ((md->HBE & 0xc0) / 0x40 * 16 ) | 840 ((md->HSE & 0x60) / 0x20 * 64)); 841 842 WCrt(ba, CRT_ID_EXT_VER_TIMING, 843 ((md->VSE & 0x10) / 0x10 * 0x80 ) | 844 ((md->VBE & 0x300)/ 0x100 * 0x20 ) | 845 0x10 | 846 ((md->VSS & 0x400)/ 0x400 * 8 ) | 847 ((md->VBS & 0x400)/ 0x400 * 4 ) | 848 ((VDE & 0x400)/ 0x400 * 2 ) | 849 ((md->VT & 0x400)/ 0x400)); 850 WCrt(ba, CRT_ID_MONITOR_POWER, 0x00); 851 852 { 853 unsigned short tmp = CompFQ(md->FQ); 854 WPLL(ba, 2 , tmp); 855 tmp = CompFQ(MEMCLK); 856 WPLL(ba,10 , tmp); 857 WPLL(ba,14 , 0x22); 858 } 859 860 WGfx(ba, GCT_ID_SET_RESET, 0x00); 861 WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00); 862 WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00); 863 WGfx(ba, GCT_ID_DATA_ROTATE, 0x00); 864 WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00); 865 WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00); 866 if (md->DEP == 4) 867 WGfx(ba, GCT_ID_MISC, 0x04); 868 else 869 WGfx(ba, GCT_ID_MISC, 0x05); 870 WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f); 871 WGfx(ba, GCT_ID_BITMASK, 0xff); 872 873 vgar(ba, ACT_ADDRESS_RESET); 874 WAttr(ba, ACT_ID_PALETTE0 , 0x00); 875 WAttr(ba, ACT_ID_PALETTE1 , 0x01); 876 WAttr(ba, ACT_ID_PALETTE2 , 0x02); 877 WAttr(ba, ACT_ID_PALETTE3 , 0x03); 878 WAttr(ba, ACT_ID_PALETTE4 , 0x04); 879 WAttr(ba, ACT_ID_PALETTE5 , 0x05); 880 WAttr(ba, ACT_ID_PALETTE6 , 0x06); 881 WAttr(ba, ACT_ID_PALETTE7 , 0x07); 882 WAttr(ba, ACT_ID_PALETTE8 , 0x08); 883 WAttr(ba, ACT_ID_PALETTE9 , 0x09); 884 WAttr(ba, ACT_ID_PALETTE10, 0x0a); 885 WAttr(ba, ACT_ID_PALETTE11, 0x0b); 886 WAttr(ba, ACT_ID_PALETTE12, 0x0c); 887 WAttr(ba, ACT_ID_PALETTE13, 0x0d); 888 WAttr(ba, ACT_ID_PALETTE14, 0x0e); 889 WAttr(ba, ACT_ID_PALETTE15, 0x0f); 890 891 vgar(ba, ACT_ADDRESS_RESET); 892 if (md->DEP == 4) 893 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x08); 894 else 895 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x09); 896 897 WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00); 898 WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f); 899 WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00); 900 WAttr(ba, ACT_ID_COLOR_SELECT, 0x00); 901 902 vgar(ba, ACT_ADDRESS_RESET); 903 vgaw(ba, ACT_ADDRESS_W, 0x20); 904 905 vgaw(ba, VDAC_MASK, 0xff); 906 if (md->DEP < 16) 907 /* well... probably the PLL chip */ 908 vgaw(ba, 0x83c6, ((0 & 7) << 5)); 909 else if (md->DEP == 16) 910 /* well... */ 911 vgaw(ba, 0x83c6, ((3 & 7) << 5)); 912 vgaw(ba, VDAC_ADDRESS_W, 0x00); 913 914 if (md->DEP < 16) { 915 short x = 256-17; 916 unsigned char cl = 16; 917 RZ3LoadPalette(gp, md->PAL, 0, 16); 918 do { 919 vgaw(ba, VDAC_DATA, (cl >> 2)); 920 vgaw(ba, VDAC_DATA, (cl >> 2)); 921 vgaw(ba, VDAC_DATA, (cl >> 2)); 922 cl++; 923 } while (x-- > 0); 924 } 925 926 if (md->DEP == 4) { 927 { 928 struct grf_bitblt bb = { 929 GRFBBOPset, 930 0, 0, 931 0, 0, 932 md->TX*4, 2*md->TY, 933 EMPTY_ALPHA 934 }; 935 RZ3BitBlit(gp, &bb); 936 } 937 938 c = (unsigned short *)(ba + LM_OFFSET); 939 c += 2 * md->FLo*32; 940 c += 1; 941 f = md->FData; 942 for (z = md->FLo; z <= md->FHi; z++) { 943 short y = md->FY-1; 944 if (md->FX > 8){ 945 do { 946 *c = *((const unsigned short *)f); 947 c += 2; 948 f += 2; 949 } while (y-- > 0); 950 } else { 951 do { 952 *c = (*f++) << 8; 953 c += 2; 954 } while (y-- > 0); 955 } 956 957 c += 2 * (32-md->FY); 958 } 959 { 960 unsigned long * pt = (unsigned long *) (ba + LM_OFFSET + PAT_MEM_OFF); 961 unsigned long tmp = 0xffff0000; 962 *pt++ = tmp; 963 *pt = tmp; 964 } 965 966 WSeq(ba, SEQ_ID_MAP_MASK, 3); 967 968 c = (unsigned short *)(ba + LM_OFFSET); 969 c += (md->TX-6)*2; 970 { 971 /* it's show-time :-) */ 972 static unsigned short init_msg[6] = { 973 0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f 974 }; 975 unsigned short * m = init_msg; 976 short x = 5; 977 do { 978 *c = *m++; 979 c += 2; 980 } while (x-- > 0); 981 } 982 983 return(1); 984 } else if (md->DEP == 8) { 985 struct grf_bitblt bb = { 986 GRFBBOPset, 987 0, 0, 988 0, 0, 989 md->TX, md->TY, 990 0x0000 991 }; 992 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 993 994 RZ3BitBlit(gp, &bb); 995 996 xpan = 0; 997 ypan = 0; 998 999 return(1); 1000 } else if (md->DEP == 16) { 1001 struct grf_bitblt bb = { 1002 GRFBBOPset, 1003 0, 0, 1004 0, 0, 1005 md->TX, md->TY, 1006 0x0000 1007 }; 1008 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 1009 1010 RZ3BitBlit16(gp, &bb); 1011 1012 xpan = 0; 1013 ypan = 0; 1014 1015 return(1); 1016 } else 1017 return(0); 1018 } 1019 1020 /* standard-palette definition */ 1021 1022 unsigned char RZ3StdPalette[16*3] = { 1023 /* R G B */ 1024 0, 0, 0, 1025 192,192,192, 1026 128, 0, 0, 1027 0,128, 0, 1028 0, 0,128, 1029 128,128, 0, 1030 0,128,128, 1031 128, 0,128, 1032 64, 64, 64, /* the higher 8 colors have more intensity for */ 1033 255,255,255, /* compatibility with standard attributes */ 1034 255, 0, 0, 1035 0,255, 0, 1036 0, 0,255, 1037 255,255, 0, 1038 0,255,255, 1039 255, 0,255 1040 }; 1041 1042 /* 1043 * The following structures are examples for monitor-definitions. To make one 1044 * of your own, first use "DefineMonitor" and create the 8-bit or 16-bit 1045 * monitor-mode of your dreams. Then save it, and make a structure from the 1046 * values provided in the file DefineMonitor stored - the labels in the comment 1047 * above the structure definition show where to put what value. 1048 * 1049 * If you want to use your definition for the text-mode, you'll need to adapt 1050 * your 8-bit monitor-definition to the font you want to use. Be FX the width of 1051 * the font, then the following modifications have to be applied to your values: 1052 * 1053 * HBS = (HBS * 4) / FX 1054 * HSS = (HSS * 4) / FX 1055 * HSE = (HSE * 4) / FX 1056 * HBE = (HBE * 4) / FX 1057 * HT = (HT * 4) / FX 1058 * 1059 * Make sure your maximum width (MW) and height (MH) are even multiples of 1060 * the fonts' width and height. 1061 * 1062 * You may use definitons created by the old DefineMonitor, but you'll get 1063 * better results with the new DefineMonitor supplied along with the Retin Z3. 1064 */ 1065 1066 /* 1067 * FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT 1068 * Depth, PAL, TX, TY, XY,FontX, FontY, FontData, FLo, Fhi 1069 */ 1070 static struct MonDef monitor_defs[] = { 1071 /* Text-mode definitions */ 1072 1073 /* horizontal 31.5 kHz */ 1074 #ifdef KFONT_8X11 1075 { 50000000, 28, 640, 506, 81, 86, 93, 98, 95, 513, 513, 521, 535, 535, 1076 4, RZ3StdPalette, 80, 46, 3680, 8, 11, kernel_font_8x11, 32, 255}, 1077 #else 1078 { 50000000, 28, 640, 512, 81, 86, 93, 98, 95, 513, 513, 521, 535, 535, 1079 4, RZ3StdPalette, 80, 64, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1080 #endif 1081 1082 /* horizontal 38kHz */ 1083 #ifdef KFONT_8X11 1084 { 75000000, 28, 768, 594, 97, 99,107,120,117, 601, 615, 625, 638, 638, 1085 4, RZ3StdPalette, 96, 54, 5184, 8, 11, kernel_font_8x11, 32, 255}, 1086 #else 1087 { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638, 1088 4, RZ3StdPalette, 96, 75, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1089 #endif 1090 1091 /* horizontal 64kHz */ 1092 #ifdef KFONT_8X11 1093 { 50000000, 24, 768, 594, 97,104,112,122,119, 601, 606, 616, 628, 628, 1094 4, RZ3StdPalette, 96, 54, 5184, 8, 8, kernel_font_8x8, 32, 255}, 1095 #else 1096 { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628, 1097 4, RZ3StdPalette, 96, 75, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1098 #endif 1099 1100 /* 8-bit gfx-mode definitions */ 1101 1102 /* 1103 * IMPORTANT: the "logical" screen size can be up to 2048x2048 pixels, 1104 * independent from the "physical" screen size. If your code does NOT 1105 * support panning, please adjust the "logical" screen sizes below to 1106 * match the physical ones 1107 */ 1108 1109 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */ 1110 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502, 1111 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1112 /* This is the logical ^ ^ screen size */ 1113 1114 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */ 1115 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502, 1116 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1117 1118 /* 800 x 600, 8 Bit, 31620 Hz, 50 Hz (1950) */ 1119 { 32000000, 0, 800, 600, 201,202,218,249,248, 601, 602, 612, 628, 628, 1120 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1121 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */ 1122 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628, 1123 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1124 1125 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */ 1126 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804, 1127 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1128 1129 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */ 1130 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938, 1131 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1132 1133 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */ 1134 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953, 1135 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1136 1137 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */ 1138 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888, 1139 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1140 1141 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */ 1142 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073, 1143 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1144 1145 /* WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR 1146 HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT 1147 MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! */ 1148 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */ 1149 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073, 1150 8, RZ3StdPalette,1280,1024, 5120, 8, 8, kernel_font_8x8, 32, 255}, 1151 1152 1153 /* 16-bit gfx-mode definitions */ 1154 1155 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */ 1156 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502, 1157 16, 0,1280, 1024, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1158 1159 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */ 1160 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628, 1161 16, 0,1280, 1024, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1162 1163 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */ 1164 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804, 1165 16, 0,1280, 1024, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1166 1167 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */ 1168 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678, 1169 16, 0,1280, 1024, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1170 1171 /* 1172 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR 1173 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT 1174 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! 1175 */ 1176 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */ 1177 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804, 1178 16, 0,1280, 1024, 7200, 8, 8, kernel_font_8x8, 32, 255}, 1179 }; 1180 1181 static const char *monitor_descr[] = { 1182 #ifdef KFONT_8X11 1183 "80x46 (640x506) 31.5kHz", 1184 "96x54 (768x594) 38kHz", 1185 "96x54 (768x594) 64kHz", 1186 #else 1187 "80x64 (640x512) 31.5kHz", 1188 "96x75 (768x600) 38kHz", 1189 "96x75 (768x600) 64kHz", 1190 #endif 1191 1192 "GFX-8 (640x480) 31.5kHz", 1193 "GFX-8 (640x480) 38kHz", 1194 "GFX-8 (800x600) 31.6kHz", 1195 "GFX-8 (800x600) 38.5kHz", 1196 "GFX-8 (1024x768) 64kHz", 1197 "GFX-8 (1120x896) 64kHz", 1198 "GFX-8 (1152x910) 76kHz", 1199 "GFX-8 (1182x848) 73kHz", 1200 "GFX-8 (1280x1024) 64.5kHz", 1201 "GFX-8 (1280x1024) 75.5kHz ***EXCEEDS CHIP LIMIT!!!***", 1202 1203 "GFX-16 (640x480) 31.8kHz", 1204 "GFX-16 (800x600) 38.5kHz", 1205 "GFX-16 (1024x768) 42.8kHz", 1206 "GFX-16 (864x648) 50kHz", 1207 "GFX-16 (1024x768) 48.5kHz ***EXCEEDS CHIP LIMIT!!!***", 1208 }; 1209 1210 int rh_mon_max = sizeof (monitor_defs)/sizeof (monitor_defs[0]); 1211 1212 /* patchable */ 1213 int rh_default_mon = 0; 1214 int rh_default_gfx = 4; 1215 1216 static struct MonDef *current_mon; 1217 1218 int rh_mode __P((struct grf_softc *, int, void *, int, int)); 1219 void grfrhattach __P((struct device *, struct device *, void *)); 1220 int grfrhprint __P((void *, char *)); 1221 int grfrhmatch __P((struct device *, struct cfdata *, void *)); 1222 1223 struct cfdriver grfrhcd = { 1224 NULL, "grfrh", (cfmatch_t)grfrhmatch, grfrhattach, 1225 DV_DULL, sizeof(struct grf_softc), NULL, 0 1226 }; 1227 1228 static struct cfdata *cfdata; 1229 1230 int 1231 grfrhmatch(pdp, cfp, auxp) 1232 struct device *pdp; 1233 struct cfdata *cfp; 1234 void *auxp; 1235 { 1236 #ifdef RETINACONSOLE 1237 static int rhconunit = -1; 1238 #endif 1239 struct zthreebus_args *zap; 1240 1241 zap = auxp; 1242 1243 if (amiga_realconfig == 0) 1244 #ifdef RETINACONSOLE 1245 if (rhconunit != -1) 1246 #endif 1247 return(0); 1248 if (zap->manid != 18260 || zap->prodid != 16) 1249 return(0); 1250 #ifdef RETINACONSOLE 1251 if (amiga_realconfig == 0 || rhconunit != cfp->cf_unit) { 1252 #endif 1253 if ((unsigned)rh_default_mon >= rh_mon_max || 1254 monitor_defs[rh_default_mon].DEP == 8) 1255 rh_default_mon = 0; 1256 current_mon = monitor_defs + rh_default_mon; 1257 if (rh_mondefok(current_mon) == 0) 1258 return(0); 1259 #ifdef RETINACONSOLE 1260 if (amiga_realconfig == 0) { 1261 rhconunit = cfp->cf_unit; 1262 cfdata = cfp; 1263 } 1264 } 1265 #endif 1266 return(1); 1267 } 1268 1269 void 1270 grfrhattach(pdp, dp, auxp) 1271 struct device *pdp, *dp; 1272 void *auxp; 1273 { 1274 static struct grf_softc congrf; 1275 static int coninited; 1276 struct zthreebus_args *zap; 1277 struct grf_softc *gp; 1278 1279 zap = auxp; 1280 1281 if (dp == NULL) 1282 gp = &congrf; 1283 else 1284 gp = (struct grf_softc *)dp; 1285 if (dp != NULL && congrf.g_regkva != 0) { 1286 /* 1287 * inited earlier, just copy (not device struct) 1288 */ 1289 bcopy(&congrf.g_display, &gp->g_display, 1290 (char *)&gp[1] - (char *)&gp->g_display); 1291 } else { 1292 gp->g_regkva = (volatile caddr_t)zap->va; 1293 gp->g_fbkva = (volatile caddr_t)zap->va + LM_OFFSET; 1294 gp->g_unit = GRF_RETINAIII_UNIT; 1295 gp->g_mode = rh_mode; 1296 gp->g_conpri = grfrh_cnprobe(); 1297 gp->g_flags = GF_ALIVE; 1298 grfrh_iteinit(gp); 1299 (void)rh_load_mon(gp, current_mon); 1300 } 1301 if (dp != NULL) 1302 printf("\n"); 1303 /* 1304 * attach grf 1305 */ 1306 amiga_config_found(cfdata, &gp->g_device, gp, grfrhprint); 1307 } 1308 1309 int 1310 grfrhprint(auxp, pnp) 1311 void *auxp; 1312 char *pnp; 1313 { 1314 if (pnp) 1315 printf("ite at %s", pnp); 1316 return(UNCONF); 1317 } 1318 1319 int 1320 rh_getvmode(gp, vm) 1321 struct grf_softc *gp; 1322 struct grfvideo_mode *vm; 1323 { 1324 struct MonDef *md; 1325 1326 if (vm->mode_num && vm->mode_num > rh_mon_max) 1327 return(EINVAL); 1328 1329 if (! vm->mode_num) 1330 vm->mode_num = (current_mon - monitor_defs) + 1; 1331 1332 md = monitor_defs + (vm->mode_num - 1); 1333 strncpy (vm->mode_descr, monitor_descr + (vm->mode_num - 1), 1334 sizeof (vm->mode_descr)); 1335 vm->pixel_clock = md->FQ; 1336 vm->disp_width = md->MW; 1337 vm->disp_height = md->MH; 1338 vm->depth = md->DEP; 1339 vm->hblank_start = md->HBS; 1340 vm->hblank_stop = md->HBE; 1341 vm->hsync_start = md->HSS; 1342 vm->hsync_stop = md->HSE; 1343 vm->htotal = md->HT; 1344 vm->vblank_start = md->VBS; 1345 vm->vblank_stop = md->VBE; 1346 vm->vsync_start = md->VSS; 1347 vm->vsync_stop = md->VSE; 1348 vm->vtotal = md->VT; 1349 1350 return(0); 1351 } 1352 1353 1354 int 1355 rh_setvmode(gp, mode, txtonly) 1356 struct grf_softc *gp; 1357 unsigned mode; 1358 int txtonly; 1359 { 1360 struct MonDef *md; 1361 int error; 1362 1363 if (!mode || mode > rh_mon_max) 1364 return(EINVAL); 1365 1366 if (txtonly && monitor_defs[mode-1].DEP != 4) 1367 return(EINVAL); 1368 1369 current_mon = monitor_defs + (mode - 1); 1370 1371 error = rh_load_mon (gp, current_mon) ? 0 : EINVAL; 1372 1373 return(error); 1374 } 1375 1376 1377 /* 1378 * Change the mode of the display. 1379 * Return a UNIX error number or 0 for success. 1380 */ 1381 rh_mode(gp, cmd, arg, a2, a3) 1382 register struct grf_softc *gp; 1383 int cmd; 1384 void *arg; 1385 int a2, a3; 1386 { 1387 /* implement these later... */ 1388 1389 switch (cmd) { 1390 case GM_GRFON: 1391 rh_setvmode (gp, rh_default_gfx + 1, 0); 1392 return(0); 1393 1394 case GM_GRFOFF: 1395 rh_setvmode (gp, rh_default_mon + 1, 0); 1396 return(0); 1397 1398 case GM_GRFCONFIG: 1399 return(0); 1400 1401 case GM_GRFGETVMODE: 1402 return(rh_getvmode (gp, (struct grfvideo_mode *) arg)); 1403 1404 case GM_GRFSETVMODE: 1405 return(rh_setvmode (gp, *(unsigned *) arg, 1)); 1406 1407 case GM_GRFGETNUMVM: 1408 *(int *)arg = rh_mon_max; 1409 return(0); 1410 1411 #ifdef BANKEDDEVPAGER 1412 case GM_GRFGETBANK: 1413 case GM_GRFGETCURBANK: 1414 case GM_GRFSETBANK: 1415 return(EINVAL); 1416 #endif 1417 case GM_GRFIOCTL: 1418 return(rh_ioctl (gp, (u_long) arg, (caddr_t) a2)); 1419 1420 default: 1421 break; 1422 } 1423 1424 return(EINVAL); 1425 } 1426 1427 int 1428 rh_ioctl (gp, cmd, data) 1429 register struct grf_softc *gp; 1430 u_long cmd; 1431 void *data; 1432 { 1433 switch (cmd) { 1434 case GRFIOCGSPRITEPOS: 1435 return(rh_getspritepos (gp, (struct grf_position *) data)); 1436 1437 case GRFIOCSSPRITEPOS: 1438 return(rh_setspritepos (gp, (struct grf_position *) data)); 1439 1440 case GRFIOCSSPRITEINF: 1441 return(rh_setspriteinfo (gp, (struct grf_spriteinfo *) data)); 1442 1443 case GRFIOCGSPRITEINF: 1444 return(rh_getspriteinfo (gp, (struct grf_spriteinfo *) data)); 1445 1446 case GRFIOCGSPRITEMAX: 1447 return(rh_getspritemax (gp, (struct grf_position *) data)); 1448 1449 case GRFIOCGETCMAP: 1450 return(rh_getcmap (gp, (struct grf_colormap *) data)); 1451 1452 case GRFIOCPUTCMAP: 1453 return(rh_putcmap (gp, (struct grf_colormap *) data)); 1454 1455 case GRFIOCBITBLT: 1456 return(rh_bitblt (gp, (struct grf_bitblt *) data)); 1457 } 1458 1459 return(EINVAL); 1460 } 1461 1462 1463 int 1464 rh_getcmap (gfp, cmap) 1465 struct grf_softc *gfp; 1466 struct grf_colormap *cmap; 1467 { 1468 volatile unsigned char *ba; 1469 u_char red[256], green[256], blue[256], *rp, *gp, *bp; 1470 short x; 1471 int error; 1472 1473 if (cmap->count == 0 || cmap->index >= 256) 1474 return 0; 1475 1476 if (cmap->index + cmap->count > 256) 1477 cmap->count = 256 - cmap->index; 1478 1479 ba = gfp->g_regkva; 1480 /* first read colors out of the chip, then copyout to userspace */ 1481 vgaw (ba, VDAC_ADDRESS_W, cmap->index); 1482 x = cmap->count - 1; 1483 rp = red + cmap->index; 1484 gp = green + cmap->index; 1485 bp = blue + cmap->index; 1486 do { 1487 *rp++ = vgar (ba, VDAC_DATA) << 2; 1488 *gp++ = vgar (ba, VDAC_DATA) << 2; 1489 *bp++ = vgar (ba, VDAC_DATA) << 2; 1490 } while (x-- > 0); 1491 1492 if (!(error = copyout (red + cmap->index, cmap->red, cmap->count)) 1493 && !(error = copyout (green + cmap->index, cmap->green, cmap->count)) 1494 && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count))) 1495 return(0); 1496 1497 return(error); 1498 } 1499 1500 int 1501 rh_putcmap (gfp, cmap) 1502 struct grf_softc *gfp; 1503 struct grf_colormap *cmap; 1504 { 1505 volatile unsigned char *ba; 1506 u_char red[256], green[256], blue[256], *rp, *gp, *bp; 1507 short x; 1508 int error; 1509 1510 if (cmap->count == 0 || cmap->index >= 256) 1511 return(0); 1512 1513 if (cmap->index + cmap->count > 256) 1514 cmap->count = 256 - cmap->index; 1515 1516 /* first copy the colors into kernelspace */ 1517 if (!(error = copyin (cmap->red, red + cmap->index, cmap->count)) 1518 && !(error = copyin (cmap->green, green + cmap->index, cmap->count)) 1519 && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) { 1520 /* argl.. LoadPalette wants a different format, so do it like with 1521 * Retina2.. */ 1522 ba = gfp->g_regkva; 1523 vgaw (ba, VDAC_ADDRESS_W, cmap->index); 1524 x = cmap->count - 1; 1525 rp = red + cmap->index; 1526 gp = green + cmap->index; 1527 bp = blue + cmap->index; 1528 do { 1529 vgaw (ba, VDAC_DATA, *rp++ >> 2); 1530 vgaw (ba, VDAC_DATA, *gp++ >> 2); 1531 vgaw (ba, VDAC_DATA, *bp++ >> 2); 1532 } while (x-- > 0); 1533 return(0); 1534 } 1535 else 1536 return(error); 1537 } 1538 1539 int 1540 rh_getspritepos (gp, pos) 1541 struct grf_softc *gp; 1542 struct grf_position *pos; 1543 { 1544 volatile unsigned char *acm = gp->g_regkva + ACM_OFFSET; 1545 1546 pos->x = acm[ACM_CURSOR_POSITION + 0] + 1547 (acm[ACM_CURSOR_POSITION + 1] << 8); 1548 pos->y = acm[ACM_CURSOR_POSITION + 2] + 1549 (acm[ACM_CURSOR_POSITION + 3] << 8); 1550 1551 pos->x += xpan; 1552 pos->y += ypan; 1553 1554 return(0); 1555 } 1556 1557 int 1558 rh_setspritepos (gp, pos) 1559 struct grf_softc *gp; 1560 struct grf_position *pos; 1561 { 1562 RZ3SetHWCloc (gp, pos->x, pos->y); 1563 return(0); 1564 } 1565 1566 int 1567 rh_getspriteinfo (gp, info) 1568 struct grf_softc *gp; 1569 struct grf_spriteinfo *info; 1570 { 1571 volatile unsigned char *ba, *fb; 1572 1573 ba = gp->g_regkva; 1574 fb = gp->g_fbkva; 1575 if (info->set & GRFSPRSET_ENABLE) 1576 info->enable = RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 0x01; 1577 if (info->set & GRFSPRSET_POS) 1578 rh_getspritepos (gp, &info->pos); 1579 if (info->set & GRFSPRSET_HOT) { 1580 info->hot.x = RSeq (ba, SEQ_ID_CURSOR_X_INDEX) & 0x3f; 1581 info->hot.y = RSeq (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f; 1582 } 1583 if (info->set & GRFSPRSET_CMAP) { 1584 struct grf_colormap cmap; 1585 int index; 1586 cmap.index = 0; 1587 cmap.count = 256; 1588 rh_getcmap (gp, &cmap); 1589 index = RSeq (ba, SEQ_ID_CURSOR_COLOR0); 1590 info->cmap.red[0] = cmap.red[index]; 1591 info->cmap.green[0] = cmap.green[index]; 1592 info->cmap.blue[0] = cmap.blue[index]; 1593 index = RSeq (ba, SEQ_ID_CURSOR_COLOR1); 1594 info->cmap.red[1] = cmap.red[index]; 1595 info->cmap.green[1] = cmap.green[index]; 1596 info->cmap.blue[1] = cmap.blue[index]; 1597 } 1598 if (info->set & GRFSPRSET_SHAPE) { 1599 u_char image[128], mask[128]; 1600 volatile u_long *hwp; 1601 u_char *imp, *mp; 1602 short row; 1603 1604 /* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h 1605 * for an explanation. To convert to "our" format, the 1606 * following holds: 1607 * col2 = !image & mask 1608 * col1 = image & mask 1609 * transp = !mask 1610 * and thus: 1611 * image = col1 1612 * mask = col1 | col2 1613 * hope I got these bool-eqs right below.. 1614 */ 1615 1616 info->size.x = 64; 1617 info->size.y = 64; 1618 for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF), 1619 mp = mask, imp = image; 1620 row < 64; 1621 row++) { 1622 u_long bp10, bp20, bp11, bp21; 1623 bp10 = *hwp++; 1624 bp20 = *hwp++; 1625 bp11 = *hwp++; 1626 bp21 = *hwp++; 1627 M2I (bp10); 1628 M2I (bp20); 1629 M2I (bp11); 1630 M2I (bp21); 1631 *imp++ = (~bp10) & bp11; 1632 *imp++ = (~bp20) & bp21; 1633 *mp++ = (~bp10) | (bp10 & ~bp11); 1634 *mp++ = (~bp20) & (bp20 & ~bp21); 1635 } 1636 copyout (image, info->image, sizeof (image)); 1637 copyout (mask, info->mask, sizeof (mask)); 1638 } 1639 return(0); 1640 } 1641 1642 int 1643 rh_setspriteinfo (gp, info) 1644 struct grf_softc *gp; 1645 struct grf_spriteinfo *info; 1646 { 1647 volatile unsigned char *ba, *fb; 1648 u_char control; 1649 1650 ba = gp->g_regkva; 1651 fb = gp->g_fbkva; 1652 1653 if (info->set & GRFSPRSET_SHAPE) { 1654 /* 1655 * For an explanation of these weird actions here, see above 1656 * when reading the shape. We set the shape directly into 1657 * the video memory, there's no reason to keep 1k on the 1658 * kernel stack just as template 1659 */ 1660 u_char *image, *mask; 1661 volatile u_long *hwp; 1662 u_char *imp, *mp; 1663 short row; 1664 1665 if (info->size.y > 64) 1666 info->size.y = 64; 1667 if (info->size.x > 64) 1668 info->size.x = 64; 1669 1670 if (info->size.x < 32) 1671 info->size.x = 32; 1672 1673 image = malloc(HWC_MEM_SIZE, M_TEMP, M_WAITOK); 1674 mask = image + HWC_MEM_SIZE/2; 1675 1676 copyin(info->image, image, info->size.y * info->size.x / 8); 1677 copyin(info->mask, mask, info->size.y * info->size.x / 8); 1678 1679 hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF); 1680 1681 /* 1682 * setting it is slightly more difficult, because we can't 1683 * force the application to not pass a *smaller* than 1684 * supported bitmap 1685 */ 1686 1687 for (row = 0, mp = mask, imp = image; 1688 row < info->size.y; 1689 row++) { 1690 u_long im1, im2, m1, m2; 1691 1692 im1 = *(unsigned long *)imp; 1693 imp += 4; 1694 m1 = *(unsigned long *)mp; 1695 mp += 4; 1696 if (info->size.x > 32) { 1697 im2 = *(unsigned long *)imp; 1698 imp += 4; 1699 m2 = *(unsigned long *)mp; 1700 mp += 4; 1701 } 1702 else 1703 im2 = m2 = 0; 1704 1705 M2I(im1); 1706 M2I(im2); 1707 M2I(m1); 1708 M2I(m2); 1709 1710 *hwp++ = ~m1; 1711 *hwp++ = ~m2; 1712 *hwp++ = m1 & im1; 1713 *hwp++ = m2 & im2; 1714 } 1715 for (; row < 64; row++) { 1716 *hwp++ = 0xffffffff; 1717 *hwp++ = 0xffffffff; 1718 *hwp++ = 0x00000000; 1719 *hwp++ = 0x00000000; 1720 } 1721 1722 free(image, M_TEMP); 1723 RZ3SetupHWC(gp, 1, 0, 0, 0, 0); 1724 } 1725 if (info->set & GRFSPRSET_CMAP) { 1726 /* hey cheat a bit here.. XXX */ 1727 WSeq(ba, SEQ_ID_CURSOR_COLOR0, 0); 1728 WSeq(ba, SEQ_ID_CURSOR_COLOR1, 1); 1729 } 1730 if (info->set & GRFSPRSET_ENABLE) { 1731 if (info->enable) 1732 control = 0x85; 1733 else 1734 control = 0; 1735 WSeq(ba, SEQ_ID_CURSOR_CONTROL, control); 1736 } 1737 if (info->set & GRFSPRSET_POS) 1738 rh_setspritepos(gp, &info->pos); 1739 if (info->set & GRFSPRSET_HOT) { 1740 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x3f); 1741 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f); 1742 } 1743 1744 return(0); 1745 } 1746 1747 int 1748 rh_getspritemax (gp, pos) 1749 struct grf_softc *gp; 1750 struct grf_position *pos; 1751 { 1752 pos->x = 64; 1753 pos->y = 64; 1754 1755 return(0); 1756 } 1757 1758 1759 int 1760 rh_bitblt (gp, bb) 1761 struct grf_softc *gp; 1762 struct grf_bitblt *bb; 1763 { 1764 struct MonDef *md = (struct MonDef *)gp->g_data; 1765 if (md->DEP < 16) 1766 RZ3BitBlit(gp, bb); 1767 else 1768 RZ3BitBlit16(gp, bb); 1769 } 1770 #endif /* NGRF */ 1771