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