1 /* $NetBSD: grf_rh.c,v 1.27 1997/07/29 17:52:05 veego Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Markus Wild 5 * Copyright (c) 1994 Lutz Vieweg 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Lutz Vieweg. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 #include "grfrh.h" 34 #if NGRFRH > 0 35 36 /* 37 * Graphics routines for the Retina BLT Z3 board, 38 * using the NCR 77C32BLT VGA controller. 39 */ 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/errno.h> 44 #include <sys/ioctl.h> 45 #include <sys/device.h> 46 #include <sys/malloc.h> 47 #include <machine/cpu.h> 48 #include <amiga/amiga/device.h> 49 #include <amiga/dev/grfioctl.h> 50 #include <amiga/dev/grfvar.h> 51 #include <amiga/dev/grf_rhreg.h> 52 #include <amiga/dev/zbusvar.h> 53 54 enum mode_type { MT_TXTONLY, MT_GFXONLY, MT_BOTH }; 55 56 int rh_mondefok __P((struct MonDef *)); 57 58 u_short rh_CompFQ __P((u_int fq)); 59 int rh_load_mon __P((struct grf_softc *gp, struct MonDef *md)); 60 int rh_getvmode __P((struct grf_softc *gp, struct grfvideo_mode *vm)); 61 int rh_setvmode __P((struct grf_softc *gp, unsigned int mode, 62 enum mode_type type)); 63 64 /* make it patchable, and settable by kernel config option */ 65 #ifndef RH_MEMCLK 66 #define RH_MEMCLK 61000000 /* this is the memory clock value, you shouldn't 67 set it to less than 61000000, higher values may 68 speed up blits a little bit, if you raise this 69 value too much, some trash will appear on your 70 screen. */ 71 #endif 72 int rh_memclk = RH_MEMCLK; 73 74 75 extern unsigned char kernel_font_8x8_width, kernel_font_8x8_height; 76 extern unsigned char kernel_font_8x8_lo, kernel_font_8x8_hi; 77 extern unsigned char kernel_font_8x8[]; 78 #ifdef KFONT_8X11 79 extern unsigned char kernel_font_8x11_width, kernel_font_8x11_height; 80 extern unsigned char kernel_font_8x11_lo, kernel_font_8x11_hi; 81 extern unsigned char kernel_font_8x11[]; 82 #endif 83 84 /* 85 * This driver for the MacroSystem Retina board was only possible, 86 * because MacroSystem provided information about the pecularities 87 * of the board. THANKS! Competition in Europe among gfx board 88 * manufacturers is rather tough, so Lutz Vieweg, who wrote the 89 * initial driver, has made an agreement with MS not to document 90 * the driver source (see also his comment below). 91 * -> ALL comments after 92 * -> " -------------- START OF CODE -------------- " 93 * -> have been added by myself (mw) from studying the publically 94 * -> available "NCR 77C32BLT" Data Manual 95 */ 96 /* 97 * This code offers low-level routines to access the Retina BLT Z3 98 * graphics-board manufactured by MS MacroSystem GmbH from within NetBSD 99 * for the Amiga. 100 * 101 * Thanks to MacroSystem for providing me with the neccessary information 102 * to create theese routines. The sparse documentation of this code 103 * results from the agreements between MS and me. 104 */ 105 106 107 108 #define MDF_DBL 1 109 #define MDF_LACE 2 110 #define MDF_CLKDIV2 4 111 112 /* set this as an option in your kernel config file! */ 113 /* #define RH_64BIT_SPRITE */ 114 115 /* -------------- START OF CODE -------------- */ 116 117 /* Convert big-endian long into little-endian long. */ 118 119 #define M2I(val) \ 120 asm volatile (" rorw #8,%0 ; \ 121 swap %0 ; \ 122 rorw #8,%0 ; " : "=d" (val) : "0" (val)); 123 124 #define M2INS(val) \ 125 asm volatile (" rorw #8,%0 ; \ 126 swap %0 ; \ 127 rorw #8,%0 ; \ 128 swap %0 ; " : "=d" (val) : "0" (val)); 129 130 #define ACM_OFFSET (0x00b00000) 131 #define LM_OFFSET (0x00c00000) 132 133 static unsigned char optab[] = { 134 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 135 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0 136 }; 137 static char optabs[] = { 138 0, -1, -1, -1, -1, 0, -1, -1, 139 -1, -1, 0, -1, -1, -1, -1, 0 140 }; 141 142 void 143 RZ3DisableHWC(gp) 144 struct grf_softc *gp; 145 { 146 volatile void *ba = gp->g_regkva; 147 148 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, 0x00); 149 } 150 151 void 152 RZ3SetupHWC(gp, col1, col2, hsx, hsy, data) 153 struct grf_softc *gp; 154 unsigned char col1; 155 unsigned col2; 156 unsigned char hsx; 157 unsigned char hsy; 158 const unsigned long *data; 159 { 160 volatile unsigned char *ba = gp->g_regkva; 161 unsigned long *c = (unsigned long *)(ba + LM_OFFSET + HWC_MEM_OFF); 162 const unsigned long *s = data; 163 struct MonDef *MonitorDef = (struct MonDef *) gp->g_data; 164 #ifdef RH_64BIT_SPRITE 165 short x = (HWC_MEM_SIZE / (4*4)) - 1; 166 #else 167 short x = (HWC_MEM_SIZE / (4*4*2)) - 1; 168 #endif 169 /* copy only, if there is a data pointer. */ 170 if (data) do { 171 *c++ = *s++; 172 *c++ = *s++; 173 *c++ = *s++; 174 *c++ = *s++; 175 } while (x-- > 0); 176 177 WSeq(ba, SEQ_ID_CURSOR_COLOR1, col1); 178 WSeq(ba, SEQ_ID_CURSOR_COLOR0, col2); 179 if (MonitorDef->DEP <= 8) { 180 #ifdef RH_64BIT_SPRITE 181 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x85); 182 #else 183 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x03); 184 #endif 185 } 186 else if (MonitorDef->DEP <= 16) { 187 #ifdef RH_64BIT_SPRITE 188 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xa5); 189 #else 190 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x23); 191 #endif 192 } 193 else { 194 #ifdef RH_64BIT_SPRITE 195 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0xc5); 196 #else 197 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x43); 198 #endif 199 } 200 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, 0x00); 201 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, 0x00); 202 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, 0x00); 203 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, 0x00); 204 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, hsx); 205 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, hsy); 206 WSeq(ba, SEQ_ID_CURSOR_STORE_HI, 0x00); 207 WSeq(ba, SEQ_ID_CURSOR_STORE_LO, ((HWC_MEM_OFF / 4) & 0x0000f)); 208 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_HI, (((HWC_MEM_OFF / 4) & 0xff000) >> 12)); 209 WSeq(ba, SEQ_ID_CURSOR_ST_OFF_LO, (((HWC_MEM_OFF / 4) & 0x00ff0) >> 4)); 210 WSeq(ba, SEQ_ID_CURSOR_PIXELMASK, 0xff); 211 } 212 213 void 214 RZ3AlphaErase (gp, xd, yd, w, h) 215 struct grf_softc *gp; 216 unsigned short xd; 217 unsigned short yd; 218 unsigned short w; 219 unsigned short h; 220 { 221 const struct MonDef * md = (struct MonDef *) gp->g_data; 222 RZ3AlphaCopy(gp, xd, yd+md->TY, xd, yd, w, h); 223 } 224 225 void 226 RZ3AlphaCopy (gp, xs, ys, xd, yd, w, h) 227 struct grf_softc *gp; 228 unsigned short xs; 229 unsigned short ys; 230 unsigned short xd; 231 unsigned short yd; 232 unsigned short w; 233 unsigned short h; 234 { 235 volatile unsigned char *ba = gp->g_regkva; 236 const struct MonDef *md = (struct MonDef *) gp->g_data; 237 volatile unsigned long *acm = (unsigned long *) (ba + ACM_OFFSET); 238 unsigned short mod; 239 240 xs *= 4; 241 ys *= 4; 242 xd *= 4; 243 yd *= 4; 244 w *= 4; 245 246 { 247 /* anyone got Windoze GDI opcodes handy?... */ 248 unsigned long tmp = 0x0000ca00; 249 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 250 } 251 252 mod = 0xc0c2; 253 254 { 255 unsigned long pat = 8 * PAT_MEM_OFF; 256 unsigned long dst = 8 * (xd + yd * md->TX); 257 258 unsigned long src = 8 * (xs + ys * md->TX); 259 260 if (xd > xs) { 261 mod &= ~0x8000; 262 src += 8 * (w - 1); 263 dst += 8 * (w - 1); 264 pat += 8 * 2; 265 } 266 if (yd > ys) { 267 mod &= ~0x4000; 268 src += 8 * (h - 1) * md->TX * 4; 269 dst += 8 * (h - 1) * md->TX * 4; 270 pat += 8 * 4; 271 } 272 273 M2I(src); 274 *(acm + ACM_SOURCE/4) = src; 275 276 M2I(pat); 277 *(acm + ACM_PATTERN/4) = pat; 278 279 M2I(dst); 280 *(acm + ACM_DESTINATION/4) = dst; 281 } 282 { 283 284 unsigned long tmp = mod << 16; 285 *(acm + ACM_CONTROL/4) = tmp; 286 } 287 { 288 289 unsigned long tmp = w | (h << 16); 290 M2I(tmp); 291 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 292 } 293 294 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 295 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 296 297 while ((*(((volatile unsigned char *)acm) + 298 (ACM_START_STATUS + 2)) & 1) == 0); 299 } 300 301 void 302 RZ3BitBlit (gp, gbb) 303 struct grf_softc *gp; 304 struct grf_bitblt * gbb; 305 { 306 volatile unsigned char *ba = gp->g_regkva; 307 volatile unsigned char *lm = ba + LM_OFFSET; 308 volatile unsigned long *acm = (unsigned long *) (ba + ACM_OFFSET); 309 const struct MonDef *md = (struct MonDef *) gp->g_data; 310 unsigned short mod; 311 312 { 313 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF); 314 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16); 315 *pt++ = tmp; 316 *pt = tmp; 317 } 318 319 { 320 321 unsigned long tmp = optab[ gbb->op ] << 8; 322 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 323 } 324 325 mod = 0xc0c2; 326 327 { 328 unsigned long pat = 8 * PAT_MEM_OFF; 329 unsigned long dst = 8 * (gbb->dst_x + gbb->dst_y * md->TX); 330 331 if (optabs[gbb->op]) { 332 unsigned long src = 8 * (gbb->src_x + gbb->src_y * md->TX); 333 334 if (gbb->dst_x > gbb->src_x) { 335 mod &= ~0x8000; 336 src += 8 * (gbb->w - 1); 337 dst += 8 * (gbb->w - 1); 338 pat += 8 * 2; 339 } 340 if (gbb->dst_y > gbb->src_y) { 341 mod &= ~0x4000; 342 src += 8 * (gbb->h - 1) * md->TX; 343 dst += 8 * (gbb->h - 1) * md->TX; 344 pat += 8 * 4; 345 } 346 347 M2I(src); 348 *(acm + ACM_SOURCE/4) = src; 349 } 350 351 M2I(pat); 352 *(acm + ACM_PATTERN/4) = pat; 353 354 M2I(dst); 355 *(acm + ACM_DESTINATION/4) = dst; 356 } 357 { 358 359 unsigned long tmp = mod << 16; 360 *(acm + ACM_CONTROL/4) = tmp; 361 } 362 { 363 unsigned long tmp = gbb->w | (gbb->h << 16); 364 M2I(tmp); 365 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 366 } 367 368 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 369 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 370 371 while ((*(((volatile unsigned char *)acm) + 372 (ACM_START_STATUS + 2)) & 1) == 0); 373 } 374 375 void 376 RZ3BitBlit16 (gp, gbb) 377 struct grf_softc *gp; 378 struct grf_bitblt * gbb; 379 { 380 volatile unsigned char *ba = gp->g_regkva; 381 volatile unsigned char *lm = ba + LM_OFFSET; 382 volatile unsigned long * acm = (unsigned long *) (ba + ACM_OFFSET); 383 const struct MonDef * md = (struct MonDef *) gp->g_data; 384 unsigned short mod; 385 386 { 387 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF); 388 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16); 389 *pt++ = tmp; 390 *pt++ = tmp; 391 *pt++ = tmp; 392 *pt = tmp; 393 } 394 395 { 396 397 unsigned long tmp = optab[ gbb->op ] << 8; 398 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 399 } 400 401 mod = 0xc0c2; 402 403 { 404 unsigned long pat = 8 * PAT_MEM_OFF; 405 unsigned long dst = 8 * 2 * (gbb->dst_x + gbb->dst_y * md->TX); 406 407 if (optabs[gbb->op]) { 408 unsigned long src = 8 * 2 * (gbb->src_x + gbb->src_y * md->TX); 409 410 if (gbb->dst_x > gbb->src_x) { 411 mod &= ~0x8000; 412 src += 8 * 2 * (gbb->w); 413 dst += 8 * 2 * (gbb->w); 414 pat += 8 * 2 * 2; 415 } 416 if (gbb->dst_y > gbb->src_y) { 417 mod &= ~0x4000; 418 src += 8 * 2 * (gbb->h - 1) * md->TX; 419 dst += 8 * 2 * (gbb->h - 1) * md->TX; 420 pat += 8 * 4 * 2; 421 } 422 423 M2I(src); 424 *(acm + ACM_SOURCE/4) = src; 425 } 426 427 M2I(pat); 428 *(acm + ACM_PATTERN/4) = pat; 429 430 M2I(dst); 431 *(acm + ACM_DESTINATION/4) = dst; 432 } 433 { 434 435 unsigned long tmp = mod << 16; 436 *(acm + ACM_CONTROL/4) = tmp; 437 } 438 { 439 440 unsigned long tmp = gbb->w | (gbb->h << 16); 441 M2I(tmp); 442 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 443 } 444 445 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 446 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 447 448 while ((*(((volatile unsigned char *)acm) + 449 (ACM_START_STATUS+ 2)) & 1) == 0); 450 } 451 452 void 453 RZ3BitBlit24 (gp, gbb) 454 struct grf_softc *gp; 455 struct grf_bitblt * gbb; 456 { 457 volatile unsigned char *ba = gp->g_regkva; 458 volatile unsigned char *lm = ba + LM_OFFSET; 459 volatile unsigned long * acm = (unsigned long *) (ba + ACM_OFFSET); 460 const struct MonDef * md = (struct MonDef *) gp->g_data; 461 unsigned short mod; 462 463 464 { 465 unsigned long * pt = (unsigned long *) (lm + PAT_MEM_OFF); 466 unsigned long tmp = gbb->mask | ((unsigned long)gbb->mask << 16); 467 *pt++ = tmp; 468 *pt++ = tmp; 469 *pt++ = tmp; 470 *pt++ = tmp; 471 *pt++ = tmp; 472 *pt = tmp; 473 } 474 475 { 476 477 unsigned long tmp = optab[ gbb->op ] << 8; 478 *(acm + ACM_RASTEROP_ROTATION/4) = tmp; 479 } 480 481 mod = 0xc0c2; 482 483 { 484 unsigned long pat = 8 * PAT_MEM_OFF; 485 unsigned long dst = 8 * 3 * (gbb->dst_x + gbb->dst_y * md->TX); 486 487 if (optabs[gbb->op]) { 488 unsigned long src = 8 * 3 * (gbb->src_x + gbb->src_y * md->TX); 489 490 if (gbb->dst_x > gbb->src_x ) { 491 mod &= ~0x8000; 492 src += 8 * 3 * (gbb->w); 493 dst += 8 * 3 * (gbb->w); 494 pat += 8 * 3 * 2; 495 } 496 if (gbb->dst_y > gbb->src_y) { 497 mod &= ~0x4000; 498 src += 8 * 3 * (gbb->h - 1) * md->TX; 499 dst += 8 * 3 * (gbb->h - 1) * md->TX; 500 pat += 8 * 4 * 3; 501 } 502 503 M2I(src); 504 *(acm + ACM_SOURCE/4) = src; 505 } 506 507 508 M2I(pat); 509 *(acm + ACM_PATTERN/4) = pat; 510 511 512 M2I(dst); 513 *(acm + ACM_DESTINATION/4) = dst; 514 } 515 { 516 517 unsigned long tmp = mod << 16; 518 *(acm + ACM_CONTROL/4) = tmp; 519 } 520 { 521 522 unsigned long tmp = gbb->w | (gbb->h << 16); 523 M2I(tmp); 524 *(acm + ACM_BITMAP_DIMENSION/4) = tmp; 525 } 526 527 528 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00; 529 *(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01; 530 531 while ( (*(((volatile unsigned char *)acm) 532 + (ACM_START_STATUS+ 2)) & 1) == 0 ) {}; 533 534 } 535 536 537 void 538 RZ3SetCursorPos (gp, pos) 539 struct grf_softc *gp; 540 unsigned short pos; 541 { 542 volatile unsigned char *ba = gp->g_regkva; 543 544 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, (unsigned char)pos); 545 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, (unsigned char)(pos >> 8)); 546 547 } 548 549 void 550 RZ3LoadPalette (gp, pal, firstcol, colors) 551 struct grf_softc *gp; 552 unsigned char * pal; 553 unsigned char firstcol; 554 unsigned char colors; 555 { 556 volatile unsigned char *ba = gp->g_regkva; 557 558 if (colors == 0) 559 return; 560 561 vgaw(ba, VDAC_ADDRESS_W, firstcol); 562 563 { 564 565 short x = colors-1; 566 const unsigned char * col = pal; 567 do { 568 569 vgaw(ba, VDAC_DATA, (*col++ >> 2)); 570 vgaw(ba, VDAC_DATA, (*col++ >> 2)); 571 vgaw(ba, VDAC_DATA, (*col++ >> 2)); 572 573 } while (x-- > 0); 574 575 } 576 } 577 578 void 579 RZ3SetPalette (gp, colornum, red, green, blue) 580 struct grf_softc *gp; 581 unsigned char colornum; 582 unsigned char red, green, blue; 583 { 584 volatile unsigned char *ba = gp->g_regkva; 585 586 vgaw(ba, VDAC_ADDRESS_W, colornum); 587 588 vgaw(ba, VDAC_DATA, (red >> 2)); 589 vgaw(ba, VDAC_DATA, (green >> 2)); 590 vgaw(ba, VDAC_DATA, (blue >> 2)); 591 592 } 593 594 void 595 RZ3SetPanning (gp, xoff, yoff) 596 struct grf_softc *gp; 597 unsigned short xoff, yoff; 598 { 599 volatile unsigned char *ba = gp->g_regkva; 600 struct grfinfo *gi = &gp->g_display; 601 const struct MonDef * md = (struct MonDef *) gp->g_data; 602 unsigned long off; 603 604 gi->gd_fbx = xoff; 605 gi->gd_fby = yoff; 606 607 if (md->DEP > 8 && md->DEP <= 16) xoff *= 2; 608 else if (md->DEP > 16) xoff *= 3; 609 610 vgar(ba, ACT_ADDRESS_RESET); 611 WAttr(ba, ACT_ID_HOR_PEL_PANNING, (unsigned char)((xoff << 1) & 0x07)); 612 /* have the color lookup function normally again */ 613 vgaw(ba, ACT_ADDRESS_W, 0x20); 614 615 if (md->DEP == 8) 616 off = ((yoff * md->TX)/ 4) + (xoff >> 2); 617 else if (md->DEP == 16) 618 off = ((yoff * md->TX * 2)/ 4) + (xoff >> 2); 619 else 620 off = ((yoff * md->TX * 3)/ 4) + (xoff >> 2); 621 WCrt(ba, CRT_ID_START_ADDR_LOW, ((unsigned char)off)); 622 off >>= 8; 623 WCrt(ba, CRT_ID_START_ADDR_HIGH, ((unsigned char)off)); 624 off >>= 8; 625 WCrt(ba, CRT_ID_EXT_START_ADDR, 626 ((RCrt(ba, CRT_ID_EXT_START_ADDR) & 0xf0) | (off & 0x0f))); 627 628 629 } 630 631 void 632 RZ3SetHWCloc (gp, x, y) 633 struct grf_softc *gp; 634 unsigned short x, y; 635 { 636 volatile unsigned char *ba = gp->g_regkva; 637 const struct MonDef *md = (struct MonDef *) gp->g_data; 638 /*volatile unsigned char *acm = ba + ACM_OFFSET;*/ 639 struct grfinfo *gi = &gp->g_display; 640 641 if (x < gi->gd_fbx) 642 RZ3SetPanning(gp, x, gi->gd_fby); 643 644 if (x >= (gi->gd_fbx+md->MW)) 645 RZ3SetPanning(gp, (1 + x - md->MW) , gi->gd_fby); 646 647 if (y < gi->gd_fby) 648 RZ3SetPanning(gp, gi->gd_fbx, y); 649 650 if (y >= (gi->gd_fby+md->MH)) 651 RZ3SetPanning(gp, gi->gd_fbx, (1 + y - md->MH)); 652 653 x -= gi->gd_fbx; 654 y -= gi->gd_fby; 655 656 #if 1 657 WSeq(ba, SEQ_ID_CURSOR_X_LOC_HI, x >> 8); 658 WSeq(ba, SEQ_ID_CURSOR_X_LOC_LO, x & 0xff); 659 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI, y >> 8); 660 WSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO, y & 0xff); 661 #else 662 *(acm + (ACM_CURSOR_POSITION+1)) = x >> 8; 663 *(acm + (ACM_CURSOR_POSITION+0)) = x & 0xff; 664 *(acm + (ACM_CURSOR_POSITION+3)) = y >> 8; 665 *(acm + (ACM_CURSOR_POSITION+2)) = y & 0xff; 666 #endif 667 } 668 669 u_short 670 rh_CompFQ(fq) 671 u_int fq; 672 { 673 /* yuck... this sure could need some explanation.. */ 674 675 unsigned long f = fq; 676 long n2 = 3; 677 long abw = 0x7fffffff; 678 long n1 = 3; 679 unsigned long m; 680 unsigned short erg = 0; 681 682 f *= 8; 683 684 do { 685 686 if (f <= 250000000) 687 break; 688 f /= 2; 689 690 } while (n2-- > 0); 691 692 if (n2 < 0) 693 return(0); 694 695 696 do { 697 long tmp; 698 699 f = fq; 700 f >>= 3; 701 f <<= n2; 702 f >>= 7; 703 704 m = (f * n1) / (14318180/1024); 705 706 if (m > 129) 707 break; 708 709 tmp = (((m * 14318180) >> n2) / n1) - fq; 710 if (tmp < 0) 711 tmp = -tmp; 712 713 if (tmp < abw) { 714 abw = tmp; 715 erg = (((n2 << 5) | (n1-2)) << 8) | (m-2); 716 } 717 718 } while ( (++n1) <= 21); 719 720 return(erg); 721 } 722 723 int 724 rh_mondefok(mdp) 725 struct MonDef *mdp; 726 { 727 switch(mdp->DEP) { 728 case 8: 729 case 16: 730 case 24: 731 return(1); 732 case 4: 733 if (mdp->FX == 4 || (mdp->FX >= 7 && mdp->FX <= 16)) 734 return(1); 735 /*FALLTHROUGH*/ 736 default: 737 return(0); 738 } 739 } 740 741 742 int 743 rh_load_mon(gp, md) 744 struct grf_softc *gp; 745 struct MonDef *md; 746 { 747 struct grfinfo *gi = &gp->g_display; 748 volatile caddr_t ba; 749 volatile caddr_t fb; 750 short FW, clksel, HDE = 0, VDE; 751 unsigned short *c, z; 752 const unsigned char *f; 753 754 ba = gp->g_regkva;; 755 fb = gp->g_fbkva; 756 757 /* provide all needed information in grf device-independant 758 * locations */ 759 gp->g_data = (caddr_t) md; 760 gi->gd_regaddr = (caddr_t) kvtop (ba); 761 gi->gd_regsize = LM_OFFSET; 762 gi->gd_fbaddr = (caddr_t) kvtop (fb); 763 gi->gd_fbsize = MEMSIZE *1024*1024; 764 #ifdef BANKEDDEVPAGER 765 /* we're not using banks NO MORE! */ 766 gi->gd_bank_size = 0; 767 #endif 768 gi->gd_colors = 1 << md->DEP; 769 gi->gd_planes = md->DEP; 770 771 if (md->DEP == 4) { 772 gi->gd_fbwidth = md->MW; 773 gi->gd_fbheight = md->MH; 774 gi->gd_fbx = 0; 775 gi->gd_fby = 0; 776 gi->gd_dwidth = md->TX * md->FX; 777 gi->gd_dheight = md->TY * md->FY; 778 gi->gd_dx = 0; 779 gi->gd_dy = 0; 780 } else { 781 gi->gd_fbwidth = md->TX; 782 gi->gd_fbheight = md->TY; 783 gi->gd_fbx = 0; 784 gi->gd_fby = 0; 785 gi->gd_dwidth = md->MW; 786 gi->gd_dheight = md->MH; 787 gi->gd_dx = 0; 788 gi->gd_dy = 0; 789 } 790 791 FW =0; 792 if (md->DEP == 4) { /* XXX some text-mode! */ 793 switch (md->FX) { 794 case 4: 795 FW = 0; 796 break; 797 case 7: 798 FW = 1; 799 break; 800 case 8: 801 FW = 2; 802 break; 803 case 9: 804 FW = 3; 805 break; 806 case 10: 807 FW = 4; 808 break; 809 case 11: 810 FW = 5; 811 break; 812 case 12: 813 FW = 6; 814 break; 815 case 13: 816 FW = 7; 817 break; 818 case 14: 819 FW = 8; 820 break; 821 case 15: 822 FW = 9; 823 break; 824 case 16: 825 FW = 11; 826 break; 827 default: 828 return(0); 829 break; 830 } 831 } 832 833 if (md->DEP == 4) HDE = (md->MW+md->FX-1)/md->FX; 834 else if (md->DEP == 8) HDE = (md->MW+3)/4; 835 else if (md->DEP == 16) HDE = (md->MW*2+3)/4; 836 else if (md->DEP == 24) HDE = (md->MW*3+3)/4; 837 838 VDE = md->MH-1; 839 840 clksel = 0; 841 842 vgaw(ba, GREG_MISC_OUTPUT_W, 0xe3 | ((clksel & 3) * 0x04)); 843 vgaw(ba, GREG_FEATURE_CONTROL_W, 0x00); 844 845 WSeq(ba, SEQ_ID_RESET, 0x00); 846 WSeq(ba, SEQ_ID_RESET, 0x03); 847 WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8)); 848 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 849 WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00); 850 WSeq(ba, SEQ_ID_MEMORY_MODE, 0x06); 851 WSeq(ba, SEQ_ID_RESET, 0x01); 852 WSeq(ba, SEQ_ID_RESET, 0x03); 853 854 WSeq(ba, SEQ_ID_EXTENDED_ENABLE, 0x05); 855 WSeq(ba, SEQ_ID_CURSOR_CONTROL, 0x00); 856 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00); 857 WSeq(ba, SEQ_ID_PRIM_HOST_OFF_HI, 0x00); 858 WSeq(ba, SEQ_ID_LINEAR_0, 0x4a); 859 WSeq(ba, SEQ_ID_LINEAR_1, 0x00); 860 861 WSeq(ba, SEQ_ID_SEC_HOST_OFF_HI, 0x00); 862 WSeq(ba, SEQ_ID_SEC_HOST_OFF_LO, 0x00); 863 WSeq(ba, SEQ_ID_EXTENDED_MEM_ENA, 0x3 | 0x4 | 0x10 | 0x40); 864 WSeq(ba, SEQ_ID_EXT_CLOCK_MODE, 0x10 | (FW & 0x0f)); 865 WSeq(ba, SEQ_ID_EXT_VIDEO_ADDR, 0x03); 866 if (md->DEP == 4) { 867 /* 8bit pixel, no gfx byte path */ 868 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x00); 869 } 870 else if (md->DEP == 8) { 871 /* 8bit pixel, gfx byte path */ 872 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x01); 873 } 874 else if (md->DEP == 16) { 875 /* 16bit pixel, gfx byte path */ 876 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x11); 877 } 878 else if (md->DEP == 24) { 879 /* 24bit pixel, gfx byte path */ 880 WSeq(ba, SEQ_ID_EXT_PIXEL_CNTL, 0x21); 881 } 882 WSeq(ba, SEQ_ID_BUS_WIDTH_FEEDB, 0x04); 883 WSeq(ba, SEQ_ID_COLOR_EXP_WFG, 0x01); 884 WSeq(ba, SEQ_ID_COLOR_EXP_WBG, 0x00); 885 WSeq(ba, SEQ_ID_EXT_RW_CONTROL, 0x00); 886 WSeq(ba, SEQ_ID_MISC_FEATURE_SEL, (0x51 | (clksel & 8))); 887 WSeq(ba, SEQ_ID_COLOR_KEY_CNTL, 0x40); 888 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH0, 0x00); 889 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH1, 0x00); 890 WSeq(ba, SEQ_ID_COLOR_KEY_MATCH2, 0x00); 891 WSeq(ba, SEQ_ID_CRC_CONTROL, 0x00); 892 WSeq(ba, SEQ_ID_PERF_SELECT, 0x10); 893 WSeq(ba, SEQ_ID_ACM_APERTURE_1, 0x00); 894 WSeq(ba, SEQ_ID_ACM_APERTURE_2, 0x30); 895 WSeq(ba, SEQ_ID_ACM_APERTURE_3, 0x00); 896 WSeq(ba, SEQ_ID_MEMORY_MAP_CNTL, 0x03); /* was 7, but stupid cursor */ 897 898 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x20); 899 WCrt(ba, CRT_ID_HOR_TOTAL, md->HT & 0xff); 900 WCrt(ba, CRT_ID_HOR_DISP_ENA_END, (HDE-1) & 0xff); 901 WCrt(ba, CRT_ID_START_HOR_BLANK, md->HBS & 0xff); 902 WCrt(ba, CRT_ID_END_HOR_BLANK, (md->HBE & 0x1f) | 0x80); 903 904 WCrt(ba, CRT_ID_START_HOR_RETR, md->HSS & 0xff); 905 WCrt(ba, CRT_ID_END_HOR_RETR, 906 (md->HSE & 0x1f) | 907 ((md->HBE & 0x20)/ 0x20 * 0x80)); 908 WCrt(ba, CRT_ID_VER_TOTAL, (md->VT & 0xff)); 909 WCrt(ba, CRT_ID_OVERFLOW, 910 ((md->VSS & 0x200) / 0x200 * 0x80) | 911 ((VDE & 0x200) / 0x200 * 0x40) | 912 ((md->VT & 0x200) / 0x200 * 0x20) | 913 0x10 | 914 ((md->VBS & 0x100) / 0x100 * 8) | 915 ((md->VSS & 0x100) / 0x100 * 4) | 916 ((VDE & 0x100) / 0x100 * 2) | 917 ((md->VT & 0x100) / 0x100)); 918 WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00); 919 920 if (md->DEP == 4) { 921 WCrt(ba, CRT_ID_MAX_SCAN_LINE, 922 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) | 923 0x40 | 924 ((md->VBS & 0x200)/0x200*0x20) | 925 ((md->FY-1) & 0x1f)); 926 } else { 927 WCrt(ba, CRT_ID_MAX_SCAN_LINE, 928 ((md->FLG & MDF_DBL)/ MDF_DBL * 0x80) | 929 0x40 | 930 ((md->VBS & 0x200)/0x200*0x20) | 931 (0 & 0x1f)); 932 } 933 934 /* I prefer "_" cursor to "block" cursor.. */ 935 #if 1 936 WCrt(ba, CRT_ID_CURSOR_START, (md->FY & 0x1f) - 2); 937 WCrt(ba, CRT_ID_CURSOR_END, (md->FY & 0x1f) - 1); 938 #else 939 WCrt(ba, CRT_ID_CURSOR_START, 0x00); 940 WCrt(ba, CRT_ID_CURSOR_END, md->FY & 0x1f); 941 #endif 942 943 WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00); 944 WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00); 945 946 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00); 947 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00); 948 949 WCrt(ba, CRT_ID_START_VER_RETR, md->VSS & 0xff); 950 WCrt(ba, CRT_ID_END_VER_RETR, (md->VSE & 0xf) | 0x80 | 0x20); 951 WCrt(ba, CRT_ID_VER_DISP_ENA_END, VDE & 0xff); 952 953 if (md->DEP == 4) { 954 WCrt(ba, CRT_ID_OFFSET, (HDE / 2) & 0xff ); 955 } 956 /* all gfx-modes are in byte-mode, means values are multiplied by 8 */ 957 else if (md->DEP == 8) { 958 WCrt(ba, CRT_ID_OFFSET, (md->TX / 8) & 0xff ); 959 } else if (md->DEP == 16) { 960 WCrt(ba, CRT_ID_OFFSET, (md->TX / 4) & 0xff ); 961 } else { 962 WCrt(ba, CRT_ID_OFFSET, (md->TX * 3 / 8) & 0xff ); 963 } 964 965 WCrt(ba, CRT_ID_UNDERLINE_LOC, (md->FY-1) & 0x1f); 966 WCrt(ba, CRT_ID_START_VER_BLANK, md->VBS & 0xff); 967 WCrt(ba, CRT_ID_END_VER_BLANK, md->VBE & 0xff); 968 WCrt(ba, CRT_ID_MODE_CONTROL, 0xe3); 969 WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); 970 971 WCrt(ba, CRT_ID_EXT_HOR_TIMING1, 972 0 | 0x20 | 973 ((md->FLG & MDF_LACE) / MDF_LACE * 0x10) | 974 ((md->HT & 0x100) / 0x100) | 975 (((HDE-1) & 0x100) / 0x100 * 2) | 976 ((md->HBS & 0x100) / 0x100 * 4) | 977 ((md->HSS & 0x100) / 0x100 * 8)); 978 979 if (md->DEP == 4) { 980 WCrt(ba, CRT_ID_EXT_START_ADDR, (((HDE / 2) & 0x100)/0x100 * 16)); 981 } 982 else if (md->DEP == 8) { 983 WCrt(ba, CRT_ID_EXT_START_ADDR, (((md->TX / 8) & 0x100)/0x100 * 16)); 984 } else if (md->DEP == 16) { 985 WCrt(ba, CRT_ID_EXT_START_ADDR, (((md->TX / 4) & 0x100)/0x100 * 16)); 986 } else { 987 WCrt(ba, CRT_ID_EXT_START_ADDR, (((md->TX * 3 / 8) & 0x100)/0x100 * 16)); 988 } 989 990 WCrt(ba, CRT_ID_EXT_HOR_TIMING2, 991 ((md->HT & 0x200)/ 0x200) | 992 (((HDE-1) & 0x200)/ 0x200 * 2 ) | 993 ((md->HBS & 0x200)/ 0x200 * 4 ) | 994 ((md->HSS & 0x200)/ 0x200 * 8 ) | 995 ((md->HBE & 0xc0) / 0x40 * 16 ) | 996 ((md->HSE & 0x60) / 0x20 * 64)); 997 998 WCrt(ba, CRT_ID_EXT_VER_TIMING, 999 ((md->VSE & 0x10) / 0x10 * 0x80 ) | 1000 ((md->VBE & 0x300)/ 0x100 * 0x20 ) | 1001 0x10 | 1002 ((md->VSS & 0x400)/ 0x400 * 8 ) | 1003 ((md->VBS & 0x400)/ 0x400 * 4 ) | 1004 ((VDE & 0x400)/ 0x400 * 2 ) | 1005 ((md->VT & 0x400)/ 0x400)); 1006 WCrt(ba, CRT_ID_MONITOR_POWER, 0x00); 1007 1008 { 1009 unsigned short tmp = rh_CompFQ(md->FQ); 1010 WPLL(ba, 2 , tmp); 1011 tmp = rh_CompFQ(rh_memclk); 1012 WPLL(ba,10 , tmp); 1013 WPLL(ba,14 , 0x22); 1014 } 1015 1016 WGfx(ba, GCT_ID_SET_RESET, 0x00); 1017 WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00); 1018 WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00); 1019 WGfx(ba, GCT_ID_DATA_ROTATE, 0x00); 1020 WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00); 1021 WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00); 1022 if (md->DEP == 4) 1023 WGfx(ba, GCT_ID_MISC, 0x04); 1024 else 1025 WGfx(ba, GCT_ID_MISC, 0x05); 1026 WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f); 1027 WGfx(ba, GCT_ID_BITMASK, 0xff); 1028 1029 vgar(ba, ACT_ADDRESS_RESET); 1030 WAttr(ba, ACT_ID_PALETTE0 , 0x00); 1031 WAttr(ba, ACT_ID_PALETTE1 , 0x01); 1032 WAttr(ba, ACT_ID_PALETTE2 , 0x02); 1033 WAttr(ba, ACT_ID_PALETTE3 , 0x03); 1034 WAttr(ba, ACT_ID_PALETTE4 , 0x04); 1035 WAttr(ba, ACT_ID_PALETTE5 , 0x05); 1036 WAttr(ba, ACT_ID_PALETTE6 , 0x06); 1037 WAttr(ba, ACT_ID_PALETTE7 , 0x07); 1038 WAttr(ba, ACT_ID_PALETTE8 , 0x08); 1039 WAttr(ba, ACT_ID_PALETTE9 , 0x09); 1040 WAttr(ba, ACT_ID_PALETTE10, 0x0a); 1041 WAttr(ba, ACT_ID_PALETTE11, 0x0b); 1042 WAttr(ba, ACT_ID_PALETTE12, 0x0c); 1043 WAttr(ba, ACT_ID_PALETTE13, 0x0d); 1044 WAttr(ba, ACT_ID_PALETTE14, 0x0e); 1045 WAttr(ba, ACT_ID_PALETTE15, 0x0f); 1046 1047 vgar(ba, ACT_ADDRESS_RESET); 1048 if (md->DEP == 4) 1049 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x08); 1050 else 1051 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x09); 1052 1053 WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00); 1054 WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f); 1055 WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00); 1056 WAttr(ba, ACT_ID_COLOR_SELECT, 0x00); 1057 1058 vgar(ba, ACT_ADDRESS_RESET); 1059 vgaw(ba, ACT_ADDRESS_W, 0x20); 1060 1061 vgaw(ba, VDAC_MASK, 0xff); 1062 /* probably some PLL timing stuff here. The value 1063 for 24bit was found by trial&error :-) */ 1064 if (md->DEP < 16) { 1065 vgaw(ba, 0x83c6, ((0 & 7) << 5) ); 1066 } 1067 else if (md->DEP == 16) { 1068 /* well... */ 1069 vgaw(ba, 0x83c6, ((3 & 7) << 5) ); 1070 } 1071 else if (md->DEP == 24) { 1072 vgaw(ba, 0x83c6, 0xe0); 1073 } 1074 vgaw(ba, VDAC_ADDRESS_W, 0x00); 1075 1076 if (md->DEP < 16) { 1077 short x = 256-17; 1078 unsigned char cl = 16; 1079 RZ3LoadPalette(gp, md->PAL, 0, 16); 1080 do { 1081 vgaw(ba, VDAC_DATA, (cl >> 2)); 1082 vgaw(ba, VDAC_DATA, (cl >> 2)); 1083 vgaw(ba, VDAC_DATA, (cl >> 2)); 1084 cl++; 1085 } while (x-- > 0); 1086 } 1087 1088 if (md->DEP == 4) { 1089 { 1090 struct grf_bitblt bb = { 1091 GRFBBOPset, 1092 0, 0, 1093 0, 0, 1094 md->TX*4, 2*md->TY, 1095 EMPTY_ALPHA 1096 }; 1097 RZ3BitBlit(gp, &bb); 1098 } 1099 1100 c = (unsigned short *)(ba + LM_OFFSET); 1101 c += 2 * md->FLo*32; 1102 c += 1; 1103 f = md->FData; 1104 for (z = md->FLo; z <= md->FHi; z++) { 1105 short y = md->FY-1; 1106 if (md->FX > 8){ 1107 do { 1108 *c = *((const unsigned short *)f); 1109 c += 2; 1110 f += 2; 1111 } while (y-- > 0); 1112 } else { 1113 do { 1114 *c = (*f++) << 8; 1115 c += 2; 1116 } while (y-- > 0); 1117 } 1118 1119 c += 2 * (32-md->FY); 1120 } 1121 { 1122 unsigned long * pt = (unsigned long *) (ba + LM_OFFSET + PAT_MEM_OFF); 1123 unsigned long tmp = 0xffff0000; 1124 *pt++ = tmp; 1125 *pt = tmp; 1126 } 1127 1128 WSeq(ba, SEQ_ID_MAP_MASK, 3); 1129 1130 c = (unsigned short *)(ba + LM_OFFSET); 1131 c += (md->TX-6)*2; 1132 { 1133 /* it's show-time :-) */ 1134 static unsigned short init_msg[6] = { 1135 0x520a, 0x450b, 0x540c, 0x490d, 0x4e0e, 0x410f 1136 }; 1137 unsigned short * m = init_msg; 1138 short x = 5; 1139 do { 1140 *c = *m++; 1141 c += 2; 1142 } while (x-- > 0); 1143 } 1144 1145 return(1); 1146 } else if (md->DEP == 8) { 1147 struct grf_bitblt bb = { 1148 GRFBBOPset, 1149 0, 0, 1150 0, 0, 1151 md->TX, md->TY, 1152 0x0000 1153 }; 1154 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 1155 1156 RZ3BitBlit(gp, &bb); 1157 1158 gi->gd_fbx = 0; 1159 gi->gd_fby = 0; 1160 1161 return(1); 1162 } else if (md->DEP == 16) { 1163 struct grf_bitblt bb = { 1164 GRFBBOPset, 1165 0, 0, 1166 0, 0, 1167 md->TX, md->TY, 1168 0x0000 1169 }; 1170 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 1171 1172 RZ3BitBlit16(gp, &bb); 1173 1174 gi->gd_fbx = 0; 1175 gi->gd_fby = 0; 1176 1177 return(1); 1178 } else if (md->DEP == 24) { 1179 struct grf_bitblt bb = { 1180 GRFBBOPset, 1181 0, 0, 1182 0, 0, 1183 md->TX, md->TY, 1184 0x0000 1185 }; 1186 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f ); 1187 1188 RZ3BitBlit24(gp, &bb ); 1189 1190 gi->gd_fbx = 0; 1191 gi->gd_fby = 0; 1192 1193 return 1; 1194 } else 1195 return(0); 1196 } 1197 1198 /* standard-palette definition */ 1199 1200 unsigned char RZ3StdPalette[16*3] = { 1201 /* R G B */ 1202 0, 0, 0, 1203 192,192,192, 1204 128, 0, 0, 1205 0,128, 0, 1206 0, 0,128, 1207 128,128, 0, 1208 0,128,128, 1209 128, 0,128, 1210 64, 64, 64, /* the higher 8 colors have more intensity for */ 1211 255,255,255, /* compatibility with standard attributes */ 1212 255, 0, 0, 1213 0,255, 0, 1214 0, 0,255, 1215 255,255, 0, 1216 0,255,255, 1217 255, 0,255 1218 }; 1219 1220 /* 1221 * The following structures are examples for monitor-definitions. To make one 1222 * of your own, first use "DefineMonitor" and create the 8-bit or 16-bit 1223 * monitor-mode of your dreams. Then save it, and make a structure from the 1224 * values provided in the file DefineMonitor stored - the labels in the comment 1225 * above the structure definition show where to put what value. 1226 * 1227 * If you want to use your definition for the text-mode, you'll need to adapt 1228 * your 8-bit monitor-definition to the font you want to use. Be FX the width of 1229 * the font, then the following modifications have to be applied to your values: 1230 * 1231 * HBS = (HBS * 4) / FX 1232 * HSS = (HSS * 4) / FX 1233 * HSE = (HSE * 4) / FX 1234 * HBE = (HBE * 4) / FX 1235 * HT = (HT * 4) / FX 1236 * 1237 * Make sure your maximum width (MW) and height (MH) are even multiples of 1238 * the fonts' width and height. 1239 * 1240 * You may use definitons created by the old DefineMonitor, but you'll get 1241 * better results with the new DefineMonitor supplied along with the Retin Z3. 1242 */ 1243 1244 /* 1245 * FQ FLG MW MH HBS HSS HSE HBE HT VBS VSS VSE VBE VT 1246 * Depth, PAL, TX, TY, XY,FontX, FontY, FontData, FLo, Fhi 1247 */ 1248 #ifdef KFONT_8X11 1249 #define KERNEL_FONT kernel_font_8x11 1250 #define FY 11 1251 #define FX 8 1252 #else 1253 #define KERNEL_FONT kernel_font_8x8 1254 #define FY 8 1255 #define FX 8 1256 #endif 1257 1258 1259 static struct MonDef monitor_defs[] = { 1260 /* Text-mode definitions */ 1261 1262 /* horizontal 31.5 kHz */ 1263 { 50000000, 28, 640, 512, 81, 86, 93, 98, 95, 513, 513, 521, 535, 535, 1264 4, RZ3StdPalette, 80, 64, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1265 1266 /* horizontal 38kHz */ 1267 { 75000000, 28, 768, 600, 97, 99,107,120,117, 601, 615, 625, 638, 638, 1268 4, RZ3StdPalette, 96, 75, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1269 1270 /* horizontal 64kHz */ 1271 { 50000000, 24, 768, 600, 97,104,112,122,119, 601, 606, 616, 628, 628, 1272 4, RZ3StdPalette, 96, 75, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1273 1274 /* 8-bit gfx-mode definitions */ 1275 1276 /* IMPORTANT: the "logical" screen size can be up to 2048x2048 pixels, 1277 independent from the "physical" screen size. If your code does NOT 1278 support panning, please adjust the "logical" screen sizes below to 1279 match the physical ones 1280 */ 1281 1282 #ifdef RH_HARDWARECURSOR 1283 1284 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */ 1285 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502, 1286 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1287 /* This is the logical ^ ^ screen size */ 1288 1289 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */ 1290 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502, 1291 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1292 1293 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */ 1294 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628, 1295 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1296 1297 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */ 1298 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804, 1299 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1300 1301 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */ 1302 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938, 1303 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1304 1305 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */ 1306 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953, 1307 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1308 1309 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */ 1310 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888, 1311 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1312 1313 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */ 1314 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073, 1315 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1316 1317 /* 1318 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR 1319 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT 1320 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! 1321 */ 1322 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */ 1323 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073, 1324 8, RZ3StdPalette,1280,1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1325 1326 1327 /* 16-bit gfx-mode definitions */ 1328 1329 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */ 1330 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502, 1331 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1332 1333 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */ 1334 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628, 1335 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1336 1337 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */ 1338 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804, 1339 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1340 1341 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */ 1342 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678, 1343 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1344 1345 /* 1346 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR 1347 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT 1348 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! 1349 */ 1350 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */ 1351 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804, 1352 16, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1353 1354 1355 /* 24-bit gfx-mode definitions */ 1356 1357 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */ 1358 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418, 1359 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1360 1361 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */ 1362 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418, 1363 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1364 1365 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */ 1366 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504, 1367 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1368 1369 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */ 1370 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628, 1371 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1372 1373 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */ 1374 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628, 1375 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1376 1377 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */ 1378 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401, 1379 24, 0,1280, 1024, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1380 1381 #else /* RH_HARDWARECURSOR */ 1382 1383 /* 640 x 480, 8 Bit, 31862 Hz, 63 Hz */ 1384 { 26000000, 0, 640, 480, 161,175,188,200,199, 481, 483, 491, 502, 502, 1385 8, RZ3StdPalette, 640, 480, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1386 /* This is the logical ^ ^ screen size */ 1387 1388 /* 640 x 480, 8 Bit, 38366 Hz, 76 Hz */ 1389 { 31000000, 0, 640, 480, 161,169,182,198,197, 481, 482, 490, 502, 502, 1390 8, RZ3StdPalette, 640, 480, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1391 1392 /* 800 x 600, 8 Bit, 38537 Hz, 61 Hz */ 1393 { 39000000, 0, 800, 600, 201,211,227,249,248, 601, 603, 613, 628, 628, 1394 8, RZ3StdPalette, 800, 600, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1395 1396 /* 1024 x 768, 8 Bit, 63862 Hz, 79 Hz */ 1397 { 82000000, 0, 1024, 768, 257,257,277,317,316, 769, 771, 784, 804, 804, 1398 8, RZ3StdPalette, 1024, 768, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1399 1400 /* 1120 x 896, 8 Bit, 64000 Hz, 69 Hz */ 1401 { 97000000, 0, 1120, 896, 281,283,306,369,368, 897, 898, 913, 938, 938, 1402 8, RZ3StdPalette, 1120, 896, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1403 1404 /* 1152 x 910, 8 Bit, 76177 Hz, 79 Hz */ 1405 {110000000, 0, 1152, 910, 289,310,333,357,356, 911, 923, 938, 953, 953, 1406 8, RZ3StdPalette, 1152, 910, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1407 1408 /* 1184 x 848, 8 Bit, 73529 Hz, 82 Hz */ 1409 {110000000, 0, 1184, 848, 297,319,342,370,369, 849, 852, 866, 888, 888, 1410 8, RZ3StdPalette, 1184, 848, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1411 1412 /* 1280 x 1024, 8 Bit, 64516 Hz, 60 Hz */ 1413 {104000000, 0, 1280,1024, 321,323,348,399,398,1025,1026,1043,1073,1073, 1414 8, RZ3StdPalette, 1280, 1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1415 1416 /* 1417 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR 1418 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT 1419 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! 1420 */ 1421 /* 1280 x 1024, 8 Bit, 75436 Hz, 70 Hz */ 1422 {121000000, 0, 1280,1024, 321,322,347,397,396,1025,1026,1043,1073,1073, 1423 8, RZ3StdPalette, 1280, 1024, 5120, FX, FY, KERNEL_FONT, 32, 255}, 1424 1425 1426 /* 16-bit gfx-mode definitions */ 1427 1428 /* 640 x 480, 16 Bit, 31795 Hz, 63 Hz */ 1429 { 51000000, 0, 640, 480, 321,344,369,397,396, 481, 482, 490, 502, 502, 1430 16, 0, 640, 480, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1431 1432 /* 800 x 600, 16 Bit, 38500 Hz, 61 Hz */ 1433 { 77000000, 0, 800, 600, 401,418,449,496,495, 601, 602, 612, 628, 628, 1434 16, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1435 1436 /* 1024 x 768, 16 Bit, 42768 Hz, 53 Hz */ 1437 {110000000, 0, 1024, 768, 513,514,554,639,638, 769, 770, 783, 804, 804, 1438 16, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1439 1440 /* 864 x 648, 16 Bit, 50369 Hz, 74 Hz */ 1441 {109000000, 0, 864, 648, 433,434,468,537,536, 649, 650, 661, 678, 678, 1442 16, 0, 864, 648, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1443 1444 /* 1445 * WARNING: THE FOLLOWING MONITOR MODE EXCEEDS THE 110-MHz LIMIT THE PROCESSOR 1446 * HAS BEEN SPECIFIED FOR. USE AT YOUR OWN RISK (AND THINK ABOUT 1447 * MOUNTING SOME COOLING DEVICE AT THE PROCESSOR AND RAMDAC)! 1448 */ 1449 /* 1024 x 768, 16 Bit, 48437 Hz, 60 Hz */ 1450 {124000000, 0, 1024, 768, 513,537,577,636,635, 769, 770, 783, 804, 804, 1451 16, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1452 1453 1454 /* 24-bit gfx-mode definitions */ 1455 1456 /* 320 x 200, 24 Bit, 35060 Hz, 83 Hz d */ 1457 { 46000000, 1, 320, 200, 241,268,287,324,323, 401, 405, 412, 418, 418, 1458 24, 0, 320, 200, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1459 1460 /* 640 x 400, 24 Bit, 31404 Hz, 75 Hz */ 1461 { 76000000, 0, 640, 400, 481,514,552,601,600, 401, 402, 409, 418, 418, 1462 24, 0, 640, 400, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1463 1464 /* 724 x 482, 24 Bit, 36969 Hz, 73 Hz */ 1465 {101000000, 0, 724, 482, 544,576,619,682,678, 483, 487, 495, 495, 504, 1466 24, 0, 724, 482, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1467 1468 /* 800 x 600, 24 Bit, 37826 Hz, 60 Hz */ 1469 {110000000, 0, 800, 600, 601,602,647,723,722, 601, 602, 612, 628, 628, 1470 24, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1471 1472 /* 800 x 600, 24 Bit, 43824 Hz, 69 Hz */ 1473 {132000000, 0, 800, 600, 601,641,688,749,748, 601, 611, 621, 628, 628, 1474 24, 0, 800, 600, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1475 1476 /*1024 x 768, 24 Bit, 32051 Hz, 79 Hz i */ 1477 {110000000, 2, 1024, 768, 769,770,824,854,853, 385, 386, 392, 401, 401, 1478 24, 0, 1024, 768, 7200, FX, FY, KERNEL_FONT, 32, 255}, 1479 1480 #endif /* RH_HARDWARECURSOR */ 1481 }; 1482 #undef KERNEL_FONT 1483 #undef FX 1484 #undef FY 1485 1486 static const char *monitor_descr[] = { 1487 #ifdef KFONT_8X11 1488 "80x46 (640x506) 31.5kHz", 1489 "96x54 (768x594) 38kHz", 1490 "96x54 (768x594) 64kHz", 1491 #else 1492 "80x64 (640x512) 31.5kHz", 1493 "96x75 (768x600) 38kHz", 1494 "96x75 (768x600) 64kHz", 1495 #endif 1496 1497 "GFX-8 (640x480) 31.5kHz", 1498 "GFX-8 (640x480) 38kHz", 1499 "GFX-8 (800x600) 38.5kHz", 1500 "GFX-8 (1024x768) 64kHz", 1501 "GFX-8 (1120x896) 64kHz", 1502 "GFX-8 (1152x910) 76kHz", 1503 "GFX-8 (1182x848) 73kHz", 1504 "GFX-8 (1280x1024) 64.5kHz", 1505 "GFX-8 (1280x1024) 75.5kHz ***EXCEEDS CHIP LIMIT!!!***", 1506 1507 "GFX-16 (640x480) 31.8kHz", 1508 "GFX-16 (800x600) 38.5kHz", 1509 "GFX-16 (1024x768) 42.8kHz", 1510 "GFX-16 (864x648) 50kHz", 1511 "GFX-16 (1024x768) 48.5kHz ***EXCEEDS CHIP LIMIT!!!***", 1512 1513 "GFX-24 (320x200 d) 35kHz", 1514 "GFX-24 (640x400) 31.4kHz", 1515 "GFX-24 (724x482) 37kHz", 1516 "GFX-24 (800x600) 38kHz", 1517 "GFX-24 (800x600) 44kHz ***EXCEEDS CHIP LIMIT!!!***", 1518 "GFX-24 (1024x768) 32kHz-i", 1519 }; 1520 1521 int rh_mon_max = sizeof (monitor_defs)/sizeof (monitor_defs[0]); 1522 1523 /* patchable */ 1524 int rh_default_mon = 0; 1525 int rh_default_gfx = 4; 1526 1527 static struct MonDef *current_mon; /* EVIL */ 1528 1529 int rh_mode __P((struct grf_softc *, u_long, void *, u_long, int)); 1530 void grfrhattach __P((struct device *, struct device *, void *)); 1531 int grfrhprint __P((void *, const char *)); 1532 int grfrhmatch __P((struct device *, struct cfdata *, void *)); 1533 1534 struct cfattach grfrh_ca = { 1535 sizeof(struct grf_softc), grfrhmatch, grfrhattach 1536 }; 1537 1538 struct cfdriver grfrh_cd = { 1539 NULL, "grfrh", DV_DULL, NULL, 0 1540 }; 1541 1542 static struct cfdata *cfdata; 1543 1544 int 1545 grfrhmatch(pdp, cfp, auxp) 1546 struct device *pdp; 1547 struct cfdata *cfp; 1548 void *auxp; 1549 { 1550 #ifdef RETINACONSOLE 1551 static int rhconunit = -1; 1552 #endif 1553 struct zbus_args *zap; 1554 1555 zap = auxp; 1556 1557 if (amiga_realconfig == 0) 1558 #ifdef RETINACONSOLE 1559 if (rhconunit != -1) 1560 #endif 1561 return(0); 1562 if (zap->manid != 18260 || 1563 ((zap->prodid != 16) && (zap->prodid != 19))) 1564 return(0); 1565 #ifdef RETINACONSOLE 1566 if (amiga_realconfig == 0 || rhconunit != cfp->cf_unit) { 1567 #endif 1568 if ((unsigned)rh_default_mon >= rh_mon_max || 1569 monitor_defs[rh_default_mon].DEP == 8) 1570 rh_default_mon = 0; 1571 current_mon = monitor_defs + rh_default_mon; 1572 if (rh_mondefok(current_mon) == 0) 1573 return(0); 1574 #ifdef RETINACONSOLE 1575 if (amiga_realconfig == 0) { 1576 rhconunit = cfp->cf_unit; 1577 cfdata = cfp; 1578 } 1579 } 1580 #endif 1581 return(1); 1582 } 1583 1584 void 1585 grfrhattach(pdp, dp, auxp) 1586 struct device *pdp, *dp; 1587 void *auxp; 1588 { 1589 static struct grf_softc congrf; 1590 struct zbus_args *zap; 1591 struct grf_softc *gp; 1592 1593 zap = auxp; 1594 1595 if (dp == NULL) 1596 gp = &congrf; 1597 else 1598 gp = (struct grf_softc *)dp; 1599 if (dp != NULL && congrf.g_regkva != 0) { 1600 /* 1601 * inited earlier, just copy (not device struct) 1602 */ 1603 bcopy(&congrf.g_display, &gp->g_display, 1604 (char *)&gp[1] - (char *)&gp->g_display); 1605 } else { 1606 gp->g_regkva = (volatile caddr_t)zap->va; 1607 gp->g_fbkva = (volatile caddr_t)zap->va + LM_OFFSET; 1608 gp->g_unit = GRF_RETINAIII_UNIT; 1609 gp->g_mode = rh_mode; 1610 gp->g_conpri = grfrh_cnprobe(); 1611 gp->g_flags = GF_ALIVE; 1612 grfrh_iteinit(gp); 1613 (void)rh_load_mon(gp, current_mon); 1614 } 1615 if (dp != NULL) 1616 printf("\n"); 1617 /* 1618 * attach grf 1619 */ 1620 amiga_config_found(cfdata, &gp->g_device, gp, grfrhprint); 1621 } 1622 1623 int 1624 grfrhprint(auxp, pnp) 1625 void *auxp; 1626 const char *pnp; 1627 { 1628 if (pnp) 1629 printf("ite at %s", pnp); 1630 return(UNCONF); 1631 } 1632 1633 int 1634 rh_getvmode(gp, vm) 1635 struct grf_softc *gp; 1636 struct grfvideo_mode *vm; 1637 { 1638 struct MonDef *md; 1639 int vmul; 1640 1641 if (vm->mode_num && vm->mode_num > rh_mon_max) 1642 return(EINVAL); 1643 1644 if (! vm->mode_num) 1645 vm->mode_num = (current_mon - monitor_defs) + 1; 1646 1647 md = monitor_defs + (vm->mode_num - 1); 1648 strncpy (vm->mode_descr, monitor_descr[vm->mode_num - 1], 1649 sizeof (vm->mode_descr)); 1650 vm->pixel_clock = md->FQ; 1651 vm->disp_width = (md->DEP == 4) ? md->MW : md->TX; 1652 vm->disp_height = (md->DEP == 4) ? md->MH : md->TY; 1653 vm->depth = md->DEP; 1654 1655 /* 1656 * From observation of the monitor definition table above, I guess 1657 * that the horizontal timings are in units of longwords. Hence, I 1658 * get the pixels by multiplication with 32 and division by the depth. 1659 * The text modes, apparently marked by depth == 4, are even more 1660 * wierd. According to a comment above, they are computed from a 1661 * depth==8 mode thats for us: * 32 / 8) by applying another factor 1662 * of 4 / font width. 1663 * Reverse applying the latter formula most of the constants cancel 1664 * themselves and we are left with a nice (* font width). 1665 * That is, internal timings are in units of longwords for graphics 1666 * modes, or in units of characters widths for text modes. 1667 * We better don't WRITE modes until this has been real live checked. 1668 * - Ignatios Souvatzis 1669 */ 1670 1671 if (md->DEP != 4) { 1672 vm->hblank_start = md->HBS * 32 / md->DEP; 1673 vm->hsync_start = md->HSS * 32 / md->DEP; 1674 vm->hsync_stop = md->HSE * 32 / md->DEP; 1675 vm->htotal = md->HT * 32 / md->DEP; 1676 } else { 1677 vm->hblank_start = md->HBS * md->FX; 1678 vm->hsync_start = md->HSS * md->FX; 1679 vm->hsync_stop = md->HSE * md->FX; 1680 vm->htotal = md->HT * md->FX; 1681 } 1682 1683 /* XXX move vm->disp_flags and vmul to rh_load_mon 1684 * if rh_setvmode can add new modes with grfconfig */ 1685 vm->disp_flags = 0; 1686 vmul = 2; 1687 if (md->FLG & MDF_DBL) { 1688 vm->disp_flags |= GRF_FLAGS_DBLSCAN; 1689 vmul = 4; 1690 } 1691 if (md->FLG & MDF_LACE) { 1692 vm->disp_flags |= GRF_FLAGS_LACE; 1693 vmul = 1; 1694 } 1695 vm->vblank_start = md->VBS * vmul / 2; 1696 vm->vsync_start = md->VSS * vmul / 2; 1697 vm->vsync_stop = md->VSE * vmul / 2; 1698 vm->vtotal = md->VT * vmul / 2; 1699 1700 return(0); 1701 } 1702 1703 1704 int 1705 rh_setvmode(gp, mode, type) 1706 struct grf_softc *gp; 1707 unsigned mode; 1708 enum mode_type type; 1709 { 1710 int error; 1711 1712 if (!mode || mode > rh_mon_max) 1713 return(EINVAL); 1714 1715 if ((type == MT_TXTONLY && monitor_defs[mode-1].DEP != 4) 1716 || (type == MT_GFXONLY && monitor_defs[mode-1].DEP == 4)) 1717 return(EINVAL); 1718 1719 current_mon = monitor_defs + (mode - 1); 1720 1721 error = rh_load_mon (gp, current_mon) ? 0 : EINVAL; 1722 1723 return(error); 1724 } 1725 1726 1727 /* 1728 * Change the mode of the display. 1729 * Return a UNIX error number or 0 for success. 1730 */ 1731 int 1732 rh_mode(gp, cmd, arg, a2, a3) 1733 register struct grf_softc *gp; 1734 u_long cmd; 1735 void *arg; 1736 u_long a2; 1737 int a3; 1738 { 1739 switch (cmd) { 1740 case GM_GRFON: 1741 rh_setvmode (gp, rh_default_gfx + 1, MT_GFXONLY); 1742 return(0); 1743 1744 case GM_GRFOFF: 1745 rh_setvmode (gp, rh_default_mon + 1, MT_TXTONLY); 1746 return(0); 1747 1748 case GM_GRFCONFIG: 1749 return(0); 1750 1751 case GM_GRFGETVMODE: 1752 return(rh_getvmode (gp, (struct grfvideo_mode *) arg)); 1753 1754 case GM_GRFSETVMODE: 1755 return(rh_setvmode (gp, *(unsigned *) arg, 1756 (gp->g_flags & GF_GRFON) ? MT_GFXONLY : MT_TXTONLY)); 1757 1758 case GM_GRFGETNUMVM: 1759 *(int *)arg = rh_mon_max; 1760 return(0); 1761 1762 #ifdef BANKEDDEVPAGER 1763 case GM_GRFGETBANK: 1764 case GM_GRFGETCURBANK: 1765 case GM_GRFSETBANK: 1766 return(EINVAL); 1767 #endif 1768 case GM_GRFIOCTL: 1769 return(rh_ioctl (gp, a2, arg)); 1770 1771 default: 1772 break; 1773 } 1774 1775 return(EINVAL); 1776 } 1777 1778 int 1779 rh_ioctl (gp, cmd, data) 1780 register struct grf_softc *gp; 1781 u_long cmd; 1782 void *data; 1783 { 1784 switch (cmd) { 1785 #ifdef RH_HARDWARECURSOR 1786 case GRFIOCGSPRITEPOS: 1787 return(rh_getspritepos (gp, (struct grf_position *) data)); 1788 1789 case GRFIOCSSPRITEPOS: 1790 return(rh_setspritepos (gp, (struct grf_position *) data)); 1791 1792 case GRFIOCSSPRITEINF: 1793 return(rh_setspriteinfo (gp, (struct grf_spriteinfo *) data)); 1794 1795 case GRFIOCGSPRITEINF: 1796 return(rh_getspriteinfo (gp, (struct grf_spriteinfo *) data)); 1797 1798 case GRFIOCGSPRITEMAX: 1799 return(rh_getspritemax (gp, (struct grf_position *) data)); 1800 #else /* RH_HARDWARECURSOR */ 1801 case GRFIOCGSPRITEPOS: 1802 case GRFIOCSSPRITEPOS: 1803 case GRFIOCSSPRITEINF: 1804 case GRFIOCGSPRITEMAX: 1805 break; 1806 #endif /* RH_HARDWARECURSOR */ 1807 1808 case GRFIOCGETCMAP: 1809 return(rh_getcmap (gp, (struct grf_colormap *) data)); 1810 1811 case GRFIOCPUTCMAP: 1812 return(rh_putcmap (gp, (struct grf_colormap *) data)); 1813 1814 case GRFIOCBITBLT: 1815 return(rh_bitblt (gp, (struct grf_bitblt *) data)); 1816 1817 case GRFIOCBLANK: 1818 return (rh_blank(gp, (int *)data)); 1819 } 1820 1821 return(EINVAL); 1822 } 1823 1824 1825 int 1826 rh_getcmap (gfp, cmap) 1827 struct grf_softc *gfp; 1828 struct grf_colormap *cmap; 1829 { 1830 volatile unsigned char *ba; 1831 u_char red[256], green[256], blue[256], *rp, *gp, *bp; 1832 short x; 1833 int error; 1834 1835 if (cmap->count == 0 || cmap->index >= 256) 1836 return 0; 1837 1838 if (cmap->index + cmap->count > 256) 1839 cmap->count = 256 - cmap->index; 1840 1841 ba = gfp->g_regkva; 1842 /* first read colors out of the chip, then copyout to userspace */ 1843 vgaw (ba, VDAC_ADDRESS_W, cmap->index); 1844 x = cmap->count - 1; 1845 rp = red + cmap->index; 1846 gp = green + cmap->index; 1847 bp = blue + cmap->index; 1848 do { 1849 *rp++ = vgar (ba, VDAC_DATA) << 2; 1850 *gp++ = vgar (ba, VDAC_DATA) << 2; 1851 *bp++ = vgar (ba, VDAC_DATA) << 2; 1852 } while (x-- > 0); 1853 1854 if (!(error = copyout (red + cmap->index, cmap->red, cmap->count)) 1855 && !(error = copyout (green + cmap->index, cmap->green, cmap->count)) 1856 && !(error = copyout (blue + cmap->index, cmap->blue, cmap->count))) 1857 return(0); 1858 1859 return(error); 1860 } 1861 1862 int 1863 rh_putcmap (gfp, cmap) 1864 struct grf_softc *gfp; 1865 struct grf_colormap *cmap; 1866 { 1867 volatile unsigned char *ba; 1868 u_char red[256], green[256], blue[256], *rp, *gp, *bp; 1869 short x; 1870 int error; 1871 1872 if (cmap->count == 0 || cmap->index >= 256) 1873 return(0); 1874 1875 if (cmap->index + cmap->count > 256) 1876 cmap->count = 256 - cmap->index; 1877 1878 /* first copy the colors into kernelspace */ 1879 if (!(error = copyin (cmap->red, red + cmap->index, cmap->count)) 1880 && !(error = copyin (cmap->green, green + cmap->index, cmap->count)) 1881 && !(error = copyin (cmap->blue, blue + cmap->index, cmap->count))) { 1882 /* argl.. LoadPalette wants a different format, so do it like with 1883 * Retina2.. */ 1884 ba = gfp->g_regkva; 1885 vgaw (ba, VDAC_ADDRESS_W, cmap->index); 1886 x = cmap->count - 1; 1887 rp = red + cmap->index; 1888 gp = green + cmap->index; 1889 bp = blue + cmap->index; 1890 do { 1891 vgaw (ba, VDAC_DATA, *rp++ >> 2); 1892 vgaw (ba, VDAC_DATA, *gp++ >> 2); 1893 vgaw (ba, VDAC_DATA, *bp++ >> 2); 1894 } while (x-- > 0); 1895 return(0); 1896 } 1897 else 1898 return(error); 1899 } 1900 1901 int 1902 rh_getspritepos (gp, pos) 1903 struct grf_softc *gp; 1904 struct grf_position *pos; 1905 { 1906 struct grfinfo *gi = &gp->g_display; 1907 #if 1 1908 volatile unsigned char *ba = gp->g_regkva; 1909 1910 pos->x = (RSeq(ba, SEQ_ID_CURSOR_X_LOC_HI) << 8) | 1911 RSeq(ba, SEQ_ID_CURSOR_X_LOC_LO); 1912 pos->y = (RSeq(ba, SEQ_ID_CURSOR_Y_LOC_HI) << 8) | 1913 RSeq(ba, SEQ_ID_CURSOR_Y_LOC_LO); 1914 #else 1915 volatile unsigned char *acm = gp->g_regkva + ACM_OFFSET; 1916 1917 pos->x = acm[ACM_CURSOR_POSITION + 0] + 1918 (acm[ACM_CURSOR_POSITION + 1] << 8); 1919 pos->y = acm[ACM_CURSOR_POSITION + 2] + 1920 (acm[ACM_CURSOR_POSITION + 3] << 8); 1921 #endif 1922 pos->x += gi->gd_fbx; 1923 pos->y += gi->gd_fby; 1924 1925 return(0); 1926 } 1927 1928 int 1929 rh_setspritepos (gp, pos) 1930 struct grf_softc *gp; 1931 struct grf_position *pos; 1932 { 1933 RZ3SetHWCloc (gp, pos->x, pos->y); 1934 return(0); 1935 } 1936 1937 int 1938 rh_getspriteinfo (gp, info) 1939 struct grf_softc *gp; 1940 struct grf_spriteinfo *info; 1941 { 1942 volatile unsigned char *ba, *fb; 1943 1944 ba = gp->g_regkva; 1945 fb = gp->g_fbkva; 1946 if (info->set & GRFSPRSET_ENABLE) 1947 info->enable = RSeq (ba, SEQ_ID_CURSOR_CONTROL) & 0x01; 1948 if (info->set & GRFSPRSET_POS) 1949 rh_getspritepos (gp, &info->pos); 1950 if (info->set & GRFSPRSET_HOT) { 1951 info->hot.x = RSeq (ba, SEQ_ID_CURSOR_X_INDEX) & 0x3f; 1952 info->hot.y = RSeq (ba, SEQ_ID_CURSOR_Y_INDEX) & 0x7f; 1953 } 1954 if (info->set & GRFSPRSET_CMAP) { 1955 struct grf_colormap cmap; 1956 int index; 1957 cmap.index = 0; 1958 cmap.count = 256; 1959 rh_getcmap (gp, &cmap); 1960 index = RSeq (ba, SEQ_ID_CURSOR_COLOR0); 1961 info->cmap.red[0] = cmap.red[index]; 1962 info->cmap.green[0] = cmap.green[index]; 1963 info->cmap.blue[0] = cmap.blue[index]; 1964 index = RSeq (ba, SEQ_ID_CURSOR_COLOR1); 1965 info->cmap.red[1] = cmap.red[index]; 1966 info->cmap.green[1] = cmap.green[index]; 1967 info->cmap.blue[1] = cmap.blue[index]; 1968 } 1969 if (info->set & GRFSPRSET_SHAPE) { 1970 u_char image[128], mask[128]; 1971 volatile u_long *hwp; 1972 u_char *imp, *mp; 1973 short row; 1974 1975 /* sprite bitmap is WEIRD in this chip.. see grf_rhvar.h 1976 * for an explanation. To convert to "our" format, the 1977 * following holds: 1978 * col2 = !image & mask 1979 * col1 = image & mask 1980 * transp = !mask 1981 * and thus: 1982 * image = col1 1983 * mask = col1 | col2 1984 * hope I got these bool-eqs right below.. 1985 */ 1986 1987 #ifdef RH_64BIT_SPRITE 1988 info->size.x = 64; 1989 info->size.y = 64; 1990 for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF), 1991 mp = mask, imp = image; 1992 row < 64; 1993 row++) { 1994 u_long bp10, bp20, bp11, bp21; 1995 bp10 = *hwp++; 1996 bp20 = *hwp++; 1997 bp11 = *hwp++; 1998 bp21 = *hwp++; 1999 M2I (bp10); 2000 M2I (bp20); 2001 M2I (bp11); 2002 M2I (bp21); 2003 *imp++ = (~bp10) & bp11; 2004 *imp++ = (~bp20) & bp21; 2005 *mp++ = (~bp10) | (bp10 & ~bp11); 2006 *mp++ = (~bp20) & (bp20 & ~bp21); 2007 } 2008 #else 2009 info->size.x = 32; 2010 info->size.y = 32; 2011 for (row = 0, hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF), 2012 mp = mask, imp = image; 2013 row < 32; 2014 row++) { 2015 u_long bp10, bp11; 2016 bp10 = *hwp++; 2017 bp11 = *hwp++; 2018 M2I (bp10); 2019 M2I (bp11); 2020 *imp++ = (~bp10) & bp11; 2021 *mp++ = (~bp10) | (bp10 & ~bp11); 2022 } 2023 #endif 2024 copyout (image, info->image, sizeof (image)); 2025 copyout (mask, info->mask, sizeof (mask)); 2026 } 2027 return(0); 2028 } 2029 2030 int 2031 rh_setspriteinfo (gp, info) 2032 struct grf_softc *gp; 2033 struct grf_spriteinfo *info; 2034 { 2035 volatile unsigned char *ba, *fb; 2036 #if 0 2037 u_char control; 2038 #endif 2039 2040 ba = gp->g_regkva; 2041 fb = gp->g_fbkva; 2042 2043 if (info->set & GRFSPRSET_SHAPE) { 2044 /* 2045 * For an explanation of these weird actions here, see above 2046 * when reading the shape. We set the shape directly into 2047 * the video memory, there's no reason to keep 1k on the 2048 * kernel stack just as template 2049 */ 2050 u_char *image, *mask; 2051 volatile u_long *hwp; 2052 u_char *imp, *mp; 2053 short row; 2054 2055 #ifdef RH_64BIT_SPRITE 2056 if (info->size.y > 64) 2057 info->size.y = 64; 2058 if (info->size.x > 64) 2059 info->size.x = 64; 2060 #else 2061 if (info->size.y > 32) 2062 info->size.y = 32; 2063 if (info->size.x > 32) 2064 info->size.x = 32; 2065 #endif 2066 2067 if (info->size.x < 32) 2068 info->size.x = 32; 2069 2070 image = malloc(HWC_MEM_SIZE, M_TEMP, M_WAITOK); 2071 mask = image + HWC_MEM_SIZE/2; 2072 2073 copyin(info->image, image, info->size.y * info->size.x / 8); 2074 copyin(info->mask, mask, info->size.y * info->size.x / 8); 2075 2076 hwp = (u_long *)(ba + LM_OFFSET + HWC_MEM_OFF); 2077 2078 /* 2079 * setting it is slightly more difficult, because we can't 2080 * force the application to not pass a *smaller* than 2081 * supported bitmap 2082 */ 2083 2084 for (row = 0, mp = mask, imp = image; 2085 row < info->size.y; 2086 row++) { 2087 u_long im1, im2, m1, m2; 2088 2089 im1 = *(unsigned long *)imp; 2090 imp += 4; 2091 m1 = *(unsigned long *)mp; 2092 mp += 4; 2093 #ifdef RH_64BIT_SPRITE 2094 if (info->size.x > 32) { 2095 im2 = *(unsigned long *)imp; 2096 imp += 4; 2097 m2 = *(unsigned long *)mp; 2098 mp += 4; 2099 } 2100 else 2101 #endif 2102 im2 = m2 = 0; 2103 2104 M2I(im1); 2105 M2I(im2); 2106 M2I(m1); 2107 M2I(m2); 2108 2109 *hwp++ = ~m1; 2110 #ifdef RH_64BIT_SPRITE 2111 *hwp++ = ~m2; 2112 #endif 2113 *hwp++ = m1 & im1; 2114 #ifdef RH_64BIT_SPRITE 2115 *hwp++ = m2 & im2; 2116 #endif 2117 } 2118 #ifdef RH_64BIT_SPRITE 2119 for (; row < 64; row++) { 2120 *hwp++ = 0xffffffff; 2121 *hwp++ = 0xffffffff; 2122 *hwp++ = 0x00000000; 2123 *hwp++ = 0x00000000; 2124 } 2125 #else 2126 for (; row < 32; row++) { 2127 *hwp++ = 0xffffffff; 2128 *hwp++ = 0x00000000; 2129 } 2130 #endif 2131 2132 free(image, M_TEMP); 2133 RZ3SetupHWC(gp, 1, 0, 0, 0, 0); 2134 } 2135 if (info->set & GRFSPRSET_CMAP) { 2136 /* hey cheat a bit here.. XXX */ 2137 WSeq(ba, SEQ_ID_CURSOR_COLOR0, 0); 2138 WSeq(ba, SEQ_ID_CURSOR_COLOR1, 1); 2139 } 2140 if (info->set & GRFSPRSET_ENABLE) { 2141 #if 0 2142 if (info->enable) 2143 control = 0x85; 2144 else 2145 control = 0; 2146 WSeq(ba, SEQ_ID_CURSOR_CONTROL, control); 2147 #endif 2148 } 2149 if (info->set & GRFSPRSET_POS) 2150 rh_setspritepos(gp, &info->pos); 2151 if (info->set & GRFSPRSET_HOT) { 2152 WSeq(ba, SEQ_ID_CURSOR_X_INDEX, info->hot.x & 0x3f); 2153 WSeq(ba, SEQ_ID_CURSOR_Y_INDEX, info->hot.y & 0x7f); 2154 } 2155 2156 return(0); 2157 } 2158 2159 int 2160 rh_getspritemax (gp, pos) 2161 struct grf_softc *gp; 2162 struct grf_position *pos; 2163 { 2164 #ifdef RH_64BIT_SPRITE 2165 pos->x = 64; 2166 pos->y = 64; 2167 #else 2168 pos->x = 32; 2169 pos->y = 32; 2170 #endif 2171 2172 return(0); 2173 } 2174 2175 2176 int 2177 rh_bitblt (gp, bb) 2178 struct grf_softc *gp; 2179 struct grf_bitblt *bb; 2180 { 2181 struct MonDef *md = (struct MonDef *)gp->g_data; 2182 if (md->DEP <= 8) 2183 RZ3BitBlit(gp, bb); 2184 else if (md->DEP <= 16) 2185 RZ3BitBlit16(gp, bb); 2186 else 2187 RZ3BitBlit24(gp, bb); 2188 2189 return(0); 2190 } 2191 2192 2193 int 2194 rh_blank(gp, on) 2195 struct grf_softc *gp; 2196 int *on; 2197 { 2198 struct MonDef *md = (struct MonDef *)gp->g_data; 2199 int r; 2200 2201 r = 0x01 | ((md->FLG & MDF_CLKDIV2)/ MDF_CLKDIV2 * 8); 2202 2203 WSeq(gp->g_regkva, SEQ_ID_CLOCKING_MODE, *on > 0 ? r : 0x21); 2204 2205 return(0); 2206 } 2207 2208 #endif /* NGRF */ 2209