]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/blit/mem.c
add games/blit
[plan9front.git] / sys / src / games / blit / mem.c
1 #include <u.h>
2 #include <libc.h>
3 #include <thread.h>
4 #include <draw.h>
5 #include <bio.h>
6 #include <mouse.h>
7 #include "dat.h"
8 #include "fns.h"
9
10 u32int irq;
11 u32int irql[8] = {
12         [1] INTVBL,
13         [2] INTKEY,
14         [4] INTMOUSE,
15         [5] INTUART,
16 };
17 int diag;
18
19 ushort ram[128*1024];
20 ushort rom[3*4096];
21 Channel *keych;
22 Channel *uartrxch, *uarttxch;
23 int mousex, mousey, mousebut;
24
25 int yes;
26 u8int kbdctrl, uartctrl;
27 enum {
28         ACIATXMASK = 0x60,
29         ACIATXIRQ = 0x20,
30         ACIARXIRQ = 0x80,
31 };
32
33 int keybuf = -1;
34 int uartrxbuf = -1;
35 int uarttxbuf = -1;
36
37 void
38 meminit(void)
39 {
40         int i, x;
41         Biobuf *bp;
42         char *s;
43         ushort *p, *q;
44         
45         p = rom;
46         if(diag){
47                 bp = Bopen("diagbits", OREAD);
48                 if(bp == nil) sysfatal("Bopen: %r");
49                 Bread(bp, rom, sizeof(rom));
50                 Bterm(bp);
51                 return;
52         }
53         for(i = 0; i < 6; i++){
54                 bp = Bopen(smprint("rom%d", i), OREAD);
55                 if(bp == nil) sysfatal("Bopen: %r");
56                 q = p;
57                 for(;;){
58                         s = Brdline(bp, '\n');
59                         if(s == nil || Blinelen(bp) == 0) break;
60                         s[Blinelen(bp) - 1] = 0;
61                         x = strtol(s, nil, 8);
62                         if((i & 1) != 0)
63                                 *p |= x << 8;
64                         else
65                                 *p |= x;
66                         p++;
67                 }
68                 if((i & 1) == 0) p = q;
69                 Bterm(bp);
70         }
71         write(3, rom, sizeof(rom));
72 }
73
74 void
75 keycheck(void)
76 {
77         yield();
78
79         if(keybuf < 0)
80                 nbrecv(keych, &keybuf);
81         if(keybuf >= 0 && (kbdctrl & ACIARXIRQ) != 0)
82                 irq |= INTKEY;
83         else
84                 irq &= ~INTKEY;
85         
86         if(uartrxbuf < 0 && uartrxctr <= 0){
87                 nbrecv(uartrxch, &uartrxbuf);
88                 uartrxctr = FREQ * 11 / baud;
89         }
90         if(uarttxbuf >= 0 && nbsend(uarttxch, &uarttxbuf) > 0)
91                 uarttxbuf = -1;
92         if(uartrxbuf >= 0 && (uartctrl & ACIARXIRQ) != 0 || uarttxbuf < 0 && (uartctrl & ACIATXMASK) == ACIATXIRQ)
93                 irq |= INTUART;
94         else
95                 irq &= ~INTUART;
96 }
97
98 u16int
99 memread(u32int a)
100 {
101         int rc;
102
103         a &= 0x3fffff;
104         if(a < 8) a += 0x40000;
105         if(a < 0x40000) return ram[a/2];
106         if(a >= 0x40000 && a < 0x40000 + sizeof(rom))
107                 return rom[(a - 0x40000)/2];
108         switch(a & ~1){
109         case 01400000: return mousey;
110         case 01400002: return mousex;
111         case 01400010: /* uart status */
112                 rc = 0;
113                 if(uartrxbuf >= 0) rc |= 1;
114                 if(uarttxbuf < 0) rc |= 2;
115                 return rc | rc << 8;
116         case 01400012: /* uart data */
117                 rc = uartrxbuf;
118                 uartrxbuf = -1;
119                 yes=1;
120                 return rc | rc << 8;
121         case 01400020:
122         case 01400024:
123                 irq &= ~INTMOUSE;
124                 return mousebut | mousebut << 8;
125         case 01400026: return 0; /* mouse: unknown purpose */
126         case 01400030: return daddr >> 2; /* display address */
127         case 01400040: return dstat; /* display status */
128         case 01400060: /* keyboard status */
129                 rc = 2;
130                 if(keybuf >= 0) rc |= 1;
131                 return rc | rc << 8;
132         case 01400062: /* keyboard data */
133                 rc = keybuf;
134                 keybuf = -1;
135                 return rc | rc << 8;
136         }
137         print("read %.8o (curpc = %.6x)\n", a, curpc & 0x3fffff);
138         return 0;
139 }
140
141 void
142 memwrite(u32int a, u16int v, u16int m)
143 {
144         extern Rectangle updated;
145         int x, y;
146
147         a &= 0x3fffff;
148         if(a < 0x40000){
149                 if(a >= daddr){
150                         y = (a - daddr) / 100;
151                         x = (((a & ~1) - daddr) % 100) * 8;
152                         if(updated.min.x > x) updated.min.x = x;
153                         if(updated.max.x < x+16) updated.max.x = x+16;
154                         if(updated.min.y > y) updated.min.y = y;
155                         if(updated.max.y <= y) updated.max.y = y+1;
156                 }
157                 ram[a/2] = ram[a/2] & ~m | v & m;
158                 return;
159         }
160         switch(a & ~1){
161         case 01400010: uartctrl = v; return;
162         case 01400012: uarttxbuf = (uchar) v; return;
163         case 01400024: return; /* mouse: purpose unknown */
164         case 01400026: return; /* mouse: purpose unknown */
165         case 01400030: daddr = ((daddr >> 2) & ~m | v & m) << 2; return;
166         case 01400040: dstat = dstat & ~m | v & m; invert = -(dstat & 1); updated = Rect(0, 0, SX, SY); return;
167         case 01400056: /* sound; exact function unknown */ return;
168         case 01400060: kbdctrl = v; return;
169         case 01400062: /* reset keyboard */ return;
170         case 01400070: irq &= ~INTVBL; return;
171         case 01400156: /* sound; exact function unknown */ return;
172         }
173         print("write %.8o = %.4x (mask = %.4x, curpc = %.6x)\n", a, v, m, curpc & 0x3fffff);
174 }
175
176 int
177 intack(int l)
178 {
179         return 24+l;
180 }