plan9fox/sys/src/games/blit/mem.c
2017-03-29 01:33:16 +02:00

181 lines
3.8 KiB
C

#include <u.h>
#include <libc.h>
#include <thread.h>
#include <draw.h>
#include <bio.h>
#include <mouse.h>
#include "dat.h"
#include "fns.h"
u32int irq;
u32int irql[8] = {
[1] INTVBL,
[2] INTKEY,
[4] INTMOUSE,
[5] INTUART,
};
int diag;
ushort ram[128*1024];
ushort rom[3*4096];
Channel *keych;
Channel *uartrxch, *uarttxch;
int mousex, mousey, mousebut;
int yes;
u8int kbdctrl, uartctrl;
enum {
ACIATXMASK = 0x60,
ACIATXIRQ = 0x20,
ACIARXIRQ = 0x80,
};
int keybuf = -1;
int uartrxbuf = -1;
int uarttxbuf = -1;
void
meminit(void)
{
int i, x;
Biobuf *bp;
char *s;
ushort *p, *q;
p = rom;
if(diag){
bp = Bopen("/sys/lib/blit/diagbits", OREAD);
if(bp == nil) sysfatal("Bopen: %r");
Bread(bp, rom, sizeof(rom));
Bterm(bp);
return;
}
for(i = 0; i < 6; i++){
bp = Bopen(smprint("/sys/lib/blit/rom%d", i), OREAD);
if(bp == nil) sysfatal("Bopen: %r");
q = p;
for(;;){
s = Brdline(bp, '\n');
if(s == nil || Blinelen(bp) == 0) break;
s[Blinelen(bp) - 1] = 0;
x = strtol(s, nil, 8);
if((i & 1) != 0)
*p |= x << 8;
else
*p |= x;
p++;
}
if((i & 1) == 0) p = q;
Bterm(bp);
}
write(3, rom, sizeof(rom));
}
void
keycheck(void)
{
yield();
if(keybuf < 0)
nbrecv(keych, &keybuf);
if(keybuf >= 0 && (kbdctrl & ACIARXIRQ) != 0)
irq |= INTKEY;
else
irq &= ~INTKEY;
if(uartrxbuf < 0 && uartrxctr <= 0){
nbrecv(uartrxch, &uartrxbuf);
uartrxctr = FREQ * 11 / baud;
}
if(uarttxbuf >= 0 && nbsend(uarttxch, &uarttxbuf) > 0)
uarttxbuf = -1;
if(uartrxbuf >= 0 && (uartctrl & ACIARXIRQ) != 0 || uarttxbuf < 0 && (uartctrl & ACIATXMASK) == ACIATXIRQ)
irq |= INTUART;
else
irq &= ~INTUART;
}
u16int
memread(u32int a)
{
int rc;
a &= 0x3fffff;
if(a < 8) a += 0x40000;
if(a < 0x40000) return ram[a/2];
if(a >= 0x40000 && a < 0x40000 + sizeof(rom))
return rom[(a - 0x40000)/2];
switch(a & ~1){
case 01400000: return mousey;
case 01400002: return mousex;
case 01400010: /* uart status */
rc = 0;
if(uartrxbuf >= 0) rc |= 1;
if(uarttxbuf < 0) rc |= 2;
return rc | rc << 8;
case 01400012: /* uart data */
rc = uartrxbuf;
uartrxbuf = -1;
yes=1;
return rc | rc << 8;
case 01400020:
case 01400024:
irq &= ~INTMOUSE;
return mousebut | mousebut << 8;
case 01400026: return 0; /* mouse: unknown purpose */
case 01400030: return daddr >> 2; /* display address */
case 01400040: return dstat; /* display status */
case 01400060: /* keyboard status */
rc = 2;
if(keybuf >= 0) rc |= 1;
return rc | rc << 8;
case 01400062: /* keyboard data */
rc = keybuf;
keybuf = -1;
return rc | rc << 8;
}
print("read %.8o (curpc = %.6x)\n", a, curpc & 0x3fffff);
return 0;
}
void
memwrite(u32int a, u16int v, u16int m)
{
extern Rectangle updated;
int x, y;
a &= 0x3fffff;
if(a < 0x40000){
if(a >= daddr){
y = (a - daddr) / 100;
x = (((a & ~1) - daddr) % 100) * 8;
if(updated.min.x > x) updated.min.x = x;
if(updated.max.x < x+16) updated.max.x = x+16;
if(updated.min.y > y) updated.min.y = y;
if(updated.max.y <= y) updated.max.y = y+1;
}
ram[a/2] = ram[a/2] & ~m | v & m;
return;
}
switch(a & ~1){
case 01400010: uartctrl = v; return;
case 01400012: uarttxbuf = (uchar) v; return;
case 01400024: return; /* mouse: purpose unknown */
case 01400026: return; /* mouse: purpose unknown */
case 01400030: daddr = ((daddr >> 2) & ~m | v & m) << 2; return;
case 01400040: dstat = dstat & ~m | v & m; invert = -(dstat & 1); updated = Rect(0, 0, SX, SY); return;
case 01400056: /* sound; exact function unknown */ return;
case 01400060: kbdctrl = v; return;
case 01400062: /* reset keyboard */ return;
case 01400070: irq &= ~INTVBL; return;
case 01400156: /* sound; exact function unknown */ return;
}
print("write %.8o = %.4x (mask = %.4x, curpc = %.6x)\n", a, v, m, curpc & 0x3fffff);
}
int
intack(int l)
{
return 24+l;
}