CPU6502 Emulator
A javascript emulator for the MOS6502 (WDC 65c02 compatible) CPU.
Designed for simulating custom logic boards that use the 6502.
All memory read/writes call out to a delegate function, allowing custom memory logic, I/O logic and address decoding.
Configuration
const cpu = new CPU6502({
accessMemory,
logInstructions: false,
logInternalState: false,
maxInstructions: 50
});
Usage
Available methods
const cpu = new CPU6502();
cpu.reset();
cpu.triggerIRQB();
cpu.triggerNMIB();
cpu.pauseClock();
cpu.startClock();
console.log(cpu.reg_a);
console.log(cpu.reg_x);
console.log(cpu.reg_y);
console.log(cpu.programCounter);
console.log(cpu.stackPointer);
console.log(cpu.processorStatus);
Example 1: Executing simple machine code
import { CPU6502, ReadWrite } from "6502-emulator";
const I_NOOP = 0xea;
const I_LDA = 0xa9;
const I_STA = 0x8d;
const I_JMP = 0x4c;
const ram = new Uint8ClampedArray(0xffff);
ram.fill(I_NOOP);
ram[0xfffc] = 0x00;
ram[0xfffd] = 0x02;
ram.set(
[
I_LDA, 0x55,
I_STA, 0x00, 0x60,
I_LDA, 0xaa,
I_STA, 0x00, 0x60,
I_JMP, 0x00, 0x02
],
0x0200
);
const accessMemory = (readWrite, address, value) => {
if (address === 0x6000 && readWrite === ReadWrite.write) {
console.log("Output: ", value.toString(16));
return;
}
if (readWrite === ReadWrite.read) {
return ram[address];
}
ram[address] = value;
};
const cpu = new CPU6502({ accessMemory });
cpu.reset();
Example 2: Load ROM image from disk
import { CPU6502, ReadWrite } from "6502-emulator";
const ramImagePath = "./myROMFile";
const ramImage = fs.readFileSync(ramImagePath);
const ram = Uint8ClampedArray.from(ramImage);
const accessMemory = (readWrite, address, value) => {
if (address === 0x6000 && readWrite === ReadWrite.write) {
console.log("Output: ", value.toString(16));
return;
}
if (address === 0x6005 && readWrite === ReadWrite.write) {
console.log("Exit captured! pausing clock");
cpu.pauseClock();
return;
}
if (readWrite === ReadWrite.read) {
return ram[address];
}
ram[address] = value;
}
const cpu = new CPU6502({ accessMemory });
cpu.reset();