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