M bitsy/clock.c => bitsy/clock.c +10 -0
@@ 75,6 75,7 @@ static void
clockintr(Ureg *ureg, void*)
{
Clock0link *lp;
+ static int inclockintr;
/* reset previous interrupt */
timerregs->ossr |= 1<<0;
@@ 87,6 88,11 @@ clockintr(Ureg *ureg, void*)
if(m->proc)
m->proc->pc = ureg->pc;
+ if(inclockintr)
+ return; /* interrupted ourself */
+
+ inclockintr = 1;
+
accounttime();
if(kproftimer != nil)
kproftimer(ureg->pc);
@@ 97,6 103,10 @@ clockintr(Ureg *ureg, void*)
lp->clock();
iunlock(&clock0lock);
+ if(active.exiting && (active.machs & (1<<m->machno)))
+ exit(0);
+ inclockintr = 0;
+
if(up == 0 || up->state != Running)
return;
M bitsy/devuart.c => bitsy/devuart.c +5 -11
@@ 549,19 549,13 @@ uartclock(void)
if(p->iw != p->ir){
iw = p->iw;
if(iw < p->ir){
- if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0){
+ if(qproduce(p->iq, p->ir, p->ie-p->ir) < 0)
(*p->phys->rts)(p, 0);
- p->ir = p->istage;
- } else {
- if(qproduce(p->iq, p->istage, iw-p->istage) < 0)
- (*p->phys->rts)(p, 0);
- p->ir = iw;
- }
- } else {
- if(qproduce(p->iq, p->ir, iw-p->ir) < 0)
- (*p->phys->rts)(p, 0);
- p->ir = iw;
+ p->ir = p->istage;
}
+ if(qproduce(p->iq, p->ir, iw-p->ir) < 0)
+ (*p->phys->rts)(p, 0);
+ p->ir = iw;
}
/* hang up if requested */
M bitsy/main.c => bitsy/main.c +5 -0
@@ 28,6 28,8 @@ main(void)
memset(m, 0, sizeof(Mach));
m->ticks = 1;
+ active.machs = 1;
+
rs232power(1);
iprint("\nPlan 9 bitsy kernel\n");
confinit();
@@ 365,6 367,9 @@ gpioinit(void)
|GPIO_COM_RTS_o;
gpioregs->rising = 0;
gpioregs->falling = 0;
+ gpioregs->altfunc |=
+ GPIO_LDD8_o|GPIO_LDD9_o|GPIO_LDD10_o|GPIO_LDD11_o
+ |GPIO_LDD12_o|GPIO_LDD13_o|GPIO_LDD14_o|GPIO_LDD15_o;
egpioreg = mapspecial(EGPIOREGS, 4);
}
A bitsy/mouse.c => bitsy/mouse.c +63 -0
@@ 0,0 1,63 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+#include "io.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+enum {
+ Button1 = 0x1;
+ Button2 = 0x2;
+ Button3 = 0x4;
+};
+
+int buttons;
+Point position;
+
+static void
+mousevent(void) {
+ static int curbuttons;
+ static Point curposition;
+
+ if (buttons == curbuttons && eqpt(position, curposition))
+ return;
+
+ /* generate a mouse event */
+ curbuttons = buttons;
+ curposition = position;
+}
+
+void
+buttonevent(int event) {
+ switch (event) {
+ case 0x02:
+ /* Button 2 down */
+ buttons |= Button2;
+ mousevent();
+ break;
+ case 0x82:
+ /* Button 2 up */
+ buttons &= ~Button2;
+ mousevent();
+ break;
+ case 0x03:
+ /* Button 3 down */
+ buttons |= Button3;
+ mousevent();
+ break;
+ case 0x83:
+ /* Button 3 up */
+ buttons &= ~Button3;
+ mousevent();
+ break;
+ default:
+ /* other buttons */
+ }
+}
M bitsy/screen.c => bitsy/screen.c +14 -9
@@ 180,6 180,7 @@ lcdinit(void)
void
screeninit(void)
{
+ int i;
/* map the lcd regs into the kernel's virtual space */
lcd = (struct sa1110regs*)mapspecial(LCDREGS, sizeof(struct sa1110regs));;
@@ 197,6 198,11 @@ screeninit(void)
gscreen = &xgscreen;
xgdata.bdata = (uchar *)framebuf->pixel;
+ i = 0;
+ while (i < Wid*Ht*1/3) framebuf->pixel[i++] = 0xf800; /* red */
+ while (i < Wid*Ht*2/3) framebuf->pixel[i++] = 0xffff; /* white */
+ while (i < Wid*Ht*3/3) framebuf->pixel[i++] = 0x001f; /* blue */
+
memimageinit();
memdefont = getmemdefont();
@@ 290,24 296,23 @@ screenwin(void)
back = memwhite;
conscol = memblack;
- memfillcolor(gscreen, 0x444488FF);
+ /* a lot of work to get a grey color */
+ grey = allocmemimage(Rect(0,0,1,1), RGB16);
+ grey->flags |= Frepl;
+ grey->clipr = gscreen->r;
+ grey->data->bdata[0] = 0x77;
+ grey->data->bdata[1] = 0x77;
w = memdefont->info[' '].width;
h = memdefont->height;
- window.min = Pt(8, 8);
- window.max = addpt(window.min, Pt(8+w*32, 8+h*14));
+ window.min = Pt(4, 4);
+ window.max = addpt(window.min, Pt(4+w*33, 4+h*15));
memimagedraw(gscreen, window, memblack, ZP, memopaque, ZP);
window = insetrect(window, 4);
memimagedraw(gscreen, window, memwhite, ZP, memopaque, ZP);
- /* a lot of work to get a grey color */
- grey = allocmemimage(Rect(0,0,1,1), RGB16);
- grey->flags |= Frepl;
- grey->clipr = gscreen->r;
- grey->data->bdata[0] = 0x77;
- grey->data->bdata[1] = 0x77;
memimagedraw(gscreen, Rect(window.min.x, window.min.y,
window.max.x, window.min.y+h+5+6), grey, ZP, nil, ZP);
freememimage(grey);
M port/devcons.c => port/devcons.c +93 -52
@@ 20,10 20,16 @@ static struct
int x; /* index into line */
char line[1024]; /* current input line */
- Rune c;
int count;
int repeat;
int ctlpoff;
+
+ /* someplace to save up characters at interrupt time before dumping them in the q */
+ Lock lockputc;
+ char istage[128];
+ char *iw;
+ char *ir;
+ char *ie;
} kbd;
char sysname[NAMELEN];
@@ 251,29 257,35 @@ pprint(char *fmt, ...)
}
void
-echo(Rune r, char *buf, int n)
+echo(char *buf, int n)
{
static int ctrlt, pid;
extern ulong etext;
int x;
+ char *e, *p;
+ char ebuf[128];
+
+ e = buf+n;
+ for(p = buf; p < e; p++){
+ switch(*p){
+ case 0x10: /* ^P */
+ if(cpuserver && !kbd.ctlpoff){
+ active.exiting = 1;
+ return;
+ }
+ break;
+ case 0x14: /* ^T */
+ ctrlt++;
+ continue;
+ }
- /*
- * ^p hack
- */
- if(r==0x10 && cpuserver && !kbd.ctlpoff){
- lock(&active);
- active.exiting = 1;
- unlock(&active);
- }
+ if(ctrlt != 2){
+ ctrlt = 0;
+ continue;
+ }
- /*
- * ^t hack BUG
- */
- if(ctrlt == 2){
- ctrlt = 0;
- switch(r){
- case 0x14:
- break; /* pass it on */
+ /* ^T escapes */
+ switch(*p){
case 's':
dumpstack();
break;
@@ 311,28 323,41 @@ echo(Rune r, char *buf, int n)
exit(0);
break;
}
+ ctrlt = 0;
}
- else if(r == 0x14){
- ctrlt++;
- return;
- }
- ctrlt = 0;
+
+ qproduce(kbdq, buf, n);
if(kbd.raw)
return;
/*
* finally, the actual echoing
*/
- if(r == '\n'){
- if(printq)
- qiwrite(printq, "\r", 1);
- } else if(r == 0x15){
- buf = "^U\n";
- n = 3;
+ p = ebuf;
+ e = ebuf + sizeof(ebuf) - 4;
+ while(n-- > 0){
+ if(p >= e){
+ screenputs(ebuf, p - ebuf);
+ if(printq)
+ qiwrite(printq, ebuf, p - ebuf);
+ p = ebuf;
+ }
+ x = *buf++;
+ if(x == '\n'){
+ *p++ = '\r';
+ *p++ = '\n';
+ } else if(x == 0x15){
+ *p++ = '^';
+ *p++ = 'U';
+ *p++ = '\n';
+ } else
+ *p++ = x;
}
- screenputs(buf, n);
+ if(p == ebuf)
+ return;
+ screenputs(ebuf, p - ebuf);
if(printq)
- qiwrite(printq, buf, n);
+ qiwrite(printq, ebuf, p - ebuf);
}
/*
@@ 355,39 380,54 @@ kbdcr2nl(Queue *q, int ch)
int
kbdputc(Queue*, int ch)
{
- int n;
+ int i, n;
char buf[3];
Rune r;
+ char *next;
+ ilock(&kbd.lockputc); /* just a mutex */
r = ch;
n = runetochar(buf, &r);
- if(n == 0)
- return 0;
- echo(r, buf, n);
- kbd.c = r;
- qproduce(kbdq, buf, n);
+ for(i = 0; i < n; i++){
+ next = kbd.iw+1;
+ if(next >= kbd.ie)
+ next = kbd.istage;
+ if(next == kbd.ir)
+ break;
+ *kbd.iw = buf[i];
+ kbd.iw = next;
+ }
+ iunlock(&kbd.lockputc);
return 0;
}
-void
-kbdrepeat(int rep)
+/*
+ * we save up input characters till clock time to reduce
+ * per character interrupt overhead.
+ */
+static void
+kbdputcclock(void)
{
- kbd.repeat = rep;
- kbd.count = 0;
+ char *iw;
+
+ /* this amortizes cost of qproduce */
+ if(kbd.iw != kbd.ir){
+ iw = kbd.iw;
+ if(iw < kbd.ir){
+ echo(kbd.ir, kbd.ie-kbd.ir);
+ kbd.ir = kbd.istage;
+ }
+ echo(kbd.ir, iw-kbd.ir);
+ kbd.ir = iw;
+ }
}
-void
-kbdclock(void)
+static void
+kbdputcinit(void)
{
- if(kbd.repeat == 0)
- return;
- if(kbd.repeat==1 && ++kbd.count>HZ){
- kbd.repeat = 2;
- kbd.count = 0;
- return;
- }
- if(++kbd.count&1)
- kbdputc(kbdq, kbd.c);
+ kbd.ir = kbd.iw = kbd.istage;
+ kbd.ie = kbd.istage + sizeof(kbd.istage);
+ addclock0link(kbdputcclock);
}
enum{
@@ 482,6 522,7 @@ consinit(void)
{
todinit();
randominit();
+ kbdputcinit();
}
static Chan*