123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include "pci.h"
- #include "vga.h"
- enum {
- NSeqx = 0x05,
- NCrtx = 0x19,
- NGrx = 0x09,
- NAttrx = 0x15,
- };
- uchar
- vgai(long port)
- {
- uchar data;
- switch(port){
- case MiscR:
- case Status0:
- case Status1:
- case FeatureR:
- case PaddrW:
- case Pdata:
- case Pixmask:
- case Pstatus:
- data = inportb(port);
- break;
- default:
- error("vgai(0x%4.4lX): unknown port\n", port);
- /*NOTREACHED*/
- data = 0xFF;
- break;
- }
- return data;
- }
- uchar
- vgaxi(long port, uchar index)
- {
- uchar data;
- switch(port){
- case Seqx:
- case Crtx:
- case Grx:
- outportb(port, index);
- data = inportb(port+1);
- break;
- case Attrx:
- /*
- * Allow processor access to the colour
- * palette registers. Writes to Attrx must
- * be preceded by a read from Status1 to
- * initialise the register to point to the
- * index register and not the data register.
- * Processor access is allowed by turning
- * off bit 0x20.
- */
- inportb(Status1);
- if(index < 0x10){
- outportb(Attrx, index);
- data = inportb(Attrx+1);
- inportb(Status1);
- outportb(Attrx, 0x20|index);
- }
- else{
- outportb(Attrx, 0x20|index);
- data = inportb(Attrx+1);
- }
- break;
- default:
- error("vgaxi(0x%4.4lx, 0x%2.2uX): unknown port\n", port, index);
- /*NOTREACHED*/
- data = 0xFF;
- break;
- }
- return data;
- }
- void
- vgao(long port, uchar data)
- {
- switch(port){
- case MiscW:
- case FeatureW:
- case PaddrW:
- case Pdata:
- case Pixmask:
- case PaddrR:
- outportb(port, data);
- break;
- default:
- error("vgao(0x%4.4lX, 0x%2.2uX): unknown port\n", port, data);
- /*NOTREACHED*/
- break;
- }
- }
- void
- vgaxo(long port, uchar index, uchar data)
- {
- switch(port){
- case Seqx:
- case Crtx:
- case Grx:
- /*
- * We could use an outport here, but some chips
- * (e.g. 86C928) have trouble with that for some
- * registers.
- */
- outportb(port, index);
- outportb(port+1, data);
- break;
- case Attrx:
- inportb(Status1);
- if(index < 0x10){
- outportb(Attrx, index);
- outportb(Attrx, data);
- inportb(Status1);
- outportb(Attrx, 0x20|index);
- }
- else{
- outportb(Attrx, 0x20|index);
- outportb(Attrx, data);
- }
- break;
- default:
- error("vgaxo(0x%4.4lX, 0x%2.2uX, 0x%2.2uX): unknown port\n",
- port, index, data);
- break;
- }
- }
- 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;
- }
- static void
- init(Vga* vga, Ctlr* ctlr)
- {
- Mode *mode;
- int vt, vde, vrs, vre;
- ulong tmp;
- mode = vga->mode;
- memset(vga->sequencer, 0, NSeqx*sizeof(vga->sequencer[0]));
- memset(vga->crt, 0, NCrtx*sizeof(vga->crt[0]));
- memset(vga->graphics, 0, NGrx*sizeof(vga->graphics[0]));
- memset(vga->attribute, 0, NAttrx*sizeof(vga->attribute[0]));
- if(dflag)
- memset(vga->palette, 0, sizeof(vga->palette));
- /*
- * Misc. If both the horizontal and vertical sync polarity
- * options are set, use them. Otherwise use the defaults for
- * the given vertical size.
- */
- vga->misc = 0x23;
- if(mode->frequency == VgaFreq1)
- vga->misc |= 0x04;
- if(mode->hsync && mode->vsync){
- if(mode->hsync == '-')
- vga->misc |= 0x40;
- if(mode->vsync == '-')
- vga->misc |= 0x80;
- }
- else{
- if(mode->y < 480)
- vga->misc |= 0x40;
- else if(mode->y < 400)
- vga->misc |= 0x80;
- else if(mode->y < 768)
- vga->misc |= 0xC0;
- }
- /*
- * Sequencer
- */
- vga->sequencer[0x00] = 0x03;
- vga->sequencer[0x01] = 0x01;
- vga->sequencer[0x02] = 0x0F;
- vga->sequencer[0x03] = 0x00;
- if(mode->z >= 8)
- vga->sequencer[0x04] = 0x0A;
- else
- vga->sequencer[0x04] = 0x06;
- /*
- * Crt. Most of the work here is in dealing
- * with field overflow.
- */
- memset(vga->crt, 0, NCrtx);
- vga->crt[0x00] = (mode->ht>>3)-5;
- vga->crt[0x01] = (mode->x>>3)-1;
- vga->crt[0x02] = (mode->shb>>3)-1;
- /*
- * End Horizontal Blank is a 6-bit field, 5-bits
- * in Crt3, high bit in Crt5.
- */
- tmp = mode->ehb>>3;
- vga->crt[0x03] = 0x80|(tmp & 0x1F);
- if(tmp & 0x20)
- vga->crt[0x05] |= 0x80;
- if(mode->shs == 0)
- mode->shs = mode->shb;
- vga->crt[0x04] = mode->shs>>3;
- if(mode->ehs == 0)
- mode->ehs = mode->ehb;
- vga->crt[0x05] |= ((mode->ehs>>3) & 0x1F);
- /*
- * Vertical Total is 10-bits, 8 in Crt6, the high
- * two bits in Crt7. What if vt is >= 1024? We hope
- * the specific controller has some more overflow
- * bits.
- *
- * Interlace: if 'v', divide the vertical timing
- * values by 2.
- */
- vt = mode->vt;
- vde = mode->y;
- vrs = mode->vrs;
- vre = mode->vre;
- if(mode->interlace == 'v'){
- vt /= 2;
- vde /= 2;
- vrs /= 2;
- vre /= 2;
- }
- tmp = vt-2;
- vga->crt[0x06] = tmp;
- if(tmp & 0x100)
- vga->crt[0x07] |= 0x01;
- if(tmp & 0x200)
- vga->crt[0x07] |= 0x20;
- tmp = vrs;
- vga->crt[0x10] = tmp;
- if(tmp & 0x100)
- vga->crt[0x07] |= 0x04;
- if(tmp & 0x200)
- vga->crt[0x07] |= 0x80;
- vga->crt[0x11] = 0x20|(vre & 0x0F);
- tmp = vde-1;
- vga->crt[0x12] = tmp;
- if(tmp & 0x100)
- vga->crt[0x07] |= 0x02;
- if(tmp & 0x200)
- vga->crt[0x07] |= 0x40;
- vga->crt[0x15] = vrs;
- if(vrs & 0x100)
- vga->crt[0x07] |= 0x08;
- if(vrs & 0x200)
- vga->crt[0x09] |= 0x20;
- vga->crt[0x16] = (vrs+1);
- vga->crt[0x17] = 0x83;
- tmp = ((vga->virtx*mode->z)/8);
- if(tmp >= 512){
- vga->crt[0x14] |= 0x60;
- tmp /= 8;
- }
- else if(tmp >= 256){
- vga->crt[0x17] |= 0x08;
- tmp /= 4;
- }
- else{
- vga->crt[0x17] |= 0x40;
- tmp /= 2;
- }
- vga->crt[0x13] = tmp;
- if(mode->x*mode->y*mode->z/8 > 64*1024)
- vga->crt[0x17] |= 0x20;
- vga->crt[0x18] = 0x7FF;
- if(vga->crt[0x18] & 0x100)
- vga->crt[0x07] |= 0x10;
- if(vga->crt[0x18] & 0x200)
- vga->crt[0x09] |= 0x40;
- /*
- * Graphics
- */
- memset(vga->graphics, 0, NGrx);
- if((vga->sequencer[0x04] & 0x04) == 0)
- vga->graphics[0x05] |= 0x10;
- if(mode->z >= 8)
- vga->graphics[0x05] |= 0x40;
- vga->graphics[0x06] = 0x05;
- vga->graphics[0x07] = 0x0F;
- vga->graphics[0x08] = 0xFF;
- /*
- * Attribute
- */
- memset(vga->attribute, 0, NAttrx);
- for(tmp = 0; tmp < 0x10; tmp++)
- vga->attribute[tmp] = tmp;
- vga->attribute[0x10] = 0x01;
- if(mode->z >= 8)
- vga->attribute[0x10] |= 0x40;
- vga->attribute[0x11] = 0xFF;
- vga->attribute[0x12] = 0x0F;
- /*
- * Palette
- */
- if(dflag)
- palette.init(vga, ctlr);
- ctlr->flag |= Finit;
- }
- static void
- load(Vga* vga, Ctlr* ctlr)
- {
- int i;
- /*
- * Reset the sequencer and leave it off.
- * Load the generic VGA registers:
- * misc;
- * sequencer (but not seq01, display enable);
- * take the sequencer out of reset;
- * take off write-protect on crt[0x00-0x07];
- * crt;
- * graphics;
- * attribute;
- * palette.
- vgaxo(Seqx, 0x00, 0x00);
- */
- vgao(MiscW, vga->misc);
- for(i = 2; i < NSeqx; i++)
- vgaxo(Seqx, i, vga->sequencer[i]);
- /*vgaxo(Seqx, 0x00, 0x03);*/
- vgaxo(Crtx, 0x11, vga->crt[0x11] & ~0x80);
- for(i = 0; i < NCrtx; i++)
- vgaxo(Crtx, i, vga->crt[i]);
- for(i = 0; i < NGrx; i++)
- vgaxo(Grx, i, vga->graphics[i]);
- for(i = 0; i < NAttrx; i++)
- vgaxo(Attrx, i, vga->attribute[i]);
- if(dflag)
- palette.load(vga, ctlr);
- ctlr->flag |= Fload;
- }
- static void
- dump(Vga* vga, Ctlr* ctlr)
- {
- int i;
- printitem(ctlr->name, "misc");
- printreg(vga->misc);
- printitem(ctlr->name, "feature");
- printreg(vga->feature);
- printitem(ctlr->name, "sequencer");
- for(i = 0; i < NSeqx; i++)
- printreg(vga->sequencer[i]);
- printitem(ctlr->name, "crt");
- for(i = 0; i < NCrtx; i++)
- printreg(vga->crt[i]);
- printitem(ctlr->name, "graphics");
- for(i = 0; i < NGrx; i++)
- printreg(vga->graphics[i]);
- printitem(ctlr->name, "attribute");
- for(i = 0; i < NAttrx; i++)
- printreg(vga->attribute[i]);
- if(dflag)
- palette.dump(vga, ctlr);
- printitem(ctlr->name, "virtual");
- Bprint(&stdout, "%ld %ld\n", vga->virtx, vga->virty);
- printitem(ctlr->name, "panning");
- Bprint(&stdout, "%s\n", vga->panning ? "on" : "off");
- if(vga->f[0]){
- printitem(ctlr->name, "clock[0] f");
- Bprint(&stdout, "%9ld\n", vga->f[0]);
- printitem(ctlr->name, "clock[0] d i m");
- Bprint(&stdout, "%9ld %8ld - %8ld\n",
- vga->d[0], vga->i[0], vga->m[0]);
- printitem(ctlr->name, "clock[0] n p q r");
- Bprint(&stdout, "%9ld %8ld - %8ld %8ld\n",
- vga->n[0], vga->p[0], vga->q[0], vga->r[0]);
- }
- if(vga->f[1]){
- printitem(ctlr->name, "clock[1] f");
- Bprint(&stdout, "%9ld\n", vga->f[1]);
- printitem(ctlr->name, "clock[1] d i m");
- Bprint(&stdout, "%9ld %8ld - %8ld\n",
- vga->d[1], vga->i[1], vga->m[1]);
- printitem(ctlr->name, "clock[1] n p q r");
- Bprint(&stdout, "%9ld %8ld - %8ld %8ld\n",
- vga->n[1], vga->p[1], vga->q[1], vga->r[1]);
- }
- if(vga->vma || vga->vmb){
- printitem(ctlr->name, "vm a b");
- Bprint(&stdout, "%9lud %8lud\n", vga->vma, vga->vmb);
- }
- if(vga->vmz){
- printitem(ctlr->name, "vmz");
- Bprint(&stdout, "%9lud\n", vga->vmz);
- }
- printitem(ctlr->name, "apz");
- Bprint(&stdout, "%9lud\n", vga->apz);
- printitem(ctlr->name, "linear");
- Bprint(&stdout, "%9d\n", vga->linear);
- }
- Ctlr generic = {
- "vga", /* name */
- snarf, /* snarf */
- 0, /* options */
- init, /* init */
- load, /* load */
- dump, /* dump */
- };
|