static void snarf(Vga* vga, Ctlr* ctlr) { int i; /* * Generic VGA registers: * misc, feature; * sequencer; * crt; * graphics; * attribute; * palette. */ vga->misc = vgai(MiscR); vga->feature = vgai(FeatureR); for(i = 0; i < NSeqx; i++) vga->sequencer[i] = vgaxi(Seqx, i); for(i = 0; i < NCrtx; i++) vga->crt[i] = vgaxi(Crtx, i); for(i = 0; i < NGrx; i++) vga->graphics[i] = vgaxi(Grx, i); for(i = 0; i < NAttrx; i++) vga->attribute[i] = vgaxi(Attrx, i); if(dflag) palette.snarf(vga, ctlr); ctlr->flag |= Fsnarf; }
/* * S3 Vision964 GUI Accelerator. */ static void snarf(Vga* vga, Ctlr* ctlr) { s3generic.snarf(vga, ctlr); vga->crt[0x22] = vgaxi(Crtx, 0x22); vga->crt[0x24] = vgaxi(Crtx, 0x24); vga->crt[0x26] = vgaxi(Crtx, 0x26); }
static int clgd542xpageset(VGAscr*, int page) { uchar gr09; int opage; if(vgaxi(Seqx, 0x07) & 0xF0) page = 0; gr09 = vgaxi(Grx, 0x09); if(vgaxi(Grx, 0x0B) & 0x20){ vgaxo(Grx, 0x09, page<<2); opage = gr09>>2; }
void sequencer(Vga* vga, int on) { static uchar seq01; static int state = 1; char *s; if(on) s = "on"; else s = "off"; trace("sequencer->enter %s\n", s); if(on){ if(vga) seq01 = vga->sequencer[0x01]; if(state == 0){ seq01 |= 0x01; vgaxo(Seqx, 0x01, seq01); vgaxo(Seqx, 0x00, 0x03); } } else{ vgaxo(Seqx, 0x00, 0x01); seq01 = vgaxi(Seqx, 0x01); vgaxo(Seqx, 0x01, seq01|0x20); } state = on; trace("sequencer->leave %s\n", s); }
static uchar tvp3026io(uchar reg, uchar data) { uchar crt55; crt55 = vgaxi(Crtx, 0x55) & 0xFC; vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); vgao(dacxreg[reg & 0x03], data); return crt55; }
static uint8_t tvp3026io(uint8_t reg, uint8_t data) { uint8_t crt55; crt55 = vgaxi(Crtx, 0x55) & 0xFC; vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); vgao(dacxreg[reg & 0x03], data); return crt55; }
/* * ARK Logic ARK2000PV GUI accelerator. */ static void snarf(Vga* vga, Ctlr* ctlr) { int i; /* * Unlock access to the extended I/O registers. */ vgaxo(Seqx, 0x1D, 0x01); for(i = 0x10; i < 0x2E; i++) vga->sequencer[i] = vgaxi(Seqx, i); for(i = 0x40; i < 0x47; i++) vga->crt[i] = vgaxi(Crtx, i); vga->crt[0x50] = vgaxi(Crtx, 0x50); /* * A hidey-hole for the coprocessor status register. */ vga->crt[0xFF] = inportb(0x3CB); /* * Memory size. */ switch((vga->sequencer[0x10]>>6) & 0x03){ case 0x00: vga->vma = vga->vmz = 1*1024*1024; break; case 0x01: vga->vma = vga->vmz = 2*1024*1024; break; case 0x02: vga->vma = vga->vmz = 4*1024*1024; break; } ctlr->flag |= Fsnarf; }
static uchar tvp3026i(uchar reg) { uchar crt55, r; crt55 = vgaxi(Crtx, 0x55) & 0xFC; vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); r = vgai(dacxreg[reg & 0x03]); vgaxo(Crtx, 0x55, crt55); return r; }
/* * Supposedly this is the way to turn DPMS * monitors off using just the VGA registers. * Unfortunately, it seems to mess up the video mode * on the cards I've tried. */ void vgablank(VGAscr*, int blank) { uchar seq1, crtc17; if(blank) { seq1 = 0x00; crtc17 = 0x80; } else { seq1 = 0x20; crtc17 = 0x00; } outs(Seqx, 0x0100); /* synchronous reset */ seq1 |= vgaxi(Seqx, 1) & ~0x20; vgaxo(Seqx, 1, seq1); crtc17 |= vgaxi(Crtx, 0x17) & ~0x80; delay(10); vgaxo(Crtx, 0x17, crtc17); outs(Crtx, 0x0300); /* end synchronous reset */ }
static uint8_t tvp3026i(uint8_t reg) { uint8_t crt55, r; crt55 = vgaxi(Crtx, 0x55) & 0xFC; vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); r = vgai(dacxreg[reg & 0x03]); vgaxo(Crtx, 0x55, crt55); return r; }
static int s3pageset(VGAscr* scr, int page) { uchar crt35, crt51; int opage; crt35 = vgaxi(Crtx, 0x35); if(scr->gscreen->depth >= 8){ /* * The S3 registers need to be unlocked for this. * Let's hope they are already: * vgaxo(Crtx, 0x38, 0x48); * vgaxo(Crtx, 0x39, 0xA0); * * The page is 6 bits, the lower 4 bits in Crt35<3:0>, * the upper 2 in Crt51<3:2>. */ vgaxo(Crtx, 0x35, page & 0x0F); crt51 = vgaxi(Crtx, 0x51); vgaxo(Crtx, 0x51, (crt51 & ~0x0C)|((page & 0x30)>>2)); opage = ((crt51 & 0x0C)<<2)|(crt35 & 0x0F); }
/* * S3 Vision968 GUI Accelerator. */ static void snarf(Vga* vga, Ctlr* ctlr) { s3generic.snarf(vga, ctlr); vga->sequencer[0x09] = vgaxi(Seqx, 0x09); vga->sequencer[0x0A] = vgaxi(Seqx, 0x0A); vga->crt[0x22] = vgaxi(Crtx, 0x22); vga->crt[0x24] = vgaxi(Crtx, 0x24); vga->crt[0x26] = vgaxi(Crtx, 0x26); vga->crt[0x2D] = vgaxi(Crtx, 0x2D); vga->crt[0x2E] = vgaxi(Crtx, 0x2E); vga->crt[0x2F] = vgaxi(Crtx, 0x2F); }
static void savageblank(VGAscr*, int blank) { uchar seqD; /* * Will handle DPMS to monitor */ vgaxo(Seqx, 8, vgaxi(Seqx,8)|0x06); seqD = vgaxi(Seqx, 0xD); seqD &= 0x03; if(blank) seqD |= 0x50; vgaxo(Seqx, 0xD, seqD); /* * Will handle LCD */ if(blank) vgaxo(Seqx, 0x31, vgaxi(Seqx, 0x31) & ~0x10); else vgaxo(Seqx, 0x31, vgaxi(Seqx, 0x31) | 0x10); }
static void snarf(Vga* vga, Ctlr* ctlr) { int i, id; char *p; /* * The Trio/ViRGE variants have some extra sequencer registers * which need to be unlocked for access. */ vgaxo(Seqx, 0x08, 0x06); s3generic.snarf(vga, ctlr); for(i = 0x08; i < 0x4F; i++) vga->sequencer[i] = vgaxi(Seqx, i); vga->crt[0x2D] = vgaxi(Crtx, 0x2D); vga->crt[0x2E] = vgaxi(Crtx, 0x2E); vga->crt[0x2F] = vgaxi(Crtx, 0x2F); for(i = 0x70; i < 0x99; i++) vga->crt[i] = vgaxi(Crtx, i); id = (vga->crt[0x2D]<<8)|vga->crt[0x2E]; switch(id){ default: trace("Unknown ViRGE/Trio64+ - 0x%4.4uX\n", (vga->crt[0x2D]<<8)|vga->crt[0x2E]); /*FALLTHROUGH*/ case 0x8810: /* Microsoft Virtual PC 2004 */ case 0x8811: /* Trio64+ */ vga->r[1] = 3; vga->m[1] = 127; vga->n[1] = 31; vga->f[1] = 135000000; trace("Trio64+\n"); break; case 0x8812: /* Aurora64V+ */ vga->r[1] = 3; vga->m[1] = 127; vga->n[1] = 63; vga->f[1] = 135000000; trace("Aurora64V+\n"); break; case 0x8901: /* Trio64V2 */ vga->r[1] = 4; vga->m[1] = 127; vga->n[1] = 31; vga->f[1] = 170000000; trace("Trio64V2\n"); break; case 0x5631: /* ViRGE */ vga->r[1] = 3; vga->m[1] = 127; vga->n[1] = 31; vga->f[1] = 135000000; vga->apz = 64*1024*1024; trace("ViRGE\n"); break; case 0x8A01: /* ViRGE/[DG]X */ vga->r[1] = 4; vga->m[1] = 127; vga->n[1] = 31; vga->f[1] = 170000000; trace("ViRGE/[DG]X\n"); break; case 0x8A10: /* ViRGE/GX2 */ vga->r[1] = 4; vga->m[1] = 127; vga->n[1] = 31; vga->f[1] = 170000000; vga->apz = 64*1024*1024; trace("ViRGE/GX2\n"); /* * Memory encoding on the ViRGE/GX2 is different. */ switch((vga->crt[0x36]>>6) & 0x03){ case 0x01: vga->vmz = 4*1024*1024; break; case 0x03: vga->vmz = 2*1024*1024; break; } break; case 0x883D: /* ViRGE/VX */ vga->r[1] = 4; vga->m[1] = 127; vga->n[1] = 31; vga->f[1] = 220000000; vga->apz = 64*1024*1024; trace("ViRGE/VX\n"); /* * Memory encoding on the ViRGE/VX is different. */ vga->vmz = (2*(((vga->crt[0x36]>>5) & 0x03)+1)) * 1*1024*1024; break; case 0x8C10: /* Savage MX/MV */ case 0x8C12: /* Savage4/IX-MV */ vga->r[1] = 4; vga->m[1] = 127; vga->n[1] = 127; vga->f[1] = 135000000; /* without clock-doubling */ for(i = 0x50; i < 0x70; i++) vga->sequencer[i] = vgaxi(Seqx, i); vga->apz = 128*1024*1024; vga->vmz = savage4mem[vga->crt[0x36]>>5] * 1024 * 1024; trace("Savage4/IX-MV\n"); break; case 0x8C2E: /* SuperSavage/IXC16 */ /* * This is all guessed, from the Savage4/IX, * inspection of the card (apz), and web pages * talking about the chip (f[1]). It seems to * work on the IBM Thinkpad T23. * * XXX only 1024x768 works, not 1400x1050. */ vga->r[1] = 4; vga->m[1] = 127; vga->n[1] = 127; vga->f[1] = 135000000; /* 300000000 after doubling? */ for(i = 0x50; i < 0x70; i++) vga->sequencer[i] = vgaxi(Seqx, i); vga->apz = 64*1024*1024; vga->vmz = savage4mem[vga->crt[0x36]>>5] * 1024 * 1024; trace("SuperSavage/IXC16\n"); break; case 0x8A22: /* Savage4 */ case 0x8A25: /* ProSavage PN133 */ case 0x8A26: /* ProSavage KN133 */ case 0x8D04: /* ProSavage DDR, K.Okamoto */ vga->r[1] = 4; vga->m[1] = 511; vga->n[1] = 127; vga->f[1] = 300000000; vga->apz = 128*1024*1024; vga->vmz = savage4mem[vga->crt[0x36]>>5] * 1024 * 1024; trace("Savage4\n"); break; } /* * Work out the part speed-grade from name. Name can have, * e.g. '-135' on the end for 135MHz part. */ if(p = strrchr(ctlr->name, '-')) vga->f[1] = strtoul(p+1, 0, 0) * 1000000; ctlr->flag |= Fsnarf; }