1use std::borrow::BorrowMut;
2use std::io::Cursor;
3use std::panic;
4
5use bincode::{deserialize_from, serialize_into};
6use log::info;
7
8use crate::audio::AudioDriver;
9use crate::cartridge_info::CartridgeInfo;
10use crate::cpu::CPUInfo;
11use crate::input::Button;
12use crate::internal::controllers::audio::AudioControllerImpl;
13use crate::internal::controllers::buttons::{ButtonController, ButtonControllerImpl};
14use crate::internal::controllers::dma::{DMAController, DMAControllerImpl};
15use crate::internal::controllers::lcd::LCDControllerImpl;
16use crate::internal::controllers::speed::{SpeedController, SpeedControllerImpl};
17use crate::internal::controllers::timer::{TimerController, TimerControllerImpl};
18use crate::internal::cpu::cpu::{CPU, CPUImpl};
19use crate::internal::cpu::interrupts::InterruptControllerImpl;
20use crate::internal::memory::bus::MemoryBus;
21use crate::internal::memory::control::ControlRegisters;
22use crate::internal::memory::cram::{CRAM, CRAMImpl};
23use crate::internal::memory::dma_bus::DMAMemoryBus;
24use crate::internal::memory::linear_memory::LinearMemory;
25use crate::internal::memory::mbc::MBC;
26use crate::internal::memory::mbc0::MBC0;
27use crate::internal::memory::mbc1::MBC1;
28use crate::internal::memory::mbc2::MBC2;
29use crate::internal::memory::mbc3::MBC3;
30use crate::internal::memory::mbc5::MBC5;
31use crate::internal::memory::memory::{Memory, MemoryAddress};
32use crate::internal::memory::oam::{OAM, OAMImpl, ObjectReference};
33use crate::internal::memory::stack::Stack;
34use crate::internal::memory::unmapped::UnmappedMemory;
35use crate::internal::memory::vram::VRAMImpl;
36use crate::internal::memory::wram::WRAMImpl;
37use crate::internal::util::compatibility_palette::CompatibilityPaletteLoader;
38use crate::internal::util::instruction_label_provider::InstructionLabelProvider;
39use crate::memory::{CartridgeType, CGBMode, OAMObject};
40use crate::renderer::{Renderer, RenderTarget};
41
42pub struct Emulator<A: AudioDriver, R: Renderer> {
43 rom: Box<dyn MBC>,
44 cartridge_info: CartridgeInfo,
45 cpu: CPUImpl,
46 cram: CRAMImpl,
47 vram: VRAMImpl,
48 wram: WRAMImpl,
49 oam: OAMImpl,
50 lcd: LCDControllerImpl,
51 timer: TimerControllerImpl,
52 dma: DMAControllerImpl,
53 renderer: R,
54 interrupt_controller: InterruptControllerImpl,
55 speed_controller: SpeedControllerImpl,
56 button_controller: ButtonControllerImpl,
57 audio_controller: AudioControllerImpl,
58 stack: Stack,
59 control_registers: ControlRegisters,
60 reserved_area_1: LinearMemory<0x1E00, 0xE000>,
61 reserved_area_2: LinearMemory<0x0060, 0xFEA0>,
62 unmapped_memory: UnmappedMemory,
63 audio_driver: A,
64 paused: bool,
65}
66
67impl<A: AudioDriver, R: Renderer> Emulator<A, R> {
68 pub fn new(rom_bytes: &[u8], audio_driver: A, renderer: R) -> Self {
69 info!("Creating new emulator");
70 let cartridge_info = CartridgeInfo::from_bytes(rom_bytes);
71 let rom = Emulator::<A, R>::create_rom(rom_bytes, &cartridge_info);
72 let mut cpu = CPUImpl::new();
73 cpu.init();
74 let mut cram = CRAMImpl::new();
75 let vram = VRAMImpl::new();
76 let wram = WRAMImpl::new();
77 let oam = OAMImpl::new();
78 let mut lcd = LCDControllerImpl::new();
79 let mut timer = TimerControllerImpl::new();
80 timer.write(MemoryAddress::TAC, 0xF8);
81 let dma = DMAControllerImpl::new();
82 let button_controller = ButtonControllerImpl::new();
83 let audio_controller = AudioControllerImpl::new();
84 let stack = Stack::new();
85 let mut control_registers = ControlRegisters::new();
86 let reserved_area_1 = LinearMemory::<0x1E00, 0xE000>::new();
87 let reserved_area_2 = LinearMemory::<0x0060, 0xFEA0>::new();
88 let interrupt_controller = InterruptControllerImpl::new();
89 let speed_controller = SpeedControllerImpl::new();
90 let unmapped_memory = UnmappedMemory::new();
91
92 if let CGBMode::Color = cartridge_info.cgb_mode {
95 control_registers.write(MemoryAddress::KEY0, rom_bytes[0x0143]);
96 } else {
97 let compatibility_palettes = CompatibilityPaletteLoader::get_compatibility_palettes(&cartridge_info);
98 cram.write_compatibility_palettes(compatibility_palettes);
99 control_registers.write(MemoryAddress::KEY0, 0x04);
100 lcd.write(MemoryAddress::OPRI, 0x01);
101 }
102
103 control_registers.write(MemoryAddress::BANK, 0x11);
105
106 Emulator {
107 cpu,
108 rom,
109 cartridge_info,
110 cram,
111 vram,
112 wram,
113 oam,
114 lcd,
115 timer,
116 dma,
117 stack,
118 button_controller,
119 audio_controller,
120 control_registers,
121 reserved_area_1,
122 reserved_area_2,
123 interrupt_controller,
124 speed_controller,
125 renderer,
126 unmapped_memory,
127 audio_driver,
128 paused: false,
129 }
130 }
131
132 pub fn get_cartridge_info(&self) -> &CartridgeInfo {
133 &self.cartridge_info
134 }
135
136 pub fn get_state(&self) -> Result<Vec<u8>, String> {
137 let mut buffer: Vec<u8> = Vec::new();
138
139 fn stringify_error(error: bincode::Error) -> String { format!("Error while serializing: {:?}", error) }
140
141 serialize_into(&mut buffer, &self.cpu).map_err(stringify_error)?;
142 serialize_into(&mut buffer, &self.cram).map_err(stringify_error)?;
143 serialize_into(&mut buffer, &self.vram).map_err(stringify_error)?;
144 serialize_into(&mut buffer, &self.wram).map_err(stringify_error)?;
145 serialize_into(&mut buffer, &self.oam).map_err(stringify_error)?;
146 serialize_into(&mut buffer, &self.lcd).map_err(stringify_error)?;
147 serialize_into(&mut buffer, &self.timer).map_err(stringify_error)?;
148 serialize_into(&mut buffer, &self.dma).map_err(stringify_error)?;
149 serialize_into(&mut buffer, &self.stack).map_err(stringify_error)?;
150 serialize_into(&mut buffer, &self.button_controller).map_err(stringify_error)?;
151 serialize_into(&mut buffer, &self.audio_controller).map_err(stringify_error)?;
152 serialize_into(&mut buffer, &self.control_registers).map_err(stringify_error)?;
153 serialize_into(&mut buffer, &self.reserved_area_1).map_err(stringify_error)?;
154 serialize_into(&mut buffer, &self.reserved_area_2).map_err(stringify_error)?;
155 serialize_into(&mut buffer, &self.interrupt_controller).map_err(stringify_error)?;
156 serialize_into(&mut buffer, &self.speed_controller).map_err(stringify_error)?;
157 serialize_into(&mut buffer, &self.unmapped_memory).map_err(stringify_error)?;
158 Ok(buffer)
159 }
160
161 pub fn load_state(&mut self, buffer: &[u8]) {
162 let mut cursor = Cursor::new(buffer);
163 self.cpu = deserialize_from(&mut cursor).unwrap();
164 self.cram = deserialize_from(&mut cursor).unwrap();
165 self.vram = deserialize_from(&mut cursor).unwrap();
166 self.wram = deserialize_from(&mut cursor).unwrap();
167 self.oam = deserialize_from(&mut cursor).unwrap();
168 self.lcd = deserialize_from(&mut cursor).unwrap();
169 self.timer = deserialize_from(&mut cursor).unwrap();
170 self.dma = deserialize_from(&mut cursor).unwrap();
171 self.stack = deserialize_from(&mut cursor).unwrap();
172 self.button_controller = deserialize_from(&mut cursor).unwrap();
173 self.audio_controller = deserialize_from(&mut cursor).unwrap();
174 self.control_registers = deserialize_from(&mut cursor).unwrap();
175 self.reserved_area_1 = deserialize_from(&mut cursor).unwrap();
176 self.reserved_area_2 = deserialize_from(&mut cursor).unwrap();
177 self.interrupt_controller = deserialize_from(&mut cursor).unwrap();
178 self.speed_controller = deserialize_from(&mut cursor).unwrap();
179 self.unmapped_memory = deserialize_from(&mut cursor).unwrap();
180 }
181
182 fn create_rom(rom_bytes: &[u8], cartridge_info: &CartridgeInfo) -> Box<dyn MBC> {
183 let rom_size = cartridge_info.rom_size;
184 let ram_size = cartridge_info.ram_size;
185 let mut rom: Box<dyn MBC> = match cartridge_info.cartridge_type {
186 CartridgeType::MBC => Box::new(MBC0::new(rom_size)),
187 CartridgeType::MBC1 => Box::new(MBC1::new(rom_size, ram_size)),
188 CartridgeType::MBC2 => Box::new(MBC2::new(rom_size)),
189 CartridgeType::MBC3 => Box::new(MBC3::new(rom_size, ram_size)),
190 CartridgeType::MBC5 => Box::new(MBC5::new(rom_size, ram_size)),
191 _ => panic!("This emulator currently does not support {:?} cartridges", cartridge_info.cartridge_type)
192 };
193 rom.load_bytes(0x0000, rom_bytes);
194 rom
195 }
196
197 pub fn press_button(&mut self, button: Button) {
198 self.button_controller.press_button(button, &mut self.interrupt_controller);
199 }
200
201 pub fn release_button(&mut self, button: Button) {
202 self.button_controller.release_button(button);
203 }
204
205 pub fn set_tile_atlas_rendering_enabled(&mut self, enabled: bool) {
206 self.renderer.set_render_target_enabled(RenderTarget::TileAtlas, enabled);
207 }
208
209 pub fn set_object_atlas_rendering_enabled(&mut self, enabled: bool) {
210 self.renderer.set_render_target_enabled(RenderTarget::ObjectAtlas, enabled);
211 }
212
213 pub fn is_paused(&self) -> bool {
214 self.paused
215 }
216
217 pub fn set_paused(&mut self, paused: bool) {
218 if paused {
219 self.audio_driver.mute_all();
220 } else {
221 self.audio_driver.unmute_all()
222 }
223 self.paused = paused;
224 }
225
226 pub fn cpu_info(&self) -> CPUInfo {
227 self.cpu.cpu_info()
228 }
229
230 pub fn get_instruction_label(mut self, address: u16) -> String {
231 let memory_bus = MemoryBus {
232 rom: self.rom.borrow_mut(),
233 vram: &mut self.vram,
234 wram: &mut self.wram,
235 reserved_area_1: &mut self.reserved_area_1,
236 oam: &mut self.oam,
237 reserved_area_2: &mut self.reserved_area_2,
238 button_controller: &mut self.button_controller,
239 timer: &mut self.timer,
240 interrupt_controller: &mut self.interrupt_controller,
241 speed_controller: &mut self.speed_controller,
242 audio_controller: &mut self.audio_controller,
243 lcd: &mut self.lcd,
244 dma: &mut self.dma,
245 cram: &mut self.cram,
246 control_registers: &mut self.control_registers,
247 stack: &mut self.stack,
248 unmapped_memory: &mut self.unmapped_memory,
249 };
250 InstructionLabelProvider::get_label(&memory_bus, address)
251 }
252
253 pub fn get_object(&self, object_index: u8) -> OAMObject {
254 self.oam.get_object(ObjectReference {
255 object_index,
256 use_bottom_tile: false,
257 }, self.lcd.use_8_x_16_tiles())
258 }
259
260 pub fn tick(&mut self) {
261 let double_speed = self.speed_controller.double_speed();
262 {
263 let mut memory_bus = MemoryBus {
264 rom: &mut self.rom,
265 vram: &mut self.vram,
266 wram: &mut self.wram,
267 reserved_area_1: &mut self.reserved_area_1,
268 oam: &mut self.oam,
269 reserved_area_2: &mut self.reserved_area_2,
270 button_controller: &mut self.button_controller,
271 timer: &mut self.timer,
272 interrupt_controller: &mut self.interrupt_controller,
273 speed_controller: &mut self.speed_controller,
274 audio_controller: &mut self.audio_controller,
275 lcd: &mut self.lcd,
276 dma: &mut self.dma,
277 cram: &mut self.cram,
278 control_registers: &mut self.control_registers,
279 stack: &mut self.stack,
280 unmapped_memory: &mut self.unmapped_memory,
281 };
282 self.cpu.tick(&mut memory_bus);
283 }
284 self.rom.tick(double_speed);
285 self.speed_controller.tick(&mut self.cpu);
286 self.button_controller.tick(&mut self.interrupt_controller);
287 self.audio_controller.tick(&mut self.audio_driver, &mut self.timer, double_speed);
288 self.timer.tick(&mut self.interrupt_controller);
289 self.lcd.tick(&self.vram, &self.cram, &self.oam, &mut self.renderer, &mut self.interrupt_controller, double_speed);
290 {
291 let mut dma_memory_bus = DMAMemoryBus {
292 rom: &mut self.rom,
293 vram: &mut self.vram,
294 wram: &mut self.wram,
295 oam: &mut self.oam,
296 };
297 self.dma.tick(&mut dma_memory_bus, &mut self.cpu, &self.lcd, double_speed);
298 }
299 }
300
301 pub fn execute_machine_cycle(&mut self) {
302 self.tick();
303 }
304
305 pub fn run_for_nanos(&mut self, nanos: u64) {
306 if !self.paused {
307 let mut remaining_nanos = nanos;
308 while remaining_nanos > 0 {
309 let double_speed = self.speed_controller.double_speed();
310 remaining_nanos = remaining_nanos.saturating_sub(if double_speed { 500 } else { 1000 });
311 self.tick();
312 }
313 }
314 }
315}