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 = accessMemory // function to be called when CPU reads/writes to memory logInstructions: false // output each instruction to console, for advanced debugging logInternalState: false // output internal processor state after each instruction for advanced debugging maxInstructions: 50 // automatically pause execution after 50 instructions;
Usage
Available methods
const cpu = ; cpu; // trigger reset sequencecpu; // trigger IRQB interruptcpu; // trigger NMIB interrupt cpu; // pause clock, stop executing instructionscpu; // start/resume clock // accessing internal stateconsole;console;console;console;console;console;
Example 1: Executing simple machine code
; // instruction opcodesconst I_NOOP = 0xea;const I_LDA = 0xa9;const I_STA = 0x8d;const I_JMP = 0x4c; // set up memoryconst ram = 0xffff; // 64kb ramram; // fill ram with noop instructions // store reset vector as 0200 (little endian)ram0xfffc = 0x00;ram0xfffd = 0x02; // create a basic programram; const accessMemory = { // capture a write to 0x6000 as a magic output address, print to console if address === 0x6000 && readWrite === ReadWritewrite console; return; // write value to RAM (processor is reading from [address]) if readWrite === ReadWriteread return ramaddress; // store value in RAM (processor is writing [value] to [address]) ramaddress = value;}; const cpu = accessMemory ;// trigger a reset to start the clock & jump to the reset vectorcpu;
Example 2: Load ROM image from disk
; // load image from diskconst ramImagePath = "./myROMFile";const ramImage = fs; // set up memoryconst ram = Uint8ClampedArray; const accessMemory = { // capture a write to 0x6000 as a magic output address, print to console if address === 0x6000 && readWrite === ReadWritewrite console; return; // capture a write to 0x6005 as a magic output address, pause the clock if address === 0x6005 && readWrite === ReadWritewrite console; cpu; return; // write value to RAM (processor is reading from [address]) if readWrite === ReadWriteread return ramaddress; // store value in RAM (processor is writing [value] to [address]) ramaddress = value;} const cpu = accessMemory ;// trigger a reset to start the clock & jump to the reset vectorcpu;