From 769a587aaaeb6a00bc80a725c5b6cde44a11b056 Mon Sep 17 00:00:00 2001 From: Alex Janka Date: Sun, 22 Jan 2023 09:07:57 +1100 Subject: [PATCH] memory fixes, interrupt table, better pause --- src/main.rs | 71 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/src/main.rs b/src/main.rs index ae2a283..4d366ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,9 +45,11 @@ union Register { as_u16: u16, } +#[allow(dead_code)] pub struct Memory { bootrom: ROM, bootrom_enabled: bool, + interrupt_table: [u8; 256], rom: ROM, vram: [u8; 8192], ram: [u8; 8192], @@ -64,6 +66,7 @@ impl Memory { Self { bootrom, bootrom_enabled, + interrupt_table: [0xFF; 256], rom, vram: [0x0; 8192], ram: [0x0; 8192], @@ -72,13 +75,20 @@ impl Memory { oam: [0x0; 160], interrupts: 0x0, ime: false, - io: [0x0; 76], + io: [0xFF; 76], } } fn get(&self, address: Address) -> u8 { match address { - 0x0..0x8000 => { + 0x0..0x100 => { + if self.bootrom_enabled { + return self.bootrom[address as usize]; + } else { + return self.interrupt_table[address as usize]; + } + } + 0x100..0x8000 => { // rom access // todo - switchable rom banks if self.bootrom_enabled && (address as usize) < self.bootrom.len() { @@ -91,7 +101,7 @@ impl Memory { return self.vram[(address - 0x8000) as usize]; } 0xA000..0xC000 => { - return self.switchable_ram[(address - 0xA000) as usize]; + 0xFF } 0xC000..0xE000 => { return self.ram[(address - 0xC000) as usize]; @@ -110,7 +120,7 @@ impl Memory { } 0xFF4C..0xFF80 => { // println!("empty space 2 read"); - return 0x0; + return 0xFF; } 0xFF80..0xFFFF => { return self.cpu_ram[(address - 0xFF80) as usize]; @@ -123,7 +133,13 @@ impl Memory { fn set(&mut self, address: Address, data: u8) { match address { - 0x0..0x8000 => { + 0x0..0x100 => { + if !self.bootrom_enabled { + self.interrupt_table[address as usize] = data; + // panic!("setting {:#X} to {:#X}", address, data) + } + } + 0x100..0x8000 => { // change this with MBC code... // println!("tried to write {:#5X} at {:#X}", data, address); } @@ -131,7 +147,8 @@ impl Memory { self.vram[(address - 0x8000) as usize] = data; } 0xA000..0xC000 => { - self.switchable_ram[(address - 0xA000) as usize] = data; + // panic!("switchable write"); + // self.switchable_ram[(address - 0xA000) as usize] = data; } 0xC000..0xE000 => { self.ram[(address - 0xC000) as usize] = data; @@ -184,7 +201,8 @@ impl Default for State { fn default() -> Self { // default post-bootrom values Self { - af: Register { as_u16: 0x01B0 }, + af: Register { as_u16: 0x00B0 }, + // af: Register { as_u16: 0x01B0 }, bc: Register { as_u16: 0x0013 }, de: Register { as_u16: 0x00D8 }, hl: Register { as_u16: 0x014D }, @@ -194,6 +212,9 @@ impl Default for State { } } +static mut PAUSE_ENABLED: bool = false; +static mut PAUSE_QUEUED: bool = false; + fn main() { let args = Args::parse(); @@ -213,6 +234,9 @@ fn main() { cpu_ram_init(&mut cpu); #[allow(unused_variables)] let mut cycle_num = 0; + let mut instructions_seen = vec![]; + let mut last_state = cpu.state.clone(); + let mut next_state: State; match args.step_by { Some(step_size) => loop { for _ in 0..step_size { @@ -231,21 +255,50 @@ fn main() { pause(); }, None => loop { + let will_pause; + unsafe { + will_pause = PAUSE_QUEUED.clone(); + } cycle_num += 1; // print_cycles(&cycle_num); cpu.exec_next(); + unsafe { + next_state = cpu.state; + if !PAUSE_ENABLED { + if next_state.pc.as_u16 >= 0x100 { + PAUSE_ENABLED = true; + } + } + last_state = next_state; + if will_pause { + pause(); + } + } + match instructions_seen.contains(&cpu.last_instruction) { + true => {} + false => { + // println!("new instruction enountered: {:#X}", cpu.last_instruction); + instructions_seen.push(cpu.last_instruction); + } + } }, } } #[allow(dead_code)] fn pause() { - io::stdin().read_line(&mut String::new()).unwrap(); + unsafe { + if PAUSE_ENABLED { + let line = &mut String::new(); + io::stdin().read_line(line).unwrap(); + PAUSE_QUEUED = !line.contains("continue"); + } + } } #[allow(dead_code)] fn print_cycles(cycles: &i32) { - if *cycles % 456 != 0 { + if *cycles % 456789 != 0 { return; } let instructions_per_second = 400000;