#include "6502.h" #include "mem.h" #include "debug.h" namespace cpu6502 { static uint32_t clock = 0; static uint32_t t = 0; // P register Flags #define fC 0b00000001 // Carry #define fZ 0b00000010 // Zero #define fI 0b00000100 // Interrupt disable #define fD 0b00001000 // Decimal #define fB 0b00010000 // Interrupt type? #define f1 0b00100000 // -Unused- #define fV 0b01000000 // Overflow #define fN 0b10000000 // Negative // Jump types #define cUnconditional 255 #define cNZ 0 #define cZ 1 #define cNC 2 #define cC 3 #define cNN 4 #define cN 5 #define cNV 6 #define cV 7 // Addressing modes #define aAccumulator 0 #define aImmediate 1 #define aZeroPage 2 #define aZeroPageX 3 #define aZeroPageY 4 #define aRelative 5 // Is really needed? #define aIndirect 6 #define aIndirectX 7 #define aIndirectY 8 #define aAbsolute 9 #define aAbsoluteX 10 #define aAbsoluteY 11 #define FLAG_IS_RESET true #define FLAG_IS_SET false uint8_t i_reg_value = 0; uint8_t regs[7]; uint8_t *_rA = ®s[0]; uint8_t *_rX = ®s[1]; uint8_t *_rY = ®s[2]; uint8_t *_rS = ®s[3]; uint8_t *_rP = ®s[4]; uint16_t *_rPC = (uint16_t*)®s[5]; #define rA (*_rA) #define rX (*_rX) #define rY (*_rY) #define rS (*_rS) #define rP (*_rP) #define rPC (*_rPC) bool reading_m1 = false; uint8_t READ_MEM_8(const uint16_t addr, const bool code=false) { if (debug::isbreak(addr, 2)) debug::stop(); //t+=1; //[TODO] const uint8_t tag = mem::getTag(addr); if ( !(tag&MEMTAG_IGNORE) ) { if (!code) { if ( tag & MEMTAG_INST ) { } else { mem::setTag(addr, tag | MEMTAG_DATA); } } else { if ( (reading_m1) && ( tag & MEMTAG_DATA ) ) { } } } reading_m1 = false; return mem::readMem(addr); } uint8_t READ_MEM_8() { const uint8_t data = READ_MEM_8(rPC, true); const uint8_t tag = mem::getTag(rPC); if ( !(tag & MEMTAG_IGNORE) ) mem::setTag(rPC, tag | MEMTAG_CODE); rPC++; return data; } uint8_t READ_M1() { reading_m1 = true; return READ_MEM_8(); } uint16_t READ_MEM_16() { const uint8_t L = READ_MEM_8(); const uint8_t H = READ_MEM_8(); return (H << 8) + L; } uint16_t READ_MEM_16(const uint16_t addr) { return READ_MEM_8(addr) + (READ_MEM_8(addr+1) << 8); } const uint8_t WRITE_MEM_8(const uint16_t addr, const uint8_t value) { //t+=1; // [TODO] mem::writeMem(addr, value); if (debug::isbreak(addr, 4)) debug::stop(); debug::setmemmodified(addr); const uint8_t tag = mem::getTag(addr); if ( !(tag & MEMTAG_IGNORE) ) { if ( tag & MEMTAG_INST ) { //printf("WARNING! WRITING DATA OVER CODE!!! $%4X\n", addr); //z80debug::stop(); } else { mem::setTag(addr, tag | MEMTAG_DATA | MEMTAG_TDATA); } } return value; } void WRITE_MEM_16(const uint16_t addr, const uint16_t value) { WRITE_MEM_8(addr, value & 0xff); WRITE_MEM_8(addr+1, (value>>8) & 0xff); } void reset() { mem::reset(); rPC = 0x00; rA = rX = rY = rS = rP = 0xff; t = 0; } void interrupt(uint8_t type) { } void notImplemented() { } uint16_t addr_mode_address = 0; bool page_crossed = false; uint8_t loadValue(uint8_t addr_mode) { page_crossed = false; switch (addr_mode) { case aAccumulator: t+=2; return rA; case aImmediate: t+=2; return READ_MEM_8(); case aZeroPage: t+=3; addr_mode_address = READ_MEM_8(); return READ_MEM_8(addr_mode_address); case aZeroPageX: t+=4; addr_mode_address = (READ_MEM_8()+rX)&0xff; return READ_MEM_8(addr_mode_address); case aZeroPageY: t+=4; addr_mode_address = (READ_MEM_8()+rY)&0xff; return READ_MEM_8(addr_mode_address); case aIndirectX: t+=6; addr_mode_address = READ_MEM_16((READ_MEM_8()+rX)&0xff); return READ_MEM_8(addr_mode_address); case aIndirectY: t+=5; addr_mode_address = READ_MEM_16(READ_MEM_8()); if ( (addr_mode_address&0xff) + rY > 0xff ) { t++; page_crossed=true; } addr_mode_address = (addr_mode_address+rY)&0xffff; return READ_MEM_8(addr_mode_address); case aAbsolute: t+=4; addr_mode_address = READ_MEM_16(); return READ_MEM_8(addr_mode_address); case aAbsoluteX: t+=4; addr_mode_address = READ_MEM_16(); if ( (addr_mode_address&0xff) + rX > 0xff ) { t++; page_crossed=true; } addr_mode_address = (addr_mode_address+rX) & 0xffff; return READ_MEM_8(addr_mode_address); case aAbsoluteY: t+=4; addr_mode_address = READ_MEM_16(); if ( (addr_mode_address&0xff) + rY > 0xff ) { t++; page_crossed=true; } addr_mode_address = (addr_mode_address+rY) & 0xffff; return READ_MEM_8(addr_mode_address); } } void storeValue(uint8_t value, uint8_t addr_mode) { switch (addr_mode) { case aAccumulator: rA = value; break; case aZeroPage: case aZeroPageX: case aZeroPageY: t+=2; WRITE_MEM_8(addr_mode_address, value); break; case aIndirectX: WRITE_MEM_8(addr_mode_address, value); break; case aAbsolute: t+=2; WRITE_MEM_8(addr_mode_address, value); break; case aAbsoluteX: t+=page_crossed?2:3; WRITE_MEM_8(addr_mode_address, value); break; } } void PHP() { t+= 3; WRITE_MEM_8(0x0100+rS, rP|f1|fB); rS--; } void PHA() { t+= 3; WRITE_MEM_8(0x0100+rS, rA); rS--; } void PLP() { t+=4; rS++; rP = READ_MEM_8(0x0100+rS) & ~(f1|fB); } void PLA() { t+=4; rS++; rA = READ_MEM_8(0x0100+rS); rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void BRK() { READ_MEM_8(); WRITE_MEM_16(0x0100+rS, rPC); rS-=2; PHP(); // t+=3 rP |= fI; rPC = READ_MEM_16(0xfffe); t+=4; } void RTI() { PLP(); i_reg_value = rP&fI; // effect of changing fI is not delayed rS+=2; rPC = READ_MEM_16(0x0100+rS); t+=2; } void ADC(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint16_t result = rA + value + fC; rA = result & 0xff; rP = ( rP & ~fC ) | ( (result>>8) & fC ); rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); rP = ( (result ^ rA) & (result ^ value) & 0x80 ) ? rP | fV : rP & ~fV; } void SBC(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint16_t result = rA + ~value + fC; rA = result & 0xff; rP = ( rP & ~fC ) | ( (result>>8) & fC ); rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); rP = ( (result ^ rA) & (result ^ value) & 0x80 ) ? rP | fV : rP & ~fV; } void CMP(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint8_t result = rA + ~value; rP = ( rP & ~fC ) | ( (result>>8) & fC ); rP = ( rP & ~fN ) | ( result & fN ); rP = ( result ? rP & ~fZ : rP | fZ ); } void CPX(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint8_t result = rX + ~value; rP = ( rP & ~fC ) | ( (result>>8) & fC ); rP = ( rP & ~fN ) | ( result & fN ); rP = ( result ? rP & ~fZ : rP | fZ ); } void CPY(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint8_t result = rY + ~value; rP = ( rP & ~fC ) | ( (result>>8) & fC ); rP = ( rP & ~fN ) | ( result & fN ); rP = ( result ? rP & ~fZ : rP | fZ ); } void INC(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); value++; rP = ( rP & ~fN ) | ( value & fN ); rP = ( value ? rP & ~fZ : rP | fZ ); storeValue(value, addr_mode); } void DEC(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); value--; rP = ( rP & ~fN ) | ( value & fN ); rP = ( value ? rP & ~fZ : rP | fZ ); storeValue(value, addr_mode); } void INY() { rY++; rP = ( rP & ~fN ) | ( rY & fN ); rP = ( rY ? rP & ~fZ : rP | fZ ); } void DEY() { rY--; rP = ( rP & ~fN ) | ( rY & fN ); rP = ( rY ? rP & ~fZ : rP | fZ ); } void INX() { rX++; rP = ( rP & ~fN ) | ( rX & fN ); rP = ( rX ? rP & ~fZ : rP | fZ ); } void DEX() { rX--; rP = ( rP & ~fN ) | ( rX & fN ); rP = ( rX ? rP & ~fZ : rP | fZ ); } void ORA(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); rA |= value; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void AND(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); rA &= value; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void EOR(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); rA = rA ^ value; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void BIT(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint8_t result = rA & value; rP = ( rP & ~(fN|fV) ) | ( rA & (fN|fV) ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void ASL(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); rP = ( rP & ~fC ) | ( (value & 0x80)>>7 ); value = value << 1; rP = ( rP & ~fN ) | ( value & fN ); rP = ( value ? rP & ~fZ : rP | fZ ); storeValue(value, addr_mode); } void LSR(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); rP = ( rP & ~fC ) | ( (value & fC) ); value = value >> 1; rP = ( rP & ~fN ) | ( value & fN ); rP = ( value ? rP & ~fZ : rP | fZ ); storeValue(value, addr_mode); } void ROL(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint8_t old_fC = rP & fC; rP = ( rP & ~fC ) | ( (value & 0x80)>>7 ); value = (value << 1) | old_fC; rP = ( rP & ~fN ) | ( value & fN ); rP = ( value ? rP & ~fZ : rP | fZ ); storeValue(value, addr_mode); } void ROR(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); uint8_t old_fC = (rP & fC) << 7; rP = ( rP & ~fC ) | ( (value & fC) ); value = (value >> 1) | old_fC; rP = ( rP & ~fN ) | ( value & fN ); rP = ( value ? rP & ~fZ : rP | fZ ); storeValue(value, addr_mode); } void JMP(uint8_t addr_mode) { t+=3; addr_mode_address = READ_MEM_16(); if (addr_mode == aIndirect) { t+=5; const uint8_t L = READ_MEM_8(addr_mode_address); const uint8_t H = READ_MEM_8( (addr_mode_address&0xff00) | ((addr_mode_address+1)&0x00ff) ); addr_mode_address = (H << 8) + L; } rPC = addr_mode_address; } void BRANCH(uint8_t flag, bool negate) { t+=3; int8_t offset = (int8_t)READ_MEM_8(); bool condition = (rP & flag); if (negate) condition = !condition; if (condition) { t++; if ( (rPC&0xff) + offset > 0xff ) t++; rPC = (rPC + offset) & 0xffff; } } void BPL() { BRANCH(fN, FLAG_IS_RESET); } void BMI() { BRANCH(fN, FLAG_IS_SET); } void BNE() { BRANCH(fZ, FLAG_IS_RESET); } void BEQ() { BRANCH(fZ, FLAG_IS_SET); } void BCC() { BRANCH(fC, FLAG_IS_RESET); } void BCS() { BRANCH(fC, FLAG_IS_SET); } void BVC() { BRANCH(fV, FLAG_IS_RESET); } void BVS() { BRANCH(fV, FLAG_IS_SET); } void JSR(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); t+=2; WRITE_MEM_16(0x0100+rS, rPC-1); rS-=2; rPC = value; } void RTS() { rS+=2; rPC = READ_MEM_16(0x0100+rS); rPC++; t+=6; } void SET_FLAG(uint8_t flag) { t+=2; rP = rP | flag; } void SEC() { SET_FLAG(fC); } void SED() { SET_FLAG(fD); } void SEI() { SET_FLAG(fI); } void CLEAR_FLAG(uint8_t flag) { t+=2; rP = rP & ~flag; } void CLC() { CLEAR_FLAG(fC); } void CLD() { CLEAR_FLAG(fD); } void CLI() { CLEAR_FLAG(fI); } void CLV() { CLEAR_FLAG(fV); } void STA(uint8_t addr_mode) { loadValue(addr_mode); if (!page_crossed) t++; storeValue(rA, addr_mode); } void STX(uint8_t addr_mode) { loadValue(addr_mode); storeValue(rX, addr_mode); } void STY(uint8_t addr_mode) { loadValue(addr_mode); storeValue(rY, addr_mode); } void LDA(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); if (!page_crossed) t++; rA = value; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void LDX(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); if (!page_crossed) t++; rX = value; rP = ( rP & ~fN ) | ( rX & fN ); rP = ( rX ? rP & ~fZ : rP | fZ ); } void LDY(uint8_t addr_mode) { uint8_t value = loadValue(addr_mode); if (!page_crossed) t++; rY = value; rP = ( rP & ~fN ) | ( rY & fN ); rP = ( rY ? rP & ~fZ : rP | fZ ); } void TAX() { t += 2; rX = rA; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void TAY() { t += 2; rY = rA; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void TSX() { t += 2; rX = rS; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rX ? rP & ~fZ : rP | fZ ); } void TXA() { t += 2; rA = rX; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void TXS() { t += 2; rS = rX; } void TYA() { t += 2; rA = rY; rP = ( rP & ~fN ) | ( rA & fN ); rP = ( rA ? rP & ~fZ : rP | fZ ); } void NOP() { t+=2; } uint32_t step() { t = 0; i_reg_value = rP & fI; uint16_t current_opcode_address = rPC; const uint8_t opcode = READ_M1(); uint8_t tag = mem::getTag(current_opcode_address); if ( !(tag & MEMTAG_IGNORE) ) tag = tag | MEMTAG_INST; mem::setTag(current_opcode_address, tag | (!(tag&MEMTAG_TOUCHED) ? MEMTAG_TREPEAT : MEMTAG_TINST) ); uint16_t tmp; switch (opcode) { case 0x00: BRK(); break; case 0x01: ORA(aIndirectX); break; case 0x02: notImplemented(); break; case 0x03: notImplemented(); break; case 0x04: notImplemented(); break; case 0x05: ORA(aZeroPage); break; case 0x06: ASL(aZeroPage); break; case 0x07: notImplemented(); break; case 0x08: PHP(); break; case 0x09: ORA(aImmediate); break; case 0x0a: ASL(aAccumulator); break; case 0x0b: notImplemented(); break; case 0x0c: notImplemented(); break; case 0x0d: ORA(aAbsolute); break; case 0x0e: ASL(aAbsolute); break; case 0x0f: notImplemented(); break; case 0x10: BPL(); break; case 0x11: ORA(aIndirectY); break; case 0x12: notImplemented(); break; case 0x13: notImplemented(); break; case 0x14: notImplemented(); break; case 0x15: ORA(aZeroPageX); break; case 0x16: ASL(aZeroPageX); break; case 0x17: notImplemented(); break; case 0x18: CLC(); break; case 0x19: ORA(aAbsoluteY); break; case 0x1a: notImplemented(); break; case 0x1b: notImplemented(); break; case 0x1c: notImplemented(); break; case 0x1d: ORA(aAbsoluteX); break; case 0x1e: ASL(aAbsoluteX); break; case 0x1f: notImplemented(); break; case 0x20: JSR(aAbsolute); break; case 0x21: AND(aIndirectX); break; case 0x22: notImplemented(); break; case 0x23: notImplemented(); break; case 0x24: BIT(aZeroPage); break; case 0x25: AND(aZeroPage); break; case 0x26: ROL(aZeroPage); break; case 0x27: notImplemented(); break; case 0x28: PLP(); break; case 0x29: AND(aImmediate); break; case 0x2a: ROL(aAccumulator); break; case 0x2b: notImplemented(); break; case 0x2c: BIT(aAbsolute); break; case 0x2d: AND(aAbsolute); break; case 0x2e: ROL(aAbsolute); break; case 0x2f: notImplemented(); break; case 0x30: BMI(); break; case 0x31: AND(aIndirectY); break; case 0x32: notImplemented(); break; case 0x33: notImplemented(); break; case 0x34: notImplemented(); break; case 0x35: AND(aZeroPageX); break; case 0x36: ROL(aZeroPageX); break; case 0x37: notImplemented(); break; case 0x38: SEC(); break; case 0x39: AND(aAbsoluteY); break; case 0x3a: notImplemented(); break; case 0x3b: notImplemented(); break; case 0x3c: notImplemented(); break; case 0x3d: AND(aAbsoluteX); break; case 0x3e: ROL(aAbsoluteX); break; case 0x3f: notImplemented(); break; case 0x40: RTI(); break; case 0x41: EOR(aIndirectX); break; case 0x42: notImplemented(); break; case 0x43: notImplemented(); break; case 0x44: notImplemented(); break; case 0x45: EOR(aZeroPage); break; case 0x46: LSR(aZeroPage); break; case 0x47: notImplemented(); break; case 0x48: PHA(); break; case 0x49: EOR(aImmediate); break; case 0x4a: LSR(aAccumulator); break; case 0x4b: notImplemented(); break; case 0x4c: JMP(aAbsolute); break; case 0x4d: EOR(aAbsolute); break; case 0x4e: LSR(aAbsolute); break; case 0x4f: notImplemented(); break; case 0x50: BVC(); break; case 0x51: EOR(aIndirectY); break; case 0x52: notImplemented(); break; case 0x53: notImplemented(); break; case 0x54: notImplemented(); break; case 0x55: EOR(aZeroPageX); break; case 0x56: LSR(aZeroPageX); break; case 0x57: notImplemented(); break; case 0x58: CLI(); break; case 0x59: EOR(aAbsoluteY); break; case 0x5a: notImplemented(); break; case 0x5b: notImplemented(); break; case 0x5c: notImplemented(); break; case 0x5d: EOR(aAbsoluteX); break; case 0x5e: LSR(aAbsoluteX); break; case 0x5f: notImplemented(); break; case 0x60: RTS(); break; case 0x61: ADC(aIndirectX); break; case 0x62: notImplemented(); break; case 0x63: notImplemented(); break; case 0x64: notImplemented(); break; case 0x65: ADC(aZeroPage); break; case 0x66: ROR(aZeroPage); break; case 0x67: notImplemented(); break; case 0x68: PLA(); break; case 0x69: ADC(aImmediate); break; case 0x6a: ROR(aAccumulator); break; case 0x6b: notImplemented(); break; case 0x6c: JMP(aIndirect); break; case 0x6d: ADC(aAbsolute); break; case 0x6e: ROR(aAbsolute); break; case 0x6f: notImplemented(); break; case 0x70: BVS(); break; case 0x71: ADC(aIndirectY); break; case 0x72: notImplemented(); break; case 0x73: notImplemented(); break; case 0x74: notImplemented(); break; case 0x75: ADC(aZeroPageX); break; case 0x76: ROR(aZeroPageX); break; case 0x77: notImplemented(); break; case 0x78: SEI(); break; case 0x79: ADC(aAbsoluteY); break; case 0x7a: notImplemented(); break; case 0x7b: notImplemented(); break; case 0x7c: notImplemented(); break; case 0x7d: ADC(aAbsoluteX); break; case 0x7e: ROR(aAbsoluteX); break; case 0x7f: notImplemented(); break; case 0x80: notImplemented(); break; case 0x81: STA(aIndirectX); break; case 0x82: notImplemented(); break; case 0x83: notImplemented(); break; case 0x84: STY(aZeroPage); break; case 0x85: STA(aZeroPage); break; case 0x86: STX(aZeroPage); break; case 0x87: notImplemented(); break; case 0x88: DEY(); break; case 0x89: notImplemented(); break; case 0x8a: TXA(); break; case 0x8b: notImplemented(); break; case 0x8c: STY(aAbsolute); break; case 0x8d: STA(aAbsolute); break; case 0x8e: STX(aAbsolute); break; case 0x8f: notImplemented(); break; case 0x90: BCC(); break; case 0x91: STA(aIndirectY); break; case 0x92: notImplemented(); break; case 0x93: notImplemented(); break; case 0x94: STY(aZeroPageX); break; case 0x95: STA(aZeroPageX); break; case 0x96: STX(aZeroPageY); break; case 0x97: notImplemented(); break; case 0x98: TYA(); break; case 0x99: STA(aAbsoluteY); break; case 0x9a: TXS(); break; case 0x9b: notImplemented(); break; case 0x9c: notImplemented(); break; case 0x9d: STA(aAbsolute); break; case 0x9e: notImplemented(); break; case 0x9f: notImplemented(); break; case 0xa0: LDY(aImmediate); break; case 0xa1: LDA(aIndirectX); break; case 0xa2: LDX(aImmediate); break; case 0xa3: notImplemented(); break; case 0xa4: LDY(aZeroPage); break; case 0xa5: LDA(aZeroPage); break; case 0xa6: LDX(aZeroPage); break; case 0xa7: notImplemented(); break; case 0xa8: TAY(); break; case 0xa9: LDA(aImmediate); break; case 0xaa: TAX(); break; case 0xab: notImplemented(); break; case 0xac: LDY(aAbsolute); break; case 0xad: LDA(aAbsolute); break; case 0xae: LDX(aAbsolute); break; case 0xaf: notImplemented(); break; case 0xb0: BCS(); break; case 0xb1: LDA(aIndirectY); break; case 0xb2: notImplemented(); break; case 0xb3: notImplemented(); break; case 0xb4: LDY(aZeroPageX); break; case 0xb5: LDA(aZeroPageX); break; case 0xb6: LDX(aZeroPageY); break; case 0xb7: notImplemented(); break; case 0xb8: CLV(); break; case 0xb9: LDA(aAbsoluteY); break; case 0xba: TSX(); break; case 0xbb: notImplemented(); break; case 0xbc: LDY(aAbsoluteX); break; case 0xbd: LDA(aAbsoluteX); break; case 0xbe: LDX(aAbsoluteY); break; case 0xbf: notImplemented(); break; case 0xc0: CPY(aImmediate); break; case 0xc1: CMP(aIndirectX); break; case 0xc2: notImplemented(); break; case 0xc3: notImplemented(); break; case 0xc4: CPY(aZeroPage); break; case 0xc5: CMP(aZeroPage); break; case 0xc6: DEC(aZeroPage); break; case 0xc7: notImplemented(); break; case 0xc8: INY(); break; case 0xc9: CMP(aImmediate); break; case 0xca: DEX(); break; case 0xcb: notImplemented(); break; case 0xcc: CPY(aAbsolute); break; case 0xcd: CMP(aAbsolute); break; case 0xce: DEC(aAbsolute); break; case 0xcf: notImplemented(); break; case 0xd0: BNE(); break; case 0xd1: CMP(aIndirectY); break; case 0xd2: notImplemented(); break; case 0xd3: notImplemented(); break; case 0xd4: notImplemented(); break; case 0xd5: CMP(aZeroPageX); break; case 0xd6: DEC(aZeroPageX); break; case 0xd7: notImplemented(); break; case 0xd8: CLD(); break; case 0xd9: CMP(aAbsoluteY); break; case 0xda: notImplemented(); break; case 0xdb: notImplemented(); break; case 0xdc: notImplemented(); break; case 0xdd: CMP(aAbsoluteX); break; case 0xde: DEC(aAbsoluteX); break; case 0xdf: notImplemented(); break; case 0xe0: CPX(aImmediate); break; case 0xe1: SBC(aIndirectX); break; case 0xe2: notImplemented(); break; case 0xe3: notImplemented(); break; case 0xe4: CPX(aZeroPage); break; case 0xe5: SBC(aZeroPage); break; case 0xe6: INC(aZeroPage); break; case 0xe7: notImplemented(); break; case 0xe8: INX(); break; case 0xe9: SBC(aImmediate); break; case 0xea: NOP(); break; case 0xeb: notImplemented(); break; case 0xec: CPX(aAbsolute); break; case 0xed: SBC(aAbsolute); break; case 0xee: INC(aAbsolute); break; case 0xef: notImplemented(); break; case 0xf0: BEQ(); break; case 0xf1: SBC(aIndirectY); break; case 0xf2: notImplemented(); break; case 0xf3: notImplemented(); break; case 0xf4: notImplemented(); break; case 0xf5: SBC(aZeroPageX); break; case 0xf6: INC(aZeroPageX); break; case 0xf7: notImplemented(); break; case 0xf8: SED(); break; case 0xf9: SBC(aAbsoluteY); break; case 0xfa: notImplemented(); break; case 0xfb: notImplemented(); break; case 0xfc: notImplemented(); break; case 0xfd: SBC(aAbsoluteX); break; case 0xfe: INC(aAbsoluteX); break; case 0xff: notImplemented(); break; }; // [TODO] Gestionar interrupcions //if (!i_reg_value) gestionar interrupcions //debug::setcursor(rPC); //debug::history::store(); mem::update_mapped(t); return t; } }