Function spectrusty_formats::sna::load_sna48
source · pub fn load_sna48<R: Read, S: SnapshotLoader>(
rd: R,
loader: &mut S
) -> Result<()>
Expand description
Loads a 48k SNA file from rd
into the provided snapshot loader
implementing SnapshotLoader.
Note
This function handles only the 48k SNA files.
Errors
This function will return an error if the file is too small or the SP
register points into the ROM page.
Other errors may also be returned from attempts to read the file.
Examples found in repository?
src/sna.rs (line 185)
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
pub fn load_sna<R: Read + Seek, S: SnapshotLoader>(
mut rd: R,
loader: &mut S
) -> Result<()>
{
let cur_pos = rd.seek(SeekFrom::Current(0))?;
let end_pos = rd.seek(SeekFrom::Current(SNA_LENGTH as i64))?;
if end_pos - cur_pos != SNA_LENGTH {
return Err(Error::new(ErrorKind::InvalidData, "SNA: wrong size of the supplied stream"));
}
let mut sna_ext = SnaHeader128::default();
let ext_read = sna_ext.read_struct_or_nothing(rd.by_ref())?;
rd.seek(SeekFrom::Start(cur_pos))?;
if !ext_read {
return load_sna48(rd, loader)
}
let mut cpu = Z80NMOS::default();
let border = read_header(rd.by_ref(), &mut cpu)?;
cpu.set_pc(u16::from_le_bytes(sna_ext.pc));
let extensions = if sna_ext.trdos_rom != 0 {
Extensions::TR_DOS
}
else {
Extensions::NONE
};
let model = ComputerModel::Spectrum128;
loader.select_model(model, extensions, border, ReadEarMode::Issue3)
.map_err(|e| Error::new(ErrorKind::Other, e))?;
let index48 = [5, 2];
let last_page = Ula128MemFlags::from_bits_truncate(sna_ext.port_data)
.last_ram_page_bank();
for page in index48.iter().chain(
Some(&last_page).filter(|n| !index48.contains(n))
) {
loader.read_into_memory(
MemoryRange::Ram(page * PAGE_SIZE..(page + 1) * PAGE_SIZE), rd.by_ref()
)?;
}
rd.seek(SeekFrom::Current(size_of::<SnaHeader128>() as i64))?;
for page in (0..8).filter(|n| !index48.contains(n) && *n != last_page) {
loader.read_into_memory(
MemoryRange::Ram(page * PAGE_SIZE..(page + 1) * PAGE_SIZE), rd.by_ref()
)?;
}
loader.assign_cpu(CpuModel::NMOS(cpu));
loader.write_port(0x7ffd, sna_ext.port_data);
if sna_ext.trdos_rom == 1 {
loader.tr_dos_rom_paged_in();
}
Ok(())
}