aboutsummaryrefslogtreecommitdiff
path: root/src/desktop/load_save.rs
diff options
context:
space:
mode:
authorAstatin <[email protected]>2025-05-22 14:07:19 +0200
committerAstatin <[email protected]>2025-05-22 14:07:19 +0200
commit0c7f945407561f7c4531b2780e908bb2098551d8 (patch)
tree082b5cef5430a787ca524b0f846be999e5633334 /src/desktop/load_save.rs
parent4fce95c86e12f91e127605d440118e1b6a64208b (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.rs131
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(())
}
}