!!HACKING!!
0x0000000000000000
Status: Initializing...
#include "c64.h" #include "instr.h" /* +-+-+-+-+-+-+-+-+ |N|V| |B|D|I|Z|C| PROCESSOR STATUS REG "P" +-+-+-+-+-+-+-+-+ | | | | | | | | | | | | | +> CARRY 1=TRUE | | | | | +--> ZERO 1=RESULT ZERO | | | | +----> IRQ DISABLE 1=DISABLE | | | +------> DECIMAL MODE 1=TRUE | | +--------> BRK COMMAND | | | +------------> OVERFLOW 1=TRUE +--------------> NEGATIVE 1=NEG */ extern FILE *_log, *_ilog; extern FILE *_cialog; extern struct writelog _wlog[10]; extern int _widx; extern int _timerA1, _timerA1L, _keydown; extern uint8_t _ics1; enum { P_CARRY = 1, P_ZERO = 2, P_IRQDIS = 4, P_DECIMAL = 8, P_BRK = 16, P_OVERFLOW = 64, P_NEGATIVE = 128 }; uint16_t _PC; uint8_t _A, _X, _Y, _S, _P, _IR; int _HWIRQ = 0, _NMI = 0; extern struct memory _page[64]; int crosspage(uint16_t addr1, uint16_t addr2) { return (addr1&0xFF00) != (addr2&0xFF00); } uint8_t immediate_value(void) { uint8_t v = load(_PC++); if (_log) fprintf(_log, "#%d", v); return v; } uint16_t immediate(void) { uint16_t addr = _PC++; if (_log) fprintf(_log, "#%d", load(addr)); return addr; } uint16_t branchaddr(int *cpb) { int8_t v = (int8_t)load(_PC++); uint16_t addr; addr = _PC + v; if (_log) fprintf(_log, "%04X", addr); if (cpb) *cpb = crosspage(_PC-1, addr); return addr; } /* Absolute */ uint16_t absolute(void) { uint16_t addr; uint8_t l, h; l = load(_PC++); h = load(_PC++); addr = (h<<8 | l); if (_log) fprintf(_log, "%04X",addr); return addr; } /* Absolute,[X|Y] */ uint16_t absolute_indexed(uint8_t idx) { uint16_t addr; uint8_t l, h; l = load(_PC++); h = load(_PC++); addr = (h<<8 | l); // if (_P & P_CARRY) idx++; if (_log) fprintf(_log, "%04X,%d",addr, idx); return addr + idx; } /* Zero-page[,X|Y] */ uint16_t zero_page(uint8_t idx) { uint8_t l; l = load(_PC++); if (_log) fprintf(_log, "%02X,%d", l, idx); l += idx; return (0x0000 | l); } /* (Zero-page),Y */ uint16_t indirect_indexed(void) { uint16_t addr; uint8_t l, h; l = load(_PC++); addr = (0x0000 | l); if (_log) fprintf(_log, "(%02X),Y:%d",l, _Y); l = load(addr); h = load(addr+1); return (h<<8|l) + _Y; } /* (Zero-page,X) */ uint16_t indexed_indirect() { uint16_t addr; uint8_t l, h; l = load(_PC++) + _X; addr = 0x0000 | l; if (_log) fprintf(_log, "(%02X,X:%d)\n",l, _X); l = load(addr); h = load(addr+1); return (h<<8|l); } void push(uint8_t data) { store(0x0100|_S--,data); } uint8_t pop() { return load(0x0100|++_S); } void adc(uint16_t addr) { uint8_t m = load(addr), r; int v; v = _A + m + ((_P&P_CARRY)? 1 : 0); r = _A + m + (uint8_t)((_P&P_CARRY)? 1 : 0); _P &= ~(P_CARRY|P_NEGATIVE|P_ZERO|P_OVERFLOW); if (((_A^r)&0x80) && ((m^r)&0x80)) _P |= P_OVERFLOW; if (v > 255) _P |= P_CARRY; if (r == 0) _P |= P_ZERO; if (r&0x80) _P |= P_NEGATIVE; _A = r; } void sbc(uint16_t addr) { uint8_t m = load(addr), r; int v; m = 255 - m; v = _A + m + ((_P&P_CARRY)? 1 : 0); r = _A + m + (uint8_t)((_P&P_CARRY)? 1 : 0); _P &= ~(P_CARRY|P_NEGATIVE|P_ZERO|P_OVERFLOW); if (((_A^r)&0x80) && ((m^r)&0x80)) _P |= P_OVERFLOW; if (v > 255) _P |= P_CARRY; if (r == 0) _P |= P_ZERO; if (r&0x80) _P |= P_NEGATIVE; _A = r; } uint8_t ror(uint8_t m) { int c = _P & P_CARRY; _P &= ~(P_CARRY|P_ZERO|P_NEGATIVE); if (m & 0x01) _P |= P_CARRY; m >>= 1; if (c) m |= 0x80; else m &= 0x7F; if (m == 0) _P |= P_ZERO; if (m & 0x80) _P |= P_NEGATIVE; return m; } uint8_t rol(uint8_t m) { int c = _P & P_CARRY; _P &= ~(P_CARRY|P_ZERO|P_NEGATIVE); if (m & 0x80) _P |= P_CARRY; m <<= 1; if (c) m |= 0x01; if (m == 0) _P |= P_ZERO; if (m & 0x80) _P |= P_NEGATIVE; return m; } uint8_t lsr(uint8_t m) { _P &= ~(P_ZERO | P_CARRY | P_NEGATIVE); if (m & 0x01) _P |= P_CARRY; m>>=1; if (m == 0) _P |= P_ZERO; return m; } uint8_t asl(uint8_t m) { _P &= ~(P_ZERO | P_CARRY | P_NEGATIVE); if (m & 0x80) _P |= P_CARRY; m<<=1; if (m == 0) _P |= P_ZERO; if (m & 0x80) _P |= P_NEGATIVE; return m; } void ora(uint16_t addr) { uint8_t m = load(addr); _A |= m; _P &= ~(P_NEGATIVE|P_ZERO); if (_A == 0) _P |= P_ZERO; if (_A & 0x80) _P |= P_NEGATIVE; } void lda(uint16_t addr) { _A = load(addr); _P &= ~(P_NEGATIVE | P_ZERO); if (_A == 0) _P |= P_ZERO; if (_A & 0x80) _P |= P_NEGATIVE; } void ldx(uint16_t addr) { _X = load(addr); _P &= ~(P_NEGATIVE | P_ZERO); if (_X == 0) _P |= P_ZERO; if (_X & 0x80) _P |= P_NEGATIVE; } void ldy(uint16_t addr) { _Y = load(addr); _P &= ~(P_NEGATIVE | P_ZERO); if (_Y == 0) _P |= P_ZERO; if (_Y & 0x80) _P |= P_NEGATIVE; } void inc(uint16_t addr) { uint8_t m = load(addr); _P &= ~(P_ZERO | P_NEGATIVE); m++; if (m == 0) _P |= P_ZERO; if (m & 0x80) _P |= P_NEGATIVE; store(addr, m); } void dec(uint16_t addr) { uint8_t m = load(addr); _P &= ~(P_ZERO | P_NEGATIVE); m--; if (m == 0) _P |= P_ZERO; if (m & 0x80) _P |= P_NEGATIVE; store(addr, m); } void eor(uint16_t addr) { uint8_t m = load(addr); _P &= ~(P_ZERO | P_NEGATIVE); _A ^= m; if (_A == 0) _P |= P_ZERO; if (_A & 0x80) _P |= P_NEGATIVE; } /* a = register, b = memory */ void cmp(uint8_t a, uint16_t addr) { uint8_t b = load(addr); if (_log) fprintf(_log," (%d/%d) ",a,b); _P &= ~(P_ZERO | P_NEGATIVE | P_CARRY); if (a == b) _P |= P_ZERO; if (a >= b) _P |= P_CARRY; a = a-b; if (a&0x80) _P |= P_NEGATIVE; } void and(uint16_t addr) { uint8_t m = load(addr); _P &= ~(P_ZERO | P_NEGATIVE); _A &= m; if (_A == 0) _P |= P_ZERO; if (_A & 0x80) _P |= P_NEGATIVE; } char *status(uint8_t P) { static char f[8]; f[0] = P & P_NEGATIVE? 'N' : '-'; f[1] = P & P_ZERO? 'Z' : '-'; f[2] = P & P_CARRY? 'C' : '-'; f[3] = P & P_IRQDIS? 'I' : '-'; f[4] = P & P_DECIMAL? 'D' : '-'; f[5] = P & P_OVERFLOW? 'V' : '-'; f[6] = 0; return f; } int run() { int i, cycles = 0, clocks = 0; uint16_t addr; uint8_t l, h; while(1) { _IR = load(_PC++); if (_log) fprintf(_log, "%04X %02X:%s ", _PC-1, _IR, _instr[_IR]); switch(_IR) { case 0x00: // BRK _PC++; push(_PC>>8); push(_PC&0xFF); push(_P | P_BRK); _P |= P_IRQDIS; _PC = load(0x0317)<<8 | load(0x0316); cycles = 7; break; case 0x01: // ORA (Indirect,X) ora(indexed_indirect()); cycles = 6; break; case 0x05: // ORA Zero-page ora(zero_page(0)); cycles = 3; break; case 0x06: // ASL Zero-page l = asl(load(addr = zero_page(0))); store(addr, l); cycles = 5; break; case 0x08: // PHP push(_P); cycles = 3; break; case 0x09: // ORA Immediate ora(immediate()); cycles = 2; break; case 0x0A: // ASL Accumulator _A = asl(_A); cycles = 2; break; case 0x0D: // ORA Absolute ora(absolute()); cycles = 4; break; case 0x0E: // ASL Absolute l = asl(load(addr = absolute())); store(addr, l); cycles = 6; break; case 0x10: // BPL l = immediate_value(); cycles = 2; if (!(_P & P_NEGATIVE)) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0x11: // ORA (Indirect),Y ora(indirect_indexed()); cycles = 5; break; case 0x15: // ORA Zero-Page,X ora(zero_page(_X)); cycles = 4; break; case 0x16: // ASL Zero-Page,X l = asl(load(addr = zero_page(_X))); store(addr, l); cycles = 6; break; case 0x18: // CLC _P &= ~P_CARRY; cycles = 2; break; case 0x19: // ORA Absolute,Y ora(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0x1D: // ORA Absolute,X ora(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0x1E: // ASL Absolute,X l = asl(load(addr = absolute_indexed(_X))); store(addr, l); cycles = 7; break; case 0x20: // JSR addr = _PC+1; push(addr>>8); push(addr&0xFF); _PC = absolute(); cycles = 6; break; case 0x21: // AND (Indirect,X) and(indexed_indirect()); cycles = 6; break; case 0x24: // BIT Zero-page l = load(zero_page(0)); _P &= ~(P_NEGATIVE|P_ZERO|P_OVERFLOW); _P |= (l&0xC0); _P |= (_A&l? 0 : P_ZERO); cycles = 3; break; case 0x25: // AND Zero-page and(zero_page(0)); cycles = 3; break; case 0x26: // ROL Zero-page l = rol(load(addr = zero_page(0))); store(addr, l); cycles = 5; break; case 0x28: // PLP _P = pop(); cycles = 4; break; case 0x29: // AND Immediate and(immediate()); cycles = 2; break; case 0x2A: // ROL Accumulator _A = rol(_A); cycles = 2; break; case 0x2C: // BIT Absolute l = load(absolute()); _P &= ~(P_NEGATIVE|P_ZERO|P_OVERFLOW); _P |= (l&0xC0); _P |= (_A&l? 0 : P_ZERO); cycles = 4; break; case 0x2D: // AND Absolute and(absolute()); cycles = 4; break; case 0x2E: // ROL Absolute l = rol(load(addr = absolute())); store(addr, l); cycles = 6; break; case 0x30: // BMI l = immediate_value(); cycles = 2; if (_P & P_NEGATIVE) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0x31: // AND (Indirect),Y and(indirect_indexed()); cycles = 5; break; case 0x35: // AND Zero-page,X and(zero_page(_X)); cycles = 4; break; case 0x36: // ROL Zero-page,X l = rol(load(addr = zero_page(_X))); store(addr, l); cycles = 6; break; case 0x38: // SEC _P |= P_CARRY; cycles = 2; break; case 0x39: // AND Absolute,Y and(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0x3D: // AND Absolute,X and(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0x3E: // ROL Absolute,X l = rol(load(addr = absolute_indexed(_X))); store(addr, l); cycles = 7; break; case 0x40: // RTI _P = pop(); l = pop(); h = pop(); _PC = h<<8 | l; if (_ilog) { fprintf(_log, "PC-> %04X", _PC); fprintf(_log, " S:1%02X A:%d X:%d Y:%d P:%s\n",_S, _A, _X, _Y, status(_P)); _log = NULL; } break; case 0x41: // EOR (Indirect,X) eor(indexed_indirect()); cycles = 6; break; case 0x45: // EOR Zero-page eor(zero_page(0)); cycles = 3; break; case 0x46: // LSR Zero-page l = lsr(load(addr = zero_page(0))); store(addr,l); cycles = 5; break; case 0x48: // PHA push(_A); cycles = 3; break; case 0x49: // EOR Immediate eor(immediate()); cycles = 2; break; case 0x4A: // LSR Accumulator _A = lsr(_A); cycles = 2; break; case 0x4C: // JMP Absolute _PC = absolute(); cycles = 3; break; case 0x4D: // EOR Absolute eor(absolute()); cycles = 4; break; case 0x4E: // LSR Absolute l = lsr(load(addr = absolute())); store(addr,l); cycles = 6; break; case 0x50: // BVC l = immediate_value(); cycles = 2; if (!(_P & P_OVERFLOW)) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0x51: // EOR (Indirect),Y eor(addr = indirect_indexed()); cycles = 5 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0x55: // EOR Zero-page,X eor(zero_page(_X)); cycles = 4; break; case 0x56: // LSR Zero-page,X l = lsr(load(addr = zero_page(_X))); store(addr,l); cycles = 6; break; case 0x58: // CLI _P &= ~(P_IRQDIS); cycles = 2; break; case 0x59: // EOR Absolute,Y eor(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0x5D: // EOR Absolute,X eor(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0x5E: // LSR Absolute,X l = lsr(load(addr = absolute_indexed(_X))); store(addr,l); cycles = 7; break; case 0x60: // RTS l = pop(); h = pop(); _PC = h<<8 | l; _PC++; break; case 0x61: // ADC (Indirect,X) adc(indexed_indirect()); cycles = 6; break; case 0x65: // ADC Zero-page adc(zero_page(0)); cycles = 3; break; case 0x66: // ROR Zero-page l = ror(load(addr = zero_page(0))); store(addr,l); cycles = 5; break; case 0x68: // PLA _A = pop(); _P &= ~(P_ZERO|P_NEGATIVE); if (_A == 0) _P |= P_ZERO; if (_A&0x80) _P |= P_NEGATIVE; cycles = 4; break; case 0x69: // ADC Immediate adc(immediate()); cycles = 2; break; case 0x6A: // ROR Accumulator _A = ror(_A); cycles = 2; break; case 0x6C: // JMP Indirect addr = absolute(); l = load(addr); if ((addr&0x00FF) == 0x00FF) { fprintf(stderr,"Possible bad indirect jump (addr=%04X)\n", addr); exit(0); } h = load(addr+1); _PC = h<<8 | l; cycles = 5; break; case 0x6D: // ADC Absolute adc(absolute()); cycles = 4; break; case 0x6E: // ROR Absolute l = ror(load(addr = absolute())); store(addr, l); cycles = 6; break; case 0x70: // BVS l = immediate_value(); cycles = 2; if (_P & P_OVERFLOW) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0x71: // ADC (Indirect),Y adc(addr = indirect_indexed()); cycles = 5 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0x75: // ADC Zero-page,X adc(zero_page(_X)); cycles = 4; break; case 0x76: // ROR Zero-page,X l = ror(load(addr = zero_page(_X))); store(addr, l); cycles = 6; break; case 0x78: // SEI _P |= P_IRQDIS; cycles = 2; break; case 0x79: // ADC Absolute,Y adc(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0x7D: // ADC Absolute,X adc(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0x7E: // ROR Absolute,X l = ror(load(addr = absolute_indexed(_X))); store(addr, l); cycles = 7; break; case 0x81: // STA (Indirect,X) store(indexed_indirect(), _A); cycles = 6; break; case 0x84: // STY Zero-page store(zero_page(0), _Y); cycles = 3; break; case 0x85: // STA Zero-page store(zero_page(0), _A); cycles = 3; break; case 0x86: // STX Zero-page store(zero_page(0), _X); cycles = 3; break; case 0x88: // DEY _Y--; _P &= ~(P_ZERO | P_NEGATIVE); if (_Y == 0) _P |= P_ZERO; if (_Y & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0x8A: // TXA _A = _X; _P &= ~(P_ZERO | P_NEGATIVE); if (_A == 0) _P |= P_ZERO; if (_A & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0x8C: // STY Absolute store(absolute(), _Y); cycles = 4; break; case 0x8D: // STA Absolute store(absolute(), _A); cycles = 4; break; case 0x8E: // STX Absolute store(absolute(), _X); cycles = 4; break; case 0x90: // BCC l = immediate_value(); cycles = 2; if (!(_P & P_CARRY)) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0x91: // STA (Indirect),Y store(indirect_indexed(), _A); cycles = 6; break; case 0x94: // STY Zero-page,X store(zero_page(_X), _Y); cycles = 4; break; case 0x95: // STA Zero-page,X store(zero_page(_X), _A); cycles = 4; break; case 0x96: // STX Zero-page,Y store(zero_page(_Y), _X); cycles = 4; break; case 0x98: // TYA _A = _Y; _P &= ~(P_ZERO | P_NEGATIVE); if (_A == 0) _P |= P_ZERO; if (_A & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0x99: // STA Absolute,Y store(absolute_indexed(_Y), _A); cycles = 5; break; case 0x9A: // TXS _S = _X; cycles = 2; break; case 0x9D: // STA Absolute,X store(absolute_indexed(_X), _A); cycles = 5; break; case 0xA0: // LDY Immediate ldy(immediate()); cycles = 2; break; case 0xA1: // LDA (Indirect,X) lda(indexed_indirect()); cycles = 6; break; case 0xA2: // LDX Immediate ldx(immediate()); cycles = 2; break; case 0xA4: // LDY Zero-page ldy(zero_page(0)); cycles = 3; break; case 0xA5: // LDA Zero-page lda(zero_page(0)); cycles = 3; break; case 0xA6: // LDX Zero-page ldx(zero_page(0)); cycles = 3; break; case 0xA8: // TAY _Y = _A; _P &= ~(P_ZERO | P_NEGATIVE); if (_Y == 0) _P |= P_ZERO; if (_Y & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0xA9: // LDA Immediate lda(immediate()); cycles = 2; break; case 0xAA: // TAX _X = _A; _P &= ~(P_ZERO | P_NEGATIVE); if (_X == 0) _P |= P_ZERO; if (_X & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0xAC: // LDY Absolute ldy(absolute()); cycles = 4; break; case 0xAD: // LDA Absolute lda(absolute()); cycles = 4; break; case 0xAE: // LDX Absolute ldx(absolute()); cycles = 4; break; case 0xB0: // BCS l = immediate_value(); cycles = 2; if (_P & P_CARRY) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0xB1: // LDA (Indirect),Y lda(addr = indirect_indexed()); cycles = 5 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0xB4: // LDY Zero-page,X ldy(zero_page(_X)); cycles = 4; break; case 0xB5: // LDA Zero-page,X lda(zero_page(_X)); cycles = 4; break; case 0xB6: // LDX Zero-page,Y ldx(zero_page(_Y)); cycles = 4; break; case 0xB8: // CLV _P &= ~P_OVERFLOW; cycles = 2; break; case 0xB9: // LDA Absolute,Y lda(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0xBA: // TSX _X = _S; _P &= ~(P_ZERO | P_NEGATIVE); if (_X == 0) _P |= P_ZERO; if (_X & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0xBC: // LDY Absolute,X ldy(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1: 0 ; break; case 0xBD: // LDA Absolute,X lda(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0xBE: // LDX Absolute,Y ldx(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1: 0 ; break; case 0xC0: // CPY Immediate cmp(_Y, immediate()); cycles = 2; break; case 0xC1: // CMP (Indirect,X) cmp(_A, indexed_indirect()); cycles = 6; break; case 0xC4: // CPY Zero-page cmp(_Y, zero_page(0)); cycles = 3; break; case 0xC5: // CMP Zero-page cmp(_A, zero_page(0)); cycles = 3; break; case 0xC6: // DEC Zero-page dec(zero_page(0)); cycles = 5; break; case 0xC8: // INY _Y++; _P &= ~(P_ZERO | P_NEGATIVE); if (_Y == 0) _P |= P_ZERO; if (_Y & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0xC9: // CMP Immediate cmp(_A, immediate()); cycles = 2; break; case 0xCA: // DEX _X--; _P &= ~(P_ZERO | P_NEGATIVE); if (_X == 0) _P |= P_ZERO; if (_X & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0xCC: // CPY Absolute cmp(_Y, absolute()); cycles = 4; break; case 0xCD: // CMP Absolute cmp(_A, absolute()); cycles = 4; break; case 0xCE: // DEC Absolute dec(absolute()); cycles = 6; break; case 0xD0: // BNE l = immediate_value(); cycles = 2; if (!(_P & P_ZERO)) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0xD1: // CMP (Indirect),Y cmp(_A, addr = indirect_indexed()); cycles = 5 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0xD5: // CMP Zero-page,X cmp(_A, zero_page(_X)); cycles = 4; break; case 0xD6: // DEC Zero-page,X dec(zero_page(_X)); cycles = 6; break; case 0xD8: // CLD _P &= ~(P_DECIMAL); cycles = 2; break; case 0xD9: // CMP Absolute,Y cmp(_A, addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0xDD: // CMP Absolute,X cmp(_A, addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0xDE: // DEC Absolute,X dec(absolute_indexed(_X)); cycles = 7; break; case 0xE0: // CPX Immediate cmp(_X, immediate()); cycles = 2; break; case 0xE1: // SBC (Indirect,X) sbc(indexed_indirect()); cycles = 6; break; case 0xE4: // CPX Zero-page cmp(_X,zero_page(0)); cycles = 3; break; case 0xE5: // SBC Zero-page sbc(zero_page(0)); cycles = 3; break; case 0xE6: // INC Zero-page inc(zero_page(0)); cycles = 5; break; case 0xE8: // INX _X++; _P &= ~(P_ZERO | P_NEGATIVE); if (_X == 0) _P |= P_ZERO; if (_X & 0x80) _P |= P_NEGATIVE; cycles = 2; break; case 0xE9: // SBC Immediate sbc(immediate()); cycles = 2; break; case 0xEA: // NOP cycles = 2; break; case 0xEC: // CPX Absolute cmp(_X,absolute()); cycles = 4; break; case 0xED: // SBC Absolute sbc(absolute()); cycles = 4; break; case 0xEE: // INC Absolute inc(absolute()); cycles = 6; break; case 0xF0: // BEQ l = immediate_value(); cycles = 2; if (_P & P_ZERO) { addr = _PC; _PC = _PC + (int8_t)l; cycles += ((addr&0xFF00) != (_PC&0xFF00))? 2 : 1; } break; case 0xF1: // SBC (Indirect),Y sbc(indirect_indexed()); cycles = 5; break; case 0xF5: // SBC Zero-page,X sbc(zero_page(_X)); cycles = 4; break; case 0xF6: // INC Zero-page,X inc(zero_page(_X)); cycles = 6; break; case 0xF8: // SED fprintf(stderr,"SED HAS BEEN SET!\n"); exit(1); _P |= P_DECIMAL; cycles = 2; break; case 0xF9: // SBC Absolute,Y sbc(addr = absolute_indexed(_Y)); cycles = 4 + ((addr&0xFF00) != ((addr-_Y)&0xFF00))? 1 : 0; break; case 0xFD: // SBC Absolute,X sbc(addr = absolute_indexed(_X)); cycles = 4 + ((addr&0xFF00) != ((addr-_X)&0xFF00))? 1 : 0; break; case 0xFE: // INC Absolute,X inc(absolute_indexed(_X)); cycles = 7; break; default: // Future Exapansion fprintf(stderr,"Illegal instruction!!! %02X\n", _IR); exit(0); break; } clocks += cycles; if (clocks > 1000) { clocks -= 1000; usleep(250); } if (_keydown > 0) _keydown -= cycles; if (_log) { fprintf(_log, "\tS:1%02X A:%d X:%d Y:%d P:%s\n",_S, _A, _X, _Y, status(_P)); for(i=0;i<_widx;i++) { fprintf(_log," %04X -> %02X/%d\n", _wlog[i].addr, _wlog[i].data, _wlog[i].data); } } _widx = 0; if (_timerA1) { _timerA1 -= cycles; if (_timerA1 <= 0) { if (!(_P & P_IRQDIS)) { _HWIRQ = 1; _ics1 |= 0x01; } if (_timerA1L) _timerA1 += _timerA1L; else _timerA1 = 0; } } if (_HWIRQ) { if (_ilog) { _log = _ilog; fprintf(_log, "PC-> %04X", _PC); fprintf(_log, " S:1%02X A:%d X:%d Y:%d P:%s\n",_S, _A, _X, _Y, status(_P)); } _IR = 0; push(_PC>>8); push(_PC&0xFF); push(_P & ~P_BRK); _PC = load(0XFFFF) <<8 | load(0xFFFE); _HWIRQ = 0; } if (_NMI) { _IR = 0; push(_PC>>8); push(_PC&0xFF); push(_P & ~P_BRK); _PC = load(0XFFFB) <<8 | load(0xFFFA); _NMI = 0; } } } void reset() { _IR = 0; _A = 0xAA; _X = _Y = 0; _P = P_BRK; _S = 0xFD; _PC = load(0xFFFD) <<8 | load(0xFFFC); run(); }