shithub: riscv

Download patch

ref: aa125d37e9fcec887dddafc1e4725f0875ed38d9
parent: ca35949c20cee081efe5cda03bfff64167da05d2
author: aiju <devnull@localhost>
date: Wed May 28 20:50:06 EDT 2014

games/md: bug fixes

--- a/sys/src/games/md/cpu.c
+++ b/sys/src/games/md/cpu.c
@@ -14,7 +14,7 @@
 };
 
 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 @@
 			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 @@
 {
 	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 @@
 {
 	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 @@
 	push16(sr);
 	pc = memread(v * 4) << 16;
 	pc |= memread(v * 4 + 2);
+	stop = 0;
 }
 
 void
@@ -461,7 +465,7 @@
 	int n, m, d;
 	static int cnt;
 
-	if(0 && pc == 0x61e8){
+	if(0 && pc == 0x200){
 		trace++;
 		print("%x\n", curpc);
 	}
@@ -470,6 +474,8 @@
 		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 @@
 			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 @@
 			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
--- a/sys/src/games/md/mem.c
+++ b/sys/src/games/md/mem.c
@@ -18,6 +18,9 @@
 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 @@
 			z80bus &= ~RESET;
 		return;
 	}
-	sysfatal("write to 0xa1%.4x", a);
+	sysfatal("write to 0xa1%.4x (pc=%#.6ux)", a, curpc);
 }
 
 void
@@ -154,6 +157,12 @@
 			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 @@
 	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 @@
 			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 @@
 				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 @@
 		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 @@
 			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 @@
 		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 @@
 		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;
 }
 
--- a/sys/src/games/md/vdp.c
+++ b/sys/src/games/md/vdp.c
@@ -145,7 +145,6 @@
 	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 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 @@
 	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 @@
 		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 @@
 				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;
 }