M port/devmnt.c => port/devmnt.c +1 -1
@@ 250,7 250,7 @@ mntclone(Chan *c, Chan *nc)
nc = newchan();
alloc = 1;
}
- if(waserror()){
+ if(waserror()) {
mntfree(r);
if(alloc)
close(nc);
M port/devproc.c => port/devproc.c +21 -16
@@ 21,7 21,8 @@ enum{
};
#define STATSIZE (2*NAMELEN+12+7*12)
-Dirtab procdir[]={
+Dirtab procdir[] =
+{
"ctl", {Qctl}, 0, 0000,
"mem", {Qmem}, 0, 0000,
"note", {Qnote}, 0, 0000,
@@ 53,13 54,14 @@ char *sname[]={ "Text", "Data", "Bss", "Stack", "Shared", "Phys", "Shdata" };
void procctlreq(Proc*, char*, int);
int procctlmemio(Proc*, ulong, int, void*, int);
-Chan *proctext(Chan*, Proc*);
-Segment *txt2data(Proc*, Segment*);
+Chan* proctext(Chan*, Proc*);
+Segment* txt2data(Proc*, Segment*);
int procstopped(void*);
int
procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
{
+ Qid qid;
Proc *p;
char buf[NAMELEN];
ulong pid, path, perm;
@@ 73,13 75,15 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
if(pid == 0)
return 0;
sprint(buf, "%d", pid);
- devdir(c, (Qid){CHDIR|((s+1)<<QSHIFT), pid}, buf, 0, p->user, CHDIR|0555, dp);
+ qid = (Qid){CHDIR|((s+1)<<QSHIFT), pid};
+ devdir(c, qid, buf, 0, p->user, CHDIR|0555, dp);
return 1;
}
if(s >= NPROC)
return -1;
if(tab)
panic("procgen");
+
tab = &procdir[s];
path = c->qid.path&~(CHDIR|((1<<QSHIFT)-1)); /* slot component */
@@ 88,7 92,8 @@ procgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
if(perm == 0)
perm = p->procmode;
- devdir(c, (Qid){path|tab->qid.path, c->qid.vers}, tab->name, tab->length, p->user, perm, dp);
+ qid = (Qid){path|tab->qid.path, c->qid.vers};
+ devdir(c, qid, tab->name, tab->length, p->user, perm, dp);
return 1;
}
@@ 156,7 161,6 @@ procopen(Chan *c, int omode)
error(Eperm);
tc = proctext(c, p);
tc->offset = 0;
-
return tc;
case Qctl:
@@ 168,11 172,12 @@ procopen(Chan *c, int omode)
break;
case Qnotepg:
- if(omode!=OWRITE || pg->pgrpid==1) /* easy to do by mistake */
+ if(omode!=OWRITE || pg->pgrpid == 1)
error(Eperm);
- c->pgrpid.path = pg->index+1;
+ c->pgrpid.path = pg->pgrpid+1;
c->pgrpid.vers = p->noteid;
break;
+
default:
pprint("procopen %lux\n", c->qid);
error(Egreg);
@@ 263,6 268,10 @@ procread(Chan *c, void *va, long n, ulong offset)
}
if(offset >= KZERO) {
+ /* Protect crypt key memory */
+ if(offset >= palloc.cmembase && offset < palloc.cmemtop)
+ error(Eperm);
+
/* validate physical kernel addresses */
if(offset < (ulong)end) {
if(offset+n > (ulong)end)
@@ 332,11 341,6 @@ procread(Chan *c, void *va, long n, ulong offset)
if(offset+n > STATSIZE)
n = STATSIZE - offset;
-/* Assertion for deref of psstate which causes faults */
-if((p->state < Dead) || (p->state > Rendezvous))
- panic("p->state=#%lux, p->psstate=#%lux\n", p->state, p->psstate);
-
-
j = sprint(statbuf, "%-27s %-27s %-11s ",
p->text, p->user, p->psstate ? p->psstate : statename[p->state]);
for(i=0; i<6; i++){
@@ 424,7 428,8 @@ procwrite(Chan *c, void *va, long n, ulong offset)
pxu = (User*)b;
hi = offset+n;
/* Check for floating point registers */
- if(offset >= (ulong)&u->fpsave && hi <= (ulong)&u->fpsave+sizeof(FPsave)){
+ if(offset >= (ulong)&u->fpsave &&
+ hi <= (ulong)&u->fpsave+sizeof(FPsave)){
memmove(b+(offset-USERADDR), a, n);
break;
}
@@ 598,9 603,9 @@ procstopped(void *a)
int
procctlmemio(Proc *p, ulong offset, int n, void *va, int read)
{
+ KMap *k;
Pte *pte;
Page *pg;
- KMap *k;
Segment *s;
ulong soff, l;
char *a = va, *b;
@@ 660,8 665,8 @@ procctlmemio(Proc *p, ulong offset, int n, void *va, int read)
Segment *
txt2data(Proc *p, Segment *s)
{
- Segment *ps;
int i;
+ Segment *ps;
ps = newseg(SG_DATA, s->base, s->size);
ps->image = s->image;
M port/error.h => port/error.h +1 -0
@@ 53,3 53,4 @@ extern char Eneedservice[]; /* service required for tcp/udp/il calls */
extern char Enomem[]; /* kernel allocate failed */
extern char Esfnotcached[]; /* subfont not cached */
extern char Egreg[]; /* it's a thermal problem */
+extern char Esoverlap[]; /* segments overlap */
M port/pgrp.c => port/pgrp.c +120 -73
@@ 8,6 8,52 @@
static Ref pgrpid;
static Ref mountid;
+struct
+{
+ Lock;
+ Crypt *free;
+} cryptalloc;
+
+/*
+ * crypt entries are allocated from a pool rather than allocated using malloc so
+ * the memory can be protected from reading by devproc. The base and top of the
+ * crypt arena is stored in palloc for devproc.
+ */
+Crypt*
+newcrypt(void)
+{
+ Crypt *c;
+
+ lock(&cryptalloc);
+ if(cryptalloc.free) {
+ c = cryptalloc.free;
+ cryptalloc.free = c->next;
+ unlock(&cryptalloc);
+ return c;
+ }
+
+ cryptalloc.free = malloc(sizeof(Crypt)*conf.nproc);
+ if(cryptalloc.free == 0)
+ panic("newcrypt");
+
+ for(c = cryptalloc.free+1; c < cryptalloc.free+conf.nproc-1; c++)
+ c->next = c+1;
+
+ palloc.cmembase = (ulong)cryptalloc.free;
+ palloc.cmembase = palloc.cmembase+(sizeof(Crypt)*conf.nproc);
+ unlock(&cryptalloc);
+ return newcrypt();
+}
+
+void
+freecrypt(Crypt *c)
+{
+ lock(&cryptalloc);
+ c->next = cryptalloc.free;
+ cryptalloc.free = c;
+ unlock(&cryptalloc);
+}
+
void
pgrpnote(ulong noteid, char *a, long n, int flag)
{
@@ 26,11 72,11 @@ pgrpnote(ulong noteid, char *a, long n, int flag)
continue;
if(p->noteid == noteid && p->kp == 0) {
qlock(&p->debug);
- if(p->pid==0 || p->noteid != noteid){
+ if(p->pid == 0 || p->noteid != noteid){
qunlock(&p->debug);
continue;
}
- if(!waserror()){
+ if(!waserror()) {
postnote(p, 0, buf, flag);
poperror();
}
@@ 44,53 90,13 @@ newpgrp(void)
{
Pgrp *p;
- p = smalloc(sizeof(Pgrp)+sizeof(Crypt));
+ p = smalloc(sizeof(Pgrp));
p->ref = 1;
- /* This needs to have its own arena for protection */
- p->crypt = (Crypt*)((uchar*)p+sizeof(Pgrp));
+ p->crypt = newcrypt();
p->pgrpid = incref(&pgrpid);
return p;
}
-Fgrp*
-dupfgrp(Fgrp *f)
-{
- Fgrp *new;
- Chan *c;
- int i;
-
- new = smalloc(sizeof(Fgrp));
- new->ref = 1;
-
- lock(f);
- new->maxfd = f->maxfd;
- for(i = 0; i <= f->maxfd; i++)
- if(c = f->fd[i]){
- incref(c);
- new->fd[i] = c;
- }
- unlock(f);
-
- return new;
-}
-
-void
-resrcwait(char *reason)
-{
- char *p;
-
- p = u->p->psstate;
- if(reason) {
- u->p->psstate = reason;
- print("%s\n", reason);
- }
- if(u == 0)
- panic("resrcwait");
-
- tsleep(&u->p->sleep, return0, 0, 1000);
- u->p->psstate = p;
-}
-
void
closepgrp(Pgrp *p)
{
@@ 110,40 116,12 @@ closepgrp(Pgrp *p)
}
}
qunlock(&p->debug);
+ freecrypt(p->crypt);
free(p);
}
}
void
-closefgrp(Fgrp *f)
-{
- int i;
- Chan *c;
-
- if(decref(f) == 0) {
- for(i = 0; i <= f->maxfd; i++)
- if(c = f->fd[i])
- close(c);
-
- free(f);
- }
-}
-
-
-Mount*
-newmount(Mhead *mh, Chan *to)
-{
- Mount *m;
-
- m = smalloc(sizeof(Mount));
- m->to = to;
- m->head = mh;
- incref(to);
- m->mountid = incref(&mountid);
- return m;
-}
-
-void
pgrpcpy(Pgrp *to, Pgrp *from)
{
Mhead **h, **e, *f, **tom, **l, *mh;
@@ 173,6 151,58 @@ pgrpcpy(Pgrp *to, Pgrp *from)
runlock(&from->ns);
}
+Fgrp*
+dupfgrp(Fgrp *f)
+{
+ Fgrp *new;
+ Chan *c;
+ int i;
+
+ new = smalloc(sizeof(Fgrp));
+ new->ref = 1;
+
+ lock(f);
+ new->maxfd = f->maxfd;
+ for(i = 0; i <= f->maxfd; i++) {
+ if(c = f->fd[i]){
+ incref(c);
+ new->fd[i] = c;
+ }
+ }
+ unlock(f);
+
+ return new;
+}
+
+void
+closefgrp(Fgrp *f)
+{
+ int i;
+ Chan *c;
+
+ if(decref(f) == 0) {
+ for(i = 0; i <= f->maxfd; i++)
+ if(c = f->fd[i])
+ close(c);
+
+ free(f);
+ }
+}
+
+
+Mount*
+newmount(Mhead *mh, Chan *to)
+{
+ Mount *m;
+
+ m = smalloc(sizeof(Mount));
+ m->to = to;
+ m->head = mh;
+ incref(to);
+ m->mountid = incref(&mountid);
+ return m;
+}
+
void
mountfree(Mount *m)
{
@@ 185,3 215,20 @@ mountfree(Mount *m)
m = f;
}
}
+
+void
+resrcwait(char *reason)
+{
+ char *p;
+
+ p = u->p->psstate;
+ if(reason) {
+ u->p->psstate = reason;
+ print("%s\n", reason);
+ }
+ if(u == 0)
+ panic("resrcwait");
+
+ tsleep(&u->p->sleep, return0, 0, 1000);
+ u->p->psstate = p;
+}
M port/portdat.h => port/portdat.h +86 -86
@@ 179,23 179,24 @@ struct Crypt
{
char key[DESKEYLEN]; /* des encryption key */
char chal[8]; /* challenge for setting user name */
+ Crypt *next;
};
struct Dev
{
- void (*reset)(void);
- void (*init)(void);
- Chan *(*attach)(char*);
- Chan *(*clone)(Chan*, Chan*);
- int (*walk)(Chan*, char*);
- void (*stat)(Chan*, char*);
- Chan *(*open)(Chan*, int);
- void (*create)(Chan*, char*, int, ulong);
- void (*close)(Chan*);
- long (*read)(Chan*, void*, long, ulong);
- long (*write)(Chan*, void*, long, ulong);
- void (*remove)(Chan*);
- void (*wstat)(Chan*, char*);
+ void (*reset)(void);
+ void (*init)(void);
+ Chan* (*attach)(char*);
+ Chan* (*clone)(Chan*, Chan*);
+ int (*walk)(Chan*, char*);
+ void (*stat)(Chan*, char*);
+ Chan* (*open)(Chan*, int);
+ void (*create)(Chan*, char*, int, ulong);
+ void (*close)(Chan*);
+ long (*read)(Chan*, void*, long, ulong);
+ long (*write)(Chan*, void*, long, ulong);
+ void (*remove)(Chan*);
+ void (*wstat)(Chan*, char*);
};
struct Dirtab
@@ 211,19 212,21 @@ struct Dirtab
*/
struct Etherpkt
{
- uchar d[6];
- uchar s[6];
- uchar type[2];
- uchar data[1500];
- uchar crc[4];
+ uchar d[6];
+ uchar s[6];
+ uchar type[2];
+ uchar data[1500];
+ uchar crc[4];
};
-#define ETHERMINTU 60 /* minimum transmit size */
-#define ETHERMAXTU 1514 /* maximum transmit size */
-#define ETHERHDRSIZE 14 /* size of an ethernet header */
-/*
- * SCSI devices.
- */
+enum
+{
+ ETHERMINTU = 60, /* minimum transmit size */
+ ETHERMAXTU = 1514, /* maximum transmit size */
+ ETHERHDRSIZE = 14, /* size of an ethernet header */
+};
+
+/* SCSI devices. */
enum
{
ScsiTestunit = 0x00,
@@ 233,44 236,41 @@ enum
ScsiRead = 0x08,
ScsiWrite = 0x0a,
- /*
- * data direction
- */
+ /* data direction */
ScsiIn = 1,
ScsiOut = 0,
};
struct Scsibuf
{
- void * virt;
- void * phys;
- Scsibuf *next;
+ void* virt;
+ void* phys;
+ Scsibuf* next;
};
struct Scsidata
{
- uchar * base;
- uchar * lim;
- uchar * ptr;
+ 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];
-};
-/*
- * character based IO (mouse, keyboard, console screen)
- */
+ ulong pid;
+ ushort target;
+ ushort lun;
+ ushort rflag;
+ ushort status;
+ Scsidata cmd;
+ Scsidata data;
+ Scsibuf* b;
+ uchar* save;
+ uchar cmdblk[16];
+};
+
+/* character based IO (mouse, keyboard, console screen) */
#define NQ 4096
struct IOQ
{
@@ 362,7 362,7 @@ struct Swapalloc
char *top; /* Top of swap map */
Rendez r; /* Pager kproc idle sleep */
ulong highwater; /* Threshold beyond which we must page */
- ulong headroom; /* Space pager attempts to clear below highwater */
+ ulong headroom; /* Space pager keeps free under highwater */
}swapalloc;
struct Image
@@ 373,7 373,7 @@ struct Image
Qid mqid;
Chan *mchan;
ushort type; /* Device type of owning channel */
- Segment *s; /* TEXT segment for image if running, may be null */
+ Segment *s; /* TEXT segment for image if running */
Image *hash; /* Qid hash chains */
Image *next; /* Free list */
};
@@ 421,22 421,26 @@ struct Segment
ulong fstart; /* start address in file for demand load */
ulong flen; /* length of segment in file */
int flushme; /* maintain consistent icache for this segment */
- Image *image; /* image in file system attached to this segment */
+ Image *image; /* text in file attached to this segment */
Page *(*pgalloc)(ulong addr);/* SG_PHYSICAL page allocator */
void (*pgfree)(Page *); /* SG_PHYSICAL page free */
Pte *map[SEGMAPSIZE]; /* segment pte map */
};
-#define RENDHASH 32
+enum
+{
+ RENDHASH = 32, /* Hash to lookup rendezvous tags */
+ MNTHASH = 32, /* Hash to walk mount table */
+ NFD = 100, /* Number of per process file descriptors */
+ PGHSIZE = 512, /* Page hash for image lookup */
+};
#define REND(p,s) ((p)->rendhash[(s)%RENDHASH])
-#define MNTHASH 32
#define MOUNTH(p,s) ((p)->mnthash[(s)->qid.path%MNTHASH])
struct Pgrp
{
Ref; /* also used as a lock when mounting */
Pgrp *next; /* free list */
- int index; /* index in pgrp table */
ulong pgrpid;
Crypt *crypt; /* encryption key and challenge */
QLock debug; /* single access via devproc.c */
@@ 462,7 466,6 @@ struct Evalue
Evalue *link;
};
-#define NFD 100
struct Fgrp
{
Ref;
@@ 470,7 473,6 @@ struct Fgrp
int maxfd; /* highest fd in use */
};
-#define PGHSIZE 512
struct Palloc
{
Lock;
@@ 485,16 487,8 @@ struct Palloc
Rendez r; /* Sleep for free mem */
QLock pwait; /* Queue of procs waiting for memory */
int wanted; /* Do the wakeup at free */
-};
-
-struct Pgrps
-{
- Lock;
- Pgrp *arena;
- Pgrp *free;
- ulong pgrpid;
- ulong cryptbase;
- ulong crypttop;
+ ulong cmembase; /* Key memory protected from read by devproc */
+ ulong cmemtop;
};
struct Waitq
@@ 609,7 603,7 @@ struct Proc
int (*tfn)(void*);
/*
- * machine specific MMU goo
+ * machine specific MMU
*/
PMMU;
};
@@ 629,13 623,14 @@ struct Qinfo
Qinfo *next;
};
-/*
- * Queue.flag
- */
-#define QHUNGUP 0x1 /* flag bit meaning the stream has been hung up */
-#define QINUSE 0x2
-#define QHIWAT 0x4 /* queue has gone past the high water mark */
-#define QDEBUG 0x8
+/* Queue.flag */
+enum
+{
+ QHUNGUP = 0x1, /* stream has been hung up */
+ QINUSE = 0x2, /* allocation check */
+ QHIWAT = 0x4, /* queue has gone past the high water mark */
+ QDEBUG = 0x8,
+};
struct Queue
{
@@ 686,12 681,12 @@ struct Stream
*/
enum
{
- Shighqid = STREAMQID(1,0) - 1,
- Sdataqid = Shighqid,
- Sctlqid = Sdataqid-1,
- Slowqid = Sctlqid,
- Streamhi= (32*1024), /* byte count high water mark */
- Streambhi= 128, /* block count high water mark */
+ Shighqid = STREAMQID(1,0) - 1,
+ Sdataqid = Shighqid,
+ Sctlqid = Sdataqid-1,
+ Slowqid = Sctlqid,
+ Streamhi = (32*1024), /* byte count high water mark */
+ Streambhi = 128, /* block count high water mark */
};
/*
@@ 725,9 720,12 @@ struct Network
Netprot *prot; /* linked list of protections */
};
-#define PRINTSIZE 256
-#define NUMSIZE 12 /* size of formatted number */
-#define MB (1024*1024)
+enum
+{
+ PRINTSIZE = 256,
+ NUMSIZE = 12, /* size of formatted number */
+ MB = (1024*1024),
+};
extern Conf conf;
extern char* conffile;
@@ 748,12 746,14 @@ extern Image swapimage;
extern char sysname[NAMELEN];
extern Talarm talarm;
extern Palloc palloc;
-extern Pgrps pgrpalloc;
extern int cpuserver;
-#define CHDIR 0x80000000L
-#define CHAPPEND 0x40000000L
-#define CHEXCL 0x20000000L
+enum
+{
+ CHDIR = 0x80000000L,
+ CHAPPEND = 0x40000000L,
+ CHEXCL = 0x20000000L,
+};
/*
* auth messages
M port/segment.c => port/segment.c +23 -29
@@ 62,9 62,7 @@ putseg(Segment *s)
return;
i = s->image;
- if(i)
- if(i->s == s)
- if(s->ref == 1) {
+ if(i && i->s == s && s->ref == 1) {
lock(i);
if(s->ref == 1)
i->s = 0;
@@ 94,22 92,24 @@ relocateseg(Segment *s, ulong offset)
Page **pg, **endpages;
endpte = &s->map[SEGMAPSIZE];
- for(p = s->map; p < endpte; p++)
+ for(p = s->map; p < endpte; p++) {
if(*p) {
endpages = &((*p)->pages[PTEPERTAB]);
for(pg = (*p)->pages; pg < endpages; pg++)
if(*pg)
(*pg)->va += offset;
}
+ }
}
Segment*
dupseg(Segment *s, int share)
{
+ int i;
Pte *pte;
Segment *n;
- int i;
+ SET(n);
switch(s->type&SG_TYPE) {
case SG_TEXT: /* New segment shares pte set */
case SG_SHARED:
@@ 121,7 121,7 @@ dupseg(Segment *s, int share)
case SG_STACK:
qlock(&s->lk);
n = newseg(s->type, s->base, s->size);
- goto copypte;
+ break;
case SG_BSS: /* Just copy on write */
qlock(&s->lk);
@@ 132,7 132,7 @@ dupseg(Segment *s, int share)
return s;
}
n = newseg(s->type, s->base, s->size);
- goto copypte;
+ break;
case SG_DATA: /* Copy on write plus demand load info */
qlock(&s->lk);
@@ 148,19 148,15 @@ dupseg(Segment *s, int share)
n->image = s->image;
n->fstart = s->fstart;
n->flen = s->flen;
-
- copypte:
- for(i = 0; i < SEGMAPSIZE; i++)
- if(pte = s->map[i])
- n->map[i] = ptecpy(pte);
-
- n->flushme = s->flushme;
- qunlock(&s->lk);
- return n;
+ break;
}
+ for(i = 0; i < SEGMAPSIZE; i++)
+ if(pte = s->map[i])
+ n->map[i] = ptecpy(pte);
- panic("dupseg");
- return 0; /* not reached */
+ n->flushme = s->flushme;
+ qunlock(&s->lk);
+ return n;
}
void
@@ 320,8 316,8 @@ ibrk(ulong addr, int seg)
qlock(&s->lk);
+ /* We may start with the bss overlapping the data */
if(addr < s->base) {
- /* We may start with the bss overlapping the data */
if(seg != BSEG || u->p->seg[DSEG] == 0 || addr < u->p->seg[DSEG]->base) {
qunlock(&s->lk);
error(Enovmem);
@@ 337,23 333,21 @@ ibrk(ulong addr, int seg)
return 0;
}
- if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) {
- qunlock(&s->lk);
- return -1;
- }
-
for(i = 0; i < NSEG; i++) {
ns = u->p->seg[i];
if(ns == 0 || ns == s)
continue;
- if(newtop >= ns->base)
- if(newtop < ns->top) {
+ if(newtop >= ns->base && newtop < ns->top) {
qunlock(&s->lk);
- pprint("segments overlap\n");
- error(Enovmem);
+ error(Esoverlap);
}
}
+ if(newsize > (PTEMAPMEM*SEGMAPSIZE)/BY2PG) {
+ qunlock(&s->lk);
+ return -1;
+ }
+
s->top = newtop;
s->size = newsize;
qunlock(&s->lk);
@@ 424,7 418,7 @@ segattach(Proc *p, ulong attr, char *name, ulong va, ulong len)
continue;
if((newtop > ns->base && newtop <= ns->top) ||
(va >= ns->base && va < ns->top))
- error(Enovmem);
+ error(Esoverlap);
}
for(ps = physseg; ps->name; ps++)
D ss/malloc.h => ss/malloc.h +0 -15
@@ 1,15 0,0 @@
-struct tbl_entry {
- struct tbl_entry *next; /* free list */
- int *data; /* data */
-};
-
-struct table {
- int size; /* # entries */
- struct tbl_entry *entries; /* the entries */
- struct tbl_entry *free; /* the free list */
-};
-
-void *tbl_alloc(struct table *, int);
-void tbl_free(struct table *, void *);
-int tbl_index(struct table *, void *);
-void *tbl_data(struct table *, int);
M ss/screen.c => ss/screen.c +7 -19
@@ 100,13 100,13 @@ screeninit(char *str)
dac->cntrl = 0x00; /* no tests */
havecol = 0;
if(havecol) {
- /*
- * For now, just use a fixed colormap, where pixel i is
- * regarded as 3 bits of red, 3 bits of green, and 2 bits of blue.
- * Intensities are inverted so that 0 means white, 255 means black.
- * Exception: pixels 85 and 170 are set to intermediate grey values
- * so that 2-bit grey scale images will look ok on this screen.
- */
+ /*
+ * For now, just use a fixed colormap, where pixel i is
+ * regarded as 3 bits of red, 3 bits of green, and 2 bits of blue.
+ * Intensities are inverted so that 0 means white, 255 means black.
+ * Exception: pixels 85 and 170 are set to intermediate grey values
+ * so that 2-bit grey scale images will look ok on this screen.
+ */
for(i = 0; i<256; i++) {
r = ~rep((i>>5) & 7, 3);
g = ~rep((i>>2) & 7, 3);
@@ 126,18 126,6 @@ screeninit(char *str)
}
}
-mapdump(void)
-{
- dac->addr = 4;
- print("cntrl4 %.2ux\n", dac->cntrl);
- dac->addr = 5;
- print("cntrl5 %.2ux\n", dac->cntrl);
- dac->addr = 6;
- print("cntrl6 %.2ux\n", dac->cntrl);
- dac->addr = 7;
- print("cntrl7 %.2ux\n", dac->cntrl);
-}
-
void
screenputnl(void)
{