M pc/archgeneric.c => pc/archgeneric.c +1 -1
@@ 15,7 15,7 @@ genericreset(void)
PCArch generic =
{
"generic",
- genericreset,
+ i8042reset,
0,
0,
0,
M pc/devfloppy.c => pc/devfloppy.c +55 -58
@@ 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();
}
M pc/devincon.c => pc/devincon.c +34 -7
@@ 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; i++){
- incon[i].dev = lptbase[i];
+ incon[i].dev = lptbase[1/*i*/];
incon[i].state = Notliving;
reset(incon[i].dev);
incon[i].ri = incon[i].wi = 0;
@@ 496,7 521,8 @@ inconattach(char *spec)
int i;
Chan *c;
- setvec(Parallelvec, inconintr);
+ /*setvec(Parallelvec, inconintr);*/
+setvec(Int0vec+5, inconintr);
i = strtoul(spec, 0, 0);
if(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);
M pc/dma.c => pc/dma.c +2 -1
@@ 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)
M pc/kbd.c => pc/kbd.c +10 -2
@@ 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();
}
M pc/mem.h => pc/mem.h +0 -1
@@ 53,7 53,6 @@
#define MACHSIZE 4096
-#define isphys(x) (((ulong)x)&KZERO)
/*
* known 80386 segments (in GDT) and their selectors
M pc/screen.h => pc/screen.h +3 -0
@@ 29,3 29,6 @@ extern Cursorinfo cursor;
extern void mouseupdate(int);
#define hwscreenwrite(a, b)
+
+#define screenupdate(z)
+int islcd;
M pc/vga.c => pc/vga.c +5 -5
@@ 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,
};
M port/devbit.c => port/devbit.c +78 -3
@@ 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);
}