M gnot/trap.c => gnot/trap.c +2 -47
@@ 233,52 233,7 @@ noted(Ureg *ur, ulong arg0)
}
}
-#undef CHDIR /* BUG */
-#include "/sys/src/libc/9syscall/sys.h"
-
-typedef long Syscall(ulong*);
-Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
-Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
-Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
-Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
-Syscall syssegattach, syssegdetach, syssegfree, syssegflush, syssegbrk;
-
-Syscall *systab[]={
- sysr1,
- syserrstr,
- sysbind,
- syschdir,
- sysclose,
- sysdup,
- sysalarm,
- sysexec,
- sysexits,
- sysfork,
- sysforkpgrp,
- sysfstat,
- syssegbrk,
- sysmount,
- sysopen,
- sysread,
- sysseek,
- syssleep,
- sysstat,
- syswait,
- syswrite,
- syspipe,
- syscreate,
- sysdeath,
- sysbrk_,
- sysremove,
- syswstat,
- sysfwstat,
- sysnotify,
- sysnoted,
- syssegattach,
- syssegdetach,
- syssegfree,
- syssegflush,
-};
+#include "../port/systab.h"
long
syscall(Ureg *aur)
@@ 314,7 269,7 @@ syscall(Ureg *aur)
u->nerrlab = 0;
ret = -1;
if(!waserror()){
- if(r0 >= sizeof systab/BY2WD){
+ if(r0 >= sizeof systab/sizeof systab[0]){
pprint("bad sys call number %d pc %lux\n", r0, ((Ureg*)UREGADDR)->pc);
msg = "sys: bad sys call";
Bad:
M pc/devfloppy.c => pc/devfloppy.c +246 -126
@@ 29,7 29,7 @@ enum
Fwrite= 0x47, /* write cmd */
Fmulti= 0x80, /* or'd with Fread or Fwrite for multi-head */
- Nfloppy= 4, /* floppies/controller */
+ Ndrive= 4, /* floppies/controller */
DMAchan= 2, /* floppy dma channel */
@@ 46,8 46,8 @@ enum
/* file types */
Qdir= 0,
- Qdata= 16,
- Qstruct= 32,
+ Qdata= 1,
+ Qstruct= 2,
};
/*
@@ 62,23 62,41 @@ struct Type
int steps; /* steps per cylinder */
int tracks; /* tracks/disk */
int gpl; /* intersector gap length for read/write */
- int fgpl; /* intersector gap length for format */
+ int fgpl; /* intersector gap length for format */
+
+ /*
+ * these depend on previous entries and are set filled in
+ * by floppyinit
+ */
+ int bcode; /* coded version of bytes for the controller */
long cap; /* drive capacity in bytes */
};
Type floppytype[] =
{
- { "MF2HD", S512, 18, 2, 1, 80, 0x1B, 0x54, 512*2*18*80 },
- { "MF2DD", S512, 9, 2, 1, 80, 0x1B, 0x54, 512*2*9*80 },
- { "F2HD", S512, 15, 2, 1, 80, 0x2A, 0x50, 512*15*2*80 },
- { "F2DD", S512, 8, 2, 1, 40, 0x2A, 0x50, 512*8*2*40 },
- { "F1DD", S512, 8, 1, 1, 40, 0x2A, 0x50, 512*8*1*40 },
+ { "MF2HD", 512, 18, 2, 1, 80, 0x1B, 0x54, },
+ { "MF2DD", 512, 9, 2, 1, 80, 0x1B, 0x54, },
+ { "F2HD", 512, 15, 2, 1, 80, 0x2A, 0x50, },
+ { "F2DD", 512, 8, 2, 2, 40, 0x2A, 0x50, },
+ { "F1DD", 512, 8, 1, 2, 40, 0x2A, 0x50, },
+};
+#define NTYPES (sizeof(floppytype)/sizeof(Type))
+
+/*
+ * bytes/sector encoding for the controller, index is (bytes per sector/128)
+ */
+static int b2c[] =
+{
+[1] 0,
+[2] 1,
+[4] 2,
+[8] 3,
};
-static int secbytes[] =
+static int c2b[] =
{
128,
256,
512,
- 1024
+ 1024,
};
/*
@@ 86,7 104,8 @@ static int secbytes[] =
*/
struct Drive
{
- QLock;
+ QLock; /* exclusive access to the drive */
+
Type *t;
int dev;
@@ 99,10 118,10 @@ struct Drive
int tcyl; /* target cylinder */
int thead; /* target head */
int tsec; /* target sector */
- long len;
+ long len; /* size of xfer */
int busy; /* true if drive is seeking */
- Rendez r; /* waiting for operation termination */
+ Rendez r; /* waiting here for motor to spin up */
};
/*
@@ 110,30 129,133 @@ struct Drive
*/
struct Controller
{
- QLock;
- Drive d[Nfloppy]; /* the floppy drives */
+ QLock; /* exclusive access to the contoller */
+
+ Drive d[Ndrive]; /* the floppy drives */
int busy; /* true if a read or write in progress */
uchar stat[8]; /* status of an operation */
int confused;
+ int intr; /* true if interrupt occured */
+ Rendez r; /* wait here for command termination */
};
Controller floppy;
/*
+ * predeclared
+ */
+static void motoron(Drive*);
+static void motoroff(Drive*);
+static void floppykproc(void*);
+static int floppysend(int);
+static int floppyrcv(void);
+static int floppyresult(int);
+static void floppypos(Drive*);
+static int floppysense(Drive*);
+static int interrupted(void*);
+static int floppyrecal(Drive*);
+static void floppyrevive(void);
+static long floppyseek(Drive*);
+static long floppyxfer(Drive*, int, void*, long);
+static void floppyintr(Ureg*);
+
+static int
+floppygen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp)
+{
+ long l;
+ Drive *dp;
+
+ if(s >= ntab)
+ return -1;
+ if(c->dev >= Ndrive)
+ return -1;
+
+ tab += s;
+ dp = &floppy.d[c->dev];
+ if((tab->qid.path&~Mask) == Qdata)
+ l = dp->t->cap;
+ else
+ l = 8;
+ devdir(c, tab->qid, tab->name, l, tab->perm, dp);
+ return 1;
+}
+
+void
+floppyreset(void)
+{
+ Drive *dp;
+
+ for(dp = floppy.d; dp < &floppy.d[Ndrive]; dp++){
+ dp->dev = dp - floppy.d;
+ dp->t = &floppytype[0]; /* default type */
+ dp->motoron = 1;
+ dp->cyl = -1;
+ motoroff(dp);
+ }
+ setvec(Floppyvec, floppyintr);
+}
+
+void
+floppyinit(void)
+{
+ Type *t;
+
+ /*
+ * init dependent parameters
+ */
+ for(t = floppytype; t < &floppytype[NTYPES], t++){
+ t->cap = t->bytes * t->heads * t->sectors * t->tracks;
+ t->bcode = bcode[t->bytes/128];
+ }
+
+ /*
+ * watchdog to turn off the motors
+ */
+ kproc(floppykproc, 0);
+}
+long
+floppyread(Chan *c, void *a, long n)
+{
+ Drive *dp;
+ long rv, i;
+ uchar *aa = a;
+
+ dp = &floppy.d[c->dev];
+ for(rv = 0; rv < n; rv += i){
+ i = floppyxfer(dp, Fread, aa+rv, n-rv);
+ if(i <= 0)
+ break;
+ }
+ return rv;
+}
+
+long
+floppywrite(Chan *c, void *a, long n)
+{
+ Drive *dp;
+ long rv, i;
+ uchar *aa = a;
+
+ dp = &floppy.d[c->dev];
+ for(rv = 0; rv < n; rv += i){
+ i = floppyxfer(dp, Fwrite, aa+rv, n-rv);
+ if(i <= 0)
+ break;
+ }
+ return rv;
+}
+
+/*
* start a floppy drive's motor. set an alarm for 1 second later to
* mark it as started (we get no interrupt to tell us).
*
* assume the caller qlocked the drive.
*/
-void
-floppystart(Drive *dp)
+static void
+motoron(Drive *dp)
{
int cmd;
- dp->lasttouched = m->ticks;
- if(dp->motoron)
- return;
-
cmd = (1<<(dp->dev+4)) | Fintena | Fena | dp->dev;
outb(Fmotor, cmd);
dp->busy = 1;
@@ 146,8 268,8 @@ floppystart(Drive *dp)
/*
* stop the floppy if it hasn't been used in 5 seconds
*/
-void
-floppystop(Drive *dp)
+static void
+motoroff(Drive *dp)
{
int cmd;
@@ 155,22 277,25 @@ floppystop(Drive *dp)
outb(Fmotor, cmd);
dp->motoron = 0;
}
-void
-floppykproc(Alarm* a)
+static void
+floppykproc(void *a)
{
Drive *dp;
- for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){
+ for(dp = floppy.d; dp < &floppy.d[Ndrive]; dp++){
if(dp->motoron && TK2SEC(m->ticks - dp->lasttouched) > 5
&& canqlock(dp)){
if(TK2SEC(m->ticks - dp->lasttouched) > 5)
- floppystop(dp);
+ motoroff(dp);
qunlock(dp);
}
}
}
-int
+/*
+ * send a byte to the floppy
+ */
+static int
floppysend(int data)
{
int tries;
@@ 193,7 318,10 @@ floppysend(int data)
return -1;
}
-int
+/*
+ * get a byte from the floppy
+ */
+static int
floppyrcv(void)
{
int tries;
@@ 215,8 343,11 @@ floppyrcv(void)
return -1;
}
-int
-floppyrdstat(int n)
+/*
+ * read a command result message from the floppy
+ */
+static int
+floppyresult(int n)
{
int i;
int c;
@@ 230,14 361,19 @@ floppyrdstat(int n)
return 0;
}
-void
-floppypos(Drive *dp, long off)
+/*
+ * calculate physical address of a logical byte offset into the disk
+ *
+ * truncate dp->length if it crosses a cylinder boundary
+ */
+static void
+floppypos(Drive *dp)
{
int lsec;
int end;
int cyl;
- lsec = off/secbytes[dp->t->bytes];
+ lsec = dp->off/dp->t->bytes;
dp->tcyl = lsec/(dp->t->sectors*dp->t->heads);
dp->tsec = (lsec % dp->t->sectors) + 1;
dp->thead = (lsec/dp->t->sectors) % dp->t->heads;
@@ 246,16 382,20 @@ floppypos(Drive *dp, long off)
* can't read across cylinder boundaries.
* if so, decrement the bytes to be read.
*/
- lsec = (off+dp->len)/secbytes[dp->t->bytes];
+ lsec = (dp->off+dp->len)/dp->t->bytes;
cyl = lsec/(dp->t->sectors*dp->t->heads);
if(cyl != dp->tcyl){
- dp->len -= (lsec % dp->t->sectors)*secbytes[dp->t->bytes];
- dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*secbytes[dp->t->bytes]
+ dp->len -= (lsec % dp->t->sectors)*dp->t->bytes;
+ dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*dp->t->bytes
*dp->t->sectors;
}
}
-int
+/*
+ * get the interrupt cause from the floppy. we need to do this
+ * after seeks and recalibrations since they don't return results.
+ */
+static int
floppysense(Drive *dp)
{
/*
@@ 265,7 405,7 @@ floppysense(Drive *dp)
floppy.confused = 1;
return -1;
}
- if(floppyrdstat(2) < 0){
+ if(floppyresult(2) < 0){
floppy.confused = 1;
dp->confused = 1;
return -1;
@@ 282,7 422,19 @@ floppysense(Drive *dp)
return 0;
}
-int
+/*
+ * return true if interrupt occurred
+ */
+static int
+interrupted(void *a)
+{
+ return floppy.intr;
+}
+
+/*
+ * we've lost the floppy position, go to cylinder 0.
+ */
+static int
floppyrecal(Drive *dp)
{
floppy.intr = 0;
@@ 291,7 443,7 @@ floppyrecal(Drive *dp)
floppy.confused = 0;
return -1;
}
- floppywait();
+ sleep(&floppy.r, interrupted, 0);
/*
* get return values
@@ 323,33 475,17 @@ floppyrecal(Drive *dp)
return 0;
}
+/*
+ * if the controller or a specific drive is in a confused state,
+ * reset it and get back to a kown state
+ */
void
-floppyreset(void)
-{
- Drive *dp;
-
- for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){
- dp->dev = dp - floppy.d;
- dp->t = &floppytype[0]; /* default type */
- dp->motoron = 1;
- dp->cyl = -1;
- floppystop(dp);
- }
-}
-
-void
-floppyinit(void)
-{
- kproc(floppykproc, 0);
-}
-
-void
-floppyreset(void)
+floppyrevive(void)
{
Drive *dp;
/*
- * reset the floppy if'n it's confused
+ * reset the floppy if it's confused
*/
if(floppy.confused){
/* reset controller and turn all motors off */
@@ 359,18 495,18 @@ floppyreset(void)
delay(1);
outb(Fmotor, Fintena|Fena);
spllo();
- for(dp = floppy.d; dp < &floppy.d[Nfloppy]; dp++){
+ for(dp = floppy.d; dp < &floppy.d[Ndrive]; dp++){
dp->motoron = 0;
dp->confused = 1;
}
- floppywait();
+ sleep(&floppy.r, interrupted, 0);
floppy.confused = 0;
}
/*
* recalibrate any confused drives
*/
- for(dp = floppy.d; floppy.confused == 0 && dp < &floppy.d[Nfloppy]; dp++){
+ for(dp = floppy.d; floppy.confused == 0 && dp < &floppy.d[Ndrive]; dp++){
if(dp->confused == 0)
floppyrecal(dp);
@@ 378,19 514,9 @@ floppyreset(void)
}
-long
-floppyseek(int dev, long off)
+static long
+floppyseek(Drive *dp)
{
- Drive *dp;
-
- dp = &floppy.d[dev];
-
- if(floppy.confused || dp->confused)
- floppyreset();
-
- floppystart(dp);
-
- floppypos(dp, off);
if(dp->cyl == dp->tcyl){
dp->offset = off;
return off;
@@ 400,7 526,7 @@ floppyseek(int dev, long off)
* tell floppy to seek
*/
if(floppysend(Fseek) < 0
- || floppysend((dp->thead<<2) | dev) < 0
+ || floppysend((dp->thead<<2) | dp->dev) < 0
|| floppysend(dp->tcyl * dp->t->steps) < 0){
print("seek cmd failed\n");
floppy.confused = 1;
@@ 410,7 536,7 @@ floppyseek(int dev, long off)
/*
* wait for interrupt
*/
- floppywait();
+ sleep(&floppy.r, interrupted, 0);
/*
* get floppy status
@@ 441,42 567,47 @@ floppyseek(int dev, long off)
return dp->offset;
}
-long
+static long
floppyxfer(Drive *dp, int cmd, void *a, long n)
{
- int dev;
ulong addr;
long offset;
addr = (ulong)a;
- dev = dp - floppy.d;
+
+ qlock(&floppy);
+ qlock(dp);
+ if(waserror){
+ qunlock(&floppy);
+ qunlock(dp);
+ }
/*
- * dma can't cross 64 k boundaries
+ * get floppy reset and spinning
*/
- if((addr & 0xffff0000) != ((addr+n) & 0xffff0000))
- n -= (addr+n)&0xffff;
+ if(floppy.confused || dp->confused)
+ floppyrevive();
+ if(!dp->motoron)
+ motoron(dp);
+ /*
+ * calculate new position and seek to it (dp->len may be trimmed)
+ */
dp->len = n;
- floppyseek(dev, dp->offset);
+ floppypos(dp);
+ if(floppyseek(dp) < 0)
+ errors("seeking floppy");
-/* print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n",
+print("tcyl %d, thead %d, tsec %d, addr %lux, n %d\n",
dp->tcyl, dp->thead, dp->tsec, addr, n);/**/
/*
- * set up the dma
+ * set up the dma (dp->len may be trimmed)
*/
- outb(DMAmode1, cmd==Fread ? 0x46 : 0x4a);
- outb(DMAmode0, cmd==Fread ? 0x46 : 0x4a);
- outb(DMAaddr, addr);
- outb(DMAaddr, addr>>8);
- outb(DMAtop, addr>>16);
- outb(DMAcount, n-1);
- outb(DMAcount, (n-1)>>8);
- outb(DMAinit, 2);
+ dp->len = dmasetup(2, a, dp->len, cmd==Fread);
/*
- * tell floppy to go
+ * start operation
*/
cmd = cmd | (dp->t->heads > 1 ? Fmulti : 0);
if(floppysend(cmd) < 0
@@ 484,64 615,53 @@ floppyxfer(Drive *dp, int cmd, void *a, long n)
|| floppysend(dp->tcyl * dp->t->steps) < 0
|| floppysend(dp->thead) < 0
|| floppysend(dp->tsec) < 0
- || floppysend(dp->t->bytes) < 0
+ || floppysend(dp->t->bcode) < 0
|| floppysend(dp->t->sectors) < 0
|| floppysend(dp->t->gpl) < 0
|| floppysend(0xFF) < 0){
print("xfer cmd failed\n");
floppy.confused = 1;
- return -1;
+ errors("floppy command failed");
}
- floppywait();
+ sleep(&floppy.r, interrupted, 0);
/*
* get status
*/
- if(floppyrdstat(7) < 0){
- print("xfer status failed\n");
+ if(floppyresult(7) < 0){
+print("xfer status failed\n");
floppy.confused = 1;
- return -1;
+ errors("floppy result failed");
}
if((floppy.stat[0] & Codemask)!=0 || floppy.stat[1] || floppy.stat[2]){
print("xfer failed %lux %lux %lux\n", floppy.stat[0],
floppy.stat[1], floppy.stat[2]);
dp->confused = 1;
- return -1;
+ errors("floppy drive lost");
}
offset = (floppy.stat[3]/dp->t->steps) * dp->t->heads + floppy.stat[4];
offset = offset*dp->t->sectors + floppy.stat[5] - 1;
- offset = offset * secbytes[floppy.stat[6]];
+ offset = offset * c2b[floppy.stat[6]];
if(offset != dp->offset+n){
- print("new offset %d instead of %d\n", offset, dp->offset+dp->len);
+print("new offset %d instead of %d\n", offset, dp->offset+dp->len);
dp->confused = 1;
- return -1;/**/
+ errors("floppy drive lost");
}
+ qunlock(&floppy);
+ qunlock(dp);
+ poperror();
+
dp->offset += dp->len;
return dp->len;
}
-long
-floppyread(int dev, void *a, long n)
-{
- Drive *dp;
- long rv, i;
- uchar *aa = a;
-
- dp = &floppy.d[dev];
- for(rv = 0; rv < n; rv += i){
- i = floppyxfer(dp, Fread, aa+rv, n-rv);
- if(i <= 0)
- break;
- }
- return rv;
-}
-
-void
+static void
floppyintr(Ureg *ur)
{
floppy.intr = 1;
+ wakeup(&floppy.r);
}
M pc/fns.h => pc/fns.h +0 -26
@@ 18,32 18,6 @@ void fprestore(FPsave*);
ulong getcr2(void);
void idle(void);
int inb(int);
-void intr0(void);
-void intr1(void);
-void intr2(void);
-void intr3(void);
-void intr4(void);
-void intr5(void);
-void intr6(void);
-void intr7(void);
-void intr8(void);
-void intr9(void);
-void intr10(void);
-void intr11(void);
-void intr12(void);
-void intr13(void);
-void intr14(void);
-void intr15(void);
-void intr16(void);
-void intr17(void);
-void intr18(void);
-void intr19(void);
-void intr20(void);
-void intr21(void);
-void intr22(void);
-void intr23(void);
-void intr64(void);
-void intrbad(void);
void kbdinit(void);
void kbdintr(Ureg*);
void mmuinit(void);
M pc/headland.c => pc/headland.c +17 -0
@@ 13,6 13,20 @@ enum
Head= 0x92, /* control port */
Reset= (1<<0), /* reset the 386 */
A20ena= (1<<1), /* enable address line 20 */
+
+ /*
+ * the byte registers for DMA0 are all one byte apart
+ */
+ Dma0= 0x00,
+ Dma0status= Dma0+0x8, /* status port */
+ Dma0reset= Dma0+0xD, /* reset port */
+
+ /*
+ * the byte registers for DMA1 are all two bytes apart (why?)
+ */
+ Dma1= 0xC0,
+ Dma1status= Dma1+2*0x8, /* status port */
+ Dma1reset= Dma1+2*0xD, /* reset port */
};
/*
@@ 96,6 110,9 @@ exit(void)
*
* we assume BIOS has set up the command register before we
* are booted.
+ *
+ * return the updated transfer length (we can't transfer across 64k
+ * boundaries)
*/
long
dmasetup(int chan, void *va, long len, int isread)
M pc/io.h => pc/io.h +10 -25
@@ 1,31 1,16 @@
/*
- * programmable interrupt vectors (for the 8259)
+ * programmable interrupt vectors (for the 8259's)
*/
enum
{
Faultvec= 14, /* page fault */
- Int0vec= 16, /* first interrupt vector used by the 8259 */
- Clockvec= Int0vec+0, /* clock interrupts */
- Kbdvec= Int0vec+1, /* keyboard interrupts */
- Mousevec= Int0vec+12, /* mouse interrupt */
-};
-
-/*
- * 8237 dma controllers
- */
-enum
-{
- /*
- * the byte registers for DMA0 are all one byte apart
- */
- Dma0= 0x00,
- Dma0status= Dma0+0x8, /* status port */
- Dma0reset= Dma0+0xD, /* reset port */
-
- /*
- * the byte registers for DMA1 are all two bytes apart (why?)
- */
- Dma1= 0xC0,
- Dma1status= Dma1+2*0x8, /* status port */
- Dma1reset= Dma1+2*0xD, /* reset port */
+ Int0vec= 16, /* first 8259 */
+ Clockvec= Int0vec+0, /* clock interrupts */
+ Kbdvec= Int0vec+1, /* keyboard interrupts */
+ ComBvec= Int0vec+3, /* inerrupt from uart b */
+ ComAvec= Int0vec+4, /* inerrupt from uart a */
+ Floppyvec= Int0vec+6, /* floppy interrupts */
+ Int1vec= Int0vec+8, /* second 8259 */
+ Mousevec= Int1vec+4, /* mouse interrupt */
+ Hardvec= Int1vec+6, /* hard disk */
};
M pc/kbd.c => pc/kbd.c +129 -48
@@ 5,6 5,10 @@
#include "fns.h"
#include "io.h"
+#include <libg.h>
+#include <gnot.h>
+#include "screen.h"
+
enum {
Data= 0x60, /* data port */
@@ 16,7 20,7 @@ enum {
Inhibit= 0x10, /* keyboard/mouse inhibited */
Minready= 0x20, /* mouse character ready */
Rtimeout= 0x40, /* general timeout */
- Parity= 0x80, /* 1 == error */
+ Parity= 0x80,
Cmd= 0x64, /* command port (write only) */
@@ 24,7 28,7 @@ enum {
PF= Spec|0x20, /* num pad function key */
View= Spec|0x00, /* view (shift window up) */
- F= Spec|0x40, /* function key */
+ KF= Spec|0x40, /* function key */
Shift= Spec|0x60,
Break= Spec|0x61,
Ctrl= Spec|0x62,
@@ 33,16 37,16 @@ enum {
Num= Spec|0x65,
No= Spec|0x7F, /* no mapping */
- Home= F|13,
- Up= F|14,
- Pgup= F|15,
- Print= F|16,
+ Home= KF|13,
+ Up= KF|14,
+ Pgup= KF|15,
+ Print= KF|16,
Left= View,
Right= View,
End= '\r',
Down= View,
Pgdown= View,
- Ins= F|20,
+ Ins= KF|20,
Del= 0x7F,
};
@@ 55,11 59,11 @@ uchar kbtab[] =
[0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v',
[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, No,
-[0x38] Latin, ' ', Caps, F|1, F|2, F|3, F|4, F|5,
-[0x40] F|6, F|7, F|8, F|9, F|10, Num, F|12, Home,
+[0x38] Latin, ' ', Caps, KF|1, KF|2, KF|3, KF|4, KF|5,
+[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home,
[0x48] No, No, No, No, No, No, No, No,
-[0x50] No, No, No, No, No, No, No, F|11,
-[0x58] F|12, No, No, No, No, No, No, No,
+[0x50] No, No, No, No, No, No, No, KF|11,
+[0x58] KF|12, No, No, No, No, No, No, No,
};
uchar kbtabshift[] =
@@ 71,11 75,11 @@ uchar kbtabshift[] =
[0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V',
[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, No,
-[0x38] Latin, ' ', Caps, F|1, F|2, F|3, F|4, F|5,
-[0x40] F|6, F|7, F|8, F|9, F|10, Num, F|12, Home,
+[0x38] Latin, ' ', Caps, KF|1, KF|2, KF|3, KF|4, KF|5,
+[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home,
[0x48] No, No, No, No, No, No, No, No,
-[0x50] No, No, No, No, No, No, No, F|11,
-[0x58] F|12, No, No, No, No, No, No, No,
+[0x50] No, No, No, No, No, No, No, KF|11,
+[0x58] KF|12, No, No, No, No, No, No, No,
};
uchar kbtabesc1[] =
@@ 236,45 240,110 @@ latin1(int k1, int k2)
return 0;
}
+static void
+mousecmd(int cmd, int arg)
+{
+ unsigned int c;
+
+ do {
+ while(inb(Status) & Outbusy)
+ ;
+ outb(Cmd, 0xD4);
+ while(inb(Status) & Outbusy)
+ ;
+ outb(Data, cmd);
+ if(arg >= 0){
+ while(inb(Status) & Outbusy)
+ ;
+ outb(Data, arg);
+ }
+ while(!(inb(Status) & Inready))
+ ;
+ c = inb(Data);
+ } while(c == 0xFE);
+ if(c != 0xFA)
+ print("mouse command returns bad status %lux", c);
+}
+
void
kbdinit(void)
{
- uchar c;
+ int c, s;
initq(&kbdq);
setvec(Kbdvec, kbdintr);
+ initq(&mouseq);
+ setvec(Mousevec, kbdintr);
/* wait for a quiescent controller */
while((c = inb(Status)) & (Outbusy | Inready))
if(c & Inready)
inb(Data);
- /* read controller command byte */
- outb(Cmd, 0x20);
- while(!(inb(Status) & Inready))
- ;
- c = inb(Data);
-print("input completed\n");
-delay(5000);
-
- /* enable mouse and mouse interupts */
- c = (c&~0x20) | 0x02;
+ /* enable kbd/mouse xfers and interrupts */
outb(Cmd, 0x60);
while(inb(Status) & Outbusy)
;
- outb(Data, c);
-print("mouse enabled\n");
+ outb(Data, 0x47);
+ while(inb(Status) & Outbusy)
+ ;
+ outb(Cmd, 0xA8);
+
+ /* make mouse streaming (and enabled) */
+ mousecmd(0xEA, -1);
+ mousecmd(0xF4, -1);
+
+ /* resolution */
+ mousecmd(0xE8, 0x03);
+print("res set\n");
delay(5000);
+}
- initq(&mouseq);
- setvec(Mousevec, kbdintr);
+/*
+ * mouse message is three bytes
+ *
+ * byte 0 - 0 0 SDY SDX 1 M R L
+ * byte 1 - DX
+ * byte 2 - DY
+ */
+static void
+mymouseputc(int c)
+{
+ static short msg[3];
+ static int nb;
+ static uchar b[] = {0, 4, 1, 5, 2, 6, 3, 7};
+ static lastdx, lastdy;
+ int diff;
+ extern Mouseinfo mouse;
+
+ /*
+ * check byte 0 for consistency
+ */
+ if(nb==0 && (c&0xc8)!=0x08)
+ return;
+
+ msg[nb] = c;
+ if(++nb == 3){
+ nb = 0;
+ if(msg[0] & 0x10)
+ msg[1] |= 0xFF00;
+ if(msg[0] & 0x20)
+ msg[2] |= 0xFF00;
+
+ mouse.newbuttons = b[msg[0]&7];
+ mouse.dx = msg[1];
+ mouse.dy = -msg[2];
+print("%d %d\n", mouse.dx, mouse.dy);
+ mouse.track = 1;
+ mouseclock();
+ }
}
/*
* keyboard interrupt
*/
-void
-kbdintr(Ureg *ur)
+int
+kbdintr0(void)
{
int s, c, nc;
static int esc1, esc2;
@@ 286,18 355,23 @@ kbdintr(Ureg *ur)
int keyup;
/*
- * get status and character
+ * get status
*/
s = inb(Status);
+ if(!(s&Inready))
+ return -1;
+
+ /*
+ * get the character
+ */
c = inb(Data);
/*
* if it's the mouse...
*/
if(s & Minready){
-print("mousechar\n");
- mouseputc(&mouseq, c);
- return;
+ mymouseputc(c);
+ return 0;
}
keyup = c&0x80;
@@ 305,7 379,7 @@ print("mousechar\n");
if(c > sizeof kbtab){
print("unknown key %ux\n", c|keyup);
kbdputc(&kbdq, k1);
- return;
+ return 0;
}
/*
@@ 313,10 387,10 @@ print("mousechar\n");
*/
if(c == 0xe0){
esc1 = 1;
- return;
+ return 0;
} else if(c == 0xe1){
esc2 = 2;
- return;
+ return 0;
}
if(esc1){
@@ 324,7 398,7 @@ print("mousechar\n");
esc1 = 0;
} else if(esc2){
esc2--;
- return;
+ return 0;
} else if(shift)
c = kbtabshift[c];
else
@@ 345,7 419,7 @@ print("mousechar\n");
ctl = 0;
break;
}
- return;
+ return 0;
}
/*
@@ 358,7 432,7 @@ print("mousechar\n");
case 1:
k1 = c;
lstate = 2;
- return;
+ return 0;
case 2:
k2 = c;
lstate = 0;
@@ 375,21 449,28 @@ print("mousechar\n");
switch(c){
case Caps:
caps ^= 1;
- return;
+ return 0;
case Num:
num ^= 1;
- return;
+ return 0;
case Shift:
shift = 1;
- return;
+ return 0;
case Latin:
lstate = 1;
- return;
+ return 0;
case Ctrl:
ctl = 1;
- return;
+ return 0;
}
}
kbdputc(&kbdq, c);
- return;
+ return 0;
+}
+
+void
+kbdintr(Ureg *ur)
+{
+ while(kbdintr0() == 0)
+ ;
}
M pc/l.s => pc/l.s +32 -0
@@ 347,6 347,38 @@ TEXT intr23(SB),$0
PUSHL $0
PUSHL $23
JMP intrcommon
+TEXT intr24(SB),$0
+ PUSHL $0
+ PUSHL $24
+ JMP intrcommon
+TEXT intr25(SB),$0
+ PUSHL $0
+ PUSHL $25
+ JMP intrcommon
+TEXT intr26(SB),$0
+ PUSHL $0
+ PUSHL $26
+ JMP intrcommon
+TEXT intr27(SB),$0
+ PUSHL $0
+ PUSHL $27
+ JMP intrcommon
+TEXT intr28(SB),$0
+ PUSHL $0
+ PUSHL $28
+ JMP intrcommon
+TEXT intr29(SB),$0
+ PUSHL $0
+ PUSHL $29
+ JMP intrcommon
+TEXT intr30(SB),$0
+ PUSHL $0
+ PUSHL $30
+ JMP intrcommon
+TEXT intr31(SB),$0
+ PUSHL $0
+ PUSHL $31
+ JMP intrcommon
TEXT intr64(SB),$0
PUSHL $0
PUSHL $64
M pc/trap.c => pc/trap.c +67 -55
@@ 10,6 10,17 @@
void noted(Ureg*, ulong);
void notify(Ureg*);
+void intr0(void), intr1(void), intr2(void), intr3(void);
+void intr4(void), intr5(void), intr6(void), intr7(void);
+void intr8(void), intr9(void), intr10(void), intr11(void);
+void intr12(void), intr13(void), intr14(void), intr15(void);
+void intr16(void), intr17(void), intr18(void), intr19(void);
+void intr20(void), intr21(void), intr22(void), intr23(void);
+void intr24(void), intr25(void), intr26(void), intr27(void);
+void intr28(void), intr29(void), intr30(void), intr31(void);
+void intr64(void);
+void intrbad(void);
+
/*
* 8259 interrupt controllers
*/
@@ 23,8 34,8 @@ enum
EOI= 0x20, /* non-specific end of interrupt */
};
-int int0mask = 7; /* interrupts enabled for first 8259 */
-int int1mask = 7; /* interrupts enabled for second 8259 */
+int int0mask = 0xff; /* interrupts enabled for first 8259 */
+int int1mask = 0xff; /* interrupts enabled for second 8259 */
/*
* trap/interrupt gates
@@ 50,6 61,9 @@ setvec(int v, void (*r)(Ureg*))
if((v&~0x7) == Int0vec){
int0mask &= ~(1<<(v&7));
outb(Int0aux, int0mask);
+ } else if((v&~0x7) == Int1vec){
+ int1mask &= ~(1<<(v&7));
+ outb(Int1aux, int1mask);
}
}
@@ 62,6 76,12 @@ trapinit(void)
int i;
/*
+ * set all interrupts to panics
+ */
+ for(i = 32; i < 256; i++)
+ sethvec(i, intrbad, SEGIG, 0);
+
+ /*
* set the standard traps
*/
sethvec(0, intr0, SEGIG, 0);
@@ 80,6 100,10 @@ trapinit(void)
sethvec(13, intr13, SEGIG, 0);
sethvec(14, intr14, SEGIG, 0);
sethvec(15, intr15, SEGIG, 0);
+
+ /*
+ * set the standard devices
+ */
sethvec(16, intr16, SEGIG, 0);
sethvec(17, intr17, SEGIG, 0);
sethvec(18, intr18, SEGIG, 0);
@@ 88,12 112,14 @@ trapinit(void)
sethvec(21, intr21, SEGIG, 0);
sethvec(22, intr22, SEGIG, 0);
sethvec(23, intr23, SEGIG, 0);
-
- /*
- * set all others to unknown interrupts
- */
- for(i = 24; i < 256; i++)
- sethvec(i, intrbad, SEGIG, 0);
+ sethvec(24, intr24, SEGIG, 0);
+ sethvec(25, intr25, SEGIG, 0);
+ sethvec(26, intr26, SEGIG, 0);
+ sethvec(27, intr27, SEGIG, 0);
+ sethvec(28, intr28, SEGIG, 0);
+ sethvec(29, intr29, SEGIG, 0);
+ sethvec(30, intr30, SEGIG, 0);
+ sethvec(31, intr31, SEGIG, 0);
/*
* system calls
@@ 115,8 141,26 @@ trapinit(void)
outb(Int0ctl, 0x11); /* ICW1 - edge triggered, master,
ICW4 will be sent */
outb(Int0aux, Int0vec); /* ICW2 - interrupt vector offset */
- outb(Int0aux, 0x04); /* ICW3 - master level 2 */
+ outb(Int0aux, 0x04); /* ICW3 - have slave on level 2 */
outb(Int0aux, 0x01); /* ICW4 - 8086 mode, not buffered */
+
+ /*
+ * Set up the second 8259 interrupt processor.
+ * Make 8259 interrupts start at CPU vector Int0vec.
+ * Set the 8259 as master with edge triggered
+ * input with fully nested interrupts.
+ */
+ outb(Int1ctl, 0x11); /* ICW1 - edge triggered, master,
+ ICW4 will be sent */
+ outb(Int1aux, Int1vec); /* ICW2 - interrupt vector offset */
+ outb(Int1aux, 0x02); /* ICW3 - I am a slave on level 2 */
+ outb(Int1aux, 0x01); /* ICW4 - 8086 mode, not buffered */
+
+ /*
+ * pass #2 8259 interrupts to #1
+ */
+ int0mask &= ~0x04;
+ outb(Int0aux, int0mask);
}
/*
@@ 125,19 169,28 @@ trapinit(void)
void
trap(Ureg *ur)
{
- if(ur->trap>=256 || ivec[ur->trap] == 0)
- panic("bad trap type %d %lux\n", ur->trap, ur->pc);
+ int v;
+ int c;
+
+ v = ur->trap;
+ if(v>=256 || ivec[v] == 0)
+ panic("bad trap type %d %lux\n", v, ur->pc);
/*
* call the trap routine
*/
- (*ivec[ur->trap])(ur);
+ (*ivec[v])(ur);
/*
* tell the 8259 that we're done with the
* highest level interrupt
*/
- outb(Int0ctl, EOI);
+ c = v&~0x7;
+ if(c==Int0vec || c==Int1vec){
+ outb(Int0ctl, EOI);
+ if(c == Int1vec)
+ outb(Int1ctl, EOI);
+ }
}
/*
@@ 173,48 226,7 @@ execpc(ulong entry)
/*
* system calls
*/
-#undef CHDIR /* BUG */
-#include "/sys/src/libc/9syscall/sys.h"
-
-typedef long Syscall(ulong*);
-Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
-Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
-Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
-Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
-
-Syscall *systab[]={
- sysr1,
- syserrstr,
- sysbind,
- syschdir,
- sysclose,
- sysdup,
- sysalarm,
- sysexec,
- sysexits,
- sysfork,
- sysforkpgrp,
- sysfstat,
- sysdeath,
- sysmount,
- sysopen,
- sysread,
- sysseek,
- syssleep,
- sysstat,
- syswait,
- syswrite,
- syspipe,
- syscreate,
- sysdeath,
- sysbrk_,
- sysremove,
- syswstat,
- sysfwstat,
- sysnotify,
- sysnoted,
- sysdeath, /* sysfilsys */
-};
+#include "../port/systab.h"
long
syscall(Ureg *ur)
M pc/vga.c => pc/vga.c +1 -1
@@ 240,7 240,7 @@ getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb)
ulong ans;
/*
- * The magnum monochrome says 0 is black (zero intensity)
+ * The safari monochrome says 0 is black (zero intensity)
*/
if(p == 0)
ans = 0;
M port/devbit.c => port/devbit.c +7 -2
@@ 1133,12 1133,17 @@ void
Cursortocursor(Cursor *c)
{
int i;
+ uchar *p;
lock(&cursor);
memmove(&cursor, c, sizeof(Cursor));
for(i=0; i<16; i++){
- setbits[i] = (c->set[2*i]<<24) + (c->set[2*i+1]<<16);
- clrbits[i] = (c->clr[2*i]<<24) + (c->clr[2*i+1]<<16);
+ p = (uchar*)&setbits[i];
+ *p = c->set[2*i];
+ *(p+1) = c->set[2*i+1];
+ p = (uchar*)&clrbits[i];
+ *p = c->clr[2*i];
+ *(p+1) = c->clr[2*i+1];
}
unlock(&cursor);
}
M port/portdat.h => port/portdat.h +1 -1
@@ 582,7 582,7 @@ enum {
Streambhi= 32, /* block count high water mark */
};
-#define MAXSYSARG 6 /* for mount(fd, mpt, flag, arg, srv, authfd) */
+#define MAXSYSARG 6 /* for mount(fd, mpt, flag, arg, srv) */
#define PRINTSIZE 256
#define NUMSIZE 12 /* size of formatted number */
M port/segment.c => port/segment.c +1 -1
@@ 442,7 442,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
errors("segments overlap");
}
- for(ps = physseg; *(ps->name); ps++)
+ for(ps = physseg; ps->name; ps++)
if(strcmp(name, ps->name) == 0)
goto found;
A port/systab.h => port/systab.h +47 -0
@@ 0,0 1,47 @@
+#undef CHDIR /* BUG */
+#include "/sys/src/libc/9syscall/sys.h"
+
+typedef long Syscall(ulong*);
+Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath;
+Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp;
+Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted;
+Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek;
+Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk;
+Syscall syssegattach, syssegdetach, syssegfree, syssegflush;
+
+Syscall *systab[]={
+ [SYSR1] sysr1,
+ [ERRSTR] syserrstr,
+ [BIND] sysbind,
+ [CHDIR] syschdir,
+ [CLOSE] sysclose,
+ [DUP] sysdup,
+ [ALARM] sysalarm,
+ [EXEC] sysexec,
+ [EXITS] sysexits,
+ [FORK] sysfork,
+ [FORKPGRP] sysforkpgrp,
+ [FSTAT] sysfstat,
+ [SEGBRK] syssegbrk,
+ [MOUNT] sysmount,
+ [OPEN] sysopen,
+ [READ] sysread,
+ [SEEK] sysseek,
+ [SLEEP] syssleep,
+ [STAT] sysstat,
+ [WAIT] syswait,
+ [WRITE] syswrite,
+ [PIPE] syspipe,
+ [CREATE] syscreate,
+ [___USERSTR___] sysdeath,
+ [BRK_] sysbrk_,
+ [REMOVE] sysremove,
+ [WSTAT] syswstat,
+ [FWSTAT] sysfwstat,
+ [NOTIFY] sysnotify,
+ [NOTED] sysnoted,
+ [SEGATTACH] syssegattach,
+ [SEGDETACH] syssegdetach,
+ [SEGFREE] syssegfree,
+ [SEGFLUSH] syssegflush,
+};
M power/segment.h => power/segment.h +1 -1
@@ 12,7 12,7 @@ struct Physseg
Page *(*pgalloc)(ulong); /* Allocation if we need it */
void (*pgfree)(Page*);
}physseg[] = {
- { SG_SHARED, "lock", 0, 1024*BY2PG, &lkpage, &lkpgfree },
+ { SG_PHYSICAL, "lock", 0, 1024*BY2PG, &lkpage, &lkpgfree },
{ SG_SHARED, "shared", 0, SEGMAXSIZE, &snewpage, &putpage },
{ SG_PHYSICAL, "kmem", KZERO, SEGMAXSIZE, 0, 0 },
{ SG_BSS, "memory", 0, SEGMAXSIZE, &snewpage, &putpage },
M power/trap.c => power/trap.c +2 -48
@@ 461,53 461,7 @@ noted(Ureg **urp, ulong arg0)
}
-#undef CHDIR /* BUG */
-#include "/sys/src/libc/9syscall/sys.h"
-
-typedef long Syscall(ulong*);
-Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath;
-Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp;
-Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted;
-Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek;
-Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm, syssegbrk;
-Syscall syssegattach, syssegdetach, syssegfree, syssegflush;
-
-Syscall *systab[]={
- [SYSR1] sysr1,
- [ERRSTR] syserrstr,
- [BIND] sysbind,
- [CHDIR] syschdir,
- [CLOSE] sysclose,
- [DUP] sysdup,
- [ALARM] sysalarm,
- [EXEC] sysexec,
- [EXITS] sysexits,
- [FORK] sysfork,
- [FORKPGRP] sysforkpgrp,
- [FSTAT] sysfstat,
- [SEGBRK] syssegbrk,
- [MOUNT] sysmount,
- [OPEN] sysopen,
- [READ] sysread,
- [SEEK] sysseek,
- [SLEEP] syssleep,
- [STAT] sysstat,
- [WAIT] syswait,
- [WRITE] syswrite,
- [PIPE] syspipe,
- [CREATE] syscreate,
- [___USERSTR___] sysdeath,
- [BRK_] sysbrk_,
- [REMOVE] sysremove,
- [WSTAT] syswstat,
- [FWSTAT] sysfwstat,
- [NOTIFY] sysnotify,
- [NOTED] sysnoted,
- [SEGATTACH] syssegattach,
- [SEGDETACH] syssegdetach,
- [SEGFREE] syssegfree,
- [SEGFLUSH] syssegflush,
-};
+#include "../port/systab.h"
long
syscall(Ureg *aur)
@@ 543,7 497,7 @@ syscall(Ureg *aur)
u->nerrlab = 0;
ret = -1;
if(!waserror()){
- if(r1 >= sizeof systab/BY2WD){
+ if(r1 >= sizeof systab/sizeof systab[0]){
pprint("bad sys call number %d pc %lux\n", r1, ((Ureg*)UREGADDR)->pc);
msg = "sys: bad sys call";
Bad:
M ss/trap.c => ss/trap.c +1 -42
@@ 306,48 306,7 @@ noted(Ureg **urp, ulong arg0)
}
}
-#undef CHDIR /* BUG */
-#include "/sys/src/libc/9syscall/sys.h"
-
-typedef long Syscall(ulong*);
-Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
-Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
-Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
-Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
-
-Syscall *systab[]={
- sysr1,
- syserrstr,
- sysbind,
- syschdir,
- sysclose,
- sysdup,
- sysalarm,
- sysexec,
- sysexits,
- sysfork,
- sysforkpgrp,
- sysfstat,
- sysdeath,
- sysmount,
- sysopen,
- sysread,
- sysseek,
- syssleep,
- sysstat,
- syswait,
- syswrite,
- syspipe,
- syscreate,
- sysdeath,
- sysbrk_,
- sysremove,
- syswstat,
- sysfwstat,
- sysnotify,
- sysnoted,
- sysdeath, /* sysfilsys */
-};
+#include "../port/systab.h"
long
syscall(Ureg *aur)