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
pub mod traits; use cpu::Cpu; use gpu::GPU; use mmu::Memory; use mmu::interrupt::Interrupt; use self::traits::Io; use joypad::Joypad; pub struct Emulator { cpu: Cpu, gpu: GPU, memory: Memory, joypad: Joypad, } impl Emulator { pub fn new() -> Emulator { Emulator { cpu: Cpu::new(), gpu: GPU::new(), memory: Memory::new(), joypad: Joypad::new(), } } pub fn load_rom(&mut self, rom: Vec<u8>) { self.memory.load_rom(rom); } pub fn cycle<T: Io>(&mut self, io: &mut T) { let cycles = self.cpu.step(&mut self.memory); self.gpu.step(cycles, &mut self.memory, io); self.handle_input(io); self.handle_interrupts(); } fn handle_input<T: Io>(&mut self, controller: &mut T) { controller.update_joypad(&mut self.joypad); self.joypad.save_to_memory(&mut self.memory); } fn handle_interrupts(&mut self) { if self.cpu.interrupt_enabled { if let Some(interrupt) = self.memory.get_interrupt() { self.process_interrupt(interrupt); } } } fn process_interrupt(&mut self, interrupt: Interrupt) { match interrupt { Interrupt::Vblank => self.cpu.rst_40(&mut self.memory), Interrupt::Lcd => self.cpu.rst_48(&mut self.memory), Interrupt::Timer => self.cpu.rst_50(&mut self.memory), Interrupt::Serial => self.cpu.rst_58(&mut self.memory), Interrupt::Joypad => self.cpu.rst_60(&mut self.memory), } self.memory.remove_interrupt(interrupt); } }