mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Chopped time accumulation out of the default Tape
process because it's proving to be sufficiently expensive for a TZX as not to be worthwhile. Introduced a cheaper position capturing/restoring method.
This commit is contained in:
parent
d9a2c32aca
commit
a3e0024980
@ -130,7 +130,7 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
|||||||
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_ && tape_player_.has_tape()) {
|
if(use_fast_tape_hack_ && address == tape_trap_address_ && tape_player_.has_tape()) {
|
||||||
Storage::Time time = tape_player_.get_tape()->get_current_time();
|
uint64_t prior_offset = tape_player_.get_tape()->get_offset();
|
||||||
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);
|
||||||
@ -144,7 +144,7 @@ int Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) {
|
|||||||
tape_advance_delay_ = 1000;
|
tape_advance_delay_ = 1000;
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
tape_player_.get_tape()->seek(time);
|
tape_player_.get_tape()->set_offset(prior_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,22 +20,43 @@ TapePlayer::TapePlayer(unsigned int input_clock_rate) :
|
|||||||
#pragma mark - Seeking
|
#pragma mark - Seeking
|
||||||
|
|
||||||
void Storage::Tape::Tape::seek(Time &seek_time) {
|
void Storage::Tape::Tape::seek(Time &seek_time) {
|
||||||
current_time_.set_zero();
|
Time next_time(0);
|
||||||
next_time_.set_zero();
|
reset();
|
||||||
while(next_time_ <= seek_time) get_next_pulse();
|
while(next_time <= seek_time) {
|
||||||
|
get_next_pulse();
|
||||||
|
next_time += pulse_.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Storage::Time Tape::get_current_time() {
|
||||||
|
Time time(0);
|
||||||
|
uint64_t steps = get_offset();
|
||||||
|
reset();
|
||||||
|
while(steps--) {
|
||||||
|
get_next_pulse();
|
||||||
|
time += pulse_.length;
|
||||||
|
}
|
||||||
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Storage::Tape::Tape::reset() {
|
void Storage::Tape::Tape::reset() {
|
||||||
current_time_.set_zero();
|
offset_ = 0;
|
||||||
next_time_.set_zero();
|
|
||||||
virtual_reset();
|
virtual_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Tape::Pulse Tape::get_next_pulse() {
|
Tape::Pulse Tape::get_next_pulse() {
|
||||||
Tape::Pulse pulse = virtual_get_next_pulse();
|
pulse_ = virtual_get_next_pulse();
|
||||||
current_time_ = next_time_;
|
offset_++;
|
||||||
next_time_ += pulse.length;
|
return pulse_;
|
||||||
return pulse;
|
}
|
||||||
|
|
||||||
|
uint64_t Tape::get_offset() {
|
||||||
|
return offset_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tape::set_offset(uint64_t offset) {
|
||||||
|
reset();
|
||||||
|
while(offset--) get_next_pulse();
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Player
|
#pragma mark - Player
|
||||||
|
@ -52,16 +52,33 @@ class Tape {
|
|||||||
/// @returns @c true if the tape has progressed beyond all recorded content; @c false otherwise.
|
/// @returns @c true if the tape has progressed beyond all recorded content; @c false otherwise.
|
||||||
virtual bool is_at_end() = 0;
|
virtual bool is_at_end() = 0;
|
||||||
|
|
||||||
/// @returns the amount of time preceeding the most recently-returned pulse.
|
/*!
|
||||||
virtual Time get_current_time() { return current_time_; }
|
Returns a numerical representation of progression into the tape. Precision is arbitrary but
|
||||||
|
required to be at least to the whole pulse. Greater numbers are later than earlier numbers,
|
||||||
|
but not necessarily continuous.
|
||||||
|
*/
|
||||||
|
virtual uint64_t get_offset();
|
||||||
|
|
||||||
/// Advances or reverses the tape to the last time before or at @c time from which a pulse starts.
|
/*!
|
||||||
|
Moves the tape to the first time at which the specified offset would be returned by get_offset.
|
||||||
|
*/
|
||||||
|
virtual void set_offset(uint64_t);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Calculates and returns the amount of time that has elapsed since the time began. Potentially expensive.
|
||||||
|
*/
|
||||||
|
virtual Time get_current_time();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Seeks to @c time. Potentially expensive.
|
||||||
|
*/
|
||||||
virtual void seek(Time &time);
|
virtual void seek(Time &time);
|
||||||
|
|
||||||
virtual ~Tape() {};
|
virtual ~Tape() {};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Time current_time_, next_time_;
|
uint64_t offset_;
|
||||||
|
Tape::Pulse pulse_;
|
||||||
|
|
||||||
virtual Pulse virtual_get_next_pulse() = 0;
|
virtual Pulse virtual_get_next_pulse() = 0;
|
||||||
virtual void virtual_reset() = 0;
|
virtual void virtual_reset() = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user