Emulating a CPU in C++ (6502)



This isn’t a full implementation of the 6502, this is more just a from scratch into in learning how a CPU works by writing an emulator one (in this case the 8-bit 6502).
If you want a more in depth video on writing a full 6502 emulator then see One Lone Coder’s “NES Emulator Part #2”: https://youtu.be/8XmxKPJDGU0
Another good talk to watch is this video from Matt Godbolt about the BBC Emulator he wrote in Javascript!!!: https://youtu.be/7WuRq-Wmw5o

Code is here: https://github.com/davepoo/6502Emulator

Links:
6502 Processor: http://www.obelisk.me.uk/6502/
C64 Memory Map: https://sta.c64.org/cbm64mem.html
C64 Reset Process: www.c64-wiki.com/wiki/Reset_(Process)

Timestamps:
0:00 – Intro
0:29 – The 6502
4:24 – Creating CPU Internals
9:23 – Resetting the CPU
12:48 – Creating the Memory
15:10 – Creating the Execute function
23:32 – Emulating “LDA Immediate” instruction
28:00 – Hardcoding a test program
31:50 – Emulating “LDA Zero Page” instruction
37:20 – Emulating “LDA Zero Page,X” instruction
38:42 – Emulating “JSR” instruction
48:30 – Closing comments

34 thoughts on “Emulating a CPU in C++ (6502)

  1. Use stdint.h. There is no guarantee that unsigned short is actually 16bits on all systems. With uint16_t you can be sure and the code becomes easier to understand.

  2. Seriously impressive video and very informative. And someone who actually does know C++.I've been around software dev alooong time and when asked 'do you know any C++ devs' I always reply 'I know quite a few who claim to be c++ devs'. The rarest of beasts I think.

  3. When you push onto the stack you actually decrement SP. The stack sits above the heap and grows downwards towards it. I guess for the purposes of this exercise it doesn’t matter, but if you want a true emulation that emulates the real CPU accurately…

  4. A couple of (small) mistakes, if you really wanted to be accurate with the 6502:
    – S (the stack register) is actually 8 bit, not 16
    – Pushing to the stack actually decrement it not increment
    – FFFC is containing an address, not code, so puting code here would not work on a real 6502
    – Going further to FFFF as you store it in a 16bit integer will just warp around to 0, exactly like the real thing would do, so no need to check if you go further

    Oh and I see this is a series, so you probably fixed most of these I suppose 🙂

  5. Couple of comments:

    a) the stack pointer is 8 bits wide (the stack resides 0x0100 to 0x01ff),

    b) the flag register is better done:
    union {
    struct {
    Byte C : 1;
    // …
    Byte B : 1;
    Byte : 1; // Bit unused, always set to zero
    Byte V : 1;
    Byte N : 1;
    };
    Byte F;
    };

    This allows an easy implementation of the instructions PHP and PLP (push processor flags & pull processor flags), and

    c) the code shown would start executing at 0xfffc, but 0xfffc is a vector, containing the address of the actual routine.

    Would it be better implementing the processor as two 256 bit arrays, viz. one for the class (eg. LDA), and one for the addressing mode?

  6. Surprisingly it worked despite a bug in FetchWord with cycles++ when it should be cycles- –
    Also you should implement the instruction vs mode table to simplify it dramatically. By masking on the opcode bits you can then use a switch statement for the addressing mode. It would reduce the combinations to 23 instruction switch statement and 8 addressing functions.
    Btw the pc++ wrapping to 0x0000 is legal so as long as mem is mem[16k] it’s fine.
    I hope this isn’t taken as armchairing. The video was fun to see.

  7. All this is just ridiculous before writing an emulator try to understand how a 6502 works
    perhaps that if at least you could read, you would have bought Chuck Peddle books about the 6502

Leave a Reply

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