7 u16int ram[32768], vram[32768];
8 u16int cram[64], vsram[40];
16 u16int vdpaddr, vdpdata;
23 //#define vramdebug(a, s, a1, a2, a3) if((a & ~1) == 0xe7a0) print(s, a1, a2, a3);
24 #define vramdebug(a, s, a1, a2, a3)
32 case 0x0001: return 0xa0;
35 if((ctl[0] & 0x40) == 0)
37 return ctl[0] & 0xc0 | v & 0x3f;
40 return ctl[a-3>>1] & 0xc0 | 0x3f;
41 case 0x0009: case 0x000b: case 0x000d:
44 return (~z80bus & BUSACK) >> 1;
46 sysfatal("read from 0xa1%.4ux (pc=%#.6ux)", a, curpc);
51 regwrite(u16int a, u16int v)
54 case 0x0003: case 0x0005: case 0x0007:
55 case 0x0009: case 0x000b: case 0x000d:
59 z80bus = z80bus & ~BUSREQ | v & BUSREQ;
74 case 0x30f3: case 0x30f5: case 0x30f7: case 0x30f9: case 0x30fb:
77 sysfatal("write to 0xa1%.4x (pc=%#.6ux)", a, curpc);
85 if((vdplatch & 0x80) == 0){
86 if((v & 0xc000) == 0x8000){
94 vdplatch = vdplatch & 0xfc | v >> 14 | 0x80;
95 vdpaddr = vdpaddr & 0xc000 | v & 0x3fff;
97 vdplatch = vdplatch & 0x03 | v >> 2 & 0x1c;
98 vdpaddr = vdpaddr & 0x3fff | v << 14 & 0xc000;
99 if((v & 0x80) != 0 && (reg[MODE2] & DMAEN) != 0){
100 dma = reg[23] >> 6 & 3;
108 cramwrite(u16int a, u16int v)
113 w = v << 12 & 0xe00000 | v << 8 & 0xe000 | v << 4 & 0xe0;
124 if((sramctl & SRAMEN) != 0 && a >= sram0 && a <= sram1)
125 switch(sramctl & ADDRMASK){
126 case ADDREVEN: return sram[(a - sram0) >> 1] << 8;
127 case ADDRODD: return sram[(a - sram0) >> 1];
128 case ADDRBOTH: return sram[a - sram0] << 8 | sram[a - sram0 + 1];
130 return prg[(a % nprg) / 2];
132 switch(a >> 16 & 0xff){
134 if((z80bus & BUSACK) != 0)
135 v = z80read(a & 0x7fff);
145 if((a & 0xe700e0) != 0xc00000)
150 switch(vdplatch & 0xf){
153 vdpaddr += reg[AUTOINC];
161 vdpaddr = (vdpaddr + reg[AUTOINC]) & 0x7f;
164 v = cram[(vdpaddr & 0x7f) / 2];
165 vdpaddr = (vdpaddr + reg[AUTOINC]) & 0x7f;
173 if(dma != 0 && dma != 2)
175 if(vdpx >= 0xe4 || vdpx < 0x08)
178 case 8: case 10: case 12: case 14:
179 if((reg[MODE4] & WIDE) != 0)
180 v = vdpx - (vdpx >= 360 ? 406 : 0);
182 v = vdpx - (vdpx >= 296 ? 342 : 0);
184 return vdpy - (vdpy >= 234 ? 5 : 0) << 8 & 0xfe00 | frame << 8 | v >> 1 & 0xff;
185 return vdpy - (vdpy >= 234 ? 5 : 0) << 8 | v >> 1 & 0xff;
189 case 7: return ram[((u16int)a) / 2];
192 sysfatal("read from %#.6ux (pc=%#.6ux)", a, curpc);
198 memwrite(u32int a, u16int v, u16int m)
203 if(0 && (a & 0xe0fffe) == 0xe0df46)
204 print("%x %x %x\n", curpc, v, m);
205 switch((a >> 21) & 7){
207 if((sramctl & SRAMEN) != 0 && a >= sram0 && a <= sram1){
208 switch(sramctl & ADDRMASK){
209 case ADDREVEN: sram[(a - sram0) >> 1] = v >> 8; break;
210 case ADDRODD: sram[(a - sram0) >> 1] = v; break;
212 if((m & 0xff00) == 0xff00)
213 sram[a - sram0] = v >> 8;
214 if((m & 0xff) == 0xff)
215 sram[a + 1 - sram0] = v;
219 saveclock = SAVEFREQ;
224 switch(a >> 16 & 0xff){
226 if((z80bus & BUSACK) != 0)
227 z80write(a & 0xffff, v >> 8);
236 if((a & 0xe700e0) != 0xc00000)
243 vramdebug(vdpaddr, "vdp fill write val %x (pc = %x) %d\n", v & 0xff, curpc, 0);
244 p = &vram[vdpaddr / 2];
245 if((vdpaddr & 1) == 0)
246 *p = *p & 0xff | v << 8;
248 *p = *p & 0xff00 | v & 0xff;
252 switch(vdplatch & 0xf){
254 if((vdpaddr & 1) != 0)
256 p = &vram[vdpaddr / 2];
257 vramdebug(vdpaddr, "vdp write val %x mask %x (pc = %x)\n", v, m, curpc);
258 *p = *p & ~m | v & m;
259 vdpaddr += reg[AUTOINC];
262 cramwrite(vdpaddr & 0x7f, v);
263 vdpaddr = (vdpaddr + reg[AUTOINC]) & 0x7f;
269 vdpaddr = (vdpaddr + reg[AUTOINC]) & 0x7f;
277 case 16: case 18: case 20: case 22:
283 p = &ram[((u16int)a) / 2];
284 *p = *p & ~m | v & m;
288 sysfatal("write to %#.6x (pc=%#.6x)", a, curpc);
300 a = reg[DMASRC0] << 1 | reg[DMASRC1] << 9 | reg[DMASRC2] << 17;
302 if(++reg[DMASRC0] == 0)
304 switch(vdplatch & 0x7){
306 if((vdpaddr & 1) != 0)
308 vramdebug(vdpaddr, "dma from 68K %x val %x (%d)\n", a, v, 0);
309 vram[vdpaddr / 2] = v;
315 cramwrite(vdpaddr, v);
319 vsram[vdpaddr / 2] = v;
326 a = reg[DMASRC0] | reg[DMASRC1] << 8;
330 if(++reg[DMASRC0] == 0)
332 vramdebug(vdpaddr, "dma copy from %x val %x (%d)\n", a, v, 0);
333 p = &vram[vdpaddr / 2];
334 if((vdpaddr & 1) != 0)
335 *p = *p & 0xff00 | v & 0xff;
337 *p = *p & 0xff | v << 8;
340 p = &vram[vdpaddr / 2];
341 vramdebug(vdpaddr, "dma fill val %x (%d%d)\n", vdpdata, 0, 0);
342 if((vdpaddr & 1) == 0)
343 *p = *p & 0xff00 | vdpdata;
345 *p = *p & 0xff | vdpdata << 8;
348 vdpaddr += reg[AUTOINC];
349 if(reg[DMACL]-- == 0)
351 if((reg[DMACL] | reg[DMACH]) == 0)
363 return zram[a & 0x1fff];
368 v = memread(0xc00000 | a & 0x7e);
373 sysfatal("z80 read from %#.4x (pc=%#.4x)", a, scurpc);
375 v = memread(z80bank << 15 | a & 0x7ffe);
383 z80write(u16int a, u8int v)
388 zram[a & 0x1fff] = v;
392 case 0: yma1 = v; return;
393 case 1: ymwrite(yma1, v, 0); return;
394 case 2: yma2 = v; return;
395 case 3: ymwrite(yma2, v, 3); return;
399 z80bank = z80bank >> 1 | v << 8 & 0x100;
403 memwrite(0xc00000 | a & 0x7e, v | v << 8, (a & 1) != 0 ? 0xff : 0xff00);
406 sysfatal("z80 write to %#.4x (pc=%#.4x)", a, scurpc);
408 memwrite(z80bank << 15 | a & 0x7ffe, v << 8 | v, (a & 1) != 0 ? 0xff : 0xff00);
423 u32int irql[8] = {[6] INTVBL, [4] INTHOR};