pub struct Parser<'a, R: Reader> { /* private fields */ }
Expand description
Parser for Software Defined Retro ROM (SDRR) firmware images.
This parser extracts configuration and ROM data from SDRR firmware files, which are used in devices that emulate vintage ROM chips (2316/2332/2364). The parser is designed to work efficiently in both PC and embedded environments.
§Architecture
The parser uses a two-phase approach:
- Metadata parsing - Headers, pin configurations, and ROM set information are parsed immediately into memory (typically just a few KB)
- ROM data access - ROM images (up to 64KB each) remain in the source and are accessed lazily through reader callbacks
This design allows embedded devices with limited RAM to parse and work with SDRR firmware without loading entire ROM images into memory.
§Usage
// Create a reader for your data source
let reader = MyReader::new("firmware.bin")?;
// Create parser and parse metadata
let mut parser = Parser::new(reader);
let info = parser.parse()?;
// Access ROM data lazily
let byte = parser.read_rom_byte(&info, 0, 0x1000, true, None, None)?;
§Firmware Structure
SDRR firmware contains:
- A header with “SDRR” magic bytes at offset 0x200 from base
- Version information and build metadata
- Pin mapping configuration for the STM32F4 microcontroller
- One or more ROM sets, each containing up to 3 ROM images
- ROM data that has been pre-processed for efficient serving
§Address Translation
ROM addresses and data bytes are “mangled” in the firmware for efficient real-time serving. The parser handles the translation between logical addresses/data and their physical representation in the firmware.
Implementations§
Source§impl<'a, R: Reader> Parser<'a, R>
impl<'a, R: Reader> Parser<'a, R>
Sourcepub fn with_base_flash_address(
reader: &'a mut R,
base_flash_address: u32,
base_ram_address: u32,
) -> Self
pub fn with_base_flash_address( reader: &'a mut R, base_flash_address: u32, base_ram_address: u32, ) -> Self
Create a new parser with a custom base address.
Use this when parsing firmware for devices with non-standard memory maps or when analyzing relocated firmware images.
§Arguments
reader
- Implementation ofReader
trait that provides access to firmware bytesbase_flash_address
- Base address where flash memory begins (e.g., 0x08000000 for STM32F4)base_ram_address
- Base address where RAM begins (e.g., 0x20000000 for STM32F4)
Sourcepub async fn detect(&mut self) -> bool
pub async fn detect(&mut self) -> bool
Function to do a brief check whether this is an SDRR device.
Returns:
true
if the SDRR header was found and is validfalse
if the header was not found (or an error occured)
Sourcepub async fn parse_flash(&mut self) -> Result<SdrrInfo, String>
pub async fn parse_flash(&mut self) -> Result<SdrrInfo, String>
Parse SDRR metadata from the firmware.
This method reads and parses all structural information from the firmware, including headers, version info, pin configurations, and ROM set descriptors. ROM image data is NOT loaded - only pointers to where it exists in the firmware.
§What gets parsed
- SDRR header with version and build information
- Pin mapping configuration for STM32F4 GPIO
- ROM set headers with serving algorithms
- ROM information (type, CS line configuration)
- String data (build date, hardware revision, ROM filenames)
§Error handling
The parser attempts to continue parsing even when encountering errors in
non-critical sections. Failed sections are recorded in SdrrInfo::parse_errors
while their fields are set to None
.
§Returns
Returns Ok(SdrrInfo)
if the header was found and core fields parsed successfully.
Returns Err
if:
- SDRR magic bytes not found at expected location
- Version is newer than this parser supports
- Critical header fields are corrupted
§Example
let mut parser = Parser::new(reader);
match parser.parse_flash() {
Ok(info) => {
println!("Parsed SDRR v{}.{}.{}",
info.major_version,
info.minor_version,
info.patch_version);
if !info.parse_errors.is_empty() {
println!("Encountered {} non-fatal errors", info.parse_errors.len());
}
}
Err(e) => eprintln!("Failed to parse: {}", e),
}