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
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;
|
|
}
|
|
}
|
|
}
|