]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/blit/mem.c
blit: always show top-left corner; add tony kaku's -m flag
[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("/sys/lib/blit/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("/sys/lib/blit/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 }
72
73 void
74 keycheck(void)
75 {
76         yield();
77
78         if(keybuf < 0)
79                 nbrecv(keych, &keybuf);
80         if(keybuf >= 0 && (kbdctrl & ACIARXIRQ) != 0)
81                 irq |= INTKEY;
82         else
83                 irq &= ~INTKEY;
84         
85         if(uartrxbuf < 0 && uartrxctr <= 0){
86                 nbrecv(uartrxch, &uartrxbuf);
87                 uartrxctr = FREQ * 11 / baud;
88         }
89         if(uarttxbuf >= 0 && nbsend(uarttxch, &uarttxbuf) > 0)
90                 uarttxbuf = -1;
91         if(uartrxbuf >= 0 && (uartctrl & ACIARXIRQ) != 0 || uarttxbuf < 0 && (uartctrl & ACIATXMASK) == ACIATXIRQ)
92                 irq |= INTUART;
93         else
94                 irq &= ~INTUART;
95 }
96
97 u16int
98 memread(u32int a)
99 {
100         int rc;
101
102         a &= 0x3fffff;
103         if(a < 8) a += 0x40000;
104         if(a < 0x40000) return ram[a/2];
105         if(a >= 0x40000 && a < 0x40000 + sizeof(rom))
106                 return rom[(a - 0x40000)/2];
107         switch(a & ~1){
108         case 01400000: return mousey;
109         case 01400002: return mousex;
110         case 01400010: /* uart status */
111                 rc = 0;
112                 if(uartrxbuf >= 0) rc |= 1;
113                 if(uarttxbuf < 0) rc |= 2;
114                 return rc | rc << 8;
115         case 01400012: /* uart data */
116                 rc = uartrxbuf;
117                 uartrxbuf = -1;
118                 yes=1;
119                 return rc | rc << 8;
120         case 01400020:
121         case 01400024:
122                 irq &= ~INTMOUSE;
123                 return mousebut | mousebut << 8;
124         case 01400026: return 0; /* mouse: unknown purpose */
125         case 01400030: return daddr >> 2; /* display address */
126         case 01400040: return dstat; /* display status */
127         case 01400060: /* keyboard status */
128                 rc = 2;
129                 if(keybuf >= 0) rc |= 1;
130                 return rc | rc << 8;
131         case 01400062: /* keyboard data */
132                 rc = keybuf;
133                 keybuf = -1;
134                 return rc | rc << 8;
135         }
136         print("read %.8o (curpc = %.6x)\n", a, curpc & 0x3fffff);
137         return 0;
138 }
139
140 void
141 memwrite(u32int a, u16int v, u16int m)
142 {
143         extern Rectangle updated;
144         int x, y;
145
146         a &= 0x3fffff;
147         if(a < 0x40000){
148                 if(a >= daddr){
149                         y = (a - daddr) / 100;
150                         x = (((a & ~1) - daddr) % 100) * 8;
151                         if(updated.min.x > x) updated.min.x = x;
152                         if(updated.max.x < x+16) updated.max.x = x+16;
153                         if(updated.min.y > y) updated.min.y = y;
154                         if(updated.max.y <= y) updated.max.y = y+1;
155                 }
156                 ram[a/2] = ram[a/2] & ~m | v & m;
157                 return;
158         }
159         switch(a & ~1){
160         case 01400010: uartctrl = v; return;
161         case 01400012: uarttxbuf = (uchar) v; return;
162         case 01400024: return; /* mouse: purpose unknown */
163         case 01400026: return; /* mouse: purpose unknown */
164         case 01400030: daddr = ((daddr >> 2) & ~m | v & m) << 2; return;
165         case 01400040: dstat = dstat & ~m | v & m; invert = -(dstat & 1); updated = Rect(0, 0, SX, SY); return;
166         case 01400056: /* sound; exact function unknown */ return;
167         case 01400060: kbdctrl = v; return;
168         case 01400062: /* reset keyboard */ return;
169         case 01400070: irq &= ~INTVBL; return;
170         case 01400156: /* sound; exact function unknown */ return;
171         }
172         print("write %.8o = %.4x (mask = %.4x, curpc = %.6x)\n", a, v, m, curpc & 0x3fffff);
173 }
174
175 int
176 intack(int l)
177 {
178         return 24+l;
179 }