A pc/bbmalloc.c => pc/bbmalloc.c +73 -0
@@ 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;
+}
M pc/clock.c => pc/clock.c +11 -0
@@ 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();
+ }
+ }
+/**/
}
M pc/devfloppy.c => pc/devfloppy.c +0 -15
@@ 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
M pc/io.h => pc/io.h +1 -0
@@ 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 */
};
/*
M pc/kbd.c => pc/kbd.c +46 -7
@@ 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){
M pc/main.c => pc/main.c +0 -6
@@ 268,12 268,6 @@ lights(int val)
{
}
-int
-mouseputc(IOQ *q, int c)
-{
- return c;
-}
-
/*
* headland hip set for the safari.
*
A pc/screen.h => pc/screen.h +32 -0
@@ 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
M pc/vga.c => pc/vga.c +140 -14
@@ 5,6 5,38 @@
#include "fns.h"
#include "io.h"
+#include <libg.h>
+#include <gnot.h>
+#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 */
@@ 29,12 61,6 @@ enum
};
/*
- * screen dimensions
- */
-#define MAXX 640
-#define MAXY 480
-
-/*
* routines for setting vga registers
*/
void
@@ 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; i<MAXY*(MAXX/8); i++)
- display[i] = 0;
-
- munch();
+ defont = &defont0; /* save space; let bitblt do the conversion work */
+ gbitblt(&gscreen, Pt(0, 0), &gscreen, gscreen.r, 0); /**/
+
+ /*
+ * stick print at the top
+ */
+ out.pos.x = MINX;
+ out.pos.y = 0;
+ out.bwid = defont0.info[' '].width;
+
+ /*
+ * swizzle the damn font longs.
+ * we do it here since the font is in a machine independent (i.e.
+ * made for the 68020) format.
+ */
+ l = defont->bits->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);
+}
M port/portfns.h => port/portfns.h +1 -0
@@ 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*);
M ss/fns.h => ss/fns.h +0 -1
@@ 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)