mirror of
https://github.com/zoriya/ComSquare.git
synced 2025-12-19 21:55:11 +00:00
720 lines
34 KiB
C++
720 lines
34 KiB
C++
//
|
|
// Created by anonymus-raccoon on 1/24/20.
|
|
//
|
|
|
|
#ifndef COMSQUARE_CPU_HPP
|
|
#define COMSQUARE_CPU_HPP
|
|
|
|
#include "../Memory/AMemory.hpp"
|
|
#include "../Memory/MemoryBus.hpp"
|
|
#include "../Models/Int24.hpp"
|
|
#include "../Cartridge/Cartridge.hpp"
|
|
#include "../Memory/AMemory.hpp"
|
|
#include "Instruction.hpp"
|
|
|
|
namespace ComSquare::CPU
|
|
{
|
|
//! @brief Struct containing registers for the main CPU.
|
|
struct Registers {
|
|
//! @brief The Accumulator
|
|
union {
|
|
struct {
|
|
uint8_t al;
|
|
uint8_t ah;
|
|
};
|
|
uint16_t a;
|
|
};
|
|
//! @brief The Data Bank Register;
|
|
uint8_t dbr;
|
|
//! @brief The Direct Page register;
|
|
union {
|
|
struct {
|
|
uint8_t dl;
|
|
uint8_t dh;
|
|
};
|
|
uint16_t d;
|
|
};
|
|
union {
|
|
struct {
|
|
//! @brief The Program Counter;
|
|
union {
|
|
struct {
|
|
uint8_t pcl;
|
|
uint8_t pch;
|
|
};
|
|
uint16_t pc;
|
|
};
|
|
//! @brief The Program Bank Register;
|
|
uint8_t pbr;
|
|
};
|
|
//! @brief The current Program Address Counter (does not exist in a snes but is useful here).
|
|
uint24_t pac;
|
|
};
|
|
//! @brief The Stack pointer
|
|
union {
|
|
struct {
|
|
uint8_t sl;
|
|
uint8_t sh;
|
|
};
|
|
uint16_t s;
|
|
};
|
|
//! @brief The X index register
|
|
union {
|
|
struct {
|
|
uint8_t xl;
|
|
uint8_t xh;
|
|
};
|
|
uint16_t x;
|
|
};
|
|
//! @brief The Y index register
|
|
union {
|
|
struct {
|
|
uint8_t yl;
|
|
uint8_t yh;
|
|
};
|
|
uint16_t y;
|
|
};
|
|
|
|
//! @brief The Processor status register;
|
|
union {
|
|
struct {
|
|
//! @brief The Carry flag
|
|
bool c : 1;
|
|
//! @brief The Zero flag
|
|
bool z : 1;
|
|
//! @brief The Interrupt request disable flag
|
|
bool i : 1;
|
|
//! @brief The Decimal mode flag
|
|
bool d : 1;
|
|
//! @brief The indeX register width flag (in native mode only) - 0 = 16 bits mode, 1 = 8 bits mode OR the Break flag (in emulation mode only)
|
|
bool x_b : 1;
|
|
//! @brief The accumulator and Memory width flag (in native mode only) - 0 = 16 bits mode, 1 = 8 bits mode.
|
|
bool m : 1;
|
|
//! @brief The oVerflow flag
|
|
bool v : 1;
|
|
//! @brief The Negative flag
|
|
bool n : 1;
|
|
};
|
|
uint8_t flags;
|
|
} p;
|
|
};
|
|
|
|
//! @brief Struct containing internal registers of the CPU.
|
|
struct InternalRegisters
|
|
{
|
|
//! @brief Interrupt Enable Register
|
|
uint8_t nmitimen;
|
|
|
|
//! @brief IO Port Write Register
|
|
uint8_t wrio;
|
|
|
|
//! @brief Multiplicand Register A
|
|
uint8_t wrmpya;
|
|
//! @brief Multiplicand Register B
|
|
uint8_t wrmpyb;
|
|
|
|
//! @brief Divisor & Dividend Registers (A - Low)
|
|
uint8_t wrdivl;
|
|
//! @brief Divisor & Dividend Registers (A - High)
|
|
uint8_t wrdivh;
|
|
//! @brief Divisor & Dividend Registers (B)
|
|
uint8_t wrdivb;
|
|
|
|
//! @brief IRQ Timer Registers (Horizontal - Low)
|
|
uint8_t htimel;
|
|
//! @brief IRQ Timer Registers (Horizontal - High)
|
|
uint8_t htimeh;
|
|
|
|
//! @brief IRQ Timer Registers (Vertical - Low)
|
|
uint8_t vtimel;
|
|
//! @brief IRQ Timer Registers (Vertical - High)
|
|
uint8_t vtimeh;
|
|
|
|
//! @brief DMA Enable Register
|
|
uint8_t mdmaen;
|
|
|
|
//! @brief HDMA Enable Register
|
|
uint8_t hdmaen;
|
|
|
|
//! @brief ROM Speed Register
|
|
uint8_t memsel;
|
|
|
|
//! @brief Interrupt Flag Registers
|
|
uint8_t rdnmi;
|
|
//! @brief Interrupt Flag Registers - TimeUp
|
|
uint8_t timeup;
|
|
|
|
//! @brief PPU Status Register
|
|
uint8_t hvbjoy;
|
|
|
|
//! @brief IO Port Read Register
|
|
uint8_t rdio;
|
|
|
|
//! @brief Divide Result Registers (can sometimes be used as multiplication result register) - LOW
|
|
uint8_t rddivl;
|
|
//! @brief Divide Result Registers (can sometimes be used as multiplication result register) - HIGH
|
|
uint8_t rddivh;
|
|
|
|
//! @brief Multiplication Result Registers (can sometimes be used as divide result register) - LOW
|
|
uint8_t rdmpyl;
|
|
//! @brief Multiplication Result Registers (can sometimes be used as divide result register) - HIGH
|
|
uint8_t rdmpyh;
|
|
|
|
//! @brief Controller Port Data Registers (Pad 1 - Low)
|
|
uint8_t joy1l;
|
|
//! @brief Controller Port Data Registers (Pad 1 - High)
|
|
uint8_t joy1h;
|
|
|
|
//! @brief Controller Port Data Registers (Pad 2 - Low)
|
|
uint8_t joy2l;
|
|
//! @brief Controller Port Data Registers (Pad 2 - High)
|
|
uint8_t joy2h;
|
|
|
|
//! @brief Controller Port Data Registers (Pad 3 - Low)
|
|
uint8_t joy3l;
|
|
//! @brief Controller Port Data Registers (Pad 3 - High)
|
|
uint8_t joy3h;
|
|
|
|
//! @brief Controller Port Data Registers (Pad 4 - Low)
|
|
uint8_t joy4l;
|
|
//! @brief Controller Port Data Registers (Pad 4 - High)
|
|
uint8_t joy4h;
|
|
};
|
|
|
|
//! @brief The main CPU
|
|
class CPU : public Memory::AMemory {
|
|
protected:
|
|
//! @brief All the registers of the CPU
|
|
Registers _registers{};
|
|
//! @brief Is the CPU running in emulation mode (in 8bits)
|
|
bool _isEmulationMode = true;
|
|
//! @brief Internal registers of the CPU (accessible from the bus via addr $4200 to $421F).
|
|
InternalRegisters _internalRegisters{};
|
|
//! @brief The memory bus to use for read/write.
|
|
std::shared_ptr<Memory::MemoryBus> _bus;
|
|
//! @brief The cartridge header (stored for interrupt vectors..
|
|
Cartridge::Header &_cartridgeHeader;
|
|
|
|
//! @brief True if an addressing mode with an iterator (x, y) has crossed the page. (Used because crossing the page boundary take one more cycle to run certain instructions).
|
|
bool _hasIndexCrossedPageBoundary = false;
|
|
|
|
//! @brief Immediate address mode is specified with a value in 8. (This functions returns the 24bit space address of the value).
|
|
uint24_t _getImmediateAddr8Bits();
|
|
//! @brief Immediate address mode is specified with a value in 8 or 16 bits. The value is 16 bits if the m flag is unset. (This functions returns the 24bit space address of the value).
|
|
uint24_t _getImmediateAddrForA();
|
|
//! @brief Immediate address mode is specified with a value in 8 or 16 bits. The value is 16 bits if the x flag is unset. (This functions returns the 24bit space address of the value).
|
|
uint24_t _getImmediateAddrForX();
|
|
//! @brief The destination is formed by adding the direct page register with the 8-bit address to form an effective address. (This functions returns the 24bit space address of the value).
|
|
uint24_t _getDirectAddr();
|
|
//! @brief The effective address is formed by DBR:<16-bit exp>. (This functions returns the 24bit space address of the value).
|
|
uint24_t _getAbsoluteAddr();
|
|
//! @brief The effective address is the expression. (This functions returns the 24bit space address of the value).
|
|
uint24_t _getAbsoluteLongAddr();
|
|
//! @brief The address is DBR:$(read($($Value + D)) + Y). (This functions returns the 24bit space address of the value).
|
|
uint24_t _getDirectIndirectIndexedYAddr();
|
|
//! @brief This mode is like the previous addressing mode, but the difference is that rather than pulling 2 bytes from the DP address, it pulls 3 bytes to form the effective address.
|
|
uint24_t _getDirectIndirectIndexedYLongAddr();
|
|
//! @brief The direct page address is calculated and added with x. 2 bytes from the dp address combined with DBR will form the effective address.
|
|
uint24_t _getDirectIndirectIndexedXAddr();
|
|
//! @brief The DP address is added to X to form the effective address. The effective address is always in bank 0.
|
|
uint24_t _getDirectIndexedByXAddr();
|
|
//! @brief The DP address is added to Y to form the effective address. The effective address is always in bank 0.
|
|
uint24_t _getDirectIndexedByYAddr();
|
|
//! @brief The absolute expression is added with X and combined with DBR to form the effective address.
|
|
uint24_t _getAbsoluteIndexedByXAddr();
|
|
//! @brief The absolute expression is added with Y and combined with DBR to form the effective address.
|
|
uint24_t _getAbsoluteIndexedByYAddr();
|
|
//! @brief The effective address is formed by adding the <long exp> with X.
|
|
uint24_t _getAbsoluteIndexedByXLongAddr();
|
|
//! @brief 2 bytes are pulled from the <abs exp> to form the effective address.
|
|
uint24_t _getAbsoluteIndirectAddr();
|
|
//! @brief 3 bytes are pulled from the <abs exp> to form the effective address.
|
|
uint24_t _getAbsoluteIndirectLongAddr();
|
|
//! @brief The <abs exp> is added with X, then 2 bytes are pulled from that address to form the new location.
|
|
uint24_t _getAbsoluteIndirectIndexedByXAddr();
|
|
//! @brief 2 bytes are pulled from the direct page address to form the 16-bit address. It is combined with DBR to form a 24-bit effective address.
|
|
uint24_t _getDirectIndirectAddr();
|
|
//! @brief 3 bytes are pulled from the direct page address to form an effective address.
|
|
uint24_t _getDirectIndirectLongAddr();
|
|
//! @brief The stack register is added to the <8-bit exp> to form the effective address.
|
|
uint24_t _getStackRelativeAddr();
|
|
//! @brief The <8-bit exp> is added to S and combined with DBR to form the base address. Y is added to the base address to form the effective address.
|
|
uint24_t _getStackRelativeIndirectIndexedYAddr();
|
|
|
|
|
|
//! @brief Push 8 bits of data to the stack.
|
|
void _push(uint8_t data);
|
|
//! @brief Push 16 bits of data to the stack.
|
|
void _push(uint16_t data);
|
|
//! @brief Pop 8 bits of data from the stack.
|
|
uint8_t _pop();
|
|
//! @brief Pop 16 bits of data from the stack.
|
|
uint16_t _pop16();
|
|
|
|
//! @brief Return the data at the program bank concatenated with the program counter. It also increment the program counter (the program bank is not incremented on overflows).
|
|
uint8_t readPC();
|
|
|
|
//! @brief Execute a single instruction.
|
|
//! @return The number of CPU cycles that the instruction took.
|
|
virtual unsigned _executeInstruction(uint8_t opcode);
|
|
|
|
//! @brief Get the parameter address of an instruction from it's addressing mode.
|
|
//! @info The current program counter should point to the instruction's opcode + 1.
|
|
//! @return The address of the data to read on the instruction.
|
|
uint24_t _getValueAddr(Instruction &instruction);
|
|
|
|
//! @brief Break instruction - Causes a software break. The PC is loaded from a vector table.
|
|
int BRK(uint24_t, AddressingMode);
|
|
//! @brief Co-Processor Enable instruction - Causes a software break. The PC is loaded from a vector table.
|
|
int COP(uint24_t, AddressingMode);
|
|
//! @brief Return from Interrupt - Used to return from a interrupt handler.
|
|
int RTI(uint24_t, AddressingMode);
|
|
//! @brief Add with carry - Adds operand to the Accumulator; adds an additional 1 if carry is set.
|
|
int ADC(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Store the accumulator to memory.
|
|
int STA(uint24_t addr, AddressingMode);
|
|
//! @brief Store the index register X to memory.
|
|
int STX(uint24_t addr, AddressingMode);
|
|
//! @brief Store the index register Y to memory.
|
|
int STY(uint24_t addr, AddressingMode);
|
|
//! @brief Store zero to the memory.
|
|
int STZ(uint24_t addr, AddressingMode);
|
|
//! @brief Load the accumulator from memory.
|
|
int LDA(uint24_t addr, AddressingMode);
|
|
//! @brief Load the X index register from memory.
|
|
int LDX(uint24_t addr, AddressingMode);
|
|
//! @brief Load the Y index register from memory.
|
|
int LDY(uint24_t addr, AddressingMode);
|
|
//! @brief Set status bits.
|
|
int SEP(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Reset status bits.
|
|
int REP(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Jump to subroutine
|
|
int JSR(uint24_t addr, AddressingMode);
|
|
//! @brief Jump to subroutine (long)
|
|
int JSL(uint24_t addr, AddressingMode);
|
|
//! @brief Push the accumulator to the stack.
|
|
int PHA(uint24_t, AddressingMode);
|
|
//! @brief Push the data bank register to the stack.
|
|
int PHB(uint24_t, AddressingMode);
|
|
//! @brief Push the direct page register to the stack.
|
|
int PHD(uint24_t, AddressingMode);
|
|
//! @brief Push the program bank register to the stack.
|
|
int PHK(uint24_t, AddressingMode);
|
|
//! @brief Push the processor status register to the stack.
|
|
int PHP(uint24_t, AddressingMode);
|
|
//! @brief Push the x index register to the stack.
|
|
int PHX(uint24_t, AddressingMode);
|
|
//! @brief Push the y index register to the stack.
|
|
int PHY(uint24_t, AddressingMode);
|
|
//! @brief Pull the accumulator to the stack.
|
|
int PLA(uint24_t, AddressingMode);
|
|
//! @brief Pull the data bank register to the stack.
|
|
int PLB(uint24_t, AddressingMode);
|
|
//! @brief Pull the direct page register to the stack.
|
|
int PLD(uint24_t, AddressingMode);
|
|
//! @brief Pull the processor status register to the stack.
|
|
int PLP(uint24_t, AddressingMode);
|
|
//! @brief Pull the x index register to the stack.
|
|
int PLX(uint24_t, AddressingMode);
|
|
//! @brief Pull the y index register to the stack.
|
|
int PLY(uint24_t, AddressingMode);
|
|
//! @brief Clear the carry flag.
|
|
int CLC(uint24_t, AddressingMode);
|
|
//! @brief Clear the Interrupt Disable flag.
|
|
int CLI(uint24_t, AddressingMode);
|
|
//! @brief Clear the decimal flag.
|
|
int CLD(uint24_t, AddressingMode);
|
|
//! @brief Clear the overflow flag.
|
|
int CLV(uint24_t, AddressingMode);
|
|
//! @brief Set the carry Flag.
|
|
int SEC(uint24_t, AddressingMode);
|
|
//! @brief Set the decimal flag.
|
|
int SED(uint24_t, AddressingMode);
|
|
//! @brief Set the Interrupt Disable flag.
|
|
int SEI(uint24_t, AddressingMode);
|
|
//! @brief Exchange Carry and Emulation Flags
|
|
int XCE(uint24_t, AddressingMode);
|
|
//! @brief And accumulator with memory.
|
|
int AND(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Subtract with Borrow from Accumulator.
|
|
int SBC(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Transfer A to X
|
|
int TAX(uint24_t, AddressingMode);
|
|
//! @brief Transfer A to Y
|
|
int TAY(uint24_t, AddressingMode);
|
|
//! @brief Transfer X to SP
|
|
int TXS(uint24_t, AddressingMode);
|
|
//! @brief Increment the X register
|
|
int INX(uint24_t, AddressingMode);
|
|
//! @brief Increment the Y register
|
|
int INY(uint24_t, AddressingMode);
|
|
//! @brief Compare the X register with the memory
|
|
int CPX(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Compare the Y register with the memory
|
|
int CPY(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if carry clear
|
|
int BCC(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if carry set
|
|
int BCS(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if equal
|
|
int BEQ(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if not equal
|
|
int BNE(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if minus
|
|
int BMI(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if plus
|
|
int BPL(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if Overflow Clear
|
|
int BVC(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch if Overflow Set
|
|
int BVS(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch always
|
|
int BRA(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Branch always long
|
|
int BRL(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Jump.
|
|
int JMP(uint24_t valueAddr, AddressingMode);
|
|
//! @brief Long jump.
|
|
int JML(uint24_t valueAddr, AddressingMode);
|
|
//! @brief No OP.
|
|
int NOP(uint24_t, AddressingMode);
|
|
//! @brief Decrement the X register.
|
|
int DEX(uint24_t, AddressingMode);
|
|
//! @brief Decrement the Y register.
|
|
int DEY(uint24_t, AddressingMode);
|
|
//! @brief Or accumulator with memory.
|
|
int ORA(uint24_t valueAddr, AddressingMode mode);
|
|
//! @brief Return from subroutine.
|
|
int RTS(uint24_t, AddressingMode);
|
|
//! @brief Return from subroutine long.
|
|
int RTL(uint24_t, AddressingMode);
|
|
//! @brief Compare Accumulator with Memory.
|
|
int CMP(uint24_t, AddressingMode);
|
|
//! @brief Increment
|
|
int INC(uint24_t, AddressingMode);
|
|
//! @brief Decrement
|
|
int DEC(uint24_t, AddressingMode);
|
|
//! @brief XOR, Exclusive OR accumulator with memory.
|
|
int EOR(uint24_t, AddressingMode);
|
|
//! @brief Transfer 16 bit A to DP
|
|
int TCD(uint24_t, AddressingMode);
|
|
//! @brief Transfer 16 bit A to SP
|
|
int TCS(uint24_t, AddressingMode);
|
|
//! @brief Transfer DP to 16 bit A
|
|
int TDC(uint24_t, AddressingMode);
|
|
//! @brief Transfer DP to 16 bit A
|
|
int TSC(uint24_t, AddressingMode);
|
|
//! @brief Transfer SP to X
|
|
int TSX(uint24_t, AddressingMode);
|
|
//! @brief Transfer X to A
|
|
int TXA(uint24_t, AddressingMode);
|
|
//! @brief Transfer Y to A
|
|
int TYA(uint24_t, AddressingMode);
|
|
//! @brief Transfer X to Y
|
|
int TXY(uint24_t, AddressingMode);
|
|
//! @brief Transfer Y to X
|
|
int TYX(uint24_t, AddressingMode);
|
|
//! @brief Test and Set Memory Bits Against Accumulator
|
|
int TSB(uint24_t, AddressingMode);
|
|
//! @brief Exchange the B and A Accumulators
|
|
int XBA(uint24_t, AddressingMode);
|
|
|
|
//! @brief All the instructions of the CPU.
|
|
//! @info Instructions are indexed by their opcode
|
|
Instruction _instructions[0x100] = {
|
|
{&CPU::BRK, 7, "brk", AddressingMode::Immediate8bits, 2}, // 00
|
|
{&CPU::ORA, 6, "ora", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 01
|
|
{&CPU::COP, 7, "cop", AddressingMode::Immediate8bits, 2}, // 02
|
|
{&CPU::ORA, 4, "ora", AddressingMode::StackRelative, 2}, // 03
|
|
{&CPU::TSB, 5, "tsb", AddressingMode::DirectPage, 2}, // 04
|
|
{&CPU::ORA, 3, "ora", AddressingMode::DirectPage, 2}, // 05
|
|
{&CPU::BRK, 7, "asl #-#", AddressingMode::Implied, 2}, // 06
|
|
{&CPU::ORA, 6, "ora", AddressingMode::DirectPageIndirectLong, 2}, // 07
|
|
{&CPU::PHP, 3, "php", AddressingMode::Implied, 3}, // 08
|
|
{&CPU::ORA, 2, "ora", AddressingMode::ImmediateForA, 2}, // 09
|
|
{&CPU::BRK, 7, "asl #-#", AddressingMode::Implied, 2}, // 0A
|
|
{&CPU::PHD, 4, "phd", AddressingMode::Implied, 1}, // 0B
|
|
{&CPU::TSB, 6, "tsb", AddressingMode::Absolute, 3}, // 0C
|
|
{&CPU::ORA, 3, "ora", AddressingMode::Absolute, 4}, // 0D
|
|
{&CPU::BRK, 7, "asl #-#", AddressingMode::Implied, 2}, // 0E
|
|
{&CPU::ORA, 5, "ora", AddressingMode::AbsoluteLong, 5}, // 0F
|
|
{&CPU::BPL, 7, "bpl", AddressingMode::Immediate8bits, 2}, // 10
|
|
{&CPU::ORA, 5, "ora", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 11
|
|
{&CPU::ORA, 5, "ora", AddressingMode::DirectPageIndirect, 2}, // 12
|
|
{&CPU::ORA, 7, "ora", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 13
|
|
{&CPU::BRK, 7, "trb #-#", AddressingMode::Implied, 2}, // 14
|
|
{&CPU::ORA, 4, "ora", AddressingMode::DirectPageIndexedByX, 2}, // 15
|
|
{&CPU::BRK, 7, "asl #-#", AddressingMode::Implied, 2}, // 16
|
|
{&CPU::ORA, 6, "ora", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // 17
|
|
{&CPU::CLC, 2, "clc", AddressingMode::Implied, 1}, // 18
|
|
{&CPU::ORA, 4, "ora", AddressingMode::AbsoluteIndexedByY, 3}, // 19
|
|
{&CPU::INC, 2, "inc", AddressingMode::Implied, 1}, // 1A
|
|
{&CPU::TCS, 2, "tcs", AddressingMode::Implied, 1}, // 1B
|
|
{&CPU::BRK, 7, "trb #-#", AddressingMode::Implied, 2}, // 1C
|
|
{&CPU::ORA, 4, "ora", AddressingMode::AbsoluteIndexedByX, 3}, // 1D
|
|
{&CPU::BRK, 7, "asl #-#", AddressingMode::Implied, 2}, // 1E
|
|
{&CPU::ORA, 5, "ora", AddressingMode::AbsoluteIndexedByXLong, 4}, // 1F
|
|
{&CPU::JSR, 6, "jsr", AddressingMode::Absolute, 3}, // 20
|
|
{&CPU::AND, 6, "and", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 21
|
|
{&CPU::JSL, 8, "jsl", AddressingMode::AbsoluteLong, 4}, // 22
|
|
{&CPU::AND, 4, "and", AddressingMode::StackRelative, 2}, // 23
|
|
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 24
|
|
{&CPU::AND, 3, "and", AddressingMode::DirectPage, 2}, // 25
|
|
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 26
|
|
{&CPU::AND, 6, "and", AddressingMode::DirectPageIndirectLong, 2}, // 27
|
|
{&CPU::PLP, 4, "plp", AddressingMode::Implied, 1}, // 28
|
|
{&CPU::AND, 2, "and", AddressingMode::ImmediateForA, 2}, // 29
|
|
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 2A
|
|
{&CPU::PLD, 5, "pld", AddressingMode::Implied, 1}, // 2B
|
|
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 2C
|
|
{&CPU::AND, 4, "and", AddressingMode::Absolute, 3}, // 2D
|
|
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 2E
|
|
{&CPU::AND, 5, "and", AddressingMode::AbsoluteLong, 4}, // 2F
|
|
{&CPU::BMI, 2, "bmi", AddressingMode::Immediate8bits, 2}, // 30
|
|
{&CPU::AND, 5, "and", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 31
|
|
{&CPU::AND, 5, "and", AddressingMode::DirectPageIndirect, 2}, // 32
|
|
{&CPU::AND, 7, "and", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 33
|
|
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 34
|
|
{&CPU::AND, 4, "and", AddressingMode::DirectPageIndexedByX, 2}, // 35
|
|
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 36
|
|
{&CPU::AND, 6, "and", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // 37
|
|
{&CPU::SEC, 2, "sec", AddressingMode::Implied, 1}, // 38
|
|
{&CPU::AND, 4, "and", AddressingMode::AbsoluteIndexedByY, 3}, // 39
|
|
{&CPU::DEC, 2, "dec", AddressingMode::Implied, 1}, // 3A
|
|
{&CPU::TSC, 2, "tsc", AddressingMode::Implied, 1}, // 3B
|
|
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 3C
|
|
{&CPU::AND, 4, "and", AddressingMode::AbsoluteIndexedByX, 3}, // 3D
|
|
{&CPU::BRK, 7, "rol #-#", AddressingMode::Implied, 2}, // 3E
|
|
{&CPU::AND, 5, "and", AddressingMode::AbsoluteIndexedByXLong, 4}, // 3F
|
|
{&CPU::RTI, 6, "rti", AddressingMode::Implied, 1}, // 40
|
|
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 41
|
|
{&CPU::BRK, 7, "wdm #-#", AddressingMode::Implied, 2}, // 42
|
|
{&CPU::EOR, 4, "eor", AddressingMode::StackRelative, 2}, // 43
|
|
{&CPU::BRK, 7, "mvp #-#", AddressingMode::Implied, 2}, // 44
|
|
{&CPU::EOR, 3, "eor", AddressingMode::DirectPage, 2}, // 45
|
|
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 46
|
|
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectLong, 2}, // 47
|
|
{&CPU::PHA, 3, "pha", AddressingMode::Implied, 1}, // 48
|
|
{&CPU::EOR, 2, "eor", AddressingMode::ImmediateForA, 2}, // 49
|
|
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 4A
|
|
{&CPU::PHK, 3, "phk", AddressingMode::Implied, 1}, // 4B
|
|
{&CPU::JMP, 3, "jmp", AddressingMode::Absolute, 3}, // 4C
|
|
{&CPU::EOR, 4, "eor", AddressingMode::Absolute, 3}, // 4D
|
|
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 4E
|
|
{&CPU::EOR, 5, "eor", AddressingMode::AbsoluteLong, 4}, // 4F
|
|
{&CPU::BVC, 2, "bvc", AddressingMode::Immediate8bits, 2}, // 50
|
|
{&CPU::EOR, 5, "eor", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 51
|
|
{&CPU::EOR, 5, "eor", AddressingMode::DirectPageIndirect, 2}, // 52
|
|
{&CPU::EOR, 4, "eor", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 53
|
|
{&CPU::BRK, 7, "mvn #-#", AddressingMode::Implied, 2}, // 54
|
|
{&CPU::EOR, 4, "eor", AddressingMode::DirectPageIndexedByX, 2}, // 55
|
|
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 56
|
|
{&CPU::EOR, 6, "eor", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // 57
|
|
{&CPU::CLI, 2, "cli", AddressingMode::Implied, 1}, // 58
|
|
{&CPU::EOR, 4, "eor", AddressingMode::AbsoluteIndexedByY, 3}, // 59
|
|
{&CPU::PHY, 3, "phy", AddressingMode::Implied, 1}, // 5A
|
|
{&CPU::TCD, 2, "tcd", AddressingMode::Implied, 1}, // 5B
|
|
{&CPU::JML, 4, "jml", AddressingMode::Implied, 4}, // 5C
|
|
{&CPU::EOR, 4, "eor", AddressingMode::AbsoluteIndexedByX, 3}, // 5D
|
|
{&CPU::BRK, 7, "lsr #-#", AddressingMode::Implied, 2}, // 5E
|
|
{&CPU::EOR, 5, "eor", AddressingMode::AbsoluteIndexedByXLong, 4}, // 5F
|
|
{&CPU::RTL, 6, "rtl", AddressingMode::Implied, 1}, // 60
|
|
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 61
|
|
{&CPU::BRK, 7, "per #-#", AddressingMode::Implied, 2}, // 62
|
|
{&CPU::ADC, 4, "adc", AddressingMode::StackRelative, 2}, // 63
|
|
{&CPU::STZ, 3, "stz", AddressingMode::DirectPage, 2}, // 64
|
|
{&CPU::ADC, 3, "adc", AddressingMode::DirectPage, 2}, // 65
|
|
{&CPU::BRK, 7, "ror #-#", AddressingMode::Implied, 2}, // 66
|
|
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectLong, 2}, // 67
|
|
{&CPU::PLA, 4, "pla", AddressingMode::Implied, 1}, // 68
|
|
{&CPU::ADC, 2, "adc", AddressingMode::ImmediateForA, 2}, // 69
|
|
{&CPU::BRK, 7, "ror #-#", AddressingMode::Implied, 2}, // 6A
|
|
{&CPU::RTS, 6, "rts", AddressingMode::Implied, 1}, // 6B
|
|
{&CPU::JMP, 5, "jmp", AddressingMode::AbsoluteIndirect, 3}, // 6C
|
|
{&CPU::ADC, 4, "adc", AddressingMode::Absolute, 3}, // 6D
|
|
{&CPU::BRK, 7, "ror #-#", AddressingMode::Implied, 2}, // 6E
|
|
{&CPU::ADC, 5, "adc", AddressingMode::AbsoluteLong, 4}, // 6F
|
|
{&CPU::BVS, 2, "bvs", AddressingMode::Immediate8bits, 2}, // 70
|
|
{&CPU::ADC, 5, "adc", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 71
|
|
{&CPU::ADC, 5, "adc", AddressingMode::DirectPageIndirect, 2}, // 72
|
|
{&CPU::ADC, 7, "adc", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 73
|
|
{&CPU::STZ, 4, "stz", AddressingMode::DirectPageIndexedByX, 2}, // 74
|
|
{&CPU::ADC, 4, "adc", AddressingMode::DirectPageIndexedByX, 2}, // 75
|
|
{&CPU::BRK, 7, "ror #-#", AddressingMode::Implied, 2}, // 76
|
|
{&CPU::ADC, 6, "adc", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 77
|
|
{&CPU::SEI, 2, "sei", AddressingMode::Implied, 1}, // 78
|
|
{&CPU::ADC, 4, "adc", AddressingMode::AbsoluteIndexedByY, 2}, // 79
|
|
{&CPU::PLY, 4, "ply", AddressingMode::Implied, 1}, // 7A
|
|
{&CPU::TDC, 2, "tdc", AddressingMode::Implied, 1}, // 7B
|
|
{&CPU::JMP, 6, "jmp", AddressingMode::AbsoluteIndirectIndexedByX, 3}, // 7C
|
|
{&CPU::ADC, 4, "adc", AddressingMode::AbsoluteIndexedByX, 3}, // 7D
|
|
{&CPU::BRK, 7, "ror #-#", AddressingMode::Implied, 2}, // 7E
|
|
{&CPU::ADC, 5, "adc", AddressingMode::AbsoluteIndexedByXLong, 4}, // 7F
|
|
{&CPU::BRA, 3, "bra", AddressingMode::Immediate8bits, 2}, // 80
|
|
{&CPU::STA, 6, "sta", AddressingMode::DirectPageIndexedByX, 2}, // 81
|
|
{&CPU::BRL, 4, "brl", AddressingMode::Absolute, 3}, // 82
|
|
{&CPU::STA, 4, "sta", AddressingMode::StackRelative, 2}, // 83
|
|
{&CPU::STY, 3, "sty", AddressingMode::DirectPage, 2}, // 84
|
|
{&CPU::STA, 3, "sta", AddressingMode::DirectPage, 2}, // 85
|
|
{&CPU::STX, 3, "stx", AddressingMode::DirectPage, 2}, // 86
|
|
{&CPU::STA, 6, "sta", AddressingMode::DirectPageIndirectLong, 2}, // 87
|
|
{&CPU::DEY, 2, "dey", AddressingMode::Implied, 1}, // 88
|
|
{&CPU::BRK, 7, "bit #-#", AddressingMode::Implied, 2}, // 89
|
|
{&CPU::TXA, 2, "txa", AddressingMode::Implied, 2}, // 8A
|
|
{&CPU::PHB, 3, "phb", AddressingMode::Implied, 1}, // 8B
|
|
{&CPU::STY, 4, "sty", AddressingMode::Absolute, 3}, // 8C
|
|
{&CPU::STA, 4, "sta", AddressingMode::Absolute, 3}, // 8D
|
|
{&CPU::STX, 4, "stx", AddressingMode::Absolute, 3}, // 8E
|
|
{&CPU::STA, 5, "sta", AddressingMode::AbsoluteLong, 4}, // 8F
|
|
{&CPU::BCC, 2, "bcc", AddressingMode::Immediate8bits, 2}, // 90
|
|
{&CPU::STA, 6, "sta", AddressingMode::DirectPageIndirectIndexedByY, 2}, // 91
|
|
{&CPU::STA, 5, "sta", AddressingMode::DirectPageIndirect, 2}, // 92
|
|
{&CPU::STA, 7, "sta", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // 93
|
|
{&CPU::STY, 4, "sty", AddressingMode::DirectPageIndirectIndexedByX, 2}, // 94
|
|
{&CPU::STA, 4, "sta", AddressingMode::DirectPageIndexedByX, 2}, // 95
|
|
{&CPU::STX, 4, "stx", AddressingMode::DirectPageIndexedByY, 2}, // 96
|
|
{&CPU::STA, 6, "sta", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // 97
|
|
{&CPU::TYA, 2, "tya", AddressingMode::Implied, 1}, // 98
|
|
{&CPU::STA, 5, "sta", AddressingMode::AbsoluteIndexedByY, 3}, // 99
|
|
{&CPU::TXS, 2, "txs", AddressingMode::Implied, 1}, // 9A
|
|
{&CPU::TXY, 2, "txy", AddressingMode::Implied, 1}, // 9B
|
|
{&CPU::STZ, 4, "stz", AddressingMode::Absolute, 3}, // 9C
|
|
{&CPU::STA, 5, "sta", AddressingMode::AbsoluteIndexedByX, 3}, // 9D
|
|
{&CPU::STZ, 5, "stz", AddressingMode::AbsoluteIndexedByX, 3}, // 9E
|
|
{&CPU::STA, 5, "sta", AddressingMode::AbsoluteIndexedByXLong, 4}, // 9F
|
|
{&CPU::LDY, 2, "ldy", AddressingMode::ImmediateForX, 2}, // A0
|
|
{&CPU::LDA, 6, "lda", AddressingMode::DirectPageIndirectIndexedByX, 2}, // A1
|
|
{&CPU::LDX, 2, "ldx", AddressingMode::ImmediateForX, 2}, // A2
|
|
{&CPU::LDA, 4, "lda", AddressingMode::StackRelative, 2}, // A3
|
|
{&CPU::LDY, 3, "ldy", AddressingMode::DirectPage, 2}, // A4
|
|
{&CPU::LDA, 3, "lda", AddressingMode::DirectPage, 2}, // A5
|
|
{&CPU::LDX, 3, "ldx", AddressingMode::DirectPage, 2}, // A6
|
|
{&CPU::LDA, 6, "lda", AddressingMode::DirectPageIndirectLong, 2}, // A7
|
|
{&CPU::TAY, 2, "tay", AddressingMode::Implied, 1}, // A8
|
|
{&CPU::LDA, 2, "lda", AddressingMode::ImmediateForA, 2}, // A9
|
|
{&CPU::TAX, 2, "tax", AddressingMode::Implied, 1}, // AA
|
|
{&CPU::BRK, 7, "trb #-#", AddressingMode::Implied, 2}, // AB
|
|
{&CPU::LDY, 4, "ldy", AddressingMode::Absolute, 4}, // AC
|
|
{&CPU::LDA, 4, "lda", AddressingMode::Absolute, 3}, // AD
|
|
{&CPU::LDX, 4, "ldx", AddressingMode::Absolute, 3}, // AE
|
|
{&CPU::LDA, 5, "lda", AddressingMode::AbsoluteLong, 4}, // AF
|
|
{&CPU::BCS, 2, "bcs", AddressingMode::Immediate8bits, 2}, // B0
|
|
{&CPU::LDA, 5, "lda", AddressingMode::DirectPageIndirectIndexedByY, 2}, // B1
|
|
{&CPU::LDA, 5, "lda", AddressingMode::DirectPageIndirect, 2}, // B2
|
|
{&CPU::LDA, 7, "lda", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // B3
|
|
{&CPU::LDY, 4, "ldy", AddressingMode::DirectPageIndexedByX, 2}, // B4
|
|
{&CPU::LDA, 4, "lda", AddressingMode::DirectPageIndexedByX, 2}, // B5
|
|
{&CPU::LDX, 4, "ldx", AddressingMode::DirectPageIndexedByY, 2}, // B6
|
|
{&CPU::LDA, 6, "lda", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // B7
|
|
{&CPU::CLV, 7, "clv", AddressingMode::Implied, 1}, // B8
|
|
{&CPU::LDA, 4, "lda", AddressingMode::AbsoluteIndexedByY, 3}, // B9
|
|
{&CPU::TSX, 2, "tsx", AddressingMode::Implied, 1}, // BA
|
|
{&CPU::TYX, 2, "tyx", AddressingMode::Implied, 1}, // BB
|
|
{&CPU::LDY, 4, "ldy", AddressingMode::AbsoluteIndexedByX, 3}, // BC
|
|
{&CPU::LDA, 4, "lda", AddressingMode::AbsoluteIndexedByX, 3}, // BD
|
|
{&CPU::LDX, 4, "ldx", AddressingMode::AbsoluteIndexedByY, 3}, // BE
|
|
{&CPU::LDA, 5, "lda", AddressingMode::AbsoluteIndexedByXLong, 4}, // BF
|
|
{&CPU::CPY, 2, "cpy", AddressingMode::ImmediateForX, 2}, // C0
|
|
{&CPU::CMP, 6, "cmp", AddressingMode::DirectPageIndirectIndexedByX, 2}, // C1
|
|
{&CPU::REP, 3, "rep", AddressingMode::Immediate8bits, 2}, // C2
|
|
{&CPU::CMP, 4, "cmp", AddressingMode::StackRelative, 2}, // C3
|
|
{&CPU::CPY, 3, "cpy", AddressingMode::DirectPage, 2}, // C4
|
|
{&CPU::CMP, 3, "cmp", AddressingMode::DirectPage, 2}, // C5
|
|
{&CPU::DEC, 5, "dec", AddressingMode::DirectPage, 2}, // C6
|
|
{&CPU::CMP, 6, "cmp", AddressingMode::DirectPageIndirectLong, 2}, // C7
|
|
{&CPU::INY, 2, "iny", AddressingMode::Implied, 1}, // C8
|
|
{&CPU::CMP, 2, "cmp", AddressingMode::ImmediateForA, 2}, // C9
|
|
{&CPU::DEX, 2, "dex", AddressingMode::Implied, 1}, // CA
|
|
{&CPU::BRK, 7, "wai #-#", AddressingMode::Implied, 2}, // CB
|
|
{&CPU::CPY, 4, "cpy", AddressingMode::Absolute, 3}, // CC
|
|
{&CPU::CMP, 4, "cmp", AddressingMode::Absolute, 3}, // CD
|
|
{&CPU::DEC, 6, "dec", AddressingMode::Absolute, 3}, // CE
|
|
{&CPU::CMP, 6, "cmp", AddressingMode::AbsoluteLong, 4}, // CF
|
|
{&CPU::BNE, 2, "bne", AddressingMode::Immediate8bits, 2}, // D0
|
|
{&CPU::CMP, 5, "cmp", AddressingMode::DirectPageIndirectIndexedByY, 2}, // D1
|
|
{&CPU::CMP, 5, "cmp", AddressingMode::DirectPageIndirect, 2}, // D2
|
|
{&CPU::CMP, 7, "cmp", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // D3
|
|
{&CPU::BRK, 7, "pei #-#", AddressingMode::Implied, 2}, // D4
|
|
{&CPU::CMP, 4, "cmp", AddressingMode::DirectPageIndexedByX, 2}, // D5
|
|
{&CPU::DEC, 6, "dec", AddressingMode::DirectPageIndexedByX, 2}, // D6
|
|
{&CPU::CMP, 6, "cmp", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // D7
|
|
{&CPU::CLD, 2, "cld", AddressingMode::Implied, 2}, // D8
|
|
{&CPU::CMP, 4, "cmp", AddressingMode::AbsoluteIndexedByY, 3}, // D9
|
|
{&CPU::PHX, 3, "phx", AddressingMode::Implied, 1}, // DA
|
|
{&CPU::BRK, 7, "stp #-#", AddressingMode::Implied, 2}, // DB
|
|
{&CPU::JML, 7, "jml", AddressingMode::AbsoluteIndirectLong, 2}, // DC
|
|
{&CPU::CMP, 4, "cmp", AddressingMode::AbsoluteIndexedByX, 3}, // DD
|
|
{&CPU::DEC, 7, "dec", AddressingMode::AbsoluteIndexedByX, 3}, // DE
|
|
{&CPU::CMP, 5, "cmp", AddressingMode::AbsoluteIndexedByXLong, 4}, // DF
|
|
{&CPU::CPX, 2, "cpx", AddressingMode::ImmediateForX, 2}, // E0
|
|
{&CPU::SBC, 6, "sbc", AddressingMode::DirectPageIndirectIndexedByX, 2}, // E1
|
|
{&CPU::SEP, 3, "sep", AddressingMode::Immediate8bits, 2}, // E2
|
|
{&CPU::SBC, 4, "sbc", AddressingMode::StackRelative, 2}, // E3
|
|
{&CPU::CPX, 3, "cpx", AddressingMode::DirectPage, 2}, // E4
|
|
{&CPU::SBC, 3, "sbc", AddressingMode::DirectPage, 2}, // E5
|
|
{&CPU::INC, 5, "inc", AddressingMode::DirectPage, 2}, // E6
|
|
{&CPU::SBC, 6, "sbc", AddressingMode::DirectPageIndirectLong, 2}, // E7
|
|
{&CPU::INX, 2, "inx", AddressingMode::Implied, 1}, // E8
|
|
{&CPU::SBC, 2, "sbc", AddressingMode::ImmediateForA, 2}, // E9
|
|
{&CPU::NOP, 2, "nop", AddressingMode::Implied, 1}, // EA
|
|
{&CPU::XBA, 3, "xba", AddressingMode::Implied, 1}, // EB
|
|
{&CPU::CPX, 4, "cpx", AddressingMode::Absolute, 3}, // EC
|
|
{&CPU::SBC, 4, "sbc", AddressingMode::Absolute, 3}, // ED
|
|
{&CPU::INC, 6, "inc", AddressingMode::Absolute, 3}, // EE
|
|
{&CPU::SBC, 5, "sbc", AddressingMode::AbsoluteLong, 4}, // EF
|
|
{&CPU::BEQ, 2, "beq", AddressingMode::Immediate8bits, 2}, // F0
|
|
{&CPU::SBC, 5, "sbc", AddressingMode::DirectPageIndirectIndexedByY, 2}, // F1
|
|
{&CPU::SBC, 5, "sbc", AddressingMode::DirectPageIndirect, 2}, // F2
|
|
{&CPU::SBC, 7, "sbc", AddressingMode::StackRelativeIndirectIndexedByY, 2}, // F3
|
|
{&CPU::BRK, 7, "pea #-#", AddressingMode::Implied, 2}, // F4
|
|
{&CPU::SBC, 4, "sbc", AddressingMode::DirectPageIndexedByX, 2}, // F5
|
|
{&CPU::INC, 6, "inc", AddressingMode::DirectPageIndexedByX, 2}, // F6
|
|
{&CPU::SBC, 6, "sbc", AddressingMode::DirectPageIndirectIndexedByYLong, 2}, // F7
|
|
{&CPU::SED, 2, "sed", AddressingMode::Implied, 1}, // F8
|
|
{&CPU::SBC, 4, "sbc", AddressingMode::AbsoluteIndexedByY, 3}, // F9
|
|
{&CPU::PLX, 4, "plx", AddressingMode::Implied, 1}, // FA
|
|
{&CPU::XCE, 2, "xce", AddressingMode::Implied, 1}, // FB
|
|
{&CPU::JSR, 8, "jsr", AddressingMode::AbsoluteIndirectIndexedByX, 3}, // FC
|
|
{&CPU::SBC, 4, "sbc", AddressingMode::AbsoluteIndexedByX, 3}, // FD
|
|
{&CPU::INC, 7, "inc", AddressingMode::AbsoluteIndexedByX, 3}, // FE
|
|
{&CPU::SBC, 5, "sbc", AddressingMode::AbsoluteIndexedByXLong, 4}, // FF
|
|
};
|
|
public:
|
|
explicit CPU(std::shared_ptr<Memory::MemoryBus> bus, Cartridge::Header &cartridgeHeader);
|
|
CPU(const CPU &) = default;
|
|
CPU &operator=(const CPU &) = delete;
|
|
~CPU() override = default;
|
|
//! @brief This function continue to execute the Cartridge code.
|
|
//! @return The number of CPU cycles that elapsed
|
|
virtual unsigned update();
|
|
//! @brief Read from the internal CPU register.
|
|
//! @param addr The address to read from. The address 0x0 should refer to the first byte of the register.
|
|
//! @throw InvalidAddress will be thrown if the address is more than $1F (the number of register).
|
|
//! @return Return the value of the register.
|
|
uint8_t read(uint24_t addr) override;
|
|
//! @brief Write data to the internal CPU register.
|
|
//! @param addr The address to write to. The address 0x0 should refer to the first byte of register.
|
|
//! @param data The new value of the register.
|
|
//! @throw InvalidAddress will be thrown if the address is more than $1F (the number of register).
|
|
void write(uint24_t addr, uint8_t data) override;
|
|
|
|
//! @brief Get the name of this accessor (used for debug purpose)
|
|
std::string getName() override;
|
|
|
|
//! @brief Get the component of this accessor (used for debug purpose)
|
|
Component getComponent() override;
|
|
|
|
//! @brief Reset interrupt - Called on boot and when the reset button is pressed.
|
|
virtual int RESB();
|
|
|
|
//! @brief Return true if the CPU is overloaded with debugging features.
|
|
virtual bool isDebugger();
|
|
|
|
//! @brief Change the memory bus used by the CPU.
|
|
void setMemoryBus(std::shared_ptr<Memory::MemoryBus> bus);
|
|
};
|
|
}
|
|
|
|
#endif //COMSQUARE_CPU_HPP
|