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