ref: 289fb207c93576321a21a2ff82f2bb45b56821ad
parent: ff677a1cb491b8a3b028057b71f662472107b418
author: aiju <devnull@localhost>
date: Fri Mar 14 11:06:21 EDT 2014
games/snes: added decimal mode and wai
--- a/sys/src/games/snes/cpu.c
+++ b/sys/src/games/snes/cpu.c
@@ -4,7 +4,7 @@
#include "dat.h"
#include "fns.h"
-u8int rP, emu, irq, nmi, dma;
+u8int rP, emu, irq, nmi, dma, wai;
u16int rA, rX, rY, rS, rD, pc;
u32int rDB, rPB, curpc, hdma;
static u8int m8, x8;
@@ -329,29 +329,51 @@
{
int r;
- if((rP & FLAGD) != 0)
- print("decimal mode\n");
if(m8){
- r = (rA & 0xff) + a + (rP & FLAGC);
+ if((rP & FLAGD) != 0){
+ r = (rA & 0xf) + (a & 0xf) + (rP & FLAGC);
+ if(r > 0x09)
+ r += 0x06;
+ if(r > 0x1f)
+ r -= 0x10;
+ r += (rA & 0xf0) + (a & 0xf0);
+ }else
+ r = (rA & 0xff) + a + (rP & FLAGC);
rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
+ if((~(rA ^ a) & (rA ^ r)) & 0x80)
+ rP |= FLAGV;
+ if((rP & FLAGD) != 0 && r > 0x9f)
+ r += 0x60;
if(r > 0xFF)
rP |= FLAGC;
rP |= r & 0x80;
- if((~(rA ^ a) & (rA ^ r)) & 0x80)
- rP |= FLAGV;
r &= 0xFF;
if(r == 0)
rP |= FLAGZ;
rA = rA & 0xFF00 | r;
}else{
- r = rA + a + (rP & FLAGC);
+ if((rP & FLAGD) != 0){
+ r = (rA & 0x000f) + (a & 0x000f) + (rP & FLAGC);
+ if(r > 0x0009) r += 0x0006;
+ if(r > 0x001f) r -= 0x0010;
+ r += (rA & 0x00f0) + (a & 0x00f0);
+ if(r > 0x0090) r += 0x0060;
+ if(r > 0x01f0) r -= 0x0100;
+ r += (rA & 0x0f00) + (a & 0x0f00);
+ if(r > 0x0900) r += 0x0600;
+ if(r > 0x1f00) r -= 0x1000;
+ r += (rA & 0xf000) + (a & 0xf000);
+ }else
+ r = rA + a + (rP & FLAGC);
rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
+ if((~(rA ^ a) & (rA ^ r)) & 0x8000)
+ rP |= FLAGV;
+ if((rP & FLAGD) != 0 && r > 0x9fff)
+ r += 0x6000;
if(r > 0xFFFF)
rP |= FLAGC;
if((r & 0x8000) != 0)
rP |= FLAGN;
- if((~(rA ^ a) & (rA ^ r)) & 0x8000)
- rP |= FLAGV;
rA = r;
if(rA == 0)
rP |= FLAGZ;
@@ -478,34 +500,51 @@
{
int r;
- if((rP & FLAGD) != 0)
- print("decimal mode\n");
if(m8){
- r = (rA & 0xff) + (a ^ 0xff) + (rP & FLAGC);
+ a ^= 0xff;
+ if((rP & FLAGD) != 0){
+ r = (rA & 0xf) + (a & 0xf) + (rP & FLAGC);
+ if(r < 0x10) r -= 0x06;
+ r += (rA & 0xf0) + (a & 0xf0);
+ }else
+ r = (rA & 0xff) + a + (rP & FLAGC);
rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
- if(r > 0xFF)
+ if((~(rA ^ a) & (rA ^ r)) & 0x80)
+ rP |= FLAGV;
+ if(r > 0xff)
rP |= FLAGC;
+ else if((rP & FLAGD) != 0)
+ r -= 0x60;
rP |= r & 0x80;
- if(((rA ^ a) & (rA ^ r)) & 0x80)
- rP |= FLAGV;
r &= 0xFF;
if(r == 0)
rP |= FLAGZ;
rA = rA & 0xFF00 | r;
}else{
- r = rA + (a ^ 0xffff) + (rP & FLAGC);
+ a ^= 0xffff;
+ if((rP & FLAGD) != 0){
+ r = (rA & 0x000f) + (a & 0x000f) + (rP & FLAGC);
+ if(r < 0x0010) r -= 0x0006;
+ r += (rA & 0x00f0) + (a & 0x00f0);
+ if(r < 0x0100) r -= 0x0060;
+ r += (rA & 0x0f00) + (a & 0x0f00);
+ if(r < 0x1000) r -= 0x0600;
+ r += (rA & 0xf000) + (a & 0xf000);
+ }else
+ r = rA + a + (rP & FLAGC);
rP &= ~(FLAGC | FLAGN | FLAGV | FLAGZ);
+ if((~(rA ^ a) & (rA ^ r)) & 0x8000)
+ rP |= FLAGV;
if(r > 0xFFFF)
rP |= FLAGC;
+ else if((rP & FLAGD) != 0)
+ r -= 0x6000;
if((r & 0x8000) != 0)
rP |= FLAGN;
- if(((rA ^ a) & (rA ^ r)) & 0x8000)
- rP |= FLAGV;
rA = r;
if(rA == 0)
rP |= FLAGZ;
}
-
}
static void
@@ -565,6 +604,7 @@
rPB = 0;
if(emu)
rDB = 0;
+ wai = 0;
}
void
@@ -605,6 +645,11 @@
return 8 - emu;
}
curpc = pc|rPB;
+ if(wai)
+ if(irq)
+ wai = 0;
+ else
+ return 1;
m8 = (rP & FLAGM) != 0;
x8 = (rP & FLAGX) != 0;
op = fetch8();
@@ -888,6 +933,7 @@
rX &= 0xff;
nzx(rX);
return 2;
+ case 0xCB: wai = 1; return 1;
case 0xCC: cmp(rY, memx816(abso(0, 0)), x8); return 4+cyc;
case 0xCD: cmp(rA, mem816(abso(0, 0), 0), m8); return 4+cyc;
case 0xCE: dec(abso(0, 0)); return 6+cyc;
@@ -903,6 +949,7 @@
case 0xD8: rP &= ~FLAGD; return 2;
case 0xD9: cmp(rA, mem816(abso(0, 2), 0), m8); return 4+cyc;
case 0xDA: push816(rX, x8); return 3+cyc;
+ case 0xDB: print("STP\n"); return 2;
case 0xDC: a = fetch16(); pc = memread(a) | memread((u16int)(a+1))<<8; rPB = memread((u16int)(a+2)) << 16; return 6;
case 0xDD: cmp(rA, mem816(abso(0, 1), 0), m8); return 4+cyc;
case 0xDE: dec(abso(0, 1)); return 7+cyc;