| plan 9 kernel history: overview | file list | diff list |
1994/0624/pc/devvga.c (diff list | history)
| 1994/0603/sys/src/9/pc/devvga.c:8,38 – 1994/0624/sys/src/9/pc/devvga.c:8,17 (short | long | prev | next) | ||
| 1992/0527 | ||
| 1992/0603 | #include <libg.h> | |
| 1994/0414 | #include "screen.h" | |
| 1994/0624 | #include "vga.h" | |
| 1992/0527 | ||
| 1993/1116 | enum { | |
| 1992/1119 | ||
| 1994/0412 |
| |
| 1994/0603/sys/src/9/pc/devvga.c:47,52 – 1994/0624/sys/src/9/pc/devvga.c:26,32 | ||
| 1993/1116 | static Lock screenlock; | |
| 1994/0415 | static Lock loadlock; | |
| 1993/1116 | static ulong colormap[256][3]; | |
| 1994/0624 | Lock pallettelock; | |
| 1992/1119 | ||
| 1993/1116 | /* cga screen */ static int cga = 1; /* true if in cga mode */ | |
| 1994/0603/sys/src/9/pc/devvga.c:59,67 – 1994/0624/sys/src/9/pc/devvga.c:39,44 | ||
| 1992/0527 | /* | |
| 1992/1119 | * screen dimensions | |
| 1992/0527 | */ | |
| 1993/1116 |
| |
| 1992/1119 |
| |
| 1993/1116 | #define CGAWIDTH 160 #define CGAHEIGHT 24 | |
| 1992/0527 | ||
| 1994/0603/sys/src/9/pc/devvga.c:79,85 – 1994/0624/sys/src/9/pc/devvga.c:56,61 | ||
| 1992/1119 | { char *name; | |
| 1993/1116 | void (*setpage)(int); /* routine to page though display memory */ | |
| 1994/0503 |
| |
| 1992/1119 | }; enum | |
| 1994/0603/sys/src/9/pc/devvga.c:93,118 – 1994/0624/sys/src/9/pc/devvga.c:69,103 | ||
| 1992/1119 | Generic, }; | |
| 1993/1116 |
| |
| 1994/0624 | static void nopage(int), tsengpage(int), tridentpage(int); | |
| 1994/0311 | static void atipage(int), cirruspage(int), s3page(int); | |
| 1993/1116 | ||
| 1994/0503 |
| |
| 1993/0106 | Vgacard vgachips[] = | |
| 1992/1119 | { | |
| 1994/0503 |
| |
| 1994/0624 | [Ati] { "ati", atipage, }, [Pvga1a] { "pvga1a", cirruspage, }, [Trident] { "trident", tridentpage, }, [Tseng] { "tseng", tsengpage, }, [Cirrus] { "cirrus", cirruspage, }, [S3] { "s3", s3page, }, [Generic] { "generic", nopage, }, | |
| 1992/1119 | { 0, 0, }, }; Vgacard *vgacard; /* current vga card */ | |
| 1994/0510 |
| |
| 1992/1119 | ||
| 1994/0624 | extern Hwgc tvp3020hwgc; extern Hwgc bt485hwgc; static Hwgc *hwcursor[] = { &tvp3020hwgc, &bt485hwgc, 0, }; static Hwgc *hwgc; extern Cursor curs; /* barf */ | |
| 1994/0415 | /* * work areas for bitblting screen characters, scrolling, and cursor redraw */ | |
| 1994/0603/sys/src/9/pc/devvga.c:122,133 – 1994/0624/sys/src/9/pc/devvga.c:107,112 | ||
| 1994/0415 | ||
| 1993/1116 | /* predefined for the stupid compiler */ static void setscreen(int, int, int); | |
| 1994/0603/sys/src/9/pc/devvga.c:141,193 – 1994/0624/sys/src/9/pc/devvga.c:120,142 | ||
| 1993/1116 | ||
| 1994/0416 | extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**); | |
| 1994/0413 | ||
| 1994/0416 | ||
| 1992/1119 | /* | |
| 1994/0416 |
| |
| 1993/1116 | * vga device | |
| 1992/1119 | */ enum { | |
| 1993/1116 |
| |
| 1994/0603 |
| |
| 1994/0624 | Qdir = 0, Qvgaiob = 1, Qvgaiow = 2, Qvgaiol = 3, Qvgactl = 4, Nvga = Qvgactl, | |
| 1992/1119 | }; | |
| 1992/0527 | Dirtab vgadir[]={ | |
| 1992/1119 |
| |
| 1992/0528 |
| |
| 1993/1116 |
| |
| 1994/0603 |
| |
| 1994/0503 |
| |
| 1994/0624 | "vgaiob", { Qvgaiob }, 0, 0666, "vgaiow", { Qvgaiow }, 0, 0666, "vgaiol", { Qvgaiol }, 0, 0666, "vgactl", { Qvgactl }, 0, 0666, | |
| 1992/0527 | }; void | |
| 1994/0603/sys/src/9/pc/devvga.c:245,250 – 1994/0624/sys/src/9/pc/devvga.c:194,209 | ||
| 1992/0711 | USED(c); | |
| 1992/0527 | } | |
| 1994/0624 | static int checkvgaport(int port, int len) { if((port == 0x102 || port == 0x46E8) && len == 1) return 0; if(port >= 0x3B0 && port+len < 0x3E0) return 0; return -1; } | |
| 1992/0527 | long vgaread(Chan *c, void *buf, long n, ulong offset) { | |
| 1994/0603/sys/src/9/pc/devvga.c:257,273 – 1994/0624/sys/src/9/pc/devvga.c:216,239 | ||
| 1992/0527 | switch(c->qid.path&~CHDIR){ case Qdir: return devdirread(c, buf, n, vgadir, Nvga, devgen); | |
| 1992/1119 |
| |
| 1994/0624 | case Qvgactl: port = sprint(cbuf, "type: %s\n", vgacard->name); port += sprint(cbuf+port, "size: %dx%dx%d\n", gscreen.r.max.x, gscreen.r.max.y, 1<<gscreen.ldepth); port += sprint(cbuf+port, "hwgc: "); if(hwgc) sprint(cbuf+port, "%s\n", hwgc->name); else sprint(cbuf+port, "off\n"); | |
| 1992/1119 | return readstr(offset, buf, n, cbuf); | |
| 1992/0528 |
| |
| 1993/1116 |
| |
| 1992/0528 |
| |
| 1994/0624 | case Qvgaiob: port = offset; if(checkvgaport(port, n)) error(Eperm); for(cp = buf; port < offset+n; port++) *cp++ = vgai(port); | |
| 1992/0528 | return n; | |
| 1993/1116 |
| |
| 1994/0624 | case Qvgaiow: | |
| 1993/1116 | if((n & 01) || (offset & 01)) error(Ebadarg); n /= 2; | |
| 1994/0603/sys/src/9/pc/devvga.c:274,280 – 1994/0624/sys/src/9/pc/devvga.c:240,246 | ||
| 1993/1116 | for (sp = buf, port=offset; port<offset+n; port+=2) *sp++ = ins(port); return n*2; | |
| 1994/0603 |
| |
| 1994/0624 | case Qvgaiol: | |
| 1994/0603 | if((n & 03) || (offset & 03)) error(Ebadarg); n /= 4; | |
| 1994/0603/sys/src/9/pc/devvga.c:286,297 – 1994/0624/sys/src/9/pc/devvga.c:252,331 | ||
| 1992/1119 | return 0; | |
| 1992/0527 | } | |
| 1994/0624 | static void vgactl(char *arg) { int i, x, y, z; char *cp, *field[3]; if(getfields(arg, field, 3, ' ') != 2) error(Ebadarg); if(strcmp(field[0], "hwgc") == 0){ if(strcmp(field[1], "off") == 0){ if(hwgc){ (*hwgc->disable)(); hwgc = 0; cursoron(1); } return; } for(i = 0; hwcursor[i]; i++){ if(strcmp(field[1], hwcursor[i]->name) == 0){ if(hwgc) (*hwgc->disable)(); else cursoroff(1); hwgc = hwcursor[i]; (*hwgc->enable)(); setcursor(&curs); cursoron(1); return; } } } else if(strcmp(field[0], "type") == 0){ for(i = 0; vgachips[i].name; i++){ if(strcmp(field[1], vgachips[i].name) == 0){ vgacard = &vgachips[i]; return; } } } else if(strcmp(field[0], "size") == 0){ if((x = strtoul(field[1], &cp, 0)) == 0 || x > 2048) error(Ebadarg); if(*cp) cp++; if((y = strtoul(cp, &cp, 0)) == 0 || y > 1280) error(Ebadarg); if(*cp) cp++; if((z = strtoul(cp, &cp, 0)) == 1) z = 0; else if(z == 8) z = 3; else error(Ebadarg); cursoroff(1); setscreen(x, y, z); cursoron(1); return; } error(Ebadarg); } | |
| 1992/0527 | long | |
| 1992/0528 | vgawrite(Chan *c, void *buf, long n, ulong offset) | |
| 1992/0527 | { | |
| 1992/1119 |
| |
| 1994/0624 | int port; uchar *cp; char cbuf[64]; | |
| 1993/1116 | ushort *sp; | |
| 1994/0603 | ulong *lp; | |
| 1992/0528 | ||
| 1994/0603/sys/src/9/pc/devvga.c:298,365 – 1994/0624/sys/src/9/pc/devvga.c:332,352 | ||
| 1992/0527 | switch(c->qid.path&~CHDIR){ case Qdir: error(Eperm); | |
| 1992/1119 |
| |
| 1992/0528 |
| |
| 1992/1119 |
| |
| 1993/0106 |
| |
| 1992/1119 |
| |
| 1994/0503 | case Qvgactl: if(offset != 0 || n >= sizeof(cbuf)) error(Ebadarg); memmove(cbuf, buf, n); cbuf[n] = 0; | |
| 1992/0527 |
| |
| 1992/1119 |
| |
| 1992/0528 |
| |
| 1992/0603 |
| |
| 1992/0604 |
| |
| 1992/0603 |
| |
| 1992/1119 |
| |
| 1992/0603 |
| |
| 1992/1119 |
| |
| 1994/0422 |
| |
| 1992/1119 |
| |
| 1992/0603 |
| |
| 1993/1117 |
| |
| 1992/1119 |
| |
| 1993/1117 |
| |
| 1994/0624 | vgactl(cbuf); | |
| 1992/0603 | return n; | |
| 1992/0528 |
| |
| 1993/1116 |
| |
| 1992/0528 |
| |
| 1994/0624 | case Qvgaiob: port = offset; if(checkvgaport(port, n)) error(Eperm); for(cp = buf; port < offset+n; port++) vgao(port, *cp++); | |
| 1992/0604 | return n; | |
| 1993/1116 |
| |
| 1994/0624 | case Qvgaiow: | |
| 1993/1116 | if((n & 01) || (offset & 01)) error(Ebadarg); n /= 2; | |
| 1994/0603/sys/src/9/pc/devvga.c:366,372 – 1994/0624/sys/src/9/pc/devvga.c:353,359 | ||
| 1993/1116 | for (sp = buf, port=offset; port<offset+n; port+=2) outs(port, *sp++); return n*2; | |
| 1994/0603 |
| |
| 1994/0624 | case Qvgaiol: | |
| 1994/0603 | if((n & 03) || (offset & 03)) error(Ebadarg); n /= 4; | |
| 1994/0603/sys/src/9/pc/devvga.c:392,444 – 1994/0624/sys/src/9/pc/devvga.c:379,489 | ||
| 1992/0527 | error(Eperm); } | |
| 1992/1119 | ||
| 1993/1116 |
| |
| 1994/0416 |
| |
| 1993/1116 |
| |
| 1994/0416 |
| |
| 1994/0624 | int vgaxi(long port, uchar index) | |
| 1993/1116 | { | |
| 1994/0416 |
| |
| 1994/0624 | uchar data; switch(port){ case Seqx: case Crtx: case Grx: outb(port, index); data = inb(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. */ inb(Status1); if(index < 0x10){ outb(Attrx, index); data = inb(Attrx+1); inb(Status1); outb(Attrx, 0x20|index); } else{ outb(Attrx, 0x20|index); data = inb(Attrx+1); } break; default: return -1; } return data & 0xFF; | |
| 1994/0416 | } | |
| 1994/0624 | int vgaxo(long port, uchar index, uchar data) | |
| 1994/0416 | { | |
| 1994/0624 | 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. */ outb(port, index); outb(port+1, data); break; case Attrx: inb(Status1); if(index < 0x10){ outb(Attrx, index); outb(Attrx, data); inb(Status1); outb(Attrx, 0x20|index); } else{ outb(Attrx, 0x20|index); outb(Attrx, data); } break; default: return -1; | |
| 1994/0416 | } | |
| 1994/0624 | return 0; | |
| 1994/0416 | } | |
| 1994/0624 | /* * start the screen in CGA mode. Create the fonts for VGA. Called by * main(). */ void screeninit(void) | |
| 1994/0416 | { | |
| 1994/0624 | int i; ulong *l; /* * swizzle the font longs. */ l = defont0.bits->base; for(i = defont0.bits->width*Dy(defont0.bits->r); i > 0; i--, l++) *l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); /* * start in CGA mode */ cga = 1; vgaxo(Crtx, 0x0A, 0xFF); /* turn off cursor */ memset(CGASCREEN, 0, CGAWIDTH*CGAHEIGHT); | |
| 1994/0416 | } | |
| 1993/1116 | ||
| 1994/0416 | /* | |
| 1994/0603/sys/src/9/pc/devvga.c:447,453 – 1994/0624/sys/src/9/pc/devvga.c:492,498 | ||
| 1994/0416 | typedef struct VGAmode VGAmode; struct VGAmode { | |
| 1994/0624 | uchar misc; | |
| 1994/0416 | uchar sequencer[5]; uchar crt[0x19]; uchar graphics[9]; | |
| 1994/0603/sys/src/9/pc/devvga.c:460,466 – 1994/0624/sys/src/9/pc/devvga.c:505,511 | ||
| 1994/0416 | VGAmode mode12 = { /* general */ | |
| 1994/0624 | 0xe7, | |
| 1994/0416 | /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x06, /* crt */ | |
| 1994/0603/sys/src/9/pc/devvga.c:483,489 – 1994/0624/sys/src/9/pc/devvga.c:528,534 | ||
| 1994/0416 | VGAmode mode13 = { /* general */ | |
| 1994/0624 | 0x63, | |
| 1994/0416 | /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x0e, /* crt */ | |
| 1994/0603/sys/src/9/pc/devvga.c:501,534 – 1994/0624/sys/src/9/pc/devvga.c:546,592 | ||
| 1994/0416 | }; | |
| 1994/0412 | static void | |
| 1994/0624 | setmode(VGAmode *vga) | |
| 1994/0412 | { int i; | |
| 1994/0624 | /* * Turn off the screen and * reset the sequencer and leave it off. * Load the generic VGA registers: * misc; * sequencer; * take the sequencer out of reset; * take off write-protect on crt[0x00-0x07]; * crt; * graphics; * attribute; * Turn on the screen. */ vgaxo(Seqx, 0x01, 0x21); | |
| 1994/0412 |
| |
| 1994/0624 | vgaxo(Seqx, 0x00, 0x00); | |
| 1994/0412 |
| |
| 1994/0624 | vgao(MiscW, vga->misc); for(i = 1; i < NSeqx; i++){ | |
| 1994/0412 | if(i == 1) | |
| 1994/0624 | continue; vgaxo(Seqx, i, vga->sequencer[i]); } vgaxo(Seqx, 0x00, 0x03); | |
| 1994/0412 |
| |
| 1994/0624 | vgaxo(Crtx, 0x11, vga->crt[0x11] & ~0x80); for(i = 0; i < NCrtx; i++) vgaxo(Crtx, i, vga->crt[i]); | |
| 1994/0412 |
| |
| 1994/0624 | for(i = 0; i < NGrax; i++) vgaxo(Grx, i, vga->graphics[i]); | |
| 1994/0412 |
| |
| 1994/0624 | for(i = 0; i < NAttrx; i++) vgaxo(Attrx, i, vga->attribute[i]); | |
| 1994/0412 |
| |
| 1994/0624 | vgaxo(Seqx, 0x01, vga->sequencer[1]); | |
| 1994/0412 | } | |
| 1993/1116 | /* | |
| 1994/0603/sys/src/9/pc/devvga.c:709,715 – 1994/0624/sys/src/9/pc/devvga.c:767,773 | ||
| 1993/1116 | if(!rectclip(&r, gscreen.r) || tl<=0) return; | |
| 1994/0412 | ||
| 1994/0503 |
| |
| 1994/0624 | if(dolock && hwgc == 0) | |
| 1994/0412 | cursorlock(r); | |
| 1994/0415 | lock(&loadlock); | |
| 1994/0412 | ||
| 1994/0603/sys/src/9/pc/devvga.c:792,798 – 1994/0624/sys/src/9/pc/devvga.c:850,856 | ||
| 1993/1116 | } | |
| 1994/0412 | ||
| 1994/0415 | unlock(&loadlock); | |
| 1994/0503 |
| |
| 1994/0624 | if(dolock && hwgc == 0) | |
| 1994/0412 | cursorunlock(); | |
| 1993/1116 | } | |
| 1994/0603/sys/src/9/pc/devvga.c:865,871 – 1994/0624/sys/src/9/pc/devvga.c:923,929 | ||
| 1994/0412 | if(!rectclip(&r, gscreen.r) || tl<=0) | |
| 1993/1116 | return; | |
| 1994/0503 |
| |
| 1994/0624 | if(dolock && hwgc == 0) | |
| 1994/0412 | cursorlock(r); | |
| 1994/0415 | lock(&loadlock); | |
| 1993/1116 | ||
| 1994/0603/sys/src/9/pc/devvga.c:948,954 – 1994/0624/sys/src/9/pc/devvga.c:1006,1012 | ||
| 1994/0412 | } | |
| 1994/0415 | unlock(&loadlock); | |
| 1994/0503 |
| |
| 1994/0624 | if(dolock && hwgc == 0) | |
| 1994/0412 | cursorunlock(); | |
| 1993/1116 | } | |
| 1994/0603/sys/src/9/pc/devvga.c:1048,1054 – 1994/0624/sys/src/9/pc/devvga.c:1106,1115 | ||
| 1993/0106 | static void | |
| 1992/1216 | tridentpage(int page) { | |
| 1993/0915 |
| |
| 1994/0624 | uchar seq0E; seq0E = vgaxi(Seqx, 0x0E) & 0xF0; vgaxo(Seqx, 0x0E, seq0E|(page^0x02)); | |
| 1992/1119 | } static void tsengpage(int page) | |
| 1994/0603/sys/src/9/pc/devvga.c:1058,1071 – 1994/0624/sys/src/9/pc/devvga.c:1119,1127 | ||
| 1992/1124 | static void | |
| 1993/0915 | cirruspage(int page) { | |
| 1994/0624 | vgaxo(Grx, 0x09, page<<4); | |
| 1993/0915 | } static void | |
| 1992/1124 |
| |
| 1993/0915 |
| |
| 1994/0311 |
| |
| 1994/0603/sys/src/9/pc/devvga.c:1077,1107 – 1994/0624/sys/src/9/pc/devvga.c:1133,1153 | ||
| 1994/0323 | /* * The S3 registers need to be unlocked for this. * Let's hope they are already: | |
| 1994/0624 | * vgaxo(Crtx, 0x38, 0x48); * vgaxo(Crtx, 0x39, 0xA0); | |
| 1994/0323 | * * The page is 6 bits, the lower 4 bits in Crt35<3:0>, * the upper 2 in Crt51<3:2>. */ | |
| 1994/0624 | vgaxo(Crtx, 0x35, page & 0x0F); crt51 = vgaxi(Crtx, 0x51) & 0xF3; vgaxo(Crtx, 0x51, crt51|((page & 0x30)>>2)); | |
| 1994/0323 | } else | |
| 1994/0624 | vgaxo(Crtx, 0x35, (page<<2) & 0x0C); | |
| 1992/1119 | } | |
| 1994/0415 | /* | |
| 1994/0503 |
| |
| 1994/0415 | * character mode console */ | |
| 1992/1119 | static void | |
| 1994/0603/sys/src/9/pc/devvga.c:1245,1255 – 1994/0624/sys/src/9/pc/devvga.c:1291,1301 | ||
| 1993/1230 | } p &= x; p ^= x; | |
| 1993/1116 |
| |
| 1994/0624 | lock(&pallettelock); | |
| 1992/1119 | *pr = colormap[p][0]; *pg = colormap[p][1]; *pb = colormap[p][2]; | |
| 1993/1116 |
| |
| 1994/0624 | unlock(&pallettelock); | |
| 1992/1119 | } int | |
| 1994/0603/sys/src/9/pc/devvga.c:1267,1286 – 1994/0624/sys/src/9/pc/devvga.c:1313,1333 | ||
| 1993/1230 | } p &= x; p ^= x; | |
| 1993/1116 |
| |
| 1994/0624 | lock(&pallettelock); | |
| 1992/1119 | colormap[p][0] = r; colormap[p][1] = g; colormap[p][2] = b; | |
| 1993/1116 |
| |
| 1994/0624 | vgao(DACWx, p); vgao(DACData, r>>(32-6)); vgao(DACData, g>>(32-6)); vgao(DACData, b>>(32-6)); unlock(&pallettelock); | |
| 1992/1119 | return ~0; | |
| 1994/0414 | } /* * software cursor | |
| 1994/0624 | * and hacks for hardware cursor | |
| 1994/0414 | */ | |
| 1994/0415 | /* | |
| 1994/0603/sys/src/9/pc/devvga.c:1340,1346 – 1994/0624/sys/src/9/pc/devvga.c:1387,1395 | ||
| 1994/0520 | uchar *p; int i; | |
| 1994/0624 | if(hwgc) (*hwgc->load)(curs); else for(i=0; i<16; i++){ | |
| 1994/0520 | p = (uchar*)&set.base[i]; *p = curs->set[2*i]; *(p+1) = curs->set[2*i+1]; | |
| 1994/0603/sys/src/9/pc/devvga.c:1350,1359 – 1994/0624/sys/src/9/pc/devvga.c:1399,1408 | ||
| 1994/0520 | } | |
| 1994/0414 | } | |
| 1994/0624 | int | |
| 1994/0414 | cursoron(int dolock) { | |
| 1994/0510 |
| |
| 1994/0624 | int xoff, yoff, s, ret; | |
| 1994/0414 | Rectangle r; uchar *a; struct { | |
| 1994/0603/sys/src/9/pc/devvga.c:1365,1376 – 1994/0624/sys/src/9/pc/devvga.c:1414,1429 | ||
| 1994/0414 | } xx; if(cursor.disable) | |
| 1994/0510 |
| |
| 1994/0624 | return 0; if(dolock){ s = 0; /* to avoid compiler warning */ | |
| 1994/0414 | lock(&cursor); | |
| 1994/0624 | } else s = spllo(); /* to avoid freezing out the eia ports */ | |
| 1994/0414 | ||
| 1994/0503 |
| |
| 1994/0624 | ret = 0; if(hwgc) ret = (*hwgc->move)(mousexy()); | |
| 1994/0503 | else if(cursor.visible++ == 0){ | |
| 1994/0414 | cursor.r.min = mousexy(); cursor.r.max = add(cursor.r.min, Pt(16, 16)); | |
| 1994/0603/sys/src/9/pc/devvga.c:1419,1430 – 1994/0624/sys/src/9/pc/devvga.c:1472,1487 | ||
| 1994/0414 | if(dolock) unlock(&cursor); | |
| 1994/0624 | else splx(s); return ret; | |
| 1994/0414 | } void cursoroff(int dolock) { | |
| 1994/0503 |
| |
| 1994/0624 | if(hwgc) | |
| 1994/0503 | return; | |
| 1994/0414 | if(cursor.disable) return; | |