diff options
author | aiju <devnull@localhost> | 2014-05-29 00:50:06 +0200 |
---|---|---|
committer | aiju <devnull@localhost> | 2014-05-29 00:50:06 +0200 |
commit | aa125d37e9fcec887dddafc1e4725f0875ed38d9 (patch) | |
tree | 8c83181c0972f1c92f3f3f1a50548552b084fc44 /sys/src | |
parent | ca35949c20cee081efe5cda03bfff64167da05d2 (diff) |
games/md: bug fixes
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/games/md/cpu.c | 37 | ||||
-rw-r--r-- | sys/src/games/md/mem.c | 22 | ||||
-rw-r--r-- | sys/src/games/md/vdp.c | 20 |
3 files changed, 55 insertions, 24 deletions
diff --git a/sys/src/games/md/cpu.c b/sys/src/games/md/cpu.c index c643bbe3b..460526da7 100644 --- a/sys/src/games/md/cpu.c +++ b/sys/src/games/md/cpu.c @@ -14,7 +14,7 @@ enum { }; u32int r[16], pc, curpc; -u32int asp, irq; +u32int asp, irq, stop; extern u32int irql[8]; u32int irqla[8]; u16int rS; @@ -248,12 +248,12 @@ add(u32int u, u32int w, int c, int s) rS &= ~FLAGZ; break; default: - v = w + u + c; + v = (u64int)w + u + c; if((v >> 32) != 0) rS |= FLAGC; - if((v >> 31) != 0) + if((v & 0x80000000) != 0) rS |= FLAGN; - if((~(w ^ u) & (v ^ u) & (1<<31)) != 0) + if((~(w ^ u) & (v ^ u) & 0x80000000) != 0) rS |= FLAGV; if((u32int)v != 0) rS &= ~FLAGZ; @@ -380,10 +380,11 @@ addbcd(u8int a, u8int b) { int r; - r = (a & 0xf) + (b & 0xf) + (rS & FLAGX >> 4); + r = (a & 0xf) + (b & 0xf) + ((rS & FLAGX) != 0); if(r > 0x09) r += 0x06; if(r > 0x1f) r -= 0x10; r += (a & 0xf0) + (b & 0xf0); + if(r > 0x9f) r += 0x60; if((u8int)r != 0) rS &= ~FLAGZ; if(r > 0xff) @@ -398,16 +399,18 @@ subbcd(u8int a, u8int b) { int x; - x = (a & 0xf) + (~b & 0xf) + !(rS & FLAGX); + x = (a & 0xf) + (~b & 0xf) + ((rS & FLAGX) == 0); if(x < 0x10) x -= 0x06; if(x < 0) x += 0x10; x += (a & 0xf0) + (~b & 0xf0); + if(x > 0xff) + rS &= ~(FLAGC|FLAGX); + else{ + rS |= FLAGC|FLAGX; + x -= 0x60; + } if((u8int)x != 0) rS &= ~FLAGZ; - if(x <= 0xff) - rS |= FLAGC|FLAGX; - else - rS &= ~(FLAGC|FLAGX); return x; } @@ -437,6 +440,7 @@ trap(int n, u32int pcv) push16(sr); pc = memread(v * 4) << 16; pc |= memread(v * 4 + 2); + stop = 0; } void @@ -461,7 +465,7 @@ step(void) int n, m, d; static int cnt; - if(0 && pc == 0x61e8){ + if(0 && pc == 0x200){ trace++; print("%x\n", curpc); } @@ -470,6 +474,8 @@ step(void) trap(-1, curpc); return; } + if(stop) + return; op = fetch16(); if(trace) print("%.6ux %.6uo %.4ux %.8ux | %.8ux %.8ux %.8ux %.8ux | %.8ux %.8ux %.8ux\n", curpc, op, rS, memread(ra[7])<<16|memread(ra[7]+2), r[0], r[1], r[2], r[3], ra[0], ra[1], ra[7]); @@ -765,6 +771,13 @@ step(void) switch(op){ case 0x4e70: break; /* RESET */ case 0x4e71: break; /* NOP */ + case 0x4e72: /* STOP */ + if((rS & FLAGS) != 0){ + rS = fetch16(); + stop = 1; + }else + trap(8, curpc); + break; case 0x4e73: /* RTE */ if((rS & FLAGS) != 0){ v = rS; @@ -875,7 +888,7 @@ step(void) if((op & 8) != 0){ a = amode(4, n, 0); v = rmode(a, 0); - w = rmode(amode(5, n, 0), 0); + w = rmode(amode(4, m, 0), 0); v = subbcd(v, w); wmode(a, 0, v); }else diff --git a/sys/src/games/md/mem.c b/sys/src/games/md/mem.c index c746498a4..6b0d05a81 100644 --- a/sys/src/games/md/mem.c +++ b/sys/src/games/md/mem.c @@ -18,6 +18,9 @@ u16int vdpaddr, vdpdata; u8int z80bus = RESET; u16int z80bank; +//#define vramdebug(a, s, a1, a2, a3) if((a & ~1) == 0xe7a0) print(s, a1, a2, a3); +#define vramdebug(a, s, a1, a2, a3) + u8int regread(u16int a) { @@ -60,7 +63,7 @@ regwrite(u16int a, u16int v) z80bus &= ~RESET; return; } - sysfatal("write to 0xa1%.4x", a); + sysfatal("write to 0xa1%.4x (pc=%#.6ux)", a, curpc); } void @@ -154,6 +157,12 @@ memread(u32int a) if(vdpx >= 0xe4 || vdpx < 0x08) v |= STATHBL; return v; + case 8: case 10: case 12: case 14: + if((reg[MODE4] & WIDE) != 0) + v = vdpx - (vdpx >= 360 ? 406 : 0); + else + v = vdpx - (vdpx >= 296 ? 342 : 0); + return vdpy - (vdpy >= 234 ? 5 : 0) << 8 | v >> 1 & 0xff; default: goto invalid; } @@ -171,7 +180,7 @@ memwrite(u32int a, u16int v, u16int m) u16int *p; u16int w; - if(0 && (a & 0xe0fffe) == 0xe0b1f4) + if(0 && (a & 0xe0fffe) == 0xe0df46) print("%x %x %x\n", curpc, v, m); switch((a >> 21) & 7){ case 5: @@ -194,6 +203,7 @@ memwrite(u32int a, u16int v, u16int m) if(dma == 2){ dma = 4; vdpdata = v >> 8; + vramdebug(vdpaddr, "vdp fill write val %x (pc = %x) %d\n", v & 0xff, curpc, 0); p = &vram[vdpaddr / 2]; if((vdpaddr & 1) == 0) *p = *p & 0xff | v << 8; @@ -207,6 +217,7 @@ memwrite(u32int a, u16int v, u16int m) if((vdpaddr & 1) != 0) v = v << 8 | v >> 8; p = &vram[vdpaddr / 2]; + vramdebug(vdpaddr, "vdp write val %x mask %x (pc = %x)\n", v, m, curpc); *p = *p & ~m | v & m; vdpaddr += reg[AUTOINC]; return; @@ -257,6 +268,7 @@ dmastep(void) case 1: if((vdpaddr & 1) != 0) v = v >> 8 | v << 8; + vramdebug(vdpaddr, "dma from 68K %x val %x (%d)\n", a, v, 0); vram[vdpaddr / 2] = v; break; case 3: @@ -280,6 +292,7 @@ dmastep(void) v = v >> 8; if(++reg[DMASRC0] == 0) reg[DMASRC1]++; + vramdebug(vdpaddr, "dma copy from %x val %x (%d)\n", a, v, 0); p = &vram[vdpaddr / 2]; if((vdpaddr & 1) != 0) *p = *p & 0xff00 | v & 0xff; @@ -288,6 +301,7 @@ dmastep(void) break; case 4: p = &vram[vdpaddr / 2]; + vramdebug(vdpaddr, "dma fill val %x (%d%d)\n", vdpdata, 0, 0); if((vdpaddr & 1) == 0) *p = *p & 0xff00 | vdpdata; else @@ -295,7 +309,9 @@ dmastep(void) break; } vdpaddr += reg[AUTOINC]; - if(--reg[DMACL] == 0 && reg[DMACH]-- == 0) + if(reg[DMACL]-- == 0) + reg[DMACH]--; + if((reg[DMACL] | reg[DMACH]) == 0) dma = 0; } diff --git a/sys/src/games/md/vdp.c b/sys/src/games/md/vdp.c index 39502e1e0..c53d63c51 100644 --- a/sys/src/games/md/vdp.c +++ b/sys/src/games/md/vdp.c @@ -145,7 +145,6 @@ planeinit(void) if(rwin > lwin){ p = pctxt + 2; p->tx = p->ty = 0; - v = vdpy - v; p->tny = vdpy & 7; p->ty = vdpy >> 3 & pctxt[2].h - 1; tile(p); @@ -211,9 +210,9 @@ static struct sprite { static void spritesinit(void) { - u16int t, *p, dy, *c; + u16int t, *p, dy, c; u32int v; - int i, ns, np; + int i, ns, np, nt; struct sprite *q; t = (reg[SPRTAB] << 8 & 0x7f00); @@ -221,6 +220,7 @@ spritesinit(void) q = spr; ns = (reg[MODE4] & WIDE) != 0 ? 20 : 16; np = 0; + nt = 0; do{ q->y = (p[0] & 0x3ff) - 128; q->h = (p[1] >> 8 & 3) + 1 << 3; @@ -234,9 +234,9 @@ spritesinit(void) if(q->x == 0xff80) break; q->w = (p[1] >> 10 & 3) + 1 << 3; - c = vram + ((q->t & 0x7ff) << 4) + (dy << 1); + c = ((q->t & 0x7ff) << 4) + (dy << 1); for(i = 0; i < q->w >> 3 && np < xdisp; i++){ - v = c[0] << 16 | c[1]; + v = vram[c] << 16 | vram[(u16int)(c+1)]; c += q->h << 1; if((q->t & 0x800) != 0) q->c[(q->w >> 3) - 1 - i] = v; @@ -244,16 +244,18 @@ spritesinit(void) q->c[i] = v; np += 8; } - if(-q->x < q->w) + if((u16int)-q->x < q->w){ + i = -(s16int)q->x; if((q->t & 0x800) != 0) - q->c[-q->x>>3] >>= (-q->x & 7) << 2; + q->c[i>>3] >>= (i & 7) << 2; else - q->c[-q->x>>3] <<= (-q->x & 7) << 2; + q->c[i>>3] <<= (i & 7) << 2; + } if(++q == spr + ns || np >= xdisp){ vdpstat |= STATOVR; break; } - }while(p = vram + (u16int)(t + ((p[1] & 0x7f) << 2)), p - vram != t); + }while(p = vram + (u16int)(t + ((p[1] & 0x7f) << 2)), p - vram != t && ++nt < 80); lsp = q; } |