M gnot/screen.c => gnot/screen.c +38 -40
@@ 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)
{
M gnot/screen.h => gnot/screen.h +0 -6
@@ 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
M pc/screen.h => pc/screen.h +0 -3
@@ 27,6 27,3 @@ extern Mouseinfo mouse;
extern Cursorinfo cursor;
extern void mouseupdate(int);
-
-#define kbitblt gbitblt
-#define ubitblt gbitblt
M port/devbit.c => port/devbit.c +5 -5
@@ 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);
}
M port/devscc.c => port/devscc.c +118 -108
@@ 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
M port/portfns.h => port/portfns.h +1 -1
@@ 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);
M ss/io.h => ss/io.h +4 -6
@@ 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 */
M ss/main.c => ss/main.c +4 -2
@@ 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);
M ss/screen.c => ss/screen.c +0 -32
@@ 44,38 44,6 @@ screeninit(void)
}
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)
{
Rune r;
M ss/screen.h => ss/screen.h +0 -2
@@ 27,5 27,3 @@ extern Mouseinfo mouse;
extern Cursorinfo cursor;
extern void mouseupdate(int);
-#define kbitblt gbitblt
-#define ubitblt gbitblt