1use crate::cart::Cartridge;
8use crate::cpu::{Cpu, bus::CpuIoBus};
9use crate::ppu::{Ppu, bus::PpuIoBus};
10use crate::apu::{Apu, bus::ApuIoBus};
11use crate::joy::Joy;
12use crate::mapper::Mapper;
13use crate::common::Clockable;
14
15use crate::ppu::Pixel;
16use crate::apu::Sample;
17use crate::joy::{Controller, Button};
18
19use crate::ppu::{DISPLAY_WIDTH, DISPLAY_HEIGHT};
22
23const FRAME_BUFFER_SIZE: usize = DISPLAY_WIDTH * DISPLAY_HEIGHT * 3;
25
26pub type FrameBuffer = [u8; FRAME_BUFFER_SIZE];
28pub type SampleBuffer = Vec<crate::apu::Sample>;
30
31
32use std::rc::Rc;
33use std::cell::RefCell;
34
35#[cfg(feature="events")]
36use std::sync::mpsc::{channel, Receiver};
37
38enum Event {
40 CPU, PPU, APU, None,
41}
42
43type SequencerEvents = [Event; 3];
44
45#[derive(Default)]
47struct FrameSequencer {
48 counter: u32,
49}
50
51impl Clockable<SequencerEvents> for FrameSequencer {
52 fn tick(&mut self) -> SequencerEvents {
53 let events = match self.counter {
54 0 => [Event::PPU, Event::CPU, Event::APU],
55 1 => [Event::PPU, Event::None, Event::None],
56 2 => [Event::PPU, Event::None, Event::None],
57 3 => [Event::PPU, Event::CPU, Event::None],
58 4 => [Event::PPU, Event::None, Event::None],
59 5 => [Event::PPU, Event::None, Event::None],
60 _ => panic!("Invalid clock for sequencer"),
61 };
62
63 self.counter = (self.counter + 1) % 6;
64
65 events
66 }
67}
68
69#[derive(Default)]
71pub struct Nes {
72 cpu: Rc<RefCell<Cpu<CpuIoBus>>>, ppu: Rc<RefCell<Ppu<PpuIoBus>>>, apu: Rc<RefCell<Apu>>, joy: Rc<RefCell<Joy>>, mapper: Option<Mapper>, sequencer: FrameSequencer,
79}
80
81impl Nes {
82 pub fn new() -> Self {
88 Nes::default()
89 }
90
91 pub fn entry(self, entry_addr: u16) -> Self {
97 self.cpu.borrow_mut().set_pc(entry_addr);
98 self
99 }
100
101 pub fn with_cart(mut self, cart: Cartridge) -> Self {
103 self.insert(cart);
104 self
105 }
106
107 pub fn debug_mode(self, debug: bool) -> Self {
113 self.cpu.borrow_mut().set_debug(debug);
114 self
115 }
116
117 pub fn emulate_frame(&mut self) -> (FrameBuffer, SampleBuffer) {
128 let mut framebuffer = [0x00u8; FRAME_BUFFER_SIZE];
129 let mut framebuffer_idx = 0usize;
130
131 let mut samplebuffer: Vec<Sample> = Vec::new();
132
133 if self.mapper.is_some() {
134 for _ in 0..crate::ppu::CYCLES_PER_FRAME {
135 let (pixel, sample) = self.clock_components();
137
138 if let Some((r, g, b)) = pixel {
139 framebuffer[framebuffer_idx] = r;
141 framebuffer[framebuffer_idx + 1] = g;
142 framebuffer[framebuffer_idx + 2] = b;
143 framebuffer_idx = (framebuffer_idx + 3) % FRAME_BUFFER_SIZE;
144 }
145
146 if let Some(sample) = sample {
147 samplebuffer.push(sample);
148 }
149 }
150 }
151
152 (framebuffer, samplebuffer)
153 }
154
155 pub fn run_audio(&mut self, buffer_size: usize) -> Vec<f32> {
162 let mut buffer = vec![0f32; 0];
163
164 while buffer.len() < buffer_size {
165 let sample = self.clock_components().1;
166 if let Some(sample) = sample {
167 buffer.push(sample);
168 }
169 }
170
171 buffer
172 }
173
174 pub fn input(&mut self, btn: Button, pressed: bool) {
181 self.joy.borrow_mut().input(btn, pressed);
182 }
183
184 pub fn controller_input(&mut self, controller: Controller, btn: Button, pressed: bool) {
194 self.joy.borrow_mut().controller_input(controller, btn, pressed);
195 }
196
197 pub fn run_until(&mut self, addr: u16) {
199 if self.mapper.is_some() {
201 while self.cpu.borrow().get_pc() != addr {
202 self.clock_components();
203 }
204 }
205 }
206
207 fn clock_components(&mut self) -> (Option<Pixel>, Option<Sample>) {
209 let mut pixel: Option<Pixel> = None;
210 let mut sample: Option<Sample> = None;
211
212 for event in self.sequencer.tick().iter() {
213 match event {
214 Event::PPU => {
215 pixel = self.ppu.borrow_mut().tick();
216 },
217 Event::CPU => {
218 self.cpu.borrow_mut().tick();
219 },
220 Event::APU => {
221 sample = Some(self.apu.borrow_mut().tick());
222 },
223 Event::None => {},
224 }
225 }
226
227 (pixel, sample)
228 }
229
230 pub fn is_holding(&self) -> bool {
232 self.cpu.borrow().is_holding()
233 }
234
235 pub fn insert(&mut self, cart: Cartridge) {
237 let mapper = crate::mapper::from_cartridge(cart);
239
240 let cpu_bus = CpuIoBus::new(self.ppu.clone(), self.apu.clone(), self.joy.clone(), mapper.clone());
242 self.cpu.borrow_mut().load_bus(cpu_bus);
243
244 let ppu_bus = PpuIoBus::new(self.cpu.clone(), mapper.clone());
245 self.ppu.borrow_mut().load_bus(ppu_bus);
246
247 let apu_bus = Rc::new(RefCell::new(ApuIoBus::new(self.cpu.clone(), mapper.clone())));
248 self.apu.borrow_mut().load_bus(apu_bus);
249
250 self.mapper = Some(mapper);
251 }
252
253 pub fn eject(self) -> Vec<u8> {
261 self.mapper.map_or(vec![], |mapper| mapper.borrow().get_battery_ram())
262 }
263
264 #[cfg(feature="events")]
268 pub fn cpu_event_channel(&mut self) -> Receiver<crate::events::CpuEvent> {
269 let (tx, rx) = channel::<crate::events::CpuEvent>();
270 self.cpu.borrow_mut().set_event_sender(tx);
271
272 rx
273 }
274
275 #[cfg(feature="events")]
276 pub fn apu_event_channel(&mut self) -> Receiver<crate::events::ApuEvent> {
277 let (tx, rx) = channel::<crate::events::ApuEvent>();
278 self.apu.borrow_mut().set_event_sender(tx);
279
280 rx
281 }
282
283 pub fn get_program_counter(&self) -> u16 {
289 self.cpu.borrow().get_pc()
290 }
291
292 pub fn read_cpu_ram(&self, addr: u16) -> u8 {
294 self.cpu.borrow().read_ram(addr)
295 }
296
297 pub fn read_ppu_memory(&self, addr: u16) -> u8 {
299 self.ppu.borrow().read_vram(addr)
300 }
301
302 pub fn read_tile(&self, nametable: u16, x: usize, y: usize) -> u8 {
304 self.ppu.borrow().read_tile(nametable, x, y)
305 }
306}
307
308impl From<Cartridge> for Nes {
309 fn from(cart: Cartridge) -> Self {
310 Nes::default().with_cart(cart)
311 }
312}
313
314#[cfg(test)]
315mod tests {
316
317}