From a942d7a9edee55905c1effade1170c0296ef1284 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 30 Jul 1991 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1991-07-30 --- pc/bbmalloc.c | 73 +++++++++++++++++++++++ pc/clock.c | 11 ++++ pc/devfloppy.c | 15 ----- pc/io.h | 1 + pc/kbd.c | 53 ++++++++++++++--- pc/main.c | 6 -- pc/screen.h | 32 ++++++++++ pc/vga.c | 154 ++++++++++++++++++++++++++++++++++++++++++++----- port/portfns.h | 1 + ss/fns.h | 1 - 10 files changed, 304 insertions(+), 43 deletions(-) create mode 100644 pc/bbmalloc.c create mode 100644 pc/screen.h diff --git a/pc/bbmalloc.c b/pc/bbmalloc.c new file mode 100644 index 0000000000000000000000000000000000000000..c9eed4fe01c8a16304020c82e9e7112e57d5f632 --- /dev/null +++ b/pc/bbmalloc.c @@ -0,0 +1,73 @@ +#include "u.h" +#include "lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" + +/* + * Allocate memory for use in kernel bitblts. + * The allocated memory must have a flushed instruction + * cache, and the data cache must be flushed by bbdflush(). + * To avoid the need for frequent cache flushes, the memory + * is allocated out of an arena, and the i-cache is only + * flushed when it has to be reused. By returning an + * address in non-cached space, the need for flushing the + * d-cache is avoided. + * + * Currently, the only kernel users of bitblt are devbit, + * print, and the cursor stuff in devbit. The cursor + * can get drawn at clock interrupt time, so it might need + * to bbmalloc while another bitblt is going on. + * + * This code will have to be interlocked if we ever get + * a multiprocessor with a bitmapped display. + */ + +/* a 0->3 bitblt can take 900 words */ +enum { + nbbarena=8192 /* number of words in an arena */ +}; + +static ulong bbarena[nbbarena]; +static ulong *bbcur = bbarena; +static ulong *bblast = 0; + +void * +bbmalloc(int nbytes) +{ + int nw; + int s; + ulong *ans; + + nw = nbytes/sizeof(long); + s = splhi(); + if(bbcur + nw > &bbarena[nbbarena]) + ans = bbarena; + else + ans = bbcur; + bbcur = ans + nw; + splx(s); +/* + if(ans == bbarena) + icflush(ans, sizeof(bbarena)); +*/ + bblast = ans; + ans = (void *)ans; + return ans; +} + +void +bbfree(void *p, int n) +{ + ulong *up; + + if(p == bblast) + bbcur = (ulong *)(((char *)bblast) + n); +} + +void * +bbdflush(void *p, int n) +{ + return p; +} diff --git a/pc/clock.c b/pc/clock.c index 4b58b2fc1a21d6b3e10405405f2fb66302064302..19ad234fcbc83421939adf3019ed7cb10bb0bcc0 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -61,6 +61,7 @@ clock(Ureg *ur) m->ticks++; checkalarms(); + mouseclock(); p = m->proc; if(p){ @@ -68,4 +69,14 @@ clock(Ureg *ur) if (p->state==Running) p->time[p->insyscall]++; } +/* + if(u && (ur->flags&IFLAG) && p && p->state==Running){ + if(anyready()){ + if(p->hasspin) + p->hasspin = 0; + else + sched(); + } + } +/**/ } diff --git a/pc/devfloppy.c b/pc/devfloppy.c index 2fd0c532d758f3e2c88631cd0e21d0dc9d4a72e4..798445fde4678fe733acd5e9eded675647ad8183 100644 --- a/pc/devfloppy.c +++ b/pc/devfloppy.c @@ -253,21 +253,6 @@ floppypos(Drive *dp, long off) dp->len -= ((lsec/dp->t->sectors) % dp->t->heads)*secbytes[dp->t->bytes] *dp->t->sectors; } - - dp->lasttouched = m->ticks; - floppy.intr = 0; -} - -void -floppywait(void) -{ - int tries; - - for(tries = 0; tries < 100 && floppy.intr == 0; tries++) - delay(5); - if(tries >= 100) - print("tired floopy\n"); - floppy.intr = 0; } int diff --git a/pc/io.h b/pc/io.h index 088fa514ea0df6494c713b43d72ccf421a0a9375..6b850438234cee0a42143b0af324b3124ffecac1 100644 --- a/pc/io.h +++ b/pc/io.h @@ -7,6 +7,7 @@ enum Int0vec= 16, /* first interrupt vector used by the 8259 */ Clockvec= Int0vec+0, /* clock interrupts */ Kbdvec= Int0vec+1, /* keyboard interrupts */ + Mousevec= Int0vec+12, /* mouse interrupt */ }; /* diff --git a/pc/kbd.c b/pc/kbd.c index d9dc7eadc89fffd6864307514312e973e01355a8..c3469582840a869d4c8e6abeffa16fd3cf896cad 100644 --- a/pc/kbd.c +++ b/pc/kbd.c @@ -11,12 +11,14 @@ enum { Status= 0x64, /* status port */ Inready= 0x01, /* input character ready */ Outbusy= 0x02, /* output busy */ - Sysflag= 0x04, /* ??? */ + Sysflag= 0x04, /* system flag */ Cmddata= 0x08, /* cmd==0, data==1 */ - kbdinh= 0x10, /* keyboard inhibited */ - Xtimeout= 0x20, /* transmit timeout */ - Rtimeout= 0x40, /* receive timeout */ - Parity= 0x80, /* 0==odd, 1==even */ + Inhibit= 0x10, /* keyboard/mouse inhibited */ + Minready= 0x20, /* mouse character ready */ + Rtimeout= 0x40, /* general timeout */ + Parity= 0x80, /* 1 == error */ + + Cmd= 0x64, /* command port (write only) */ Spec= 0x80, @@ -237,8 +239,35 @@ latin1(int k1, int k2) void kbdinit(void) { + uchar c; + initq(&kbdq); setvec(Kbdvec, kbdintr); + + /* wait for a quiescent controller */ + while((c = inb(Status)) & (Outbusy | Inready)) + if(c & Inready) + inb(Data); + + /* read controller command byte */ + outb(Cmd, 0x20); + while(!(inb(Status) & Inready)) + ; + c = inb(Data); +print("input completed\n"); +delay(5000); + + /* enable mouse and mouse interupts */ + c = (c&~0x20) | 0x02; + outb(Cmd, 0x60); + while(inb(Status) & Outbusy) + ; + outb(Data, c); +print("mouse enabled\n"); +delay(5000); + + initq(&mouseq); + setvec(Mousevec, kbdintr); } /* @@ -247,7 +276,7 @@ kbdinit(void) void kbdintr(Ureg *ur) { - int c, nc; + int s, c, nc; static int esc1, esc2; static int shift; static int caps; @@ -257,10 +286,20 @@ kbdintr(Ureg *ur) int keyup; /* - * get a character + * get status and character */ + s = inb(Status); c = inb(Data); + /* + * if it's the mouse... + */ + if(s & Minready){ +print("mousechar\n"); + mouseputc(&mouseq, c); + return; + } + keyup = c&0x80; c &= 0x7f; if(c > sizeof kbtab){ diff --git a/pc/main.c b/pc/main.c index a710d858c014d7a44f3e425f1595399488b7ae7b..76fd47bb8750d538f61a7a9a1566afce0af28fe8 100644 --- a/pc/main.c +++ b/pc/main.c @@ -268,12 +268,6 @@ lights(int val) { } -int -mouseputc(IOQ *q, int c) -{ - return c; -} - /* * headland hip set for the safari. * diff --git a/pc/screen.h b/pc/screen.h new file mode 100644 index 0000000000000000000000000000000000000000..979d7d3678de83304fece2708e615dab0b45ef81 --- /dev/null +++ b/pc/screen.h @@ -0,0 +1,32 @@ +typedef struct Mouseinfo Mouseinfo; +typedef struct Cursorinfo Cursorinfo; + +struct Mouseinfo{ + /* + * First three fields are known in some l.s's + */ + int dx; /* interrupt-time delta */ + int dy; + int track; /* update cursor on screen */ + Mouse; + int changed; /* mouse structure changed since last read */ + Rendez r; + int newbuttons; /* interrupt time access only */ + int clock; /* check mouse.track on RTE */ +}; + +struct Cursorinfo{ + Cursor; + Lock; + int visible; /* on screen */ + Rectangle r; /* location */ +}; + + +extern Mouseinfo mouse; +extern Cursorinfo cursor; + +extern void mouseupdate(int); + +#define kbitblt gbitblt +#define ubitblt gbitblt diff --git a/pc/vga.c b/pc/vga.c index a04c358eff2f7317efcbd0acfb21ed00324074f8..70d47c557482647f9256628bf15787565dbf5b79 100644 --- a/pc/vga.c +++ b/pc/vga.c @@ -5,6 +5,38 @@ #include "fns.h" #include "io.h" +#include +#include +#include "screen.h" + +#define MINX 8 + +extern GFont defont0; +GFont *defont; + +struct{ + Point pos; + int bwid; +}out; + +/* + * 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 +}; + enum { GRX= 0x3CE, /* index to graphics registers */ @@ -28,12 +60,6 @@ enum Acpe= 0x12, /* color plane enable */ }; -/* - * screen dimensions - */ -#define MAXX 640 -#define MAXY 480 - /* * routines for setting vga registers */ @@ -91,7 +117,7 @@ munch(void) ulong x,y,i,d; uchar *screen, tab[8], *p; - screen = (uchar *)(0xA0000 | KZERO); + screen = (uchar *)SCREENMEM; d=0; tab[0] = 0x80; tab[1] = 0x40; @@ -120,13 +146,15 @@ munch(void) * Set up for 4 separately addressed bit planes. Each plane is */ void -vgainit(void) +screeninit(void) { uchar *display; int i, j, k; int c; + ulong *l; + + display = (uchar *)SCREENMEM; - display = (uchar *)(0xA0000 | KZERO); arout(Acpe, 0x0f); /* enable all planes */ arout(Amode, 0x01); /* graphics mode - 4 bit pixels */ grout(Gmisc, 0x01); /* graphics mode */ @@ -136,14 +164,112 @@ vgainit(void) crout(Cmsl, 0x40); /* 1 pixel per scan line */ srout(Smode, 0x06); /* extended memory, odd/even off */ srout(Sclock, 0x01); /* 8 bits/char */ + srout(Smmask, 0x0f); /* enable all 4 color planes for writing */ /* * zero out display */ - srout(Smmask, 0x0f); /* enable all 4 color planes for writing */ - for(i=0; ibits->base; + for(i = defont->bits->width*Dy(defont->bits->r); i > 0; i--, l++) + *l = (*l<<24) | ((*l>>8)&0x0000ff00) | ((*l<<8)&0x00ff0000) | (*l>>24); +} + +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) +{ + while(n-- > 0) + screenputc(*s++); +} + +int +screenbits(void) +{ + return 1; /* bits per pixel */ +} + +void +getcolor(ulong p, ulong *pr, ulong *pg, ulong *pb) +{ + ulong ans; + + /* + * The magnum 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 */ +} + +int +hwcursset(uchar *s, uchar *c, int ox, int oy) +{ + return 0; +} + +int +hwcursmove(int x, int y) +{ + return 0; } +void +mouseclock(void) /* called splhi */ +{ + mouseupdate(1); +} diff --git a/port/portfns.h b/port/portfns.h index eb0b40429764dc55d8621435b78a8b97731175e4..4fe8b9dc5ed0af53dfefda7f258acd1ff07dd6aa 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -112,6 +112,7 @@ void mfreeseg(Segment*, ulong, int); void mmurelease(Proc*); void mntdump(void); int mount(Chan*, Chan*, int); +void mouseclock(void); int mouseputc(IOQ*, int); Chan* namec(char*, int, int, ulong); void nameok(char*); diff --git a/ss/fns.h b/ss/fns.h index facfb778572ce38ff4ca15929498cdcd9c8abd62..002750da1ab6ae540cf5d3df15c584a53cf9912f 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -33,7 +33,6 @@ void lancesetup(Lance*); void lancetoggle(void); void mmuinit(void); void mousebuttons(int); -void mouseclock(void); void printinit(void); #define procrestore(x,y) #define procsave(x,y)