| plan 9 kernel history: overview | file list | diff list |
1991/1109/pc/vga.c (diff list | history)
| pc/vga.c on 1991/0723 | ||
| 1991/0723 | #include "u.h" #include "lib.h" #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 extern GFont defont0; GFont *defont; struct{ Point pos; int bwid; }out; /* * screen dimensions */ #define MAXX 640 #define MAXY 480 | |
| 1991/1109 | #define XPERIOD 800 /* Hsync freq == 31.47 KHZ */ #define YPERIOD 525 /* Vsync freq == 59.9 HZ */ #define YBORDER 2 | |
| 1991/0730 | #define SCREENMEM (0xA0000 | KZERO) GBitmap gscreen = { (ulong*)SCREENMEM, 0, 640/32, 0, 0, 0, MAXX, MAXY, 0 }; | |
| 1991/0723 | enum { GRX= 0x3CE, /* index to graphics registers */ | |
| 1991/0727 | GR= 0x3CF, /* graphics registers */ Grot= 0x03, /* data rotate register */ Gmode= 0x05, /* mode register */ Gmisc= 0x06, /* miscillaneous register */ Grms= 0x04, /* read map select register */ | |
| 1991/0724 | SRX= 0x3C4, /* index to sequence registers */ | |
| 1991/0727 | SR= 0x3C5, /* sequence registers */ Sclock= 0x01, /* clocking register */ Smode= 0x04, /* mode register */ Smmask= 0x02, /* map mask */ CRX= 0x3D4, /* index to crt registers */ CR= 0x3D5, /* crt registers */ | |
| 1991/1109 | Cvt= 0x06, /* vertical total */ Cvover= 0x07, /* bits that didn't fit elsewhere */ | |
| 1991/0727 | Cmsl= 0x09, /* max scan line */ | |
| 1991/1109 | Cvrs= 0x10, /* vertical retrace start */ Cvre= 0x11, /* vertical retrace end */ Cvde= 0x12, /* vertical display end */ Cvbs= 0x15, /* vertical blank start */ Cvbe= 0x16, /* vertical blank end */ Cmode= 0x17, /* mode register */ | |
| 1991/0727 | ARX= 0x3C0, /* index to attribute registers */ AR= 0x3C1, /* attribute registers */ Amode= 0x10, /* mode register */ Acpe= 0x12, /* color plane enable */ | |
| 1991/0723 | }; | |
| 1991/0727 | /* * routines for setting vga registers */ | |
| 1991/0724 | void srout(int reg, int val) { 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) { inb(0x3DA); outb(ARX, reg | 0x20); outb(AR, val); } 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/1109 | * set up like vga mode 0x12 * 16 color (though we only use values 0x0 and 0xf) | |
| 1991/0928 | * 640x480 | |
| 1991/1109 | * * we assume the BIOS left the registers in a * CGA-like mode. Thus we don't set all the registers. | |
| 1991/0928 | */ | |
| 1991/1109 | vga12(void) | |
| 1991/0928 | { | |
| 1991/1109 | int overflow; int msl; | |
| 1991/0928 | arout(Acpe, 0x00); /* disable planes for output */ gscreen.ldepth = 0; arout(Amode, 0x01); /* color graphics mode */ grout(Gmisc, 0x01); /* graphics mode */ grout(Gmode, 0x00); /* 1 bit deep */ grout(Grot, 0x00); /* CPU writes bytes to video * mem without modifications */ | |
| 1991/1109 | msl = overflow = 0; | |
| 1991/0928 | crout(Cmode, 0xe3); /* turn off address wrap & * word mode */ | |
| 1991/1109 | /* last scan line displayed (first is 0) */ crout(Cvde, MAXY-1); overflow |= ((MAXY-1)&0x200) ? 0x40 : 0; overflow |= ((MAXY-1)&0x100) ? 0x2 : 0; /* total scan lines (including retrace) - 2 */ crout(Cvt, (YPERIOD-2)); overflow |= ((YPERIOD-2)&0x200) ? 0x20 : 0; overflow |= ((YPERIOD-2)&0x100) ? 0x1 : 0; /* scan lines at which vertcal retrace starts & ends */ crout(Cvrs, (MAXY+10)); overflow |= ((MAXY+10)&0x200) ? 0x80 : 0; overflow |= ((MAXY+10)&0x100) ? 0x4 : 0; crout(Cvre, ((YPERIOD-1)&0xf)|0xa0); /* also disable vertical interrupts */ /* scan lines at which vertical blanking starts & ends */ crout(Cvbs, (MAXY+YBORDER)); msl |= ((MAXY+YBORDER)&0x200) ? 0x20 : 0; overflow |= ((MAXY+YBORDER)&0x100) ? 0x8 : 0; crout(Cvbe, (YPERIOD-YBORDER)&0x7f); /* pixels per scan line (always 0 for graphics) */ crout(Cmsl, 0x40|msl); /* also 10th bit of line compare */ /* the overflow bits from the other registers */ crout(Cvover, 0x10|overflow); /* also 9th bit of line compare */ | |
| 1991/0928 | srout(Smode, 0x06); /* extended memory, * odd/even off */ srout(Sclock, 0x01); /* 8 bits/char */ srout(Smmask, 0x0f); /* enable 4 planes for writing */ arout(Acpe, 0x0f); /* enable 4 planes for output */ } | |
| 1991/0727 | void | |
| 1991/0730 | screeninit(void) | |
| 1991/0723 | { | |
| 1991/0727 | int i, j, k; int c; | |
| 1991/0730 | ulong *l; | |
| 1991/0723 | ||
| 1991/1109 | vga12(); | |
| 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 screenputc(int c) { char buf[2]; int nx; if(c == '\n'){ 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, | |
| 1991/0801 | Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), flipD[0]); | |
| 1991/0730 | }else if(c == '\t'){ out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; if(out.pos.x >= gscreen.r.max.x) screenputc('\n'); }else if(c == '\b'){ if(out.pos.x >= out.bwid+MINX){ out.pos.x -= out.bwid; screenputc(' '); out.pos.x -= out.bwid; } }else{ if(out.pos.x >= gscreen.r.max.x-out.bwid) screenputc('\n'); buf[0] = c&0x7F; buf[1] = 0; | |
| 1991/0801 | out.pos = gstring(&gscreen, out.pos, defont, buf, flipD[S]); | |
| 1991/0730 | } } void screenputs(char *s, int n) { while(n-- > 0) screenputc(*s++); } 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/0730 | } | |