diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/aux/vga/et4000.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/aux/vga/et4000.c')
-rwxr-xr-x | sys/src/cmd/aux/vga/et4000.c | 340 |
1 files changed, 340 insertions, 0 deletions
diff --git a/sys/src/cmd/aux/vga/et4000.c b/sys/src/cmd/aux/vga/et4000.c new file mode 100755 index 000000000..f44b792ee --- /dev/null +++ b/sys/src/cmd/aux/vga/et4000.c @@ -0,0 +1,340 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> + +#include "pci.h" +#include "vga.h" + +/* + * Tseng Labs Inc. ET4000 Video Controller. + */ +enum { + Crtcbx = 0x217A, /* Secondary CRT controller */ + + Sprite = 0xE0, + NSprite = 0x10, + + Ima = 0xF0, + NIma = 0x08, +}; + +static void +setkey(void) +{ + outportb(0x3BF, 0x03); + outportb(0x3D8, 0xA0); + outportb(0x3CD, 0x00); +} + +static void +snarf(Vga* vga, Ctlr* ctlr) +{ + int i; + + setkey(); + + vga->sequencer[0x06] = vgaxi(Seqx, 0x06); + vga->sequencer[0x07] = vgaxi(Seqx, 0x07); + + for(i = 0x30; i < 0x38; i++) + vga->crt[i] = vgaxi(Crtx, i); + vga->crt[0x3F] = vgaxi(Crtx, 0x3F); + + vga->attribute[0x16] = vgaxi(Attrx, 0x16); + vga->attribute[0x17] = vgaxi(Attrx, 0x17); + + /* + * Memory size. + */ + switch(vga->crt[0x37] & 0x03){ + + case 1: + vga->vmz = 256*1024; + break; + + case 2: + vga->vmz = 512*1024; + break; + + case 3: + vga->vmz = 1024*1024; + break; + } + if(strncmp(ctlr->name, "et4000-w32", 10) == 0){ + if(vga->crt[0x32] & 0x80) + vga->vmz *= 2; + } + else if(vga->crt[0x37] & 0x80) + vga->vmz *= 2; + + ctlr->flag |= Fsnarf; +} + +static void +options(Vga* vga, Ctlr* ctlr) +{ + /* + * The ET4000 does not need to have the vertical + * timing values divided by 2 for interlace mode. + */ + if(vga->mode->interlace == 'v') + vga->mode->interlace = 'V'; + + if(strncmp(ctlr->name, "et4000-w32", 10) == 0) + ctlr->flag |= Hpclk2x8; + + ctlr->flag |= Hclkdiv|Foptions; +} + +static void +init(Vga* vga, Ctlr* ctlr) +{ + Mode *mode; + ulong x; + + if(vga->mode->z > 8) + error("depth %d not supported\n", vga->mode->z); + + if(ctlr->flag & Upclk2x8){ + mode = vga->mode; + vga->crt[0x00] = ((mode->ht/2)>>3)-5; + vga->crt[0x01] = ((mode->x/2)>>3)-1; + vga->crt[0x02] = ((mode->shb/2)>>3)-1; + + x = (mode->ehb/2)>>3; + vga->crt[0x03] = 0x80|(x & 0x1F); + vga->crt[0x04] = (mode->shs/2)>>3; + vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F; + if(x & 0x20) + vga->crt[0x05] |= 0x80; + } + /* + * Itth a mythtawee. + */ + if(vga->crt[0x14] & 0x20) + vga->crt[0x17] |= 0x08; + vga->crt[0x17] &= ~0x20; + + vga->crt[0x30] = 0x00; + vga->crt[0x33] = 0x00; + + /* + * Overflow High. + */ + vga->crt[0x35] = 0x00; + if(vga->crt[0x15] & 0x400) + vga->crt[0x35] |= 0x01; + if(vga->crt[0x06] & 0x400) + vga->crt[0x35] |= 0x02; + if(vga->crt[0x12] & 0x400) + vga->crt[0x35] |= 0x04; + if(vga->crt[0x10] & 0x400) + vga->crt[0x35] |= 0x08; + if(vga->crt[0x18] & 0x400) + vga->crt[0x35] |= 0x10; + if(vga->mode->interlace == 'V') + vga->crt[0x35] |= 0x80; + + /* + * Horizontal Overflow. + */ + vga->crt[0x3F] = 0x00; + if(vga->crt[0x00] & 0x100) + vga->crt[0x3F] |= 0x01; + if(vga->crt[0x02] & 0x100) + vga->crt[0x3F] |= 0x04; + if(vga->crt[0x04] & 0x100) + vga->crt[0x3F] |= 0x10; + if(vga->crt[0x13] & 0x100) + vga->crt[0x3F] |= 0x80; + + /* + * Turn off MMU buffers, linear map + * and memory-mapped registers. + */ + vga->crt[0x36] &= ~0x38; + + if(strncmp(ctlr->name, "et4000-w32", 10) == 0) + vga->crt[0x37] |= 0x80; + + vga->sequencer[0x06] = 0x00; + + /* + * Clock select. + */ + if(vga->f[0] > 86000000) + error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]); + vga->misc &= ~0x0C; + vga->misc |= (vga->i[0] & 0x03)<<2; + if(vga->i[0] & 0x04) + vga->crt[0x34] |= 0x02; + else + vga->crt[0x34] &= ~0x02; + vga->crt[0x31] &= ~0xC0; + vga->crt[0x31] |= (vga->i[0] & 0x18)<<3; + + vga->sequencer[0x07] &= ~0x41; + if(vga->d[0] == 4) + vga->sequencer[0x07] |= 0x01; + else if(vga->d[0] == 2) + vga->sequencer[0x07] |= 0x40; + + vga->attribute[0x10] &= ~0x40; + vga->attribute[0x11] = Pblack; + vga->attribute[0x16] = 0x80; + + if(ctlr->flag & Upclk2x8) + vga->attribute[0x16] |= 0x20; + + ctlr->flag |= Finit; +} + +static void +load(Vga* vga, Ctlr* ctlr) +{ + vgaxo(Crtx, 0x30, vga->crt[0x30]); + vgaxo(Crtx, 0x31, vga->crt[0x31]); + vgaxo(Crtx, 0x33, vga->crt[0x33]); + vgaxo(Crtx, 0x34, vga->crt[0x34]); + vgaxo(Crtx, 0x35, vga->crt[0x35]); + vgaxo(Crtx, 0x36, vga->crt[0x36]); + vgaxo(Crtx, 0x37, vga->crt[0x37]); + vgaxo(Crtx, 0x3F, vga->crt[0x3F]); + + vgaxo(Seqx, 0x06, vga->sequencer[0x06]); + vgaxo(Seqx, 0x07, vga->sequencer[0x07]); + + vgaxo(Attrx, 0x16, vga->attribute[0x16]); + + ctlr->flag |= Fload; +} + +static void +dump(Vga* vga, Ctlr* ctlr) +{ + int i; + char *name; + ushort shb, vrs, x; + + name = ctlr->name; + + printitem(name, "Seq06"); + printreg(vga->sequencer[0x06]); + printreg(vga->sequencer[0x07]); + + printitem(name, "Crt30"); + for(i = 0x30; i < 0x38; i++) + printreg(vga->crt[i]); + printitem(name, "Crt3F"); + printreg(vga->crt[0x3F]); + + printitem(name, "Attr16"); + printreg(vga->attribute[0x16]); + printreg(vga->attribute[0x17]); + + if(strncmp(name, "et4000-w32", 10) == 0){ + printitem(name, "SpriteE0"); + for(i = Sprite; i < Sprite+NSprite; i++){ + outportb(Crtcbx, i); + printreg(inportb(Crtcbx+1)); + } + printitem(name, "ImaF0"); + for(i = Ima; i < Ima+NIma; i++){ + outportb(Crtcbx, i); + printreg(inportb(Crtcbx+1)); + } + } + + /* + * Try to disassemble the snarfed values into + * understandable numbers. + * Only do this if we weren't called after Finit. + */ + if(ctlr->flag & Finit) + return; + + x = (vga->crt[0x01]+1)<<3; + printitem(name, "hde"); + printreg(x); + Bprint(&stdout, "%6ud", x); + + shb = ((((vga->crt[0x3F] & 0x04)<<6)|vga->crt[0x02])+1)<<3; + printitem(name, "shb"); + printreg(shb); + Bprint(&stdout, "%6ud", shb); + + x = (((vga->crt[0x05] & 0x80)>>2)|(vga->crt[0x03] & 0x1F))<<3; + printitem(name, "ehb"); + printreg(x); + for(i = 0; x < shb; i++) + x |= 0x200<<i; + Bprint(&stdout, "%6ud", x); + + x = ((((vga->crt[0x3F] & 0x01)<<8)|vga->crt[0x00])+5)<<3; + printitem(name, "ht"); + printreg(x); + Bprint(&stdout, "%6ud", x); + + x = vga->crt[0x12]; + if(vga->crt[0x07] & 0x02) + x |= 0x100; + if(vga->crt[0x07] & 0x40) + x |= 0x200; + if(vga->crt[0x35] & 0x04) + x |= 0x400; + x += 1; + printitem(name, "vde"); + printreg(x); + Bprint(&stdout, "%6ud", x); + + vrs = vga->crt[0x10]; + if(vga->crt[0x07] & 0x04) + vrs |= 0x100; + if(vga->crt[0x07] & 0x80) + vrs |= 0x200; + if(vga->crt[0x35] & 0x08) + vrs |= 0x400; + printitem(name, "vrs"); + printreg(vrs); + Bprint(&stdout, "%6ud", vrs); + + x = (vrs & ~0x0F)|(vga->crt[0x11] & 0x0F); + printitem(name, "vre"); + printreg(x); + Bprint(&stdout, "%6ud", x); + + x = vga->crt[0x06]; + if(vga->crt[0x07] & 0x01) + x |= 0x100; + if(vga->crt[0x07] & 0x20) + x |= 0x200; + if(vga->crt[0x35] & 0x02) + x |= 0x400; + x += 2; + printitem(name, "vt"); + printreg(x); + Bprint(&stdout, "%6ud", x); + + printitem(name, "d i"); + if(vga->sequencer[0x07] & 0x01) + x = 4; + else if(vga->sequencer[0x07] & 0x40) + x = 2; + else + x = 0; + Bprint(&stdout, "%9ud", x); + x = (vga->misc & 0x0C)>>2; + if(vga->crt[0x34] & 0x02) + x |= 0x04; + x |= (vga->crt[0x31] & 0xC0)>>3; + Bprint(&stdout, "%8ud\n", x); +} + +Ctlr et4000 = { + "et4000", /* name */ + snarf, /* snarf */ + options, /* options */ + init, /* init */ + load, /* load */ + dump, /* dump */ +}; |