123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include "pci.h"
- #include "vga.h"
- /*
- * Trident Cyber938x.
- */
- typedef struct {
- uchar old[3];
- int pcr; /* Pixel Command Register */
- int x;
- int y;
- } Cyber938x;
- /*
- * Access to the DAC Pixel Command Register.
- * The access is similar to that used on the old
- * SGS-Thompson STG1702 Enhanced True Color Palette-DAC
- * and Sierra SC1502[56] HiCOLOR-24 Palette.
- */
- static void
- pcrrw(void)
- {
- int i;
- inportb(PaddrW);
- for(i = 0; i < 4; i++)
- inportb(Pixmask);
- }
- static int
- pcrr(void)
- {
- int pcr;
- pcrrw();
- pcr = inportb(Pixmask);
- inportb(PaddrW);
- return pcr;
- }
- static void
- pcrw(int pcr)
- {
- pcrrw();
- outportb(Pixmask, pcr);
- inportb(PaddrW);
- }
- static void
- snarf(Vga* vga, Ctlr* ctlr)
- {
- int i;
- Cyber938x *cyber;
- if(vga->private == nil)
- vga->private = alloc(sizeof(Cyber938x));
- cyber = vga->private;
- /*
- * Switch to old mode (write to Seq0B), read the old
- * mode registers (Seq0[CDE]) then switch to new mode
- * (read Seq0B).
- */
- vgaxo(Seqx, 0x0B, 0);
- cyber->old[0] = vgaxi(Seqx, 0x0C);
- cyber->old[1] = vgaxi(Seqx, 0x0D);
- cyber->old[2] = vgaxi(Seqx, 0x0E);
- vga->sequencer[0x0B] = vgaxi(Seqx, 0x0B);
- cyber->pcr = pcrr();
- for(i = 0x08; i < 0x20; i++){
- if(i == 0x0B)
- continue;
- vga->sequencer[i] = vgaxi(Seqx, i);
- }
- for(i = 0x19; i < 0x60; i++)
- vga->crt[i] = vgaxi(Crtx, i);
- vga->crt[0xCF] = vgaxi(Crtx, 0xCF);
- for(i = 0x09; i < 0x60; i++)
- vga->graphics[i] = vgaxi(Grx, i);
- vga->vma = 4*1024*1024;
- switch(vga->crt[0x1F] & 0x07){
- case 0:
- case 4:
- vga->vma = 8*1024*1024;
- vga->vmz = 8*1024*1024;
- break;
- case 1:
- case 5:
- vga->vmz = 4*1024*1024;
- break;
- case 2:
- case 6:
- vga->vmz = 768*1024;
- break;
- case 7:
- vga->vmz = 2*1024*1024;
- break;
- case 3:
- default:
- vga->vmz = 1024*1024;
- break;
- }
- switch((vga->graphics[0x52]>>4) & 0x03){
- case 0:
- cyber->x = 1280;
- cyber->y = 1024;
- break;
- case 1:
- cyber->x = 640;
- cyber->y = 480;
- break;
- case 2:
- cyber->x = 1024;
- cyber->y = 768;
- break;
- case 3:
- cyber->x = 800;
- cyber->y = 600;
- break;
- }
- ctlr->flag |= Fsnarf;
- }
- static void
- options(Vga* vga, Ctlr* ctlr)
- {
- USED(vga);
- ctlr->flag |= Hlinear|Foptions;
- }
- static void
- init(Vga* vga, Ctlr* ctlr)
- {
- Cyber938x *cyber;
- cyber = vga->private;
- vga->crt[0x1E] = 0x80;
- vga->crt[0x2A] |= 0x40;
- if(vga->linear && (ctlr->flag & Hlinear))
- ctlr->flag |= Ulinear;
- vga->graphics[0x31] &= 0x8F;
- if(vga->mode->y > 768)
- vga->graphics[0x31] |= 0x30;
- else if(vga->mode->y > 600)
- vga->graphics[0x31] |= 0x20;
- else if(vga->mode->y > 480)
- vga->graphics[0x31] |= 0x10;
- switch(vga->mode->z){
- case 8:
- cyber->pcr = 0; /* DAC Pixel Command Register */
- vga->crt[0x38] = 0x00; /* Pixel Bus Register */
- break;
- case 16:
- cyber->pcr = 0x30;
- vga->crt[0x38] = 0x05;
- vga->crt[0x29] |= 0x10; /* RSC: necessary for Versa SX */
- break;
- case 24:
- cyber->pcr = 0xD0;
- vga->crt[0x38] = 0x29;
- break;
- default:
- error("depth %d not supported\n", vga->mode->z);
- }
- switch(vga->sequencer[0x09]){
- default:
- error("unknown Cyber revision 0x%uX\n", vga->sequencer[0x09]);
- break;
- case 0x21: /* ProVidia 9685 */
- /*
- * Incomplete - no clock code so only 640x480x8 works.
- */
- vga->attribute[0x11] = 0;
- vga->graphics[0x0F] |= 0x07;
- break;
- case 0x42: /* Cyber9382 */
- /*
- * Try a little magic for DSTN displays.
- * May work on other chips too, who knows.
- */
- if(!(vga->graphics[0x42] & 0x80) /* !TFT */
- && (vga->graphics[0x43] & 0x20)){ /* DSTN */
- if(vga->mode->x == 640)
- vga->graphics[0x30] |= 0x81;
- else
- vga->graphics[0x30] &= ~0x81;
- }
- /*FALLTHROUGH*/
- case 0x3: /* Cyber9320 */
- case 0x33: /* Cyber9385 */
- case 0x34: /* Cyber9385 */
- case 0x35: /* Cyber9385 */
- case 0x3A: /* Cyber9385 */
- vga->graphics[0x0F] |= 0x07;
- break;
- case 0x41: /* Cyber9525/DVD */
- vga->graphics[0x0F] |= 0x17;
- break;
- case 0x4A: /* Cyber9388 */
- case 0x5D: /* CyberBlade */
- case 0x6A: /* CyberBlade (iTuner) */
- case 0x7A: /* CyberBlade */
- vga->crt[0x2F] = 0x3F;
- vga->graphics[0x0F] |= 0x17;
- if(vga->mode->x == 1024)
- vga->graphics[0x30] = 0x18;
- break;
- }
- vga->graphics[0x52] &= ~0x01;
- vga->graphics[0x53] &= ~0x01;
- ctlr->flag |= Finit;
- }
- static void
- load(Vga* vga, Ctlr* ctlr)
- {
- Cyber938x *cyber;
- cyber = vga->private;
- outportw(0x3C4, 0x000B);
- outportb(0x3C4, 0x0B);
- inportb(0x3C5);
- pcrw(cyber->pcr);
- outportw(0x3C4, (0xC2 << 8) | 0x0E);
- vgaxo(Grx, 0x52, vga->graphics[0x52]);
- vgaxo(Grx, 0x53, vga->graphics[0x53]);
- vgaxo(Grx, 0x30, vga->graphics[0x30]);
- vgaxo(Grx, 0x31, vga->graphics[0x31]);
- vgaxo(Crtx, 0x1E, vga->crt[0x1E]);
- if(ctlr->flag & Ulinear)
- vga->crt[0x21] |= 0x20;
- vgaxo(Crtx, 0x21, vga->crt[0x21]);
- vgaxo(Crtx, 0x29, vga->crt[0x29]);
- vgaxo(Crtx, 0x2A, vga->crt[0x2A]);
- vgaxo(Crtx, 0x2F, vga->crt[0x2F]);
- vgaxo(Crtx, 0x38, vga->crt[0x38]);
- vgaxo(Grx, 0x0F, vga->graphics[0x0F]);
- ctlr->flag |= Fload;
- }
- static void
- dump(Vga* vga, Ctlr* ctlr)
- {
- char *name;
- Cyber938x *cyber;
- int i, k, m, n, vclka, vclkb;
- name = ctlr->name;
- cyber = vga->private;
- printitem(name, "Seq08");
- for(i = 0x08; i < 0x20; i++)
- printreg(vga->sequencer[i]);
- printitem(name, "Old Seq0C");
- for(i = 0; i < 3; i++)
- printreg(cyber->old[i]);
- printitem(name, "pcr");
- printreg(cyber->pcr);
- printitem(name, "Crt19");
- for(i = 0x19; i < 0x20; i++)
- printreg(vga->crt[i]);
- printitem(name, "Crt20");
- for(i = 0x20; i < 0x60; i++)
- printreg(vga->crt[i]);
- printitem(name, "CrtCF");
- printreg(vga->crt[0xCF]);
- printitem(name, "Gr09");
- for(i = 0x09; i < 0x10; i++)
- printreg(vga->graphics[i]);
- printitem(name, "Gr10");
- for(i = 0x10; i < 0x60; i++)
- printreg(vga->graphics[i]);
- if(vga->sequencer[0x09] >= 0x4A){
- vclka = vga->sequencer[0x18];
- vclkb = vga->sequencer[0x19];
- }
- else{
- vclka = inportb(0x43C8);
- vclkb = inportb(0x43C9);
- printitem(name, "mclk");
- printreg(inportb(0x43C6));
- printreg(inportb(0x43C7));
- }
- printitem(name, "vclk");
- printreg(vclka);
- printreg(vclkb);
- k = vclkb>>6;
- m = vclkb & 0x3F;
- n = vclka;
- Bprint(&stdout, "%18d\n", (((n+8)*RefFreq)*(1<<k))/(m+2));
- printitem(name, "lcd size");
- Bprint(&stdout, "%9ud %8ud\n", cyber->x, cyber->y);
- }
- Ctlr cyber938x = {
- "cyber938x", /* name */
- snarf, /* snarf */
- options, /* options */
- init, /* init */
- load, /* load */
- dump, /* dump */
- };
- Ctlr cyber938xhwgc = {
- "cyber938xhwgc", /* name */
- 0, /* snarf */
- 0, /* options */
- 0, /* init */
- 0, /* load */
- 0, /* dump */
- };
|