mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Merge branch 'master' into BufferOverflow
This commit is contained in:
commit
7476c64a66
@ -22,7 +22,8 @@ Machine::Machine() :
|
|||||||
hsync_(false),
|
hsync_(false),
|
||||||
nmi_is_enabled_(false),
|
nmi_is_enabled_(false),
|
||||||
tape_player_(ZX8081ClockRate),
|
tape_player_(ZX8081ClockRate),
|
||||||
use_fast_tape_hack_(false) {
|
use_fast_tape_hack_(false),
|
||||||
|
tape_advance_delay_(0) {
|
||||||
set_clock_rate(ZX8081ClockRate);
|
set_clock_rate(ZX8081ClockRate);
|
||||||
tape_player_.set_motor_control(true);
|
tape_player_.set_motor_control(true);
|
||||||
clear_all_keys();
|
clear_all_keys();
|
||||||
@ -53,7 +54,11 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(is_zx81_) horizontal_counter_ %= 207;
|
if(is_zx81_) horizontal_counter_ %= 207;
|
||||||
|
if(!tape_advance_delay_) {
|
||||||
tape_player_.run_for_cycles(cycle.length);
|
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()) {
|
if(nmi_is_enabled_ && !get_halt_line() && get_non_maskable_interrupt_line()) {
|
||||||
set_wait_line(true);
|
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::ReadOpcodeStart:
|
||||||
case CPU::Z80::PartialMachineCycle::ReadOpcodeWait:
|
case CPU::Z80::PartialMachineCycle::ReadOpcodeWait:
|
||||||
// Check for use of the fast tape hack.
|
// 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());
|
int next_byte = parser_.get_next_byte(tape_player_.get_tape());
|
||||||
if(next_byte != -1) {
|
if(next_byte != -1) {
|
||||||
uint16_t hl = get_value_of_register(CPU::Z80::Register::HL);
|
uint16_t hl = get_value_of_register(CPU::Z80::Register::HL);
|
||||||
ram_[hl & ram_mask_] = (uint8_t)next_byte;
|
ram_[hl & ram_mask_] = (uint8_t)next_byte;
|
||||||
*cycle.value = 0x00;
|
*cycle.value = 0x00;
|
||||||
set_value_of_register(CPU::Z80::Register::ProgramCounter, tape_return_address_ - 1);
|
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;
|
return 0;
|
||||||
|
} else {
|
||||||
|
tape_player_.get_tape()->seek(time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is_opcode_read = true;
|
is_opcode_read = true;
|
||||||
|
@ -94,6 +94,7 @@ class Machine:
|
|||||||
uint8_t latched_video_byte_;
|
uint8_t latched_video_byte_;
|
||||||
|
|
||||||
bool use_fast_tape_hack_;
|
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.
|
// Start with 1 second of silence.
|
||||||
if(!is_past_silence_ || has_finished_data()) {
|
if(!is_past_silence_ || has_finished_data()) {
|
||||||
pulse.type = Pulse::Type::Low;
|
pulse.type = Pulse::Type::Low;
|
||||||
pulse.length.length = 5;
|
pulse.length.length = 10;
|
||||||
pulse.length.clock_rate = 1;
|
pulse.length.clock_rate = 1;
|
||||||
is_past_silence_ = true;
|
is_past_silence_ = true;
|
||||||
has_ended_final_byte_ = has_finished_data();
|
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"
|
// 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
|
// logic applied to pulse detection. So those two things will merge. Meaning we're looking for
|
||||||
// 17 and/or 7 pulses.
|
// 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) {
|
switch(number_of_pulses) {
|
||||||
case 17: push_symbol(SymbolType::One, 17 + gaps_to_swallow); break;
|
case 18: case 17: push_symbol(SymbolType::One, (int)(number_of_pulses + gaps_to_swallow)); break;
|
||||||
case 7: push_symbol(SymbolType::Zero, 7 + 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;
|
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) {
|
void Storage::Tape::Tape::seek(Time &seek_time) {
|
||||||
current_time_.set_zero();
|
current_time_.set_zero();
|
||||||
next_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() {
|
void Storage::Tape::Tape::reset() {
|
||||||
|
Loading…
Reference in New Issue
Block a user