remove save states (they didnt work)

This commit is contained in:
Alex Janka 2023-05-18 10:29:53 +10:00
parent f1b3cabef9
commit 087bef7dc4
18 changed files with 18 additions and 696 deletions

View file

@ -9,7 +9,6 @@ crate-type = ["cdylib", "rlib"]
[features] [features]
default = [] default = []
savestate = []
[dependencies] [dependencies]
gb-emu-lib = { path = "../lib" } gb-emu-lib = { path = "../lib" }

View file

@ -15,31 +15,8 @@ use std::sync::{
}; };
use ui::{Emulator, EmulatorRenderer}; use ui::{Emulator, EmulatorRenderer};
#[cfg(feature = "savestate")]
use gb_emu_lib::connect::CpuSaveState;
mod ui; mod ui;
#[cfg(feature = "savestate")]
#[derive(Default)]
struct SaveStateParam {
state: Arc<Mutex<Option<CpuSaveState<[u8; 4]>>>>,
}
#[cfg(feature = "savestate")]
impl PersistentField<'_, Option<CpuSaveState<[u8; 4]>>> for SaveStateParam {
fn set(&self, new_value: Option<CpuSaveState<[u8; 4]>>) {
*self.state.lock().unwrap() = new_value;
}
fn map<F, R>(&self, f: F) -> R
where
F: Fn(&Option<CpuSaveState<[u8; 4]>>) -> R,
{
f(&self.state.lock().unwrap())
}
}
#[derive(Default)] #[derive(Default)]
struct SramParam { struct SramParam {
state: Arc<RwLock<Vec<u8>>>, state: Arc<RwLock<Vec<u8>>>,
@ -64,9 +41,6 @@ impl PersistentField<'_, Vec<u8>> for SramParam {
struct EmuParams { struct EmuParams {
#[persist = "sram"] #[persist = "sram"]
sram_save: SramParam, sram_save: SramParam,
// #[cfg(feature = "savestate")]
// #[persist = "save_state"]
// last_save_state: SaveStateParam,
} }
struct EmuVars { struct EmuVars {
@ -218,7 +192,6 @@ impl Plugin for GameboyEmu {
} else { } else {
while context.next_event().is_some() {} while context.next_event().is_some() {}
} }
self.update_save_state();
ProcessStatus::KeepAlive ProcessStatus::KeepAlive
} }
@ -266,19 +239,6 @@ impl Plugin for GameboyEmu {
tx: None, tx: None,
}; };
#[cfg(feature = "savestate")]
let mut emulator_core = if let Some(state) =
self.params.last_save_state.state.lock().unwrap().take()
{
EmulatorCore::from_save_state(state, rom, receiver, window, output, serial_target)
} else {
let options = gb_emu_lib::Options::new(window, rom, output)
.with_serial_target(serial_target)
.force_no_save();
EmulatorCore::init(receiver, options)
};
#[cfg(not(feature = "savestate"))]
let mut emulator_core = { let mut emulator_core = {
let options = EmulatorOptions::new(window, rom, output) let options = EmulatorOptions::new(window, rom, output)
.with_serial_target(serial_target) .with_serial_target(serial_target)
@ -295,14 +255,12 @@ impl Plugin for GameboyEmu {
emulator_core, emulator_core,
serial_tx, serial_tx,
}); });
self.update_save_state();
} }
true true
} }
fn deactivate(&mut self) { fn deactivate(&mut self) {
self.update_save_state();
if let Some(ref mut vars) = self.vars { if let Some(ref mut vars) = self.vars {
match vars.sender.send(EmulatorMessage::Stop) { match vars.sender.send(EmulatorMessage::Stop) {
Ok(_) => self.vars = None, Ok(_) => self.vars = None,
@ -312,16 +270,6 @@ impl Plugin for GameboyEmu {
} }
} }
impl GameboyEmu {
fn update_save_state(&mut self) {
#[cfg(feature = "savestate")]
if let Some(ref mut vars) = self.vars {
*self.params.last_save_state.state.lock().unwrap() =
Some(vars.emulator_core.get_save_state());
}
}
}
impl Vst3Plugin for GameboyEmu { impl Vst3Plugin for GameboyEmu {
const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula"; const VST3_CLASS_ID: [u8; 16] = *b"alexjankagbemula";

View file

@ -4,7 +4,6 @@ use std::sync::{Arc, Mutex, RwLock};
pub use crate::processor::memory::mmio::gpu::Colour; pub use crate::processor::memory::mmio::gpu::Colour;
pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState}; pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState};
pub use crate::processor::memory::mmio::serial::SerialTarget; pub use crate::processor::memory::mmio::serial::SerialTarget;
pub use crate::processor::CpuSaveState;
pub use crate::{HEIGHT, WIDTH}; pub use crate::{HEIGHT, WIDTH};
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb}; use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};

View file

@ -6,7 +6,7 @@ use crate::{
}; };
use connect::{ use connect::{
AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorCoreTrait, EmulatorMessage, AudioOutput, CameraWrapper, CameraWrapperRef, EmulatorCoreTrait, EmulatorMessage,
EmulatorOptions, NoCamera, PocketCamera, Renderer, RomFile, SerialTarget, SramType, EmulatorOptions, PocketCamera, Renderer, RomFile, SramType,
}; };
use processor::{ use processor::{
memory::{ memory::{
@ -14,7 +14,7 @@ use processor::{
rom::{sram_save::SaveDataLocation, CgbRomType}, rom::{sram_save::SaveDataLocation, CgbRomType},
OutputTargets, Rom, OutputTargets, Rom,
}, },
Cpu, CpuSaveState, Cpu,
}; };
use std::{ use std::{
fs::{self}, fs::{self},
@ -186,13 +186,6 @@ where
} }
} }
} }
pub fn get_save_state(&self) -> CpuSaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
CpuSaveState::create(&self.cpu)
}
} }
impl<ColourFormat, R, C> EmulatorCoreTrait for EmulatorCore<ColourFormat, R, C> impl<ColourFormat, R, C> EmulatorCoreTrait for EmulatorCore<ColourFormat, R, C>
@ -254,41 +247,3 @@ where
} }
} }
} }
impl<ColourFormat, R> EmulatorCore<ColourFormat, R, NoCamera>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
pub fn from_save_state(
state: CpuSaveState<ColourFormat, R>,
rom: RomFile,
receiver: Receiver<EmulatorMessage>,
window: R,
output: AudioOutput,
serial_target: SerialTarget,
) -> Self {
let data = match rom {
RomFile::Path(path) => match fs::read(path) {
Ok(data) => data,
Err(e) => {
println!("Error reading ROM: {e}");
exit(1);
}
},
RomFile::Raw(data) => data,
};
Self {
receiver,
cpu: Cpu::from_save_state(
state,
data,
window,
output,
serial_target,
Arc::new(Mutex::new(CameraWrapper::new(NoCamera::default()))),
),
spooky: PhantomData,
}
}
}

View file

@ -4,13 +4,10 @@ pub use self::rom::Rom;
use self::{ use self::{
addresses::{Address, AddressMarker, CgbIoAddress, IoAddress}, addresses::{Address, AddressMarker, CgbIoAddress, IoAddress},
mmio::{ mmio::{
apu::ApuSaveState,
cgb::{DoubleSpeed, Infrared, VramDma}, cgb::{DoubleSpeed, Infrared, VramDma},
gpu::{Colour, GpuSaveState}, gpu::Colour,
serial::SerialSaveState,
Apu, Gpu, Joypad, OamDma, Serial, Timer, Apu, Gpu, Joypad, OamDma, Serial, Timer,
}, },
rom::RomSaveState,
}; };
use crate::{ use crate::{
connect::{AudioOutput, CameraWrapperRef, JoypadState, PocketCamera, Renderer, SerialTarget}, connect::{AudioOutput, CameraWrapperRef, JoypadState, PocketCamera, Renderer, SerialTarget},
@ -112,56 +109,6 @@ where
cgb_peripherals: Option<CgbPeripherals>, cgb_peripherals: Option<CgbPeripherals>,
} }
#[serde_with::serde_as]
#[derive(Serialize, Deserialize)]
pub struct MemorySaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
rom: RomSaveState,
ram: Wram,
#[serde_as(as = "[_; 128]")]
cpu_ram: [u8; 128],
pub(super) interrupts: Interrupts,
pub(super) ime: bool,
pub(super) ime_scheduled: u8,
pub(super) user_mode: bool,
oam_dma: OamDma,
joypad: Joypad,
gpu: GpuSaveState<ColourFormat, R>,
apu: ApuSaveState,
serial: SerialSaveState,
timers: Timer,
cgb_peripherals: Option<CgbPeripherals>,
}
impl<ColourFormat, R> MemorySaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
// C: PocketCamera + Send + 'static,
{
pub fn create<C: PocketCamera + Send + 'static>(memory: &Memory<ColourFormat, R, C>) -> Self {
Self {
rom: RomSaveState::create(&memory.rom),
ram: memory.ram.clone(),
cpu_ram: memory.cpu_ram,
interrupts: memory.interrupts,
ime: memory.ime,
ime_scheduled: memory.ime_scheduled,
user_mode: memory.user_mode,
oam_dma: memory.oam_dma,
joypad: memory.joypad,
gpu: GpuSaveState::create(&memory.gpu),
apu: ApuSaveState::create(&memory.apu),
serial: SerialSaveState::create(&memory.serial),
timers: memory.timers,
cgb_peripherals: memory.cgb_peripherals,
}
}
}
pub(crate) struct OutputTargets<ColourFormat, R, C> pub(crate) struct OutputTargets<ColourFormat, R, C>
where where
ColourFormat: From<Colour> + Clone, ColourFormat: From<Colour> + Clone,
@ -455,34 +402,6 @@ where
pub fn replace_output(&mut self, new: AudioOutput) { pub fn replace_output(&mut self, new: AudioOutput) {
self.apu.replace_output(new); self.apu.replace_output(new);
} }
pub(crate) fn from_save_state(
state: MemorySaveState<ColourFormat, R>,
data: Vec<u8>,
window: R,
output: AudioOutput,
serial_target: SerialTarget,
camera: CameraWrapperRef<C>,
) -> Self {
Self {
bootrom: None,
rom: Rom::from_save_state(state.rom, data, camera.clone()),
ram: state.ram,
cpu_ram: state.cpu_ram,
interrupts: state.interrupts,
ime: state.ime,
ime_scheduled: state.ime_scheduled,
user_mode: state.user_mode,
oam_dma: state.oam_dma,
joypad: state.joypad,
gpu: Gpu::from_save_state(state.gpu, window, None),
apu: Apu::from_save_state(state.apu, output),
serial: Serial::from_save_state(state.serial, serial_target),
timers: state.timers,
camera,
cgb_peripherals: state.cgb_peripherals,
}
}
} }
impl<ColourFormat, R, C> Cpu<ColourFormat, R, C> impl<ColourFormat, R, C> Cpu<ColourFormat, R, C>

View file

@ -9,7 +9,6 @@ use crate::{
}; };
use futures::executor; use futures::executor;
use itertools::izip; use itertools::izip;
use serde::{Deserialize, Serialize};
mod channels; mod channels;
mod downsampler; mod downsampler;
@ -46,27 +45,6 @@ pub struct Apu {
output: AudioOutput, output: AudioOutput,
} }
#[derive(Serialize, Deserialize)]
pub struct ApuSaveState {
apu_enable: bool,
channels: Channels,
vin: VinEnable,
mixer: Mixer,
div_apu: u8,
}
impl ApuSaveState {
pub fn create(apu: &Apu) -> Self {
Self {
apu_enable: apu.apu_enable,
channels: apu.channels,
vin: apu.vin,
mixer: apu.mixer,
div_apu: apu.div_apu,
}
}
}
impl Apu { impl Apu {
pub fn new(output: AudioOutput) -> Self { pub fn new(output: AudioOutput) -> Self {
Self { Self {
@ -80,18 +58,6 @@ impl Apu {
} }
} }
pub fn from_save_state(state: ApuSaveState, output: AudioOutput) -> Self {
Self {
apu_enable: state.apu_enable,
channels: state.channels,
vin: state.vin,
mixer: state.mixer,
div_apu: state.div_apu,
converter: Downsampler::new(output.sample_rate, output.downsample_type),
output,
}
}
pub fn replace_output(&mut self, new: AudioOutput) { pub fn replace_output(&mut self, new: AudioOutput) {
self.converter = Downsampler::new(new.sample_rate, new.downsample_type); self.converter = Downsampler::new(new.sample_rate, new.downsample_type);
self.output = new; self.output = new;

View file

@ -1,5 +1,3 @@
use std::marker::PhantomData;
pub(crate) use self::types::DrawMode; pub(crate) use self::types::DrawMode;
use self::{ use self::{
cgb::CgbData, cgb::CgbData,
@ -15,7 +13,6 @@ use crate::{
util::{clear_bit, get_bit}, util::{clear_bit, get_bit},
HEIGHT, WIDTH, HEIGHT, WIDTH,
}; };
use serde::{Deserialize, Serialize};
pub use types::Colour; pub use types::Colour;
mod addresses; mod addresses;
@ -56,70 +53,6 @@ where
cgb_data: Option<CgbData>, cgb_data: Option<CgbData>,
} }
#[derive(Serialize, Deserialize)]
pub struct GpuSaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
buffer: Vec<ColourFormat>,
vram: Vram,
oam: Oam,
is_bg_zero: Vec<bool>,
is_bg_priority: Vec<bool>,
lcdc: Lcdc,
stat: Stat,
mode_clock: usize,
scanline: u8,
lyc: u8,
window_lc: u8,
has_window_been_enabled: bool,
bg_palette: Palette,
obj_palette_0: Palette,
obj_palette_1: Palette,
scx: u8,
scy: u8,
wx: u8,
wy: u8,
prev_stat: bool,
cgb_data: Option<CgbData>,
#[serde(skip)]
spooky: PhantomData<R>,
}
impl<ColourFormat, R> GpuSaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
pub fn create(gpu: &Gpu<ColourFormat, R>) -> Self {
Self {
buffer: gpu.buffer.clone(),
vram: gpu.vram.clone(),
oam: gpu.oam,
is_bg_zero: gpu.is_bg_zero.clone(),
is_bg_priority: gpu.is_bg_priority.clone(),
lcdc: gpu.lcdc,
stat: gpu.stat,
mode_clock: gpu.mode_clock,
scanline: gpu.scanline,
lyc: gpu.lyc,
window_lc: gpu.window_lc,
has_window_been_enabled: gpu.has_window_been_enabled,
bg_palette: gpu.bg_palette,
obj_palette_0: gpu.obj_palette_0,
obj_palette_1: gpu.obj_palette_1,
scx: gpu.scx,
scy: gpu.scy,
wx: gpu.wx,
wy: gpu.wy,
prev_stat: gpu.prev_stat,
cgb_data: gpu.cgb_data,
spooky: PhantomData,
}
}
}
impl<ColourFormat, R> Gpu<ColourFormat, R> impl<ColourFormat, R> Gpu<ColourFormat, R>
where where
ColourFormat: From<Colour> + Clone, ColourFormat: From<Colour> + Clone,
@ -157,47 +90,6 @@ where
} }
} }
pub fn from_save_state(
state: GpuSaveState<ColourFormat, R>,
window: R,
tile_window_renderer: Option<R>,
) -> Self {
let tile_window = if let Some(tile_window_renderer) = tile_window_renderer {
Some(TileWindow::new(
tile_window_renderer,
state.cgb_data.is_some(),
))
} else {
None
};
Self {
buffer: state.buffer,
vram: state.vram,
oam: state.oam,
window,
is_bg_zero: state.is_bg_zero,
is_bg_priority: state.is_bg_priority,
lcdc: state.lcdc,
stat: state.stat,
mode_clock: state.mode_clock,
scanline: state.scanline,
lyc: state.lyc,
tile_window,
window_lc: state.window_lc,
has_window_been_enabled: state.has_window_been_enabled,
bg_palette: state.bg_palette,
obj_palette_0: state.obj_palette_0,
obj_palette_1: state.obj_palette_1,
scx: state.scx,
scy: state.scy,
wx: state.wx,
wy: state.wy,
prev_stat: state.prev_stat,
cgb_data: state.cgb_data,
}
}
pub(crate) fn get_mode(&self) -> DrawMode { pub(crate) fn get_mode(&self) -> DrawMode {
self.stat.mode self.stat.mode
} }

View file

@ -111,31 +111,6 @@ pub struct Serial {
clock_inc: usize, clock_inc: usize,
} }
#[derive(Serialize, Deserialize)]
pub struct SerialSaveState {
byte: u8,
output_byte: u8,
input_byte: InputByte,
bits_remaining: u8,
control: SerialControl,
#[cfg(feature = "clocked-serial")]
clock_inc: usize,
}
impl SerialSaveState {
pub fn create(serial: &Serial) -> Self {
Self {
byte: serial.byte,
output_byte: serial.output_byte,
input_byte: serial.input_byte,
bits_remaining: serial.bits_remaining,
control: serial.control,
#[cfg(feature = "clocked-serial")]
clock_inc: serial.clock_inc,
}
}
}
impl Serial { impl Serial {
pub fn new(target: SerialTarget) -> Self { pub fn new(target: SerialTarget) -> Self {
Self { Self {
@ -150,19 +125,6 @@ impl Serial {
} }
} }
pub fn from_save_state(state: SerialSaveState, target: SerialTarget) -> Self {
Self {
byte: state.byte,
output_byte: state.output_byte,
input_byte: state.input_byte,
bits_remaining: state.bits_remaining,
control: state.control,
target,
#[cfg(feature = "clocked-serial")]
clock_inc: state.clock_inc,
}
}
fn is_connected(&self) -> bool { fn is_connected(&self) -> bool {
!matches!(&self.target, SerialTarget::None) !matches!(&self.target, SerialTarget::None)
} }

View file

@ -1,8 +1,5 @@
use self::{ use self::{
mbcs::{ mbcs::{Mbc, Mbc1, Mbc2, Mbc3, Mbc5, None, PocketCamera},
Mbc, Mbc1, Mbc1SaveState, Mbc2, Mbc2SaveState, Mbc3, Mbc3SaveState, Mbc5, Mbc5SaveState,
None, PocketCamera, PocketCameraSaveState,
},
sram_save::SaveDataLocation, sram_save::SaveDataLocation,
}; };
use crate::connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait}; use crate::connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait};
@ -31,50 +28,6 @@ where
spooky: PhantomData<C>, spooky: PhantomData<C>,
} }
#[derive(Serialize, Deserialize)]
pub struct RomSaveState {
title: String,
mbc: MbcSaveState,
}
impl RomSaveState {
pub fn create<C: PocketCameraTrait>(rom: &Rom<C>) -> Self {
Self {
title: rom.title.clone(),
mbc: rom.mbc.get_save_state(),
}
}
}
#[derive(Serialize, Deserialize)]
enum MbcSaveState {
Mbc1(Mbc1SaveState),
Mbc2(Mbc2SaveState),
Mbc3(Mbc3SaveState),
Mbc5(Mbc5SaveState),
PocketCamera(PocketCameraSaveState),
None,
}
impl MbcSaveState {
fn get_mbc<C: PocketCameraTrait + Send + 'static>(
self,
data: Vec<u8>,
camera: CameraWrapperRef<C>,
) -> Box<dyn Mbc> {
match self {
MbcSaveState::Mbc1(state) => Box::new(Mbc1::from_save_state(state, data)),
MbcSaveState::Mbc2(state) => Box::new(Mbc2::from_save_state(state, data)),
MbcSaveState::Mbc3(state) => Box::new(Mbc3::from_save_state(state, data)),
MbcSaveState::Mbc5(state) => Box::new(Mbc5::from_save_state(state, data)),
MbcSaveState::None => Box::new(None::init(data)),
MbcSaveState::PocketCamera(state) => {
Box::new(PocketCamera::from_save_state(state, data, camera))
}
}
}
}
impl<C> Rom<C> impl<C> Rom<C>
where where
C: PocketCameraTrait + Send + 'static, C: PocketCameraTrait + Send + 'static,
@ -135,20 +88,6 @@ where
} }
} }
pub(crate) fn from_save_state(
state: RomSaveState,
data: Vec<u8>,
camera: CameraWrapperRef<C>,
) -> Self {
let rom_type = get_cgb_rom_type(data[0x143]);
Self {
title: state.title,
mbc: state.mbc.get_mbc(data, camera),
rom_type,
spooky: PhantomData,
}
}
pub fn get_title(&self) -> &String { pub fn get_title(&self) -> &String {
&self.title &self.title
} }

View file

@ -6,14 +6,12 @@ mod mbc3;
mod mbc5; mod mbc5;
mod none; mod none;
mod pocketcamera; mod pocketcamera;
pub use mbc1::{Mbc1, Mbc1SaveState}; pub use mbc1::Mbc1;
pub use mbc2::{Mbc2, Mbc2SaveState}; pub use mbc2::Mbc2;
pub use mbc3::{Mbc3, Mbc3SaveState}; pub use mbc3::Mbc3;
pub use mbc5::{Mbc5, Mbc5SaveState}; pub use mbc5::Mbc5;
pub use none::None; pub use none::None;
pub use pocketcamera::{PocketCamera, PocketCameraSaveState}; pub use pocketcamera::PocketCamera;
use super::MbcSaveState;
pub(super) const KB: usize = 1024; pub(super) const KB: usize = 1024;
const ROM_BANK_SIZE: usize = 16 * KB; const ROM_BANK_SIZE: usize = 16 * KB;
@ -27,7 +25,6 @@ pub(super) trait Mbc: Send {
fn set(&mut self, address: RomAddress, data: u8); fn set(&mut self, address: RomAddress, data: u8);
fn set_ram(&mut self, address: CartRamAddress, data: u8); fn set_ram(&mut self, address: CartRamAddress, data: u8);
fn mbc_type(&self) -> String; fn mbc_type(&self) -> String;
fn get_save_state(&self) -> MbcSaveState;
fn is_rumbling(&self) -> bool { fn is_rumbling(&self) -> bool {
false false
} }

View file

@ -1,10 +1,7 @@
use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE}; use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE};
use crate::processor::memory::{ use crate::processor::memory::{
addresses::{AddressMarker, CartRamAddress, RomAddress}, addresses::{AddressMarker, CartRamAddress, RomAddress},
rom::{ rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
MbcSaveState,
},
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -25,17 +22,6 @@ pub struct Mbc1 {
bank_mode: BankingMode, bank_mode: BankingMode,
} }
#[derive(Serialize, Deserialize)]
pub struct Mbc1SaveState {
rom_len: usize,
rom_bank: u8,
ram_enabled: bool,
ram: Option<SramSaveState>,
ram_bank: u8,
upper_banks: u8,
bank_mode: BankingMode,
}
impl Mbc1 { impl Mbc1 {
pub fn init( pub fn init(
data: Vec<u8>, data: Vec<u8>,
@ -86,19 +72,6 @@ impl Mbc1 {
} }
} }
} }
pub fn from_save_state(state: Mbc1SaveState, data: Vec<u8>) -> Self {
Self {
data,
rom_len: state.rom_len,
rom_bank: state.rom_bank,
ram_enabled: state.ram_enabled,
ram: state.ram.map(MaybeBufferedSram::from_save_state),
ram_bank: state.ram_bank,
upper_banks: state.upper_banks,
bank_mode: state.bank_mode,
}
}
} }
impl Mbc for Mbc1 { impl Mbc for Mbc1 {
@ -165,16 +138,4 @@ impl Mbc for Mbc1 {
ram.flush(); ram.flush();
} }
} }
fn get_save_state(&self) -> MbcSaveState {
MbcSaveState::Mbc1(Mbc1SaveState {
rom_len: self.rom_len,
rom_bank: self.rom_bank,
ram_enabled: self.ram_enabled,
ram: self.ram.as_ref().map(SramSaveState::create),
ram_bank: self.ram_bank,
upper_banks: self.upper_banks,
bank_mode: self.bank_mode,
})
}
} }

View file

@ -1,13 +1,8 @@
use super::{rom_banks, Mbc, ROM_BANK_SIZE};
use crate::processor::memory::{ use crate::processor::memory::{
addresses::{AddressMarker, CartRamAddress, RomAddress}, addresses::{AddressMarker, CartRamAddress, RomAddress},
rom::{ rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
MbcSaveState,
},
}; };
use serde::{Deserialize, Serialize};
use super::{rom_banks, Mbc, ROM_BANK_SIZE};
pub struct Mbc2 { pub struct Mbc2 {
data: Vec<u8>, data: Vec<u8>,
@ -17,14 +12,6 @@ pub struct Mbc2 {
ram_enabled: bool, ram_enabled: bool,
} }
#[derive(Serialize, Deserialize)]
pub struct Mbc2SaveState {
rom_len: usize,
rom_bank: u8,
ram: SramSaveState,
ram_enabled: bool,
}
impl Mbc2 { impl Mbc2 {
pub fn init(data: Vec<u8>, rom_size: u8, save_file: Option<SaveDataLocation>) -> Self { pub fn init(data: Vec<u8>, rom_size: u8, save_file: Option<SaveDataLocation>) -> Self {
let rom_len = rom_banks(rom_size) * ROM_BANK_SIZE; let rom_len = rom_banks(rom_size) * ROM_BANK_SIZE;
@ -38,16 +25,6 @@ impl Mbc2 {
ram_enabled: false, ram_enabled: false,
} }
} }
pub fn from_save_state(state: Mbc2SaveState, data: Vec<u8>) -> Self {
Self {
data,
rom_len: state.rom_len,
rom_bank: state.rom_bank,
ram: MaybeBufferedSram::from_save_state(state.ram),
ram_enabled: state.ram_enabled,
}
}
} }
impl Mbc for Mbc2 { impl Mbc for Mbc2 {
@ -97,13 +74,4 @@ impl Mbc for Mbc2 {
fn flush(&mut self) { fn flush(&mut self) {
self.ram.flush(); self.ram.flush();
} }
fn get_save_state(&self) -> MbcSaveState {
MbcSaveState::Mbc2(Mbc2SaveState {
rom_len: self.rom_len,
rom_bank: self.rom_bank,
ram: SramSaveState::create(&self.ram),
ram_enabled: self.ram_enabled,
})
}
} }

View file

@ -2,10 +2,7 @@ use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE};
use crate::{ use crate::{
processor::memory::{ processor::memory::{
addresses::{AddressMarker, CartRamAddress, RomAddress}, addresses::{AddressMarker, CartRamAddress, RomAddress},
rom::{ rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
MbcSaveState,
},
}, },
util::set_or_clear_bit, util::set_or_clear_bit,
}; };
@ -95,16 +92,6 @@ pub struct Mbc3 {
// TODO - save/load rtc!! // TODO - save/load rtc!!
} }
#[derive(Serialize, Deserialize)]
pub struct Mbc3SaveState {
rom_bank: u8,
rom_size: usize,
ram: Option<SramSaveState>,
ram_bank: RamBank,
ram_size: usize,
ram_enabled: bool,
}
impl Mbc3 { impl Mbc3 {
pub fn init( pub fn init(
data: Vec<u8>, data: Vec<u8>,
@ -139,20 +126,6 @@ impl Mbc3 {
fn get_ram_addr(&self, address: CartRamAddress, ram_bank: usize) -> usize { fn get_ram_addr(&self, address: CartRamAddress, ram_bank: usize) -> usize {
((address.get_local() as usize) + (RAM_BANK_SIZE * ram_bank)) % self.ram_size ((address.get_local() as usize) + (RAM_BANK_SIZE * ram_bank)) % self.ram_size
} }
pub fn from_save_state(state: Mbc3SaveState, data: Vec<u8>) -> Self {
// TODO - FIX RTC!!!
Self {
data,
rom_bank: state.rom_bank,
rom_size: state.rom_size,
ram: state.ram.map(MaybeBufferedSram::from_save_state),
ram_bank: state.ram_bank,
ram_size: state.ram_size,
ram_enabled: state.ram_enabled,
rtc: None,
}
}
} }
impl Mbc for Mbc3 { impl Mbc for Mbc3 {
@ -255,15 +228,4 @@ impl Mbc for Mbc3 {
ram.flush(); ram.flush();
} }
} }
fn get_save_state(&self) -> MbcSaveState {
MbcSaveState::Mbc3(Mbc3SaveState {
rom_bank: self.rom_bank,
rom_size: self.rom_size,
ram: self.ram.as_ref().map(SramSaveState::create),
ram_bank: self.ram_bank,
ram_size: self.ram_size,
ram_enabled: self.ram_enabled,
})
}
} }

View file

@ -1,14 +1,10 @@
use crate::{ use crate::{
processor::memory::{ processor::memory::{
addresses::{AddressMarker, CartRamAddress, RomAddress}, addresses::{AddressMarker, CartRamAddress, RomAddress},
rom::{ rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation, SramSaveState},
MbcSaveState,
},
}, },
util::get_bit, util::get_bit,
}; };
use serde::{Deserialize, Serialize};
use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE}; use super::{ram_size_kb, rom_banks, Mbc, KB, RAM_BANK_SIZE, ROM_BANK_SIZE};
@ -24,18 +20,6 @@ pub struct Mbc5 {
is_rumbling: bool, is_rumbling: bool,
} }
#[derive(Serialize, Deserialize)]
pub struct Mbc5SaveState {
rom_bank: u16,
rom_size: usize,
ram: Option<SramSaveState>,
ram_bank: u8,
ram_size: usize,
ram_enabled: bool,
rumble: bool,
is_rumbling: bool,
}
impl Mbc5 { impl Mbc5 {
pub fn init( pub fn init(
data: Vec<u8>, data: Vec<u8>,
@ -71,20 +55,6 @@ impl Mbc5 {
fn get_ram_addr(&self, address: CartRamAddress) -> usize { fn get_ram_addr(&self, address: CartRamAddress) -> usize {
((address.get_local() as usize) + (RAM_BANK_SIZE * self.ram_bank as usize)) % self.ram_size ((address.get_local() as usize) + (RAM_BANK_SIZE * self.ram_bank as usize)) % self.ram_size
} }
pub fn from_save_state(state: Mbc5SaveState, data: Vec<u8>) -> Self {
Self {
data,
rom_bank: state.rom_bank,
rom_size: state.rom_size,
ram: state.ram.map(MaybeBufferedSram::from_save_state),
ram_bank: state.ram_bank,
ram_size: state.ram_size,
ram_enabled: state.ram_enabled,
rumble: state.rumble,
is_rumbling: state.is_rumbling,
}
}
} }
impl Mbc for Mbc5 { impl Mbc for Mbc5 {
@ -157,17 +127,4 @@ impl Mbc for Mbc5 {
ram.flush(); ram.flush();
} }
} }
fn get_save_state(&self) -> MbcSaveState {
MbcSaveState::Mbc5(Mbc5SaveState {
rom_bank: self.rom_bank,
rom_size: self.rom_size,
ram: self.ram.as_ref().map(SramSaveState::create),
ram_bank: self.ram_bank,
ram_size: self.ram_size,
ram_enabled: self.ram_enabled,
rumble: self.rumble,
is_rumbling: self.is_rumbling,
})
}
} }

View file

@ -1,8 +1,5 @@
use super::Mbc; use super::Mbc;
use crate::processor::memory::{ use crate::processor::memory::addresses::{AddressMarker, CartRamAddress, RomAddress};
addresses::{AddressMarker, CartRamAddress, RomAddress},
rom::MbcSaveState,
};
pub struct None { pub struct None {
data: Vec<u8>, data: Vec<u8>,
@ -30,8 +27,4 @@ impl Mbc for None {
fn mbc_type(&self) -> String { fn mbc_type(&self) -> String {
String::from("None") String::from("None")
} }
fn get_save_state(&self) -> MbcSaveState {
MbcSaveState::None
}
} }

View file

@ -3,13 +3,9 @@ use crate::{
connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait}, connect::{CameraWrapperRef, PocketCamera as PocketCameraTrait},
processor::memory::{ processor::memory::{
addresses::{AddressMarker, CartRamAddress, RomAddress}, addresses::{AddressMarker, CartRamAddress, RomAddress},
rom::{ rom::sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
sram_save::{BufferedSramTrait, MaybeBufferedSram, SaveDataLocation},
MbcSaveState,
},
}, },
}; };
use serde::{Deserialize, Serialize};
enum RamBank { enum RamBank {
Ram(u8), Ram(u8),
@ -32,9 +28,6 @@ where
camera_ram: [u8; 53], camera_ram: [u8; 53],
} }
#[derive(Serialize, Deserialize)]
pub struct PocketCameraSaveState;
impl<C> PocketCamera<C> impl<C> PocketCamera<C>
where where
C: PocketCameraTrait, C: PocketCameraTrait,
@ -76,14 +69,6 @@ where
((address.get_local() as usize) + (RAM_BANK_SIZE * bank as usize)) % self.ram_size ((address.get_local() as usize) + (RAM_BANK_SIZE * bank as usize)) % self.ram_size
} }
pub(crate) fn from_save_state(
_state: PocketCameraSaveState,
_data: Vec<u8>,
_camera: CameraWrapperRef<C>,
) -> Self {
todo!();
}
fn get_cam_reg(&self, address: CartRamAddress) -> u8 { fn get_cam_reg(&self, address: CartRamAddress) -> u8 {
match address.inner() { match address.inner() {
0xA000 => { 0xA000 => {
@ -202,8 +187,4 @@ where
ram.flush(); ram.flush();
} }
} }
fn get_save_state(&self) -> MbcSaveState {
MbcSaveState::PocketCamera(PocketCameraSaveState)
}
} }

View file

@ -1,4 +1,3 @@
use serde::{Deserialize, Serialize};
use std::{ use std::{
fs::{File, OpenOptions}, fs::{File, OpenOptions},
io::{Read, Seek, SeekFrom, Write}, io::{Read, Seek, SeekFrom, Write},
@ -28,10 +27,6 @@ impl MaybeBufferedSram {
None => Self::Unbuffered(UnbufferedSram::new(length)), None => Self::Unbuffered(UnbufferedSram::new(length)),
} }
} }
pub(crate) fn from_save_state(state: SramSaveState) -> Self {
Self::Unbuffered(UnbufferedSram::new(state.length))
}
} }
pub(crate) struct UnbufferedSram { pub(crate) struct UnbufferedSram {
@ -228,17 +223,6 @@ impl BufferedSramTrait for MaybeBufferedSram {
} }
} }
#[derive(Serialize, Deserialize)]
pub(crate) struct SramSaveState {
length: usize,
}
impl SramSaveState {
pub fn create(sram: &MaybeBufferedSram) -> Self {
Self { length: sram.len() }
}
}
impl Drop for MaybeBufferedSram { impl Drop for MaybeBufferedSram {
fn drop(&mut self) { fn drop(&mut self) {
self.flush(); self.flush();

View file

@ -1,7 +1,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use self::memory::{mmio::gpu::Colour, Interrupt, Memory, MemorySaveState}; use self::memory::{mmio::gpu::Colour, Interrupt, Memory};
use crate::connect::{AudioOutput, CameraWrapperRef, PocketCamera, Renderer, SerialTarget}; use crate::connect::{PocketCamera, Renderer};
mod instructions; mod instructions;
pub mod memory; pub mod memory;
@ -36,39 +36,6 @@ where
pub(crate) is_skipping: bool, pub(crate) is_skipping: bool,
} }
#[derive(Serialize, Deserialize)]
pub struct CpuSaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
memory: MemorySaveState<ColourFormat, R>,
reg: Registers,
last_instruction: u8,
last_instruction_addr: u16,
halted: bool,
should_halt_bug: bool,
cycle_count: usize,
}
impl<ColourFormat, R> CpuSaveState<ColourFormat, R>
where
ColourFormat: From<Colour> + Clone,
R: Renderer<ColourFormat>,
{
pub fn create<C: PocketCamera + Send + 'static>(cpu: &Cpu<ColourFormat, R, C>) -> Self {
Self {
memory: MemorySaveState::create(&cpu.memory),
reg: cpu.reg,
last_instruction: cpu.last_instruction,
last_instruction_addr: cpu.last_instruction_addr,
halted: cpu.halted,
should_halt_bug: cpu.should_halt_bug,
cycle_count: cpu.cycle_count,
}
}
}
impl<ColourFormat, R, C> Cpu<ColourFormat, R, C> impl<ColourFormat, R, C> Cpu<ColourFormat, R, C>
where where
ColourFormat: From<Colour> + Clone, ColourFormat: From<Colour> + Clone,
@ -178,33 +145,6 @@ where
self.reg.pc = addr; self.reg.pc = addr;
self.memory.ime = false; self.memory.ime = false;
} }
pub(crate) fn from_save_state(
state: CpuSaveState<ColourFormat, R>,
data: Vec<u8>,
window: R,
output: AudioOutput,
serial_target: SerialTarget,
camera: CameraWrapperRef<C>,
) -> Self {
Self {
memory: Memory::from_save_state(
state.memory,
data,
window,
output,
serial_target,
camera,
),
reg: state.reg,
last_instruction: state.last_instruction,
last_instruction_addr: state.last_instruction_addr,
halted: state.halted,
should_halt_bug: state.should_halt_bug,
cycle_count: state.cycle_count,
is_skipping: false,
}
}
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]