pub struct VirtualMachine {
    pub registers: Registers,
    pub flatmap: BytesMut,
    pub zero_bounds: (usize, usize),
    pub stack_bounds: (usize, usize),
    pub heap_bounds: (usize, usize),
    pub vheap_bounds: (usize, usize),
    pub interrupt_bounds: (usize, usize),
    pub reset_bounds: (usize, usize),
    pub irq_bounds: (usize, usize),
    pub addr_mode: Mode,
    pub cycles: u64,
    pub halted: bool,
}
Expand description

The virtual machine implementation

This module provides VirtualMachine, a 6502 cpu vm. It’s API is intended to closely adhere to the 6502 specs.

See Masswerk’s 6502 Instruction Set for more info on the spec.

Fields

registers: Registers

Machine registers struct.

flatmap: BytesMut

The machine memory in a linear layout. We set the size to 64k+1 to allow easy indexing.

zero_bounds: (usize, usize)

Machine zero page bounds. This is a tuple of (start, end) addresses.

stack_bounds: (usize, usize)

Machine stack page bounds. The stack grows downwards from 0x01FF to 0x0100.

heap_bounds: (usize, usize)

Machine heap(dynamic memory) bounds. This is the only memory that can be dynamically allocated. Accessing memory outside of these bounds is undefined behavior.

vheap_bounds: (usize, usize)interrupt_bounds: (usize, usize)

Interrupt vector table bounds. Placed at end of heap.

Three vectors are used: reset, irq, nmi. Each vector is 2 bytes.

reset_bounds: (usize, usize)irq_bounds: (usize, usize)addr_mode: Mode

Current mode state, this is generally set internally by step.

cycles: u64

The current cycle count of the vm. This is incremented by step.

halted: bool

Implementations

Trait Implementations

Formats the value using the given formatter. Read more
Returns the “default value” for a type. Read more

Returns the page offset for the current PC.

Sets the PC to the given page offset.

Checks if the given address is within the heap bounds. TODO: Reimplement.

Returns the value at the heap address given.
Sets the value at the heap address given.

Virtual machine core control functionality.

This provides three main internal functions, step, mode, and fetch.

Examples

step
use vm6502::prelude::*;
let mut vm = VirtualMachine::new();

vm.insert_program(0x00, "69FFFF");
vm.registers.pc = 0x00;

vm.step();

assert_eq!(vm.flatmap[vm.registers.pc as usize + vm.heap_bounds.0], 0xFF);
mode
use vm6502::prelude::*;

let mut vm = VirtualMachine::new();
let mode = vm.mode(0x69);

assert_eq!(mode, Mode::Immediate);
fetch

// TODO: Unignore this later.

use vm6502::prelude::*;

let mut vm = VirtualMachine::new();
let byte = 0x01;

// 0x200 is heap start. See `VirtualMachine::heap_bounds`.
vm.set_heap(0x0000, 0x69);
vm.set_heap(0x0001, byte);

assert_ne!(vm.flatmap[0x0001], byte, "Byte {} was not set to 0x0201", byte);
assert_eq!(byte, vm.flatmap[0x0201], "Byte {} was not set at 0x0201", byte);

// Should PC be 0x01 or two here?
vm.registers.pc = 0x01;
vm.addr_mode = Mode::Immediate;
let fetched = vm.fetch();
assert_eq!(vm.registers.pc, 0x02, "PC should be incremented by 1 after fetch");

assert_eq!(fetched, byte, "Fetched byte {} does not match expected byte {}", fetched, byte);

Fetch the next byte from the program counter.

Check the opcode and return the addressing mode.

Execute the an arbitrary op. It returns the vm’s current cycle count.

Load Instructions;

Accumulator <-> ZeroPage, Absolute, ZeroPageX and AbsoluteX

Break
Add with carry
Subtract with carry
Logical AND
Exclusive OR
Logical inclusive OR
Branch on carry clear
Branch on carry set
Branch on equal (zero set)
Branch on minus (negative set)
Branch on plus (negative clear)
Branch on overflow clear
Branch on overflow set
Decrement memory
Increment memory
Decrement X register
Decrement Y register
Increment X register
Increment Y register
Load X register
Load Y register
Bit test
Compare
Compare X register
Compare Y register
Logical shift right
Arithmetic shift left
Rotate left
Rotate right
Jump
Jump to subroutine
Return from interrupt
Return from subroutine
Clear carry flag
Clear decimal mode
Clear interrupt disable bit
Clear overflow flag
Set carry flag
Set decimal mode
Set interrupt disable status
Store accumulator
Store X register
Store Y register
Transfer accumulator to X
Transfer X to accumulator
Transfer accumulator to Y
Transfer Y to accumulator
Transfer stack pointer to X
Transfer X to stack pointer
Push accumulator
Push processor status (SR)
Pull accumulator
Pull processor status (SR)
No operation

Insert a hex encoded string prog at heap offset offset.s

Replaces and runs the program at offset.

Run the internally set program. Intended API for running programs.

Run the internally set program for duration time, returning the number of cycles executed.

Resets the total machine state.

Fill the stack with ops.

Set the interrupt vectors to the given values.
Set the interrupt vectors to the values: (0xFFFA, 0xFFFB), (0xFFFC, 0xFFFD), (0xFFFE, 0xFFFF)

Implements a high level interface for accessing the status register.

This is the intended API access for frontends to use the VM.

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.