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
use crate::apu::APU;
use crate::cart::Cart;
use crate::controller::ButtonState;
use crate::cpu::CPU;
use crate::memory::MemoryBus;
use crate::ports::{AudioDevice, VideoDevice};
use crate::ppu::PPU;
pub struct Console {
apu: APU,
cpu: CPU,
ppu: PPU,
}
impl Console {
pub fn new(cart: Cart, sample_rate: u32) -> Self {
let mut memory = MemoryBus::with_cart(cart);
let ppu = PPU::new(&mut memory);
let cpu = CPU::new(memory);
Console {
apu: APU::new(sample_rate),
cpu,
ppu,
}
}
pub fn step<'a, A, V>(&'a mut self, audio: &mut A, video: &mut V) -> i32
where
A: AudioDevice,
V: VideoDevice,
{
let cpucycles = self.cpu.step();
let m = &mut self.cpu.mem;
for _ in 0..cpucycles * 3 {
self.ppu.step(m, video);
}
for _ in 0..cpucycles {
self.apu.step(m, audio);
}
cpucycles
}
pub fn step_micros<'a, A, V>(&'a mut self, audio: &mut A, video: &mut V, micros: u32)
where
A: AudioDevice,
V: VideoDevice,
{
let mut cpu_cycles = ((micros * 179) / 100) as i32;
while cpu_cycles > 0 {
cpu_cycles -= self.step(audio, video);
}
}
pub fn step_frame<'a, A, V>(&'a mut self, audio: &mut A, video: &mut V)
where
A: AudioDevice,
V: VideoDevice,
{
let mut frame_happened = false;
while !frame_happened {
let cpucycles = self.cpu.step();
let m = &mut self.cpu.mem;
for _ in 0..cpucycles * 3 {
frame_happened = self.ppu.step(m, video) || frame_happened;
}
for _ in 0..cpucycles {
self.apu.step(m, audio);
}
}
}
pub fn update_controller(&mut self, buttons: ButtonState) {
self.cpu.set_buttons(buttons);
}
pub fn reset(&mut self) {
self.cpu.reset();
self.cpu.mem.reset();
self.ppu.reset(&mut self.cpu.mem);
self.ppu.clear_vbuffers();
}
}