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(())
}