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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#![no_std]
extern crate alloc;
#[macro_use]
mod bus;
mod cartridge;
mod cpu;
mod ppu;
pub use cartridge::RomParserError;
pub use cpu::Cpu;
pub use ppu::Ppu;
use crate::cartridge::Cartridge;
use crate::ppu::PpuFrame;
pub const RAM_SIZE: u16 = 0x0800;
pub struct Emulator {
cartridge: Cartridge,
cpu: Cpu,
controller1: u8,
controller2: u8,
controller1_state: bool,
controller2_state: bool,
controller1_snapshot: u8,
controller2_snapshot: u8,
ram: [u8; RAM_SIZE as usize],
ppu: Ppu,
name_tables: [u8; 1024 * 4],
clock_count: u8,
}
impl Emulator {
pub fn new(rom: &[u8], save_data: Option<&[u8]>) -> Result<Self, RomParserError> {
let mut emulator = Self {
cartridge: Cartridge::load(rom, save_data)?,
cpu: Default::default(),
controller1: 0,
controller2: 0,
controller1_state: false,
controller2_state: false,
controller1_snapshot: 0,
controller2_snapshot: 0,
ram: [0u8; RAM_SIZE as usize],
ppu: Ppu::new(),
name_tables: [0u8; 1024 * 4],
clock_count: 0,
};
emulator.reset();
Ok(emulator)
}
pub fn clock(&mut self) -> Option<&PpuFrame> {
let mut ppu_bus = borrow_ppu_bus!(self);
self.ppu.clock(&mut ppu_bus);
if self.clock_count % 3 == 0 {
self.clock_count = 0;
if self.cpu.cycles == 0 && self.ppu.take_vblank_nmi_set_state() {
let mut cpu_bus = borrow_cpu_bus!(self);
self.cpu.nmi(&mut cpu_bus);
self.cpu.clock(&mut cpu_bus);
} else if self.cpu.cycles == 0 && self.cartridge.take_irq_set_state() {
let mut cpu_bus = borrow_cpu_bus!(self);
self.cpu.irq(&mut cpu_bus);
self.cpu.clock(&mut cpu_bus);
} else {
let mut cpu_bus = borrow_cpu_bus!(self);
self.cpu.clock(&mut cpu_bus);
}
}
self.clock_count = self.clock_count.wrapping_add(1);
self.ppu.ready_frame()
}
pub fn set_controller1(&mut self, state: u8) {
self.controller1 = state;
}
pub fn set_controller2(&mut self, state: u8) {
self.controller2 = state;
}
pub fn reset(&mut self) {
let mut cpu_bus = borrow_cpu_bus!(self);
self.cpu.reset(&mut cpu_bus);
self.ppu.reset();
self.clock_count = 0;
}
pub fn get_save_data(&self) -> Option<&[u8]> {
self.cartridge.get_save_data()
}
#[cfg(feature = "debugger")]
#[allow(unused_variables)]
pub fn disassemble(
&self,
start: u16,
end: u16,
) -> alloc::vec::Vec<(u16, alloc::string::String)> {
self.cartridge.disassemble()
}
#[cfg(feature = "debugger")]
pub fn cpu(&self) -> &Cpu {
&self.cpu
}
}