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