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