NMOS 6502 in Rust

Another 6502 Emulator?

Yes! But wait, here's why you may want this one:

This 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.

Quick Start

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);

Further Details

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.