From 7beaef922774bae5a96a3dd2518b895473ed19a5 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 24 Aug 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-08-24 --- port/devmnt.c | 2 +- port/devproc.c | 37 ++++++---- port/error.h | 1 + port/pgrp.c | 193 ++++++++++++++++++++++++++++++------------------- port/portdat.h | 172 +++++++++++++++++++++---------------------- port/segment.c | 52 ++++++------- ss/malloc.h | 15 ---- ss/screen.c | 26 ++----- 8 files changed, 259 insertions(+), 239 deletions(-) delete mode 100644 ss/malloc.h diff --git a/port/devmnt.c b/port/devmnt.c index 1871ff35c60a52da852a11e648c363d832decd32..274eb905c18aad964508b5e602bc3628b2e34fa6 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -250,7 +250,7 @@ mntclone(Chan *c, Chan *nc) nc = newchan(); alloc = 1; } - if(waserror()){ + if(waserror()) { mntfree(r); if(alloc) close(nc); diff --git a/port/devproc.c b/port/devproc.c index d227f547cbb4a68bd3ce78429313d4f45d6a2209..74245cd27f6340ff2a8fd2d7a1761f641ab6bf1e 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -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)<user, CHDIR|0555, dp); + qid = (Qid){CHDIR|((s+1)<user, CHDIR|0555, dp); return 1; } if(s >= NPROC) return -1; if(tab) panic("procgen"); + tab = &procdir[s]; path = c->qid.path&~(CHDIR|((1<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; diff --git a/port/error.h b/port/error.h index 828195020927a9e7ee4144cfa3d756e578546d50..a15e19e283de408dbd4e18e4511cf4bb8f1be552 100644 --- a/port/error.h +++ b/port/error.h @@ -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 */ diff --git a/port/pgrp.c b/port/pgrp.c index 7927d3b0fcb685334a94c52721e5bc45e4265168..a762033302fce064299036a7d374fe155b6d55aa 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -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,39 +116,11 @@ 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) { @@ -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; +} diff --git a/port/portdat.h b/port/portdat.h index 643315f23660346de556efbf4628f4501d38c4b0..16b48522045b270c8e62bd006bf8c5e2fb3b33f2 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -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 diff --git a/port/segment.c b/port/segment.c index 46f82ac7be74879671fa6247a075184057df6e7f..ddd554b81b7196d18588c83903a80569da269fc4 100644 --- a/port/segment.c +++ b/port/segment.c @@ -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++) diff --git a/ss/malloc.h b/ss/malloc.h deleted file mode 100644 index 82d145d1af301580f5d152abcfb423b117978fea..0000000000000000000000000000000000000000 --- a/ss/malloc.h +++ /dev/null @@ -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); diff --git a/ss/screen.c b/ss/screen.c index 2f96b11045c82921e67108829e3c2e16b7fbe4c5..ff335eb19c55acdca82fe9a8da2cd2635c33f09a 100644 --- a/ss/screen.c +++ b/ss/screen.c @@ -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) {