You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1797 lines
28 KiB
C

#include <stdio.h>
#include "cpu/65el02.h"
#include "memory/memory.h"
int nospbug = 0;
int readMem(int addr)
{
int i = 0;
while ( (i <= cpu.breakpoint_count) && ((cpu.breakpoints[i] & 0x2ffff) != (cpu.regPC | 0x20000)) )
i++;
if (i <= cpu.breakpoint_count) // breakpoint hit
{
cpu.cycles = 0;
cpu.brk = 1;
}
return (mem_load(addr) & 0xff);
}
void writeMem(int addr, int val)
{
int i = 0;
while ( (i <= cpu.breakpoint_count) && ((cpu.breakpoints[i] & 0x4ffff) != (cpu.regPC | 0x40000)) )
i++;
if (i <= cpu.breakpoint_count) // breakpoint hit
{
cpu.cycles = 0;
cpu.brk = 1;
}
mem_store(addr, val);
}
void
coldBootCPU()
{
cpu.addrPOR = 0x2000;
cpu.addrBRK = 0x2000;
if (nospbug)
cpu.regSP = 0x1ff;
else
cpu.regSP = 0x200;
cpu.regPC = 0x400;
cpu.regR = 0x300;
cpu.regA = 0;
cpu.regX = 0;
cpu.regY = 0;
cpu.regD = 0;
cpu.flagC = 0;
cpu.flagZ = 0;
cpu.flagID = 0;
cpu.flagD = 0;
cpu.flagBRK = 0;
cpu.flagO = 0;
cpu.flagN = 0;
cpu.flagE = 1;
cpu.flagM = 1;
cpu.flagX = 1;
if (!cpu.byte0)
cpu.byte0 = 2;
if (!cpu.byte1)
cpu.byte1 = 1;
cpu.cycles = 0;
cpu.ticks = 0;
cpu.brk = 0;
if (!cpu.cycles_per_tick)
cpu.cycles_per_tick = 1000;
}
void incPC()
{
cpu.regPC = (cpu.regPC + 1) & 0xffff;
}
int maskM()
{
return cpu.flagM ? 0xff : 0xffff;
}
int maskX()
{
return cpu.flagX ? 0xff : 0xffff;
}
int negM()
{
return cpu.flagM ? 0x80 : 0x8000;
}
int negX()
{
return cpu.flagX ? 0x80 : 0x8000;
}
int readB()
{
int i = readMem(cpu.regPC);
incPC();
return i;
}
int readM_PC()
{
int i = readMem(cpu.regPC);
incPC();
if (!cpu.flagM)
{
i |= readMem(cpu.regPC) << 8;
incPC();
}
return i;
}
int readX_PC()
{
int i = readMem(cpu.regPC);
incPC();
if (!cpu.flagX)
{
i |= readMem(cpu.regPC) << 8;
incPC();
}
return i;
}
int readM(int addr)
{
int i = readMem(addr);
if (!cpu.flagM)
i |= readMem(addr + 1) << 8;
return i;
}
int readX(int addr)
{
int i = readMem(addr);
if (!cpu.flagX)
i |= readMem(addr + 1) << 8;
return i;
}
void writeM(int addr, int reg)
{
writeMem(addr, reg);
if (!cpu.flagM)
writeMem(addr + 1, reg >> 8);
}
void writeX(int addr, int reg)
{
writeMem(addr, reg);
if (!cpu.flagX)
writeMem(addr + 1, reg >> 8);
}
int readBX()
{
int i = readMem(cpu.regPC) + cpu.regX;
if (cpu.flagX)
i &= 0xff;
incPC();
return i;
}
int readBY()
{
int i = readMem(cpu.regPC) + cpu.regY;
if (cpu.flagX)
i &= 0xff;
incPC();
return i;
}
int readBS()
{
int i = readMem(cpu.regPC) + cpu.regSP & 0xffff;
incPC();
return i;
}
int readBR()
{
int i = readMem(cpu.regPC) + cpu.regR & 0xffff;
incPC();
return i;
}
int readBSWY()
{
int i = readMem(cpu.regPC) + cpu.regSP & 0xffff;
incPC();
return readW(i) + cpu.regY & 0xffff;
}
int readBRWY()
{
int i = readMem(cpu.regPC) + cpu.regR & 0xffff;
incPC();
return readW(i) + cpu.regY & 0xffff;
}
int readW_PC()
{
int i = readMem(cpu.regPC);
incPC();
i |= readMem(cpu.regPC) << 8;
incPC();
return i;
}
int readW(int addr)
{
int i = readMem(addr);
i |= readMem(addr + 1) << 8;
return i;
}
int readWX()
{
int i = readMem(cpu.regPC);
incPC();
i |= readMem(cpu.regPC) << 8;
incPC();
return i + cpu.regX & 0xffff;
}
int readWY()
{
int i = readMem(cpu.regPC);
incPC();
i |= readMem(cpu.regPC) << 8;
incPC();
return i + cpu.regY & 0xffff;
}
int readWXW()
{
int i = readMem(cpu.regPC);
incPC();
i |= readMem(cpu.regPC) << 8;
incPC();
i = i + cpu.regX & 0xffff;
int j = readMem(i);
j |= readMem(i + 1) << 8;
return j;
}
int readBW()
{
int i = readMem(cpu.regPC);
incPC();
int j = readMem(i);
j |= readMem(i + 1) << 8;
return j;
}
int readWW()
{
int i = readMem(cpu.regPC);
incPC();
i |= readMem(cpu.regPC) << 8;
incPC();
int j = readMem(i);
j |= readMem(i + 1) << 8;
return j;
}
int readBXW()
{
int i = readMem(cpu.regPC) + cpu.regX & 0xff;
incPC();
int j = readMem(i);
j |= readMem(i + 1) << 8;
return j;
}
int readBWY()
{
int i = readMem(cpu.regPC);
incPC();
int j = readMem(i);
j |= readMem(i + 1) << 8;
return j + cpu.regY & 0xffff;
}
void upNZ_A()
{
cpu.flagN = ((cpu.regA & negM()) > 0);
cpu.flagZ = (cpu.regA == 0);
}
void upNZ(int i)
{
cpu.flagN = ((i & negM()) > 0);
cpu.flagZ = (i == 0);
}
void upNZX(int i)
{
cpu.flagN = ((i & negX()) > 0);
cpu.flagZ = (i == 0);
}
void push1(int b)
{
if (nospbug)
writeMem(cpu.regSP, b);
if (!cpu.flagE)
cpu.regSP = (cpu.regSP - 1) & 0xffff;
else
cpu.regSP = ((cpu.regSP - 1) & 0xff) | (cpu.regSP & 0xff00);
if (!nospbug)
writeMem(cpu.regSP, b);
}
void push1r(int b)
{
cpu.regR = (cpu.regR - 1) & 0xffff;
writeMem(cpu.regR, b);
}
void push2(int w)
{
push1(w >> 8);
push1(w & 0xff);
}
void push2r(int w)
{
push1r(w >> 8);
push1r(w & 0xff);
}
void pushM(int b)
{
if (cpu.flagM)
push1(b);
else
push2(b);
}
void pushX(int b)
{
if (cpu.flagX)
push1(b);
else
push2(b);
}
void pushMr(int b)
{
if (cpu.flagM)
push1r(b);
else
push2r(b);
}
void pushXr(int b)
{
if (cpu.flagX)
push1r(b);
else
push2r(b);
}
int pop1()
{
int tr;
if (!nospbug)
tr = readMem(cpu.regSP);
if (!cpu.flagE)
cpu.regSP = (cpu.regSP + 1) & 0xffff;
else
cpu.regSP = ((cpu.regSP + 1) & 0xff) | (cpu.regSP & 0xff00);
if (nospbug)
tr = readMem(cpu.regSP);
return tr;
}
int pop1r()
{
int tr = readMem(cpu.regR);
cpu.regR = (cpu.regR + 1) & 0xffff;
return tr;
}
int pop2()
{
int tr = pop1();
tr |= pop1() << 8;
return tr;
}
int pop2r()
{
int tr = pop1r();
tr |= pop1r() << 8;
return tr;
}
int popM()
{
if (cpu.flagM)
return pop1();
return pop2();
}
int popMr()
{
if (cpu.flagM)
return pop1r();
return pop2r();
}
int popX()
{
if (cpu.flagX)
return pop1();
return pop2();
}
int popXr()
{
if (cpu.flagX)
return pop1r();
return pop2r();
}
int getFlags()
{
return (cpu.flagC ? 1 : 0) | (cpu.flagZ ? 2 : 0) | (cpu.flagID ? 4 : 0) | (cpu.flagD ? 8 : 0) | (cpu.flagX ? 16 : 0) | (cpu.flagM ? 32 : 0) | (cpu.flagO ? 64 : 0) | (cpu.flagN ? 128 : 0);
}
void setFlags(int flags)
{
int m2 = (flags & 0x20) > 0;
cpu.flagC = ((flags & 0x1) > 0);
cpu.flagZ = ((flags & 0x2) > 0);
cpu.flagID = ((flags & 0x4) > 0);
cpu.flagD = ((flags & 0x8) > 0);
cpu.flagX = ((flags & 0x10) > 0);
cpu.flagO = ((flags & 0x40) > 0);
cpu.flagN = ((flags & 0x80) > 0);
if (cpu.flagE)
{
cpu.flagX = 0;
cpu.flagM = 0;
}
else
{
cpu.flagX = ((flags & 0x10) > 0);
if (cpu.flagX)
{
cpu.regX &= 0xff;
cpu.regY &= 0xff;
}
if (m2 != cpu.flagM)
{
if (m2)
{
cpu.regB = (cpu.regA >> 8);
cpu.regA &= 0xff;
}
else
{
cpu.regA |= cpu.regB << 8;
}
cpu.flagM = m2;
}
}
}
void i_adc(int val)
{
if (cpu.flagM)
{
if (cpu.flagD)
{
int v1 = (cpu.regA & 0x0f) + (val & 0x0f) + (cpu.flagC ? 1 : 0);
if (v1 > 9)
v1 = (v1 + 6 & 0x0f) + 16;
int v2 = (cpu.regA & 0xf0) + (val & 0xf0) + v1;
if (v2 > 160)
v2 += 96;
cpu.flagC = (v2 > 100);
cpu.regA = (v2 & 0xff);
cpu.flagO = 0;
}
else
{
int v = cpu.regA + val + (cpu.flagC ? 1 : 0);
cpu.flagC = (v > 0xff);
cpu.flagO = (((v ^ cpu.regA) & (v ^ val) & 0x80) > 0);
cpu.regA = (v & 0xff);
}
}
else
{
int v = cpu.regA + val + (cpu.flagC ? 1 : 0);
cpu.flagC = (v > 0xffff);
cpu.flagO = (((v ^ cpu.regA) & (v ^ val) & 0x8000) > 0);
cpu.regA = (v & 0xffff);
}
upNZ_A();
}
void i_sbc(int val)
{
if (cpu.flagM)
{
if (cpu.flagD)
{
int v1 = (cpu.regA & 0x0f) - (val & 0x0f) + (cpu.flagC ? 1 : 0) - 1;
if (v1 < 0)
v1 = (v1 - 6 & 0x0f) - 16;
int v2 = (cpu.regA & 0xf0) - (val & 0xf0) + v1;
if (v2 < 0)
v2 -= 96;
cpu.flagC = (v2 < 100);
cpu.regA = (v2 & 0xff);
cpu.flagO = 0;
}
else
{
int v = cpu.regA - val + (cpu.flagC ? 1 : 0) - 1;
cpu.flagC = ((v & 0x100) == 0);
cpu.flagO = (((v ^ cpu.regA) & (v ^ -val) & 0x80) > 0);
cpu.regA = (v & 0xff);
}
}
else
{
int v = cpu.regA - val + (cpu.flagC ? 1 : 0) - 1;
cpu.flagC = ((v & 0x10000) == 0);
cpu.flagO = (((v ^ cpu.regA) & (v ^ -val) & 0x8000) > 0);
cpu.regA = (v & 0xffff);
}
upNZ_A();
}
void i_mul(int val)
{
int v;
if (cpu.flagM)
{
if (cpu.flagC)
v = (signed char) val * (signed char) cpu.regA;
else
v = (unsigned char) val * (unsigned char) cpu.regA;
cpu.regA = (v & 0xff);
cpu.regD = (v >> 8 & 0xff);
cpu.flagN = (v < 0);
cpu.flagZ = (v == 0);
cpu.flagO = ((cpu.regD != 0) && (cpu.regD != 0xff));
}
else
{
if (cpu.flagC)
v = (short) val * (short) cpu.regA;
else
v = (unsigned short) val * (unsigned short) cpu.regA;
cpu.regA = (v & 0xffff);
cpu.regD = ((v >> 16) & 0xffff);
cpu.flagN = (v < 0);
cpu.flagZ = (v == 0);
cpu.flagO = ((cpu.regD != 0) && (cpu.regD != 0xffff));
}
}
void i_div(int val)
{
int q;
if (val == 0)
{
cpu.regA = 0;
cpu.regD = 0;
cpu.flagO = 1;
cpu.flagZ = 0;
cpu.flagN = 0;
return;
}
if (cpu.flagM)
{
if (cpu.flagC)
{
q = (signed char) cpu.regD << 8 | cpu.regA;
val = (signed char) val;
}
else
q = (unsigned char) cpu.regD << 8 | cpu.regA;
cpu.regD = (q % val & 0xff);
q /= val;
cpu.regA = (q & 0xff);
if (cpu.flagC)
cpu.flagO = ((q > 127) || (q < -128));
else
cpu.flagO = (q > 255);
cpu.flagZ = (cpu.regA == 0);
cpu.flagN = (q < 0);
}
else
{
if (cpu.flagC)
{
q = (short) cpu.regD << 16 | cpu.regA;
val = (short) val;
}
else
q = (unsigned short) cpu.regD << 16 | cpu.regA;
cpu.regD = (q % val & 0xffff);
q /= val;
cpu.regA = (q & 0xffff);
if (cpu.flagC)
cpu.flagO = ((q > 32767) || (q < -32768));
else
cpu.flagO = (q > 65535);
cpu.flagZ = (cpu.regA == 0);
cpu.flagN = (q < 0);
}
}
void i_and(int val)
{
cpu.regA &= val;
upNZ_A();
}
void i_asl(int addr)
{
int i = readM(addr);
cpu.flagC = ((i & negM()) > 0);
i = i << 1 & maskM();
upNZ(i);
writeM(addr, i);
}
void i_lsr(int addr)
{
int i = readM(addr);
cpu.flagC = ((i & 0x1) > 0);
i = i >> 1;
upNZ(i);
writeM(addr, i);
}
void i_rol(int addr)
{
int i = readM(addr);
int n = (i << 1 | (cpu.flagC ? 1 : 0)) & maskM();
cpu.flagC = ((i & negM()) > 0);
upNZ(n);
writeM(addr, n);
}
void i_ror(int addr)
{
int i = readM(addr);
int n = i >> 1 | (cpu.flagC ? negM() : 0);
cpu.flagC = ((i & 0x1) > 0);
upNZ(n);
writeM(addr, n);
}
void i_brc(int cond)
{
int n = readB();
if (cond)
cpu.regPC = (cpu.regPC + (signed char) n & 0xffff);
}
void i_bit(int val)
{
if (cpu.flagM)
{
cpu.flagO = ((val & 0x40) > 0);
cpu.flagN = ((val & 0x80) > 0);
}
else
{
cpu.flagO = ((val & 0x4000) > 0);
cpu.flagN = ((val & 0x8000) > 0);
}
cpu.flagZ = ((val & cpu.regA) > 0);
}
void i_trb(int val)
{
cpu.flagZ = ((val & cpu.regA) > 0);
cpu.regA &= (val ^ 0xffffffff);
}
void i_tsb(int val)
{
cpu.flagZ = ((val & cpu.regA) > 0);
cpu.regA |= val;
}
void i_cmp(int reg, int val)
{
reg -= val;
cpu.flagC = (reg >= 0);
cpu.flagZ = (reg == 0);
cpu.flagN = ((reg & negM()) > 0);
}
void i_cmpx(int reg, int val)
{
reg -= val;
cpu.flagC = (reg >= 0);
cpu.flagZ = (reg == 0);
cpu.flagN = ((reg & negX()) > 0);
}
void i_dec(int addr)
{
int i = readM(addr);
i = i - 1 & maskM();
writeM(addr, i);
upNZ(i);
}
void i_inc(int addr)
{
int i = readM(addr);
i = i + 1 & maskM();
writeM(addr, i);
upNZ(i);
}
void i_eor(int val)
{
cpu.regA ^= val;
upNZ_A();
}
void i_or(int val)
{
cpu.regA |= val;
upNZ_A();
}
void i_mmu(int mmu)
{
int t;
switch (mmu)
{
case 0x00:
t = cpu.regA & 0xff;
if ((t != cpu.mmuRBA) && (!cpu.no_io_penality))
cpu.rbTimeout = 1;
cpu.mmuRBA = t;
break;
case 0x80:
cpu.regA = cpu.mmuRBA;
break;
case 0x01:
cpu.mmuRBB = cpu.regA;
break;
case 0x81:
cpu.regA = cpu.mmuRBB;
if (!cpu.flagM)
break;
cpu.regB = (cpu.regA >> 8);
cpu.regA &= 0xff;
break;
case 0x02:
cpu.mmuEnRB = 1;
break;
case 0x82:
cpu.mmuEnRB = 0;
break;
case 0x03:
cpu.mmuRBW = cpu.regA;
break;
case 0x83:
cpu.regA = cpu.mmuRBW;
if (!cpu.flagM)
break;
cpu.regB = (cpu.regA >> 8);
cpu.regA &= 0xff;
break;
case 0x04:
cpu.mmuEnRBW = 1;
break;
case 0x84:
cpu.mmuEnRBW = 0;
break;
case 0x05:
cpu.addrBRK = cpu.regA;
break;
case 0x85:
cpu.regA = cpu.addrBRK;
if (!cpu.flagM)
break;
cpu.regB = (cpu.regA >> 8);
cpu.regA &= 0xff;
break;
case 0x06:
cpu.addrPOR = cpu.regA;
break;
case 0x86:
cpu.regA = cpu.addrPOR;
if (!cpu.flagM)
break;
cpu.regB = (cpu.regA >> 8);
cpu.regA &= 0xff;
break;
default:
printf("invalid MMU parameter %02x\n",mmu);
}
}
void executeInsn()
{
int insn = readMem(cpu.regPC);
incPC();
int n;
switch (insn)
{
case 0x69:
i_adc(readM_PC());
break;
case 0x65:
i_adc(readM(readB()));
break;
case 0x75:
i_adc(readM(readBX()));
break;
case 0x6d:
i_adc(readM(readW_PC()));
break;
case 0x7d:
i_adc(readM(readWX()));
break;
case 0x79:
i_adc(readM(readWY()));
break;
case 0x61:
i_adc(readM(readBXW()));
break;
case 0x71:
i_adc(readM(readBWY()));
break;
case 0x72:
i_adc(readM(readBW()));
break;
case 0x63:
i_adc(readM(readBS()));
break;
case 0x73:
i_adc(readM(readBSWY()));
break;
case 0x67:
i_adc(readM(readBR()));
break;
case 0x77:
i_adc(readM(readBRWY()));
break;
case 0x29:
i_and(readM_PC());
break;
case 0x25:
i_and(readM(readB()));
break;
case 0x35:
i_and(readM(readBX()));
break;
case 0x2d:
i_and(readM(readW_PC()));
break;
case 0x3d:
i_and(readM(readWX()));
break;
case 0x39:
i_and(readM(readWY()));
break;
case 0x21:
i_and(readM(readBXW()));
break;
case 0x31:
i_and(readM(readBWY()));
break;
case 0x32:
i_and(readM(readBW()));
break;
case 0x23:
i_and(readM(readBS()));
break;
case 0x33:
i_and(readM(readBSWY()));
break;
case 0x27:
i_and(readM(readBR()));
break;
case 0x37:
i_and(readM(readBRWY()));
break;
case 0x0a:
cpu.flagC = ((cpu.regA & negM()) > 0);
cpu.regA = (cpu.regA << 1 & maskM());
upNZ_A();
break;
case 0x06:
i_asl(readB());
break;
case 0x16:
i_asl(readBX());
break;
case 0x0e:
i_asl(readW_PC());
break;
case 0x1e:
i_asl(readWX());
break;
case 0x90:
i_brc(!cpu.flagC);
break;
case 0xb0:
i_brc(cpu.flagC);
break;
case 0xf0:
i_brc(cpu.flagZ);
break;
case 0x30:
i_brc(cpu.flagN);
break;
case 0xd0:
i_brc(!cpu.flagZ);
break;
case 0x10:
i_brc(!cpu.flagN);
break;
case 0x50:
i_brc(!cpu.flagO);
break;
case 0x70:
i_brc(cpu.flagO);
break;
case 0x80:
i_brc(1);
break;
case 0x89:
cpu.flagZ = ((readM_PC() & cpu.regA) == 0);
break;
case 0x24:
i_bit(readM(readB()));
break;
case 0x34:
i_bit(readM(readBX()));
break;
case 0x2c:
i_bit(readM(readW_PC()));
break;
case 0x3c:
i_bit(readM(readWX()));
break;
case 0x00:
push2(cpu.regPC);
push1(getFlags());
cpu.flagBRK = 1;
cpu.regPC = cpu.addrBRK;
break;
case 0x18:
cpu.flagC = 0;
break;
case 0xd8:
cpu.flagD = 0;
break;
case 0x58:
cpu.flagID = 0;
break;
case 0xb8:
cpu.flagO = 0;
break;
case 0xc9:
i_cmp(cpu.regA, readM_PC());
break;
case 0xc5:
i_cmp(cpu.regA, readM(readB()));
break;
case 0xd5:
i_cmp(cpu.regA, readM(readBX()));
break;
case 0xcd:
i_cmp(cpu.regA, readM(readW_PC()));
break;
case 0xdd:
i_cmp(cpu.regA, readM(readWX()));
break;
case 0xd9:
i_cmp(cpu.regA, readM(readWY()));
break;
case 0xc1:
i_cmp(cpu.regA, readM(readBXW()));
break;
case 0xd1:
i_cmp(cpu.regA, readM(readBWY()));
break;
case 0xd2:
i_cmp(cpu.regA, readM(readBW()));
break;
case 0xc3:
i_cmp(cpu.regA, readM(readBS()));
break;
case 0xd3:
i_cmp(cpu.regA, readM(readBSWY()));
break;
case 0xc7:
i_cmp(cpu.regA, readM(readBR()));
break;
case 0xd7:
i_cmp(cpu.regA, readM(readBRWY()));
break;
case 0xe0:
i_cmpx(cpu.regX, readX_PC());
break;
case 0xe4:
i_cmpx(cpu.regX, readX(readB()));
break;
case 0xec:
i_cmpx(cpu.regX, readX(readW_PC()));
break;
case 0xc0:
i_cmpx(cpu.regY, readX_PC());
break;
case 0xc4:
i_cmpx(cpu.regY, readX(readB()));
break;
case 0xcc:
i_cmpx(cpu.regY, readX(readW_PC()));
break;
case 0x3a:
cpu.regA = (cpu.regA - 1 & maskM());
upNZ(cpu.regA);
break;
case 0xc6:
i_dec(readB());
break;
case 0xd6:
i_dec(readBX());
break;
case 0xce:
i_dec(readW_PC());
break;
case 0xde:
i_dec(readWX());
break;
case 0xca:
cpu.regX = (cpu.regX - 1 & maskX());
upNZ(cpu.regX);
break;
case 0x88:
cpu.regY = (cpu.regY - 1 & maskX());
upNZ(cpu.regY);
break;
case 0x49:
i_eor(readM_PC());
break;
case 0x45:
i_eor(readM(readB()));
break;
case 0x55:
i_eor(readM(readBX()));
break;
case 0x4d:
i_eor(readM(readW_PC()));
break;
case 0x5d:
i_eor(readM(readWX()));
break;
case 0x59:
i_eor(readM(readWY()));
break;
case 0x41:
i_eor(readM(readBXW()));
break;
case 0x51:
i_eor(readM(readBWY()));
break;
case 0x52:
i_eor(readM(readBW()));
break;
case 0x43:
i_eor(readM(readBS()));
break;
case 0x53:
i_eor(readM(readBSWY()));
break;
case 0x47:
i_eor(readM(readBR()));
break;
case 0x57:
i_eor(readM(readBRWY()));
break;
case 0x1a:
cpu.regA = (cpu.regA + 1 & maskM());
upNZ(cpu.regA);
break;
case 0xe6:
i_inc(readB());
break;
case 0xf6:
i_inc(readBX());
break;
case 0xee:
i_inc(readW_PC());
break;
case 0xfe:
i_inc(readWX());
break;
case 0xe8:
cpu.regX = (cpu.regX + 1 & maskX());
upNZ(cpu.regX);
break;
case 0xc8:
cpu.regY = (cpu.regY + 1 & maskX());
upNZ(cpu.regY);
break;
case 0x4c:
cpu.regPC = readW_PC();
break;
case 0x6c:
cpu.regPC = readWW();
break;
case 0x7c:
cpu.regPC = readWXW();
break;
case 0x20:
push2(cpu.regPC + 1);
cpu.regPC = readW_PC();
break;
case 0xfc:
push2(cpu.regPC + 1);
cpu.regPC = readWXW();
break;
case 0xa9:
cpu.regA = readM_PC();
upNZ_A();
break;
case 0xa5:
cpu.regA = readM(readB());
upNZ_A();
break;
case 0xb5:
cpu.regA = readM(readBX());
upNZ_A();
break;
case 0xad:
cpu.regA = readM(readW_PC());
upNZ_A();
break;
case 0xbd:
cpu.regA = readM(readWX());
upNZ_A();
break;
case 0xb9:
cpu.regA = readM(readWY());
upNZ_A();
break;
case 0xa1:
cpu.regA = readM(readBXW());
upNZ_A();
break;
case 0xb1:
cpu.regA = readM(readBWY());
upNZ_A();
break;
case 0xb2:
cpu.regA = readM(readBW());
upNZ_A();
break;
case 0xa3:
cpu.regA = readM(readBS());
upNZ_A();
break;
case 0xb3:
cpu.regA = readM(readBSWY());
upNZ_A();
break;
case 0xa7:
cpu.regA = readM(readBR());
upNZ_A();
break;
case 0xb7:
cpu.regA = readM(readBRWY());
upNZ_A();
break;
case 0xa2:
cpu.regX = readX_PC();
upNZ(cpu.regX);
break;
case 0xa6:
cpu.regX = readX(readB());
upNZ(cpu.regX);
break;
case 0xb6:
cpu.regX = readX(readBY());
upNZ(cpu.regX);
break;
case 0xae:
cpu.regX = readX(readW_PC());
upNZ(cpu.regX);
break;
case 0xbe:
cpu.regX = readX(readWY());
upNZ(cpu.regX);
break;
case 0xa0:
cpu.regY = readX_PC();
upNZ(cpu.regY);
break;
case 0xa4:
cpu.regY = readX(readB());
upNZ(cpu.regY);
break;
case 0xb4:
cpu.regY = readX(readBX());
upNZ(cpu.regY);
break;
case 0xac:
cpu.regY = readX(readW_PC());
upNZ(cpu.regY);
break;
case 0xbc:
cpu.regY = readX(readWX());
upNZ(cpu.regY);
break;
case 0x4a:
cpu.flagC = ((cpu.regA & 0x1) > 0);
cpu.regA = cpu.regA >> 1;
upNZ_A();
break;
case 0x46:
i_lsr(readB());
break;
case 0x56:
i_lsr(readBX());
break;
case 0x4e:
i_lsr(readW_PC());
break;
case 0x5e:
i_lsr(readWX());
break;
case 0xea:
break;
case 0x09:
i_or(readM_PC());
break;
case 0x05:
i_or(readM(readB()));
break;
case 0x15:
i_or(readM(readBX()));
break;
case 0x0d:
i_or(readM(readW_PC()));
break;
case 0x1d:
i_or(readM(readWX()));
break;
case 0x19:
i_or(readM(readWY()));
break;
case 0x01:
i_or(readM(readBXW()));
break;
case 0x11:
i_or(readM(readBWY()));
break;
case 0x12:
i_or(readM(readBW()));
break;
case 0x03:
i_or(readM(readBS()));
break;
case 0x13:
i_or(readM(readBSWY()));
break;
case 0x07:
i_or(readM(readBR()));
break;
case 0x17:
i_or(readM(readBRWY()));
break;
case 0x48:
pushM(cpu.regA);
break;
case 0x08:
push1(getFlags());
break;
case 0xda:
pushX(cpu.regX);
break;
case 0x5a:
pushX(cpu.regY);
break;
case 0x68:
cpu.regA = popM();
upNZ_A();
break;
case 0x28:
setFlags(pop1());
break;
case 0xfa:
cpu.regX = popX();
upNZX(cpu.regX);
break;
case 0x7a:
cpu.regY = popX();
upNZX(cpu.regY);
break;
case 0x2a:
n = (cpu.regA << 1 | (cpu.flagC ? 1 : 0)) & maskM();
cpu.flagC = ((cpu.regA & negM()) > 0);
cpu.regA = n;
upNZ_A();
break;
case 0x26:
i_rol(readB());
break;
case 0x36:
i_rol(readBX());
break;
case 0x2e:
i_rol(readW_PC());
break;
case 0x3e:
i_rol(readWX());
break;
case 0x6a:
n = cpu.regA >> 1 | (cpu.flagC ? negM() : 0);
cpu.flagC = ((cpu.regA & 0x1) > 0);
cpu.regA = n;
upNZ_A();
break;
case 0x66:
i_ror(readB());
break;
case 0x76:
i_ror(readBX());
break;
case 0x6e:
i_ror(readW_PC());
break;
case 0x7e:
i_ror(readWX());
break;
case 0x40:
setFlags(pop1());
cpu.regPC = pop2();
break;
case 0x60:
cpu.regPC = (pop2() + 1);
break;
case 0xe9:
i_sbc(readM_PC());
break;
case 0xe5:
i_sbc(readM(readB()));
break;
case 0xf5:
i_sbc(readM(readBX()));
break;
case 0xed:
i_sbc(readM(readW_PC()));
break;
case 0xfd:
i_sbc(readM(readWX()));
break;
case 0xf9:
i_sbc(readM(readWY()));
break;
case 0xe1:
i_sbc(readM(readBXW()));
break;
case 0xf1:
i_sbc(readM(readBWY()));
break;
case 0xf2:
i_sbc(readM(readBW()));
break;
case 0xe3:
i_sbc(readM(readBS()));
break;
case 0xf3:
i_sbc(readM(readBSWY()));
break;
case 0xe7:
i_sbc(readM(readBR()));
break;
case 0xf7:
i_sbc(readM(readBRWY()));
break;
case 0x38:
cpu.flagC = 1;
break;
case 0xf8:
cpu.flagD = 1;
break;
case 0x78:
cpu.flagID = 1;
break;
case 0x85:
writeM(readB(), cpu.regA);
break;
case 0x95:
writeM(readBX(), cpu.regA);
break;
case 0x8d:
writeM(readW_PC(), cpu.regA);
break;
case 0x9d:
writeM(readWX(), cpu.regA);
break;
case 0x99:
writeM(readWY(), cpu.regA);
break;
case 0x81:
writeM(readBXW(), cpu.regA);
break;
case 0x91:
writeM(readBWY(), cpu.regA);
break;
case 0x92:
writeM(readBW(), cpu.regA);
break;
case 0x83:
writeM(readBS(), cpu.regA);
break;
case 0x93:
writeM(readBSWY(), cpu.regA);
break;
case 0x87:
writeM(readBR(), cpu.regA);
break;
case 0x97:
writeM(readBRWY(), cpu.regA);
break;
case 0x86:
writeX(readB(), cpu.regX);
break;
case 0x96:
writeX(readBY(), cpu.regX);
break;
case 0x8e:
writeX(readW_PC(), cpu.regX);
break;
case 0x84:
writeX(readB(), cpu.regY);
break;
case 0x94:
writeX(readBX(), cpu.regY);
break;
case 0x8c:
writeX(readW_PC(), cpu.regY);
break;
case 0xaa:
cpu.regX = cpu.regA;
if (cpu.flagX)
cpu.regX &= 0xff;
upNZX(cpu.regX);
break;
case 0xa8:
cpu.regY = cpu.regA;
if (cpu.flagX)
cpu.regY &= 0xff;
upNZX(cpu.regY);
break;
case 0xba:
cpu.regX = cpu.regSP;
if (cpu.flagX)
cpu.regX &= 0xff;
upNZX(cpu.regX);
break;
case 0x8a:
cpu.regA = cpu.regX;
if (cpu.flagM)
cpu.regA &= 0xff;
upNZ_A();
break;
case 0x9a:
if (cpu.flagX)
cpu.regSP = (cpu.regSP & 0xff00 | cpu.regX & 0xff);
else
cpu.regSP = cpu.regX;
upNZX(cpu.regX);
break;
case 0x98:
cpu.regA = cpu.regY;
if (cpu.flagM)
cpu.regA &= 0xff;
upNZX(cpu.regY);
break;
case 0x64:
writeM(readB(), 0);
break;
case 0x74:
writeM(readBX(), 0);
break;
case 0x9c:
writeM(readW_PC(), 0);
break;
case 0x9e:
writeM(readWX(), 0);
break;
case 0x14:
i_trb(readM(readB()));
break;
case 0x1c:
i_trb(readM(readW_PC()));
break;
case 0x04:
i_tsb(readM(readB()));
break;
case 0x0c:
i_tsb(readM(readW_PC()));
break;
case 0xdb:
cpu.regPC--;
break;
case 0xcb:
cpu.waiTimeout = 1;
break;
case 0x9b:
cpu.regY = cpu.regX;
upNZX(cpu.regY);
break;
case 0xbb:
cpu.regX = cpu.regY;
upNZX(cpu.regX);
break;
case 0xf4:
push2(readW_PC());
break;
case 0xd4:
push2(readBW());
break;
case 0x62:
n = readB();
push2(cpu.regPC + n);
break;
case 0xeb:
if (cpu.flagM)
{
n = cpu.regA;
cpu.regA = cpu.regB;
cpu.regB = n;
}
else
{
cpu.regA = (cpu.regA >> 8 & 0xff | cpu.regA << 8 & 0xff00);
}
break;
case 0xfb:
if (cpu.flagE == cpu.flagC)
break;
if (cpu.flagE)
{
cpu.flagE = 0;
cpu.flagC = 1;
}
else
{
cpu.flagE = 1;
cpu.flagC = 0;
if (!cpu.flagM)
cpu.regB = (cpu.regA >> 8);
cpu.flagM = 1;
cpu.flagX = 1;
cpu.regA &= 0xff;
cpu.regX &= 0xff;
cpu.regY &= 0xff;
}
break;
case 0xc2:
setFlags(getFlags() & (readB() ^ 0xffffffff));
break;
case 0xe2:
setFlags(getFlags() | readB());
break;
case 0x8b:
if (cpu.flagX)
cpu.regSP = (cpu.regR & 0xff00 | cpu.regX & 0xff);
else
cpu.regR = cpu.regX;
upNZX(cpu.regR);
break;
case 0xab:
cpu.regX = cpu.regR;
if (cpu.flagX)
cpu.regX &= 0xff;
upNZX(cpu.regX);
break;
case 0x44:
push2r(readW_PC());
break;
case 0x54:
push2r(readBW());
break;
case 0x82:
n = readB();
push2r(cpu.regPC + n);
break;
case 0x3b:
cpu.regX = popXr();
upNZX(cpu.regX);
break;
case 0x6b:
cpu.regA = popMr();
upNZ(cpu.regA);
break;
case 0x7b:
cpu.regY = popXr();
upNZX(cpu.regY);
break;
case 0x1b:
pushXr(cpu.regX);
break;
case 0x4b:
pushMr(cpu.regA);
break;
case 0x5b:
pushXr(cpu.regY);
break;
case 0x0b:
push2r(cpu.regI);
break;
case 0x2b:
cpu.regI = pop2r();
upNZX(cpu.regI);
break;
case 0x5c:
cpu.regI = cpu.regX;
upNZX(cpu.regX);
break;
case 0xdc:
cpu.regX = cpu.regI;
if (cpu.flagX)
cpu.regX &= 0xff;
upNZX(cpu.regX);
break;
case 0x02:
cpu.regPC = readW(cpu.regI);
cpu.regI += 2;
break;
case 0x42:
if (cpu.flagM)
{
cpu.regA = readMem(cpu.regI);
cpu.regI += 1;
}
else
{
cpu.regA = readW(cpu.regI);
cpu.regI += 2;
}
break;
case 0x22:
push2r(cpu.regI);
cpu.regI = (cpu.regPC + 2);
cpu.regPC = readW(cpu.regPC);
break;
case 0x0f:
i_mul(readM(readB()));
break;
case 0x1f:
i_mul(readM(readBX()));
break;
case 0x2f:
i_mul(readM(readW_PC()));
break;
case 0x3f:
i_mul(readM(readWX()));
break;
case 0x4f:
i_div(readM(readB()));
break;
case 0x5f:
i_div(readM(readBX()));
break;
case 0x6f:
i_div(readM(readW_PC()));
break;
case 0x7f:
i_div(readM(readWX()));
break;
case 0x8f:
cpu.regD = 0;
cpu.regB = 0;
break;
case 0x9f:
cpu.regD = ((cpu.regA & negM()) > 0 ? 0xffff : 0);
cpu.regB = (cpu.regD & 0xff);
break;
case 0xaf:
cpu.regA = cpu.regD;
if (cpu.flagM)
cpu.regA &= 0xff;
upNZ(cpu.regA);
break;
case 0xbf:
if (cpu.flagM)
cpu.regD = (cpu.regA | cpu.regB << 8);
else
{
cpu.regD = cpu.regA;
}
upNZ(cpu.regA);
break;
case 0xcf:
cpu.regD = popM();
break;
case 0xdf:
pushM(cpu.regD);
break;
case 0xef:
i_mmu(readB());
break;
}
}
void emulateframe()
{
int i = 0;
cpu.rbTimeout = 0;
cpu.waiTimeout = 0;
cpu.brk = 0;
cpu.cycles += cpu.cycles_per_tick;
cpu.ticks ++;
if (cpu.cycles > 100000)
cpu.cycles = 100000;
while ((cpu.cycles > 0) && (!cpu.waiTimeout) && (!cpu.rbTimeout) && (!cpu.brk))
{
cpu.cycles --;
executeInsn();
i = 0;
while ( (i <= cpu.breakpoint_count) && ((cpu.breakpoints[i] & 0x1ffff) != (cpu.regPC | 0x10000)) )
i++;
if (i <= cpu.breakpoint_count) // breakpoint hit
{
cpu.cycles = 0;
cpu.brk = 1;
}
}
}