mirror of
https://github.com/balt-dev/r6502.git
synced 2024-11-21 18:30:49 +00:00
A simple NMOS 6502 emulator.
.idea | ||
src | ||
tests | ||
.gitignore | ||
Cargo.toml | ||
LICENSE-APACHE | ||
LICENSE-MIT | ||
README.md |
r6502
Yet another NMOS 6502 emulator.
Designed to support no-std
and not require an allocator nor any unsafe code.
The API of this crate shies away from implementing interrupt handling,
instead having you step the emulator one opcode at a time and handle them yourself.
Feature Flags
The following feature flags exist:
Name | Description |
---|---|
bcd | Enable binary-coded decimal arithmetic. Enabled by default. Disable if you're writing a NES emulator. Note that invalid BCD is left untested and will not function faithfully to the NMOS 6502. |
bytemuck | Enables bytemuck support. |
arbitrary | Enables arbitrary support. This will pull in std . |
serde | Enables serde support. |
hashbrown | Enables hashbrown support. |
Example
extern crate std;
use std::eprintln;
use r6502::{Emulator, FunctionReadCallback, FunctionWriteCallback};
fn main() {
let mut emu = Emulator::default()
.with_read_callback(FunctionReadCallback(|state: &mut State, addr| {
// Log reads
eprintln!("Read from #${addr:04x}");
state.memory[addr as usize]
}))
.with_write_callback(FunctionWriteCallback(|state: &mut State, addr, byte|
// Don't write to ROM
if addr < 0xFF00 {
state.memory[addr as usize] = byte
})
)
.with_rom(include_bytes!("rom.bin"))
.with_program_counter(0x200);
loop {
let interrupt_requested = emu.step()
.expect("found an invalid opcode (only NMOS 6502 opcodes are supported)");
if interrupt_requested { // Go to IRQ interrupt vector
let vector = u16::from_le_bytes([
emu.read(0xFFFE),
emu.read(0xFFFF)
]);
emu.state.program_counter = vector;
}
}
}
Licensing
This may be licensed under either the MIT or Apache-2.0 license, at your option.