summaryrefslogtreecommitdiff
path: root/sys/src/games/blit/mem.c
blob: 59354050b5eadcd992455b58277af51289c7c8cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#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);
	}
}

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; updated = Rect(0, 0, SX, SY); 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;
}