// // SNA.cpp // Clock Signal // // Created by Thomas Harte on 24/04/2021. // Copyright © 2021 Thomas Harte. All rights reserved. // #include "SNA.hpp" #include "../FileHolder.hpp" #include "../../Analyser/Static/ZXSpectrum/Target.hpp" #include "../../Machines/Sinclair/ZXSpectrum/State.hpp" using namespace Storage::State; std::unique_ptr SNA::load(const std::string &file_name) { // Make sure the file is accessible and appropriately sized. FileHolder file(file_name); if(file.stats().st_size != 48*1024 + 0x1b) { return nullptr; } // SNAs are always for 48kb machines. using Target = Analyser::Static::ZXSpectrum::Target; auto result = std::make_unique(); result->model = Target::Model::FortyEightK; // Prepare to populate ZX Spectrum state. auto *const state = new Sinclair::ZXSpectrum::State(); result->state = std::unique_ptr(state); // Comments below: [offset] [contents] // 00 I const uint8_t i = file.get8(); // 01 HL'; 03 DE'; 05 BC'; 07 AF' state->z80.registers.hlDash = file.get16le(); state->z80.registers.deDash = file.get16le(); state->z80.registers.bcDash = file.get16le(); state->z80.registers.afDash = file.get16le(); // 09 HL; 0B DE; 0D BC; 0F IY; 11 IX state->z80.registers.hl = file.get16le(); state->z80.registers.de = file.get16le(); state->z80.registers.bc = file.get16le(); state->z80.registers.iy = file.get16le(); state->z80.registers.ix = file.get16le(); // 13 IFF2 (in bit 2) const uint8_t iff = file.get8(); state->z80.registers.iff1 = state->z80.registers.iff2 = iff & 4; // 14 R const uint8_t r = file.get8(); state->z80.registers.ir = uint16_t((i << 8) | r); // 15 AF; 17 SP; 19 interrupt mode state->z80.registers.flags = file.get8(); state->z80.registers.a = file.get8(); state->z80.registers.stack_pointer = file.get16le(); state->z80.registers.interrupt_mode = file.get8(); // 1A border colour const uint8_t border_colour = file.get8(); (void)border_colour; // TODO. // 1B– 48kb RAM contents state->ram = file.read(48*1024); // Establish program counter. state->z80.registers.program_counter = state->ram[state->z80.registers.stack_pointer]; state->ram[state->z80.registers.stack_pointer] = 0; state->z80.registers.program_counter |= state->ram[state->z80.registers.stack_pointer+1] << 8; state->ram[state->z80.registers.stack_pointer+1] = 0; state->z80.registers.stack_pointer += 2; return result; }