mos6502 C++ Implementation

repository·master·Indexed 18 days ago

https://github.com/gianlucag/mos6502

A C++ implementation of the MOS Technology 6502 CPU featuring a jump-table architecture for legal opcodes and addressing modes. Designed for integration into machine emulators, it requires BusRead and BusWrite callbacks for memory access. The API includes methods for Reset, NMI, IRQ, and executing a specific number of instructions via Run().

Tokens
731
Snippets
2
Records
3
Agent score
13%

What's inside mos6502

  1. Understand the MOS6502 emulator architecture

    master

    This emulator uses a jump-table based approach for opcode selection. Instead of a large switch-case block, the opcode value (e.g., 0x80) is used as an index into a table of function pointers. Each entry in the table is a C++ function that emulates a specific instruction.

    Key Features:

    • 100% coverage of legal opcodes: All 151 valid opcodes are implemented.
    • Decimal mode: Supported.
    • Addressing modes: All 13 addressing modes (e.g., ACCUMULATOR, IMMEDIATE, ABSOLUTE, ZERO PAGE, etc.) are emulated.
    • Fetch-Decode-Execute loop: The internal loop retrieves the opcode from memory, looks up the instruction in the InstrTable, and executes it via Exec(instr).
  2. Integrate the MOS6502 emulator into your project

    master

    The emulator is provided as a single C++ class. To use it, you must provide two callback functions to the constructor to handle memory access. These callbacks allow you to implement address decoding for memory-mapped I/O or virtual devices.

    Requirements for callbacks:

    • BusRead: A function with signature uint8_t MemoryRead(uint16_t address) to read an 8-bit value from a 16-bit address.
    • BusWrite: A function with signature void MemoryWrite(uint16_t address, uint8_t value) to write an 8-bit value to a 16-bit address.

    Limitations:

    • The emulator does not yet support 100% cycle accuracy. It is not suitable for projects requiring precise mid-frame register update timing.
    • Illegal opcodes are not implemented and will result in a NOP (No Operation).
    // Define your memory access logic
    uint8_t MyMemoryRead(uint16_t address) {
        // Implement your read logic here
        return 0;
    }
    
    void MyMemoryWrite(uint16_t address, uint8_t value) {
        // Implement your write logic here
    }
    
    // Initialize the emulator
    mos6502 cpu(MyMemoryRead, MyMemoryWrite);
  3. Use the mos6502 public API

    master

    The mos6502 class provides five public methods to control the CPU state and execution:

    • mos6502(BusRead r, BusWrite w): Constructor. Requires memory read and write callbacks.
    • void Reset(): Performs a hardware reset, simulating the physical reset pin.
    • void NMI(): Triggers a Non-Maskable Interrupt request.
    • void IRQ(): Triggers an Interrupt Request.
    • void Run(uint32_t n): Executes the CPU for the next n machine instructions.
    // Example usage
    mos6502 cpu(MyMemoryRead, MyMemoryWrite);
    
    cpu.Reset();      // Reset the CPU
    cpu.Run(1000);    // Run 1000 instructions
    cpu.IRQ();        // Trigger an interrupt