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