123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #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 */
- };
|