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