#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include "Cpu.h"
#include "Tedmem.h"
#ifdef CPU_STATS
#include "Cpu7501asm.h"
#endif
#define push(VALUE) (stack[SP--]=(VALUE))
#define pull() (stack[SP])
bool CPU::bp_active = false;
bool CPU::bp_reached = false;
const unsigned int CPU::nr_of_bps = 11;
static unsigned int stats[255];
CPU::CPU( MemoryHandler *memhandler, unsigned char *irqreg, unsigned char *cpustack ) : mem(memhandler), irq_register(irqreg), stack(cpustack)
{
irq_sequence = 0;
IRQcount = 0;
cpu_jammed = false;
PC = 0xFFFF;
for( int i=0; i<nr_of_bps; i++) {
bp[i].address = 0x10000;
bp[i].enabled = false;
bp[i].slot_free = true;
}
nr_activebps = 0;
memset( stats, 0, sizeof(stats));
}
unsigned int CPU::getcins()
{
return (currins==0) ? mem->Read((PC-1)&0xFFFF) : currins&0xFF;
};
bool CPU::saveshot(void *CPUdump)
{
FILE *img = (FILE *) CPUdump;
fwrite(&currins,sizeof(currins),1,img);
fwrite(&nextins,sizeof(nextins),1,img);
fwrite(&ptr,sizeof(ptr),1,img);
fwrite(&PC,sizeof(PC),1,img);
fwrite(&cycle,sizeof(cycle),1,img);
fwrite(&SP,sizeof(SP),1,img);
fwrite(&ST,sizeof(ST),1,img);
fwrite(&AC,sizeof(AC),1,img);
fwrite(&X,sizeof(X),1,img);
fwrite(&Y,sizeof(Y),1,img);
return true;
}
bool CPU::loadshot(void *CPUdump)
{
FILE *img = (FILE *) CPUdump;
fread(&currins,sizeof(currins),1,img);
fread(&nextins,sizeof(nextins),1,img);
fread(&ptr,sizeof(ptr),1,img);
fread(&PC,sizeof(PC),1,img);
PC &= 0xFFFF;
fread(&cycle,sizeof(cycle),1,img);
fread(&SP,sizeof(SP),1,img);
fread(&ST,sizeof(ST),1,img);
fread(&AC,sizeof(AC),1,img);
fread(&X,sizeof(X),1,img);
fread(&Y,sizeof(Y),1,img);
return true;
}
void CPU::Reset()
{
ST=0x24;
softreset();
IRQcount = cycle = 0;
irq_sequence = 0;
}
void CPU::softreset()
{
ST&=0xEF;
setPC(mem->Read(0xFFFC)|(mem->Read(0xFFFD)<<8));
}
void CPU::setPC(unsigned int addr)
{
PC=addr;
cycle=0;
}
inline void CPU::DoCompare(unsigned char reg, unsigned char value)
{
ST = (ST & 0xFE) | ( value<=reg);
SETFLAGS_ZN( reg - value);
}
void CPU::process()
{
if (IRQcount || ((*irq_register)&0x80 ) && !irq_sequence && !(ST&0x04))
IRQcount++;
if (!cycle) { if (IRQcount>=3 && currins != 0x58) {
IRQcount = 0;
if (!(ST&0x04) || currins == 0x78) { irq_sequence = 0x10; currins = 0x00; cycle = 1;
return;
}
}
currins=mem->Read(PC); nextins=mem->Read(PC+1); cycle = 1; #ifdef CPU_STATS
stats[currins]++;
static FILE *f = fopen("disasm.txt", "a");
if (f)
fprintf(f, ". %04X %s", PC, ins[currins].name);
int i = 1;
while (i < typlen[ins[currins].type] && f) {
fprintf(f, " %02X", mem->Read(PC+i++));
}
fprintf(f, "\n");
fflush(f);
#endif
PC=(PC+1)&0xFFFF;
}
else
switch (currins){
case 0xea : cycle=0;
break;
case 0x18 : ST&=0xFE;
cycle=0;
break;
case 0x38 : ST|=0x01;
cycle=0;
break;
case 0x58 : ST&=0xFB;
cycle=0;
break;
case 0x78 : ST|=0x04;
cycle=0;
break;
case 0xb8 : ClearVFlag();
cycle=0;
break;
case 0xD8 : ST&=0xF7;
cycle=0;
break;
case 0xF8 : ST|=0x08;
cycle=0;
break;
case 0x10 : switch(cycle++) {
case 1: PC++;
if ((ST&0x80))
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0x30 : switch(cycle++) {
case 1: PC++;
if (!(ST&0x80))
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0x50 : switch(cycle++) {
case 1: PC++;
if (CheckVFlag())
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0x70 : switch(cycle++) {
case 1: PC++;
if (!(CheckVFlag()))
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0x90 : switch(cycle++) {
case 1: PC++;
if (ST&0x01)
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0xB0 : switch(cycle++) {
case 1: PC++;
if (!(ST&0x01))
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0xD0 : switch(cycle++) {
case 1: PC++;
if (ST&0x02)
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0xF0 : switch(cycle++) {
case 1: PC++;
if (!(ST&0x02))
cycle=0;
break;
case 2: if (!(((PC&0xFF)+(signed char) nextins)&0xFF00)) {
PC+=(signed char) nextins;
cycle=0;
};
break;
case 3: PC+=(signed char) nextins;
cycle=0;
break;
};
break;
case 0x88 : --Y;
SETFLAGS_ZN(Y);
cycle=0;
break;
case 0xC8 : ++Y;
SETFLAGS_ZN(Y);
cycle=0;
break;
case 0xCA : --X;
SETFLAGS_ZN(X);
cycle=0;
break;
case 0xE8 : ++X;
SETFLAGS_ZN(X);
cycle=0;
break;
case 0x00 : switch (cycle++) {
case 1: if (!irq_sequence)
PC++;
break;
case 2: push(PC>>8);
break;
case 3: push(PC&0xFF);
break;
case 4: push((ST|0x30)&~irq_sequence);
ST|=0x04;
break;
case 5: break;
case 6: PC=mem->Read(0xFFFE)|(mem->Read(0xFFFF)<<8);
irq_sequence = 0x0;
cycle=0;
break;
};
break;
case 0x40 : switch (cycle++) {
case 1: break;
case 2: SP++;
break;
case 3: ST=pull(); SP++;
break;
case 4: PC=pull();
SP++;
break;
case 5: PC|=pull()<<8;
cycle=0;
break;
};
break;
case 0x60 : switch (cycle++) {
case 1: break;
case 2: SP++;
break;
case 3: PC=pull();
SP++;
break;
case 4: PC|=pull()<<8;
break;
case 5: PC++;
cycle=0;
break;
};
break;
case 0x08 : if (cycle++==2) {
push(ST|0x30);
cycle=0;
};
break;
case 0x28 : if (cycle++==3) {
SP++;
ST=(pull() ); cycle=0;
};
break;
case 0x48 : if (cycle++==2) {
push(AC);
cycle=0;
};
break;
case 0x68 : if (cycle++==3) {
SP++;
AC=pull();
SETFLAGS_ZN(AC);
cycle=0;
};
break;
case 0x8A : AC=X;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0xAA : X=AC;
SETFLAGS_ZN(X);
cycle=0;
break;
case 0x98 : AC=Y;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0xA8 : Y=AC;
SETFLAGS_ZN(Y);
cycle=0;
break;
case 0x9A : SP=X;
cycle=0;
break;
case 0xBA : X=SP;
SETFLAGS_ZN(X);
cycle=0;
break;
case 0x20 : switch (cycle++) {
case 1: PC++;
break;
case 2: break;
case 3: push(PC>>8);
break;
case 4: push(PC&0xFF);
break;
case 5: PC=ptr=nextins|(mem->Read(PC)<<8);
cycle=0;
break;
};
break;
case 0x4C : if (cycle++==2) {
PC=nextins|(mem->Read(PC+1)<<8);
cycle=0;
};
break;
case 0x6C : if (cycle++==4) {
ptr=nextins|(mem->Read(PC+1)<<8);
PC=mem->Read(ptr)|(mem->Read( ptr&0xFF00 | (ptr+1)&0xFF) << 8);
cycle=0;
};
break;
case 0x09 : PC++;
AC|=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x29 : PC++;
AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x49 : PC++;
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x69 : PC++;
ADC(nextins);
cycle=0;
break;
case 0xC9 : PC++;
DoCompare(AC,nextins);
cycle=0;
break;
case 0xE9 : PC++;
SBC(nextins);
cycle=0;
break;
case 0x0A : AC&0x80 ? ST|=0x01 : ST&=0xFE; AC<<=1;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x2A : nextins=(AC<<1)|(ST&0x01);
AC&0x80 ? ST|=0x01 : ST&=0xFE; AC=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x4A : AC&0x01 ? ST|=0x01 : ST&=0xFE; AC=AC>>1;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x6A : nextins=(AC>>1)|((ST&0x01)<<7);
AC&0x01 ? ST|=0x01 : ST&=0xFE; AC=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0xA0 : PC++;
Y=nextins;
SETFLAGS_ZN(Y);
cycle=0;
break;
case 0xA2 : PC++;
X=nextins;
SETFLAGS_ZN(X);
cycle=0;
break;
case 0xA9 : PC++;
AC=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0xC0 : PC++;
DoCompare(Y,nextins);
cycle=0;
break;
case 0xE0 : PC++;
DoCompare(X,nextins);
cycle=0;
break;
case 0x24 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins=mem->Read(nextins);
ST = (ST&0x3D)
| (nextins&0xC0)
| (((AC&nextins)==0)<<1);
cycle=0;
break;
};
break;
case 0x2C : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
ST = (ST&0x3D)
| (nextins&0xC0)
| (((AC&nextins)==0)<<1);
cycle=0;
break;
};
break;
case 0x0D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: AC|=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x2D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: AC&=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
};
break;
case 0x4D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: AC^=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x6D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ADC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0x99 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: break;
case 4: mem->Write(ptr+Y,AC);
cycle=0;
break;
};
break;
case 0xAC : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: Y=mem->Read(ptr);
SETFLAGS_ZN(Y);
cycle=0;
break;
};
break;
case 0xCC : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: DoCompare(Y,mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xEC : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: DoCompare(X,mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xAD : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: AC=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xCD : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: DoCompare(AC,mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xED : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: SBC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0x0E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
(nextins&0x80) ? ST|=0x01 : ST&=0xFE; nextins<<=1;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x1E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ptr+=X;
break;
case 4: nextins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,nextins);
(nextins&0x80) ? ST|=0x01 : ST&=0xFE; nextins<<=1;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x2E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: farins=mem->Read(ptr);
nextins=(farins<<1)|(ST&0x01);
break;
case 4: mem->Write(ptr,farins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x3E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ptr+=X;
break;
case 4: farins=mem->Read(ptr);
nextins=(farins<<1)|(ST&0x01);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,farins);
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x4E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
(nextins&0x01) ? ST|=0x01 : ST&=0xFE;; break;
case 4: mem->Write(ptr,nextins);
nextins=nextins>>1;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x5E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ptr+=X;
break;
case 4: nextins=mem->Read(ptr);
(nextins&0x01) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,nextins);
nextins>>=1;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x6E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: farins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,farins);
nextins=(farins>>1)|((ST&0x01)<<7);
(farins&0x01) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x7E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ptr+=X;
break;
case 4: farins=mem->Read(ptr);
nextins=(farins>>1)|((ST&0x01)<<7);
(farins&0x01) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,farins);
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xAE : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: X=mem->Read(ptr);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xCE : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
--nextins;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xDE : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ptr+=X;
break;
case 4: nextins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,nextins);
--nextins;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xEE : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
++nextins;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xFE : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: ptr+=X;
break;
case 4: nextins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,nextins);
++nextins;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x94 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: mem->Write(nextins,Y);
cycle=0;
break;
};
break;
case 0x95 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: mem->Write(nextins,AC);
cycle=0;
break;
};
break;
case 0x96 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=Y;
break;
case 3: mem->Write(nextins,X);
cycle=0;
break;
};
break;
case 0xB4 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: Y=mem->Read(nextins);
SETFLAGS_ZN(Y);
cycle=0;
break;
};
break;
case 0xB5 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: AC=mem->Read(nextins);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xB6 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=Y;
break;
case 3: X=mem->Read(nextins);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xD5 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: DoCompare(AC,mem->Read(nextins));
cycle=0;
break;
};
break;
case 0x15 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: AC|=(mem->Read(nextins));
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x35 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: AC&=(mem->Read(nextins));
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x16 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: farins=mem->Read(nextins);
break;
case 4: mem->Write(nextins,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x36 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
ptr=nextins;
break;
case 3: farins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,farins);
nextins=(farins<<1)|((ST&0x01));
farins&0x80 ? ST|=0x01 : ST&=0xFE;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x19 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
AC|=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
}
break;
case 4: AC|=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x39 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
AC&=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
}
break;
case 4: AC&=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x59 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
AC^=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
}
break;
case 4: AC^=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x79 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
ADC(mem->Read(ptr));
cycle=0;
}
break;
case 4: ADC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xB9 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
AC=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
}
break;
case 4: AC=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x1D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
AC|=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
};
break;
case 4: AC|=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x3D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
AC&=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
};
break;
case 4: AC&=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x5D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
AC^=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
};
break;
case 4: AC^=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x7D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
ADC(mem->Read(ptr));
cycle=0;
};
break;
case 4: ADC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xBC : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
Y=mem->Read(ptr);
SETFLAGS_ZN(Y);
cycle=0;
};
break;
case 4: Y=mem->Read(ptr);
SETFLAGS_ZN(Y);
cycle=0;
break;
};
break;
case 0xBD : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
AC=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
};
break;
case 4: AC=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xBE : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
X=mem->Read(ptr);
SETFLAGS_ZN(X);
cycle=0;
};
break;
case 4: X=mem->Read(ptr);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xD9 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: if (nextins+Y<0x100){
DoCompare(AC,mem->Read(ptr+Y));
cycle=0;
};
break;
case 4: DoCompare(AC,mem->Read(ptr+Y));
cycle=0;
break;
};
break;
case 0xF9 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100){
SBC(mem->Read(ptr));
cycle=0;
};
break;
case 4: SBC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xDD : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: if (nextins+X<0x100) {
DoCompare(AC,mem->Read(ptr+X));
cycle=0;
};
break;
case 4: DoCompare(AC,mem->Read(ptr+X));
cycle=0;
break;
};
break;
case 0xFD : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: if (nextins+X<0x100) {
SBC(mem->Read(ptr));
cycle=0;
};
break;
case 4: SBC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xA4 : switch (cycle++) {
case 1: PC++;
break;
case 2: Y=mem->Read(nextins);
SETFLAGS_ZN(Y);
cycle=0;
break;
};
break;
case 0xC4 : switch (cycle++) {
case 1: PC++;
break;
case 2: DoCompare(Y,mem->Read(nextins));
cycle=0;
break;
};
break;
case 0x05 : switch (cycle++) {
case 1: PC++;
break;
case 2: AC|=mem->Read(nextins);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x55 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: AC^=mem->Read(nextins);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x65 : switch (cycle++) {
case 1: PC++;
break;
case 2: ADC(mem->Read(nextins));
cycle=0;
break;
};
break;
case 0x75 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ADC(mem->Read(nextins));
cycle=0;
break;
};
break;
case 0xA5 : switch (cycle++) {
case 1: PC++;
break;
case 2: AC=mem->Read(nextins);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xC5 : switch (cycle++) {
case 1: PC++;
break;
case 2: DoCompare(AC,mem->Read(nextins));
cycle=0;
break;
};
break;
case 0xE5 : switch (cycle++) {
case 1: PC++;
break;
case 2: SBC(mem->Read(nextins));
cycle=0;
break;
};
break;
case 0xF5 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: SBC(mem->Read(nextins));
cycle=0;
break;
};
break;
case 0x06 : switch (cycle++) {
case 1: PC++;
break;
case 2: farins=mem->Read(nextins);
farins&0x80 ? ST|=0x01 : ST&=0xFE;
break;
case 3: mem->Write(nextins,farins);
farins<<=1;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x26 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: farins=mem->Read(ptr);
nextins=(farins<<1)|(ST&0x01);
break;
case 3: mem->Write(ptr,farins);
farins&0x80 ? ST|=0x01 : ST&=0xFE; break;
case 4: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x25 : switch (cycle++) {
case 1: PC++;
break;
case 2: AC&=mem->Read(nextins);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x45 : switch (cycle++) {
case 1: PC++;
break;
case 2: AC^=mem->Read(nextins);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x46 : switch (cycle++) {
case 1: PC++;
break;
case 2: farins=mem->Read(nextins);
farins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 3: mem->Write(nextins,farins);
farins>>=1;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x56 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: farins=mem->Read(nextins);
farins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 4: mem->Write(nextins,farins);
farins>>=1;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x66 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=nextins;
farins=mem->Read(ptr);
nextins=(farins>>1)|((ST&0x01)<<7);
break;
case 3: mem->Write(ptr,farins);
farins&0x01 ? ST|=0x01 : ST&=0xFE; break;
case 4: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x76 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
ptr=nextins;
break;
case 3: farins=mem->Read(ptr);
nextins=(farins>>1)|((ST&0x01)<<7);
break;
case 4: mem->Write(ptr,farins);
farins&0x01 ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xA6 : switch (cycle++) {
case 1: PC++;
break;
case 2: X=mem->Read(nextins);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xC6 : switch (cycle++) {
case 1: PC++;
break;
case 2: farins=mem->Read(nextins);
break;
case 3: mem->Write(nextins,farins);
--farins;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xE4 : switch (cycle++) {
case 1: PC++;
break;
case 2: DoCompare(X,mem->Read(nextins));
cycle=0;
break;
};
break;
case 0xE6 : switch (cycle++) {
case 1: PC++;
break;
case 2: farins=mem->Read(nextins);
break;
case 3: mem->Write(nextins,farins);
++farins;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xD6 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: farins=mem->Read(nextins);
break;
case 4: mem->Write(nextins,farins);
--farins;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xF6 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: farins=mem->Read(nextins);
break;
case 4: mem->Write(nextins,farins);
++farins;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x01 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: AC|=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x21 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: AC&=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x41 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: AC^=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x61 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: ADC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0x81 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: mem->Write(ptr,AC);
cycle=0;
break;
};
break;
case 0xA1 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: AC=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xC1 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: DoCompare(AC,mem->Read(ptr));
cycle=0;
break;
};
break;
case 0xE1 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins++);
break;
case 4: ptr|=(mem->Read(nextins)<<8);
break;
case 5: SBC(mem->Read(ptr));
cycle=0;
break;
};
break;
case 0x11 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
AC|=mem->Read(ptr+Y);
cycle=0;
SETFLAGS_ZN(AC);
}
break;
case 5: AC|=mem->Read(ptr+Y);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x31 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
AC&=mem->Read(ptr+Y);
cycle=0;
SETFLAGS_ZN(AC);
}
break;
case 5: AC&=mem->Read(ptr+Y);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x51 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
AC^=mem->Read(ptr+Y);
cycle=0;
SETFLAGS_ZN(AC);
}
break;
case 5: AC^=mem->Read(ptr+Y);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x71 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
ADC(mem->Read(ptr+Y));
cycle=0;
};
break;
case 5: ADC(mem->Read(ptr+Y));
cycle=0;
break;
};
break;
case 0x91 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: mem->Write(ptr+Y,AC);
cycle=0;
break;
};
break;
case 0xB1 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
AC=mem->Read(ptr+Y);
SETFLAGS_ZN(AC);
cycle=0;
}
break;
case 5: AC=mem->Read(ptr+Y);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xD1 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
DoCompare(AC,mem->Read(ptr+Y));
cycle=0;
}
break;
case 5: DoCompare(AC,mem->Read(ptr+Y));
cycle=0;
break;
};
break;
case 0xF1 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
SBC(mem->Read(ptr+Y));
cycle=0;
};
break;
case 5: SBC(mem->Read(ptr+Y));
cycle=0;
break;
};
break;
case 0x84 : switch (cycle++) {
case 1: PC++;
break;
case 2: mem->Write(nextins,Y);
cycle=0;
break;
};
break;
case 0x85 : switch (cycle++) {
case 1: PC++;
break;
case 2: mem->Write(nextins,AC);
cycle=0;
break;
};
break;
case 0x86 : switch (cycle++) {
case 1: PC++;
break;
case 2: mem->Write(nextins,X);
cycle=0;
break;
};
break;
case 0x8C : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: mem->Write(ptr,Y);
cycle=0;
break;
};
break;
case 0x8D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: mem->Write(ptr,AC);
cycle=0;
break;
};
break;
case 0x8E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: mem->Write(ptr,X);
cycle=0;
break;
};
break;
case 0x9D : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: break;
case 4: mem->Write(ptr+X,AC);
cycle=0;
break;
};
break;
case 0x03 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=(mem->Read(nextins+1)<<8);
break;
case 5: farins=mem->Read(ptr);
break;
case 6: mem->Write(ptr,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
break;
case 7: mem->Write(ptr,farins);
AC|=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x07 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: nextins=mem->Read(ptr);
break;
case 3: mem->Write(ptr,nextins);
(nextins)&0x80 ? ST|=0x01 : ST&=0xFE;
nextins<<=1;
break;
case 4: mem->Write(ptr,nextins);
AC|=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x0B : case 0x2B : PC++;
AC&=nextins;
(AC&0x80) ? ST|=0x01 : ST&=0xFE;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x0C : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: cycle=0;
break;
};
break;
case 0x0F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
(nextins)&0x80 ? ST|=0x01 : ST&=0xFE;
nextins<<=1;
break;
case 5: mem->Write(ptr,nextins);
AC|=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x13 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=(mem->Read(nextins+1)<<8);
break;
case 4: break;
case 5: farins=mem->Read(ptr+Y);
break;
case 6: mem->Write(ptr+Y,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
break;
case 7: mem->Write(ptr+Y,farins);
AC|=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x14 : switch (cycle++) {
case 1: PC++;
break;
case 2: break;
case 3: cycle=0;
break;
};
break;
case 0x17 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=(nextins+X)&0xFF;
break;
case 3: farins = mem->Read(ptr);
break;
case 4: mem->Write(ptr,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
break;
case 5: mem->Write(ptr,farins);
AC|=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x80 : case 0x82 : case 0x89 : case 0xC2 : case 0xE2 : PC++;
case 0x1A : case 0x3A : case 0x5A : case 0x7A : case 0xDA : case 0xFA : cycle=0;
break;
case 0x1B : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
break;
case 6: mem->Write(ptr,farins);
AC|=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x1C : case 0x3C : case 0x5C : case 0x7C : case 0xDC : case 0xFC : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: if (nextins+X<0x100)
cycle=0;
break;
case 4: cycle=0;
break;
};
break;
case 0x1F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
ptr+=X;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
break;
case 6: mem->Write(ptr,farins);
AC|=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x23 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=(mem->Read(nextins+1)<<8);
farins=mem->Read(ptr);
break;
case 5: nextins=(farins<<1)|(ST&0x01);
mem->Write(ptr,nextins);
break;
case 6: (farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 7: AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x27 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: farins=mem->Read(ptr);
break;
case 3: mem->Write(ptr,farins);
nextins=(farins<<1)|(ST&0x01);
break;
case 4: mem->Write(ptr,nextins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x2F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: farins=mem->Read(ptr);
break;
case 4: mem->Write(ptr, farins);
nextins=(farins<<1)|(ST&0x01);
break;
case 5: mem->Write(ptr,nextins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x33 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: farins=mem->Read(ptr+Y);
nextins=(farins<<1)|(ST&0x01);
break;
case 6: mem->Write(ptr+Y,farins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 7: mem->Write(ptr+Y,nextins);
AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x34 : switch (cycle++) {
case 1: PC++;
break;
case 2: break;
case 3: cycle=0;
break;
};
break;
case 0x37 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
ptr=nextins;
break;
case 3: farins=mem->Read(ptr);
nextins=(farins<<1)|(ST&0x01);
break;
case 4: mem->Write(ptr,farins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,nextins);
AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x3B : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr+Y);
break;
case 5: mem->Write(ptr+Y,farins);
nextins=(farins<<1)|(ST&0x01);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 6: mem->Write(ptr+Y,nextins);
AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x3F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
nextins=(farins<<1)|(ST&0x01);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,farins);
break;
case 6: mem->Write(ptr,nextins);
AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x43 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=(mem->Read(nextins+1)<<8);
break;
case 5: nextins=mem->Read(ptr)>>1;
break;
case 6: mem->Write(ptr,nextins);
break;
case 7: AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x47 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: nextins=mem->Read(ptr);
break;
case 3: mem->Write(ptr,nextins);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
nextins>>=1;
break;
case 4: mem->Write(ptr,nextins);
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x4B : PC++;
AC=(AC&nextins);
(AC&0x01) ? ST|=0x01 : ST&=0xFE;
AC>>=1;
SETFLAGS_ZN(AC);
cycle=0;
break;
case 0x4F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
nextins>>=1;
break;
case 5: mem->Write(ptr,nextins);
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x53 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: nextins=mem->Read(ptr+Y);
break;
case 6: mem->Write(ptr+Y,nextins);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
nextins>>=1;
break;
case 7: mem->Write(ptr+Y,nextins);
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x54 : switch (cycle++) {
case 1: break;
case 2: PC++;
break;
case 3: cycle=0;
break;
};
break;
case 0x57 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=nextins;
nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
nextins>>=1;
break;
case 5: mem->Write(ptr,nextins);
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x5B : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
farins&0x01 ? ST|=0x01 : ST&=0xFE;
farins>>=1;
break;
case 6: mem->Write(ptr,farins);
AC^=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
}
break;
case 0x5F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
ptr+=X;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
farins&0x01 ? ST|=0x01 : ST&=0xFE;
farins>>=1;
break;
case 6: mem->Write(ptr,farins);
AC^=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x63 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=(mem->Read(nextins+1)<<8);
break;
case 5: nextins=mem->Read(ptr);
farins=(nextins>>1)|((ST&0x01)<<7);
break;
case 6: nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 7: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x04 : case 0x44 : case 0x64 : if (cycle++==2) {
PC++;
cycle=0;
};
break;
case 0x67 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: nextins=mem->Read(ptr);
break;
case 3: mem->Write(ptr,nextins);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 4: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x6B : switch (cycle++) {
case 1: PC++;
AC&=nextins;
break;
case 2: AC=(AC>>1)&((ST&0x01)<<7);
SETFLAGS_ZN(AC);
(AC&0x40) ? ST|=0x01 : ST&=0xFE;
(AC&0x40)^((AC&0x20)<<1) ? SetVFlag() : ClearVFlag();
cycle=0;
break;
};
break;
case 0x6F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 5: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x73 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: nextins=mem->Read(ptr+Y);
break;
case 6: mem->Write(ptr+Y,nextins);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 7: mem->Write(ptr+Y,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x74 : switch (cycle++) {
case 1: PC++;
break;
case 2: break;
case 3: cycle=0;
break;
};
break;
case 0x77 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
ptr=nextins;
break;
case 3: nextins=mem->Read(ptr);
farins=(nextins>>1)|((ST&0x01)<<7);
break;
case 4: nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 5: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x7B : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: break;
case 4: nextins=mem->Read(ptr);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 5: mem->Write(ptr,nextins);
break;
case 6: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
}
break;
case 0x7F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: break;
case 4: nextins=mem->Read(ptr);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
break;
case 5: mem->Write(ptr, nextins);
break;
case 6: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
}
break;
case 0x83 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=(mem->Read(nextins+1)<<8);
break;
case 5: mem->Write(ptr,AC&X);
cycle=0;
break;
};
break;
case 0x87 : switch (cycle++) {
case 1: PC++;
break;
case 2: mem->Write(nextins,AC&X);
cycle=0;
break;
};
break;
case 0x8B : switch (cycle++) {
case 1: PC++;
AC=X&nextins&(AC|0xEE);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x8F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: mem->Write(ptr,AC&X);
cycle=0;
break;
};
break;
case 0x93 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: mem->Write(ptr+Y,AC&X&(nextins+1)); cycle=0;
break;
};
break;
case 0x97 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=Y;
break;
case 3: mem->Write(nextins,AC&X);
cycle=0;
break;
};
break;
case 0x9B : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
ptr+=Y;
break;
case 3: SP=AC&X;
break;
case 4: mem->Write(ptr+Y,SP&(nextins+1));
cycle=0;
break;
};
break;
case 0x9C : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: break;
case 4: if (nextins+X<256) {
mem->Write(ptr+X,Y&(nextins+1));
}
cycle=0;
break;
};
break;
case 0x9E : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: break;
case 4: if (nextins+Y<256) {
mem->Write(ptr+Y,X&(nextins+1));
}
cycle=0;
break;
};
break;
case 0x9F : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: break;
case 4: mem->Write(ptr+Y,AC&X&(nextins+1));
cycle=0;
break;
};
break;
case 0xA3 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=mem->Read(nextins+1)<<8;
break;
case 5: X=AC=mem->Read(ptr);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xA7 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=nextins;
break;
case 3: X=AC=mem->Read(ptr);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xAB : switch (cycle++) {
case 1: PC++;
X=AC=(nextins&(AC|0xEE));
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xAF : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: X=AC=mem->Read(ptr);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xB3 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: if ((ptr&0x00FF)+Y<0x100) {
X=AC=mem->Read(ptr+Y);
SETFLAGS_ZN(X);
cycle=0;
}
break;
case 5: X=AC=mem->Read(ptr+Y);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xB7 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: X=AC=mem->Read(nextins);
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xBB : switch (cycle++) {
case 1: PC++;
break;
case 2: PC++;
ptr+=Y;
break;
case 3: if (nextins+Y<0x100) {
SP&=mem->Read(ptr);
AC=X=SP;
SETFLAGS_ZN(X);
cycle=0;
}
break;
case 4: SP&=mem->Read(ptr);
AC=X=SP;
SETFLAGS_ZN(X);
cycle=0;
break;
};
break;
case 0xBF : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: if (nextins+Y<0x100) {
AC=X=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
}
break;
case 4: AC=X=mem->Read(ptr);
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0xC3 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=mem->Read(nextins+1)<<8;
break;
case 5: nextins=mem->Read(ptr)-1;
break;
case 6: break;
case 7: mem->Write(ptr,nextins);
(AC>=nextins) ? ST|=0x01: ST&=0xFE;
farins=AC-nextins;
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xC7 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: nextins=mem->Read(ptr);
break;
case 3: mem->Write(ptr,nextins);
nextins -= 1;
break;
case 4: mem->Write(ptr,nextins);
(AC>=nextins) ? ST|=0x01 : ST&=0xFE;
nextins=AC-nextins;
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xCB : PC++;
((X&AC) >= nextins) ? ST|=0x01 : ST&=0xFE;
X = (X&AC) - nextins;
SETFLAGS_ZN(X);
cycle=0;
break;
case 0xCF : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: farins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,farins);
farins -= 1;
break;
case 5: mem->Write(ptr,farins);
(AC>=farins) ? ST|=0x01 : ST&=0xFE;
farins=AC-farins;
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xD3 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: farins=mem->Read(ptr+Y);
break;
case 6: mem->Write(ptr+Y,farins);
farins -= 1;
break;
case 7: mem->Write(ptr+Y,farins);
DoCompare(AC,farins);
cycle=0;
break;
};
break;
case 0xD4 : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: break;
case 3: cycle=0;
break;
};
break;
case 0xD7 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
ptr=nextins;
break;
case 3: nextins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,nextins);
nextins-=1;
break;
case 5: mem->Write(ptr,nextins);
(AC>=nextins) ? ST|=0x01 : ST&=0xFE;
nextins=AC-nextins;
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xDB : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
farins -= 1;
break;
case 6: mem->Write(ptr,farins);
(AC>=farins) ? ST|=0x01 : ST&=0xFE;
farins=AC-farins;
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xDF : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=X;
PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
farins -= 1;
break;
case 6: mem->Write(ptr,farins);
(AC>=farins) ? ST|=0x01 : ST&=0xFE;
farins=AC-farins;
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xE3 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: ptr=mem->Read(nextins);
break;
case 4: ptr|=(mem->Read(nextins+1)<<8);
break;
case 5: nextins=mem->Read(ptr);
break;
case 6: mem->Write(ptr,nextins);
nextins += 1;
break;
case 7: mem->Write(ptr,nextins);
SBC(nextins);
cycle=0;
break;
};
break;
case 0xE7 : switch (cycle++) {
case 1: PC++;
ptr=nextins;
break;
case 2: nextins=mem->Read(ptr);
break;
case 3: mem->Write(ptr,nextins);
nextins += 1;
break;
case 4: mem->Write(ptr,nextins);
SBC(nextins);
cycle=0;
break;
};
break;
case 0xEB : PC++;
SBC(nextins);
cycle=0;
break;
case 0xEF : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
break;
case 3: farins=mem->Read(ptr);
break;
case 4: mem->Write(ptr,farins);
farins += 1;
break;
case 5: mem->Write(ptr,farins);
SBC(farins);
cycle=0;
break;
};
break;
case 0xF3 : switch (cycle++) {
case 1: PC++;
break;
case 2: ptr=mem->Read(nextins);
break;
case 3: ptr|=mem->Read(nextins+1)<<8;
break;
case 4: break;
case 5: farins=mem->Read(ptr+Y);
break;
case 6: mem->Write(ptr+Y,farins);
farins+=1;
break;
case 7: mem->Write(ptr+Y,farins);
SBC(farins);
cycle=0;
break;
};
break;
case 0xF4 : switch (cycle++) {
case 1: PC++;
break;
case 2: break;
case 3: cycle=0;
break;
};
break;
case 0xF7 : switch (cycle++) {
case 1: PC++;
break;
case 2: nextins+=X;
break;
case 3: farins=mem->Read(nextins);
break;
case 4: mem->Write(nextins,farins);
farins += 1;
break;
case 5: mem->Write(nextins,farins);
SBC(farins);
cycle=0;
break;
};
break;
case 0xFB : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: ptr+=Y;
PC++;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
farins += 1;
break;
case 6: mem->Write(ptr,farins);
SBC(farins);
cycle=0;
break;
};
break;
case 0xFF : switch (cycle++) {
case 1: PC++;
ptr=nextins|(mem->Read(PC)<<8);
break;
case 2: PC++;
ptr+=X;
break;
case 3: break;
case 4: farins=mem->Read(ptr);
break;
case 5: mem->Write(ptr,farins);
farins += 1;
break;
case 6: mem->Write(ptr,farins);
SBC(farins);
cycle=0;
break;
};
break;
case 0x02 : case 0x12 : case 0x22 : case 0x32 : case 0x42 : case 0x52 : case 0x62 : case 0x72 : case 0x92 : case 0xB2 : case 0xD2 : case 0xF2 : cycle = 0;
PC = (PC-1)&0xFFFF;
bp_reached = bp_active = cpu_jammed = true;
break;
default : cycle=1; };
};
void CPU::stopcycle()
{
switch (currins) {
case 0x00 : switch (cycle) {
case 2: push(PC>>8);
cycle++;
break;
case 3: push(PC&0xFF);
cycle++;
break;
case 4: push((ST|0x30)&~irq_sequence);
ST|=0x04;
cycle++;
break;
};
break;
case 0x08 : if (cycle==2) {
push(ST|0x30);
cycle=0;
};
break;
case 0x48 : if (cycle==2) {
push(AC);
cycle=0;
};
break;
case 0x20 : switch (cycle) {
case 3: push(PC>>8);
cycle++;
break;
case 4: push(PC&0xFF);
cycle++;
break;
};
break;
case 0x06 : switch (cycle) {
case 3: mem->Write(nextins,farins);
farins<<=1;
++cycle;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x07 : switch (cycle) {
case 3: mem->Write(ptr,nextins);
(nextins)&0x80 ? ST|=0x01 : ST&=0xFE;
nextins<<=1;
cycle++;
break;
case 4: mem->Write(ptr,nextins);
AC|=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x0E : switch (cycle) {
case 4: mem->Write(ptr,nextins);
(nextins&0x80) ? ST|=0x01 : ST&=0xFE; nextins<<=1;
++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x0F : switch (cycle) {
case 4: mem->Write(ptr,nextins);
(nextins)&0x80 ? ST|=0x01 : ST&=0xFE;
nextins<<=1;
cycle++;
break;
case 5: mem->Write(ptr,nextins);
AC|=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x16 : switch (cycle) {
case 4: mem->Write(nextins,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
++cycle;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x17 : switch (cycle) {
case 4: mem->Write(ptr,farins);
(farins)&0x80 ? ST|=0x01 : ST&=0xFE;
farins<<=1;
cycle++;
break;
case 5: mem->Write(ptr,farins);
AC|=farins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x1E : switch (cycle) {
case 5: mem->Write(ptr,nextins);
(nextins&0x80) ? ST|=0x01 : ST&=0xFE; nextins<<=1;
++cycle;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x26 : switch (cycle) {
case 3: mem->Write(ptr,farins);
farins&0x80 ? ST|=0x01 : ST&=0xFE; ++cycle;
break;
case 4: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x27 : switch (cycle) {
case 3: mem->Write(ptr,farins);
nextins=(farins<<1)|(ST&0x01);
cycle++;
break;
case 4: mem->Write(ptr,nextins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x2E : switch (cycle) {
case 4: mem->Write(ptr,farins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; ++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x2F : switch (cycle) {
case 4: mem->Write(ptr, farins);
nextins=(farins<<1)|(ST&0x01);
cycle++;
break;
case 5: mem->Write(ptr,nextins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x36 : switch (cycle) {
case 4: mem->Write(ptr,farins);
nextins=(farins<<1)|((ST&0x01));
farins&0x80 ? ST|=0x01 : ST&=0xFE;
++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x37 : switch (cycle) {
case 4: mem->Write(ptr,farins);
(farins&0x80) ? ST|=0x01 : ST&=0xFE; cycle++;
break;
case 5: mem->Write(ptr,nextins);
AC&=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x3E : switch (cycle) {
case 5: mem->Write(ptr,farins);
++cycle;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x46 : switch (cycle) {
case 3: mem->Write(nextins,farins);
farins>>=1;
++cycle;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x47 : switch (cycle) {
case 3: mem->Write(ptr,nextins);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
nextins>>=1;
cycle++;
break;
case 4: mem->Write(ptr,nextins);
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x4E : switch (cycle) {
case 4: mem->Write(ptr,nextins);
nextins=nextins>>1;
++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x4F : switch (cycle) {
case 4: mem->Write(ptr,nextins);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
nextins>>=1;
cycle++;
break;
case 5: mem->Write(ptr,nextins);
AC^=nextins;
SETFLAGS_ZN(AC);
cycle=0;
break;
};
break;
case 0x56 : switch (cycle) {
case 4: mem->Write(nextins,farins);
farins>>=1;
++cycle;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0x5E : switch (cycle) {
case 5: mem->Write(ptr,nextins);
nextins>>=1;
++cycle;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x66 : switch (cycle) {
case 3: mem->Write(ptr,farins);
farins&0x01 ? ST|=0x01 : ST&=0xFE; ++cycle;
break;
case 4: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x67 : switch (cycle) {
case 3: mem->Write(ptr,nextins);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
cycle++;
break;
case 4: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x6E : switch (cycle) {
case 4: mem->Write(ptr,farins);
nextins=(farins>>1)|((ST&0x01)<<7);
(farins&0x01) ? ST|=0x01 : ST&=0xFE; ++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x6F : switch (cycle) {
case 4: mem->Write(ptr,nextins);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
cycle++;
break;
case 5: mem->Write(ptr,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x73 : switch (cycle) {
case 6: mem->Write(ptr+Y,nextins);
farins=(nextins>>1)|((ST&0x01)<<7);
nextins&0x01 ? ST|=0x01 : ST&=0xFE;
cycle++;
break;
case 7: mem->Write(ptr+Y,farins);
ADC(farins);
cycle=0;
break;
};
break;
case 0x76 : switch (cycle) {
case 4: mem->Write(ptr,farins);
farins&0x01 ? ST|=0x01 : ST&=0xFE; break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x7E : switch (cycle) {
case 5: mem->Write(ptr,farins);
++cycle;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0x81 : if (cycle==5) {
mem->Write(ptr,AC);
cycle=0;
};
break;
case 0x83 : if (cycle==5) {
mem->Write(ptr,nextins);
cycle=0;
};
break;
case 0x84 : if (cycle==2) {
mem->Write(nextins,Y);
cycle=0;
};
break;
case 0x85 : if (cycle==2) {
mem->Write(nextins,AC);
cycle=0;
};
break;
case 0x86 : if (cycle==2) {
mem->Write(nextins,X);
cycle=0;
};
break;
case 0x87 : if (cycle==2) {
mem->Write(nextins,AC&X);
cycle=0;
};
break;
case 0x8C : if (cycle==3) {
mem->Write(ptr,Y);
cycle=0;
};
break;
case 0x8D : if (cycle==3) {
mem->Write(ptr,AC);
cycle=0;
};
break;
case 0x8E : if (cycle==3) {
mem->Write(ptr,X);
cycle=0;
};
break;
case 0x8F : if (cycle==3) {
mem->Write(ptr,AC&X);
cycle=0;
};
break;
case 0x91 : if (cycle==5) {
mem->Write(ptr+Y,AC);
cycle=0;
};
break;
case 0x94 : switch (cycle) {
case 3: mem->Write(nextins,Y);
cycle=0;
break;
};
break;
case 0x95 : switch (cycle) {
case 3: mem->Write(nextins,AC);
cycle=0;
break;
};
break;
case 0x96 : switch (cycle) {
case 3: mem->Write(nextins,X);
cycle=0;
break;
};
break;
case 0x97 : if (cycle==3) {
mem->Write(nextins,AC&X);
cycle=0;
};
break;
case 0x99 : if (cycle==4) {
mem->Write(ptr+Y,AC);
cycle=0;
};
break;
case 0x9C : if (cycle==4) {
if (nextins+X<256)
mem->Write(ptr+X,Y&(nextins+1));
cycle=0;
};
break;
case 0x9D : if (cycle==4) {
mem->Write(ptr+X,AC);
cycle=0;
};
break;
case 0xC6 : switch (cycle) {
case 3: mem->Write(nextins,farins);
--farins;
++cycle;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xC7 : switch (cycle) {
case 3: mem->Write(ptr,nextins);
nextins -= 1;
cycle++;
break;
case 4: mem->Write(ptr,nextins);
(AC>=nextins) ? ST|=0x01 : ST&=0xFE;
nextins=AC-nextins;
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xCE : switch (cycle) {
case 4: mem->Write(ptr,nextins);
--nextins;
++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xCF : switch (cycle) {
case 4: mem->Write(ptr,farins);
farins -= 1;
cycle++;
break;
case 5: mem->Write(ptr,farins);
(AC>=farins) ? ST|=0x01 : ST&=0xFE;
farins=AC-farins;
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xD6 : switch (cycle) {
case 4: mem->Write(nextins,farins);
--farins;
++cycle;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xD7 : switch (cycle) {
case 4: mem->Write(ptr,nextins);
nextins-=1;
cycle++;
break;
case 5: mem->Write(ptr,nextins);
(AC>=nextins) ? ST|=0x01 : ST&=0xFE;
nextins=AC-nextins;
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xDE : switch (cycle) {
case 5: mem->Write(ptr,nextins);
--nextins;
++cycle;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xE6 : switch (cycle) {
case 3: mem->Write(nextins,farins);
++farins;
++cycle;
break;
case 4: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xE7 : switch (cycle) {
case 3: mem->Write(ptr,nextins);
nextins += 1;
cycle++;
break;
case 4: mem->Write(ptr,nextins);
SBC(nextins);
cycle=0;
break;
};
break;
case 0xEE : switch (cycle) {
case 4: mem->Write(ptr,nextins);
++nextins;
++cycle;
break;
case 5: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xEF : switch (cycle) {
case 4: mem->Write(ptr,farins);
farins += 1;
cycle++;
break;
case 5: mem->Write(ptr,farins);
SBC(farins);
cycle=0;
break;
};
break;
case 0xF6 : switch (cycle) {
case 4: mem->Write(nextins,farins);
++farins;
++cycle;
break;
case 5: mem->Write(nextins,farins);
SETFLAGS_ZN(farins);
cycle=0;
break;
};
break;
case 0xFE : switch (cycle) {
case 5: mem->Write(ptr,nextins);
++nextins;
++cycle;
break;
case 6: mem->Write(ptr,nextins);
SETFLAGS_ZN(nextins);
cycle=0;
break;
};
break;
case 0xFF : switch (cycle) {
case 5: mem->Write(ptr,farins);
farins += 1;
cycle++;
break;
case 6: mem->Write(ptr,farins);
SBC(farins);
cycle=0;
break;
default:
return;
};
break;
}
if ((IRQcount || (!irq_sequence && (*irq_register)&0x80)) )
IRQcount++;
}
CPU::~CPU()
{
}