M carrera/fns.h => carrera/fns.h +2 -0
@@ 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*);
M pc/clock.c => pc/clock.c +39 -37
@@ 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();
-}
M pc/devether.c => pc/devether.c +1 -24
@@ 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<<ctlr->irq)) == 0){
- setvec(Int0vec+ctlr->irq, etherintr);
+ setvec(Int0vec+ctlr->irq, ctlr->interrupt, ctlr);
irqmask |= 1<<ctlr->irq;
}
M pc/devfloppy.c => pc/devfloppy.c +5 -5
@@ 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:
M pc/devhard.c => pc/devhard.c +5 -5
@@ 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;
D pc/devuart.c => pc/devuart.c +0 -891
@@ 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);
-}
M pc/ether509.c => pc/ether509.c +6 -1
@@ 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){
M pc/ether8390.c => pc/ether8390.c +5 -1
@@ 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;
M pc/etherif.h => pc/etherif.h +1 -1
@@ 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 */
M pc/fault386.c => pc/fault386.c +5 -3
@@ 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);
}
M pc/fns.h => pc/fns.h +2 -6
@@ 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)
M pc/kbd.c => pc/kbd.c +193 -203
@@ 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);
@@ 341,145 357,10 @@ ct82c710(void)
}
/*
- * 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();
}
M pc/main.c => pc/main.c +11 -9
@@ 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);
}
/*
M pc/mmu.c => pc/mmu.c +4 -7
@@ 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);
}
/*
M pc/trap.c => pc/trap.c +15 -11
@@ 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;
}
/*
D port/crc_16.h => port/crc_16.h +0 -35
@@ 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
D port/devbit.c => port/devbit.c +0 -2304
@@ 1,2304 0,0 @@
-#include "u.h"
-#include "../port/lib.h"
-#include <libg.h>
-#include <gnot.h>
-#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; i<bit.nsubfont; i++){
- s = bit.subfont[i];
- if(s && s!=bdefont && s->ref==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; i<bit.narena; i++){
- a = &bit.arena[i];
- if(a->words){
- 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; i<bit.nmap; i++)
- if(bit.map[i])
- l++;
- print("%d bitmaps ", l);
- l = 0;
- for(i=0; i<bit.nfont; i++)
- if(bit.font[i])
- l++;
- print("%d fonts ", l);
- l = 0;
- for(i=0; i<bit.nsubfont; i++)
- if(bit.subfont[i]){
- print("%d: %lux %lux ", i, bit.subfont[i]->qid[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; bp<ebp; bp++){
- b = *bp;
- if(b){
- bitfree(b);
- *bp = 0;
- }
- }
- esp = &bit.subfont[bit.nsubfont];
- for(sp=bit.subfont; sp<esp; sp++){
- s = *sp;
- if(s)
- subfontfree(s, sp-bit.subfont);
- /* don't clear *sp: cached */
- }
- efp = &bit.font[bit.nfont];
- for(fp=bit.font; fp<efp; fp++){
- f = *fp;
- if(f){
- fontfree(f);
- *fp = 0;
- }
- }
- }
- unlock(&bit);
- }
-}
-
-long
-bitread(Chan *c, void *va, long n, ulong offset)
-{
- uchar *p, *q;
- long miny, maxy, t, x, y;
- ulong l, nw, ws, rv, gv, bv;
- int off, j;
- Fontchar *i;
- GBitmap *src;
- BSubfont *s;
-
- if(c->qid.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; y<maxy; y++){
- q = (uchar*)gaddr(&gscreen, Pt(0, y));
- memmove(p, q, l);
- if(flipping)
- /* is screen, so must be word aligned */
- for(x=0; x<l; x+=sizeof(ulong),p+=sizeof(ulong))
- *(ulong*)p ^= ~0;
- else
- p += l;
- n += l;
- }
- return n;
- }
- if(c->qid.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<<src->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 || miny<src->r.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; y<maxy; y++){
- q = (uchar*)gaddr(src, Pt(src->r.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<l; x+=sizeof(ulong),p+=sizeof(ulong))
- *(ulong*)p ^= ~0;
- else
- p += l;
- n += l;
- }
- if(off)
- cursoron(1);
- bit.rid = -1;
- }
-
- poperror();
- qunlock(&bit);
- return n;
-}
-
-Point
-bitstrsize(GFont *f, uchar *p, int l)
-{
- ushort r;
- Point s = {0,0};
- GCacheinfo *c;
-
- while(l > 0){
- r = BGSHORT(p);
- p += 2;
- l -= 2;
- if(r >= f->ncache)
- continue;
- c = &f->cache[r];
- if(c->bottom > s.y)
- s.y = c->bottom;
- s.x += c->width;
- }
- return s;
-}
-
-long
-bitwrite(Chan *c, void *va, long n, ulong offset)
-{
- 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(; i<bit.nsubfont; i++){
- f = bit.subfont[i];
- if(f && f->qid[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; i<bit.nsubfont; i++)
- if(bit.subfont[i] == 0)
- goto subfontfound;
- fp = bitmalloc((bit.nsubfont+DMAP)*sizeof(BSubfont*));
- if(fp == 0)
- error(Enomem);
- memmove(fp, bit.subfont, bit.nsubfont*sizeof(BSubfont*));
- free(bit.subfont);
- bit.subfont = fp;
- bit.nsubfont += DMAP;
- subfontfound:
- f = bitmalloc(sizeof(BSubfont));
- if(f == 0)
- error(Enomem);
- f->info = 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; j<bit.nsubfont; j++){
- if(j == i)
- continue;
- tf = bit.subfont[j];
- if(tf && tf->qid[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; i<bit.nfont; i++)
- if(bit.font[i] == 0)
- goto fontfound;
- ffp = bitmalloc((bit.nfont+DMAP)*sizeof(GFont*));
- if(ffp == 0)
- error(Enomem);
- memmove(ffp, bit.font, bit.nfont*sizeof(GFont*));
- free(bit.font);
- bit.font = ffp;
- bit.nfont += DMAP;
- fontfound:
- ff = bitmalloc(sizeof(GFont));
- if(ff == 0)
- error(Enomem);
- ff->ncache = 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 || miny<src->r.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 || miny<dst->r.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; y<maxy; y++){
- oq = (uchar*)gaddr(dst, Pt(dst->r.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<l; x+=sizeof(ulong))
- *lp++ ^= ~0;
- }
- p += l;
- m -= l;
- }
- break;
-
- case 'x':
- /*
- * cursorset
- *
- * 'x' 1
- * pt 8
- */
- if(m < 9)
- error(Ebadblt);
- pt1.x = BGLONG(p+1);
- pt1.y = BGLONG(p+5);
- if(ptinrect(pt1, gscreen.r)){
- mouse.xy = pt1;
- mouse.redraw = 1;
- mouse.track = 1;
- mouseclock();
- }
- m -= 9;
- p += 9;
- break;
-
- case 'y':
- /*
- * load font from subfont
- * 'y' 1
- * id 2
- * cache index 2
- * subfont id 2
- * subfont index 2
- */
- if(m < 9)
- error(Ebadblt);
- v = BGSHORT(p+1);
- if(v<0 || v>=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; a<ea; a++){
- if(a->words == 0)
- continue;
- if(a->wfree+HDR+nw <= a->words+a->nwords)
- goto found;
- }
-
- /* compact and try again */
- bitcompact();
- aa = 0;
- for(a=bit.arena; a<ea; a++){
- if(a->words == 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; a<ea; a++){
- if(a->words == 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; bp<ep; bp++)
- if(*bp == 0)
- break;
- if(bp == ep){
- bp = bitmalloc((bit.nmap+DMAP)*sizeof(GBitmap*));
- if(bp == 0){
- bitfree(b);
- error(Enomem);
- }
- memmove(bp, bit.map, bit.nmap*sizeof(GBitmap*));
- free(bit.map);
- bit.map = bp;
- bp += bit.nmap;
- bit.nmap += DMAP;
- }
- *bp = b;
- return bp-bit.map;
-}
-
-void
-bitfree(GBitmap *b)
-{
- Arena *a;
-
- if(b->base != 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; a<ea; a++){
- if(a->words == 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(na<ea && p1<a->words+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; a<ea; a++)
- if(a->words && 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];
-}
D port/devcdrom.c => port/devcdrom.c +0 -234
@@ 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<target>
- */
-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);
-}
D port/devscc.c => port/devscc.c +0 -814
@@ 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("<start %2.2ux>", 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);
-}
D port/devscsi.c => port/devscsi.c +0 -536
@@ 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;
-}
D port/devwren.c => port/devwren.c +0 -336
@@ 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<target>.<lun>
- */
-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);
-}
D port/netXXX.c => port/netXXX.c +0 -108
@@ 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)
-{
-}
M port/portdat.h => port/portdat.h +0 -51
@@ 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,
M port/portfns.h => port/portfns.h +0 -23
@@ 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);
M power/fns.h => power/fns.h +2 -0
@@ 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);