From a53b7e0b24948183a1d0cffb1618009dfc766180 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 24 Nov 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-11-24 --- carrera/fns.h | 2 + pc/clock.c | 76 +- pc/devether.c | 25 +- pc/devfloppy.c | 10 +- pc/devhard.c | 10 +- pc/devuart.c | 891 ------------------ pc/ether509.c | 7 +- pc/ether8390.c | 6 +- pc/etherif.h | 2 +- pc/fault386.c | 8 +- pc/fns.h | 8 +- pc/kbd.c | 396 ++++---- pc/main.c | 20 +- pc/mmu.c | 11 +- pc/trap.c | 26 +- port/crc_16.h | 35 - port/devbit.c | 2304 ----------------------------------------------- port/devcdrom.c | 234 ----- port/devscc.c | 814 ----------------- port/devscsi.c | 536 ----------- port/devwren.c | 336 ------- port/netXXX.c | 108 --- port/portdat.h | 51 -- port/portfns.h | 23 - power/fns.h | 2 + 25 files changed, 296 insertions(+), 5645 deletions(-) delete mode 100644 pc/devuart.c delete mode 100644 port/crc_16.h delete mode 100644 port/devbit.c delete mode 100644 port/devcdrom.c delete mode 100644 port/devscc.c delete mode 100644 port/devscsi.c delete mode 100644 port/devwren.c delete mode 100644 port/netXXX.c diff --git a/carrera/fns.h b/carrera/fns.h index a0af9e4ea297b9abcfd65f0ac8af13266b1fa238..9b19ae28deb4f09f99043ceef4d130bd639af428 100644 --- a/carrera/fns.h +++ b/carrera/fns.h @@ -8,6 +8,7 @@ void arginit(void); int busprobe(ulong); void cleancache(void); void clearmmucache(void); +void clock(Ureg*); void clockinit(void); ulong confeval(char*); void confprint(void); @@ -80,6 +81,7 @@ int readlog(ulong, char*, ulong); void restfpregs(FPsave*, ulong); void screeninit(void); void screenputs(char*, int); +long syscall(Ureg*); void syslog(char*, int); void sysloginit(void); int tas(ulong*); diff --git a/pc/clock.c b/pc/clock.c index b49a6b55f11fe55f0cff8bc69da439d063174a20..bd3c524d1cc06e3e93fe56922e7bf99fb5c081a4 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -42,6 +42,44 @@ delay(int l) ; } +static void +clock(Ureg *ur, void *arg) +{ + Proc *p; + int nrun = 0; + + USED(arg); + + m->ticks++; + + checkalarms(); + mouseclock(); + + /* + * process time accounting + */ + p = m->proc; + if(p){ + nrun = 1; + p->pc = ur->pc; + if (p->state==Running) + p->time[p->insyscall]++; + } + nrun = (nrdy+nrun)*1000; + MACHP(0)->load = (MACHP(0)->load*19+nrun)/20; + + if(up == 0 || (ur->cs&0xffff) != UESEL || up->state != Running) + return; + + if(anyready()) + sched(); + + /* user profiling clock */ + spllo(); /* in case we fault */ + (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); + splhi(); +} + void clockinit(void) { @@ -50,7 +88,7 @@ clockinit(void) /* * set vector for clock interrupts */ - setvec(Clockvec, clock); + setvec(Clockvec, clock, 0); /* * make clock output a square wave with a 1/HZ period @@ -78,39 +116,3 @@ clockinit(void) if(delayloop == 0) delayloop = 1; } - -void -clock(Ureg *ur) -{ - Proc *p; - int nrun = 0; - - m->ticks++; - - checkalarms(); - mouseclock(); - - /* - * process time accounting - */ - p = m->proc; - if(p){ - nrun = 1; - p->pc = ur->pc; - if (p->state==Running) - p->time[p->insyscall]++; - } - nrun = (nrdy+nrun)*1000; - MACHP(0)->load = (MACHP(0)->load*19+nrun)/20; - - if(up == 0 || (ur->cs&0xffff) != UESEL || up->state != Running) - return; - - if(anyready()) - sched(); - - /* user profiling clock */ - spllo(); /* in case we fault */ - (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); - splhi(); -} diff --git a/pc/devether.c b/pc/devether.c index 72bdcabfa365cec85b0fd43d3957c6f97313d6a5..8afe838658f7a3eb455317c3eb0446a8230243e9 100644 --- a/pc/devether.c +++ b/pc/devether.c @@ -162,25 +162,6 @@ etherwrite(Chan *c, void *buf, long n, ulong offset) return n; } -static void -etherintr(Ureg *ur) -{ - int i, irq; - - /* - * Call all ethernet interrupt routines on this IRQ. - * Might be better if setvec() took an argument which - * was passed down to the interrupt routine when - * called. This would let us easily distinguish multiple - * controllers. A hack by any other name... - */ - irq = ur->trap-Int0vec; - for(i = 0; i < MaxEther; i++){ - if(ether[i] && ether[i]->irq == irq) - (*ether[i]->interrupt)(ether[i]); - } -} - static struct { char *type; int (*reset)(Ether*); @@ -222,15 +203,11 @@ etherreset(void) * IRQ2 doesn't really exist, it's used to gang the interrupt * controllers together. A device set to IRQ2 will appear on * the second interrupt controller as IRQ9. - * If there are multiple controllers on the same IRQ, only - * call setvec() for one of them, etherintr() will scan through - * all the controllers looking for those at the IRQ it was - * called with. This is a hack, see the comments in etherintr(). */ if(ctlr->irq == 2) ctlr->irq = 9; if((irqmask & (1<irq)) == 0){ - setvec(Int0vec+ctlr->irq, etherintr); + setvec(Int0vec+ctlr->irq, ctlr->interrupt, ctlr); irqmask |= 1<irq; } diff --git a/pc/devfloppy.c b/pc/devfloppy.c index a1cab6659fdcb7c8df378f4d844d527e326523b9..2ecd129f0ac67b66b2c5f1618b673636bfa53d6f 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -189,7 +189,7 @@ Controller fl; */ static int floppycmd(void); static void floppyeject(Drive*); -static void floppyintr(Ureg*); +static void floppyintr(Ureg*, void*); static void floppykproc(void*); static void floppyon(Drive*); static void floppyoff(Drive*); @@ -304,7 +304,7 @@ floppyreset(void) * first operation will recalibrate */ fl.confused = 1; - setvec(Floppyvec, floppyintr); + setvec(Floppyvec, floppyintr, 0); } void @@ -791,7 +791,7 @@ floppywait(void) { tsleep(&fl.r, cmddone, 0, 5000); if(!cmddone(0)){ - floppyintr(0); + floppyintr(0, 0); fl.confused = 1; } } @@ -1119,9 +1119,9 @@ floppyformat(Drive *dp, char *params) } static void -floppyintr(Ureg *ur) +floppyintr(Ureg *ur, void *arg) { - USED(ur); + USED(ur, arg); switch(fl.cmd[0]&~Fmulti){ case Fread: case Fwrite: diff --git a/pc/devhard.c b/pc/devhard.c index da3627193d8a791e345f45e21325f1665ae3de61..ec8b6ebce42515d77096caa925ec695f3d70d89e 100644 --- a/pc/devhard.c +++ b/pc/devhard.c @@ -121,7 +121,7 @@ struct Controller Controller *hardc; Drive *hard; -static void hardintr(Ureg*); +static void hardintr(Ureg*, void*); static long hardxfer(Drive*, Partition*, int, long, long, char*); static void hardident(Drive*); static void hardsetbuf(Drive*, int); @@ -194,7 +194,7 @@ hardreset(void) cp->lastcmd = cp->cmd; cp->cmd = 0; cp->pbase = Pbase + (cp-hardc)*8; /* BUG!! guessing */ - setvec(Hardvec + (cp-hardc)*8, hardintr); /* BUG!! guessing */ + setvec(Hardvec + (cp-hardc)*8, hardintr, 0); /* BUG!! guessing */ } } } @@ -909,18 +909,18 @@ hardpart(Drive *dp) * we get an interrupt for every sector transferred */ static void -hardintr(Ureg *ur) +hardintr(Ureg *ur, void *arg) { Controller *cp; Drive *dp; long loop; char *addr; - USED(ur); + USED(ur, arg); /* * BUG!! if there is ever more than one controller, we need a way to - * distinguish which interrupted + * distinguish which interrupted (use arg). */ cp = &hardc[0]; dp = cp->dp; diff --git a/pc/devuart.c b/pc/devuart.c deleted file mode 100644 index 2575cf488c735157fe903557569be2aa4dcf1425..0000000000000000000000000000000000000000 --- a/pc/devuart.c +++ /dev/null @@ -1,891 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include "devtab.h" -#define nelem(x) (sizeof(x)/sizeof(x[0])) -/* - * Driver for an NS16450 serial port - */ -enum -{ - /* - * register numbers - */ - Data= 0, /* xmit/rcv buffer */ - Iena= 1, /* interrdpt enable */ - Ircv= (1<<0), /* for char rcv'd */ - Ixmt= (1<<1), /* for xmit buffer empty */ - Irstat=(1<<2), /* for change in rcv'er status */ - Imstat=(1<<3), /* for change in modem status */ - Istat= 2, /* interrdpt flag (read) */ - Tctl= 2, /* test control (write) */ - Format= 3, /* byte format */ - Bits8= (3<<0), /* 8 bits/byte */ - Stop2= (1<<2), /* 2 stop bits */ - Pena= (1<<3), /* generate parity */ - Peven= (1<<4), /* even parity */ - Pforce=(1<<5), /* force parity */ - Break= (1<<6), /* generate a break */ - Dra= (1<<7), /* address the divisor */ - Mctl= 4, /* modem control */ - Dtr= (1<<0), /* data terminal ready */ - Rts= (1<<1), /* request to send */ - Ri= (1<<2), /* ring */ - Inton= (1<<3), /* turn on interrdpts */ - Loop= (1<<4), /* loop back */ - Lstat= 5, /* line status */ - Inready=(1<<0), /* receive buffer full */ - Oerror=(1<<1), /* receiver overrun */ - Perror=(1<<2), /* receiver parity error */ - Ferror=(1<<3), /* rcv framing error */ - Outready=(1<<5), /* output buffer full */ - Mstat= 6, /* modem status */ - Ctsc= (1<<0), /* clear to send changed */ - Dsrc= (1<<1), /* data set ready changed */ - Rire= (1<<2), /* rising edge of ring indicator */ - Dcdc= (1<<3), /* data carrier detect changed */ - Cts= (1<<4), /* complement of clear to send line */ - Dsr= (1<<5), /* complement of data set ready line */ - Ring= (1<<6), /* complement of ring indicator line */ - Dcd= (1<<7), /* complement of data carrier detect line */ - Scratch=7, /* scratchpad */ - Dlsb= 0, /* divisor lsb */ - Dmsb= 1, /* divisor msb */ - - Serial= 0, - Modem= 1, -}; - -typedef struct Uart Uart; -struct Uart -{ - QLock; - int port; - uchar sticky[8]; /* sticky write register values */ - int printing; /* true if printing */ - int enabled; - int cts; - - /* console interface */ - int special; /* can't use the stream interface */ - IOQ *iq; /* input character queue */ - IOQ *oq; /* output character queue */ - - /* stream interface */ - Queue *wq; /* write queue */ - Rendez r; /* kproc waiting for input */ - int kstarted; /* kproc started */ - - /* error statistics */ - ulong frame; - ulong overrun; -}; - -Uart uart[34]; -int Nuart; /* total no of uarts in the machine */ -int Nscard; /* number of serial cards */ -ISAConf scard[5]; /* configs for the serial card */ - -#define UartFREQ 1843200 - -#define uartwrreg(u,r,v) outb((u)->port + r, (u)->sticky[r] | (v)) -#define uartrdreg(u,r) inb((u)->port + r) - -void uartintr(Uart*); -void uartintr0(Ureg*); -void uartintr1(Ureg*); -void uartintr2(Ureg*); -void uartsetup(void); - -/* - * set the baud rate by calculating and setting the baudrate - * generator constant. This will work with fairly non-standard - * baud rates. - */ -void -uartsetbaud(Uart *dp, int rate) -{ - ulong brconst; - - brconst = (UartFREQ+8*rate-1)/(16*rate); - - uartwrreg(dp, Format, Dra); - outb(dp->port+Dmsb, (brconst>>8) & 0xff); - outb(dp->port+Dlsb, brconst & 0xff); - uartwrreg(dp, Format, 0); -} - -/* - * toggle DTR - */ -void -uartdtr(Uart *dp, int n) -{ - if(n) - dp->sticky[Mctl] |= Dtr; - else - dp->sticky[Mctl] &= ~Dtr; - uartwrreg(dp, Mctl, 0); -} - -/* - * toggle RTS - */ -void -uartrts(Uart *dp, int n) -{ - if(n) - dp->sticky[Mctl] |= Rts; - else - dp->sticky[Mctl] &= ~Rts; - uartwrreg(dp, Mctl, 0); -} - -/* - * send break - */ -void -uartbreak(Uart *dp, int ms) -{ - if(ms == 0) - ms = 200; - uartwrreg(dp, Format, Break); - tsleep(&dp->sleep, return0, 0, ms); - uartwrreg(dp, Format, 0); -} - -/* - * set bits/char - */ -void -uartbits(Uart *dp, int bits) -{ - if(bits < 5 || bits > 8) - error(Ebadarg); - dp->sticky[Format] &= ~3; - dp->sticky[Format] |= bits-5; - uartwrreg(dp, Format, 0); -} - -/* - * set parity - */ -void -uartparity(Uart *dp, int c) -{ - switch(c&0xff){ - case 'e': - dp->sticky[Format] |= Pena|Peven; - break; - case 'o': - dp->sticky[Format] &= ~Peven; - dp->sticky[Format] |= Pena; - break; - default: - dp->sticky[Format] &= ~(Pena|Peven); - break; - } - uartwrreg(dp, Format, 0); -} - -/* - * set stop bits - */ -void -uartstop(Uart *dp, int n) -{ - switch(n){ - case 1: - dp->sticky[Format] &= ~Stop2; - break; - case 2: - default: - dp->sticky[Format] |= Stop2; - break; - } - uartwrreg(dp, Format, 0); -} - -/* - * modem flow control on/off (rts/cts) - */ -void -uartmflow(Uart *dp, int n) -{ - if(n){ - dp->sticky[Iena] |= Imstat; - uartwrreg(dp, Iena, 0); - dp->cts = uartrdreg(dp, Mstat) & Cts; - } else { - dp->sticky[Iena] &= ~Imstat; - uartwrreg(dp, Iena, 0); - dp->cts = 1; - } -} - - -/* - * default is 9600 baud, 1 stop bit, 8 bit chars, no interrdpts, - * transmit and receive enabled, interrdpts disabled. - */ -void -uartsetup(void) -{ - Uart *dp; - int i, j, baddr; - static int already; - - if(already) - return; - already = 1; - - /* - * set port addresses - */ - uart[0].port = 0x3F8; - uart[1].port = 0x2F8; - setvec(Uart0vec, uartintr0); - setvec(Uart1vec, uartintr1); - Nuart = 2; - for(i = 0; isaconfig("serial", i, &scard[i]) && i < nelem(scard); i++) { - /* - * mem gives base port address for uarts - * irq is interrdpt - * port is the polling port - * size is the number of serial ports on the same polling port - */ - setvec(Int0vec + scard[i].irq, uartintr2); - baddr = scard[i].mem; - for(j=0, dp = &uart[Nuart]; j < scard[i].size; baddr += 8, j++, dp++) - dp->port = baddr; - Nuart += scard[i].size; - } - Nscard = i; - for(dp = uart; dp < &uart[Nuart]; dp++){ - memset(dp->sticky, 0, sizeof(dp->sticky)); - /* - * set rate to 9600 baud. - * 8 bits/character. - * 1 stop bit. - * interrdpts enabled. - */ - uartsetbaud(dp, 9600); - dp->sticky[Format] = Bits8; - uartwrreg(dp, Format, 0); - dp->sticky[Mctl] |= Inton; - uartwrreg(dp, Mctl, 0x0); - } -} - -/* - * Queue n characters for output; if queue is full, we lose characters. - * Get the output going if it isn't already. - */ -void -uartputs(IOQ *cq, char *s, int n) -{ - Uart *dp = cq->ptr; - int ch, x, multiprocessor; - int tries; - - multiprocessor = active.machs > 1; - x = splhi(); - if(multiprocessor) - lock(cq); - puts(cq, s, n); - if(dp->printing == 0){ - ch = getc(cq); - if(ch >= 0){ - dp->printing = 1; - for(tries = 0; tries<10000 && !(uartrdreg(dp, Lstat)&Outready); - tries++) - ; - outb(dp->port + Data, ch); - } - } - if(multiprocessor) - unlock(cq); - splx(x); -} - -/* - * a uart interrdpt (a damn lot of work for one character) - */ -void -uartintr(Uart *dp) -{ - int ch; - IOQ *cq; - int s, l, multiprocessor; - - multiprocessor = active.machs > 1; - for(;;){ - s = uartrdreg(dp, Istat); - switch(s){ - case 6: /* receiver line status */ - l = uartrdreg(dp, Lstat); - if(l & Ferror) - dp->frame++; - if(l & Oerror) - dp->overrun++; - break; - - case 4: /* received data available */ - ch = uartrdreg(dp, Data) & 0xff; - cq = dp->iq; - if(cq == 0) - break; - if(cq->putc) - (*cq->putc)(cq, ch); - else - putc(cq, ch); - break; - - case 2: /* transmitter empty */ - cq = dp->oq; - if(cq == 0) - break; - if(multiprocessor) - lock(cq); - if(dp->cts == 0) - dp->printing = 0; - else { - ch = getc(cq); - if(ch < 0){ - dp->printing = 0; - wakedp(&cq->r); - }else - outb(dp->port + Data, ch); - } - if(multiprocessor) - unlock(cq); - break; - - case 0: /* modem status */ - ch = uartrdreg(dp, Mstat); - if(ch & Ctsc){ - dp->cts = ch & Cts; - cq = dp->oq; - if(cq == 0) - break; - if(multiprocessor) - lock(cq); - if(dp->cts && dp->printing == 0){ - ch = getc(cq); - if(ch >= 0){ - dp->printing = 1; - outb(dp->port + Data, getc(cq)); - } else - wakedp(&cq->r); - } - if(multiprocessor) - unlock(cq); - } - break; - - default: - if(s&1) - return; - print("weird modem interrdpt #%2.2ux\n", s); - break; - } - } -} -void -uartintr0(Ureg *ur) -{ - USED(ur); - uartintr(&uart[0]); -} -void -uartintr1(Ureg *ur) -{ - USED(ur); - uartintr(&uart[1]); -} -void -uartintr2(Ureg *ur) -{ - uchar i, j, nuart, n; - - USED(ur); - for(nuart=2, j = 0; j < Nscard; nuart += scard[j].size, j++) { - n = ~inb(scard[j].port); - if(n == 0) - continue; - for(i = 0; n; i++){ - if(n & 1) - uartintr(&uart[nuart + i]); - n >>= 1; - } - } -} - -void -uartclock(void) -{ - Uart *dp; - IOQ *cq; - - for(dp = uart; dp < &uart[Nuart]; dp++){ - cq = dp->iq; - if(dp->wq && cangetc(cq)) - wakedp(&cq->r); - } -} - - -/* - * turn on a port's interrdpts. set DTR and RTS - */ -void -uartenable(Uart *dp) -{ - /* - * turn on power to the port - */ - if(dp == &uart[Modem]){ - if(modem(1) < 0) - print("can't turn on modem speaker\n"); - } else { - if(serial(1) < 0) - print("can't turn on serial port power\n"); - } - - /* - * set dp i/o routines - */ - if(dp->oq){ - dp->oq->puts = uartputs; - dp->oq->ptr = dp; - } - if(dp->iq){ - dp->iq->ptr = dp; - } - dp->enabled = 1; - - /* - * turn on interrdpts - */ - dp->sticky[Iena] = Ircv | Ixmt | Irstat; - uartwrreg(dp, Iena, 0); - - /* - * turn on DTR and RTS - */ - uartdtr(dp, 1); - uartrts(dp, 1); - - /* - * assume we can send - */ - dp->cts = 1; -} - -/* - * turn off the uart - */ -void -uartdisable(Uart *dp) -{ - - /* - * turn off interrdpts - */ - dp->sticky[Iena] = 0; - uartwrreg(dp, Iena, 0); - - /* - * revert to default settings - */ - dp->sticky[Format] = Bits8; - uartwrreg(dp, Format, 0); - - /* - * turn off DTR and RTS - */ - uartdtr(dp, 0); - uartrts(dp, 0); - dp->enabled = 0; - - /* - * turn off power - */ - if(dp == &uart[Modem]){ - if(modem(0) < 0) - print("can't turn off modem speaker\n"); - } else { - if(serial(0) < 0) - print("can't turn off serial power\n"); - } -} - -/* - * set dp an uart port as something other than a stream - */ -void -uartspecial(int port, IOQ *oq, IOQ *iq, int baud) -{ - Uart *dp = &uart[port]; - - uartsetup(); - dp->special = 1; - dp->oq = oq; - dp->iq = iq; - uartenable(dp); - if(baud) - uartsetbaud(dp, baud); - - if(iq){ - /* - * Stdpid HACK to undo a stdpid hack - */ - if(iq == &kbdq) - kbdq.putc = kbdcr2nl; - } -} - -static int uartputc(IOQ *, int); -static void uartstopen(Queue*, Stream*); -static void uartstclose(Queue*); -static void uartoput(Queue*, Block*); -static void uartkproc(void *); -Qinfo uartinfo = -{ - nullput, - uartoput, - uartstopen, - uartstclose, - "uart" -}; - -static void -uartstopen(Queue *q, Stream *s) -{ - Uart *dp; - char name[NAMELEN]; - - dp = &uart[s->id]; - dp->iq->putc = 0; - uartenable(dp); - - qlock(dp); - dp->wq = WR(q); - WR(q)->ptr = dp; - RD(q)->ptr = dp; - qunlock(dp); - - if(dp->kstarted == 0){ - dp->kstarted = 1; - sprint(name, "uart%d", s->id); - kproc(name, uartkproc, dp); - } -} - -static void -uartstclose(Queue *q) -{ - Uart *dp = q->ptr; - - if(dp->special) - return; - - uartdisable(dp); - - qlock(dp); - kprint("uartstclose: q=0x%ux, id=%d\n", q, dp-uart); - dp->wq = 0; - dp->iq->putc = 0; - WR(q)->ptr = 0; - RD(q)->ptr = 0; - qunlock(dp); -} - -static void -uartoput(Queue *q, Block *bp) -{ - Uart *dp = q->ptr; - IOQ *cq; - int n, m; - - if(dp == 0){ - freeb(bp); - return; - } - cq = dp->oq; - if(waserror()){ - freeb(bp); - nexterror(); - } - if(bp->type == M_CTL){ - while (cangetc(cq)) /* let output drain */ - sleep(&cq->r, cangetc, cq); - n = strtoul((char *)(bp->rptr+1), 0, 0); - switch(*bp->rptr){ - case 'B': - case 'b': - if(n <= 0) - error(Ebadctl); - uartsetbaud(dp, n); - break; - case 'D': - case 'd': - uartdtr(dp, n); - break; - case 'K': - case 'k': - uartbreak(dp, n); - break; - case 'L': - case 'l': - uartbits(dp, n); - break; - case 'm': - case 'M': - uartmflow(dp, n); - break; - case 'P': - case 'p': - uartparity(dp, *(bp->rptr+1)); - break; - case 'R': - case 'r': - uartrts(dp, n); - break; - case 'S': - case 's': - uartstop(dp, n); - break; - } - }else while((m = BLEN(bp)) > 0){ - while ((n = canputc(cq)) == 0){ - sleep(&cq->r, canputc, cq); - } - if(n > m) - n = m; - (*cq->puts)(cq, bp->rptr, n); - bp->rptr += n; - } - freeb(bp); - poperror(); -} - -/* - * process to send bytes dpstream for a port - */ -static void -uartkproc(void *a) -{ - Uart *dp = a; - IOQ *cq = dp->iq; - Block *bp; - int n; - ulong frame, overrun; - static ulong ints; - - frame = 0; - overrun = 0; - - if(waserror()) - print("uartkproc got an error\n"); - - for(;;){ - sleep(&cq->r, cangetc, cq); - if((ints++ & 0x1f) == 0) - lights((ints>>5)&1); - qlock(dp); - if(dp->wq == 0){ - cq->out = cq->in; - }else{ - n = cangetc(cq); - bp = allocb(n); - bp->flags |= S_DELIM; - bp->wptr += gets(cq, bp->wptr, n); - PUTNEXT(RD(dp->wq), bp); - } - qunlock(dp); - if(dp->frame != frame){ - kprint("uart%d: %d framing\n", dp-uart, dp->frame); - frame = dp->frame; - } - if(dp->overrun != overrun){ - kprint("uart%d: %d overruns\n", dp-uart, dp->overrun); - overrun = dp->overrun; - } - } -} - -enum{ - Qdir= 0, -}; - -Dirtab uartdir[2*nelem(uart)]; - -/* - * allocate the queues if no one else has - */ -void -uartreset(void) -{ - Uart *dp; - - uartsetup(); - for(dp = uart; dp < &uart[Nuart]; dp++){ - if(dp->special) - continue; - dp->iq = xalloc(sizeof(IOQ)); - initq(dp->iq); - dp->oq = xalloc(sizeof(IOQ)); - initq(dp->oq); - } -} - -void -uartinit(void) -{ - int i; - - for(i=0; i < 2*Nuart; ++i) { - if(i & 1 != 0) { - sprint(uartdir[i].name, "eia%dctl", i/2); - uartdir[i].qid.path = STREAMQID(i/2, Sctlqid); - } else { - sprint(uartdir[i].name, "eia%d", i/2); - uartdir[i].qid.path = STREAMQID(i/2, Sdataqid); - } - uartdir[i].length = 0; - uartdir[i].perm = 0666; - } -} - -Chan* -uartattach(char *dpec) -{ - return devattach('t', dpec); -} - -Chan* -uartclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -uartwalk(Chan *c, char *name) -{ - return devwalk(c, name, uartdir, Nuart * 2, devgen); -} - -void -uartstat(Chan *c, char *dir) -{ - int i; - - for(i=0; i < 2*Nuart; i += 2) - if(c->qid.path == uartdir[i].qid.path) { - streamstat(c, dir, uartdir[i].name, uartdir[i].perm); - return; - } - devstat(c, dir, uartdir, Nuart * 2, devgen); -} - -Chan* -uartopen(Chan *c, int omode) -{ - Uart *dp; - int i; - - dp = 0; - for(i=0; i < 2*Nuart; ++i) - if(c->qid.path == uartdir[i].qid.path) { - dp = &uart[i/2]; - break; - } - - if(dp && dp->special) - error(Einuse); - if((c->qid.path & CHDIR) == 0) - streamopen(c, &uartinfo); - return devopen(c, omode, uartdir, Nuart * 2, devgen); -} - -void -uartcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -uartclose(Chan *c) -{ - if(c->stream) - streamclose(c); -} - -long -uartstatus(Uart *dp, void *buf, long n, ulong offset) -{ - uchar mstat; - uchar tstat; - char str[128]; - - str[0] = 0; - tstat = dp->sticky[Mctl]; - mstat = uartrdreg(dp, Mstat); - if(mstat & Cts) - strcat(str, " cts"); - if(mstat & Dsr) - strcat(str, " dsr"); - if(mstat & Ring) - strcat(str, " ring"); - if(mstat & Dcd) - strcat(str, " dcd"); - if(tstat & Dtr) - strcat(str, " dtr"); - if(tstat & Dtr) - strcat(str, " rts"); - return readstr(offset, buf, n, str); -} - -long -uartread(Chan *c, void *buf, long n, ulong offset) -{ - int i; - long qpath; - - USED(offset); - qpath = c->qid.path & ~CHDIR; - if(qpath == Qdir) - return devdirread(c, buf, n, uartdir, Nuart * 2, devgen); - for(i=1; i < 2*Nuart; i += 2) - if(qpath == uartdir[i].qid.path) - return uartstatus(&uart[i/2], buf, n, offset); - return streamread(c, buf, n); -} - -long -uartwrite(Chan *c, void *va, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, va, n, 0); -} - -void -uartremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -uartwstat(Chan *c, char *dir) -{ - USED(c, dir); - error(Eperm); -} diff --git a/pc/ether509.c b/pc/ether509.c index 12fb8c0dec998cd0e1f0a6ccdd8768a80c36b4de..820b1090a5526c5ceadd3dae01d9141175b9499c 100644 --- a/pc/ether509.c +++ b/pc/ether509.c @@ -260,13 +260,18 @@ getdiag(Ether *ether) } static void -interrupt(Ether *ether) +interrupt(Ureg *ur, void *arg) { ushort status, diag; uchar txstatus, x; ulong port; + Ether *ether; + + USED(ur); + ether = arg; port = ether->port; + status = ins(port+Status); if(status & Failure){ diff --git a/pc/ether8390.c b/pc/ether8390.c index 4c61c290cd041de9c41cf5306492f76683fa5531..4131e0c9e37bb41af4d7465fe0ec94e62ee87d5e 100644 --- a/pc/ether8390.c +++ b/pc/ether8390.c @@ -554,12 +554,16 @@ overflow(Ether *ether) } static void -interrupt(Ether *ether) +interrupt(Ureg *ur, void *arg) { + Ether *ether; Dp8390 *dp8390; ulong port; uchar isr, r; + USED(ur); + + ether = arg; dp8390 = ether->private; port = dp8390->dp8390; diff --git a/pc/etherif.h b/pc/etherif.h index 364f94fbc21cdfbf16d01928931e7005cdb1d2c5..d92c53bd7d26d1ef56c59299c32d708c0534b4bf 100644 --- a/pc/etherif.h +++ b/pc/etherif.h @@ -9,7 +9,7 @@ struct Ether { void (*attach)(Ether*); /* filled in by reset routine */ long (*write)(Ether*, void*, long); - void (*interrupt)(Ether*); + void (*interrupt)(Ureg*, void*); void *private; Etherpkt tpkt; /* transmit buffer */ diff --git a/pc/fault386.c b/pc/fault386.c index 3fa6282ca3b7b6f75c1bee014e84e5906c264194..c7dd201e5d4d2a3411bdd636d31d98dcfd0bb549 100644 --- a/pc/fault386.c +++ b/pc/fault386.c @@ -8,8 +8,8 @@ int faulting; -void -fault386(Ureg *ur) +static void +fault386(Ureg *ur, void *arg) { ulong addr; int read; @@ -18,6 +18,8 @@ fault386(Ureg *ur) int insyscall; char buf[ERRLEN]; + USED(arg); + insyscall = up->insyscall; up->insyscall = 1; addr = getcr2(); @@ -43,5 +45,5 @@ print("fault: 0x%lux", addr); void faultinit(void) { - setvec(Faultvec, fault386); + setvec(Faultvec, fault386, 0); } diff --git a/pc/fns.h b/pc/fns.h index 7f58de3c9356409bda7d3ebffbe8bbde64f8babc..01505d14bc79c8cd823bbac0569f6e492c4eff57 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -5,7 +5,6 @@ void bbinit(void); void bigcursor(void); void bootargs(ulong); #define clearmmucache() /* 386 doesn't have one */ -void clock(Ureg*); void clockinit(void); void config(int); int cpuspeed(int); @@ -14,7 +13,6 @@ void dmaend(int); void dmainit(void); long dmasetup(int, void*, long, int); #define evenaddr(x) /* 386 doesn't care */ -void fault386(Ureg*); void faultinit(void); void fclock(Ureg*); void fclockinit(void); @@ -77,15 +75,13 @@ void puttr(ulong); void screeninit(void); void screenputs(char*, int); int serial(int); -void setvec(int, void (*)(Ureg*)); +void setvec(int, void (*)(Ureg*, void*), void*); +void syscall(Ureg*, void*); void systrap(void); void toscreen(void*); void touser(void*); void trapinit(void); int tas(void*); -void uartclock(void); -void uartintr0(Ureg*); -void uartspecial(int, IOQ*, IOQ*, int); void vgainit(void); #define waserror() (up->nerrlab++, setlabel(&up->errlab[up->nerrlab-1])) #define kmapperm(x) kmap(x) diff --git a/pc/kbd.c b/pc/kbd.c index 5da9d8be66b5ff34859fd0229670c5f4b1e32d80..1e96e6adf1d0170d5166b6ba243d9f606009e0e4 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -130,9 +130,6 @@ enum Ckbdint= (1<<0), /* kbd interrupt enable */ }; -static void kbdintr(Ureg*); -static void ctps2intr(Ureg*); - extern int m3mouseputc(IOQ*, int), mouseputc(IOQ*, int); /* @@ -235,41 +232,6 @@ i8042reset(void) outready(); } - -void -kbdinit(void) -{ - int c; - - kbdq = qopen(4*1024, 0, 0, 0); - - setvec(Kbdvec, kbdintr); - - /* wait for a quiescent controller */ - while((c = inb(Status)) & (Outbusy | Inready)) - if(c & Inready) - inb(Data); - - /* get current controller command byte */ - outb(Cmd, 0x20); - if(inready() < 0){ - print("kbdinit: can't read ccc\n"); - ccc = 0; - } else - ccc = inb(Data); - - /* enable kbd xfers and interrupts */ - ccc &= ~Ckbddis; - ccc |= Csf | Ckbdint | Cscs1; - if(outready() < 0) - print("kbd init failed\n"); - outb(Cmd, 0x60); - if(outready() < 0) - print("kbd init failed\n"); - outb(Data, ccc); - outready(); -} - /* * setup a serial mouse */ @@ -292,6 +254,60 @@ serialmouse(int port, char *type, int setspeed) mousetype = Mouseserial; } +/* + * ps/2 mouse message is three bytes + * + * byte 0 - 0 0 SDY SDX 1 M R L + * byte 1 - DX + * byte 2 - DY + * + * shift & left button is the same as middle button + */ +static int +ps2mouseputc(int c) +{ + static short msg[3]; + static int nb; + static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 }; + int buttons, dx, dy; + + /* + * check byte 0 for consistency + */ + if(nb==0 && (c&0xc8)!=0x08) + return 0; + + msg[nb] = c; + if(++nb == 3){ + nb = 0; + if(msg[0] & 0x10) + msg[1] |= 0xFF00; + if(msg[0] & 0x20) + msg[2] |= 0xFF00; + + buttons = b[(msg[0]&7) | (shift ? 8 : 0)] | keybuttons; + dx = msg[1]; + dy = -msg[2]; + mousetrack(buttons, dx, dy); + } + return 0; +} + +static void +ctps2intr(Ureg *ur, void *arg) +{ + uchar c; + + USED(ur, arg); + c = inb(ctport + CTstatus); + if(c & Error) + return; + if((c & Rready) == 0) + return; + c = inb(ctport + CTdata); + ps2mouseputc(c); +} + static void nop(void){}; /* @@ -328,7 +344,7 @@ ct82c710(void) outb(0x390, 0xf); nop(); nop(); outb(0x391, 0xf); - setvec(Mousevec, ctps2intr); + setvec(Mousevec, ctps2intr, 0); /* enable for interrupts */ c = inb(ctport + CTstatus); @@ -340,146 +356,11 @@ ct82c710(void) return 0; } -/* - * set up a ps2 mouse - */ -static void -ps2mouse(void) -{ - int x; - - if(mousetype) - error(Emouseset); - - if(ct82c710() == 0) - return; - - /* enable kbd/mouse xfers and interrupts */ - setvec(Mousevec, kbdintr); - x = splhi(); - ccc &= ~Cmousedis; - ccc |= Cmouseint; - if(outready() < 0) - print("mouse init failed\n"); - outb(Cmd, 0x60); - if(outready() < 0) - print("mouse init failed\n"); - outb(Data, ccc); - if(outready() < 0) - print("mouse init failed\n"); - outb(Cmd, 0xA8); - if(outready() < 0) - print("mouse init failed\n"); - - /* make mouse streaming, enabled */ - mousecmd(0xEA); - mousecmd(0xF4); - splx(x); - - mousetype = MousePS2; -} - -/* - * ps/2 mouse message is three bytes - * - * byte 0 - 0 0 SDY SDX 1 M R L - * byte 1 - DX - * byte 2 - DY - * - * shift & left button is the same as middle button - */ -static int -ps2mouseputc(int c) -{ - static short msg[3]; - static int nb; - static uchar b[] = {0, 1, 4, 5, 2, 3, 6, 7, 0, 1, 2, 5, 2, 3, 6, 7 }; - int buttons, dx, dy; - - /* - * check byte 0 for consistency - */ - if(nb==0 && (c&0xc8)!=0x08) - return 0; - - msg[nb] = c; - if(++nb == 3){ - nb = 0; - if(msg[0] & 0x10) - msg[1] |= 0xFF00; - if(msg[0] & 0x20) - msg[2] |= 0xFF00; - - buttons = b[(msg[0]&7) | (shift ? 8 : 0)] | keybuttons; - dx = msg[1]; - dy = -msg[2]; - mousetrack(buttons, dx, dy); - } - return 0; -} - -/* - * set/change mouse configuration - */ -void -mousectl(char *arg) -{ - int n, x; - char *field[3]; - - n = getfields(arg, field, 3, ' '); - if(strncmp(field[0], "serial", 6) == 0){ - switch(n){ - case 1: - serialmouse(atoi(field[0]+6), 0, 1); - break; - case 2: - serialmouse(atoi(field[1]), 0, 0); - break; - case 3: - default: - serialmouse(atoi(field[1]), field[2], 0); - break; - } - } else if(strcmp(field[0], "ps2") == 0){ - ps2mouse(); - } else if(strcmp(field[0], "accelerated") == 0){ - switch(mousetype){ - case MousePS2: - x = splhi(); - mousecmd(0xE7); - splx(x); - break; - } - } else if(strcmp(field[0], "linear") == 0){ - switch(mousetype){ - case MousePS2: - x = splhi(); - mousecmd(0xE6); - splx(x); - break; - } - } else if(strcmp(field[0], "res") == 0){ - if(n < 2) - n = 1; - else - n = atoi(field[1]); - switch(mousetype){ - case MousePS2: - x = splhi(); - mousecmd(0xE8); - mousecmd(n); - splx(x); - break; - } - } -} - /* * keyboard interrupt */ -int -kbdintr0(void) +static void +kbdintr(Ureg *ur, void *arg) { int s, c, i, nk; static int esc1, esc2; @@ -490,12 +371,14 @@ kbdintr0(void) static uchar kc[5]; int keyup; + USED(ur, arg); + /* * get status */ s = inb(Status); if(!(s&Inready)) - return -1; + return; /* * get the character @@ -507,7 +390,7 @@ kbdintr0(void) */ if(s & Minready){ ps2mouseputc(c); - return 0; + return; } /* @@ -515,17 +398,17 @@ kbdintr0(void) */ if(c == 0xe0){ esc1 = 1; - return 0; + return; } else if(c == 0xe1){ esc2 = 2; - return 0; + return; } keyup = c&0x80; c &= 0x7f; if(c > sizeof kbtab){ print("unknown key %ux\n", c|keyup); - return 0; + return; } if(esc1){ @@ -533,7 +416,7 @@ kbdintr0(void) esc1 = 0; } else if(esc2){ esc2--; - return 0; + return; } else if(shift) c = kbtabshift[c]; else @@ -554,7 +437,7 @@ kbdintr0(void) ctl = 0; break; } - return 0; + return; } /* @@ -596,48 +479,155 @@ kbdintr0(void) kbdputc(kbdq, c); break; } - return 0; + return; } else { switch(c){ case Caps: caps ^= 1; - return 0; + return; case Num: num ^= 1; - return 0; + return; case Shift: mouseshifted = shift = 1; - return 0; + return; case Latin: lstate = 1; - return 0; + return; case Ctrl: ctl = 1; - return 0; + return; } } kbdputc(kbdq, c); - return 0; } +/* + * set up a ps2 mouse + */ +static void +ps2mouse(void) +{ + int x; + + if(mousetype) + error(Emouseset); + + if(ct82c710() == 0) + return; + + /* enable kbd/mouse xfers and interrupts */ + setvec(Mousevec, kbdintr, 0); + x = splhi(); + ccc &= ~Cmousedis; + ccc |= Cmouseint; + if(outready() < 0) + print("mouse init failed\n"); + outb(Cmd, 0x60); + if(outready() < 0) + print("mouse init failed\n"); + outb(Data, ccc); + if(outready() < 0) + print("mouse init failed\n"); + outb(Cmd, 0xA8); + if(outready() < 0) + print("mouse init failed\n"); + + /* make mouse streaming, enabled */ + mousecmd(0xEA); + mousecmd(0xF4); + splx(x); + + mousetype = MousePS2; +} + +/* + * set/change mouse configuration + */ void -kbdintr(Ureg *ur) +mousectl(char *arg) { - USED(ur); - kbdintr0(); + int n, x; + char *field[3]; + + n = getfields(arg, field, 3, ' '); + if(strncmp(field[0], "serial", 6) == 0){ + switch(n){ + case 1: + serialmouse(atoi(field[0]+6), 0, 1); + break; + case 2: + serialmouse(atoi(field[1]), 0, 0); + break; + case 3: + default: + serialmouse(atoi(field[1]), field[2], 0); + break; + } + } else if(strcmp(field[0], "ps2") == 0){ + ps2mouse(); + } else if(strcmp(field[0], "accelerated") == 0){ + switch(mousetype){ + case MousePS2: + x = splhi(); + mousecmd(0xE7); + splx(x); + break; + } + } else if(strcmp(field[0], "linear") == 0){ + switch(mousetype){ + case MousePS2: + x = splhi(); + mousecmd(0xE6); + splx(x); + break; + } + } else if(strcmp(field[0], "res") == 0){ + if(n < 2) + n = 1; + else + n = atoi(field[1]); + switch(mousetype){ + case MousePS2: + x = splhi(); + mousecmd(0xE8); + mousecmd(n); + splx(x); + break; + } + } } void -ctps2intr(Ureg *ur) +kbdinit(void) { - uchar c; + int c; - USED(ur); - c = inb(ctport + CTstatus); - if(c & Error) - return; - if((c & Rready) == 0) - return; - c = inb(ctport + CTdata); - ps2mouseputc(c); + kbdq = qopen(4*1024, 0, 0, 0); + + setvec(Kbdvec, kbdintr, 0); + + /* wait for a quiescent controller */ + while((c = inb(Status)) & (Outbusy | Inready)) + if(c & Inready) + inb(Data); + + /* get current controller command byte */ + outb(Cmd, 0x20); + if(inready() < 0){ + print("kbdinit: can't read ccc\n"); + ccc = 0; + } else + ccc = inb(Data); + + /* enable kbd xfers and interrupts */ + ccc &= ~Ckbddis; + ccc |= Csf | Ckbdint | Cscs1; + if(outready() < 0) + print("kbd init failed\n"); + outb(Cmd, 0x60); + if(outready() < 0) + print("kbd init failed\n"); + outb(Data, ccc); + outready(); } diff --git a/pc/main.c b/pc/main.c index fd4225f4e24f29ce6f62ddec79dd1152cb2ff1ac..4567e8b476a93a6eb9a4c1ecf3dc0531381c3045 100644 --- a/pc/main.c +++ b/pc/main.c @@ -413,13 +413,15 @@ char *mathmsg[] = * math coprocessor error */ void -matherror(Ureg *ur) +matherror(Ureg *ur, void *arg) { ulong status; int i; char *msg; char note[ERRLEN]; + USED(arg); + /* * a write cycle to port 0xF0 clears the interrupt latch attached * to the error# line from the 387 @@ -453,9 +455,9 @@ matherror(Ureg *ur) * math coprocessor emulation fault */ void -mathemu(Ureg *ur) +mathemu(Ureg *ur, void *arg) { - USED(ur); + USED(ur, arg); switch(up->fpstate){ case FPinit: fpinit(); @@ -475,9 +477,9 @@ mathemu(Ureg *ur) * math coprocessor segment overrun */ void -mathover(Ureg *ur) +mathover(Ureg *ur, void *arg) { - USED(ur); + USED(ur, arg); print("sys: fp: math overrun pc 0x%lux pid %d\n", ur->pc, up->pid); pexit("math overrun", 0); } @@ -485,10 +487,10 @@ print("sys: fp: math overrun pc 0x%lux pid %d\n", ur->pc, up->pid); void mathinit(void) { - setvec(Matherr1vec, matherror); - setvec(Matherr2vec, matherror); - setvec(Mathemuvec, mathemu); - setvec(Mathovervec, mathover); + setvec(Matherr1vec, matherror, 0); + setvec(Matherr2vec, matherror, 0); + setvec(Mathemuvec, mathemu, 0); + setvec(Mathovervec, mathover, 0); } /* diff --git a/pc/mmu.c b/pc/mmu.c index 80caa5dfc323c3f7ca28695f8f91ebe44a35d13a..9d2d15300f60381aad6db0be93acdf74fe2172d6 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -227,11 +227,9 @@ mmuswitch(Proc *p) taskswitch(ktoppg.pa, (ulong)(p->kstack+KSTACK)); } -void +static void simpleputpage(Page *pg) { - Rendez *r; - if(pg->ref != 1) panic("simpleputpage"); @@ -247,10 +245,9 @@ simpleputpage(Page *pg) palloc.head = pg; pg->prev = 0; - palloc.freecol[pg->color]++; - r = &palloc.r[pg->color]; - if(r->p != 0) - wakeup(r); + palloc.freecount++; + if(palloc.r.p != 0) + wakeup(&palloc.r); } /* diff --git a/pc/trap.c b/pc/trap.c index 3be0d4c4fc29606c0bad8c6e81e5f39f3613c979..f58baecf1ccf24f2ca6ff8812cc7e702910809a9 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -48,7 +48,8 @@ int badintr[16]; typedef struct Handler Handler; struct Handler { - void (*r)(void*); + void (*r)(Ureg*, void*); + void *arg; Handler *next; }; @@ -68,7 +69,7 @@ sethvec(int v, void (*r)(void), int type, int pri) } void -setvec(int v, void (*r)(Ureg*)) +setvec(int v, void (*r)(Ureg*, void*), void *arg) { Handler *h; @@ -78,6 +79,7 @@ setvec(int v, void (*r)(Ureg*)) h = &halloc.h[halloc.free++]; h->next = halloc.ivec[v]; h->r = r; + h->arg = arg; halloc.ivec[v] = h; unlock(&halloc); @@ -94,10 +96,12 @@ setvec(int v, void (*r)(Ureg*)) } void -debugbpt(Ureg *ur) +debugbpt(Ureg *ur, void *arg) { char buf[ERRLEN]; + USED(arg); + if(up == 0) panic("kernel bpt"); /* restore pc to instruction that caused the trap */ @@ -164,9 +168,9 @@ trapinit(void) * system calls and break points */ sethvec(Syscallvec, intr64, SEGIG, 3); - setvec(Syscallvec, (void (*)(Ureg*))syscall); + setvec(Syscallvec, syscall, 0); sethvec(Bptvec, intr3, SEGIG, 3); - setvec(Bptvec, debugbpt); + setvec(Bptvec, debugbpt, 0); /* * tell the hardware where the table is (and how long) @@ -223,7 +227,7 @@ Proc *lastup; /* - * All trapscome here. It is slower to have all traps call trap() rather than + * All traps come here. It is slower to have all traps call trap() rather than * directly vectoring the handler. However, this avoids a lot of code duplication * and possible bugs. */ @@ -295,7 +299,7 @@ lastup = up; /* there may be multiple handlers on one interrupt level */ do { - (*h->r)(ur); + (*h->r)(ur, h->arg); h = h->next; } while(h); @@ -387,13 +391,15 @@ dumpstack(void) /* * syscall is called spllo() */ -long -syscall(Ureg *ur) +void +syscall(Ureg *ur, void *arg) { ulong sp; long ret; int i; + USED(arg); + up->insyscall = 1; up->pc = ur->pc; if((ur->cs)&0xffff == KESEL) @@ -455,8 +461,6 @@ syscall(Ureg *ur) splhi(); /* avoid interrupts during the iret */ if(up->scallnr!=RFORK && (up->procctl || up->nnote)) notify(ur); - - return ret; } /* diff --git a/port/crc_16.h b/port/crc_16.h deleted file mode 100644 index 9a5ad04f4919762732d82919c54bb5298db8b54b..0000000000000000000000000000000000000000 --- a/port/crc_16.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * CRC 0120001 - */ - 0x0, 0xc0c1, 0xc181, 0x140, 0xc301, 0x3c0, 0x280, 0xc241, - 0xc601, 0x6c0, 0x780, 0xc741, 0x500, 0xc5c1, 0xc481, 0x440, - 0xcc01, 0xcc0, 0xd80, 0xcd41, 0xf00, 0xcfc1, 0xce81, 0xe40, - 0xa00, 0xcac1, 0xcb81, 0xb40, 0xc901, 0x9c0, 0x880, 0xc841, - 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, - 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, - 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, - 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, - 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, - 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, - 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, - 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, - 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, - 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, - 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, - 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, - 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, - 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, - 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, - 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, - 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, - 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, - 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, - 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, - 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, - 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, - 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, - 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, - 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, - 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, - 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, - 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 diff --git a/port/devbit.c b/port/devbit.c deleted file mode 100644 index 3d4b6bb53144a87cd2d0e98b27da75c708cce1dd..0000000000000000000000000000000000000000 --- a/port/devbit.c +++ /dev/null @@ -1,2304 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include -#include -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -#include "devtab.h" - -/* - * Some monochrome screens are reversed from what we like: - * We want 0's bright and 1's dark. - * Indexed by an Fcode, these compensate for the source bitmap being wrong - * (exchange S rows) and destination (exchange D columns and invert result) - */ -int flipS[] = { - 0x0, 0x4, 0x8, 0xC, 0x1, 0x5, 0x9, 0xD, - 0x2, 0x6, 0xA, 0xE, 0x3, 0x7, 0xB, 0xF -}; - -int flipD[] = { - 0xF, 0xD, 0xE, 0xC, 0x7, 0x5, 0x6, 0x4, - 0xB, 0x9, 0xA, 0x8, 0x3, 0x1, 0x2, 0x0, -}; - -int flipping; /* are flip tables being used to transform Fcodes? */ - -/* - * Device (#b/bitblt) is exclusive use on open, so no locks are necessary - * for i/o - */ - -/* - * Arena is a word containing N, followed by a pointer to the Arena, - * followed by a pointer to the Bitmap, followed by N words. - * The bitmap pointer is zero if block is free. - * bit.map is an array of pointers to GBitmaps. The GBitmaps are - * freed individually and their corresponding entries in bit.map are zeroed. - * The index into bit.map is the Bitmap id as seen in libg. Subfonts and - * fonts are handled similarly. - */ - -typedef struct Arena Arena; -struct Arena -{ - ulong *words; /* storage */ - ulong *wfree; /* pointer to next free word */ - ulong nwords; /* total in arena */ - int nbusy; /* number of busy blocks */ -}; - -typedef struct BSubfont BSubfont; -struct BSubfont -{ - GSubfont; - int ref; /* number of times this subfont is open */ - ulong qid[2]; /* unique id used as a cache tag */ -}; - -extern GSubfont *defont; - BSubfont *bdefont; - BSubfont bdefont0; - - -struct -{ - Ref; - QLock; - GBitmap **map; /* indexed array */ - int nmap; /* number allocated */ - GFont **font; /* indexed array */ - int nfont; /* number allocated */ - BSubfont**subfont; /* indexed array */ - int nsubfont; /* number allocated */ - Arena *arena; /* array */ - int narena; /* number allocated */ - int mouseopen; /* flag: mouse open */ - int bitbltopen; /* flag: bitblt open */ - int bid; /* last allocated bitmap id */ - int subfid; /* last allocated subfont id */ - int cacheid; /* last cached subfont id */ - int fid; /* last allocated font id */ - int init; /* freshly opened; init message pending */ - int rid; /* read bitmap id */ - int rminy; /* read miny */ - int rmaxy; /* read maxy */ - int mid; /* colormap read bitmap id */ -}bit; - -#define DMAP 16 /* delta increase in size of arrays */ -#define FREE 0x80000000 - -void bitcompact(void); -int bitalloc(Rectangle, int); -void bitfree(GBitmap*); -void fontfree(GFont*); -void subfontfree(BSubfont*, int); -void arenafree(Arena*); -void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode); -void bitloadchar(GFont*, int, GSubfont*, int); -extern GBitmap gscreen; - -typedef struct Mouseinfo Mouseinfo; -typedef struct Cursorinfo Cursorinfo; - -struct Mouseinfo -{ - /* - * First three fields are known in some l.s's - */ - int dx; - int dy; - int track; /* l.s has updated dx & dy */ - Mouse; - int redraw; /* update cursor on screen */ - ulong counter; /* increments every update */ - ulong lastcounter; /* value when /dev/mouse read */ - Rendez r; -}; - -struct Cursorinfo -{ - Cursor; - Lock; - int visible; /* on screen */ - int disable; /* from being used */ - Rectangle r; /* location */ -}; - -Mouseinfo mouse; -Cursorinfo cursor; -int mouseshifted; -int mousetype; -int islittle; -int hwcurs; - -Cursor arrow = -{ - {-1, -1}, - {0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0x00, - 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0, - 0xE7, 0xF0, 0xE3, 0xF8, 0xC1, 0xFC, 0x00, 0xFE, - 0x00, 0x7F, 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, - }, - {0x00, 0x00, 0x7F, 0xC0, 0x7F, 0x00, 0x7C, 0x00, - 0x7E, 0x00, 0x7F, 0x00, 0x6F, 0x80, 0x67, 0xC0, - 0x43, 0xE0, 0x41, 0xF0, 0x00, 0xF8, 0x00, 0x7C, - 0x00, 0x3E, 0x00, 0x1C, 0x00, 0x08, 0x00, 0x00, - } -}; - -ulong setbits[16]; -GBitmap set = -{ - setbits, - 0, - 1, - 0, - {0, 0, 16, 16}, - {0, 0, 16, 16} -}; - -ulong clrbits[16]; -GBitmap clr = -{ - clrbits, - 0, - 1, - 0, - {0, 0, 16, 16}, - {0, 0, 16, 16} -}; - -ulong cursorbackbits[16*4]; -GBitmap cursorback = -{ - cursorbackbits, - 0, - 1, - 0, - {0, 0, 16, 16}, - {0, 0, 16, 16} -}; - -void Cursortocursor(Cursor*); -int mousechanged(void*); - -enum{ - Qdir, - Qbitblt, - Qmouse, - Qmousectl, - Qscreen, -}; - -Dirtab bitdir[]={ - "bitblt", {Qbitblt}, 0, 0666, - "mouse", {Qmouse}, 0, 0666, - "mousectl", {Qmousectl}, 0, 0220, - "screen", {Qscreen}, 0, 0444, -}; - -#define NBIT (sizeof bitdir/sizeof(Dirtab)) -#define NINFO 8192 /* max chars per subfont; sanity check only */ -#define HDR 3 - -void -lockedupdate(void) -{ - qlock(&bit); - if(waserror()){ - qunlock(&bit); - return; - } - screenupdate(); - qunlock(&bit); - poperror(); -} - -void -bitfreeup(void) -{ - int i; - BSubfont *s; - - /* free unused subfonts and compact */ - for(i=0; iref==0){ - s->ref = 1; - s->qid[0] = ~0; /* force cleanup */ - subfontfree(s, i); - } - } - bitcompact(); -} - -void* -bitmalloc(ulong n) -{ - void *p; - - p = malloc(n); - if(p) - return p; - bitfreeup(); - return malloc(n); -} - -void -bitdebug(void) -{ - int i; - long l; - Arena *a; - - l = 0; - for(i=0; iwords){ - l += a->nwords; - print("%d: %ld bytes used; %ld total\n", i, - (a->wfree-a->words)*sizeof(ulong), - a->nwords*sizeof(ulong)); - } - } - print("arena: %ld bytes\n", l*sizeof(ulong)); - l = 0; - for(i=0; iqid[0], bit.subfont[i]->qid[1]); - l++; - } - print("%d subfonts\n", l); -} - -void -bitreset(void) -{ - int ws; - ulong r; - Arena *a; - - if(!conf.monitor) - return; - - memmove(&bdefont0, defont, sizeof(*defont)); - bdefont = &bdefont0; - bit.map = smalloc(DMAP*sizeof(GBitmap*)); - bit.nmap = DMAP; - getcolor(0, &r, &r, &r); - if(r == 0) - flipping = 1; - bit.bid = -1; - bit.subfid = -1; - bit.fid = -1; - bit.cacheid = -1; - bit.font = smalloc(DMAP*sizeof(GFont*)); - bit.nfont = DMAP; - bit.subfont = smalloc(DMAP*sizeof(BSubfont*)); - bit.nsubfont = DMAP; - bit.arena = smalloc(DMAP*sizeof(Arena)); - bit.narena = DMAP; - a = &bit.arena[0]; - /* - * Somewhat of a heuristic: start with three screensful and - * allocate single screensful dynamically if needed. - */ - - ws = BI2WD>>gscreen.ldepth; /* pixels per word */ - a->nwords = 3*(HDR + gscreen.r.max.y*gscreen.r.max.x/ws); - a->words = xalloc(a->nwords*sizeof(ulong)); - if(a->words == 0){ - /* try again */ - print("bitreset: allocating only 1 screenful\n"); - a->nwords /= 3; - a->words = a->words = xalloc(a->nwords*sizeof(ulong)); - if(a->words == 0) - panic("bitreset"); - } - a->wfree = a->words; - a->nbusy = 1; /* keep 0th arena from being freed */ - Cursortocursor(&arrow); -} - -/* - * screen bit depth changed, reset backup map for cursor - */ -void -bitdepth(void) -{ - cursoroff(1); - if(gscreen.ldepth > 3) - cursorback.ldepth = 0; - else{ - cursorback.ldepth = gscreen.ldepth; - cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5; - } - cursoron(1); -} - -void -bitinit(void) -{ - if(!conf.monitor) - return; - if(gscreen.ldepth > 3) - cursorback.ldepth = 0; - else{ - cursorback.ldepth = gscreen.ldepth; - cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5; - } - cursoron(1); -} - -Chan* -bitattach(char *spec) -{ - if(!conf.monitor) - error(Egreg); - return devattach('b', spec); -} - -Chan* -bitclone(Chan *c, Chan *nc) -{ - nc = devclone(c, nc); - if(c->qid.path != CHDIR) - incref(&bit); - return nc; -} - -int -bitwalk(Chan *c, char *name) -{ - return devwalk(c, name, bitdir, NBIT, devgen); -} - -void -bitstat(Chan *c, char *db) -{ - devstat(c, db, bitdir, NBIT, devgen); -} - -Chan* -bitopen(Chan *c, int omode) -{ - GBitmap *b; - - switch(c->qid.path){ - case CHDIR: - if(omode != OREAD) - error(Eperm); - break; - case Qmouse: - lock(&bit); - if(bit.mouseopen){ - unlock(&bit); - error(Einuse); - } - bit.mouseopen = 1; - bit.ref++; - unlock(&bit); - break; - case Qbitblt: - lock(&bit); - if(bit.bitbltopen || bit.mouseopen){ - unlock(&bit); - error(Einuse); - } - b = smalloc(sizeof(GBitmap)); - *b = gscreen; - bit.map[0] = b; /* bitmap 0 is screen */ - bit.subfont[0] = bdefont; /* subfont 0 is default */ - bit.subfont[0]->ref = 1; - bit.subfont[0]->qid[0] = 0; - bit.subfont[0]->qid[1] = 0; - bit.bid = -1; - bit.fid = -1; - bit.subfid = -1; - bit.cacheid = -1; - bit.rid = -1; - bit.mid = -1; - bit.init = 0; - bit.bitbltopen = 1; - Cursortocursor(&arrow); - unlock(&bit); - break; - default: - incref(&bit); - } - c->mode = openmode(omode); - c->flag |= COPEN; - c->offset = 0; - return c; -} - -void -bitcreate(Chan *c, char *name, int omode, ulong perm) -{ - if(!conf.monitor) - error(Egreg); - USED(c, name, omode, perm); - error(Eperm); -} - -void -bitremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -bitwstat(Chan *c, char *db) -{ - USED(c, db); - error(Eperm); -} - -void -bitclose(Chan *c) -{ - GBitmap *b, **bp, **ebp; - BSubfont *s, **sp, **esp; - GFont *f, **fp, **efp; - - if(c->qid.path!=CHDIR && (c->flag&COPEN)){ - lock(&bit); - if(c->qid.path == Qmouse) - bit.mouseopen = 0; - if(c->qid.path == Qbitblt) - bit.bitbltopen = 0; - if(--bit.ref == 0){ - ebp = &bit.map[bit.nmap]; - for(bp = bit.map; bpqid.path & CHDIR) - return devdirread(c, va, n, bitdir, NBIT, devgen); - - if(c->qid.path == Qmouse){ - /* - * mouse: - * 'm' 1 - * buttons 1 - * point 8 - * msec 4 - */ - if(n < 14) - error(Ebadblt); - while(mousechanged(0) == 0) - sleep(&mouse.r, mousechanged, 0); - lock(&cursor); - p = va; - p[0] = 'm'; - p[1] = mouse.buttons; - BPLONG(p+2, mouse.xy.x); - BPLONG(p+6, mouse.xy.y); - BPLONG(p+10, TK2MS(MACHP(0)->ticks)); - mouse.lastcounter = mouse.counter; - unlock(&cursor); - return 14; - } - if(c->qid.path == Qscreen){ - if(offset==0){ - if(n < 5*12) - error(Eio); - sprint(va, "%11d %11d %11d %11d %11d", - gscreen.ldepth, gscreen.r.min.x, - gscreen.r.min.y, gscreen.r.max.x, - gscreen.r.max.y); - return 5*12; - } - ws = 1<<(3-gscreen.ldepth); /* pixels per byte */ - l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws; - t = offset-5*12; - miny = t/l; /* unsigned computation */ - maxy = (t+n)/l; - if(miny >= gscreen.r.max.y) - return 0; - if(maxy >= gscreen.r.max.y) - maxy = gscreen.r.max.y; - n = 0; - p = va; - for(y=miny; yqid.path != Qbitblt) - error(Egreg); - - qlock(&bit); - if(waserror()){ - qunlock(&bit); - nexterror(); - } - p = va; - /* - * Fuss about and figure out what to say. - */ - if(bit.init){ - /* - * init: - * 'I' 1 - * ldepth 1 - * rectangle 16 - * clip rectangle 16 - * font info 3*12 - * fontchars 6*(bdefont->n+1) - */ - if(n < 34) - error(Ebadblt); - p[0] = 'I'; - p[1] = gscreen.ldepth; - BPLONG(p+2, gscreen.r.min.x); - BPLONG(p+6, gscreen.r.min.y); - BPLONG(p+10, gscreen.r.max.x); - BPLONG(p+14, gscreen.r.max.y); - BPLONG(p+18, gscreen.clipr.min.x); - BPLONG(p+22, gscreen.clipr.min.y); - BPLONG(p+26, gscreen.clipr.max.x); - BPLONG(p+30, gscreen.clipr.max.y); - if(n >= 34+3*12+6*(bdefont->n+1)){ - p += 34; - sprint((char*)p, "%11d %11d %11d ", bdefont->n, - bdefont->height, bdefont->ascent); - p += 3*12; - for(i=bdefont->info,j=0; j<=bdefont->n; j++,i++,p+=6){ - BPSHORT(p, i->x); - p[2] = i->top; - p[3] = i->bottom; - p[4] = i->left; - p[5] = i->width; - } - n = 34+3*12+6*(bdefont->n+1); - }else - n = 34; - bit.init = 0; - }else if(bit.bid > 0){ - /* - * allocate: - * 'A' 1 - * bitmap id 2 - */ - if(n < 3) - error(Ebadblt); - if(bit.bid<0 || bit.map[bit.bid]==0) - error(Ebadbitmap); - p[0] = 'A'; - BPSHORT(p+1, bit.bid); - bit.bid = -1; - n = 3; - }else if(bit.subfid > 0){ - /* - * allocate subfont: - * 'K' 1 - * subfont id 2 - */ - if(n<3 || bit.subfid<0) - error(Ebadblt); - s = bit.subfont[bit.subfid]; - if(s==0 || s->ref==0) - error(Ebadfont); - p[0] = 'K'; - BPSHORT(p+1, bit.subfid); - bit.subfid = -1; - n = 3; - }else if(bit.cacheid >= 0){ - /* - * check cache for subfont: - * 'J' 1 - * subfont id 2 - * font info 3*12 - * fontchars 6*(subfont->n+1) - */ - p[0] = 'J'; - if(bit.cacheid < 0) - error(Ebadfont); - s = bit.subfont[bit.cacheid]; - if(s==0 || s->ref==0) - error(Ebadfont); - if(n < 3+3*12+6*(s->n+1)) - error(Ebadblt); - BPSHORT(p+1, bit.cacheid); - p += 3; - sprint((char*)p, "%11d %11d %11d ", s->n, s->height, s->ascent); - p += 3*12; - for(i=s->info,j=0; j<=s->n; j++,i++,p+=6){ - BPSHORT(p, i->x); - p[2] = i->top; - p[3] = i->bottom; - p[4] = i->left; - p[5] = i->width; - } - n = 3+3*12+6*(s->n+1); - bit.cacheid = -1; - }else if(bit.fid >= 0){ - /* - * allocate font: - * 'N' 1 - * font id 2 - */ - if(n < 3) - error(Ebadblt); - if(bit.fid<0 || bit.font[bit.fid]==0) - error(Ebadfont); - p[0] = 'N'; - BPSHORT(p+1, bit.fid); - bit.fid = -1; - n = 3; - }else if(bit.mid >= 0){ - /* - * read colormap: - * data 12*(2**bitmapdepth) - */ - src = bit.map[bit.mid]; - if(src == 0) - error(Ebadbitmap); - l = (1<ldepth); - nw = 1 << l; - if(n < 12*nw) - error(Ebadblt); - for(j = 0; j < nw; j++){ - if(bit.mid == 0){ - getcolor(flipping? nw-j-1 : j, &rv, &gv, &bv); - }else{ - rv = j; - for(off = 32-l; off > 0; off -= l) - rv = (rv << l) | j; - gv = bv = rv; - } - BPLONG(p, rv); - BPLONG(p+4, gv); - BPLONG(p+8, bv); - p += 12; - } - bit.mid = -1; - n = 12*nw; - }else if(bit.rid >= 0){ - /* - * read bitmap: - * data bytewidth*(maxy-miny) - */ - src = bit.map[bit.rid]; - if(src == 0) - error(Ebadbitmap); - off = 0; - if(bit.rid == 0) - off = 1; - miny = bit.rminy; - maxy = bit.rmaxy; - if(miny>maxy || minyr.min.y || maxy>src->r.max.y) - error(Ebadblt); - ws = 1<<(3-src->ldepth); /* pixels per byte */ - /* set l to number of bytes of incoming data per scan line */ - if(src->r.min.x >= 0) - l = (src->r.max.x+ws-1)/ws - src->r.min.x/ws; - else{ /* make positive before divide */ - t = (-src->r.min.x)+ws-1; - t = (t/ws)*ws; - l = (t+src->r.max.x+ws-1)/ws; - } - if(n < l*(maxy-miny)) - error(Ebadblt); - if(off) - cursoroff(1); - n = 0; - p = va; - for(y=miny; yr.min.x, y)); - q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; - memmove(p, q, l); - if(islittle) - pixreverse(p, l, src->ldepth); - if(bit.rid==0 && flipping) - /* is screen, so must be word aligned */ - for(x=0; x 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) -{ - uchar *p, *q, *oq; - long m, v, miny, maxy, t, x, y; - 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; - Fcode fc; - Fontchar *fcp; - GBitmap *src, *dst; - BSubfont *f, *tf, **fp; - GFont *ff, **ffp; - GCacheinfo *gc; - char buf[64]; - - USED(offset); - - if(c->qid.path == CHDIR) - error(Eisdir); - - if(c->qid.path == Qmousectl){ - if(n >= sizeof(buf)) - n = sizeof(buf)-1; - strncpy(buf, va, n); - buf[n] = 0; - mousectl(buf); - return n; - } - - if(c->qid.path != Qbitblt) - error(Egreg); - - isoff = 0; - qlock(&bit); - if(waserror()){ - qunlock(&bit); - if(isoff) - cursoron(1); - nexterror(); - } - p = va; - m = n; - SET(src, dst, f, ff); - while(m > 0) - switch(*p){ - default: - pprint("bitblt request 0x%x\n", *p); - error(Ebadblt); - - case 'a': - /* - * allocate: - * 'a' 1 - * ldepth 1 - * Rectangle 16 - * next read returns allocated bitmap id - */ - if(m < 18) - error(Ebadblt); - v = *(p+1); - if(v > 3) /* BUG */ - error(Ebadblt); - rect.min.x = BGLONG(p+2); - rect.min.y = BGLONG(p+6); - rect.max.x = BGLONG(p+10); - rect.max.y = BGLONG(p+14); - if(Dx(rect) < 0 || Dy(rect) < 0) - error(Ebadblt); - bit.bid = bitalloc(rect, v); - m -= 18; - p += 18; - break; - - case 'b': - /* - * bitblt - * 'b' 1 - * dst id 2 - * dst Point 8 - * src id 2 - * src Rectangle 16 - * code 2 - */ - if(m < 31) - error(Ebadblt); - fc = BGSHORT(p+29) & 0xF; - v = BGSHORT(p+11); - if(v<0 || v>=bit.nmap || (src=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - if(v == 0){ - if(flipping) - fc = flipS[fc]; - off = 1; - } - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - pt.x = BGLONG(p+3); - pt.y = BGLONG(p+7); - rect.min.x = BGLONG(p+13); - rect.min.y = BGLONG(p+17); - rect.max.x = BGLONG(p+21); - rect.max.y = BGLONG(p+25); - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - gbitblt(dst, pt, src, rect, fc); - if(dst->base < endscreen) - mbbrect(Rpt(pt, add(pt, sub(rect.max, rect.min)))); - m -= 31; - p += 31; - break; - - case 'c': - /* - * cursorswitch - * 'c' 1 - * if one more byte, says whether to disable - * because of stupid lcd's (thank you bart) - * else - * nothing more: return to arrow; else - * Point 8 - * clr 32 - * set 32 - */ - if(m == 1){ - if(!isoff){ - cursoroff(1); - isoff = 1; - } - Cursortocursor(&arrow); - m -= 1; - p += 1; - break; - } - if(m == 2){ - if(p[1]){ /* make damn sure */ - cursor.disable = 0; - isoff = 1; - }else{ - cursoroff(1); - cursor.disable = 1; - } - m -= 2; - p += 2; - break; - } - if(m < 73) - error(Ebadblt); - curs.offset.x = BGLONG(p+1); - curs.offset.y = BGLONG(p+5); - memmove(curs.clr, p+9, 2*16); - memmove(curs.set, p+41, 2*16); - if(islittle){ - pixreverse(curs.clr, 2*16, 0); - pixreverse(curs.set, 2*16, 0); - } - if(!isoff){ - cursoroff(1); - isoff = 1; - } - Cursortocursor(&curs); - m -= 73; - p += 73; - break; - - case 'e': - /* - * polysegment - * - * 'e' 1 - * id 2 - * pt 8 - * value 1 - * code 2 - * n 2 - * pts 2*n - */ - if(m < 16) - error(Ebadblt); - l = BGSHORT(p+14); - if(m < 16+2*l) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - fc = BGSHORT(p+12) & 0xF; - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - pt1.x = BGLONG(p+3); - pt1.y = BGLONG(p+7); - t = p[11]; - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - p += 16; - m -= 16; - while(l > 0){ - pt2.x = pt1.x + (schar)p[0]; - pt2.y = pt1.y + (schar)p[1]; - gsegment(dst, pt1, pt2, t, fc); - if(dst->base < endscreen){ - mbbpt(pt1); - mbbpt(pt2); - } - pt1 = pt2; - p += 2; - m -= 2; - l--; - } - break; - - case 'f': - /* - * free - * 'f' 1 - * id 2 - */ - if(m < 3) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - bitfree(dst); - bit.map[v] = 0; - m -= 3; - p += 3; - break; - - case 'g': - /* - * free subfont - * 'g' 1 - * id 2 - */ - if(m < 3) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0 || f->ref==0) - error(Ebadfont); - subfontfree(f, v); - m -= 3; - p += 3; - break; - - case 'h': - /* - * free font - * 'h' 1 - * id 2 - */ - if(m < 3) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0) - error(Ebadfont); - fontfree(ff); - bit.font[v] = 0; - m -= 3; - p += 3; - break; - - case 'i': - /* - * init - * - * 'i' 1 - */ - bit.init = 1; - m -= 1; - p += 1; - break; - - case 'j': - /* - * subfont cache check - * - * 'j' 1 - * qid 8 - */ - if(m < 9) - error(Ebadblt); - q0 = BGLONG(p+1); - q1 = BGLONG(p+5); - i = 0; - if(q0 != ~0) - for(; iqid[0]==q0 && f->qid[1]==q1) - goto sfcachefound; - } - error(Esfnotcached); - - sfcachefound: - f->ref++; - bit.cacheid = i; - m -= 9; - p += 9; - break; - - case 'k': - /* - * allocate subfont - * 'k' 1 - * n 2 - * height 1 - * ascent 1 - * bitmap id 2 - * qid 8 - * fontchars 6*(n+1) - * next read returns allocated font id - */ - if(m < 15) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>NINFO || m<15+6*(v+1)) - error(Ebadblt); - for(i=1; iinfo = bitmalloc((v+1)*sizeof(Fontchar)); - if(f->info == 0){ - free(f); - error(Enomem); - } - bit.subfont[i] = f; - f->n = v; - f->height = p[3]; - f->ascent = p[4]; - f->qid[0] = BGLONG(p+7); - f->qid[1] = BGLONG(p+11); - /* check to see if already there, uncache if so */ - for(j=0; jqid[0]==f->qid[0] && tf->qid[1]==f->qid[1]){ - f->qid[0] = ~0; /* uncached */ - break; - } - } - f->ref = 1; - v = BGSHORT(p+5); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - f->bits = dst; - bit.map[v] = 0; /* subfont now owns bitmap */ - m -= 15; - p += 15; - fcp = f->info; - for(j=0; j<=f->n; j++,fcp++){ - fcp->x = BGSHORT(p); - fcp->top = p[2]; - fcp->bottom = p[3]; - fcp->left = p[4]; - fcp->width = p[5]; - fcp->top = p[2]; - p += 6; - m -= 6; - } - bit.subfid = i; - break; - - case 'l': - /* - * line segment - * - * 'l' 1 - * id 2 - * pt1 8 - * pt2 8 - * value 1 - * code 2 - */ - if(m < 22) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - fc = BGSHORT(p+20) & 0xF; - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - pt1.x = BGLONG(p+3); - pt1.y = BGLONG(p+7); - pt2.x = BGLONG(p+11); - pt2.y = BGLONG(p+15); - t = p[19]; - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - gsegment(dst, pt1, pt2, t, fc); - if(dst->base < endscreen){ - mbbpt(pt1); - mbbpt(pt2); - } - m -= 22; - p += 22; - break; - - case 'm': - /* - * read colormap - * - * 'm' 1 - * id 2 - */ - if(m < 3) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - bit.mid = v; - m -= 3; - p += 3; - break; - - case 'n': - /* - * allocate font - * 'n' 1 - * height 1 - * ascent 1 - * ldepth 2 - * ncache 2 - * next read returns allocated font id - */ - if(m < 7) - error(Ebadblt); - v = BGSHORT(p+3); - t = BGSHORT(p+5); - if(v<0 || t<0) - error(Ebadblt); - for(i=0; incache = t; - ff->cache = bitmalloc(t*sizeof(GCacheinfo)); - if(ff->cache == 0){ - free(ff); - error(Enomem); - } - bit.font[i] = ff; - ff = bit.font[i]; - ff->height = p[1]; - ff->ascent = p[2]; - ff->ldepth = v; - ff->width = 0; - ff->b = 0; - m -= 7; - p += 7; - bit.fid = i; - break; - - case 'p': - /* - * point - * - * 'p' 1 - * id 2 - * pt 8 - * value 1 - * code 2 - */ - if(m < 14) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - fc = BGSHORT(p+12) & 0xF; - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - pt1.x = BGLONG(p+3); - pt1.y = BGLONG(p+7); - t = p[11]; - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - gpoint(dst, pt1, t, fc); - if(dst->base < endscreen) - mbbpt(pt1); - m -= 14; - p += 14; - break; - - case 'q': - /* - * clip rectangle - * 'q' 1 - * id 2 - * rect 16 - */ - if(m < 19) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - rect.min.x = BGLONG(p+3); - rect.min.y = BGLONG(p+7); - rect.max.x = BGLONG(p+11); - rect.max.y = BGLONG(p+15); - if(rectclip(&rect, dst->r)) - dst->clipr = rect; - else - dst->clipr = dst->r; - m -= 19; - p += 19; - break; - - case 'r': - /* - * read - * 'r' 1 - * src id 2 - * miny 4 - * maxy 4 - */ - if(m < 11) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (src=bit.map[v])==0) - error(Ebadbitmap); - miny = BGLONG(p+3); - maxy = BGLONG(p+7); - if(miny>maxy || minyr.min.y || maxy>src->r.max.y) - error(Ebadblt); - bit.rid = v; - bit.rminy = miny; - bit.rmaxy = maxy; - p += 11; - m -= 11; - break; - - case 's': - /* - * string - * 's' 1 - * id 2 - * pt 8 - * font id 2 - * code 2 - * n 2 - * cache indices 2*n (not null terminated) - */ - if(m < 17) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - fc = BGSHORT(p+13) & 0xF; - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - pt.x = BGLONG(p+3); - pt.y = BGLONG(p+7); - v = BGSHORT(p+11); - if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0) - error(Ebadfont); - l = BGSHORT(p+15)*2; - p += 17; - m -= 17; - if(l > m) - error(Ebadblt); - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - bitstring(dst, pt, ff, p, l, fc); - if(dst->base < endscreen) - mbbrect(Rpt(pt, add(pt, bitstrsize(ff, p, l)))); - m -= l; - p += l; - break; - - case 't': - /* - * texture - * 't' 1 - * dst id 2 - * rect 16 - * src id 2 - * fcode 2 - */ - if(m < 23) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - fc = BGSHORT(p+21) & 0xF; - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - rect.min.x = BGLONG(p+3); - rect.min.y = BGLONG(p+7); - rect.max.x = BGLONG(p+11); - rect.max.y = BGLONG(p+15); - v = BGSHORT(p+19); - if(v<0 || v>=bit.nmap || (src=bit.map[v])==0) - error(Ebadbitmap); - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - gtexture(dst, rect, src, fc); - if(dst->base < endscreen) - mbbrect(rect); - m -= 23; - p += 23; - break; - - case 'v': - /* - * clear font cache and bitmap. - * if error, font is unchanged. - * 'v' 1 - * id 2 - * ncache 2 - * width 2 - */ - if(m < 7) - error(Ebadblt); - v = BGSHORT(p+1); - t = BGSHORT(p+3); - if(t<0 || v<0 || v>=bit.nfont || (ff=bit.font[v])==0) - error(Ebadblt); - x = BGSHORT(p+5); - i = bitalloc(Rect(0, 0, t*x, ff->height), ff->ldepth); - if(t != ff->ncache){ - gc = bitmalloc(t*sizeof(ff->cache[0])); - if(gc == 0){ - bitfree(bit.map[i]); - bit.map[i] = 0; - error(Enomem); - } - free(ff->cache); - ff->cache = gc; - ff->ncache = t; - }else{ - /* - * memset not necessary but helps avoid - * confusion if the cache is mishandled by the - * user. - */ - memset(ff->cache, 0, t*sizeof(ff->cache[0])); - } - if(ff->b) - bitfree(ff->b); - ff->b = bit.map[i]; - bit.map[i] = 0; /* disconnect it from GBitmap space */ - ff->width = x; - p += 7; - m -= 7; - break; - - case 'w': - /* - * write - * 'w' 1 - * dst id 2 - * miny 4 - * maxy 4 - * data bytewidth*(maxy-miny) - */ - if(m < 11) - error(Ebadblt); - v = BGSHORT(p+1); - if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - if(v == 0) - off = 1; - miny = BGLONG(p+3); - maxy = BGLONG(p+7); - if(miny>maxy || minyr.min.y || maxy>dst->r.max.y) - error(Ebadblt); - ws = 1<<(3-dst->ldepth); /* pixels per byte */ - /* set l to number of bytes of incoming data per scan line */ - if(dst->r.min.x >= 0) - l = (dst->r.max.x+ws-1)/ws - dst->r.min.x/ws; - else{ /* make positive before divide */ - t = (-dst->r.min.x)+ws-1; - t = (t/ws)*ws; - l = (t+dst->r.max.x+ws-1)/ws; - } - if(dst->base < endscreen) - mbbrect(Rect(dst->r.min.x, miny, dst->r.max.x, maxy)); - p += 11; - m -= 11; - if(m < l*(maxy-miny)) - error(Ebadblt); - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - for(y=miny; yr.min.x, y)); - q = oq + (dst->r.min.x&((sizeof(ulong))*ws-1))/ws; - memmove(q, p, l); - if(islittle) - pixreverse(q, l, dst->ldepth); - if(v==0 && flipping){ /* flip bits */ - /* we know it's all word aligned */ - lp = (ulong*)oq; - for(x=0; x=bit.nfont || (ff=bit.font[v])==0) - error(Ebadblt); - if(ff->b == 0) - error(Ebadbitmap); - l = BGSHORT(p+3); - if(l >= ff->ncache) - error(Ebadblt); - v = BGSHORT(p+5); - if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0 || f->ref==0) - error(Ebadfont); - nw = BGSHORT(p+7); - if(nw >= f->n) - error(Ebadblt); - bitloadchar(ff, l, f, nw); - p += 9; - m -= 9; - break; - - case 'z': - /* - * write the colormap - * - * 'z' 1 - * id 2 - * map 12*(2**bitmapdepth) - */ - if(m < 3) - error(Ebadblt); - v = BGSHORT(p+1); - if(v != 0) - error(Ebadbitmap); - m -= 3; - p += 3; - nw = 1 << (1 << gscreen.ldepth); - if(m < 12*nw) - error(Ebadblt); - ok = 1; - for(i = 0; i < nw; i++){ - ok &= setcolor(flipping ? ~i : i, BGLONG(p), BGLONG(p+4), BGLONG(p+8)); - p += 12; - m -= 12; - } - if(!ok){ - /* assume monochrome: possibly change flipping */ - l = BGLONG(p-12); - getcolor(nw-1, &rv, &rv, &rv); - flipping = (l != rv); - } - break; - } - - poperror(); - if(isoff) - cursoron(1); - screenupdate(); - qunlock(&bit); - return n; -} - -int -bitalloc(Rectangle rect, int ld) -{ - Arena *a, *ea, *aa; - GBitmap *b, **bp, **ep; - ulong l, ws, nw; - long t; - - ws = BI2WD>>ld; /* pixels per word */ - if(rect.min.x >= 0){ - l = (rect.max.x+ws-1)/ws; - l -= rect.min.x/ws; - }else{ /* make positive before divide */ - t = (-rect.min.x)+ws-1; - t = (t/ws)*ws; - l = (t+rect.max.x+ws-1)/ws; - } - nw = l*Dy(rect); - ea = &bit.arena[bit.narena]; - - /* first try easy fit */ - for(a=bit.arena; awords == 0) - continue; - if(a->wfree+HDR+nw <= a->words+a->nwords) - goto found; - } - - /* compact and try again */ - bitcompact(); - aa = 0; - for(a=bit.arena; awords == 0){ - if(aa == 0) - aa = a; - continue; - } - if(a->wfree+HDR+nw <= a->words+a->nwords) - goto found; - } - - /* need new arena */ - if(aa){ - a = aa; - a->nwords = HDR + (gscreen.r.max.y*gscreen.r.max.x)/ws; - if(a->nwords < HDR+nw) - a->nwords = HDR+nw; - a->words = xalloc(a->nwords*sizeof(ulong)); - if(a->words){ - a->wfree = a->words; - a->nbusy = 0; - goto found; - } - } - /* else can't grow list: bitmaps have backpointers */ - - bitfreeup(); - - for(a=bit.arena; awords == 0) - continue; - if(a->wfree+HDR+nw <= a->words+a->nwords) - goto found; - } - if(a == ea) - error(Enobitstore); - - found: - b = bitmalloc(sizeof(GBitmap)); - if(b == 0) - error(Enomem); - *a->wfree++ = nw; - *a->wfree++ = (ulong)a; - *a->wfree++ = (ulong)b; - memset(a->wfree, 0, nw*sizeof(ulong)); - b->base = a->wfree; - a->wfree += nw; - a->nbusy++; - b->zero = l*rect.min.y; - if(rect.min.x >= 0) - b->zero += rect.min.x/ws; - else - b->zero -= (-rect.min.x+ws-1)/ws; - b->zero = -b->zero; - b->width = l; - b->ldepth = ld; - b->r = rect; - b->clipr = rect; - b->cache = 0; - /* worth doing better than linear lookup? */ - ep = bit.map+bit.nmap; - for(bp=bit.map; bpbase != gscreen.base){ /* can't free screen memory */ - a = (Arena*)(b->base[-2]); - a->nbusy--; - if(a->nbusy == 0) - arenafree(a); - b->base[-1] = 0; - } - free(b); -} - -void -fontfree(GFont *f) -{ - if(f->b) - bitfree(f->b); - free(f->cache); - free(f); -} - -void -subfontfree(BSubfont *s, int i) -{ - if(s!=bdefont && s->ref>0){ /* don't free subfont 0, bdefont */ - s->ref--; - if(s->ref==0 && s->qid[0]==~0){ /* uncached */ - bitfree(s->bits); - free(s->info); - free(s); - bit.subfont[i] = 0; - } - } - return; -} - -void -arenafree(Arena *a) -{ - xfree(a->words); - a->words = 0; -} - -void -bitstring(GBitmap *bp, Point pt, GFont *f, uchar *p, long l, Fcode fc) -{ - int full; - Rectangle rect; - ushort r; - GCacheinfo *c; - int x; - Fcode clr; - - clr = 0; - full = (fc&~S)^(D&~S); /* result involves source */ - if(full){ - rect.min.y = 0; - rect.max.y = f->height; - /* set clr to result under fc if source pixel is zero */ - /* hard to do without knowing layout of bits, so we cheat */ - clr = (fc&3); /* fc&3 is result if source is zero */ - clr |= clr<<2; /* fc&(3<<2) is result if source is one */ - } - - while(l > 0){ - r = BGSHORT(p); - p += 2; - l -= 2; - if(r >= f->ncache) - continue; - c = &f->cache[r]; - if(!full){ - rect.min.y = c->top; - rect.max.y = c->bottom; - }else{ - if(c->left > 0) - gbitblt(bp, pt, bp, - Rect(pt.x, pt.y, pt.x+c->left, pt.y+f->height), - clr); - x = c->left+(c->xright-c->x); - if(x < c->width) - gbitblt(bp, Pt(pt.x+x, pt.y), bp, - Rect(pt.x+x, pt.y, pt.x+c->width, pt.y+f->height), - clr); - } - rect.min.x = c->x; - rect.max.x = c->xright; - gbitblt(bp, Pt(pt.x+c->left, pt.y+rect.min.y), f->b, rect, fc); - pt.x += c->width; - } -} - -void -bitloadchar(GFont *f, int ci, GSubfont *subf, int si) -{ - GCacheinfo *c; - Rectangle rect; - Fontchar *fi; - int y; - - c = &f->cache[ci]; - fi = &subf->info[si]; - /* careful about sign extension: top and bottom are uchars */ - y = fi->top + (f->ascent-subf->ascent); - if(y < 0) - y = 0; - c->top = y; - y = fi->bottom + (f->ascent-subf->ascent); - if(y < 0) - y = 0; - c->bottom = y; - c->width = fi->width; - c->left = fi->left; - c->x = ci*f->width; - c->xright = c->x + ((fi+1)->x - fi->x); - rect.min.y = 0; - rect.max.y = f->height; - rect.min.x = c->x; - rect.max.x = c->x+f->width; - gbitblt(f->b, rect.min, f->b, rect, 0); - rect.min.x = fi->x; - rect.max.x = (fi+1)->x; - rect.max.y = subf->height; - gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S); -} - -QLock bitlock; - -GBitmap* -id2bit(int v) -{ - GBitmap *bp=0; - - if(v<0 || v>=bit.nmap || (bp=bit.map[v])==0) - error(Ebadbitmap); - return bp; -} - -void -bitcompact(void) -{ - Arena *a, *ea, *na; - ulong *p1, *p2, n; - - qlock(&bitlock); - ea = &bit.arena[bit.narena]; - for(a=bit.arena; awords == 0) - continue; - /* first compact what's here */ - p1 = p2 = a->words; - while(p2 < a->wfree){ - n = HDR+p2[0]; - if(p2[2] == 0){ - p2 += n; - continue; - } - if(p1 != p2){ - memmove(p1, p2, n*sizeof(ulong)); - ((GBitmap*)p1[2])->base = p1+HDR; - } - p2 += n; - p1 += n; - } - /* now pull stuff from later arena to fill this one */ - na = a+1; - while(nawords+a->nwords){ - p2 = na->words; - if(p2 == 0){ - na++; - continue; - } - while(p2 < na->wfree){ - n = HDR+p2[0]; - if(p2[2] == 0){ - p2 += n; - continue; - } - if(p1+n < a->words+a->nwords){ - memmove(p1, p2, n*sizeof(ulong)); - ((GBitmap*)p1[2])->base = p1+HDR; - /* block now in new arena... */ - p1[1] = (ulong)a; - a->nbusy++; - /* ... not in old arena */ - na->nbusy--; - p2[2] = 0; - p1 += n; - } - p2 += n; - } - na++; - } - a->wfree = p1; - } - for(a=bit.arena; awords && a->nbusy==0) - arenafree(a); - qunlock(&bitlock); -} - -void -Cursortocursor(Cursor *c) -{ - int i; - uchar *p; - - lock(&cursor); - memmove(&cursor, c, sizeof(Cursor)); - for(i=0; i<16; i++){ - 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]; - } - if(hwcurs) - hwcursset(set.base, clr.base, cursor.offset.x, cursor.offset.y); - unlock(&cursor); -} - -void -cursoron(int dolock) -{ - if(cursor.disable) - return; - if(dolock) - lock(&cursor); - if(cursor.visible++ == 0){ - if(hwcurs) - hwcursmove(mouse.xy.x, mouse.xy.y); - else { - cursor.r.min = mouse.xy; - 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, cursor.r.min, - &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S); - gbitblt(&gscreen, cursor.r.min, - &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D); - mbbrect(cursor.r); - } - } - if(dolock) - unlock(&cursor); -} - -void -cursoroff(int dolock) -{ - if(cursor.disable) - return; - if(dolock) - lock(&cursor); - if(--cursor.visible == 0) { - if(!hwcurs) { - gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S); - mbbrect(cursor.r); - mousescreenupdate(); - } - } - if(dolock) - unlock(&cursor); -} - -/* - * called by the clock routine to redraw the cursor - */ -void -mouseclock(void) -{ - if(mouse.track){ - mousetrack(mouse.buttons, mouse.dx, mouse.dy); - mouse.track = 0; - mouse.dx = 0; - mouse.dy = 0; - } - if(mouse.redraw && canlock(&cursor)){ - mouse.redraw = 0; - cursoroff(0); - cursoron(0); - mousescreenupdate(); - unlock(&cursor); - } -} - -/* - * called at interrupt level to update the structure and - * awaken any waiting procs. - */ -void -mousetrack(int b, int dx, int dy) -{ - int x, y; - - x = mouse.xy.x + dx; - if(x < gscreen.r.min.x) - x = gscreen.r.min.x; - if(x >= gscreen.r.max.x) - x = gscreen.r.max.x; - y = mouse.xy.y + dy; - if(y < gscreen.r.min.y) - y = gscreen.r.min.y; - if(y >= gscreen.r.max.y) - y = gscreen.r.max.y; - mouse.counter++; - mouse.xy = Pt(x, y); - mouse.buttons = b; - mouse.redraw = 1; - wakeup(&mouse.r); -} - -/* - * microsoft 3 button, 7 bit bytes - * - * byte 0 - 1 L R Y7 Y6 X7 X6 - * byte 1 - 0 X5 X4 X3 X2 X1 X0 - * byte 2 - 0 Y5 Y4 Y3 Y2 Y1 Y0 - * byte 3 - 0 M x x x x x (optional) - * - * shift & right button is the same as middle button (for 2 button mice) - */ -int -m3mouseputc(IOQ *q, int c) -{ - static uchar msg[3]; - static int nb; - static int middle; - static uchar b[] = { 0, 4, 1, 5, 0, 2, 1, 5 }; - short x; - int dx, dy, newbuttons; - - USED(q); - /* - * check bit 6 for consistency - */ - if(nb==0){ - if((c&0x40) == 0){ - /* an extra byte gets sent for the middle button */ - middle = (c&0x20) ? 2 : 0; - newbuttons = (mouse.buttons & ~2) | middle; - mousetrack(newbuttons, 0, 0); - return 0; - } - } - msg[nb] = c; - if(++nb == 3){ - nb = 0; - newbuttons = middle | b[(msg[0]>>4)&3 | (mouseshifted ? 4 : 0)]; - x = (msg[0]&0x3)<<14; - dx = (x>>8) | msg[1]; - x = (msg[0]&0xc)<<12; - dy = (x>>8) | msg[2]; - mousetrack(newbuttons, dx, dy); - } - return 0; -} - -/* - * Logitech 5 byte packed binary mouse format, 8 bit bytes - * - * shift & right button is the same as middle button (for 2 button mice) - */ -int -mouseputc(IOQ *q, int c) -{ - static short msg[5]; - static int nb; - static uchar b[] = {0, 4, 2, 6, 1, 5, 3, 7, 0, 2, 2, 6, 1, 5, 3, 7}; - int dx, dy, newbuttons; - - USED(q); - if((c&0xF0) == 0x80) - nb=0; - msg[nb] = c; - if(c & 0x80) - msg[nb] |= ~0xFF; /* sign extend */ - if(++nb == 5){ - newbuttons = b[((msg[0]&7)^7) | (mouseshifted ? 8 : 0)]; - dx = msg[1]+msg[3]; - dy = -(msg[2]+msg[4]); - mousetrack(newbuttons, dx, dy); - nb = 0; - } - return 0; -} - -int -mousechanged(void *m) -{ - USED(m); - return mouse.lastcounter != mouse.counter; -} - -/* - * reverse pixels into little endian order - */ -uchar revtab0[] = { - 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, - 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, - 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, - 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, - 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, - 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, - 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, - 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, - 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, - 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, - 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, - 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, - 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, - 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, - 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, - 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, - 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, - 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, - 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, - 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, - 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, - 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, - 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, - 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, - 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, - 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, - 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, - 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, - 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, - 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, - 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, - 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, -}; -uchar revtab1[] = { - 0x00, 0x40, 0x80, 0xc0, 0x10, 0x50, 0x90, 0xd0, - 0x20, 0x60, 0xa0, 0xe0, 0x30, 0x70, 0xb0, 0xf0, - 0x04, 0x44, 0x84, 0xc4, 0x14, 0x54, 0x94, 0xd4, - 0x24, 0x64, 0xa4, 0xe4, 0x34, 0x74, 0xb4, 0xf4, - 0x08, 0x48, 0x88, 0xc8, 0x18, 0x58, 0x98, 0xd8, - 0x28, 0x68, 0xa8, 0xe8, 0x38, 0x78, 0xb8, 0xf8, - 0x0c, 0x4c, 0x8c, 0xcc, 0x1c, 0x5c, 0x9c, 0xdc, - 0x2c, 0x6c, 0xac, 0xec, 0x3c, 0x7c, 0xbc, 0xfc, - 0x01, 0x41, 0x81, 0xc1, 0x11, 0x51, 0x91, 0xd1, - 0x21, 0x61, 0xa1, 0xe1, 0x31, 0x71, 0xb1, 0xf1, - 0x05, 0x45, 0x85, 0xc5, 0x15, 0x55, 0x95, 0xd5, - 0x25, 0x65, 0xa5, 0xe5, 0x35, 0x75, 0xb5, 0xf5, - 0x09, 0x49, 0x89, 0xc9, 0x19, 0x59, 0x99, 0xd9, - 0x29, 0x69, 0xa9, 0xe9, 0x39, 0x79, 0xb9, 0xf9, - 0x0d, 0x4d, 0x8d, 0xcd, 0x1d, 0x5d, 0x9d, 0xdd, - 0x2d, 0x6d, 0xad, 0xed, 0x3d, 0x7d, 0xbd, 0xfd, - 0x02, 0x42, 0x82, 0xc2, 0x12, 0x52, 0x92, 0xd2, - 0x22, 0x62, 0xa2, 0xe2, 0x32, 0x72, 0xb2, 0xf2, - 0x06, 0x46, 0x86, 0xc6, 0x16, 0x56, 0x96, 0xd6, - 0x26, 0x66, 0xa6, 0xe6, 0x36, 0x76, 0xb6, 0xf6, - 0x0a, 0x4a, 0x8a, 0xca, 0x1a, 0x5a, 0x9a, 0xda, - 0x2a, 0x6a, 0xaa, 0xea, 0x3a, 0x7a, 0xba, 0xfa, - 0x0e, 0x4e, 0x8e, 0xce, 0x1e, 0x5e, 0x9e, 0xde, - 0x2e, 0x6e, 0xae, 0xee, 0x3e, 0x7e, 0xbe, 0xfe, - 0x03, 0x43, 0x83, 0xc3, 0x13, 0x53, 0x93, 0xd3, - 0x23, 0x63, 0xa3, 0xe3, 0x33, 0x73, 0xb3, 0xf3, - 0x07, 0x47, 0x87, 0xc7, 0x17, 0x57, 0x97, 0xd7, - 0x27, 0x67, 0xa7, 0xe7, 0x37, 0x77, 0xb7, 0xf7, - 0x0b, 0x4b, 0x8b, 0xcb, 0x1b, 0x5b, 0x9b, 0xdb, - 0x2b, 0x6b, 0xab, 0xeb, 0x3b, 0x7b, 0xbb, 0xfb, - 0x0f, 0x4f, 0x8f, 0xcf, 0x1f, 0x5f, 0x9f, 0xdf, - 0x2f, 0x6f, 0xaf, 0xef, 0x3f, 0x7f, 0xbf, 0xff, -}; -uchar revtab2[] = { - 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, - 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, - 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, - 0x81, 0x91, 0xa1, 0xb1, 0xc1, 0xd1, 0xe1, 0xf1, - 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, - 0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0xe2, 0xf2, - 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, - 0x83, 0x93, 0xa3, 0xb3, 0xc3, 0xd3, 0xe3, 0xf3, - 0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74, - 0x84, 0x94, 0xa4, 0xb4, 0xc4, 0xd4, 0xe4, 0xf4, - 0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75, - 0x85, 0x95, 0xa5, 0xb5, 0xc5, 0xd5, 0xe5, 0xf5, - 0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76, - 0x86, 0x96, 0xa6, 0xb6, 0xc6, 0xd6, 0xe6, 0xf6, - 0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77, - 0x87, 0x97, 0xa7, 0xb7, 0xc7, 0xd7, 0xe7, 0xf7, - 0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78, - 0x88, 0x98, 0xa8, 0xb8, 0xc8, 0xd8, 0xe8, 0xf8, - 0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79, - 0x89, 0x99, 0xa9, 0xb9, 0xc9, 0xd9, 0xe9, 0xf9, - 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a, 0x6a, 0x7a, - 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa, - 0x0b, 0x1b, 0x2b, 0x3b, 0x4b, 0x5b, 0x6b, 0x7b, - 0x8b, 0x9b, 0xab, 0xbb, 0xcb, 0xdb, 0xeb, 0xfb, - 0x0c, 0x1c, 0x2c, 0x3c, 0x4c, 0x5c, 0x6c, 0x7c, - 0x8c, 0x9c, 0xac, 0xbc, 0xcc, 0xdc, 0xec, 0xfc, - 0x0d, 0x1d, 0x2d, 0x3d, 0x4d, 0x5d, 0x6d, 0x7d, - 0x8d, 0x9d, 0xad, 0xbd, 0xcd, 0xdd, 0xed, 0xfd, - 0x0e, 0x1e, 0x2e, 0x3e, 0x4e, 0x5e, 0x6e, 0x7e, - 0x8e, 0x9e, 0xae, 0xbe, 0xce, 0xde, 0xee, 0xfe, - 0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, - 0x8f, 0x9f, 0xaf, 0xbf, 0xcf, 0xdf, 0xef, 0xff, -}; - -void -pixreverse(uchar *p, int len, int ldepth) -{ - uchar *e; - uchar *tab; - - switch(ldepth){ - case 0: - tab = revtab0; - break; - case 1: - tab = revtab1; - break; - case 2: - tab = revtab2; - break; - default: - return; - } - - for(e = p + len; p < e; p++) - *p = tab[*p]; -} diff --git a/port/devcdrom.c b/port/devcdrom.c deleted file mode 100644 index ba6802d45acc287d349e2926b5bc957f4619defc..0000000000000000000000000000000000000000 --- a/port/devcdrom.c +++ /dev/null @@ -1,234 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" -#include "io.h" - -/* - * CD-ROM. Gutted version of devwren. - */ - -#define DATASIZE 2048 /* max in a transfer */ - -typedef struct Drive Drive; - -enum { - Ndisk= 8, /* maximum disks */ - /* file types */ - Qdir= 0, - Qdisk= 1, -}; - -struct Drive -{ - QLock; - ulong blocks; /* blocks on disk */ - ulong bsize; /* bytes per block */ - int drive; -}; - -static Drive cdrom[Ndisk]; - -static void cdromsize(int); -static long cdromio(Chan*, char*, ulong, ulong); - -static char Ecap[] = "CD-ROM device capacity unknown"; -static char EnotCD[] = "not a CD-ROM device"; - -/* - * accepts [0-7]. lun is therefore always zero. - */ -static int -cdromdev(char *p) -{ - int drive; - - if(p == 0 || p[0] == '\0') - error(Ebadarg); - if(p[0] < '0' || p[0] > '7' || p[1]) - error(Ebadarg); - drive = p[0] - '0'; - return (drive << 3) | 0; -} - -static int -cdromgen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) -{ - char name[NAMELEN+4]; - Drive *dp; - - USED(tab, ntab); - if(s != 0) - return -1; - sprint(name, "cd%d", c->dev>>3); - dp = &cdrom[c->dev>>3]; - devdir(c, (Qid){Qdisk, 0}, name, dp->blocks*dp->bsize, eve, 0444, dirp); - return 1; -} - -void -cdromreset(void) -{ -} - -void -cdrominit(void) -{ -} - -/* - * param is #R - */ -Chan* -cdromattach(char *param) -{ - Chan *c; - int drive; - - drive = cdromdev(param); - cdromsize(drive); - c = devattach('R', param); - c->dev = drive; - return c; -} - -Chan* -cdromclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -cdromwalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, cdromgen); -} - -void -cdromstat(Chan *c, char *dp) -{ - devstat(c, dp, 0, 0, cdromgen); -} - -Chan* -cdromopen(Chan *c, int omode) -{ - return devopen(c, omode, 0, 0, cdromgen); -} - -void -cdromcreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -cdromclose(Chan *c) -{ - USED(c); -} - -void -cdromremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -cdromwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -long -cdromread(Chan *c, char *a, long n, ulong offset) -{ - if(c->qid.path == CHDIR) - return devdirread(c, a, n, 0, 0, cdromgen); - return cdromio(c, a, n, offset); -} - -long -cdromwrite(Chan *c, char *a, long n, ulong offset) -{ - USED(c, a, n, offset); - error(Eperm); - return 0; -} - -static long -cdromio(Chan *c, char *a, ulong len, ulong offset) -{ - Drive *d; - Scsibuf *b; - ulong block, n, max, x; - - d = &cdrom[c->dev>>3]; - - block = offset / d->bsize; - n = (offset + len + d->bsize - 1) / d->bsize - block; - max = DATASIZE / d->bsize; - if(n > max) - n = max; - if(block + n > d->blocks) - n = d->blocks - block; - if(block >= d->blocks || n == 0) - return 0; - b = scsibuf(); - if(waserror()){ - scsifree(b); - nexterror(); - } - offset %= d->bsize; - x = scsibread(d->drive, b, n, d->bsize, block); - if(x < offset) - len = 0; - else if(len > x - offset) - len = x - offset; - memmove(a, (char*)b->virt + offset, len); - poperror(); - scsifree(b); - return len; -} - -/* - * size disk - */ -static void -cdromsize(int dev) -{ - Drive *dp; - uchar buf[128]; - long nb, bs; - - dp = &cdrom[dev>>3]; - if(waserror()){ - qunlock(dp); - nexterror(); - } - qlock(dp); - scsiready(dev); - scsisense(dev, buf); - /* - * capacity not defined on CD-ROM, but most implement it. - */ - if(scsicap(dev, buf)!=0) - error(Ecap); - nb = (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0); - bs = (buf[4]<<24)|(buf[5]<<16)|(buf[6]<<8)|(buf[7]<<0); - if(nb==0 || bs==0) - error(Ecap); - - scsiinquiry(dev, buf, sizeof buf); - dp->drive = dev; - dp->blocks = nb; - dp->bsize = bs; - poperror(); - qunlock(dp); -} diff --git a/port/devscc.c b/port/devscc.c deleted file mode 100644 index 6b4cf19ec387a2cbb6605538b75714a6fb69415d..0000000000000000000000000000000000000000 --- a/port/devscc.c +++ /dev/null @@ -1,814 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "io.h" -#include "../port/error.h" - -#include "devtab.h" - -/* - * Driver for the Z8530. - */ -enum -{ - /* wr 0 */ - ResExtPend= 2<<3, - ResTxPend= 5<<3, - ResErr= 6<<3, - - /* wr 1 */ - ExtIntEna= 1<<0, - TxIntEna= 1<<1, - RxIntDis= 0<<3, - RxIntFirstEna= 1<<3, - RxIntAllEna= 2<<3, - - /* wr 3 */ - RxEna= 1, - Rx5bits= 0<<6, - Rx7bits= 1<<6, - Rx6bits= 2<<6, - Rx8bits= 3<<6, - Rxbitmask= 3<<6, - - /* wr 4 */ - ParEven= 3<<0, - ParOdd= 1<<0, - ParOff= 0<<0, - ParMask= 3<<0, - SyncMode= 0<<2, - Rx1stop= 1<<2, - Rx1hstop= 2<<2, - Rx2stop= 3<<2, - X16= 1<<6, - - /* wr 5 */ - TxRTS= 1<<1, - TxEna= 1<<3, - TxBreak= 1<<4, - TxDTR= 1<<7, - Tx5bits= 0<<5, - Tx7bits= 1<<5, - Tx6bits= 2<<5, - Tx8bits= 3<<5, - Txbitmask= 3<<5, - - /* wr 9 */ - IntEna= 1<<3, - ResetB= 1<<6, - ResetA= 2<<6, - HardReset= 3<<6, - - /* wr 11 */ - TRxCOutBR= 2, - TxClockBR= 2<<3, - RxClockBR= 2<<5, - TRxCOI= 1<<2, - - /* wr 14 */ - BREna= 1, - BRSource= 2, - - /* rr 0 */ - RxReady= 1, - TxReady= 1<<2, - RxDCD= 1<<3, - RxCTS= 1<<5, - RxBreak= 1<<7, - - /* rr 3 */ - ExtPendB= 1, - TxPendB= 1<<1, - RxPendB= 1<<2, - ExtPendA= 1<<3, - TxPendA= 1<<4, - RxPendA= 1<<5, -}; - -typedef struct SCC SCC; -struct SCC -{ - QLock; - ushort sticky[16]; /* sticky write register values */ - uchar *ptr; /* command/pointer register in Z8530 */ - uchar *data; /* data register in Z8530 */ - int printing; /* true if printing */ - ulong freq; /* clock frequency */ - uchar mask; /* bits/char */ - - /* console interface */ - int special; /* can't use the stream interface */ - IOQ *iq; /* input character queue */ - IOQ *oq; /* output character queue */ - - /* stream interface */ - Queue *wq; /* write queue */ - Rendez r; /* kproc waiting for input */ - int kstarted; /* kproc started */ - - /* idiot flow control */ - int xonoff; /* true if we obey this tradition */ - int blocked; /* abstinence */ -}; - -int nscc; -SCC *scc[8]; /* up to 4 8530's */ -#define CTLS 023 -#define CTLQ 021 - -#ifdef Zduart -#define SCCTYPE 'z' -#define onepointseven() -#else -#define SCCTYPE 't' -void -onepointseven(void) -{ - int i; - for(i = 0; i < 20; i++) - ; -} -#endif - -/* - * Access registers using the pointer in register 0. - * This is a bit stupid when accessing register 0. - */ -void -sccwrreg(SCC *sp, int addr, int value) -{ - onepointseven(); - *sp->ptr = addr; - wbflush(); - onepointseven(); - *sp->ptr = sp->sticky[addr] | value; - wbflush(); -} -ushort -sccrdreg(SCC *sp, int addr) -{ - onepointseven(); - *sp->ptr = addr; - wbflush(); - onepointseven(); - return *sp->ptr; -} - -/* - * set the baud rate by calculating and setting the baudrate - * generator constant. This will work with fairly non-standard - * baud rates. - */ -void -sccsetbaud(SCC *sp, int rate) -{ - int brconst; - - if(rate == 0) - error(Ebadctl); - - brconst = (sp->freq+16*rate-1)/(2*16*rate) - 2; - - sccwrreg(sp, 12, brconst & 0xff); - sccwrreg(sp, 13, (brconst>>8) & 0xff); -} - -void -sccparity(SCC *sp, char type) -{ - int val; - - switch(type){ - case 'e': - val = ParEven; - break; - case 'o': - val = ParOdd; - break; - default: - val = ParOff; - break; - } - sp->sticky[4] = (sp->sticky[4] & ~ParMask) | val; - sccwrreg(sp, 4, 0); -} - -/* - * set bits/character, default 8 - */ -void -sccbits(SCC *sp, int n) -{ - int rbits, tbits; - - switch(n){ - case 5: - sp->mask = 0x1f; - rbits = Rx5bits; - tbits = Tx5bits; - break; - case 6: - sp->mask = 0x3f; - rbits = Rx6bits; - tbits = Tx6bits; - break; - case 7: - sp->mask = 0x7f; - rbits = Rx7bits; - tbits = Tx7bits; - break; - case 8: - default: - sp->mask = 0xff; - rbits = Rx8bits; - tbits = Tx8bits; - break; - } - sp->sticky[3] = (sp->sticky[3]&~Rxbitmask) | rbits; - sccwrreg(sp, 3, 0); - sp->sticky[5] = (sp->sticky[5]&~Txbitmask) | tbits; - sccwrreg(sp, 5, 0); -} - -/* - * toggle DTR - */ -void -sccdtr(SCC *sp, int n) -{ - if(n) - sp->sticky[5] |= TxDTR; - else - sp->sticky[5] &=~TxDTR; - sccwrreg(sp, 5, 0); -} - -/* - * toggle RTS - */ -void -sccrts(SCC *sp, int n) -{ - if(n) - sp->sticky[5] |= TxRTS; - else - sp->sticky[5] &=~TxRTS; - sccwrreg(sp, 5, 0); -} - -/* - * send break - */ -void -sccbreak(SCC *sp, int ms) -{ - if(ms == 0) - ms = 100; - sp->sticky[1] &=~TxIntEna; - sccwrreg(sp, 1, 0); - sccwrreg(sp, 5, TxBreak|TxEna); - tsleep(&u->p->sleep, return0, 0, ms); - sccwrreg(sp, 5, 0); - if(sp->oq){ - sp->sticky[1] |= TxIntEna; - sccwrreg(sp, 1, 0); - } -} - -/* - * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, - * transmit and receive enabled, interrupts disabled. - */ -static void -sccsetup0(SCC *sp, int brsource) -{ - memset(sp->sticky, 0, sizeof(sp->sticky)); - - /* - * turn on baud rate generator and set rate to 9600 baud. - * use 1 stop bit. - */ - sp->sticky[14] = brsource ? BRSource : 0; - sccwrreg(sp, 14, 0); - sccsetbaud(sp, 9600); - sp->sticky[4] = Rx1stop | X16; - sccwrreg(sp, 4, 0); - sp->sticky[11] = TxClockBR | RxClockBR | TRxCOutBR /*| TRxCOI*/; - sccwrreg(sp, 11, 0); - sp->sticky[14] = BREna; - if(brsource) - sp->sticky[14] |= BRSource; - sccwrreg(sp, 14, 0); - - /* - * enable I/O, 8 bits/character - */ - sp->sticky[3] = RxEna | Rx8bits; - sccwrreg(sp, 3, 0); - sp->sticky[5] = TxEna | Tx8bits; - sccwrreg(sp, 5, 0); - sp->mask = 0xff; -} - -void -sccsetup(void *addr, ulong freq, int brsource) -{ - SCCdev *dev; - SCC *sp; - - dev = addr; - - /* - * allocate a structure, set port addresses, and setup the line - */ - sp = xalloc(sizeof(SCC)); - scc[nscc] = sp; - sp->ptr = &dev->ptra; - sp->data = &dev->dataa; - sp->freq = freq; - sccsetup0(sp, brsource); - sp = xalloc(sizeof(SCC)); - scc[nscc+1] = sp; - sp->ptr = &dev->ptrb; - sp->data = &dev->datab; - sp->freq = freq; - sccsetup0(sp, brsource); - nscc += 2; -} - -/* - * Queue n characters for output; if queue is full, we lose characters. - * Get the output going if it isn't already. - */ -void -sccputs(IOQ *cq, char *s, int n) -{ - SCC *sp = cq->ptr; - int ch, x; - - x = splhi(); - lock(cq); - puts(cq, s, n); - if(sp->printing == 0 && sp->blocked==0){ - ch = getc(cq); - /*kprint("", ch);*/ - if(ch >= 0){ - sp->printing = 1; - while((*sp->ptr&TxReady)==0) - ; - *sp->data = ch; - } - } - unlock(cq); - splx(x); -} - -/* - * an scc interrupt (a damn lot of work for one character) - */ -void -sccintr0(SCC *sp, uchar x) -{ - int ch; - IOQ *cq; - - if(x & ExtPendB){ - sccwrreg(sp, 0, ResExtPend); - } - if(x & RxPendB){ - cq = sp->iq; - while(*sp->ptr&RxReady){ - onepointseven(); - ch = *sp->data & sp->mask; - if (ch == CTLS && sp->xonoff) - sp->blocked = 1; - else if (ch == CTLQ && sp->xonoff) { - sp->blocked = 0; - sccputs(sp->oq, "", 0); - } - if(cq->putc) - (*cq->putc)(cq, ch); - else - putc(cq, ch); - } - } - if(x & TxPendB){ - if (sp->blocked) { - sccwrreg(sp, 0, ResTxPend); - sp->printing = 0; - return; - } - cq = sp->oq; - lock(cq); - ch = getc(cq); - onepointseven(); - if(ch < 0){ - sccwrreg(sp, 0, ResTxPend); - sp->printing = 0; - wakeup(&cq->r); - }else - *sp->data = ch; - unlock(cq); - } -} -int -sccintr(void) -{ - uchar x; - int i, j; - - for(i = j = 0; i < nscc; i += 2){ - x = sccrdreg(scc[i], 3); - if(x & (ExtPendB|RxPendB|TxPendB)) - ++j, sccintr0(scc[i+1], x); - x = x >> 3; - if(x & (ExtPendB|RxPendB|TxPendB)) - ++j, sccintr0(scc[i], x); - } - return j; -} - -void -sccclock(void) -{ - SCC *sp; - IOQ *cq; - int i; - - for(i = 0; i < nscc; i++){ - sp = scc[i]; - cq = sp->iq; - if(sp->wq && cangetc(cq)) - wakeup(&cq->r); - } -} - -/* - * turn on a port's interrupts. set DTR and RTS - */ -void -sccenable(SCC *sp) -{ - /* - * set up i/o routines - */ - if(sp->oq){ - sp->oq->puts = sccputs; - sp->oq->ptr = sp; - sp->sticky[1] |= TxIntEna | ExtIntEna; - } - if(sp->iq){ - sp->iq->ptr = sp; - sp->sticky[1] |= RxIntAllEna | ExtIntEna; - } - - /* - * turn on interrupts - */ - sccwrreg(sp, 1, 0); - sp->sticky[9] |= IntEna; - sccwrreg(sp, 9, 0); - - /* - * turn on DTR and RTS - */ - sccdtr(sp, 1); - sccrts(sp, 1); -} - -/* - * set up an scc port as something other than a stream - */ -void -sccspecial(int port, IOQ *oq, IOQ *iq, int baud) -{ - SCC *sp = scc[port]; - - sp->special = 1; - sp->oq = oq; - sp->iq = iq; - sccenable(sp); - if(baud) - sccsetbaud(sp, baud); - - if(iq){ - /* - * Stupid HACK to undo a stupid hack - */ - if(iq == &kbdq) - kbdq.putc = kbdcr2nl; - } -} - -void -sccrawput(int port, int c) -{ - SCC *sp = scc[port]; - - if(c == '\n') { - sccrawput(port, '\r'); - delay(100); - } - - while((*sp->ptr&TxReady)==0) - ; - *sp->data = c; -} - -static void sccstopen(Queue*, Stream*); -static void sccstclose(Queue*); -static void sccoput(Queue*, Block*); -static void scckproc(void *); -Qinfo sccinfo = -{ - nullput, - sccoput, - sccstopen, - sccstclose, - "scc" -}; - -static void -sccstopen(Queue *q, Stream *s) -{ - SCC *sp; - char name[NAMELEN]; - - kprint("sccstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n", - q, s->inuse, s->type, s->dev, s->id); - sp = scc[s->id]; - qlock(sp); - sp->wq = WR(q); - WR(q)->ptr = sp; - RD(q)->ptr = sp; - qunlock(sp); - - if(sp->kstarted == 0){ - sp->kstarted = 1; - sprint(name, "scc%d", s->id); - kproc(name, scckproc, sp); - } -} - -static void -sccstclose(Queue *q) -{ - SCC *sp = q->ptr; - - if(sp->special) - return; - - qlock(sp); - sp->wq = 0; - sp->iq->putc = 0; - WR(q)->ptr = 0; - RD(q)->ptr = 0; - qunlock(sp); -} - -static void -sccoput(Queue *q, Block *bp) -{ - SCC *sp = q->ptr; - IOQ *cq; - int n, m; - - if(sp == 0){ - freeb(bp); - return; - } - cq = sp->oq; - if(waserror()){ - freeb(bp); - nexterror(); - } - if(bp->type == M_CTL){ - while (cangetc(cq)) /* let output drain */ - sleep(&cq->r, cangetc, cq); - n = strtoul((char *)(bp->rptr+1), 0, 0); - switch(*bp->rptr){ - case 'B': - case 'b': - if(BLEN(bp)>4 && strncmp((char*)(bp->rptr+1), "reak", 4) == 0) - sccbreak(sp, 0); - else - sccsetbaud(sp, n); - break; - case 'D': - case 'd': - sccdtr(sp, n); - break; - case 'L': - case 'l': - sccbits(sp, n); - break; - - case 'P': - case 'p': - sccparity(sp, *(bp->rptr+1)); - break; - case 'K': - case 'k': - sccbreak(sp, n); - break; - case 'R': - case 'r': - sccrts(sp, n); - break; - case 'W': - case 'w': - /* obsolete */ - break; - case 'X': - case 'x': - sp->xonoff = n; - break; - } - }else while((m = BLEN(bp)) > 0){ - while ((n = canputc(cq)) == 0){ - kprint(" sccoput: sleeping\n"); - sleep(&cq->r, canputc, cq); - } - if(n > m) - n = m; - (*cq->puts)(cq, bp->rptr, n); - bp->rptr += n; - } - freeb(bp); - poperror(); -} - -/* - * process to send bytes upstream for a port - */ -static void -scckproc(void *a) -{ - SCC *sp = a; - IOQ *cq = sp->iq; - Block *bp; - int n; - -loop: - while ((n = cangetc(cq)) == 0) - sleep(&cq->r, cangetc, cq); - /*kprint(" scckproc: %d\n", n);*/ - qlock(sp); - if(sp->wq == 0){ - cq->out = cq->in; - }else{ - bp = allocb(n); - bp->flags |= S_DELIM; - bp->wptr += gets(cq, bp->wptr, n); - PUTNEXT(RD(sp->wq), bp); - } - qunlock(sp); - goto loop; -} - -Dirtab *sccdir; - -/* - * create 2 directory entries for each 'sccsetup' ports. - * allocate the queues if no one else has. - */ -void -sccreset(void) -{ - SCC *sp; - int i; - Dirtab *dp; - - sccdir = xalloc(2 * nscc * sizeof(Dirtab)); - dp = sccdir; - for(i = 0; i < nscc; i++){ - /* 2 directory entries per port */ - sprint(dp->name, "eia%d", i); - dp->qid.path = STREAMQID(i, Sdataqid); - dp->perm = 0666; - dp++; - sprint(dp->name, "eia%dctl", i); - dp->qid.path = STREAMQID(i, Sctlqid); - dp->perm = 0666; - dp++; - - /* set up queues if a stream port */ - sp = scc[i]; - if(sp->special) - continue; - sp->iq = xalloc(sizeof(IOQ)); - initq(sp->iq); - sp->oq = xalloc(sizeof(IOQ)); - initq(sp->oq); - sccenable(sp); - } -} - -void -sccinit(void) -{ -} - -Chan* -sccattach(char *spec) -{ - return devattach(SCCTYPE, spec); -} - -Chan* -sccclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -sccwalk(Chan *c, char *name) -{ - return devwalk(c, name, sccdir, 2*nscc, devgen); -} - -void -sccstat(Chan *c, char *dp) -{ - int i; - - i = STREAMID(c->qid.path); - switch(STREAMTYPE(c->qid.path)){ - case Sdataqid: - streamstat(c, dp, sccdir[2*i].name, sccdir[2*i].perm); - break; - default: - devstat(c, dp, sccdir, 2*nscc, devgen); - break; - } -} - -Chan* -sccopen(Chan *c, int omode) -{ - SCC *sp; - - if(c->qid.path != CHDIR){ - sp = scc[STREAMID(c->qid.path)]; - if(sp->special) - error(Einuse); - streamopen(c, &sccinfo); - } - return devopen(c, omode, sccdir, 2*nscc, devgen); -} - -void -scccreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -sccclose(Chan *c) -{ - if(c->stream) - streamclose(c); -} - -long -sccread(Chan *c, void *buf, long n, ulong offset) -{ - char b[8]; - - if(c->qid.path == CHDIR) - return devdirread(c, buf, n, sccdir, 2*nscc, devgen); - - switch(STREAMTYPE(c->qid.path)){ - case Sdataqid: - return streamread(c, buf, n); - case Sctlqid: - sprint(b, "%d", STREAMID(c->qid.path)); - return readstr(offset, buf, n, b); - } - error(Egreg); - return 0; /* not reached */ -} - -long -sccwrite(Chan *c, void *va, long n, ulong offset) -{ - USED(offset); - return streamwrite(c, va, n, 0); -} - -void -sccremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -sccwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} diff --git a/port/devscsi.c b/port/devscsi.c deleted file mode 100644 index 8bc3f6b3f15c31ff91f3c367e04a43213e5b63f1..0000000000000000000000000000000000000000 --- a/port/devscsi.c +++ /dev/null @@ -1,536 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" - -#define DPRINT if(debug)kprint - -#define DATASIZE (64*512) - -static Scsi staticcmd; /* BUG: should be one per scsi device */ - -enum -{ - Qdir, - Qcmd, - Qdata, - Qdebug, -}; - -static Dirtab scsidir[]={ - "cmd", {Qcmd}, 0, 0666, - "data", {Qdata}, 0, 0666, - "debug", {Qdebug}, 1, 0666, -}; -#define NSCSI (sizeof scsidir/sizeof(Dirtab)) - -extern int scsidebugs[]; -extern int scsiownid; - -static int -scsigen1(Chan *c, long qid, Dir *dp) -{ - if (qid == CHDIR) - devdir(c, (Qid){qid,0}, ".", 0, eve, 0555, dp); - else if (qid == 1) - devdir(c, (Qid){qid,0}, "id", 1, eve, 0666, dp); - else if (qid&CHDIR) { - char name[2]; - name[0] = '0'+((qid>>4)&7), name[1] = 0; - devdir(c, (Qid){qid,0}, name, 0, eve, 0555, dp); - } else { - Dirtab *tab = &scsidir[(qid&7)-1]; - devdir(c, (Qid){qid,0}, tab->name, tab->length, eve, tab->perm, dp); - } - return 1; -} - -static int -scsigeno(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) -{ - USED(tab, ntab, s); - return scsigen1(c, c->qid.path, dp); -} - -static int -scsigen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dp) -{ - USED(tab, ntab); - if (c->qid.path == CHDIR) { - if (0<=s && s<=7) - return scsigen1(c, CHDIR|0x100|(s<<4), dp); - else if (s == 8) - return scsigen1(c, 1, dp); - else - return -1; - } - if (s >= NSCSI) - return -1; - return scsigen1(c, (c->qid.path&~CHDIR)+s+1, dp); -} - -void -scsireset(void) -{ - scsibufreset(DATASIZE); - resetscsi(); -} - -void -scsiinit(void) -{ - initscsi(); -} - -Chan * -scsiattach(char *param) -{ - return devattach('S', param); -} - -Chan * -scsiclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -scsiwalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, scsigen); -} - -void -scsistat(Chan *c, char *db) -{ - devstat(c, db, 0, 0, scsigeno); -} - -Chan * -scsiopen(Chan *c, int omode) -{ - return devopen(c, omode, 0, 0, scsigeno); -} - -void -scsicreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -scsiclose(Chan *c) -{ - Scsi *cmd = &staticcmd; - - if((c->qid.path & CHDIR) || c->qid.path==1) - return; - if((c->qid.path & 0xf) == Qcmd){ - if(canqlock(cmd) || cmd->pid == up->pid){ - cmd->pid = 0; - qunlock(cmd); - } - } -} - -long -scsiread(Chan *c, char *a, long n, ulong offset) -{ - Scsi *cmd = &staticcmd; - - if(n == 0) - return 0; - if(c->qid.path & CHDIR) - return devdirread(c, a, n, 0, 0, scsigen); - if(c->qid.path==1){ - if(offset == 0){ - /*void scsidump(void); scsidump();*/ - *a = scsiownid; - n = 1; - }else - n = 0; - }else switch(c->qid.path & 0xf){ - case Qcmd: - if(n < 4) - error(Ebadarg); - if(canqlock(cmd)){ - qunlock(cmd); - error(Egreg); - } - if(cmd->pid != up->pid) - error(Egreg); - n = 4; - *a++ = 0; - *a++ = 0; - *a++ = cmd->status >> 8; - *a = cmd->status; - cmd->pid = 0; - qunlock(cmd); - break; - case Qdata: - if(canqlock(cmd)){ - qunlock(cmd); - error(Egreg); - } - if(cmd->pid != up->pid) - error(Egreg); - if (n > DATASIZE) - error(Ebadarg); - cmd->b = scsibuf(); - cmd->data.base = cmd->b->virt; - if(waserror()){ - scsifree(cmd->b); - nexterror(); - } - cmd->data.lim = cmd->data.base + n; - cmd->data.ptr = cmd->data.base; - cmd->save = cmd->data.base; - scsiexec(cmd, ScsiIn); - n = cmd->data.ptr - cmd->data.base; - memmove(a, cmd->data.base, n); - poperror(); - scsifree(cmd->b); - break; - case Qdebug: - if(offset == 0){ - n=1; - *a="01"[scsidebugs[(c->qid.path>>4)&7]!=0]; - }else - n = 0; - break; - default: - panic("scsiread"); - } - return n; -} - -long -scsiwrite(Chan *c, char *a, long n, ulong offset) -{ - Scsi *cmd = &staticcmd; - - if(c->qid.path==1 && n>0){ - if(offset == 0){ - n = 1; - scsiownid=*a; - scsireset(); - }else - n = 0; - }else switch(c->qid.path & 0xf){ - case Qcmd: - if(n < 6 || n > sizeof cmd->cmdblk) - error(Ebadarg); - qlock(cmd); - cmd->pid = up->pid; - cmd->cmd.base = cmd->cmdblk; - memmove(cmd->cmd.base, a, n); - cmd->cmd.lim = cmd->cmd.base + n; - cmd->cmd.ptr = cmd->cmd.base; - cmd->target = (c->qid.path>>4)&7; - cmd->lun = (a[1]>>5)&7; - cmd->status = 0xFFFF; - break; - case Qdata: - if(canqlock(cmd)){ - qunlock(cmd); - error(Egreg); - } - if(cmd->pid != up->pid) - error(Egreg); - if (n > DATASIZE) - error(Ebadarg); - cmd->b = scsibuf(); - cmd->data.base = cmd->b->virt; - if(waserror()){ - scsifree(cmd->b); - nexterror(); - } - cmd->data.lim = cmd->data.base + n; - cmd->data.ptr = cmd->data.base; - cmd->save = cmd->data.base; - memmove(cmd->data.base, a, n); - scsiexec(cmd, ScsiOut); - n = cmd->data.ptr - cmd->data.base; - poperror(); - scsifree(cmd->b); - break; - case Qdebug: - if(offset == 0){ - scsidebugs[(c->qid.path>>4)&7] = (*a=='1'); - n = 1; - }else - n = 0; - break; - default: - panic("scsiwrite"); - } - return n; -} - -void -scsiremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -scsiwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -Scsi * -scsicmd(int dev, int cmdbyte, Scsibuf *b, long size) -{ - Scsi *cmd = &staticcmd; - - qlock(cmd); - cmd->target = dev >> 3; - cmd->lun = dev & 7; - cmd->cmd.base = cmd->cmdblk; - cmd->cmd.ptr = cmd->cmd.base; - memset(cmd->cmdblk, 0, sizeof cmd->cmdblk); - cmd->cmdblk[0] = cmdbyte; - switch(cmdbyte >> 5){ - case 0: - cmd->cmd.lim = &cmd->cmdblk[6]; - break; - case 1: - cmd->cmd.lim = &cmd->cmdblk[10]; - break; - default: - cmd->cmd.lim = &cmd->cmdblk[12]; - break; - } - switch(cmdbyte){ - case ScsiTestunit: - break; - case ScsiStartunit: - cmd->cmdblk[4] = 1; - break; - case ScsiModesense: - cmd->cmdblk[2] = 1; - /* fall through */ - case ScsiExtsens: - case ScsiInquiry: - cmd->cmdblk[4] = size; - break; - case ScsiGetcap: - break; - } - cmd->b = b; - cmd->data.base = b->virt; - cmd->data.lim = cmd->data.base + size; - cmd->data.ptr = cmd->data.base; - cmd->save = cmd->data.base; - return cmd; -} - -int -scsiready(int dev) -{ - Scsi *cmd; - int status; - - cmd = scsicmd(dev, ScsiTestunit, scsibuf(), 0); - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiOut); - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if((status&0xff00) != 0x6000) - error(Eio); - return status&0xff; -} - -int -scsistartstop(int dev, int cmdbyte) -{ - Scsi *cmd; - int status; - - cmd = scsicmd(dev, cmdbyte, scsibuf(), 0); - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiOut); - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if((status&0xff00) != 0x6000) - error(Eio); - return status&0xff; -} - -int -scsisense(int dev, void *p) -{ - Scsi *cmd; - int status; - - cmd = scsicmd(dev, ScsiExtsens, scsibuf(), 18); - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiIn); - memmove(p, cmd->data.base, 18); - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if((status&0xff00) != 0x6000) - error(Eio); - return status&0xff; -} - -int -scsicap(int dev, void *p) -{ - Scsi *cmd; - int status; - - cmd = scsicmd(dev, ScsiGetcap, scsibuf(), 8); - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiIn); - memmove(p, cmd->data.base, 8); - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if((status&0xff00) != 0x6000) - error(Eio); - if(status & 0xFF) - scsisense(dev, p); - return status&0xff; -} - -int -scsiinquiry(int dev, void *p, int size) -{ - Scsi *cmd; - int status; - - cmd = scsicmd(dev, ScsiInquiry, scsibuf(), size); - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiIn); - memmove(p, cmd->data.base, size); - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if((status&0xff00) != 0x6000) - error(Eio); - if(status & 0xFF) - scsisense(dev, p); - return status&0xff; -} - -int -scsiwp(int dev) -{ -/* Device specific - Scsi *cmd; - int r, status; - - cmd = scsicmd(dev, ScsiModesense, scsibuf(), 12); - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiIn); - r = cmd->data.base[2] & 0x80; - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if ((status&0xffff) != 0x6000) - error(Eio); - return r; -*/ - USED(dev); - return 0; -} - -int -scsimodesense(int dev, int page, void *p, int size) -{ - Scsi *cmd; - int status; - - cmd = scsicmd(dev, ScsiModesense, scsibuf(), size); - cmd->cmdblk[2] = page; - if(waserror()){ - scsifree(cmd->b); - qunlock(cmd); - nexterror(); - } - status = scsiexec(cmd, ScsiIn); - memmove(p, cmd->data.base, size); - poperror(); - scsifree(cmd->b); - qunlock(cmd); - if ((status&0xffff) != 0x6000) - error(Eio); - return status&0xff; -} - -int -scsibread(int dev, Scsibuf *b, long n, long blocksize, long blockno) -{ - Scsi *cmd; - - cmd = scsicmd(dev, ScsiRead, b, n*blocksize); - if(waserror()){ - qunlock(cmd); - nexterror(); - } - cmd->cmdblk[1] = blockno >> 16; - cmd->cmdblk[2] = blockno >> 8; - cmd->cmdblk[3] = blockno; - cmd->cmdblk[4] = n; - scsiexec(cmd, ScsiIn); - n = cmd->data.ptr - cmd->data.base; - poperror(); - qunlock(cmd); - return n; -} - -int -scsibwrite(int dev, Scsibuf *b, long n, long blocksize, long blockno) -{ - Scsi *cmd; - - cmd = scsicmd(dev, ScsiWrite, b, n*blocksize); - if(waserror()){ - qunlock(cmd); - nexterror(); - } - cmd->cmdblk[1] = blockno >> 16; - cmd->cmdblk[2] = blockno >> 8; - cmd->cmdblk[3] = blockno; - cmd->cmdblk[4] = n; - scsiexec(cmd, ScsiOut); - n = cmd->data.ptr - cmd->data.base; - poperror(); - qunlock(cmd); - return n; -} diff --git a/port/devwren.c b/port/devwren.c deleted file mode 100644 index a752073854c53aa5d300f6e6faa1e545446b5bf3..0000000000000000000000000000000000000000 --- a/port/devwren.c +++ /dev/null @@ -1,336 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "devtab.h" -#include "io.h" - -#define DATASIZE (8*1024) - -typedef struct Partition Partition; -typedef struct Drive Drive; - -enum { - Npart= 8+2, /* 8 sub partitions, disk, and partition */ - Ndisk= 64, /* maximum disks; if you change it, you must - map from dev to disk */ - - /* file types */ - Qdir= 0, -}; -#define PART(x) ((x)&0xF) -#define DRIVE(x) (((x)>>4)&(Ndisk-1)) -#define MKQID(d,p) (((d)<<4) | (p)) - -struct Partition -{ - ulong start; - ulong end; - char name[NAMELEN+1]; -}; - -struct Drive -{ - QLock; - ulong bytes; /* bytes per block */ - int npart; /* actual number of partitions */ - int drive; - int readonly; - Partition p[Npart]; -}; - -static Drive wren[Ndisk]; - -static void wrenpart(int); -static long wrenio(Chan*, int, char*, ulong, ulong); - -/* - * accepts [0-7].[0-7], or abbreviation - */ -static int -wrendev(char *p) -{ - int drive, unit; - - if(p == 0 || p[0] == '\0') - return 0; - if(p[0] < '0' || p[0] > '7') - error(Ebadarg); - drive = p[0] - '0'; - unit = 0; - if(p[1]){ - if(p[1] != '.' || p[2] < '0' || p[2] > '7' || p[3] != '\0') - error(Ebadarg); - unit = p[2] - '0'; - } - return (drive << 3) | unit; -} - -static int -wrengen(Chan *c, Dirtab *tab, long ntab, long s, Dir *dirp) -{ - Qid qid; - int drive; - char name[NAMELEN+4]; - Drive *dp; - Partition *pp; - ulong l; - - USED(tab, ntab); - qid.vers = 0; - drive = c->dev; - if(drive >= Ndisk) - return -1; - dp = &wren[drive]; - - if(s >= dp->npart) - return -1; - - pp = &dp->p[s]; - if(drive & 7) - sprint(name, "sd%d.%d%s", drive>>3, drive&7, pp->name); - else - sprint(name, "sd%d%s", drive>>3, pp->name); - name[NAMELEN] = 0; - qid.path = MKQID(drive, s); - l = (pp->end - pp->start) * dp->bytes; - devdir(c, qid, name, l, eve, dp->readonly ? 0444 : 0666, dirp); - return 1; -} - -void -wrenreset(void) -{ -} - -void -wreninit(void) -{ -} - -/* - * param is #w. - */ -Chan * -wrenattach(char *param) -{ - Chan *c; - int drive; - - drive = wrendev(param); - wrenpart(drive); - c = devattach('w', param); - c->dev = drive; - return c; -} - -Chan* -wrenclone(Chan *c, Chan *nc) -{ - return devclone(c, nc); -} - -int -wrenwalk(Chan *c, char *name) -{ - return devwalk(c, name, 0, 0, wrengen); -} - -void -wrenstat(Chan *c, char *dp) -{ - devstat(c, dp, 0, 0, wrengen); -} - -Chan* -wrenopen(Chan *c, int omode) -{ - return devopen(c, omode, 0, 0, wrengen); -} - -void -wrencreate(Chan *c, char *name, int omode, ulong perm) -{ - USED(c, name, omode, perm); - error(Eperm); -} - -void -wrenclose(Chan *c) -{ - USED(c); -} - -void -wrenremove(Chan *c) -{ - USED(c); - error(Eperm); -} - -void -wrenwstat(Chan *c, char *dp) -{ - USED(c, dp); - error(Eperm); -} - -long -wrenread(Chan *c, char *a, long n, ulong offset) -{ - if(c->qid.path == CHDIR) - return devdirread(c, a, n, 0, 0, wrengen); - return wrenio(c, 0, a, n, offset); -} - -long -wrenwrite(Chan *c, char *a, long n, ulong offset) -{ - n = wrenio(c, 1, a, n, offset); - if(n) - return n; - error("end of device"); - return 0; /* not reached */ -} - -static long -wrenio(Chan *c, int write, char *a, ulong len, ulong offset) -{ - Drive *d; - Partition *p; - Scsibuf *b; - ulong block, n, max, x; - - d = &wren[DRIVE(c->qid.path)]; - if(d->npart == 0) /* drive repartitioned */ - error(Eio); - p = &d->p[PART(c->qid.path)]; - - block = offset / d->bytes + p->start; - n = (offset + len + d->bytes - 1) / d->bytes + p->start - block; - max = DATASIZE / d->bytes; - if(n > max) - n = max; - if(block + n > p->end) - n = p->end - block; - if(block >= p->end || n == 0) - return 0; - b = scsibuf(); - if(waserror()){ - scsifree(b); - nexterror(); - } - offset %= d->bytes; - if(write){ - if(offset || len % d->bytes){ - x = scsibread(d->drive, b, n, d->bytes, block); - if(x < n * d->bytes){ - n = x / d->bytes; - x = n * d->bytes - offset; - if(len > x) - len = x; - } - } - memmove((char*)b->virt + offset, a, len); - x = scsibwrite(d->drive, b, n, d->bytes, block); - if(x < offset) - len = 0; - else if(len > x - offset) - len = x - offset; - }else{ - x = scsibread(d->drive, b, n, d->bytes, block); - if(x < offset) - len = 0; - else if(len > x - offset) - len = x - offset; - memmove(a, (char*)b->virt + offset, len); - } - poperror(); - scsifree(b); - return len; -} - -/* - * read partition table. The partition table is just ascii strings. - */ -#define MAGIC "plan9 partitions" -static void -wrenpart(int dev) -{ - Drive *dp; - Partition *pp; - uchar buf[128]; - Scsibuf *b; - char *rawpart, *line[Npart+1], *field[3]; - ulong n; - int i; - - dp = &wren[dev]; - if(waserror()){ - qunlock(dp); - nexterror(); - } - qlock(dp); - scsiready(dev); - scsisense(dev, buf); - scsistartstop(dev, ScsiStartunit); - scsisense(dev, buf); - if(scsicap(dev, buf)) - error(Eio); - dp->drive = dev; - dp->readonly = scsiwp(dev); - - /* - * we always have a partition for the whole disk - * and one for the partition table - */ - dp->bytes = (buf[4]<<24)+(buf[5]<<16)+(buf[6]<<8)+(buf[7]); - pp = &dp->p[0]; - strcpy(pp->name, "disk"); - pp->start = 0; - pp->end = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+(buf[3]) + 1; - pp++; - strcpy(pp->name, "partition"); - pp->start = dp->p[0].end - 1; - pp->end = dp->p[0].end; - - scsiinquiry(dev, buf, sizeof buf); - if(memcmp(&buf[8], "INSITE I325VM *F", 24) == 0) - scsimodesense(dev, 0x2e, buf, 0x2a); - /* - * read partition table from disk, null terminate - */ - b = scsibuf(); - if(waserror()){ - scsifree(b); - nexterror(); - } - scsibread(dev, b, 1, dp->bytes, dp->p[0].end-1); - rawpart = b->virt; - rawpart[dp->bytes-1] = 0; - - /* - * parse partition table. - */ - pp = &dp->p[2]; - n = getfields(rawpart, line, Npart+1, '\n'); - if(n > 0 && strncmp(line[0], MAGIC, sizeof(MAGIC)-1) == 0){ - for(i = 1; i < n; i++){ - if(getfields(line[i], field, 3, ' ') != 3) - break; - strncpy(pp->name, field[0], NAMELEN); - pp->start = strtoul(field[1], 0, 0); - pp->end = strtoul(field[2], 0, 0); - if(pp->start > pp->end || pp->start >= dp->p[0].end) - break; - pp++; - } - } - dp->npart = pp - dp->p; - poperror(); - scsifree(b); - poperror(); - qunlock(dp); -} diff --git a/port/netXXX.c b/port/netXXX.c deleted file mode 100644 index 5068b5747a6cccfadca4cea50c14d0e8c07c0b6b..0000000000000000000000000000000000000000 --- a/port/netXXX.c +++ /dev/null @@ -1,108 +0,0 @@ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" - -static void nulloput(Queue*, Block*); -static void protooput(Queue*, Block*); -static void protoiput(Queue*, Block*); - -static Qinfo XXXprotold = -{ - protoiput, - protooput, - 0, - 0, - "proto", - 0 -}; - -static Qinfo XXXmuxld = -{ - 0, - nulloput, - 0, - 0, - "mux" -}; - -static void -protooput(Queue *q, Block *bp) -{ - PUTNEXT(q, bp); -} - -static void -protoiput(Queue *q, Block *bp) -{ - PUTNEXT(q, bp); -} - -static void -nulloput(Queue *q, Block *bp) -{ - freeb(bp); -} - -static void XXXaddr(Chan*, char*, int); -static void XXXother(Chan*, char*, int); -static void XXXraddr(Chan*, char*, int); -static void XXXruser(Chan*, char*, int); -static int XXXclone(Chan*); -static void XXXconnect(Chan*, char*); - -Network netXXX = -{ - "XXX", - 4, - 32, /* # conversations */ - &XXXmuxld, - &XXXprotold, - 0, /* no listener */ - XXXclone, - XXXconnect, - 0, /* no announces */ - 4, /* info files */ - { { "addr", XXXaddr, }, - { "other", XXXother, }, - { "raddr", XXXraddr, }, - { "ruser", XXXruser, }, - }, -}; - -static void -XXXaddr(Chan *c, char *buf, int len) -{ - strncpy(buf, "my address", len-1); -} - -static void -XXXother(Chan *c, char *buf, int len) -{ - strncpy(buf, "other stuff", len-1); -} - -static void -XXXraddr(Chan *c, char *buf, int len) -{ - strncpy(buf, "remote address", len-1); -} - -static void -XXXruser(Chan *c, char *buf, int len) -{ - strncpy(buf, "remote user", len-1); -} - -static int -XXXclone(Chan *c) -{ - return 5; -} - -static void -XXXconnect(Chan *c, char *dest) -{ -} diff --git a/port/portdat.h b/port/portdat.h index 00bdd34709b4e8db0ca672cc0ca7103722c24e37..76c32d490290f9897d76d7cfacb64b04e77aeff6 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -9,7 +9,6 @@ typedef struct Evalue Evalue; typedef struct Fgrp Fgrp; typedef struct Image Image; typedef struct IOQ IOQ; -typedef struct KIOQ KIOQ; typedef struct List List; typedef struct Mntcache Mntcache; typedef struct Mount Mount; @@ -33,9 +32,6 @@ typedef struct Ref Ref; typedef struct Rendez Rendez; typedef struct RWlock RWlock; typedef struct Sargs Sargs; -typedef struct Scsi Scsi; -typedef struct Scsibuf Scsibuf; -typedef struct Scsidata Scsidata; typedef struct Segment Segment; typedef struct Session Session; typedef struct Talarm Talarm; @@ -174,53 +170,6 @@ struct Dirtab long perm; }; -/* SCSI devices. */ -enum -{ - ScsiTestunit = 0x00, - ScsiExtsens = 0x03, - ScsiInquiry = 0x12, - ScsiModesense = 0x1a, - ScsiStartunit = 0x1B, - ScsiStopunit = 0x1B, - ScsiGetcap = 0x25, - ScsiRead = 0x08, - ScsiWrite = 0x0a, - - /* data direction */ - ScsiIn = 1, - ScsiOut = 0, -}; - -struct Scsibuf -{ - void* virt; - void* phys; - Scsibuf* next; -}; - -struct Scsidata -{ - uchar* base; - uchar* lim; - uchar* ptr; -}; - -struct Scsi -{ - QLock; - ulong pid; - ushort target; - ushort lun; - ushort rflag; - ushort status; - Scsidata cmd; - Scsidata data; - Scsibuf* b; - uchar* save; - uchar cmdblk[16]; -}; - enum { NSMAX = 1000, diff --git a/port/portfns.h b/port/portfns.h index d8abdce25c71dba877558290b6594a58d1d12e71..456e2485fa954846e9e7ee73174cde6dceeb1571 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -11,9 +11,6 @@ void authreply(Session*, ulong, Fcall*); ulong authrequest(Session*, Fcall*); long authwrite(Chan*, char*, int); Page* auxpage(void); -void bitdebug(void); -void bitdepth(void); -void bitreverse(uchar*, int); void buzz(int, int); void cachedel(Image*, ulong); void cachepage(Page*, Image*); @@ -27,7 +24,6 @@ void chandevreset(void); void chanfree(Chan*); void chanrec(Mnt*); void checkalarms(void); -void clock(Ureg*); Chan* clone(Chan*, Chan*); void close(Chan*); void closeegrp(Egrp*); @@ -95,7 +91,6 @@ long ibrk(ulong, int); int incref(Ref*); void initscsi(void); void initseg(void); -void invalidateu(void); void isdir(Chan*); int iseve(void); int ispages(void*); @@ -214,19 +209,6 @@ void sched(void); void schedinit(void); int screenbits(void); void screenupdate(void); -int scsibread(int, Scsibuf*, long, long, long); -void scsibufreset(ulong); -int scsibwrite(int, Scsibuf*, long, long, long); -int scsicap(int, void*); -Scsi* scsicmd(int, int, Scsibuf*, long); -int scsiexec(Scsi*, int); -void scsifree(Scsibuf*); -int scsiinquiry(int, void*, int); -int scsimodesense(int, int, void*, int); -int scsiready(int); -int scsisense(int, void*); -int scsistartstop(int, int); -int scsiwp(int); long seconds(void); ulong segattach(Proc*, ulong, char *, ulong, ulong); void segpage(Segment*, Page*); @@ -235,7 +217,6 @@ void setkernur(Ureg*, Proc*); int setlabel(Label*); void setregisters(Ureg*, char*, char*, int); void setswapchan(Chan*); -void simpleputpage(Page*); char* skipslash(char*); void sleep(Rendez*, int(*)(void*), void*); void* smalloc(ulong); @@ -244,7 +225,6 @@ int spllo(void); void splx(int); void srvrecover(Chan*, Chan*); void swapinit(void); -long syscall(Ureg*); void tsleep(Rendez*, int (*)(void*), void*, int); void unbreak(Proc*); void uncachepage(Page*); @@ -252,7 +232,6 @@ long unicode(uchar*); long unionread(Chan*, void*, long); void unlock(Lock*); void unmount(Chan*, Chan*); -void urpfillstats(Chan*, char*, int); void userinit(void); ulong userpc(void); long userwrite(char*, int); @@ -272,8 +251,6 @@ void xsummary(void); Segment* data2txt(Segment*); Segment* dupseg(Segment**, int, int); Segment* newseg(int, ulong, ulong); -Scsibuf* scsialloc(ulong); -Scsibuf* scsibuf(void); Segment* seg(Proc*, ulong, int); diff --git a/power/fns.h b/power/fns.h index e160d48249ccced7ffd8a810f54914abfa9596cb..656d93e2ab3dd187f5aa45c80a41ad0eea75513e 100644 --- a/power/fns.h +++ b/power/fns.h @@ -2,6 +2,7 @@ void arginit(void); void clearmmucache(void); +void clock(Ureg*); void clockinit(void); ulong confeval(char*); void confread(void); @@ -64,6 +65,7 @@ void setvmevec(int, void (*)(int)); void sinit(void); uchar* smap(int, uchar*); void sunmap(int, uchar*); +long syscall(Ureg*); void sysloginit(void); void syslog(char*, int); void tlbinit(void);