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