Crates.io | nmos6502 |
lib.rs | nmos6502 |
version | 1.0.1 |
source | src |
created_at | 2023-03-29 19:12:37.731601 |
updated_at | 2023-03-31 17:53:53.863164 |
description | A no_std compliant NMOS6502 emulator suitable for embedded environments. |
homepage | |
repository | https://github.com/super-saturn/nmos6502 |
max_upload_size | |
id | 824310 |
size | 73,924 |
Yes! But wait, here's why you may want this one:
no_std
compatiblenum_enum
as a preprocessor for Opcodes)IRQ
and NMI
interruptsThis implementation covers all standard opcodes for the NMOS 6502 and all the "illegal" NOP equivalents. Unrecognized opcodes are exposed for debugging purposes and will be implemented at a later time.
This library is only the CPU. In a 6502 system the CPU is always in charge of the current address of the bus. Basic usage is as follows:
let cpu = Nmos6502::new();
loop {
// "bus" is any struct
// that implements: BusInterface
cpu.tick(&mut bus);
}
The CPU send and receives data via a BusInterface
, which the crate user must implement themselves. At its most rudimentary, an implementation could simply allocate a blank 64k array of u8
and return/write the indexed value.
BusInterface must fundamentally provide:
fn get_byte_at(&mut self, addr:u16) -> u8;
fn set_byte_at(&mut self, addr:u16, byte: u8);
The 6502 will use the default RESET vector of 0xFFFC-0xFFFD
. That is, whatever value the BusInterface
returns for that address will be where the cpu sets its Program Counter.
In more complex systems, eg., an Apple ][ emulator, you may implement whatever clever system you like to intercept/distribute any request via BusInterface
to various subsystems.
For efficiency/speed, you may optionally override
fn get_pipelined_bytes(&mut self, addr:u16) -> (u8, u8, u8)
Which is utilized to retrieve the current opcode and the next two bytes as possible operands. This is only of use if you have a way to actually pipeline these bytes (eg., a system which can send a 24bit+ word in one instruction) or if you need to avoid extraneous memory accesses which might trigger eg., softswitches. The default implementation simply uses get_byte_at
with a wrapping increment on the address.