I've recently been messing around with the MOS 6502 processor which was used in many retro systems of the 1980s, however, what's annoyed me is that there isn't really an easy way just to mess around with code and see what happens. The closest thing is the Virtual 6502 which is decent, but it's online which means you have to deal with uploading files and such, and it also doesn't really have enough configuration options for my taste. Considering I like D and that I couldn't find a DUB package that already emulated the 6502, I decided to make my own emulator, which is currently called Emu6502 (very original name, I know). It supports most features of the 6502, with the exception of a few small things (which are listed under the TODO section of the readme). Here's an example program:
module example;
import std.stdio;
import emu6502;
void main() {
ubyte[0x10000] memory;
ubyte[] code = [
0xA2, 0x00, // lda #0
// loop:
0xBD, 0x0E, 0x80, // lda data,x
0x8D, 0x00, 0xE0, // sta $E000
0xC9, 0x00, // cmp #0
0xE8, // inx
0xD0, 0xF5, // bne loop
0x00, // brk
// data: .asciiz 'Hello, World!\n'
0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x2C, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00
];
// put code into memory
foreach(i, b; code)
memory[0x8000+i] = b;
// set reset vector
memory[0xFFFC] = 0x00;
memory[0xFFFD] = 0x80;
// create emulator
auto emu = new Emu6502(
(ushort address) {
return memory[address];
},
(ushort address, ubyte value) {
if(address == 0xE000)
write(cast(char)value);
else
memory[address] = value;
},
(ubyte n) {}
);
emu.reset();
emu.throwExceptionOnBreak = true;
// run until brk triggered
try {
while(true)
emu.step();
} catch(BreakException) {}
}
Links: Github Repo DUB Package