1 /* $NetBSD: grfabs_et.c,v 1.4 1996/10/13 04:10:57 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1996 Leo Weppelman. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Leo Weppelman. 18 * 4. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 * Most of the lower-level et4000 stuff was derived from: 35 * .../amiga/dev/grf_et.c 36 * 37 * Which was copyrighted by: 38 * Copyright (c) 1996 Tobias Abt 39 * Copyright (c) 1995 Ezra Story 40 * Copyright (c) 1995 Kari Mettinen 41 * Copyright (c) 1994 Markus Wild 42 * Copyright (c) 1994 Lutz Vieweg 43 * 44 * Thanks guys! 45 * 46 */ 47 #include <sys/param.h> 48 #include <sys/queue.h> 49 #include <sys/malloc.h> 50 #include <sys/device.h> 51 #include <sys/systm.h> 52 53 /* 54 * For PCI probing... 55 */ 56 #include <dev/pci/pcireg.h> 57 #include <dev/pci/pcivar.h> 58 59 #include <machine/iomap.h> 60 #include <machine/video.h> 61 #include <machine/mfp.h> 62 #include <atari/atari/device.h> 63 #include <atari/dev/grfioctl.h> 64 #include <atari/dev/grfabs_reg.h> 65 #include <atari/dev/grfabs_et.h> 66 #include <atari/dev/grf_etreg.h> 67 68 #define SAVEBUF_SIZE (32*1024 + sizeof(save_area_t)) 69 70 /* 71 * Function decls 72 */ 73 static void init_view __P((view_t *, bmap_t *, dmode_t *, box_t *)); 74 static colormap_t *alloc_colormap __P((dmode_t *)); 75 static void et_display_view __P((view_t *)); 76 static view_t *et_alloc_view __P((dmode_t *, dimen_t *, u_char)); 77 static void et_boardinit __P((void)); 78 static void et_free_view __P((view_t *)); 79 static void et_loadmode __P((struct grfvideo_mode *, et_sv_reg_t *)); 80 static void et_remove_view __P((view_t *)); 81 static void et_save_view __P((view_t *)); 82 static int et_use_colormap __P((view_t *, colormap_t *)); 83 84 /* 85 * Our function switch table 86 */ 87 struct grfabs_sw et_vid_sw = { 88 et_display_view, 89 et_alloc_view, 90 et_free_view, 91 et_remove_view, 92 et_save_view, 93 et_use_colormap 94 }; 95 96 static struct grfvideo_mode hw_modes[] = { 97 { 98 0, "", 25175000, /* num, descr, pix-clock */ 99 640, 400, 4, /* width, height, depth */ 100 640/8, 672/8, 688/8, 752/8, 768/8,/* HBS, HBE, HSS, HSE, HT */ 101 399, 450, 408, 413, 449 /* VBS, VBE, VSS, VSE, VT */ 102 }, 103 { 104 0, "", 25175000, /* num, descr, pix-clock */ 105 640, 480, 4, /* width, height, depth */ 106 640/8, 672/8, 704/8, 752/8, 760/8,/* HBS, HBE, HSS, HSE, HT */ 107 481, 522, 490, 498, 522 /* VBS, VBE, VSS, VSE, VT */ 108 } 109 }; 110 111 static dmode_t vid_modes[] = { 112 { { NULL, NULL }, 113 "640x400", { 640, 400 }, 1, (void*)&hw_modes[0], &et_vid_sw }, 114 { { NULL, NULL }, 115 "640x480", { 640, 480 }, 1, (void*)&hw_modes[1], &et_vid_sw }, 116 { { NULL, NULL }, NULL, } 117 }; 118 119 #define ET_NUMCLOCKS 32 120 121 static u_int et_clockfreqs[ET_NUMCLOCKS] = { 122 6293750, 7080500, 7875000, 8125000, 123 9000000, 9375000, 10000000, 11225000, 124 12587500, 14161000, 15750000, 16250000, 125 18000000, 18750000, 20000000, 22450000, 126 25175000, 28322000, 31500000, 32500000, 127 36000000, 37500000, 40000000, 44900000, 128 50350000, 56644000, 63000000, 65000000, 129 72000000, 75000000, 80000000, 89800000 130 }; 131 132 static bmap_t con_bm; /* XXX */ 133 134 struct grfabs_et_priv { 135 pcitag_t pci_tag; 136 volatile caddr_t regkva; 137 volatile caddr_t memkva; 138 int regsz; 139 int memsz; 140 } et_priv; 141 142 /* 143 * XXX: called from ite console init routine. 144 * Initialize list of posible video modes. 145 */ 146 void 147 et_probe_video(modelp) 148 MODES *modelp; 149 { 150 dmode_t *dm; 151 int i; 152 153 for (i = 0; (dm = &vid_modes[i])->name != NULL; i++) { 154 LIST_INSERT_HEAD(modelp, dm, link); 155 } 156 } 157 158 static void 159 et_display_view(v) 160 view_t *v; 161 { 162 dmode_t *dm = v->mode; 163 bmap_t *bm = v->bitmap; 164 int sv_size; 165 u_short *src, *dst; 166 save_area_t *sa; 167 168 if (dm->current_view && (dm->current_view != v)) { 169 /* 170 * Mark current view for this mode as no longer displayed 171 */ 172 dm->current_view->flags &= ~VF_DISPLAY; 173 } 174 dm->current_view = v; 175 v->flags |= VF_DISPLAY; 176 177 if ((sa = (save_area_t*)v->save_area) == NULL) 178 return; /* XXX: Can't happen.... */ 179 180 /* 181 * Restore register settings and turn the plane pointer 182 * to the card-memory 183 */ 184 et_hwrest(&sa->sv_regs); 185 bm->plane = et_priv.memkva; 186 187 et_use_colormap(v, v->colormap); 188 189 /* 190 * Copy the backing store to card-memory 191 */ 192 sv_size = sa->fb_size; 193 src = sa->sv_fb; 194 dst = (u_short *)bm->plane; 195 while (sv_size--) 196 *dst++ = *src++; 197 } 198 199 void 200 et_remove_view(v) 201 view_t *v; 202 { 203 dmode_t *mode = v->mode; 204 205 if (mode->current_view == v) { 206 #if 0 207 if (v->flags & VF_DISPLAY) 208 panic("Cannot shutdown display\n"); /* XXX */ 209 #endif 210 mode->current_view = NULL; 211 } 212 v->flags &= ~VF_DISPLAY; 213 } 214 215 void 216 et_save_view(v) 217 view_t *v; 218 { 219 bmap_t *bm = v->bitmap; 220 u_char font_height; 221 int sv_size; 222 u_short *src, *dst; 223 save_area_t *sa; 224 225 if (!atari_realconfig) 226 return; 227 228 if (RGfx(et_priv.regkva, GCT_ID_MISC) & 1) { 229 #if 0 /* XXX: Can't use printf here.... */ 230 printf("et_save_view: Don't know how to save" 231 " a graphics mode\n"); 232 #endif 233 return; 234 } 235 if (v->save_area == NULL) 236 v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK); 237 238 /* 239 * Calculate the size of the copy 240 */ 241 font_height = RCrt(et_priv.regkva, CRT_ID_MAX_ROW_ADDRESS) & 0x1f; 242 sv_size = bm->bytes_per_row * (bm->rows / (font_height + 1)); 243 sv_size = min(SAVEBUF_SIZE, sv_size); 244 245 /* 246 * Save all we need to know.... 247 */ 248 sa = (save_area_t *)v->save_area; 249 et_hwsave(&sa->sv_regs); 250 sa->fb_size = sv_size; 251 src = (u_short *)bm->plane; 252 dst = sa->sv_fb; 253 while (sv_size--) 254 *dst++ = *src++; 255 bm->plane = (u_char *)sa->sv_fb; 256 } 257 258 void 259 et_free_view(v) 260 view_t *v; 261 { 262 if(v) { 263 et_remove_view(v); 264 if (v->colormap != &gra_con_cmap) 265 free(v->colormap, M_DEVBUF); 266 if (v->save_area != NULL) 267 free(v->save_area, M_DEVBUF); 268 if (v != &gra_con_view) { 269 free(v->bitmap, M_DEVBUF); 270 free(v, M_DEVBUF); 271 } 272 } 273 } 274 275 static int 276 et_use_colormap(v, cm) 277 view_t *v; 278 colormap_t *cm; 279 { 280 return (0); /* XXX: Nothing here for now... */ 281 } 282 283 static view_t * 284 et_alloc_view(mode, dim, depth) 285 dmode_t *mode; 286 dimen_t *dim; 287 u_char depth; 288 { 289 view_t *v; 290 bmap_t *bm; 291 box_t box; 292 save_area_t *sa; 293 294 if (!atari_realconfig) { 295 v = &gra_con_view; 296 bm = &con_bm; 297 } 298 else { 299 v = malloc(sizeof(*v), M_DEVBUF, M_WAITOK); 300 bm = malloc(sizeof(*bm), M_DEVBUF, M_WAITOK); 301 } 302 v->bitmap = bm; 303 304 /* 305 * Initialize the bitmap 306 */ 307 bm->plane = et_priv.memkva; 308 bm->hw_address = et_priv.memkva; /* XXX: kvtop? */ 309 bm->regs = et_priv.regkva; 310 bm->hw_regs = et_priv.regkva; /* XXX: kvtop? */ 311 bm->reg_size = et_priv.regsz; 312 313 bm->bytes_per_row = (mode->size.width * depth) / NBBY; 314 bm->rows = mode->size.height; 315 bm->depth = depth; 316 317 /* 318 * Allocate a save_area. 319 * Note: If atari_realconfig is false, no save area is (can be) 320 * allocated. This means that the plane is the video memory, 321 * which is what's wanted in this case. 322 */ 323 if (atari_realconfig) { 324 v->save_area = malloc(SAVEBUF_SIZE, M_DEVBUF, M_WAITOK); 325 sa = (save_area_t*)v->save_area; 326 sa->fb_size = 0; 327 bm->plane = (u_char *)sa->sv_fb; 328 et_loadmode(mode->data, &sa->sv_regs); 329 } 330 else v->save_area = NULL; 331 332 v->colormap = alloc_colormap(mode); 333 if (v->colormap) { 334 INIT_BOX(&box,0,0,mode->size.width,mode->size.height); 335 init_view(v, bm, mode, &box); 336 return (v); 337 } 338 if (v != &gra_con_view) { 339 free(v, M_DEVBUF); 340 free(bm, M_DEVBUF); 341 } 342 return (NULL); 343 } 344 345 static void 346 init_view(v, bm, mode, dbox) 347 view_t *v; 348 bmap_t *bm; 349 dmode_t *mode; 350 box_t *dbox; 351 { 352 v->bitmap = bm; 353 v->mode = mode; 354 v->flags = 0; 355 bcopy(dbox, &v->display, sizeof(box_t)); 356 } 357 358 /* XXX: No more than a stub... */ 359 static colormap_t * 360 alloc_colormap(dm) 361 dmode_t *dm; 362 { 363 colormap_t *cm; 364 int i; 365 366 cm = &gra_con_cmap; 367 cm->entry = gra_con_colors; 368 369 cm->first = 0; 370 cm->size = 2; 371 372 for (i = 0; i < 2; i++) 373 cm->entry[i] = gra_def_color16[i % 16]; 374 return (cm); 375 } 376 377 /* 378 * Go look for a VGA card on the PCI-bus. This search is a 379 * stripped down version of the PCI-probe. It only looks on 380 * bus0 for simple cards. 381 */ 382 int 383 et_probe_card() 384 { 385 pci_chipset_tag_t pc = NULL; /* XXX */ 386 pcitag_t tag; 387 int class, device, found, id, maxndevs; 388 389 found = 0; 390 tag = 0; 391 maxndevs = pci_bus_maxdevs(pc, 0); 392 393 for (device = 0; device < maxndevs; device++) { 394 395 tag = pci_make_tag(pc, 0, device, 0); 396 id = pci_conf_read(pc, tag, PCI_ID_REG); 397 if (id == 0 || id == 0xffffffff) 398 continue; 399 class = pci_conf_read(pc, tag, PCI_CLASS_REG); 400 if (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC 401 && PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA) { 402 found = 1; 403 break; 404 } 405 if (PCI_CLASS(class) == PCI_CLASS_DISPLAY 406 && PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) { 407 found = 1; 408 break; 409 } 410 } 411 if (!found) 412 return (0); 413 414 et_priv.pci_tag = tag; 415 416 /* 417 * The things below are setup in atari_init.c 418 */ 419 et_priv.regkva = (volatile caddr_t)pci_io_addr; 420 et_priv.memkva = (volatile caddr_t)pci_mem_addr; 421 et_priv.memsz = 4 * NBPG; 422 et_priv.regsz = NBPG; 423 424 if (found && !atari_realconfig) { 425 et_boardinit(); 426 et_loadmode(&hw_modes[0], NULL); 427 return (1); 428 } 429 430 return (1); 431 } 432 433 static void 434 et_loadmode(mode, regs) 435 struct grfvideo_mode *mode; 436 et_sv_reg_t *regs; 437 { 438 unsigned short HDE, VDE; 439 int lace, dblscan; 440 int uplim, lowlim; 441 int i; 442 unsigned char clock, tmp; 443 volatile u_char *ba; 444 et_sv_reg_t loc_regs; 445 446 if (regs == NULL) 447 regs = &loc_regs; 448 449 ba = et_priv.regkva; 450 HDE = mode->disp_width / 8 - 1; 451 VDE = mode->disp_height - 1; 452 453 /* figure out whether lace or dblscan is needed */ 454 455 uplim = mode->disp_height + (mode->disp_height / 4); 456 lowlim = mode->disp_height - (mode->disp_height / 4); 457 lace = (((mode->vtotal * 2) > lowlim) 458 && ((mode->vtotal * 2) < uplim)) ? 1 : 0; 459 dblscan = (((mode->vtotal / 2) > lowlim) 460 && ((mode->vtotal / 2) < uplim)) ? 1 : 0; 461 462 /* adjustments */ 463 if (lace) 464 VDE /= 2; 465 466 regs->misc_output = 0x23; /* Page 0, Color mode */ 467 regs->seg_sel = 0x00; 468 regs->state_ctl = 0x00; 469 470 regs->seq[SEQ_ID_RESET] = 0x03; /* reset off */ 471 regs->seq[SEQ_ID_CLOCKING_MODE] = 0x21; /* Turn off screen */ 472 regs->seq[SEQ_ID_MAP_MASK] = 0xff; /* Cpu writes all planes*/ 473 regs->seq[SEQ_ID_CHAR_MAP_SELECT] = 0x00; /* Char. generator 0 */ 474 regs->seq[SEQ_ID_MEMORY_MODE] = 0x0e; /* Seq. Memory mode */ 475 476 /* 477 * Set the clock... 478 */ 479 for(clock = ET_NUMCLOCKS-1; clock > 0; clock--) { 480 if (et_clockfreqs[clock] <= mode->pixel_clock) 481 break; 482 } 483 regs->misc_output |= (clock & 3) << 2; 484 regs->aux_mode = 0xb4 | ((clock & 8) << 3); 485 regs->compat_6845 = (clock & 4) ? 0x0a : 0x08; 486 487 /* 488 * The display parameters... 489 */ 490 regs->crt[CRT_ID_HOR_TOTAL] = mode->htotal; 491 regs->crt[CRT_ID_HOR_DISP_ENA_END] = ((HDE >= mode->hblank_start) 492 ? mode->hblank_stop - 1 493 : HDE); 494 regs->crt[CRT_ID_START_HOR_BLANK] = mode->hblank_start; 495 regs->crt[CRT_ID_END_HOR_BLANK] = (mode->hblank_stop & 0x1f) | 0x80; 496 regs->crt[CRT_ID_START_HOR_RETR] = mode->hsync_start; 497 regs->crt[CRT_ID_END_HOR_RETR] = (mode->hsync_stop & 0x1f) 498 | ((mode->hblank_stop & 0x20) 499 ? 0x80 : 0x00); 500 regs->crt[CRT_ID_VER_TOTAL] = mode->vtotal; 501 regs->crt[CRT_ID_START_VER_RETR] = mode->vsync_start; 502 regs->crt[CRT_ID_END_VER_RETR] = (mode->vsync_stop & 0x0f) | 0x30; 503 regs->crt[CRT_ID_VER_DISP_ENA_END] = VDE; 504 regs->crt[CRT_ID_START_VER_BLANK] = mode->vblank_start; 505 regs->crt[CRT_ID_END_VER_BLANK] = mode->vblank_stop; 506 regs->crt[CRT_ID_MODE_CONTROL] = 0xab; 507 regs->crt[CRT_ID_START_ADDR_HIGH] = 0x00; 508 regs->crt[CRT_ID_START_ADDR_LOW] = 0x00; 509 regs->crt[CRT_ID_LINE_COMPARE] = 0xff; 510 regs->crt[CRT_ID_UNDERLINE_LOC] = 0x00; 511 regs->crt[CRT_ID_OFFSET] = mode->disp_width/16; 512 regs->crt[CRT_ID_MAX_ROW_ADDRESS] = 513 0x40 | 514 (dblscan ? 0x80 : 0x00) | 515 ((mode->vblank_start & 0x200) ? 0x20 : 0x00); 516 regs->crt[CRT_ID_OVERFLOW] = 517 0x10 | 518 ((mode->vtotal & 0x100) ? 0x01 : 0x00) | 519 ((VDE & 0x100) ? 0x02 : 0x00) | 520 ((mode->vsync_start & 0x100) ? 0x04 : 0x00) | 521 ((mode->vblank_start & 0x100) ? 0x08 : 0x00) | 522 ((mode->vtotal & 0x200) ? 0x20 : 0x00) | 523 ((VDE & 0x200) ? 0x40 : 0x00) | 524 ((mode->vsync_start & 0x200) ? 0x80 : 0x00); 525 regs->overfl_high = 526 0x10 | 527 ((mode->vblank_start & 0x400) ? 0x01 : 0x00) | 528 ((mode->vtotal & 0x400) ? 0x02 : 0x00) | 529 ((VDE & 0x400) ? 0x04 : 0x00) | 530 ((mode->vsync_start & 0x400) ? 0x08 : 0x00) | 531 (lace ? 0x80 : 0x00); 532 regs->hor_overfl = 533 ((mode->htotal & 0x100) ? 0x01 : 0x00) | 534 ((mode->hblank_start & 0x100) ? 0x04 : 0x00) | 535 ((mode->hsync_start & 0x100) ? 0x10 : 0x00); 536 537 regs->grf[GCT_ID_SET_RESET] = 0x00; 538 regs->grf[GCT_ID_ENABLE_SET_RESET] = 0x00; 539 regs->grf[GCT_ID_COLOR_COMPARE] = 0x00; 540 regs->grf[GCT_ID_DATA_ROTATE] = 0x00; 541 regs->grf[GCT_ID_READ_MAP_SELECT] = 0x00; 542 regs->grf[GCT_ID_GRAPHICS_MODE] = mode->depth == 1 ? 0x00: 0x40; 543 regs->grf[GCT_ID_MISC] = 0x01; 544 regs->grf[GCT_ID_COLOR_XCARE] = 0x0f; 545 regs->grf[GCT_ID_BITMASK] = 0xff; 546 547 for (i = 0; i < 0x10; i++) 548 regs->attr[i] = i; 549 regs->attr[ACT_ID_ATTR_MODE_CNTL] = 0x01; 550 regs->attr[ACT_ID_OVERSCAN_COLOR] = 0x00; 551 regs->attr[ACT_ID_COLOR_PLANE_ENA] = 0x0f; 552 regs->attr[ACT_ID_HOR_PEL_PANNING] = 0x00; 553 regs->attr[ACT_ID_COLOR_SELECT] = 0x00; 554 regs->attr[ACT_ID_MISCELLANEOUS] = 0x00; 555 556 /* 557 * XXX: This works for depth == 4. I need some better docs 558 * to fix the other modes.... 559 */ 560 vgaw(ba, VDAC_MASK, 0xff); 561 vgar(ba, VDAC_MASK); 562 vgar(ba, VDAC_MASK); 563 vgar(ba, VDAC_MASK); 564 vgar(ba, VDAC_MASK); 565 566 vgaw(ba, VDAC_MASK, 0); 567 /* 568 * End of depth stuff 569 */ 570 571 /* 572 * Compute Hsync & Vsync polarity 573 * Note: This seems to be some kind of a black art :-( 574 */ 575 tmp = regs->misc_output & 0x3f; 576 #if 0 /* This is according to my BW monitor & Xfree... */ 577 if (VDE < 400) 578 tmp |= 0x40; /* -hsync +vsync */ 579 else if (VDE < 480) 580 tmp |= 0xc0; /* -hsync -vsync */ 581 #else /* This is according to my color monitor.... */ 582 if (VDE < 400) 583 tmp |= 0x00; /* +hsync +vsync */ 584 else if (VDE < 480) 585 tmp |= 0x80; /* +hsync -vsync */ 586 #endif 587 /* I'm unable to try the rest.... */ 588 regs->misc_output = tmp; 589 590 if(regs == &loc_regs) 591 et_hwrest(regs); 592 } 593 594 static void 595 et_boardinit() 596 { 597 volatile u_char *ba; 598 int i, j; 599 600 ba = et_priv.regkva; 601 602 vgaw(ba, GREG_HERCULESCOMPAT, 0x03); 603 vgaw(ba, GREG_DISPMODECONTROL, 0xa0); 604 vgaw(ba, GREG_MISC_OUTPUT_W, 0x23); 605 606 WSeq(ba, SEQ_ID_RESET, 0x03); 607 WSeq(ba, SEQ_ID_CLOCKING_MODE, 0x21); /* 8 dot, Display off */ 608 WSeq(ba, SEQ_ID_MAP_MASK, 0x0f); 609 WSeq(ba, SEQ_ID_CHAR_MAP_SELECT, 0x00); 610 WSeq(ba, SEQ_ID_MEMORY_MODE, 0x0e); 611 WSeq(ba, SEQ_ID_AUXILIARY_MODE, 0xf4); 612 613 WCrt(ba, CRT_ID_PRESET_ROW_SCAN, 0x00); 614 WCrt(ba, CRT_ID_CURSOR_START, 0x00); 615 WCrt(ba, CRT_ID_CURSOR_END, 0x08); 616 WCrt(ba, CRT_ID_START_ADDR_HIGH, 0x00); 617 WCrt(ba, CRT_ID_START_ADDR_LOW, 0x00); 618 WCrt(ba, CRT_ID_CURSOR_LOC_HIGH, 0x00); 619 WCrt(ba, CRT_ID_CURSOR_LOC_LOW, 0x00); 620 621 WCrt(ba, CRT_ID_UNDERLINE_LOC, 0x07); 622 WCrt(ba, CRT_ID_MODE_CONTROL, 0xa3); 623 WCrt(ba, CRT_ID_LINE_COMPARE, 0xff); 624 /* 625 * ET4000 special 626 */ 627 WCrt(ba, CRT_ID_RASCAS_CONFIG, 0x28); 628 WCrt(ba, CTR_ID_EXT_START, 0x00); 629 WCrt(ba, CRT_ID_6845_COMPAT, 0x08); 630 WCrt(ba, CRT_ID_VIDEO_CONFIG1, 0x73); 631 WCrt(ba, CRT_ID_VIDEO_CONFIG2, 0x09); 632 633 WCrt(ba, CRT_ID_HOR_OVERFLOW, 0x00); 634 635 WGfx(ba, GCT_ID_SET_RESET, 0x00); 636 WGfx(ba, GCT_ID_ENABLE_SET_RESET, 0x00); 637 WGfx(ba, GCT_ID_COLOR_COMPARE, 0x00); 638 WGfx(ba, GCT_ID_DATA_ROTATE, 0x00); 639 WGfx(ba, GCT_ID_READ_MAP_SELECT, 0x00); 640 WGfx(ba, GCT_ID_GRAPHICS_MODE, 0x00); 641 WGfx(ba, GCT_ID_MISC, 0x01); 642 WGfx(ba, GCT_ID_COLOR_XCARE, 0x0f); 643 WGfx(ba, GCT_ID_BITMASK, 0xff); 644 645 vgaw(ba, GREG_SEGMENTSELECT, 0x00); 646 647 for (i = 0; i < 0x10; i++) 648 WAttr(ba, i, i); 649 WAttr(ba, ACT_ID_ATTR_MODE_CNTL, 0x01); 650 WAttr(ba, ACT_ID_OVERSCAN_COLOR, 0x00); 651 WAttr(ba, ACT_ID_COLOR_PLANE_ENA, 0x0f); 652 WAttr(ba, ACT_ID_HOR_PEL_PANNING, 0x00); 653 WAttr(ba, ACT_ID_COLOR_SELECT, 0x00); 654 WAttr(ba, ACT_ID_MISCELLANEOUS, 0x00); 655 656 vgaw(ba, VDAC_MASK, 0xff); 657 658 #if 0 /* XXX: We like to do this: */ 659 delay(200000); 660 #else /* But because we run before the delay is initialized: */ 661 for(i = 0; i < 4000; i++) 662 for(j = 0; j < 400; j++); 663 #endif 664 665 /* 666 * colors initially set to greyscale 667 */ 668 vgaw(ba, VDAC_ADDRESS_W, 0); 669 for (i = 255; i >= 0; i--) { 670 vgaw(ba, VDAC_DATA, i); 671 vgaw(ba, VDAC_DATA, i); 672 vgaw(ba, VDAC_DATA, i); 673 } 674 } 675 676 void 677 et_hwsave(et_regs) 678 et_sv_reg_t *et_regs; 679 { 680 volatile u_char *ba; 681 int i, s; 682 683 ba = et_priv.regkva; 684 685 s = splhigh(); 686 687 /* 688 * General VGA registers 689 */ 690 et_regs->misc_output = vgar(ba, GREG_MISC_OUTPUT_R); 691 for(i = 0; i < 25; i++) 692 et_regs->crt[i] = RCrt(ba, i); 693 for(i = 0; i < 21; i++) 694 et_regs->attr[i] = RAttr(ba, i | 0x20); 695 for(i = 0; i < 9; i++) 696 et_regs->grf[i] = RGfx(ba, i); 697 for(i = 0; i < 5; i++) 698 et_regs->seq[i] = RSeq(ba, i); 699 700 /* 701 * ET4000 extensions 702 */ 703 et_regs->ext_start = RCrt(ba, CTR_ID_EXT_START); 704 et_regs->compat_6845 = RCrt(ba, CRT_ID_6845_COMPAT); 705 et_regs->overfl_high = RCrt(ba, CRT_ID_OVERFLOW_HIGH); 706 et_regs->hor_overfl = RCrt(ba, CRT_ID_HOR_OVERFLOW); 707 et_regs->state_ctl = RSeq(ba, SEQ_ID_STATE_CONTROL); 708 et_regs->aux_mode = RSeq(ba, SEQ_ID_AUXILIARY_MODE); 709 et_regs->seg_sel = vgar(ba, GREG_SEGMENTSELECT); 710 711 s = splx(s); 712 } 713 714 void 715 et_hwrest(et_regs) 716 et_sv_reg_t *et_regs; 717 { 718 volatile u_char *ba; 719 int i, s; 720 721 ba = et_priv.regkva; 722 723 s = splhigh(); 724 725 vgaw(ba, GREG_SEGMENTSELECT, 0); 726 vgaw(ba, GREG_MISC_OUTPUT_W, et_regs->misc_output); 727 728 /* 729 * General VGA registers 730 */ 731 for(i = 0; i < 5; i++) 732 WSeq(ba, i, et_regs->seq[i]); 733 734 /* 735 * Make sure we're allowed to write all crt-registers 736 */ 737 WCrt(ba, CRT_ID_END_VER_RETR, 738 et_regs->crt[CRT_ID_END_VER_RETR] & 0x7f); 739 for(i = 0; i < 25; i++) 740 WCrt(ba, i, et_regs->crt[i]); 741 for(i = 0; i < 9; i++) 742 WGfx(ba, i, et_regs->grf[i]); 743 for(i = 0; i < 21; i++) 744 WAttr(ba, i | 0x20, et_regs->attr[i]); 745 746 /* 747 * ET4000 extensions 748 */ 749 WSeq(ba, SEQ_ID_STATE_CONTROL, et_regs->state_ctl); 750 WSeq(ba, SEQ_ID_AUXILIARY_MODE, et_regs->aux_mode); 751 WCrt(ba, CTR_ID_EXT_START, et_regs->ext_start); 752 WCrt(ba, CRT_ID_6845_COMPAT, et_regs->compat_6845); 753 WCrt(ba, CRT_ID_OVERFLOW_HIGH, et_regs->overfl_high); 754 WCrt(ba, CRT_ID_HOR_OVERFLOW, et_regs->hor_overfl); 755 vgaw(ba, GREG_SEGMENTSELECT, et_regs->seg_sel); 756 757 i = et_regs->seq[SEQ_ID_CLOCKING_MODE] & ~0x20; 758 WSeq(ba, SEQ_ID_CLOCKING_MODE, i); 759 760 s = splx(s); 761 } 762