-
Notifications
You must be signed in to change notification settings - Fork 1
/
microcode_step_capture.rs
55 lines (49 loc) · 2.2 KB
/
microcode_step_capture.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use mainspring::address_map::memory::{Memory, ReadOnly, ReadWrite};
use mainspring::cpu::mos6502::{microcode::Microcode, Mos6502};
use mainspring::cpu::Execute;
#[allow(unused)]
use mainspring::prelude::v1::*;
type Rom = Memory<ReadOnly, u16, u8>;
type Ram = Memory<ReadWrite, u16, u8>;
fn main() {
// A ReadOnly memory segment containing a small rom consisting of a
// LDA/STA loop. This will run until stopped. This exists in the address
// space inclusively between 0xffea and 0xffff.
let rom = Rom::new(0xffea, 0xffff).load(vec![
0xa9, 0x01, 0x8d, 0x00, 0x02, 0xa9, 0x02, 0x8d, 0x01, 0x02, 0xa9, 0x03, 0x8d, 0x02, 0x02,
0x4c, 0xea, 0xff, 0xea, 0xff, 0x00, 0x00,
]);
// A segment of ReadWrite memory existing inclusively in the the space
// between 0x8000 and 0xffff.
let ram = Ram::new(0x0200, 0x7fff);
let cpu = Mos6502::default()
// Registers the address space and the rom as addressable memory with
// the cpu. This accepts any implementation of the Addressable trait.
.register_address_space(0xffea..=0xffff, rom)
// Registration can fail, this unwraps the result.
.unwrap()
.register_address_space(0x0200..=0x7fff, ram)
.unwrap()
// Resets the cpu and loads the reset vector into the PC.
.reset()
// This return a StepState<Mos6502> which is unwrapped to return the
// enclosing cpu.
.unwrap();
// States represents a flattened vector of Microcode, or small cpu
// operations that are generated by each instruction as they are
// interpreted. These instructions are small enough to make storage viable
// and can be replayed to any position in time of the collected
// instructions.
let states: Vec<Microcode> = cpu
.clone()
.into_iter()
.flat_map(Into::<Vec<Vec<Microcode>>>::into) // Flatten instructions to cycles
.take(1_000_000) // Take 1,000,000 cycles.
.flatten() // Flatten the cycles to a vector of microcode.
.collect();
println!(
"{:#?}",
// Microcode can then be folded onto a cpu to replay its state onto a fresh cpu.
states.iter().fold(cpu, |c, mc| mc.execute(c))
);
}