From f15aa24b2d38101e5c7f8837250ceaf388acc82f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 13 Oct 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-10-13 --- pc/archgeneric.c | 2 +- pc/devfloppy.c | 113 +++++++++++++++++++++++------------------------ pc/devincon.c | 41 ++++++++++++++--- pc/dma.c | 3 +- pc/kbd.c | 12 ++++- pc/mem.h | 1 - pc/screen.h | 3 ++ pc/vga.c | 10 ++--- port/devbit.c | 81 +++++++++++++++++++++++++++++++-- 9 files changed, 188 insertions(+), 78 deletions(-) diff --git a/pc/archgeneric.c b/pc/archgeneric.c index 1c74267eb719ba151b90d411c0380f275b803ac4..e826527af6ace1203c15169195b79dc948c74571 100644 --- a/pc/archgeneric.c +++ b/pc/archgeneric.c @@ -15,7 +15,7 @@ genericreset(void) PCArch generic = { "generic", - genericreset, + i8042reset, 0, 0, 0, diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 90491154ed4b4af61ee49aa5a7a3d33b28da18cf..e157bcb17cd368d4670c28b5badf6235127d20a9 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -196,7 +196,6 @@ static int floppysense(void); static void floppywait(void); static long floppyxfer(Drive*, int, void*, long, long); static void floppyformat(Drive*, char*); -static long floppythrice(Drive*, int, void*, long, long); static int cmddone(void*); void Xdelay(int); @@ -372,32 +371,52 @@ islegal(ulong offset, long n, Drive *dp) } /* - * check if the floppy has been replaced under foot. cause a read error if it has. + * check if the floppy has been replaced under foot. cause + * an error if it has. * - * a seek and a read clears the condition. this was determined experimentally, - * there has to be a better way. + * a seek and a read clears the condition. this was determined + * experimentally, there has to be a better way. + * + * if the read fails, cycle through the possible floppy + * density till one works or we've cycled through all + * possibilities. */ static void changed(Chan *c, Drive *dp) { ulong old; + Type *start; - if(inb(Pdir)&Fchange){ - setdef(dp); + /* + * if floppy has changed or first time through + */ + if((inb(Pdir)&Fchange) || dp->vers == 0){ dp->vers++; - dp->confused = 1; + setdef(dp); + start = dp->t; + dp->confused = 1; /* make floppyon recal */ floppyon(dp); - if(dp->cyl) - floppythrice(dp, Fread, dp->cache, 0, dp->t->tsize); - else - floppythrice(dp, Fread, dp->cache, dp->t->heads*dp->t->tsize, - dp->t->tsize); + floppyseek(dp, dp->t->heads*dp->t->tsize); + while(waserror()){ + while(++dp->t){ + if(dp->t == &floppytype[NTYPES]) + dp->t = floppytype; + if(dp->dt == dp->t->dt) + break; + } + floppydir[NFDIR*dp->dev].length = dp->t->cap; + if(dp->t == start) + nexterror(); + floppyon(dp); + } + floppyxfer(dp, Fread, dp->cache, 0, dp->t->tsize); + poperror(); } + old = c->qid.vers; c->qid.vers = dp->vers; - if(old && old!=dp->vers){ + if(old && old != dp->vers) error(Eio); - } } long @@ -443,7 +462,7 @@ floppyread(Chan *c, void *a, long n, ulong offset) */ if(dp->ccyl!=cyl || dp->chead!=head){ dp->ccyl = -1; - i = floppythrice(dp, Fread, dp->cache, + i = floppyxfer(dp, Fread, dp->cache, (cyl*dp->t->heads+head)*nn, nn); if(i != nn){ if(i == 0) @@ -494,7 +513,7 @@ floppywrite(Chan *c, void *a, long n, ulong offset) floppypos(dp, offset+rv); if(dp->tcyl == dp->ccyl) dp->ccyl = -1; - i = floppythrice(dp, Fwrite, aa+rv, offset+rv, n-rv); + i = floppyxfer(dp, Fwrite, aa+rv, offset+rv, n-rv); if(i < 0) break; if(i == 0) @@ -753,6 +772,7 @@ floppyrecal(Drive *dp) dp->cyl = fl.stat[1]; if(dp->cyl != 0){ DPRINT("recalibrate went to wrong cylinder %d\n", dp->cyl); + dp->cyl = -1; dp->confused = 1; return -1; } @@ -829,59 +849,24 @@ floppyseek(Drive *dp, long off) } /* - * since floppies are so flakey, automaticly retry failed attempts. - * every 3 tries switch to a different density + * read or write to floppy. try up to three times. */ -static long -floppythrice(Drive *dp, int cmd, void *a, long off, long n) -{ - int tries; - long rv; - Type *start; - - start = dp->t; - for(tries = 0; ; tries++){ - if(waserror()){ - if(cmd != Fread || strcmp(u->error, Eintr)==0) - nexterror(); - - /* walk through the compatible types */ - if(tries == 3){ - while(++dp->t){ - if(dp->t == &floppytype[NTYPES]) - dp->t = floppytype; - if(dp->dt == Tnone) - break; - if(dp->dt == dp->t->dt) - break; - } - floppydir[NFDIR*dp->dev].length = dp->t->cap; - if(dp->t == start) - nexterror(); - tries = 0; - floppyon(dp); - } - } else { - rv = floppyxfer(dp, cmd, a, off, n); - poperror(); - return rv; - } - } -} - static long floppyxfer(Drive *dp, int cmd, void *a, long off, long n) { long offset; + int tries = 0; if(off >= dp->t->cap) return 0; if(off + n > dp->t->cap) n = dp->t->cap - off; - /* - * calculate new position and seek to it (dp->len may be trimmed) - */ + /* retry on error 3 times */ + while(waserror()) + if(tries++ >= 3) + nexterror(); + dp->len = n; if(floppyseek(dp, off) < 0) error(Eio); @@ -892,6 +877,10 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) /* * set up the dma (dp->len may be trimmed) */ + if(waserror()){ + dmaend(DMAchan); + nexterror(); + } dp->len = dmasetup(DMAchan, a, dp->len, cmd==Fread); /* @@ -919,6 +908,7 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) */ floppywait(); dmaend(DMAchan); + poperror(); /* * check for errors @@ -947,6 +937,7 @@ floppyxfer(Drive *dp, int cmd, void *a, long off, long n) dp->confused = 1; error(Eio); } + poperror(); dp->lasttouched = m->ticks; return dp->len; @@ -1016,6 +1007,10 @@ floppyformat(Drive *dp, char *params) *bp++ = sec; *bp++ = t->bcode; } + if(waserror()){ + dmaend(DMAchan); + nexterror(); + } dmasetup(DMAchan, buf, bp-buf, 0); /* @@ -1038,6 +1033,7 @@ floppyformat(Drive *dp, char *params) */ floppywait(); dmaend(DMAchan); + poperror(); /* * check for errors @@ -1055,6 +1051,7 @@ floppyformat(Drive *dp, char *params) } } free(buf); + dp->confused = 1; poperror(); } diff --git a/pc/devincon.c b/pc/devincon.c index ebf37801aaac7a1ee013e96af27b97fd088564f3..e0df87608e629a81a9e86b29a66fea66823bf584 100644 --- a/pc/devincon.c +++ b/pc/devincon.c @@ -60,7 +60,7 @@ typedef struct Incon Incon; #define NOW (MACHP(0)->ticks*MS2HZ) -#define DPRINT if(incondebug)kprint +#define DPRINT /*if(incondebug)k*/print static void inconintr(Ureg *ur); @@ -174,11 +174,21 @@ Dirtab incondir[]={ }; #define NINCON (sizeof incondir/sizeof incondir[0]) +/*static void +Xdelay(int n) +{ + while(--n >= 0) ; +} +#define SDLY 1000 +*/ +#define Xdelay(n) + static void reset(int dev) /* hardware reset */ { outb(dev+Qpcr, Finitbar); outb(dev+Qpcr, 0); + Xdelay(10000); outb(dev+Qpcr, Finitbar); } @@ -188,6 +198,7 @@ wrctl(int dev, int data) /* write control character */ outb(dev+Qpcr, Finitbar); /* no interrupts, please */ outb(dev+Qdlr, data); outb(dev+Qpcr, Finitbar|Fstrobe); + Xdelay(SDLY); outb(dev+Qpcr, Finitbar|Fie); } @@ -197,6 +208,7 @@ wrdata(int dev, int data) /* write data character */ outb(dev+Qpcr, Finitbar|Fsi); outb(dev+Qdlr, data); outb(dev+Qpcr, Finitbar|Fsi|Fstrobe); + Xdelay(SDLY); outb(dev+Qpcr, Finitbar|Fsi|Fie); } @@ -206,6 +218,7 @@ wrcmd(int dev, int data) /* write command */ outb(dev+Qpcr, Finitbar|Faf); outb(dev+Qdlr, data); outb(dev+Qpcr, Finitbar|Faf|Fstrobe); + Xdelay(SDLY); outb(dev+Qpcr, Finitbar|Faf|Fie); } @@ -219,8 +232,10 @@ rdstatus(Incon *ip) /* read status */ outb(dev+Qpcr, Finitbar|Faf|Fsi); outb(dev+Qdlr, 0x01); outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); + Xdelay(SDLY); data = (inb(dev+Qpsr)&0xf8)<<2; outb(dev+Qpcr, Finitbar|Faf|Fsi); + Xdelay(SDLY); data |= inb(dev+Qpsr)>>3; if(data&(OVERFLOW|CRC_ERROR)){ if(data&OVERFLOW) @@ -230,6 +245,7 @@ rdstatus(Incon *ip) /* read status */ } outb(dev+Qdlr, 0x03); outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); + Xdelay(SDLY); outb(dev+Qpcr, Finitbar|Faf|Fsi|Fie); return data; @@ -240,6 +256,7 @@ iwrcmd(int dev, int data) /* write command at interrupt level */ { outb(dev+Qdlr, data); outb(dev+Qpcr, Finitbar|Faf|Fstrobe); + Xdelay(SDLY); outb(dev+Qpcr, Finitbar|Faf); } @@ -252,8 +269,10 @@ irdstatus(Incon *ip) /* read status at interrupt level */ outb(dev+Qdlr, 0x01); outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); + Xdelay(SDLY); data = (inb(dev+Qpsr)&0xf8)<<2; outb(dev+Qpcr, Finitbar|Faf|Fsi); + Xdelay(SDLY); data |= inb(dev+Qpsr)>>3; if(data&(OVERFLOW|CRC_ERROR)){ if(data&OVERFLOW) @@ -272,8 +291,10 @@ irddata(int dev) /* read data at interrupt level */ outb(dev+Qdlr, 0x00); outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); + Xdelay(SDLY); data = (inb(dev+Qpsr)&0xf8)<<2; outb(dev+Qpcr, Finitbar|Faf|Fsi); + Xdelay(SDLY); data |= inb(dev+Qpsr)>>3; return data; @@ -285,8 +306,10 @@ irdnext(int dev) /* read next data at interrupt level */ int data; outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); + Xdelay(SDLY); data = (inb(dev+Qpsr)&0xf8)<<2; outb(dev+Qpcr, Finitbar|Faf|Fsi); + Xdelay(SDLY); data |= inb(dev+Qpsr)>>3; return data; @@ -297,12 +320,13 @@ irdnop(int dev, int pcr) /* read nop (mux reset) */ { outb(dev+Qdlr, 0x03); outb(dev+Qpcr, Finitbar|Faf|Fsi|Fstrobe); + Xdelay(SDLY); outb(dev+Qpcr, pcr); } - +/* int Irdnext(int); #define irdnext Irdnext - +*/ /* * set the incon parameters */ @@ -415,6 +439,7 @@ inconpoll(Incon *ip, int station) break; } } +print("poll: status 0x%.2ux\n", rdstatus(ip)); } /* @@ -471,7 +496,7 @@ inconreset(void) */ /* inconset(&incon[0], 3, 15); /**/ for(i=0; i= Nincon) error(Ebadarg); @@ -785,10 +811,10 @@ inconoput(Queue *q, Block *bp) /* * spin till there is room */ - for(n=0, end = NOW+1000; rdstatus(ip) & TX_FULL; n++){ + for(n=0, end = NOW+1000; (ctl=rdstatus(ip)) & TX_FULL; n++){ nop(); /* make sure we don't optimize too much */ if(NOW > end){ - print("incon output stuck 0\n"); + print("incon output stuck 0 %.2ux\n", ctl); freemsg(q, bp); qunlock(&ip->xmit); return; @@ -1076,6 +1102,7 @@ inconintr(Ureg *ur) int pcr; Incon *ip; +print("I"); USED(ur); ip = &incon[0]; pcr = inb(ip->dev+Qpcr); diff --git a/pc/dma.c b/pc/dma.c index c58b07c8d31cea7f435b57b688e860ca6c1d540a..eab296752d4b011683ada39ec2ba448b798ebbff 100644 --- a/pc/dma.c +++ b/pc/dma.c @@ -105,7 +105,8 @@ dmasetup(int chan, void *va, long len, int isread) * allocate a page for the DMA. */ pa = ((ulong)va) & ~KZERO; - if(!isphys(va) || (pa&0xFFFF0000)!=((pa+len)&0xFFFF0000)){ + if((((ulong)va)&0xF0000000) != KZERO + || (pa&0xFFFF0000) != ((pa+len)&0xFFFF0000)){ if(xp->pg == 0) xp->pg = newpage(1, 0, 0); if(len > BY2PG) diff --git a/pc/kbd.c b/pc/kbd.c index b65e9f79e653a5c8d5809f8d183754964ddfa3bc..365223ecb1befb3ac1bd4aac2615428ea88a6906 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -183,7 +183,6 @@ mousecmd(int cmd) void i8042a20(void) { - outready(); outb(Cmd, 0xD1); outready(); outb(Data, 0xDF); @@ -196,10 +195,19 @@ i8042a20(void) void i8042reset(void) { + /* + * this works for dhog + */ + outready(); + outb(Cmd, 0xFE); /* pulse reset line */ + outready(); + /* + * this is the old IBM way + */ outready(); outb(Cmd, 0xD1); outready(); - outb(Data, 0xDE); + outb(Data, 0xDE); /* set reset line high */ outready(); } diff --git a/pc/mem.h b/pc/mem.h index a9e3a0dfefc4a10f49a9bb5edeb102c9c1c8d055..768fbe13d51532352540ecc1ceb6a51c8ca205eb 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -53,7 +53,6 @@ #define MACHSIZE 4096 -#define isphys(x) (((ulong)x)&KZERO) /* * known 80386 segments (in GDT) and their selectors diff --git a/pc/screen.h b/pc/screen.h index a3dd699a525856e050fc5a74688ba926b93df537..18eeecffdd0310be6a8293457df46d510a526680 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -29,3 +29,6 @@ extern Cursorinfo cursor; extern void mouseupdate(int); #define hwscreenwrite(a, b) + +#define screenupdate(z) +int islcd; diff --git a/pc/vga.c b/pc/vga.c index 00a51b2e74d3d223db1052c610faf3db45798f33..710ce2197a4c19fd85bd06d2a668dd0e1809fcdc 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -49,18 +49,18 @@ struct VGAmode }; /* - * 640x480 display, 16 bit color. + * 640x480 display, 16 bit color. */ VGAmode mode12 = { /* general */ - 0xe7, 0x00, + 0xe3, 0x00, /* sequence */ 0x03, 0x01, 0x0f, 0x00, 0x06, /* crt */ - 0x65, 0x4f, 0x50, 0x88, 0x55, 0x9a, 0x09, 0x3e, + 0x63, 0x4f, 0x58, 0x81, 0x59, 0x81, 0x0b, 0x3e, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe8, 0x8b, 0xdf, 0x28, 0x00, 0xe7, 0x04, 0xe3, + 0xea, 0x2c, 0xdf, 0x28, 0x00, 0xea, 0xeb, 0xe3, 0xff, /* graphics */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x0f, @@ -68,7 +68,7 @@ VGAmode mode12 = /* attribute */ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x3f, - 0x01, 0x10, 0x0f, 0x00, 0x00, + 0x01, 0x00, 0x0f, 0x00, 0x00, }; diff --git a/port/devbit.c b/port/devbit.c index 0a5d7f3de637467926496c6636d9336afa9ffbc6..e04dca4b83b553c364ade7b31d6d3283ade83292 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -103,6 +103,7 @@ void arenafree(Arena*); void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode); void bitloadchar(GFont*, int, GSubfont*, int); extern GBitmap gscreen; +extern islcd; Mouseinfo mouse; Cursorinfo cursor; @@ -746,6 +747,55 @@ bitread(Chan *c, void *va, long n, ulong offset) return n; } +static Rectangle mbb = {10000, 10000, -10000, -10000}; + +static void +mbbrect(Rectangle r) +{ + if (r.min.x < mbb.min.x) + mbb.min.x = r.min.x; + if (r.min.y < mbb.min.y) + mbb.min.y = r.min.y; + if (r.max.x > mbb.max.x) + mbb.max.x = r.max.x; + if (r.max.y > mbb.max.y) + mbb.max.y = r.max.y; +} + +static void +mbbpt(Point p) +{ + if (p.x < mbb.min.x) + mbb.min.x = p.x; + if (p.y < mbb.min.y) + mbb.min.y = p.y; + if (p.x >= mbb.max.x) + mbb.max.x = p.x+1; + if (p.y >= mbb.max.y) + mbb.max.y = p.y+1; +} + +Point +bitstrsize(GFont *f, uchar *p, int l) +{ + ushort r; + Point s = {0,0}; + GCacheinfo *c; + + while(l > 0){ + r = BGSHORT(p); + p += 2; + l -= 2; + if(r >= f->ncache) + continue; + c = &f->cache[r]; + if(c->bottom > s.y) + s.y = c->bottom; + s.x += c->width; + } + return s; +} + long bitwrite(Chan *c, void *va, long n, ulong offset) { @@ -754,6 +804,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset) ulong l, nw, ws, rv, q0, q1; ulong *lp; int off, isoff, i, j, ok; + ulong *endscreen = gaddr(&gscreen, Pt(0, gscreen.r.max.y)); Point pt, pt1, pt2; Rectangle rect; Cursor curs; @@ -763,6 +814,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset) BSubfont *f, *tf, **fp; GFont *ff, **ffp; GCacheinfo *gc; + extern void screenupdate(Rectangle); if(!conf.monitor) error(Egreg); @@ -856,6 +908,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset) isoff = 1; } gbitblt(dst, pt, src, rect, fc); + if(islcd && dst->base < endscreen) + mbbrect(Rpt(pt, add(pt, sub(rect.max, rect.min)))); m -= 31; p += 31; break; @@ -1089,6 +1143,10 @@ bitwrite(Chan *c, void *va, long n, ulong offset) isoff = 1; } gsegment(dst, pt1, pt2, t, fc); + if(islcd && dst->base < endscreen) { + mbbpt(pt1); + mbbpt(pt2); + } m -= 22; p += 22; break; @@ -1188,6 +1246,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset) isoff = 1; } gpoint(dst, pt1, t, fc); + if(islcd && dst->base < endscreen) + mbbpt(pt1); m -= 14; p += 14; break; @@ -1278,6 +1338,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset) isoff = 1; } bitstring(dst, pt, ff, p, l, fc); + if(islcd && dst->base < endscreen) + mbbrect(Rpt(pt, add(pt, bitstrsize(ff, p, l)))); m -= l; p += l; break; @@ -1315,6 +1377,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset) isoff = 1; } gtexture(dst, rect, src, fc); + if(islcd && dst->base < endscreen) + mbbrect(rect); m -= 23; p += 23; break; @@ -1393,6 +1457,8 @@ bitwrite(Chan *c, void *va, long n, ulong offset) t = (t/ws)*ws; l = (t+dst->r.max.x+ws-1)/ws; } + if(islcd && dst->base < endscreen) + mbbrect(Rect(dst->r.min.x, miny, dst->r.max.x, maxy)); p += 11; m -= 11; if(m < l*(maxy-miny)) @@ -1504,6 +1570,10 @@ bitwrite(Chan *c, void *va, long n, ulong offset) poperror(); if(isoff) cursoron(1); + if(islcd) { + screenupdate(mbb); + mbb = Rect(10000, 10000, -10000, -10000); + } qunlock(&bit); return n; } @@ -1851,10 +1921,12 @@ cursoron(int dolock) cursor.r.max = add(mouse.xy, Pt(16, 16)); cursor.r = raddp(cursor.r, cursor.offset); gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S); - gbitblt(&gscreen, add(mouse.xy, cursor.offset), + gbitblt(&gscreen, cursor.r.min, &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S); - gbitblt(&gscreen, add(mouse.xy, cursor.offset), + gbitblt(&gscreen, cursor.r.min, &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D); + if(islcd) + mbbrect(cursor.r); } if(dolock) unlock(&cursor); @@ -1865,8 +1937,11 @@ cursoroff(int dolock) { if(dolock) lock(&cursor); - if(--cursor.visible == 0) + if(--cursor.visible == 0) { gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S); + if(islcd) + mbbrect(cursor.r); + } if(dolock) unlock(&cursor); }