public uint Step() { uint cycles = 0; byte opcode; opcode = m_map.Read(m_pc); //http://homepage.ntlworld.com/cyborgsystems/CS_Main/6502/6502.htm if (!m_opcode_methods.ContainsKey(opcode)) { // dump memory //StringBuilder builder = new StringBuilder(); //for (uint i = 0; i < 0xFFFF; i++) //{ // builder.AppendFormat("0x{0:X4} ", i); // for (uint j = 0; j < 0x0F; j++) // { // builder.AppendFormat("0x{0:X2} ", m_map.Read(i)); // i++; // } // builder.Append("\r\n"); //} //Logger(builder.ToString()); throw new NotImplementedException(string.Format("Unimplemented OPCODE 0x{0:X2} at 0x{1:X4}", opcode, m_pc)); } byte?[] bytes = new byte?[3]; for (byte b = 0; b < 3; b++) { if (b < m_opcode_lengths[opcode]) { bytes[b] = m_map.Read(m_pc + b); } else { bytes[b] = null; } } Logger(string.Format("0x{0:X4} 0x{1:X2} {2} {3} ; {4} {5}", m_pc, bytes[0], bytes[1] != null ? string.Format("0x{0:X2}", bytes[1]) : " ", bytes[2] != null ? string.Format("0x{0:X2}", bytes[2]) : " ", m_opcode_names[opcode], m_opcode_modes[opcode])); uint?address = null; switch (m_opcode_modes[opcode]) { case AddressMode.Implied: // do nothing break; case AddressMode.Accumulator: // do nothing break; case AddressMode.Absolute: address = Read_Absolute(); break; case AddressMode.AbsoluteX: address = Read_AbsoluteX(); break; case AddressMode.AbsoluteY: address = Read_AbsoluteY(); break; case AddressMode.IndirectY: address = Read_IndirectY(); break; case AddressMode.Immediate: address = Read_Immediate(); break; case AddressMode.Relative: address = Read_Relative(); break; case AddressMode.ZeroPage: address = Read_ZeroPage(); break; case AddressMode.ZeroPageX: address = Read_ZeroPageX(); break; case AddressMode.ZeroPageY: address = Read_ZeroPageY(); break; default: throw new NotImplementedException(string.Format("Unimplemented Addressing Mode {0}", m_opcode_modes[opcode].ToString())); } // jsr if (opcode == 0x20) { m_pc += m_opcode_lengths[opcode]; } m_opcode_methods[opcode](address); cycles = m_opcode_cycles[opcode]; // not jsr or rts if (opcode != 0x20 && opcode != 0x60) { m_pc += m_opcode_lengths[opcode]; } Logger("CPU\tA: 0x{0:X2}\tP: 0x{1:X2}\tX: 0x{2:X2}\tY: 0x{3:X2}\tSP:0x{4:X4}", m_reg_a, m_reg_p, m_reg_x, m_reg_y, m_sp); return(cycles); }
public Cpu(CpuMap map) { m_map = map; // read pc from fffc lo and fffd hi m_pc = m_map.Read(0xFFFC); m_pc |= (uint)(m_map.Read(0xFFFD)<<8); m_opcode_methods = new Dictionary<byte, Op> { { 0x08, Op_PHP }, { 0x09, Op_ORA }, { 0x10, Op_BPL }, { 0x0A, Op_ASL }, { 0x18, Op_CLC }, { 0x20, Op_JSR }, { 0x28, Op_PLP }, { 0x29, Op_AND }, { 0x38, Op_SEC }, { 0x45, Op_EOR }, { 0x48, Op_PHA }, { 0x4A, Op_LSR }, { 0x56, Op_LSR }, { 0x60, Op_RTS }, { 0x65, Op_ADC }, { 0x68, Op_PLA }, { 0x6A, Op_ROR }, { 0x76, Op_ROR }, { 0x78, Op_SEI }, { 0x84, Op_STY }, { 0x85, Op_STA }, { 0x86, Op_STX }, { 0x88, Op_DEY }, { 0x8A, Op_TXA }, { 0x8C, Op_STY }, { 0x8D, Op_STA }, { 0x8E, Op_STX }, { 0x90, Op_BCC }, { 0x91, Op_STA }, { 0x98, Op_TYA }, { 0x99, Op_STA }, { 0x9A, Op_TXS }, { 0xA0, Op_LDY }, { 0xA2, Op_LDX }, { 0xA4, Op_LDY }, { 0xA5, Op_LDA }, { 0xA6, Op_LDX }, { 0xA9, Op_LDA }, { 0xAA, Op_TAX }, { 0xAD, Op_LDA }, { 0xAE, Op_LDX }, { 0xB0, Op_BCS }, { 0xB1, Op_LDA }, { 0xB5, Op_LDA }, { 0xBD, Op_LDA }, { 0xC6, Op_DEC }, { 0xC8, Op_INY }, { 0xC9, Op_CMP }, { 0xCA, Op_DEX }, { 0xD0, Op_BNE }, { 0xD8, Op_CLD }, { 0xE5, Op_SBC }, { 0xE8, Op_INX }, { 0xF0, Op_BEQ } }; }
public Cpu(CpuMap map) { m_map = map; // read pc from fffc lo and fffd hi m_pc = m_map.Read(0xFFFC); m_pc |= (uint)(m_map.Read(0xFFFD) << 8); m_opcode_methods = new Dictionary <byte, Op> { { 0x08, Op_PHP }, { 0x09, Op_ORA }, { 0x10, Op_BPL }, { 0x0A, Op_ASL }, { 0x18, Op_CLC }, { 0x20, Op_JSR }, { 0x28, Op_PLP }, { 0x29, Op_AND }, { 0x38, Op_SEC }, { 0x45, Op_EOR }, { 0x48, Op_PHA }, { 0x4A, Op_LSR }, { 0x56, Op_LSR }, { 0x60, Op_RTS }, { 0x65, Op_ADC }, { 0x68, Op_PLA }, { 0x6A, Op_ROR }, { 0x76, Op_ROR }, { 0x78, Op_SEI }, { 0x84, Op_STY }, { 0x85, Op_STA }, { 0x86, Op_STX }, { 0x88, Op_DEY }, { 0x8A, Op_TXA }, { 0x8C, Op_STY }, { 0x8D, Op_STA }, { 0x8E, Op_STX }, { 0x90, Op_BCC }, { 0x91, Op_STA }, { 0x98, Op_TYA }, { 0x99, Op_STA }, { 0x9A, Op_TXS }, { 0xA0, Op_LDY }, { 0xA2, Op_LDX }, { 0xA4, Op_LDY }, { 0xA5, Op_LDA }, { 0xA6, Op_LDX }, { 0xA9, Op_LDA }, { 0xAA, Op_TAX }, { 0xAD, Op_LDA }, { 0xAE, Op_LDX }, { 0xB0, Op_BCS }, { 0xB1, Op_LDA }, { 0xB5, Op_LDA }, { 0xBD, Op_LDA }, { 0xC6, Op_DEC }, { 0xC8, Op_INY }, { 0xC9, Op_CMP }, { 0xCA, Op_DEX }, { 0xD0, Op_BNE }, { 0xD8, Op_CLD }, { 0xE5, Op_SBC }, { 0xE8, Op_INX }, { 0xF0, Op_BEQ } }; }