use crate::{
emulator::Emulator,
error::ScreenLoadError,
host::{Host, LoadableAsset, SeekFrom, SeekableAsset},
zx::memory::Page,
Result,
};
use rustzx_z80::CodeGenerator;
const PRIMARY_SCREEN_MEMORY_SIZE: usize = 6912;
pub fn load<H, A>(emulator: &mut Emulator<H>, mut asset: A) -> Result<()>
where
H: Host,
A: LoadableAsset + SeekableAsset,
{
const SCREEN_ADDR: u16 = 0x4000;
const LOOP_ADDR: u16 = 0x8000;
let file_size = asset.seek(SeekFrom::End(0))?;
if file_size != PRIMARY_SCREEN_MEMORY_SIZE {
return Err(ScreenLoadError::InvalidScrFile.into());
}
asset.seek(SeekFrom::Start(0))?;
let bank = match emulator.controller.memory.get_page(SCREEN_ADDR) {
Page::Ram(page) => page,
Page::Rom(_) => {
return Err(ScreenLoadError::MachineNotSupported.into());
}
};
CodeGenerator::new(&mut emulator.controller)
.codegen_set_addr(LOOP_ADDR)
.jump(LOOP_ADDR);
emulator.cpu.regs.set_pc(LOOP_ADDR);
let memory = emulator.controller.memory.ram_page_data_mut(bank);
asset.read_exact(&mut memory[..PRIMARY_SCREEN_MEMORY_SIZE])?;
emulator.controller.refresh_memory_dependent_devices();
Ok(())
}