1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-27 16:31:31 +00:00

Merge pull request #141 from TomHarte/ZX81FastLoading

Corrects ZX81 fast loading
This commit is contained in:
Thomas Harte 2017-07-06 22:39:19 -04:00 committed by GitHub
commit cd646aab9e
5 changed files with 22 additions and 8 deletions

View File

@ -22,7 +22,8 @@ Machine::Machine() :
hsync_(false),
nmi_is_enabled_(false),
tape_player_(ZX8081ClockRate),
use_fast_tape_hack_(false) {
use_fast_tape_hack_(false),
tape_advance_delay_(0) {
set_clock_rate(ZX8081ClockRate);
tape_player_.set_motor_control(true);
clear_all_keys();
@ -53,7 +54,11 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
}
if(is_zx81_) horizontal_counter_ %= 207;
tape_player_.run_for_cycles(cycle.length);
if(!tape_advance_delay_) {
tape_player_.run_for_cycles(cycle.length);
} else {
tape_advance_delay_ = std::max(tape_advance_delay_ - cycle.length, 0);
}
if(nmi_is_enabled_ && !get_halt_line() && get_non_maskable_interrupt_line()) {
set_wait_line(true);
@ -124,14 +129,22 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
case CPU::Z80::PartialMachineCycle::ReadOpcodeStart:
case CPU::Z80::PartialMachineCycle::ReadOpcodeWait:
// Check for use of the fast tape hack.
if(use_fast_tape_hack_ && address == tape_trap_address_) {
if(use_fast_tape_hack_ && address == tape_trap_address_ && tape_player_.has_tape()) {
Storage::Time time = tape_player_.get_tape()->get_current_time();
int next_byte = parser_.get_next_byte(tape_player_.get_tape());
if(next_byte != -1) {
uint16_t hl = get_value_of_register(CPU::Z80::Register::HL);
ram_[hl & ram_mask_] = (uint8_t)next_byte;
*cycle.value = 0x00;
set_value_of_register(CPU::Z80::Register::ProgramCounter, tape_return_address_ - 1);
// Assume that having read one byte quickly, we're probably going to be asked to read
// another shortly. Therefore, temporarily disable the tape motor for 1000 cycles in order
// to avoid fighting with real time. This is a stop-gap fix.
tape_advance_delay_ = 1000;
return 0;
} else {
tape_player_.get_tape()->seek(time);
}
}
is_opcode_read = true;

View File

@ -94,6 +94,7 @@ class Machine:
uint8_t latched_video_byte_;
bool use_fast_tape_hack_;
int tape_advance_delay_;
};
}

View File

@ -54,7 +54,7 @@ Tape::Pulse ZX80O81P::virtual_get_next_pulse() {
// Start with 1 second of silence.
if(!is_past_silence_ || has_finished_data()) {
pulse.type = Pulse::Type::Low;
pulse.length.length = 5;
pulse.length.length = 10;
pulse.length.clock_rate = 1;
is_past_silence_ = true;
has_ended_final_byte_ = has_finished_data();

View File

@ -79,10 +79,10 @@ void Parser::inspect_waves(const std::vector<WaveType> &waves) {
// the gap that follows the bit due to the simplified "high is high, everything else is low"
// logic applied to pulse detection. So those two things will merge. Meaning we're looking for
// 17 and/or 7 pulses.
int gaps_to_swallow = (int)wave_offset + ((waves[number_of_pulses + wave_offset] == WaveType::Gap) ? 1 : 0);
size_t gaps_to_swallow = wave_offset + ((waves[number_of_pulses + wave_offset] == WaveType::Gap) ? 1 : 0);
switch(number_of_pulses) {
case 17: push_symbol(SymbolType::One, 17 + gaps_to_swallow); break;
case 7: push_symbol(SymbolType::Zero, 7 + gaps_to_swallow); break;
case 18: case 17: push_symbol(SymbolType::One, (int)(number_of_pulses + gaps_to_swallow)); break;
case 8: case 7: push_symbol(SymbolType::Zero, (int)(number_of_pulses + gaps_to_swallow)); break;
default: push_symbol(SymbolType::Unrecognised, 1); break;
}
}

View File

@ -22,7 +22,7 @@ TapePlayer::TapePlayer(unsigned int input_clock_rate) :
void Storage::Tape::Tape::seek(Time &seek_time) {
current_time_.set_zero();
next_time_.set_zero();
while(next_time_ < seek_time) get_next_pulse();
while(next_time_ <= seek_time) get_next_pulse();
}
void Storage::Tape::Tape::reset() {