diff --git a/Cargo.lock b/Cargo.lock index 398d7ac..459e426 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1046,6 +1046,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "elf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55dd888a213fc57e957abf2aa305ee3e8a28dbe05687a251f33b637cd46b0070" + [[package]] name = "emath" version = "0.32.0" @@ -1833,6 +1839,7 @@ dependencies = [ "egui-wgpu", "egui-winit", "egui_extras", + "elf", "fixed", "gilrs", "hex", diff --git a/Cargo.toml b/Cargo.toml index 022d750..9669059 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ egui_extras = { version = "0.32", features = ["image"] } egui-notify = "0.20" egui-winit = "0.32" egui-wgpu = { version = "0.32", features = ["winit"] } +elf = "0.8" fixed = { version = "1.28", features = ["num-traits"] } gilrs = { version = "0.11", features = ["serde-serialize"] } hex = "0.4" diff --git a/src/emulator/cart.rs b/src/emulator/cart.rs index 79f53c3..8aec193 100644 --- a/src/emulator/cart.rs +++ b/src/emulator/cart.rs @@ -18,6 +18,7 @@ pub struct Cart { impl Cart { pub fn load(file_path: &Path, sim_id: SimId) -> Result { let rom = fs::read(file_path)?; + let rom = try_parse_elf(&rom).unwrap_or(rom); let mut sram_file = File::options() .read(true) @@ -55,6 +56,23 @@ impl Cart { } } +fn try_parse_elf(data: &[u8]) -> Option> { + let parsed = elf::ElfBytes::::minimal_parse(data).ok()?; + let mut bytes = vec![]; + let mut pstart = None; + for phdr in parsed.segments()? { + if phdr.p_filesz == 0 { + continue; + } + let start = pstart.unwrap_or(phdr.p_paddr); + pstart = Some(start); + bytes.resize((phdr.p_paddr - start) as usize, 0); + let data = parsed.segment_data(&phdr).ok()?; + bytes.extend_from_slice(data); + } + Some(bytes) +} + fn sram_path(file_path: &Path, sim_id: SimId) -> PathBuf { match sim_id { SimId::Player1 => file_path.with_extension("p1.sram"),