diff options
author | Astatin <[email protected]> | 2025-05-22 14:07:19 +0200 |
---|---|---|
committer | Astatin <[email protected]> | 2025-05-22 14:07:19 +0200 |
commit | 0c7f945407561f7c4531b2780e908bb2098551d8 (patch) | |
tree | 082b5cef5430a787ca524b0f846be999e5633334 /src/desktop/load_save.rs | |
parent | 4fce95c86e12f91e127605d440118e1b6a64208b (diff) |
Add load/save parameters to the CLI & remove errors
Diffstat (limited to 'src/desktop/load_save.rs')
-rw-r--r-- | src/desktop/load_save.rs | 131 |
1 files changed, 104 insertions, 27 deletions
diff --git a/src/desktop/load_save.rs b/src/desktop/load_save.rs index 5c3a123..a7eadfc 100644 --- a/src/desktop/load_save.rs +++ b/src/desktop/load_save.rs @@ -76,45 +76,122 @@ impl LoadSave for FSLoadSave { Ok(()) } - fn save_state<S: Serial, A: Audio>(&self, state: &GBState<S, A>) { - if let Some(state_file) = &self.state_file { - { - let mut vram_dump_file = File::create(format!("{}.vram", state_file)).unwrap(); + fn dump_state<S: Serial, A: Audio>(&self, state: &GBState<S, A>) -> Result<(), std::io::Error> { + { + let mut vram_dump_file = File::create(format!("{}.vram.dump", self.rom_file))?; + + for addr in 0x8000..0xa000 { + vram_dump_file.write_all(format!("{:02X} ", state.mem.r(addr)).as_bytes())?; + } + } + + { + let mut wram_dump_file = File::create(format!("{}.wram.dump", self.rom_file))?; - for addr in 0x8000..0xa000 { - vram_dump_file - .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); - } + for addr in 0xc000..0xe000 { + wram_dump_file.write_all(format!("{:02X} ", state.mem.r(addr)).as_bytes())?; } + } - { - let mut wram_dump_file = File::create(format!("{}.wram", state_file)).unwrap(); + { + let mut io_dump_file = File::create(format!("{}.io.dump", self.rom_file))?; - for addr in 0xc000..0xe000 { - wram_dump_file - .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); - } + for addr in 0xff00..0xff80 { + io_dump_file.write_all(format!("{:02X} ", state.mem.r(addr)).as_bytes())?; } + } + + { + let mut hram_dump_file = File::create(format!("{}.hram.dump", self.rom_file))?; - { - let mut io_dump_file = File::create(format!("{}.io", state_file)).unwrap(); + for addr in 0xff80..=0xffff { + hram_dump_file.write_all(format!("{:02X} ", state.mem.r(addr)).as_bytes())?; + } + } + + { + let mut cpu_dump_file = File::create(format!("{}.cpu.dump", self.rom_file))?; + + for i in 0..8 { + cpu_dump_file.write_all(format!("{:02X} ", state.cpu.r[i]).as_bytes())?; + } + + cpu_dump_file.write_all(format!("{:04X} ", state.cpu.pc).as_bytes())?; + + cpu_dump_file.write_all(format!("{:04X} ", state.cpu.sp).as_bytes())?; + } + + Ok(()) + } - for addr in 0xff00..0xff80 { - io_dump_file - .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); - } + fn save_state<S: Serial, A: Audio>(&self, state: &GBState<S, A>) -> Result<(), std::io::Error> { + if let Some(state_file) = &self.state_file { + let mut state_file = File::create(state_file)?; + for addr in 0x8000..0xa000 { + state_file.write_all(&[state.mem.r(addr)])?; } - { - let mut hram_dump_file = File::create(format!("{}.hram", state_file)).unwrap(); + state_file.write_all(state.mem.wram_00.as_ref())?; + state_file.write_all(state.mem.wram_01.as_ref())?; - for addr in 0xff80..=0xffff { - hram_dump_file - .write_all(format!("{:02X} ", state.mem.r(addr).unwrap()).as_bytes()); - } + for addr in 0xff00..0xff80 { + state_file.write_all(&[state.mem.r(addr)])?; } + + state_file.write_all(state.mem.hram.as_ref())?; + state_file.write_all(&[state.mem.interrupts_register])?; + + state_file.write_all(&state.cpu.r)?; + state_file.write_all(&state.cpu.pc.to_le_bytes())?; + state_file.write_all(&state.cpu.sp.to_le_bytes())?; + state_file.write_all(&[state.mem.boot_rom_on.into(), state.mem.ime.into()])?; } else { - panic!("{:?}", self) + eprintln!("Tried to save state without state_file specified"); } + Ok(()) + } + + fn load_state<S: Serial, A: Audio>( + &self, + state: &mut GBState<S, A>, + ) -> Result<(), std::io::Error> { + if let Some(state_file) = &self.state_file { + let mut state_file = File::open(state_file)?; + + let mut vram = Box::new([0; 0x2000]); + state_file.read_exact(vram.as_mut())?; + for i in 0x0000..0x2000 { + state.mem.w(0x8000 + i, vram[i as usize]); + } + + state_file.read_exact(state.mem.wram_00.as_mut())?; + state_file.read_exact(state.mem.wram_01.as_mut())?; + + let mut io = [0; 0x80]; + state_file.read_exact(io.as_mut())?; + for i in 0x00..0x80 { + state.mem.w(0xff00 + i, io[i as usize]); + } + + state_file.read_exact(state.mem.hram.as_mut())?; + + let mut reg8 = [0; 1]; + state_file.read_exact(reg8.as_mut())?; + state.mem.interrupts_register = reg8[0]; + + state_file.read_exact(&mut state.cpu.r)?; + + let mut reg16 = [0; 2]; + state_file.read_exact(&mut reg16)?; + state.cpu.pc = u16::from_le_bytes(reg16); + state_file.read_exact(&mut reg16)?; + state.cpu.sp = u16::from_le_bytes(reg16); + + state_file.read_exact(reg8.as_mut())?; + state.mem.boot_rom_on = reg8[0] != 0; + state_file.read_exact(reg8.as_mut())?; + state.mem.ime = reg8[0] != 0; + } + Ok(()) } } |