1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-19 07:31:15 +00:00

Attempts a later interception of tape loading.

This commit is contained in:
Thomas Harte 2021-04-04 22:39:30 -04:00
parent 18d6197d6c
commit 90c3d6a1e8

View File

@ -39,6 +39,8 @@
#include "../../../ClockReceiver/JustInTime.hpp" #include "../../../ClockReceiver/JustInTime.hpp"
#include "../../../Processors/Z80/State/State.hpp"
#include "../Keyboard/Keyboard.hpp" #include "../Keyboard/Keyboard.hpp"
#include <array> #include <array>
@ -186,6 +188,14 @@ template<Model model> class ConcreteMachine:
const uint16_t address = cycle.address ? *cycle.address : 0x0000; const uint16_t address = cycle.address ? *cycle.address : 0x0000;
// using Register = CPU::Z80::Register;
// if(cycle.operation == PartialMachineCycle::WriteStart && z80_.get_value_of_register(Register::ProgramCounter) == 0x5b1) {
// printf("%04x <- %02x\n", address, *cycle.value);
// }
// if(cycle.operation == PartialMachineCycle::ReadOpcodeStart && address == 0x0562) {
// printf("\n");
// }
// Apply contention if necessary. // Apply contention if necessary.
if( if(
is_contended_[address >> 14] && is_contended_[address >> 14] &&
@ -211,15 +221,15 @@ template<Model model> class ConcreteMachine:
case PartialMachineCycle::ReadOpcode: case PartialMachineCycle::ReadOpcode:
// Fast loading: ROM version. // Fast loading: ROM version.
// //
// The below patches over the 'LD-BYTES' routine from the 48kb ROM. // The below patches over part of the 'LD-BYTES' routine from the 48kb ROM.
if(use_fast_tape_hack_ && address == 0x0556 && read_pointers_[0] == &rom_[0xc000]) { if(use_fast_tape_hack_ && address == 0x056b && read_pointers_[0] == &rom_[0xc000]) {
if(perform_rom_ld_bytes()) { // Stop pressing enter, if neccessry.
// Stop pressing enter, if neccessry. if(duration_to_press_enter_ > Cycles(0)) {
if(duration_to_press_enter_ > Cycles(0)) { duration_to_press_enter_ = Cycles(0);
duration_to_press_enter_ = Cycles(0); keyboard_.set_key_state(ZX::Keyboard::KeyEnter, false);
keyboard_.set_key_state(ZX::Keyboard::KeyEnter, false); }
}
if(perform_rom_ld_bytes_56b()) {
*cycle.value = 0xc9; // i.e. RET. *cycle.value = 0xc9; // i.e. RET.
break; break;
} }
@ -627,31 +637,42 @@ template<Model model> class ConcreteMachine:
} }
// Reimplements the 'LD-BYTES' routine, as documented at // Reimplements the 'LD-BYTES' routine, as documented at
// https://skoolkid.github.io/rom/asm/0556.html i.e. // https://skoolkid.github.io/rom/asm/0556.html but picking
// up from address 56b i.e.
// //
// In: // In:
// A: 0x00 or 0xff for block type; // A': 0x00 or 0xff for block type;
// F: carry set if loading, clear if verifying; // F': carry set if loading, clear if verifying;
// DE: block length; // DE: block length;
// IX: start address. // IX: start address.
// //
// Out: // Out:
// F: carry set for success, clear for error. // F: carry set for success, clear for error.
bool perform_rom_ld_bytes() { //
// And, empirically:
// IX: one beyond final address written;
// DE: 0;
// L: parity byte;
// H: 0 for no error, 0xff for error;
// A: same as H.
// BC: ???
bool perform_rom_ld_bytes_56b() {
using Parser = Storage::Tape::ZXSpectrum::Parser; using Parser = Storage::Tape::ZXSpectrum::Parser;
Parser parser(Parser::MachineType::ZXSpectrum); Parser parser(Parser::MachineType::ZXSpectrum);
using Register = CPU::Z80::Register; using Register = CPU::Z80::Register;
uint8_t flags = uint8_t(z80_.get_value_of_register(Register::Flags)); uint8_t flags = uint8_t(z80_.get_value_of_register(Register::FlagsDash));
if(!(flags & 1)) return false; if(!(flags & 1)) return false;
const uint8_t block_type = uint8_t(z80_.get_value_of_register(Register::A)); const uint8_t block_type = uint8_t(z80_.get_value_of_register(Register::ADash));
const auto block = parser.find_block(tape_player_.get_tape()); const auto block = parser.find_block(tape_player_.get_tape());
if(!block || block_type != (*block).type) return false; if(!block || block_type != (*block).type) return false;
uint16_t length = z80_.get_value_of_register(Register::DE); uint16_t length = z80_.get_value_of_register(Register::DE);
uint16_t target = z80_.get_value_of_register(Register::IX); uint16_t target = z80_.get_value_of_register(Register::IX);
flags = 0x93;
uint8_t parity = 0x00;
while(length--) { while(length--) {
auto next = parser.get_byte(tape_player_.get_tape()); auto next = parser.get_byte(tape_player_.get_tape());
if(!next) { if(!next) {
@ -660,10 +681,25 @@ template<Model model> class ConcreteMachine:
} }
write_pointers_[target >> 14][target] = *next; write_pointers_[target >> 14][target] = *next;
parity ^= *next;
++target; ++target;
} }
auto stored_parity = parser.get_byte(tape_player_.get_tape());
if(!stored_parity) {
flags &= ~1;
} else {
z80_.set_value_of_register(Register::L, *stored_parity);
}
z80_.set_value_of_register(Register::Flags, flags); z80_.set_value_of_register(Register::Flags, flags);
z80_.set_value_of_register(Register::DE, length);
z80_.set_value_of_register(Register::IX, target);
const uint8_t h = (flags & 1) ? 0x00 : 0xff;
z80_.set_value_of_register(Register::H, h);
z80_.set_value_of_register(Register::A, h);
return true; return true;
} }