Decoupling the CPU and Memory

When building a 6502 emulator, one of the most fundamental architectural decisions you’ll face is how to organize memory access. It’s tempting to embed the memory array directly into the CPU class – especially for early prototypes – but as your emulator grows, this tight coupling becomes a liability. A better approach is to implement a dedicated memory bus and pass it into the CPU. Here’s why, and how.

Why Separate Memory from CPU Logic?

At a hardware level, the 6502 CPU doesn’t own memory – it communicates with memory-mapped peripherals and RAM through the system bus. Mirroring that in your code makes your emulator more accurate, modular, and testable.

Benefits of separating the CPU from memory:

  • Cleaner abstraction: The CPU should only know how to read and write bytes, not where they come from.
  • Peripheral integration: You can easily map memory addresses to I/O devices (e.g., screen, keyboard, VIA, etc.).
  • Bank switching: Dynamic memory mapping becomes trivial with a proper bus.
  • Testing: You can mock memory for unit testing the CPU without dragging the entire system along.

A Simple Bus Interface

Start by defining a bus interface:

C#
public interface IMemoryBus
{
    byte Read(ushort address);
    void Write(ushort address, byte data);
}

CPU only interacts with this interface:

C#
public class CPU
{
    private readonly IMemoryBus _bus;

    public CPU(IMemoryBus bus)
    {
        _bus = bus;
    }

    public void ExecuteNextInstruction()
    {
        ushort pc = /* fetch program counter */;
        byte opcode = _bus.Read(pc);
        // decode & execute
    }
}

Modeling your emulator with a decoupled bus architecture brings your code closer to real hardware behavior. It simplifies future expansion and makes the CPU a truly generic component – unaware of the memory layout or even what devices are attached.
If you’re serious about maintainability and hardware accuracy, decoupling CPU and memory isn’t just good style – it’s essential.

Leave a Reply

Your email address will not be published. Required fields are marked *