From 4db08b02a6b8a1ee615e521a080eb82e11d11e76 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 24 Jun 1994 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1994-06-24 --- carrera/screen.c | 3 +- carrera/screen.h | 2 +- pc/devvga.c | 571 ++++++++++++++++++++++++++--------------------- pc/screen.h | 2 +- pc/vga.h | 72 +++--- pc/vgabt485.c | 259 +++++++++++++++++++++ pc/vgatvp3020.c | 232 +++++++++++++++++++ port/alarm.c | 1 - port/auth.c | 1 - port/devcons.c | 1 - port/devlance.c | 1 - port/devmouse.c | 2 +- port/netif.c | 1 - 13 files changed, 856 insertions(+), 292 deletions(-) create mode 100644 pc/vgabt485.c create mode 100644 pc/vgatvp3020.c diff --git a/carrera/screen.c b/carrera/screen.c index 857c386897a04c112168ff83d8e0b03e8f412a06..4ed462e73bc6bd6016d5ff9008b2ff826a2a5125 100644 --- a/carrera/screen.c +++ b/carrera/screen.c @@ -441,7 +441,7 @@ setcursor(Cursor *curs) free(hwcursor.base); } -void +int cursoron(int dolock) { Dac *d; @@ -465,6 +465,7 @@ cursoron(int dolock) if(dolock) unlock(&cursor); + return 0; } int diff --git a/carrera/screen.h b/carrera/screen.h index 64d33762f32f17c2b4d99fbbe0fd70320eb02222..55ad7d78d0dbf09eff69ba312c1577f320326290 100644 --- a/carrera/screen.h +++ b/carrera/screen.h @@ -9,7 +9,7 @@ struct Cursorinfo extern Cursorinfo cursor; extern void mouseupdate(int); -extern void cursoron(int); +extern int cursoron(int); #define cursoroff(x) #define mousectl(s) extern Point mousexy(void); diff --git a/pc/devvga.c b/pc/devvga.c index d055d178572420ae82c08c6e47a9dce968ab0f19..54d26244ce4d63c44f2224dcc2a73201ca2e077b 100644 --- a/pc/devvga.c +++ b/pc/devvga.c @@ -8,28 +8,7 @@ #include #include "screen.h" - -enum -{ - EMISCR= 0x3CC, /* control sync polarity */ - EMISCW= 0x3C2, - EFCW= 0x3DA, /* feature control */ - EFCR= 0x3CA, - GRX= 0x3CE, /* index to graphics registers */ - GR= 0x3CF, /* graphics registers */ - Grms= 0x04, /* read map select register */ - SRX= 0x3C4, /* index to sequence registers */ - SR= 0x3C5, /* sequence registers */ - Smmask= 0x02, /* map mask */ - CRX= 0x3D4, /* index to crt registers */ - CR= 0x3D5, /* crt registers */ - Cvre= 0x11, /* vertical retrace end */ - ARW= 0x3C0, /* attribute registers (writing) */ - ARR= 0x3C1, /* attribute registers (reading) */ - CMRX= 0x3C7, /* color map read index */ - CMWX= 0x3C8, /* color map write index */ - CM= 0x3C9, /* color map data reg */ -}; +#include "vga.h" enum { @@ -47,6 +26,7 @@ Bitmap gscreen; static Lock screenlock; static Lock loadlock; static ulong colormap[256][3]; +Lock pallettelock; /* cga screen */ static int cga = 1; /* true if in cga mode */ @@ -59,9 +39,6 @@ static Point curpos; /* * screen dimensions */ -#define MINX 8 -#define MAXX 640 -#define MAXY 480 #define CGAWIDTH 160 #define CGAHEIGHT 24 @@ -79,7 +56,6 @@ struct Vgacard { char *name; void (*setpage)(int); /* routine to page though display memory */ - void (*mvcursor)(Point); /* routine to move hardware cursor */ }; enum @@ -93,25 +69,34 @@ enum Generic, }; -static void nopage(int), tsengpage(int), tridentpage(int), parapage(int); +static void nopage(int), tsengpage(int), tridentpage(int); static void atipage(int), cirruspage(int), s3page(int); -static void nomvcursor(Point); - Vgacard vgachips[] = { -[Ati] { "ati", atipage, nomvcursor, }, -[Pvga1a] { "pvga1a", parapage, nomvcursor, }, -[Trident] { "trident", tridentpage, nomvcursor, }, -[Tseng] { "tseng", tsengpage, nomvcursor, }, -[Cirrus] { "cirrus", cirruspage, nomvcursor, }, -[S3] { "s3", s3page, nomvcursor, }, -[Generic] { "generic", nopage, nomvcursor, }, +[Ati] { "ati", atipage, }, +[Pvga1a] { "pvga1a", cirruspage, }, +[Trident] { "trident", tridentpage, }, +[Tseng] { "tseng", tsengpage, }, +[Cirrus] { "cirrus", cirruspage, }, +[S3] { "s3", s3page, }, +[Generic] { "generic", nopage, }, { 0, 0, }, }; Vgacard *vgacard; /* current vga card */ -int hwcursor; + +extern Hwgc tvp3020hwgc; +extern Hwgc bt485hwgc; + +static Hwgc *hwcursor[] = { + &tvp3020hwgc, + &bt485hwgc, + 0, +}; + +static Hwgc *hwgc; +extern Cursor curs; /* barf */ /* * work areas for bitblting screen characters, scrolling, and cursor redraw @@ -122,12 +107,6 @@ Bitmap cursorwork; /* predefined for the stupid compiler */ static void setscreen(int, int, int); -static uchar srin(int); -static void genout(int, int); -static void srout(int, int); -static void grout(int, int); -static void arout(int, int); -static void crout(int, int); static void cgascreenputc(int); static void cgascreenputs(char*, int); static void screenputc(char*); @@ -141,53 +120,23 @@ static void cursorunlock(void); extern int graphicssubtile(uchar*, int, int, Rectangle, Rectangle, uchar**); - -/* - * start the screen in CGA mode. Create the fonts for VGA. Called by - * main(). - */ -void -screeninit(void) -{ - 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; - crout(0x0a, 0xff); /* turn off cursor */ - memset(CGASCREEN, 0, CGAWIDTH*CGAHEIGHT); -} - /* * vga device */ enum { - Qdir= 0, - Qvgasize= 1, - Qvgatype= 2, - Qvgaport= 3, - Qvgaportw= 4, - Qvgaportl= 5, - Qvgactl= 6, - Nvga= 6, + Qdir = 0, + Qvgaiob = 1, + Qvgaiow = 2, + Qvgaiol = 3, + Qvgactl = 4, + Nvga = Qvgactl, }; Dirtab vgadir[]={ - "vgasize", {Qvgasize}, 0, 0666, - "vgatype", {Qvgatype}, 0, 0666, - "vgaport", {Qvgaport}, 0, 0666, - "vgaportw", {Qvgaportw}, 0, 0666, - "vgaportl", {Qvgaportl}, 0, 0666, - "vgactl", {Qvgactl}, 0, 0666, + "vgaiob", { Qvgaiob }, 0, 0666, + "vgaiow", { Qvgaiow }, 0, 0666, + "vgaiol", { Qvgaiol }, 0, 0666, + "vgactl", { Qvgactl }, 0, 0666, }; void @@ -245,6 +194,16 @@ vgaclose(Chan *c) USED(c); } +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; +} + long vgaread(Chan *c, void *buf, long n, ulong offset) { @@ -257,24 +216,31 @@ vgaread(Chan *c, void *buf, long n, ulong offset) switch(c->qid.path&~CHDIR){ case Qdir: return devdirread(c, buf, n, vgadir, Nvga, devgen); - case Qvgasize: - sprint(cbuf, "%dx%dx%d", gscreen.r.max.x, gscreen.r.max.y, - 1<name); + port += sprint(cbuf+port, "size: %dx%dx%d\n", + gscreen.r.max.x, gscreen.r.max.y, 1<name); + else + sprint(cbuf+port, "off\n"); return readstr(offset, buf, n, cbuf); - case Qvgatype: - return readstr(offset, buf, n, vgacard->name); - case Qvgaport: - for (cp = buf, port=offset; portdisable)(); + 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); +} + long vgawrite(Chan *c, void *buf, long n, ulong offset) { - char cbuf[64], *cp; - Vgacard *vp; - int port, maxx, maxy, ldepth; + int port; + uchar *cp; + char cbuf[64]; ushort *sp; ulong *lp; switch(c->qid.path&~CHDIR){ case Qdir: error(Eperm); - case Qvgatype: - if(offset != 0 || n >= sizeof(cbuf) || n < 1) - error(Ebadarg); - memmove(cbuf, buf, n); - cbuf[n] = 0; - if(cp = strchr(cbuf, '\n')) - *cp = 0; - for(vp = vgachips; vp->name; vp++) - if(strcmp(cbuf, vp->name) == 0){ - vgacard = vp; - return n; - } - error(Ebadarg); case Qvgactl: if(offset != 0 || n >= sizeof(cbuf)) error(Ebadarg); memmove(cbuf, buf, n); cbuf[n] = 0; - if(strncmp(cbuf, "hwcursor", 8) == 0) - hwcursor = 1; - break; - case Qvgasize: - if(offset != 0 || n >= sizeof(cbuf)) - error(Ebadarg); - memmove(cbuf, buf, n); - cbuf[n] = 0; - cp = cbuf; - maxx = strtoul(cp, &cp, 0); - if(*cp!=0) - cp++; - maxy = strtoul(cp, &cp, 0); - if(*cp!=0) - cp++; - switch(strtoul(cp, &cp, 0)){ - case 1: - ldepth = 0; - break; - case 2: - ldepth = 1; - break; - case 4: - ldepth = 2; - break; - case 8: - ldepth = 3; - break; - default: - ldepth = -1; - } - if(maxx == 0 || maxy == 0 - || maxx > 1600 || maxy > 1280 - || ldepth > 3 || ldepth < 0) - error(Ebadarg); - cursoroff(1); - setscreen(maxx, maxy, ldepth); - cursoron(1); + vgactl(cbuf); return n; - case Qvgaport: - for (cp = buf, port=offset; portbase; + 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); } /* @@ -447,7 +492,7 @@ crout(int reg, int val) typedef struct VGAmode VGAmode; struct VGAmode { - uchar general[2]; + uchar misc; uchar sequencer[5]; uchar crt[0x19]; uchar graphics[9]; @@ -460,7 +505,7 @@ struct VGAmode VGAmode mode12 = { /* general */ - 0xe7, 0x00, + 0xe7, /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x06, /* crt */ @@ -483,7 +528,7 @@ VGAmode mode12 = VGAmode mode13 = { /* general */ - 0x63, 0x00, + 0x63, /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x0e, /* crt */ @@ -501,34 +546,47 @@ VGAmode mode13 = }; static void -setmode(VGAmode *v) +setmode(VGAmode *vga) { int i; - /* turn screen off (to avoid damage) */ - srout(1, 0x21); + /* + * 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); + + vgaxo(Seqx, 0x00, 0x00); - for(i = 0; i < sizeof(v->general); i++) - genout(i, v->general[i]); + vgao(MiscW, vga->misc); - for(i = 0; i < sizeof(v->sequencer); i++) + for(i = 1; i < NSeqx; i++){ if(i == 1) - srout(i, v->sequencer[i]|0x20); /* avoid enabling screen */ - else - srout(i, v->sequencer[i]); + continue; + vgaxo(Seqx, i, vga->sequencer[i]); + } + vgaxo(Seqx, 0x00, 0x03); - crout(Cvre, 0); /* allow writes to CRT registers 0-7 */ - for(i = 0; i < sizeof(v->crt); i++) - crout(i, v->crt[i]); + vgaxo(Crtx, 0x11, vga->crt[0x11] & ~0x80); + for(i = 0; i < NCrtx; i++) + vgaxo(Crtx, i, vga->crt[i]); - for(i = 0; i < sizeof(v->graphics); i++) - grout(i, v->graphics[i]); + for(i = 0; i < NGrax; i++) + vgaxo(Grx, i, vga->graphics[i]); - for(i = 0; i < sizeof(v->attribute); i++) - arout(i, v->attribute[i]); + for(i = 0; i < NAttrx; i++) + vgaxo(Attrx, i, vga->attribute[i]); - /* turn screen on */ - srout(1, v->sequencer[1]); + vgaxo(Seqx, 0x01, vga->sequencer[1]); } /* @@ -709,7 +767,7 @@ screenload(Rectangle r, uchar *data, int tl, int l, int dolock) if(!rectclip(&r, gscreen.r) || tl<=0) return; - if(dolock && hwcursor == 0) + if(dolock && hwgc == 0) cursorlock(r); lock(&loadlock); @@ -792,7 +850,7 @@ screenload(Rectangle r, uchar *data, int tl, int l, int dolock) } unlock(&loadlock); - if(dolock && hwcursor == 0) + if(dolock && hwgc == 0) cursorunlock(); } @@ -865,7 +923,7 @@ screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) if(!rectclip(&r, gscreen.r) || tl<=0) return; - if(dolock && hwcursor == 0) + if(dolock && hwgc == 0) cursorlock(r); lock(&loadlock); @@ -948,7 +1006,7 @@ screenunload(Rectangle r, uchar *data, int tl, int l, int dolock) } unlock(&loadlock); - if(dolock && hwcursor == 0) + if(dolock && hwgc == 0) cursorunlock(); } @@ -1048,7 +1106,10 @@ atipage(int page) static void tridentpage(int page) { - srout(0xe, (srin(0xe)&0xf0) | page^0x2); + uchar seq0E; + + seq0E = vgaxi(Seqx, 0x0E) & 0xF0; + vgaxo(Seqx, 0x0E, seq0E|(page^0x02)); } static void tsengpage(int page) @@ -1058,12 +1119,7 @@ tsengpage(int page) static void cirruspage(int page) { - grout(0x9, page<<4); -} -static void -parapage(int page) -{ - grout(0x9, page<<4); + vgaxo(Grx, 0x09, page<<4); } static void s3page(int page) @@ -1077,28 +1133,18 @@ s3page(int page) /* * The S3 registers need to be unlocked for this. * Let's hope they are already: - * crout(0x38, 0x48); - * crout(0x39, 0xA0); + * vgaxo(Crtx, 0x38, 0x48); + * vgaxo(Crtx, 0x39, 0xA0); * * The page is 6 bits, the lower 4 bits in Crt35<3:0>, * the upper 2 in Crt51<3:2>. */ - crout(0x35, page & 0x0F); - outb(CRX, 0x51); - crt51 = (0xF3 & inb(CR))|((page & 0x30)>>2); - outb(CR, crt51); + vgaxo(Crtx, 0x35, page & 0x0F); + crt51 = vgaxi(Crtx, 0x51) & 0xF3; + vgaxo(Crtx, 0x51, crt51|((page & 0x30)>>2)); } else - crout(0x35, (page<<2) & 0x0C); -} - -/* - * hardware cursor routines - */ -static void -nomvcursor(Point p) -{ - USED(p.x); + vgaxo(Crtx, 0x35, (page<<2) & 0x0C); } /* @@ -1245,11 +1291,11 @@ getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) } p &= x; p ^= x; - lock(&screenlock); + lock(&pallettelock); *pr = colormap[p][0]; *pg = colormap[p][1]; *pb = colormap[p][2]; - unlock(&screenlock); + unlock(&pallettelock); } int @@ -1267,20 +1313,21 @@ setcolor(ulong p, ulong r, ulong g, ulong b) } p &= x; p ^= x; - lock(&screenlock); + lock(&pallettelock); colormap[p][0] = r; colormap[p][1] = g; colormap[p][2] = b; - outb(CMWX, p); - outb(CM, r>>(32-6)); - outb(CM, g>>(32-6)); - outb(CM, b>>(32-6)); - unlock(&screenlock); + vgao(DACWx, p); + vgao(DACData, r>>(32-6)); + vgao(DACData, g>>(32-6)); + vgao(DACData, b>>(32-6)); + unlock(&pallettelock); return ~0; } /* * software cursor + * and hacks for hardware cursor */ /* @@ -1340,7 +1387,9 @@ setcursor(Cursor *curs) uchar *p; int i; - for(i=0; i<16; i++){ + if(hwgc) + (*hwgc->load)(curs); + else for(i=0; i<16; i++){ p = (uchar*)&set.base[i]; *p = curs->set[2*i]; *(p+1) = curs->set[2*i+1]; @@ -1350,10 +1399,10 @@ setcursor(Cursor *curs) } } -void +int cursoron(int dolock) { - int xoff, yoff; + int xoff, yoff, s, ret; Rectangle r; uchar *a; struct { @@ -1365,12 +1414,16 @@ cursoron(int dolock) } xx; if(cursor.disable) - return; - if(dolock) + return 0; + if(dolock){ + s = 0; /* to avoid compiler warning */ lock(&cursor); + } else + s = spllo(); /* to avoid freezing out the eia ports */ - if(hwcursor) - (*vgacard->mvcursor)(mousexy()); + ret = 0; + if(hwgc) + ret = (*hwgc->move)(mousexy()); else if(cursor.visible++ == 0){ cursor.r.min = mousexy(); cursor.r.max = add(cursor.r.min, Pt(16, 16)); @@ -1419,12 +1472,16 @@ cursoron(int dolock) if(dolock) unlock(&cursor); + else + splx(s); + + return ret; } void cursoroff(int dolock) { - if(hwcursor) + if(hwgc) return; if(cursor.disable) return; diff --git a/pc/screen.h b/pc/screen.h index 976cdc322bda2876af7449499ff52b5b4868a65a..ac28818ff1b263dad2b2a75ce37568c1b0e1a93e 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -14,7 +14,7 @@ struct Cursorinfo }; Cursorinfo cursor; -extern void cursoron(int); +extern int cursoron(int); extern void cursoroff(int); extern Point mousexy(void); extern void cursorinit(void); diff --git a/pc/vga.h b/pc/vga.h index d58bfa35110b9950ae7fa392e3aef808c784e519..748c0f31894ae4d2e4f8f1078cb861e8dca9f18d 100644 --- a/pc/vga.h +++ b/pc/vga.h @@ -1,29 +1,49 @@ -enum -{ - EMISCR= 0x3CC, /* control sync polarity */ - EMISCW= 0x3C2, - EFCW= 0x3DA, /* feature control */ - EFCR= 0x3CA, - GRX= 0x3CE, /* index to graphics registers */ - GR= 0x3CF, /* graphics registers */ - Grms= 0x04, /* read map select register */ - SRX= 0x3C4, /* index to sequence registers */ - SR= 0x3C5, /* sequence registers */ - Smmask= 0x02, /* map mask */ - CRX= 0x3D4, /* index to crt registers */ - CR= 0x3D5, /* crt registers */ - Cvre= 0x11, /* vertical retrace end */ - ARW= 0x3C0, /* attribute registers (writing) */ - ARR= 0x3C1, /* attribute registers (reading) */ - CMRX= 0x3C7, /* color map read index */ - CMWX= 0x3C8, /* color map write index */ - CM= 0x3C9, /* color map data reg */ +/* + * Generic VGA registers. + */ +enum { + MiscW = 0x03C2, /* Miscellaneous Output (W) */ + MiscR = 0x03CC, /* Miscellaneous Output (R) */ + Status0 = 0x03C2, /* Input status 0 (R) */ + Status1 = 0x03DA, /* Input Status 1 (R) */ + FeatureR = 0x03CA, /* Feature Control (R) */ + FeatureW = 0x03DA, /* Feature Control (W) */ + + Seqx = 0x03C4, /* Sequencer Index, Data at Seqx+1 */ + NSeqx = 0x05, + + Crtx = 0x03D4, /* CRT Controller Index, Data at Crtx+1 */ + NCrtx = 0x19, + + Grx = 0x03CE, /* Graphics Controller Index, Data at Grx+1 */ + NGrax = 0x09, + + Attrx = 0x03C0, /* Attribute Controller Index and Data */ + NAttrx = 0x15, + + DACMask = 0x03C6, /* DAC Mask */ + DACRx = 0x03C7, /* DAC Read Index (W) */ + DACSts = 0x03C7, /* DAC Status (R) */ + DACWx = 0x03C8, /* DAC Write Index */ + DACData = 0x03C9, /* DAC Data */ + NDACx = 0x100, }; -#define SCREENMEM (0xA0000 | KZERO) -#define CGASCREEN ((uchar*)(0xB8000 | KZERO)) -#define CGAWIDTH 160 -#define CGAHEIGHT 24 +#define vgai(port) inb(port) +#define vgao(port, data) outb(port, data) + +extern int vgaxi(long, uchar); +extern int vgaxo(long, uchar, uchar); + +/* + * Definitions of known hardware graphics cursors. + */ +typedef struct Hwgc { + char *name; + void (*enable)(void); + void (*load)(Cursor*); + int (*move)(Point); + void (*disable)(void); +} Hwgc; -extern void setscreen(int, int, int); -extern struct GBitmap gscreen; +extern Lock pallettelock; diff --git a/pc/vgabt485.c b/pc/vgabt485.c new file mode 100644 index 0000000000000000000000000000000000000000..56499e87a4aeadd9fbb26cde0ab0486a5ad50405 --- /dev/null +++ b/pc/vgabt485.c @@ -0,0 +1,259 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include +#include "screen.h" +#include "vga.h" + +/* + * Hardware graphics cursor support for + * Brooktree Bt485 Monolithic True-Color RAMDAC. + * Assumes hooked up to an S3 86C928. + * + * BUGS: + * 64x64x2 cursor always used; + * no support for interlaced mode. + */ +enum { + AddrW = 0x00, /* Address register; palette/cursor RAM write */ + Palette = 0x01, /* 6/8-bit color palette data */ + Pmask = 0x02, /* Pixel mask register */ + AddrR = 0x03, /* Address register; palette/cursor RAM read */ + ColorW = 0x04, /* Address register; cursor/overscan color write */ + Color = 0x05, /* Cursor/overscan color data */ + Cmd0 = 0x06, /* Command register 0 */ + ColorR = 0x07, /* Address register; cursor/overscan color read */ + Cmd1 = 0x08, /* Command register 1 */ + Cmd2 = 0x09, /* Command register 2 */ + Status = 0x0A, /* Status */ + Cmd3 = 0x1A, /* Command register 3 */ + Cram = 0x0B, /* Cursor RAM array data */ + Cxlr = 0x0C, /* Cursor x-low register */ + Cxhr = 0x0D, /* Cursor x-high register */ + Cylr = 0x0E, /* Cursor y-low register */ + Cyhr = 0x0F, /* Cursor y-high register */ + + Nreg = 0x10, +}; + +/* + * Lower 2-bits of indirect DAC register + * addressing. + */ +static ushort dacxreg[4] = { + DACWx, DACData, DACMask, DACSts +}; + +static uchar +bt485io(uchar reg) +{ + uchar crt55, cr0; + + crt55 = vgaxi(Crtx, 0x55) & 0xFC; + if((reg & 0x0F) == Status){ + /* + * 1,2: Set indirect addressing for Status or + * Cmd3 - set bit7 of Cr0. + */ + vgaxo(Crtx, 0x55, crt55|((Cmd0>>2) & 0x03)); + cr0 = vgai(dacxreg[Cmd0 & 0x03])|0x80; + vgao(dacxreg[Cmd0 & 0x03], cr0); + + /* + * 3,4: Set the index into the Write register, + * index == 0x00 for Status, 0x01 for Cmd3. + */ + vgaxo(Crtx, 0x55, crt55|((AddrW>>2) & 0x03)); + vgao(dacxreg[AddrW & 0x03], (reg == Status) ? 0x00: 0x01); + + /* + * 5,6: Get the contents of the appropriate + * register at 0x0A. + */ + } + + return crt55; +} + +static uchar +bt485i(uchar reg) +{ + uchar crt55, r; + + crt55 = bt485io(reg); + vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); + r = vgai(dacxreg[reg & 0x03]); + vgaxo(Crtx, 0x55, crt55); + + return r; +} + +static void +bt485o(uchar reg, uchar data) +{ + uchar crt55; + + crt55 = bt485io(reg); + vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); + vgao(dacxreg[reg & 0x03], data); + vgaxo(Crtx, 0x55, crt55); +} + +static Point hotpoint; + +static void +load(Cursor *c) +{ + uchar r; + int x, y; + + + lock(&pallettelock); + + /* + * Turn cursor off; + * put cursor into 64x64x2 mode and clear MSBs of address; + * clear LSBs of address; + */ + r = bt485i(Cmd2) & 0xFC; + bt485o(Cmd2, r); + + r = (bt485i(Cmd3) & 0xFC)|0x04; + bt485o(Cmd3, r); + + bt485o(AddrW, 0x00); + + /* + * Now load the cursor RAM array, both planes. + * The cursor is 16x16, the array 64x64; put + * the cursor in the top left. The 0,0 cursor + * point is bottom-right, so positioning will + * have to take that into account. + */ + for(y = 0; y < 64; y++){ + for(x = 0; x < 64/8; x++){ + if(x < 16/8 && y < 16) + bt485o(Cram, c->clr[x+y*2]); + else + bt485o(Cram, 0x00); + } + } + for(y = 0; y < 64; y++){ + for(x = 0; x < 64/8; x++){ + if(x < 16/8 && y < 16) + bt485o(Cram, c->set[x+y*2]); + else + bt485o(Cram, 0x00); + } + } + + /* + * Initialise the cursor hot-point + * and enable the cursor. + */ + hotpoint.x = 64+c->offset.x; + hotpoint.y = 64+c->offset.y; + + r = (bt485i(Cmd2) & 0xFC)|0x01; + bt485o(Cmd2, r); + + unlock(&pallettelock); +} + +static void +enable(void) +{ + uchar r; + + lock(&pallettelock); + + /* + * Turn cursor off. + */ + r = bt485i(Cmd2) & 0xFC; + bt485o(Cmd2, r); + + /* + * Overscan colour, + * cursor colour 1 (white), + * cursor colour 2, 3 (black). + */ + bt485o(ColorW, 0x00); + bt485o(Color, 0xFF); bt485o(Color, 0xFF); bt485o(Color, 0xFF); + + bt485o(Color, 0xFF); bt485o(Color, 0xFF); bt485o(Color, 0xFF); + + bt485o(Color, 0x00); bt485o(Color, 0x00); bt485o(Color, 0x00); + bt485o(Color, 0x00); bt485o(Color, 0x00); bt485o(Color, 0x00); + + unlock(&pallettelock); + + /* + * Finally, enable + * the hardware cursor external operation mode; + * cursor control enable for Bt485 DAC. + * The #9GXE cards seem to need the 86C928 Bt485 support + * enabled in order to work at all in enhanced mode. + */ + + r = vgaxi(Crtx, 0x55)|0x20; + vgaxo(Crtx, 0x55, r); + + r = vgaxi(Crtx, 0x45)|0x20; + vgaxo(Crtx, 0x45, r); +} + +static int +move(Point p) +{ + int x, y; + + if(canlock(&pallettelock) == 0) + return 1; + + x = p.x+hotpoint.x; + y = p.y+hotpoint.y; + + bt485o(Cxlr, x & 0xFF); + bt485o(Cxhr, (x>>8) & 0x0F); + bt485o(Cylr, y & 0xFF); + bt485o(Cyhr, (y>>8) & 0x0F); + + unlock(&pallettelock); + return 0; +} + +static void +disable(void) +{ + uchar r; + + /* + * Disable + * cursor mode 3; + * cursor control enable for Bt485 DAC; + * the hardware cursor external operation mode. + */ + lock(&pallettelock); + r = bt485i(Cmd2) & ~0x03; + bt485o(Cmd2, r); + unlock(&pallettelock); + + r = vgaxi(Crtx, 0x45) & ~0x20; + vgaxo(Crtx, 0x45, r); + + r = vgaxi(Crtx, 0x55) & ~0x20; + vgaxo(Crtx, 0x55, r); +} + +Hwgc bt485hwgc = { + "bt485hwgc", + enable, + load, + move, + disable, +}; diff --git a/pc/vgatvp3020.c b/pc/vgatvp3020.c new file mode 100644 index 0000000000000000000000000000000000000000..af52a4ebd3a62ddb1c913da3a5964bc7b86d77c9 --- /dev/null +++ b/pc/vgatvp3020.c @@ -0,0 +1,232 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "../port/error.h" + +#include +#include "screen.h" +#include "vga.h" + +/* + * TVP3020 Viewpoint Video Interface Pallette. + * Assumes hooked up to an S3 86C928. + */ +enum { + AddrW = 0x00, /* Palette address register - write mode */ + Palette = 0x01, /* Color palette holding register */ + Pmask = 0x02, /* Pixel read mask */ + AddrR = 0x03, /* Palette address register - read mode */ + + Index = 0x06, /* Index register */ + Data = 0x07, /* Data register */ +}; + +/* + * Lower 2-bits of indirect DAC register + * addressing. + */ +static ushort dacxreg[4] = { + DACWx, DACData, DACMask, DACSts +}; + +static uchar +tvp3020io(uchar reg, uchar data) +{ + uchar crt55; + + crt55 = vgaxi(Crtx, 0x55) & 0xFC; + vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03)); + vgao(dacxreg[reg & 0x03], data); + + return crt55; +} + +static void +tvp3020xo(uchar index, uchar data) +{ + uchar crt55; + + crt55 = tvp3020io(Index, index); + vgao(dacxreg[Data & 0x03], data); + vgaxo(Crtx, 0x55, crt55); +} + +static void +load(Cursor *c) +{ + uchar p, p0, p1; + int x, y; + + lock(&pallettelock); + + /* + * Make sure cursor is off by initialising the cursor + * control to defaults + X-Windows cursor mode. + */ + tvp3020xo(0x06, 0x10); /* Cursor Control Register */ + + /* + * Initialise the cursor RAM LS and MS address + * (LS must be first). + */ + tvp3020xo(0x08, 0x00); /* Cursor RAM LS Address */ + tvp3020xo(0x09, 0x00); /* Cursor RAM MS Address */ + + /* + * Initialise the 64x64 cursor RAM array. There are 2 planes, + * p0 and p1. Data is written 4 pixels per byte, with p1 the + * MS bit of each pixel. + * The cursor is set in X-Windows mode which gives the following + * truth table: + * p1 p0 colour + * 0 0 underlying pixel colour + * 0 1 underlying pixel colour + * 1 0 cursor colour 1 + * 1 1 cursor colour 2 + * Put the cursor into the top-left of the 64x64 array. + */ + for(y = 0; y < 64; y++){ + for(x = 0; x < 64/8; x++){ + if(x < 16/8 && y < 16){ + p0 = c->clr[x+y*2]; + p1 = c->set[x+y*2]; + + p = 0x00; + if(p1 & 0x10) + p |= 0x03; + else if(p0 & 0x10) + p |= 0x02; + if(p1 & 0x20) + p |= 0x0C; + else if(p0 & 0x20) + p |= 0x08; + if(p1 & 0x40) + p |= 0x30; + else if(p0 & 0x40) + p |= 0x20; + if(p1 & 0x80) + p |= 0xC0; + else if(p0 & 0x80) + p |= 0x80; + tvp3020xo(0x0A, p); /* Cursor RAM Data */ + + p = 0x00; + if(p1 & 0x01) + p |= 0x03; + else if(p0 & 0x01) + p |= 0x02; + if(p1 & 0x02) + p |= 0x0C; + else if(p0 & 0x02) + p |= 0x08; + if(p1 & 0x04) + p |= 0x30; + else if(p0 & 0x04) + p |= 0x20; + if(p1 & 0x08) + p |= 0xC0; + else if(p0 & 0x08) + p |= 0x80; + tvp3020xo(0x0A, p); /* Cursor RAM Data */ + } + else{ + tvp3020xo(0x0A, 0x00); /* Cursor RAM Data */ + tvp3020xo(0x0A, 0x00); + } + } + } + + /* + * Initialise the cursor hot-point + * and enable the cursor. + */ + tvp3020xo(0x04, -c->offset.x); /* Sprite Origin X */ + tvp3020xo(0x05, -c->offset.y); /* Sprite Origin Y */ + + tvp3020xo(0x06, 0x40|0x10); /* Cursor Control Register */ + + unlock(&pallettelock); +} + +static void +enable(void) +{ + uchar r; + + lock(&pallettelock); + + /* + * Make sure cursor is off by initialising the cursor + * control to defaults + X-Windows cursor mode. + */ + tvp3020xo(0x06, 0x10); /* Cursor Control Register */ + + /* + * Overscan colour, + * cursor colour 1 (white), + * cursor colour 2 (black). + */ + tvp3020xo(0x20, 0xFF); tvp3020xo(0x21, 0xFF); tvp3020xo(0x22, 0xFF); + tvp3020xo(0x23, 0xFF); tvp3020xo(0x24, 0xFF); tvp3020xo(0x25, 0xFF); + tvp3020xo(0x26, 0x00); tvp3020xo(0x27, 0x00); tvp3020xo(0x28, 0x00); + + unlock(&pallettelock); + + /* + * Finally, enable + * the hardware cursor external operation mode; + * cursor control enable for Bt485 DAC (!). + */ + r = vgaxi(Crtx, 0x55)|0x20; + vgaxo(Crtx, 0x55, r); + + r = vgaxi(Crtx, 0x45)|0x20; + vgaxo(Crtx, 0x45, r); +} + +static int +move(Point p) +{ + if(canlock(&pallettelock) == 0) + return 1; + + tvp3020xo(0x00, p.x & 0xFF); /* Cursor Position X LSB */ + tvp3020xo(0x01, (p.x>>8) & 0x0F); /* Cursor Position X MSB */ + tvp3020xo(0x02, p.y & 0xFF); /* Cursor Position Y LSB */ + tvp3020xo(0x03, (p.y>>8) & 0x0F); /* Cursor Position Y MSB */ + + unlock(&pallettelock); + return 0; +} + +static void +disable(void) +{ + uchar r; + + /* + * Disable + * cursor; + * cursor control enable for Bt485 DAC (!); + * the hardware cursor external operation mode. + */ + lock(&pallettelock); + tvp3020xo(0x06, 0x10); /* Cursor Control Register */ + unlock(&pallettelock); + + r = vgaxi(Crtx, 0x45) & ~0x20; + vgaxo(Crtx, 0x45, r); + + r = vgaxi(Crtx, 0x55) & ~0x20; + vgaxo(Crtx, 0x55, r); +} + +Hwgc tvp3020hwgc = { + "tvp3020hwgc", + enable, + load, + move, + disable, +}; diff --git a/port/alarm.c b/port/alarm.c index 2cd83286340de40b4fde4070b73f4935334ddeec..98b752087afdf823e4dd4f06c1aee3ba0bfdc157 100644 --- a/port/alarm.c +++ b/port/alarm.c @@ -3,7 +3,6 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#include "io.h" Alarms alarms; Rendez alarmr; diff --git a/port/auth.c b/port/auth.c index 9ccc1d85fd7a8f40a6ab412d929c06a728fe938a..37c558295058cbfea408e4c818dc68ee0ceffa04 100644 --- a/port/auth.c +++ b/port/auth.c @@ -3,7 +3,6 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#include "io.h" #include "../port/error.h" typedef struct Crypt Crypt; diff --git a/port/devcons.c b/port/devcons.c index 32b0ad2562e0eaff4b1f439464f5b23ce09f4d9b..070cdf90ca591ea1fdb4c2d9327f82cc273e40b5 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -3,7 +3,6 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#include "io.h" #include "../port/error.h" #include "devtab.h" diff --git a/port/devlance.c b/port/devlance.c index 402f18cb5ea6d380a7f689e1f5b1883bc06f9761..7e23b27fc35b999de60e099b10ee986d845550a0 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -3,7 +3,6 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#include "io.h" #include "../port/error.h" #include "../port/netif.h" diff --git a/port/devmouse.c b/port/devmouse.c index d1fa22d50484d7cd6321a7b48f2819ba7053094d..300601a96f613e82a725c929d963c16cc7391160 100644 --- a/port/devmouse.c +++ b/port/devmouse.c @@ -321,7 +321,7 @@ mouseclock(void) if(mouse.redraw && canlock(&cursor)){ mouse.redraw = 0; cursoroff(0); - cursoron(0); + mouse.redraw = cursoron(0); unlock(&cursor); } } diff --git a/port/netif.c b/port/netif.c index f4841abcdc2be11a47c5d6c9d80807a07f045fbc..45744dd2f824ddc32298231633aca19d6111806f 100644 --- a/port/netif.c +++ b/port/netif.c @@ -3,7 +3,6 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#include "io.h" #include "../port/error.h" #include "../port/netif.h"