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:
commit
cd646aab9e
@ -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;
|
||||
|
@ -94,6 +94,7 @@ class Machine:
|
||||
uint8_t latched_video_byte_;
|
||||
|
||||
bool use_fast_tape_hack_;
|
||||
int tape_advance_delay_;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user