From 2f74d45e15e6e5f1583e9118b6c2d2cc507bdf85 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 25 Dec 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-12-25 --- gnot/screen.c | 78 +++++++++-------- gnot/screen.h | 6 -- pc/screen.h | 3 - port/devbit.c | 10 +-- port/devscc.c | 226 ++++++++++++++++++++++++++----------------------- port/portfns.h | 2 +- ss/io.h | 10 +-- ss/main.c | 6 +- ss/screen.c | 32 ------- ss/screen.h | 2 - 10 files changed, 170 insertions(+), 205 deletions(-) diff --git a/gnot/screen.c b/gnot/screen.c index 99f738555a8ac5c9124dcabd5939e319c399d8f0..31a03736d2fc3de6e39cc17b070d22dd74da04f5 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -40,57 +40,55 @@ screeninit(void) if(*(uchar*)MOUSE & (1<<4)) gscreen.ldepth = 1; defont = &defont0; /* save space; let bitblt do the conversion work */ - kbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); + gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); out.pos.x = MINX; out.pos.y = 0; out.bwid = defont0.info[' '].width; } void -screenputc(int c) +screenputs(char *s, int n) { - char buf[2]; - int nx; - - if(c == '\n'){ - out.pos.x = MINX; - out.pos.y += defont0.height; - if(out.pos.y > gscreen.r.max.y-defont0.height) - out.pos.y = gscreen.r.min.y; - kbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, - Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0); - }else if(c == '\t'){ - out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; - if(out.pos.x >= gscreen.r.max.x) - screenputc('\n'); - }else if(c == '\b'){ - if(out.pos.x >= out.bwid+MINX){ - out.pos.x -= out.bwid; - screenputc(' '); - out.pos.x -= out.bwid; + Rune r; + int i; + char buf[4]; + + while(n > 0){ + i = chartorune(&r, s); + if(i == 0){ + s++; + --n; + continue; + } + memmove(buf, s, i); + buf[i] = 0; + n -= i; + s += i; + if(r == '\n'){ + out.pos.x = MINX; + out.pos.y += defont0.height; + if(out.pos.y > gscreen.r.max.y-defont0.height) + out.pos.y = gscreen.r.min.y; + gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, + Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0); + }else if(r == '\t'){ + out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; + if(out.pos.x >= gscreen.r.max.x) + screenputs("\n", 1); + }else if(r == '\b'){ + if(out.pos.x >= out.bwid+MINX){ + out.pos.x -= out.bwid; + screenputs(" ", 1); + out.pos.x -= out.bwid; + } + }else{ + if(out.pos.x >= gscreen.r.max.x-out.bwid) + screenputs("\n", 1); + out.pos = gstring(&gscreen, out.pos, defont, buf, S); } - }else{ - if(out.pos.x >= gscreen.r.max.x-out.bwid) - screenputc('\n'); - buf[0] = c&0x7F; - buf[1] = 0; - out.pos = gstring(&gscreen, out.pos, defont, buf, S); } } -void -screenputs(char *s, int n) -{ - int x; - - x = splhi(); - lock(&printq); - while(n-- > 0) - screenputc(*s++); - unlock(&printq); - splx(x); -} - int screenbits(void) { diff --git a/gnot/screen.h b/gnot/screen.h index 45d3e2938c0e831ba69f83aa307f1717bfdb5102..de51fd5b8b1ad916ffd7684fb90b38b52bf9fea4 100644 --- a/gnot/screen.h +++ b/gnot/screen.h @@ -27,9 +27,3 @@ extern Mouseinfo mouse; extern Cursorinfo cursor; extern void mouseupdate(int); - -/* - * kernel mustn't use balu; user (/dev/bitblt) can - */ -#define kbitblt gbitblt -#define ubitblt gbitblt diff --git a/pc/screen.h b/pc/screen.h index 979d7d3678de83304fece2708e615dab0b45ef81..de51fd5b8b1ad916ffd7684fb90b38b52bf9fea4 100644 --- a/pc/screen.h +++ b/pc/screen.h @@ -27,6 +27,3 @@ extern Mouseinfo mouse; extern Cursorinfo cursor; extern void mouseupdate(int); - -#define kbitblt gbitblt -#define ubitblt gbitblt diff --git a/port/devbit.c b/port/devbit.c index 9427b4419818749772fa5b4e949679d4d2c2e54e..545dc866a2c42e8d6e7cf8389b5548ad89ebf72f 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -652,7 +652,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset) cursoroff(1); isoff = 1; } - ubitblt(dst, pt, src, rect, fc); + gbitblt(dst, pt, src, rect, fc); m -= 31; p += 31; break; @@ -1164,10 +1164,10 @@ cursoron(int dolock) cursor.r.min = mouse.xy; cursor.r.max = add(mouse.xy, Pt(16, 16)); cursor.r = raddp(cursor.r, cursor.offset); - kbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S); - kbitblt(&gscreen, add(mouse.xy, cursor.offset), + gbitblt(&cursorback, Pt(0, 0), &gscreen, cursor.r, S); + gbitblt(&gscreen, add(mouse.xy, cursor.offset), &clr, Rect(0, 0, 16, 16), flipping? flipD[D&~S] : D&~S); - kbitblt(&gscreen, add(mouse.xy, cursor.offset), + gbitblt(&gscreen, add(mouse.xy, cursor.offset), &set, Rect(0, 0, 16, 16), flipping? flipD[S|D] : S|D); } if(dolock) @@ -1180,7 +1180,7 @@ cursoroff(int dolock) if(dolock) lock(&cursor); if(--cursor.visible == 0) - kbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S); + gbitblt(&gscreen, cursor.r.min, &cursorback, Rect(0, 0, 16, 16), S); if(dolock) unlock(&cursor); } diff --git a/port/devscc.c b/port/devscc.c index 02f9355e6f770148a581a123a74978ed2237f6f6..d5efead2c39878f6d7e9555cb7af8ee94df9077a 100644 --- a/port/devscc.c +++ b/port/devscc.c @@ -89,6 +89,7 @@ struct SCC uchar *ptr; /* command/pointer register in Z8530 */ uchar *data; /* data register in Z8530 */ int printing; /* true if printing */ + ulong freq; /* clock frequency */ /* console interface */ int nostream; /* can't use the stream interface */ @@ -101,7 +102,9 @@ struct SCC Alarm *a; /* alarm for waking the kernel process */ int kstarted; /* kproc started */ }; -SCC scc[2]; + +int nscc; +SCC *scc[8]; /* up to 4 8530's */ void onepointseven(void) @@ -145,7 +148,10 @@ sccsetbaud(SCC *sp, int rate) { int brconst; - brconst = (SCCFREQ+16*rate-1)/(2*16*rate) - 2; + if(rate == 0) + errors("bad baud rate"); + + brconst = (sp->freq+16*rate-1)/(2*16*rate) - 2; sccwrreg(sp, 12, brconst & 0xff); sccwrreg(sp, 13, (brconst>>8) & 0xff); @@ -183,6 +189,8 @@ sccrts(SCC *sp, int n) void sccbreak(SCC *sp, int ms) { + if(ms == 0) + ms = 100; sp->sticky[1] &=~TxIntEna; sccwrreg(sp, 1, 0); sccwrreg(sp, 5, TxBreak|TxEna); @@ -198,51 +206,57 @@ sccbreak(SCC *sp, int ms) * default is 9600 baud, 1 stop bit, 8 bit chars, no interrupts, * transmit and receive enabled, interrupts disabled. */ +static void +sccsetup0(SCC *sp) +{ + 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; + 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 | 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); +} void -sccsetup(void *addr) +sccsetup(void *addr, ulong freq) { SCCdev *dev; SCC *sp; - static int already; - if(already) - return; - already = 1; dev = addr; /* - * get port addresses + * allocate a structure, set port addresses, and setup the line */ - scc[0].ptr = &dev->ptra; - scc[0].data = &dev->dataa; - scc[1].ptr = &dev->ptrb; - scc[1].data = &dev->datab; - - for(sp = scc; sp < &scc[2]; sp++){ - 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; - 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 | 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 = ialloc(sizeof(SCC), 0); + scc[nscc] = sp; + sp->ptr = &dev->ptra; + sp->data = &dev->dataa; + sp->freq = freq; + sccsetup0(sp); + sp = ialloc(sizeof(SCC), 0); + scc[nscc+1] = sp; + sp->ptr = &dev->ptrb; + sp->data = &dev->datab; + sp->freq = freq; + sccsetup0(sp); + nscc += 2; } /* @@ -313,10 +327,16 @@ void sccintr(void) { uchar x; + int i; - x = sccrdreg(&scc[0], 3); - sccintr0(&scc[1], x); - sccintr0(&scc[0], x>>3); + for(i = 0; i < nscc; i += 2){ + x = sccrdreg(scc[i], 3); + if(x & (ExtPendB|RxPendB|TxPendB)) + sccintr0(scc[i+1], x); + x = x >> 3; + if(x & (ExtPendB|RxPendB|TxPendB)) + sccintr0(scc[i], x); + } } void @@ -324,8 +344,10 @@ sccclock(void) { SCC *sp; IOQ *cq; + int i; - for(sp = scc; sp < &scc[2]; sp++){ + for(i = 0; i < nscc; i++){ + sp = scc[i]; cq = sp->iq; if(sp->wq && cangetc(cq)) wakeup(&cq->r); @@ -371,7 +393,7 @@ sccenable(SCC *sp) void sccspecial(int port, IOQ *oq, IOQ *iq, int baud) { - SCC *sp = &scc[port]; + SCC *sp = scc[port]; sp->nostream = 1; sp->oq = oq; @@ -410,7 +432,7 @@ sccstopen(Queue *q, Stream *s) 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]; + sp = scc[s->id]; qlock(sp); sp->wq = WR(q); WR(q)->ptr = sp; @@ -430,7 +452,6 @@ sccstclose(Queue *q) SCC *sp = q->ptr; qlock(sp); - kprint("sccstclose: q=0x%ux, id=%d\n", q, sp-scc); sp->wq = 0; sp->iq->putc = 0; WR(q)->ptr = 0; @@ -461,7 +482,10 @@ sccoput(Queue *q, Block *bp) switch(*bp->rptr){ case 'B': case 'b': - sccsetbaud(sp, n); + if(BLEN(bp)>4 && strncmp((char*)(bp->rptr+1), "reak", 4) == 0) + sccbreak(sp, 0); + else + sccsetbaud(sp, n); break; case 'D': case 'd': @@ -522,32 +546,34 @@ loop: goto loop; } -enum{ - Qdir= 0, - Qeia0= STREAMQID(0, Sdataqid), - Qeia0ctl= STREAMQID(0, Sctlqid), - Qeia1= STREAMQID(1, Sdataqid), - Qeia1ctl= STREAMQID(1, Sctlqid), -}; - -Dirtab sccdir[]={ - "eia0", {Qeia0}, 0, 0666, - "eia0ctl", {Qeia0ctl}, 0, 0666, - "eia1", {Qeia1}, 0, 0666, - "eia1ctl", {Qeia1ctl}, 0, 0666, -}; - -#define NSCC (sizeof sccdir/sizeof(Dirtab)) +Dirtab *sccdir; /* - * allocate the queues if no one else has + * create 2 directory entries for each 'sccsetup' ports. + * allocate the queues if no one else has. */ void sccreset(void) { SCC *sp; - - for(sp = scc; sp < &scc[2]; sp++){ + int i; + Dirtab *dp; + + sccdir = ialloc(2 * nscc * sizeof(Dirtab), 0); + 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->nostream) continue; sp->iq = ialloc(sizeof(IOQ), 0); @@ -578,21 +604,21 @@ sccclone(Chan *c, Chan *nc) int sccwalk(Chan *c, char *name) { - return devwalk(c, name, sccdir, NSCC, devgen); + return devwalk(c, name, sccdir, 2*nscc, devgen); } void sccstat(Chan *c, char *dp) { - switch(c->qid.path){ - case Qeia0: - streamstat(c, dp, "eia0"); - break; - case Qeia1: - streamstat(c, dp, "eia1"); + int i; + + i = STREAMID(c->qid.path); + switch(STREAMTYPE(c->qid.path)){ + case Sdataqid: + streamstat(c, dp, sccdir[2*i].name); break; default: - devstat(c, dp, sccdir, NSCC, devgen); + devstat(c, dp, sccdir, 2*nscc, devgen); break; } } @@ -602,26 +628,13 @@ sccopen(Chan *c, int omode) { SCC *sp; - switch(c->qid.path){ - case Qeia0: - case Qeia0ctl: - sp = &scc[0]; - break; - case Qeia1: - case Qeia1ctl: - sp = &scc[1]; - break; - default: - sp = 0; - break; - } - - if(sp && sp->nostream) - errors("in use"); - - if((c->qid.path & CHDIR) == 0) + if(c->qid.path != CHDIR){ + sp = scc[STREAMID(c->qid.path)]; + if(sp->nostream) + errors("in use"); streamopen(c, &sccinfo); - return devopen(c, omode, sccdir, NSCC, devgen); + } + return devopen(c, omode, sccdir, 2*nscc, devgen); } void @@ -641,23 +654,20 @@ sccclose(Chan *c) long sccread(Chan *c, void *buf, long n, ulong offset) { - SCC *sp = &scc[0]; int s; - - switch(c->qid.path&~CHDIR){ - case Qdir: - return devdirread(c, buf, n, sccdir, NSCC, devgen); - case Qeia1ctl: - ++sp; - /* fall through */ - case Qeia0ctl: - if(offset) - return 0; - s = splhi(); - *(uchar *)buf = *sp->ptr; - splx(s); - return 1; + SCC *sp; + 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 stringread(buf, n, b, offset); } - return streamread(c, buf, n); + errors("bad qid"); } long diff --git a/port/portfns.h b/port/portfns.h index 5d793e2943693ba8abc7d15f30b984d4ce176712..de3735387a44c64ade3a9801b762c00462630e45 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -195,7 +195,7 @@ Proc* runproc(void); void savefpregs(FPsave*); void sccclock(void); void sccintr(void); -void sccsetup(void*); +void sccsetup(void*, ulong); void sccspecial(int, IOQ*, IOQ*, int); void sched(void); void schedinit(void); diff --git a/ss/io.h b/ss/io.h index 9156578f206c89ccb4c25ac405a0c8e8dc240858..6ea3105eb2bdd6cd7de08727144ffd8e084f156b 100644 --- a/ss/io.h +++ b/ss/io.h @@ -2,8 +2,8 @@ #define EPROM 0xF6000000 #define CLOCK 0xF3000000 #define CLOCKFREQ 1000000 /* one microsecond increments */ -#define KMDUART0 0xF0000000 /* keyboard A, mouse B */ -#define KMDUART1 0xF1000000 /* serial ports */ +#define KMDUART 0xF0000000 /* keyboard A, mouse B */ +#define EIADUART 0xF1000000 /* serial ports */ #define ETHER 0xF8C00000 /* RDP, RAP */ #define EEPROM 0xF2000000 #define INTRREG 0xF5000000 /* interrupt register, IO space */ @@ -21,7 +21,5 @@ struct SCCdev uchar dummy4; }; -/* - * crystal frequency for SCC - */ -#define SCCFREQ 10000000 +#define KMFREQ 10000000 /* crystal frequency for kbd/mouse 8530 */ +#define EIAFREQ 5000000 /* crystal frequency for serial port 8530 */ diff --git a/ss/main.c b/ss/main.c index 8dc04bb461d72af6206641f6028e13c1530dacf3..e17f1972df90238cd0b401352b5b48354f6ce273 100644 --- a/ss/main.c +++ b/ss/main.c @@ -80,9 +80,11 @@ ioinit(void) { KMap *k; - /* tell scc driver it's address */ + /* tell scc driver it's addresses */ k = kmappa(KMDUART, PTEIO|PTENOCACHE); - sccsetup((void*)(k->va)); + sccsetup((void*)(k->va), KMFREQ); + k = kmappa(EIADUART, PTEIO|PTENOCACHE); + sccsetup((void*)(k->va), EIAFREQ); /* scc port 0 is the keyboard */ sccspecial(0, 0, &kbdq, 2400); diff --git a/ss/screen.c b/ss/screen.c index a8cb7b7cca3a2554286b4b92ffb5379aa2059d7e..d7a3996d2fd019ff6ecbda5c78721101d0cbcf9d 100644 --- a/ss/screen.c +++ b/ss/screen.c @@ -43,38 +43,6 @@ screeninit(void) out.bwid = defont0.info[' '].width; } -void -screenputc(int c) -{ - char buf[2]; - int nx; - - if(c == '\n'){ - out.pos.x = MINX; - out.pos.y += defont0.height; - if(out.pos.y > gscreen.r.max.y-defont0.height) - out.pos.y = gscreen.r.min.y; - gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen, - Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0); - }else if(c == '\t'){ - out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid; - if(out.pos.x >= gscreen.r.max.x) - screenputc('\n'); - }else if(c == '\b'){ - if(out.pos.x >= out.bwid+MINX){ - out.pos.x -= out.bwid; - screenputc(' '); - out.pos.x -= out.bwid; - } - }else{ - if(out.pos.x >= gscreen.r.max.x-out.bwid) - screenputc('\n'); - buf[0] = c&0x7F; - buf[1] = 0; - out.pos = gstring(&gscreen, out.pos, defont, buf, S); - } -} - void screenputs(char *s, int n) { diff --git a/ss/screen.h b/ss/screen.h index 059a4a097c290de755713b7682bc7175c6d45b40..de51fd5b8b1ad916ffd7684fb90b38b52bf9fea4 100644 --- a/ss/screen.h +++ b/ss/screen.h @@ -27,5 +27,3 @@ extern Mouseinfo mouse; extern Cursorinfo cursor; extern void mouseupdate(int); -#define kbitblt gbitblt -#define ubitblt gbitblt