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