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