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