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