| plan 9 kernel history: overview | file list | diff list |
1992/0502/pc/vga.c (diff list | history)
| pc/vga.c on 1991/0723 | ||
| 1991/0723 | #include "u.h" | |
| 1992/0321 | #include "../port/lib.h" | |
| 1991/0723 | #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" | |
| 1991/0730 | #include <libg.h> #include <gnot.h> #include "screen.h" #define MINX 8 | |
| 1992/0208 | extern GSubfont defont0; GSubfont *defont; | |
| 1991/0730 | struct{ Point pos; int bwid; }out; /* * screen dimensions */ | |
| 1992/0502 | /* | |
| 1992/0430 | #define MAXX 800 #define MAXY 600 | |
| 1992/0502 | */ #define MAXX 640 #define MAXY 480 | |
| 1991/0730 | #define SCREENMEM (0xA0000 | KZERO) GBitmap gscreen = { (ulong*)SCREENMEM, 0, 640/32, 0, 0, 0, MAXX, MAXY, 0 }; | |
| 1991/0723 | enum { | |
| 1991/1112 | EMISCR= 0x3CC, /* control sync polarity */ EMISCW= 0x3C2, EFCW= 0x3DA, /* feature control */ EFCR= 0x3CA, | |
| 1991/0723 | GRX= 0x3CE, /* index to graphics registers */ | |
| 1991/0727 | GR= 0x3CF, /* graphics registers */ Grms= 0x04, /* read map select register */ | |
| 1991/0724 | SRX= 0x3C4, /* index to sequence registers */ | |
| 1991/0727 | SR= 0x3C5, /* sequence registers */ Smmask= 0x02, /* map mask */ CRX= 0x3D4, /* index to crt registers */ CR= 0x3D5, /* crt registers */ | |
| 1991/1109 | Cvre= 0x11, /* vertical retrace end */ | |
| 1991/1211 | ARW= 0x3C0, /* attribute registers (writing) */ ARR= 0x3C1, /* attribute registers (reading) */ | |
| 1991/0723 | }; | |
| 1991/1113 | typedef struct VGAmode VGAmode; struct VGAmode { | |
| 1992/0423 | uchar general[2]; | |
| 1991/1113 | uchar sequencer[5]; uchar crt[0x19]; uchar graphics[9]; uchar attribute[0x15]; }; | |
| 1991/0727 | /* | |
| 1992/0430 | * 640x480 display, 16 bit color. | |
| 1992/0414 | */ VGAmode mode12 = { /* general */ | |
| 1992/0502 | 0xe7, 0x00, | |
| 1992/0414 | /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x06, /* crt */ 0x65, 0x4f, 0x50, 0x88, 0x55, 0x9a, 0x09, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, 0xff, /* graphics */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* attribute */ | |
| 1992/0418 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, | |
| 1992/0423 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x3f, | |
| 1992/0418 | 0x01, 0x10, 0x0f, 0x00, 0x00, | |
| 1992/0414 | }; | |
| 1992/0418 | ||
| 1992/0430 | /* | |
| 1992/0502 | * VESA standard (?) 800x600 display, 16 bit color. | |
| 1992/0430 | */ | |
| 1992/0501 | VGAmode mode6a = | |
| 1992/0430 | { /* general */ | |
| 1992/0502 | 0xe3, 0x00, /* 0x70, 0x04, these are read-only */ | |
| 1992/0430 | /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x06, /* crt */ | |
| 1992/0502 | 0x7f, 0x63, 0x64, 0x02, 0x6a, 0x1d, 0x77, 0xf0, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, | |
| 1992/0501 | 0x5d, 0x8f, 0x57, 0x32, 0x00, 0x5b, 0x74, 0xc3, 0xff, | |
| 1992/0430 | /* graphics */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, 0xff, /* attribute */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x3f, 0x01, 0x10, 0x0f, 0x00, 0x00, }; | |
| 1991/0724 | void | |
| 1991/1113 | genout(int reg, int val) { if(reg == 0) outb(EMISCW, val); else if (reg == 1) outb(EFCW, val); } void | |
| 1991/0724 | srout(int reg, int val) { | |
| 1992/0414 | /* * needed or the screen goes blank on an ultra VGA card */ | |
| 1991/0724 | outb(SRX, reg); outb(SR, val); } void grout(int reg, int val) { outb(GRX, reg); outb(GR, val); } | |
| 1991/0727 | void arout(int reg, int val) { | |
| 1992/0414 | /* * if this print is missing, we are left with a blank white screen. */ | |
| 1991/0727 | inb(0x3DA); | |
| 1992/0423 | if (reg <= 0xf) { outb(ARW, reg | 0x0); outb(ARW, val); inb(0x3DA); outb(ARW, reg | 0x20); } else { outb(ARW, reg | 0x20); outb(ARW, val); } | |
| 1991/0727 | } | |
| 1992/0423 | ||
| 1991/0727 | void crout(int reg, int val) { outb(CRX, reg); outb(CR, val); } | |
| 1991/1107 | ||
| 1991/0723 | /* | |
| 1991/0727 | * m is a bit mask of planes to be affected by CPU writes | |
| 1991/0723 | */ | |
| 1991/0727 | vgawrmask(int m) { srout(Smmask, m&0xf); } /* * p is the plane that will respond to CPU reads */ vgardplane(int p) { grout(Grms, p&3); } | |
| 1991/1112 | vgadump(void) { print("misc is 0x%ux fc is 0x%ux\n", inb(EMISCR), inb(EFCR)); } | |
| 1991/1113 | void setmode(VGAmode *v) | |
| 1991/1112 | { | |
| 1991/1113 | int i; | |
| 1991/1112 | ||
| 1991/1113 | for(i = 0; i < sizeof(v->general); i++) genout(i, v->general[i]); | |
| 1991/0928 | ||
| 1991/1113 | for(i = 0; i < sizeof(v->sequencer); i++) srout(i, v->sequencer[i]); | |
| 1991/0928 | ||
| 1991/1113 | crout(Cvre, 0); /* allow writes to CRT registers 0-7 */ for(i = 0; i < sizeof(v->crt); i++) crout(i, v->crt[i]); | |
| 1991/1109 | ||
| 1991/1113 | for(i = 0; i < sizeof(v->graphics); i++) grout(i, v->graphics[i]); | |
| 1991/1109 | ||
| 1991/1113 | for(i = 0; i < sizeof(v->attribute); i++) arout(i, v->attribute[i]); | |
| 1991/0928 | } | |
| 1992/0423 | #ifdef VGATROUBLE | |
| 1991/0727 | void | |
| 1992/0502 | getmode(VGAmode *v) { | |
| 1992/0423 | int i; | |
| 1992/0502 | v->general[0] = inb(0x3cc); v->general[1] = inb(0x3ca); for(i = 0; i < sizeof(v->sequencer); i++) { outb(SRX, i); v->sequencer[i] = inb(SR); } for(i = 0; i < sizeof(v->crt); i++) { outb(CRX, i); v->crt[i] = inb(CR); } for(i = 0; i < sizeof(v->graphics); i++) { outb(GRX, i); v->graphics[i] = inb(GR); } for(i = 0; i < sizeof(v->attribute); i++) { inb(0x3DA); outb(ARW, i | 0x20); v->attribute[i] = inb(ARR); } } | |
| 1992/0423 | ||
| 1992/0502 | void printmode(VGAmode *v) { int i; print("general registers: %02x %02x\n", v->general[0], v->general[1]); print("sequence registers: "); for(i = 0; i < sizeof(v->sequencer); i++) { print(" %02x", v->sequencer[i]); } print("\nCRT registers: "); for(i = 0; i < sizeof(v->crt); i++) { print(" %02x", v->crt[i]); } print("\nGraphics registers: "); for(i = 0; i < sizeof(v->graphics); i++) { print(" %02x", v->graphics[i]); } print("\nAttribute registers: "); for(i = 0; i < sizeof(v->attribute); i++) { print(" %02x", v->attribute[i]); } print("\n"); } void dumpmodes(void) { VGAmode *v; int i; | |
| 1992/0423 | print("general registers: %02x %02x %02x %02x\n", inb(0x3cc), inb(0x3ca), inb(0x3c2), inb(0x3da)); print("sequence registers: "); for(i = 0; i < sizeof(v->sequencer); i++) { outb(SRX, i); print(" %02x", inb(SR)); } print("\nCRT registers: "); for(i = 0; i < sizeof(v->crt); i++) { outb(CRX, i); print(" %02x", inb(CR)); } print("\nGraphics registers: "); for(i = 0; i < sizeof(v->graphics); i++) { outb(GRX, i); print(" %02x", inb(GR)); } print("\nAttribute registers: "); for(i = 0; i < sizeof(v->attribute); i++) { inb(0x3DA); outb(ARW, i | 0x20); print(" %02x", inb(ARR)); } } #endif void | |
| 1991/0730 | screeninit(void) | |
| 1991/0723 | { | |
| 1991/0727 | int i, j, k; int c; | |
| 1991/0730 | ulong *l; | |
| 1992/0502 | VGAmode v; | |
| 1991/0723 | ||
| 1992/0501 | setmode(&mode12); | |
| 1991/0929 | ||
| 1991/0727 | /* | |
| 1991/0801 | * swizzle the font longs. | |
| 1991/0921 | * we do it here since the font is initialized with big * endian longs. | |
| 1991/0801 | */ defont = &defont0; l = defont->bits->base; for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++) *l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, flipD[0]); | |
| 1991/0730 | out.pos.x = MINX; out.pos.y = 0; out.bwid = defont0.info[' '].width; | |
| 1991/0723 | } | |
| 1991/0727 | ||
| 1991/0730 | void | |
| 1991/1228 | screenputnl(void) | |
| 1991/0730 | { | |
| 1991/1228 | out.pos.x = MINX; out.pos.y += defont0.height; if(out.pos.y > gscreen.r.max.y-defont0.height) out.pos.y = gscreen.r.min.y; gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), flipD[0]); | |
| 1991/0730 | } | |
| 1992/0402 | Lock screenlock; | |
| 1991/0730 | void screenputs(char *s, int n) { | |
| 1991/1228 | Rune r; int i; char buf[4]; | |
| 1992/0402 | lock(&screenlock); | |
| 1991/1228 | while(n > 0){ i = chartorune(&r, s); if(i == 0){ s++; --n; continue; } memmove(buf, s, i); buf[i] = 0; n -= i; s += i; if(r == '\n') screenputnl(); else if(r == '\t'){ out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; if(out.pos.x >= gscreen.r.max.x) screenputnl(); }else if(r == '\b'){ if(out.pos.x >= out.bwid+MINX){ out.pos.x -= out.bwid; | |
| 1992/0208 | gsubfstring(&gscreen, out.pos, defont, " ", flipD[S]); | |
| 1991/1228 | } }else{ if(out.pos.x >= gscreen.r.max.x-out.bwid) screenputnl(); | |
| 1992/0208 | out.pos = gsubfstring(&gscreen, out.pos, defont, buf, flipD[S]); | |
| 1991/1228 | } } | |
| 1992/0402 | unlock(&screenlock); | |
| 1991/0730 | } int screenbits(void) { return 1; /* bits per pixel */ } void getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) { ulong ans; /* | |
| 1991/0731 | * The safari monochrome says 0 is black (zero intensity) | |
| 1991/0730 | */ if(p == 0) ans = 0; else ans = ~0; *pr = *pg = *pb = ans; } int setcolor(ulong p, ulong r, ulong g, ulong b) { return 0; /* can't change mono screen colormap */ } int hwcursset(uchar *s, uchar *c, int ox, int oy) { return 0; } int hwcursmove(int x, int y) { return 0; } void | |
| 1991/0904 | mouseclock(void) | |
| 1991/0730 | { mouseupdate(1); | |
| 1991/0927 | } vgaset(char *cmd) { int set; int reg; int val; set = *cmd++; cmd++; reg = strtoul(cmd, &cmd, 0); cmd++; val = strtoul(cmd, &cmd, 0); switch(set){ case 'a': arout(reg, val); break; case 'g': grout(reg, val); break; case 'c': crout(reg, val); break; case 's': srout(reg, val); break; } | |
| 1991/1113 | } /* * a fatter than usual cursor for the safari */ Cursor fatarrow = { { -1, -1 }, { 0xff, 0xff, 0x80, 0x01, 0x80, 0x02, 0x80, 0x0c, 0x80, 0x10, 0x80, 0x10, 0x80, 0x08, 0x80, 0x04, 0x80, 0x02, 0x80, 0x01, 0x80, 0x02, 0x8c, 0x04, 0x92, 0x08, 0x91, 0x10, 0xa0, 0xa0, 0xc0, 0x40, }, { 0x00, 0x00, 0x7f, 0xfe, 0x7f, 0xfc, 0x7f, 0xf0, 0x7f, 0xe0, 0x7f, 0xe0, 0x7f, 0xf0, 0x7f, 0xf8, 0x7f, 0xfc, 0x7f, 0xfe, 0x7f, 0xfc, 0x73, 0xf8, 0x61, 0xf0, 0x60, 0xe0, 0x40, 0x40, 0x00, 0x00, }, }; void bigcursor(void) { extern Cursor arrow; memmove(&arrow, &fatarrow, sizeof(fatarrow)); | |
| 1991/0730 | } | |