From 585d88738b10a578d0e851ea3a685b25c0388877 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 10 Dec 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-12-10 --- pc/cga.c | 144 +++++++++++++++++++++++++++++++++++ pc/dat.h | 7 ++ pc/devuart.c | 11 ++- pc/fns.h | 12 ++- pc/headland.c | 175 ++---------------------------------------- pc/kbd.c | 63 ++++++++++++---- pc/main.c | 201 ++++++++++++++++++++----------------------------- pc/mem.h | 1 + pc/mmu.c | 24 +++--- pc/pmu.c | 149 ++++++++++++++++++++++++++++++++++++ port/devwren.c | 4 + 11 files changed, 470 insertions(+), 321 deletions(-) create mode 100644 pc/pmu.c diff --git a/pc/cga.c b/pc/cga.c index cdea7ed446290ac0c709a16132309d86eb4e7cd6..4789a13bf3815187983cbdcdde57957f98e9c6ec 100644 --- a/pc/cga.c +++ b/pc/cga.c @@ -12,7 +12,10 @@ int pos; void screeninit(void) { + void vgadump(void); + memset(SCREEN+pos, 0, WIDTH*HEIGHT-pos); + vgadump(); } void @@ -56,3 +59,144 @@ screenbits(void) { return 4; } + + +#include +#include +#include "screen.h" + +/* + * screen dimensions + */ +#define MAXX 640 +#define MAXY 480 + +#define SCREENMEM (0xA0000 | KZERO) +GBitmap gscreen = +{ + (ulong*)SCREENMEM, + 0, + 640/32, + 0, + 0, 0, MAXX, MAXY, + 0 +}; + +typedef struct VGAmode VGAmode; +struct VGAmode +{ + uchar general[4]; + uchar sequencer[5]; + uchar crt[0x19]; + uchar graphics[9]; + uchar attribute[0x15]; +}; + +enum +{ + EMISCR= 0x3CC, /* control sync polarity */ + EMISCW= 0x3C2, + EFCW= 0x3DA, /* feature control */ + EFCR= 0x3CA, + GRX= 0x3CE, /* index to graphics registers */ + GR= 0x3CF, /* graphics registers */ + Grms= 0x04, /* read map select register */ + SRX= 0x3C4, /* index to sequence registers */ + SR= 0x3C5, /* sequence registers */ + Smmask= 0x02, /* map mask */ + CRX= 0x3D4, /* index to crt registers */ + CR= 0x3D5, /* crt registers */ + Cvre= 0x11, /* vertical retrace end */ + ARX= 0x3C0, /* index to attribute registers */ + AR= 0x3C1, /* attribute registers */ +}; + +uchar +genin(int reg) +{ + if(reg == 0) + return inb(EMISCR); + else if (reg == 1) + return inb(EFCR); +} +uchar +srin(int reg) +{ + outb(SRX, reg); + return inb(SR); +} +uchar +grin(int reg) +{ + outb(GRX, reg); + return inb(GR); +} +uchar +arin(int reg) +{ + inb(0x3DA); + outb(ARX, reg | 0x20); + return inb(AR); +} +uchar +crin(int reg) +{ + outb(CRX, reg); + return inb(CR); +} + +void +vgadump(void) +{ + int i; + VGAmode *v; + + print("GEN "); + for(i = 0; i < sizeof(v->general); i++) + print("%d-%ux ", i, genin(i)); + print("\nSR "); + for(i = 0; i < sizeof(v->sequencer); i++) + print("%d-%ux ", i, srin(i)); + print("\nCR "); + for(i = 0; i < sizeof(v->crt); i++) + print("%d-%ux ", i, crin(i)); + print("\nGR "); + for(i = 0; i < sizeof(v->graphics); i++) + print("%d-%ux ", i, grin(i)); + print("\nAR "); + for(i = 0; i < sizeof(v->attribute); i++) + print("%d-%ux ", i, arin(i)); + print("\n "); +} + +void +bigcursor(void) +{} + +void +getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) +{ + ulong ans; + + /* + * The safari monochrome says 0 is black (zero intensity) + */ + if(p == 0) + ans = 0; + else + ans = ~0; + *pr = *pg = *pb = ans; +} + + +int +setcolor(ulong p, ulong r, ulong g, ulong b) +{ + return 0; /* can't change mono screen colormap */ +} + +void +mouseclock(void) +{ + mouseupdate(1); +} diff --git a/pc/dat.h b/pc/dat.h index a124ad219790ba30f6a24d96569d0bf62b2122ff..29bc3cd40c75e0697fc47ca8897ff7424cf5736a 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -193,3 +193,10 @@ extern Mach *m; extern User *u; extern int flipD[]; /* for flipping bitblt destination polarity */ + +enum +{ + At= 0, + Attnsx= 1, +}; +extern int machtype; diff --git a/pc/devuart.c b/pc/devuart.c index 7b1e30f08b4d4f59d40e6295f754f9db6d33b221..9f7cc3a403c26ca22a56e3dc9ca5bee1e73fbb97 100644 --- a/pc/devuart.c +++ b/pc/devuart.c @@ -303,10 +303,10 @@ uartenable(Uart *up) * turn on power to the port */ if(up == &uart[Serial]){ - if(serial(0) < 0) + if(serial(1) < 0) print("can't turn on serial port power\n"); } else { - if(modem(0) < 0) + if(modem(1) < 0) print("can't turn on modem speaker\n"); } @@ -358,8 +358,11 @@ uartdisable(Uart *up) * turn off power */ if(up == &uart[Serial]){ - if(serial(1) < 0) + if(serial(0) < 0) print("can't turn off serial power\n"); + } else { + if(modem(0) < 0) + print("can't turn off modem speaker\n"); } /* @@ -532,7 +535,7 @@ uartkproc(void *a) for(;;){ sleep(&cq->r, cangetc, cq); if((ints++ & 0x1f) == 0) - owl(ints>>5); + lights((ints>>5)&1); qlock(up); if(up->wq == 0){ cq->out = cq->in; diff --git a/pc/fns.h b/pc/fns.h index 68a78c00707c6bfecb44eaf76eea07f5e77c1b02..c80b7e93c360af94293cff5e36833aeabca23061 100644 --- a/pc/fns.h +++ b/pc/fns.h @@ -22,6 +22,11 @@ void fpsave(FPsave*); ulong fpstatus(void); ulong getcr0(void); ulong getcr2(void); +void heada20(void); +void headreset(void); +void i8042a20(void); +void i8042reset(void); +void ident(void); void idle(void); int inb(int); void inss(int, void*, int); @@ -31,8 +36,11 @@ void mmuinit(void); int modem(int); void outb(int, int); void outss(int, void*, int); -void owl(int); -int pmuwrbit(int, int, int); +void pmubuzz(int, int); +int pmucpuspeed(int); +void pmulights(int); +int pmumodem(int); +int pmuserial(int); void prhex(ulong); void procrestore(Proc*, uchar*); void procsave(uchar*, int); diff --git a/pc/headland.c b/pc/headland.c index f258a16ecad524e070f1f765310a380e6057090f..9f33126f83a043b7b4f06a3640ba1bfd19335ea2 100644 --- a/pc/headland.c +++ b/pc/headland.c @@ -3,14 +3,11 @@ #include "mem.h" #include "dat.h" #include "fns.h" +#include "io.h" /* - * headland chip set for the safari. + * headland system controller (ht21) */ -typedef struct DMAport DMAport; -typedef struct DMA DMA; -typedef struct DMAxfer DMAxfer; - enum { /* @@ -19,184 +16,22 @@ enum Head= 0x92, /* control port */ Reset= (1<<0), /* reset the 386 */ A20ena= (1<<1), /* enable address line 20 */ - - /* - * the byte registers for DMA0 are all one byte apart - */ - Dma0= 0x00, - Dma0status= Dma0+0x8, /* status port */ - Dma0reset= Dma0+0xD, /* reset port */ - - /* - * the byte registers for DMA1 are all two bytes apart (why?) - */ - Dma1= 0xC0, - Dma1status= Dma1+2*0x8, /* status port */ - Dma1reset= Dma1+2*0xD, /* reset port */ -}; - -/* - * state of a dma transfer - */ -struct DMAxfer -{ - Page *pg; /* page used by dma */ - void *va; /* virtual address destination/src */ - long len; /* bytes to be transferred */ - int isread; -}; - -/* - * the dma controllers. the first half of this structure specifies - * the I/O ports used by the DMA controllers. - */ -struct DMAport -{ - uchar addr[4]; /* current address (4 channels) */ - uchar count[4]; /* current count (4 channels) */ - uchar page[4]; /* page registers (4 channels) */ - uchar cmd; /* command status register */ - uchar req; /* request registers */ - uchar sbm; /* single bit mask register */ - uchar mode; /* mode register */ - uchar cbp; /* clear byte pointer */ - uchar mc; /* master clear */ - uchar cmask; /* clear mask register */ - uchar wam; /* write all mask register bit */ - - Lock; -}; - -struct DMA -{ - DMAport; - Lock; - DMAxfer x[4]; -}; - -DMA dma[2] = { - { 0x00, 0x02, 0x04, 0x06, - 0x01, 0x03, 0x05, 0x07, - 0x87, 0x83, 0x81, 0x82, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, - { 0xc0, 0xc6, 0xca, 0xce, - 0xc4, 0xc8, 0xcc, 0xcf, - 0x80, 0x8b, 0x89, 0x8a, - 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde }, }; /* * enable address bit 20 */ void -a20enable(void) +heada20(void) { outb(Head, A20ena); } /* - * reset the chip + * reset machine */ void -exit(void) +headreset(void) { - int i; - - u = 0; - print("exiting\n"); outb(Head, Reset); } - -/* - * setup a dma transfer. if the destination is not in kernel - * memory, allocate a page for the transfer. - * - * we assume BIOS has set up the command register before we - * are booted. - * - * return the updated transfer length (we can't transfer across 64k - * boundaries) - */ -long -dmasetup(int chan, void *va, long len, int isread) -{ - DMA *dp; - DMAxfer *xp; - ulong pa; - uchar mode; - - dp = &dma[(chan>>2)&1]; - chan = chan & 3; - xp = &dp->x[chan]; - - /* - * if this isn't kernel memory (or crossing 64k boundary), - * allocate a page for the DMA. - */ - pa = ((ulong)va) & ~KZERO; - if(!isphys(va) || (pa&0xFFFF0000)!=((pa+len)&0xFFFF0000)){ - xp->pg = newpage(1, 0, 0); - if(len > BY2PG) - len = BY2PG; - if(!isread) - memmove((void*)(KZERO|xp->pg->pa), va, len); - xp->va = va; - xp->len = len; - xp->isread = isread; - pa = xp->pg->pa; - } - - /* - * this setup must be atomic - */ - lock(dp); - outb(dp->cbp, 0); /* set count & address to their first byte */ - mode = (isread ? 0x44 : 0x48) | chan; - outb(dp->mode, mode); /* single mode dma (give CPU a chance at mem) */ - outb(dp->addr[chan], pa); /* set address */ - outb(dp->addr[chan], pa>>8); - outb(dp->page[chan], pa>>16); - outb(dp->count[chan], len-1); /* set count */ - outb(dp->count[chan], (len-1)>>8); - outb(dp->sbm, chan); /* enable the channel */ - unlock(dp); - - return len; -} - -/* - * this must be called after a dma has been completed. - * - * if a page has been allocated for the dma, - * copy the data into the actual destination - * and free the page. - */ -void -dmaend(int chan) -{ - DMA *dp; - DMAxfer *xp; - ulong addr; - uchar mode; - - dp = &dma[(chan>>2)&1]; - chan = chan & 3; - - /* - * disable the channel - */ - lock(dp); - outb(dp->sbm, 4|chan); - unlock(dp); - - xp = &dp->x[chan]; - if(xp->pg == 0) - return; - - /* - * copy out of temporary page - */ - memmove(xp->va, (void*)(KZERO|xp->pg->pa), xp->len); - putpage(xp->pg); - xp->pg = 0; -} diff --git a/pc/kbd.c b/pc/kbd.c index a8810594db36ed7c0e4d6ed2b4da9c633ed0a1de..e44519062ffc19ceb1e6d747bf6e8f70d204e5c6 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -169,6 +169,32 @@ mousecmd(int cmd) return 0; } +/* + * ask 8042 to enable the use of address bit 20 + */ +void +i8042a20(void) +{ + outready(); + outb(Cmd, 0xD1); + outready(); + outb(Data, 0xDF); + outready(); +} + +/* + * ask 8042 to reset the 386 + */ +void +i8042reset(void) +{ + outready(); + outb(Cmd, 0xD1); + outready(); + outb(Data, 0xDE); + outready(); +} + void kbdinit(void) { @@ -185,19 +211,30 @@ kbdinit(void) if(c & Inready) inb(Data); - /* enable kbd/mouse xfers and interrupts */ - outb(Cmd, 0x60); - if(outready() < 0) - print("kbd init failed\n"); - outb(Data, 0x47); /* BUG -- on 6300 0x65 */ - if(outready() < 0) - print("kbd init failed\n"); - outb(Cmd, 0xA8); /* BUG -- should this be AE? */ - - /* make mouse streaming, enabled */ - if(mousecmd(0xEA) < 0 - || mousecmd(0xF4) < 0) - print("can't initialize mouse\n"); + switch(machtype){ + case Attnsx: + /* enable kbd/mouse xfers and interrupts */ + outb(Cmd, 0x60); + if(outready() < 0) + print("kbd init failed\n"); + outb(Data, 0x47); + if(outready() < 0) + print("kbd init failed\n"); + outb(Cmd, 0xA8); + + /* make mouse streaming, enabled */ + if(mousecmd(0xEA) < 0 + || mousecmd(0xF4) < 0) + print("can't initialize mouse\n"); + break; + case At: + /* enable kbd xfers and interrupts */ + outb(Cmd, 0x60); + if(outready() < 0) + print("kbd init failed\n"); + outb(Data, 0x65); + break; + } } /* diff --git a/pc/main.c b/pc/main.c index 90014ae62fea7854c21e4db89be59a2db2e320bc..9c19f5b6e26fcaf201057e24255ab350588d3a9b 100644 --- a/pc/main.c +++ b/pc/main.c @@ -8,10 +8,12 @@ #include "init.h" extern long edata; +int machtype; void main(void) { + ident(); meminit(); machinit(); active.exiting = 0; @@ -41,6 +43,18 @@ main(void) schedinit(); } +void +ident(void) +{ + char *id = (char*)(ROMBIOS + 0xFF40); + + /* check for a safari (tres special) */ + if(strncmp(id, "AT&TNSX", 7) == 0) + machtype = Attnsx; + else + machtype = At; +} + void machinit(void) { @@ -342,42 +356,26 @@ firmware(void) } /* - * special stuff for 80c51 power management and headland system controller + * the following functions all are slightly different from + * PC to PC. */ -enum -{ - /* - * system control port - */ - Head= 0x92, /* control port */ - Reset= (1<<0), /* reset the 386 */ - A20ena= (1<<1), /* enable address line 20 */ - /* - * power management unit ports - */ - Pmudata= 0x198, - - Pmucsr= 0x199, - Busy= 0x1, - - /* - * configuration port - */ - Pconfig= 0x3F3, -}; - -/* - * enable address bit 20 - */ +/* enable address bit 20 (extended memory) */ void meminit(void) { - outb(Head, A20ena); /* enable memory address bit 20 */ + switch(machtype){ + case Attnsx: + heada20(); /* via headland chip */ + break; + case At: + i8042a20(); /* via keyboard controller */ + break; + } } /* - * reset the chip + * reset the i387 chip */ void exit(void) @@ -386,128 +384,91 @@ exit(void) u = 0; print("exiting\n"); - outb(Head, Reset); + switch(machtype){ + case Attnsx: + headreset(); /* via headland chip */ + break; + case At: + i8042reset(); /* via keyboard controller */ + break; + } } /* - * return when pmu ready + * set cpu speed + * 0 == low speed + * 1 == high speed */ -static int -pmuready(void) +int +cpuspeed(int speed) { - int tries; - - for(tries = 0; (inb(Pmucsr) & Busy); tries++) - if(tries > 1000) - return -1; - return 0; + switch(machtype){ + case Attnsx: + return pmucpuspeed(speed); + default: + return 0; + } } /* - * return when pmu busy + * f == frequency (Hz) + * d == duration (ms) */ -static int -pmubusy(void) +void +buzz(int f, int d) { - int tries; - - for(tries = 0; !(inb(Pmucsr) & Busy); tries++) - if(tries > 1000) - return -1; - return 0; + switch(machtype){ + case Attnsx: + pmubuzz(f, d); + break; + default: + break; + } } /* - * set a bit in the PMU + * each bit in val stands for a light */ -Lock pmulock; -int -pmuwrbit(int index, int bit, int pos) +void +lights(int val) { - lock(&pmulock); - outb(Pmucsr, 0x02); /* next is command request */ - if(pmuready() < 0){ - unlock(&pmulock); - return -1; - } - outb(Pmudata, (2<<4) | index); /* send write bit command */ - outb(Pmucsr, 0x01); /* send available */ - if(pmubusy() < 0){ - unlock(&pmulock); - return -1; - } - outb(Pmucsr, 0x01); /* next is data */ - if(pmuready() < 0){ - unlock(&pmulock); - return -1; - } - outb(Pmudata, (bit<<3) | pos); /* send bit to write */ - outb(Pmucsr, 0x01); /* send available */ - if(pmubusy() < 0){ - unlock(&pmulock); - return -1; + switch(machtype){ + case Attnsx: + pmulights(val); + break; + default: + break; } - unlock(&pmulock); - return 0; } /* * power to serial port - * onoff == 0 means on - * onoff == 1 means off + * onoff == 1 means on + * onoff == 0 means off */ int serial(int onoff) { - return pmuwrbit(1, onoff, 6); + switch(machtype){ + case Attnsx: + return pmuserial(onoff); + default: + return 0; + } } /* * power to modem - * onoff == 0 means on - * onoff == 1 means off + * onoff == 1 means on + * onoff == 0 means off */ int modem(int onoff) { - if(pmuwrbit(1, onoff, 0)<0) - return -1; - return pmuwrbit(1, 1^onoff, 5); -} - -/* - * CPU speed - * onoff == 0 means 2 MHZ - * onoff == 1 means 20 MHZ - */ -int -cpuspeed(int speed) -{ - return pmuwrbit(0, speed, 0); -} - -void -buzz(int f, int d) -{ - static Rendez br; - static QLock bl; - - qlock(&bl); - pmuwrbit(0, 0, 6); - tsleep(&br, return0, 0, d); - pmuwrbit(0, 1, 6); - qunlock(&bl); -} - -void -lights(int val) -{ - pmuwrbit(0, (val&1), 4); /* owl */ - pmuwrbit(0, ((val>>1)&1), 1); /* mail */ -} - -void -owl(int val) -{ - pmuwrbit(0, (val&1), 4); /* owl */ + switch(machtype){ + case Attnsx: + return pmumodem(onoff); + default: + return 0; + } } diff --git a/pc/mem.h b/pc/mem.h index c30a27b7b1ddf6e5adc9e1951d8f6ff03154e848..74d0b0a6e34e6686bb3de8edb59e7e3b9c02f3bd 100644 --- a/pc/mem.h +++ b/pc/mem.h @@ -48,6 +48,7 @@ #define TSTKSIZ 10 #define USTKTOP (TSTKTOP-TSTKSIZ*BY2PG) /* byte just beyond user stack */ #define USTKSIZE (16*1024*1024 - TSTKSIZ*BY2PG) /* size of user stack */ +#define ROMBIOS (KZERO|0xF0000) #define MACHSIZE 4096 diff --git a/pc/mmu.c b/pc/mmu.c index 33aef5a5956bca020d78a2c389bd3cfe18ea1d0d..3c781992d2cc624f353b9df2cd8e37080f6baa14 100644 --- a/pc/mmu.c +++ b/pc/mmu.c @@ -128,33 +128,33 @@ mmuinit(void) /* * set up system page tables. * map all of physical memory to start at KZERO. + * map ROM BIOS at the usual place (F0000000). * leave a map entry for a user area. */ - /* allocate and fill low level page tables for kernel mem */ + /* allocate top level table */ + top = ialloc(BY2PG, 1); + ktoppg.va = (ulong)top; + ktoppg.pa = ktoppg.va & ~KZERO; + + /* map all memory to KZERO */ npage = conf.base1/BY2PG + conf.npage1; nbytes = PGROUND(npage*BY2WD); /* words of page map */ nkpt = nbytes/BY2PG; /* pages of page map */ kpt = ialloc(nbytes, 1); for(i = 0; i < npage; i++) - kpt[i] = (i< */ - upt = ialloc(BY2PG, 1); - - /* allocate top level table and put pointers to lower tables in it */ - top = ialloc(BY2PG, 1); - ktoppg.va = (ulong)top; - ktoppg.pa = ktoppg.va & ~KZERO; + kpt[i] = (0+i*BY2PG) | PTEVALID | PTEKERNEL | PTEWRITE; x = TOPOFF(KZERO); y = ((ulong)kpt)&~KZERO; for(i = 0; i < nkpt; i++) top[x+i] = (y+i*BY2PG) | PTEVALID | PTEKERNEL | PTEWRITE; + + /* page table for u-> */ + upt = ialloc(BY2PG, 1); x = TOPOFF(USERADDR); y = ((ulong)upt)&~KZERO; top[x] = y | PTEVALID | PTEKERNEL | PTEWRITE; + putcr3(ktoppg.pa); /* diff --git a/pc/pmu.c b/pc/pmu.c new file mode 100644 index 0000000000000000000000000000000000000000..c991abda8c148793cefe77cfcf3157d107e42ccc --- /dev/null +++ b/pc/pmu.c @@ -0,0 +1,149 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +/* + * intel power management unit (i80c51) + */ +enum { + /* + * power management unit ports + */ + Pmudata= 0x198, + + Pmucsr= 0x199, + Busy= 0x1, + + /* + * configuration port + */ + Pconfig= 0x3F3, +}; + +/* + * return when pmu ready + */ +static int +pmuready(void) +{ + int tries; + + for(tries = 0; (inb(Pmucsr) & Busy); tries++) + if(tries > 1000) + return -1; + return 0; +} + +/* + * return when pmu busy + */ +static int +pmubusy(void) +{ + int tries; + + for(tries = 0; !(inb(Pmucsr) & Busy); tries++) + if(tries > 1000) + return -1; + return 0; +} + +/* + * set a bit in the PMU + */ +Lock pmulock; +int +pmuwrbit(int index, int bit, int pos) +{ + lock(&pmulock); + outb(Pmucsr, 0x02); /* next is command request */ + if(pmuready() < 0){ + unlock(&pmulock); + return -1; + } + outb(Pmudata, (2<<4) | index); /* send write bit command */ + outb(Pmucsr, 0x01); /* send available */ + if(pmubusy() < 0){ + unlock(&pmulock); + return -1; + } + outb(Pmucsr, 0x01); /* next is data */ + if(pmuready() < 0){ + unlock(&pmulock); + return -1; + } + outb(Pmudata, (bit<<3) | pos); /* send bit to write */ + outb(Pmucsr, 0x01); /* send available */ + if(pmubusy() < 0){ + unlock(&pmulock); + return -1; + } + unlock(&pmulock); + return 0; +} + +/* + * power to serial port + * onoff == 1 means on + * onoff == 0 means off + */ +int +pmuserial(int onoff) +{ + return pmuwrbit(1, 1^onoff, 6); +} + +/* + * power to modem + * onoff == 1 means on + * onoff == 0 means off + */ +int +pmumodem(int onoff) +{ + if(pmuwrbit(1, 1^onoff, 0)<0) /* modem speaker */ + return -1; + return pmuwrbit(1, onoff, 5); /* modem power */ +} + +/* + * set cpu speed + * 0 == low speed + * 1 == high speed + */ +int +pmucpuspeed(int speed) +{ + return pmuwrbit(0, speed, 0); +} + +/* + * f == frequency in Hz + * d == duration in ms + */ +void +pmubuzz(int f, int d) +{ + static QLock bl; + static Rendez br; + + qlock(&bl); + pmuwrbit(0, 0, 6); + tsleep(&br, return0, 0, d); + pmuwrbit(0, 1, 6); + qunlock(&bl); +} + +/* + * 1 == owl eye + * 2 == mail icon + */ +void +pmulights(int val) +{ + pmuwrbit(0, (val&1), 4); /* owl */ + pmuwrbit(0, ((val>>1)&1), 1); /* mail */ +} diff --git a/port/devwren.c b/port/devwren.c index 5efa396c8a3cc1ffa59a588eff63514f8c3db5a6..7353c6a544bc33e47e0967f8a4afcd51db82cfca 100644 --- a/port/devwren.c +++ b/port/devwren.c @@ -150,23 +150,27 @@ wrenopen(Chan *c, int omode) 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); }