mirror of
https://github.com/TomHarte/CLK.git
synced 2026-03-11 04:42:20 +00:00
Switch to get/as.
This commit is contained in:
@@ -164,7 +164,7 @@ public:
|
||||
if constexpr (divider == 1) {
|
||||
return time_since_update_;
|
||||
}
|
||||
return TargetTimeScale(time_since_update_.as_integral() / divider);
|
||||
return TargetTimeScale(time_since_update_.get() / divider);
|
||||
}
|
||||
|
||||
/// @returns the amount of time since the object was last flushed, plus the local time scale @c offset,
|
||||
@@ -173,7 +173,7 @@ public:
|
||||
if constexpr (divider == 1) {
|
||||
return time_since_update_ + offset;
|
||||
}
|
||||
return TargetTimeScale((time_since_update_ + offset).as_integral() / divider);
|
||||
return TargetTimeScale((time_since_update_ + offset).get() / divider);
|
||||
}
|
||||
|
||||
/// Flushes all accumulated time.
|
||||
@@ -238,8 +238,8 @@ public:
|
||||
// Figure out the number of whole input steps that is required to get
|
||||
// past target, and subtract the number of whole input steps necessary
|
||||
// to get to base.
|
||||
const auto steps_to_base = base.as_integral() / multiplier;
|
||||
const auto steps_to_target = (target.as_integral() + divider - 1) / multiplier;
|
||||
const auto steps_to_base = base.get() / multiplier;
|
||||
const auto steps_to_target = (target.get() + divider - 1) / multiplier;
|
||||
|
||||
return LocalTimeScale(steps_to_target - steps_to_base);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ void WD1770::run_for(const Cycles cycles) {
|
||||
Storage::Disk::Controller::run_for(cycles);
|
||||
|
||||
if(delay_time_) {
|
||||
const auto number_of_cycles = cycles.as_integral();
|
||||
const auto number_of_cycles = cycles.get();
|
||||
if(delay_time_ <= number_of_cycles) {
|
||||
delay_time_ = 0;
|
||||
posit_event(int(Event1770::Timer));
|
||||
|
||||
@@ -407,7 +407,7 @@ template <typename T> void MOS6522<T>::evaluate_port_b_output() {
|
||||
|
||||
/*! Runs for a specified number of half cycles. */
|
||||
template <typename T> void MOS6522<T>::run_for(const HalfCycles half_cycles) {
|
||||
auto number_of_half_cycles = half_cycles.as_integral();
|
||||
auto number_of_half_cycles = half_cycles.get();
|
||||
if(!number_of_half_cycles) return;
|
||||
|
||||
if(is_phase2_) {
|
||||
@@ -436,7 +436,7 @@ template <typename T> void MOS6522<T>::flush() {
|
||||
|
||||
/*! Runs for a specified number of cycles. */
|
||||
template <typename T> void MOS6522<T>::run_for(const Cycles cycles) {
|
||||
auto number_of_cycles = cycles.as_integral();
|
||||
auto number_of_cycles = cycles.get();
|
||||
while(number_of_cycles--) {
|
||||
do_phase1();
|
||||
do_phase2();
|
||||
|
||||
@@ -113,7 +113,7 @@ public:
|
||||
}
|
||||
|
||||
inline void run_for(const Cycles cycles) {
|
||||
unsigned int number_of_cycles = unsigned(cycles.as_integral());
|
||||
auto number_of_cycles = cycles.as<unsigned int>();
|
||||
|
||||
// permit counting _to_ zero; counting _through_ zero initiates the other behaviour
|
||||
if(timer_.value >= number_of_cycles) {
|
||||
|
||||
@@ -184,7 +184,7 @@ public:
|
||||
// keep track of the amount of time since the speaker was updated; lazy updates are applied
|
||||
cycles_since_speaker_update_ += cycles;
|
||||
|
||||
auto number_of_cycles = cycles.as_integral();
|
||||
auto number_of_cycles = cycles.get();
|
||||
while(number_of_cycles--) {
|
||||
// keep an old copy of the vertical count because that test is a cycle later than the actual changes
|
||||
int previous_vertical_counter = vertical_counter_;
|
||||
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
}
|
||||
|
||||
void run_for(const Cycles cycles) {
|
||||
auto cyles_remaining = cycles.as_integral();
|
||||
auto cyles_remaining = cycles.get();
|
||||
while(cyles_remaining--) {
|
||||
// Intention of code below: all conditionals are evaluated as if functional; they should be
|
||||
// ordered so that whatever assignments result don't affect any subsequent conditionals
|
||||
|
||||
@@ -84,7 +84,7 @@ void ACIA::write(const int address, const uint8_t value) {
|
||||
transmit.write(false);
|
||||
break;
|
||||
}
|
||||
receive.set_read_delegate(this, Storage::Time(divider_ * 2, int(receive_clock_rate_.as_integral())));
|
||||
receive.set_read_delegate(this, Storage::Time(divider_ * 2, receive_clock_rate_.as<int>()));
|
||||
receive_interrupt_enabled_ = value & 0x80;
|
||||
|
||||
update_interrupt_line();
|
||||
|
||||
@@ -203,7 +203,7 @@ void MFP68901::run_timer_for(const int cycles) {
|
||||
void MFP68901::run_for(const HalfCycles time) {
|
||||
cycles_left_ += time;
|
||||
|
||||
const int cycles = int(cycles_left_.flush<Cycles>().as_integral());
|
||||
const auto cycles = cycles_left_.flush<Cycles>().as<int>();
|
||||
if(!cycles) return;
|
||||
|
||||
run_timer_for<0>(cycles);
|
||||
|
||||
@@ -40,11 +40,11 @@ void i8272::run_for(const Cycles cycles) {
|
||||
|
||||
// check for an expired timer
|
||||
if(delay_time_ > 0) {
|
||||
if(cycles.as_integral() >= delay_time_) {
|
||||
if(cycles.get() >= delay_time_) {
|
||||
delay_time_ = 0;
|
||||
posit_event(int(Event8272::Timer));
|
||||
} else {
|
||||
delay_time_ -= cycles.as_integral();
|
||||
delay_time_ -= cycles.get();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void i8272::run_for(const Cycles cycles) {
|
||||
int drives_left = drives_seeking_;
|
||||
for(int c = 0; c < 4; c++) {
|
||||
if(drives_[c].phase == Drive::Seeking) {
|
||||
drives_[c].step_rate_counter += cycles.as_integral();
|
||||
drives_[c].step_rate_counter += cycles.get();
|
||||
auto steps = drives_[c].step_rate_counter / (8000 * step_rate_time_);
|
||||
drives_[c].step_rate_counter %= (8000 * step_rate_time_);
|
||||
while(steps--) {
|
||||
@@ -90,12 +90,12 @@ void i8272::run_for(const Cycles cycles) {
|
||||
int head = c&1;
|
||||
|
||||
if(drives_[drive].head_unload_delay[head] > 0) {
|
||||
if(cycles.as_integral() >= drives_[drive].head_unload_delay[head]) {
|
||||
if(cycles.get() >= drives_[drive].head_unload_delay[head]) {
|
||||
drives_[drive].head_unload_delay[head] = 0;
|
||||
drives_[drive].head_is_loaded[head] = false;
|
||||
head_timers_running_--;
|
||||
} else {
|
||||
drives_[drive].head_unload_delay[head] -= cycles.as_integral();
|
||||
drives_[drive].head_unload_delay[head] -= cycles.get();
|
||||
}
|
||||
timers_left--;
|
||||
if(!timers_left) break;
|
||||
|
||||
@@ -89,7 +89,7 @@ void DiskII::select_drive(const int drive) {
|
||||
void DiskII::run_for(const Cycles cycles) {
|
||||
if(preferred_clocking() == ClockingHint::Preference::None) return;
|
||||
|
||||
auto integer_cycles = cycles.as_integral();
|
||||
auto integer_cycles = cycles.get();
|
||||
while(integer_cycles--) {
|
||||
const int address = (state_ & 0xf0) | inputs_ | ((shift_register_&0x80) >> 6);
|
||||
if(flux_duration_) {
|
||||
@@ -140,7 +140,7 @@ void DiskII::run_for(const Cycles cycles) {
|
||||
// motor switch being flipped and the drive motor actually switching off.
|
||||
// This models that, accepting overrun as a risk.
|
||||
if(motor_off_time_ >= 0) {
|
||||
motor_off_time_ -= cycles.as_integral();
|
||||
motor_off_time_ -= cycles.get();
|
||||
if(motor_off_time_ < 0) {
|
||||
set_control(Control::Motor, false);
|
||||
}
|
||||
|
||||
@@ -241,7 +241,7 @@ void IWM::run_for(const Cycles cycles) {
|
||||
}
|
||||
|
||||
// Activity otherwise depends on mode and motor state.
|
||||
auto integer_cycles = cycles.as_integral();
|
||||
auto integer_cycles = cycles.get();
|
||||
switch(shift_mode_) {
|
||||
case ShiftMode::Reading: {
|
||||
// Per the IWM patent, column 7, around line 35 onwards: "The expected time
|
||||
@@ -249,7 +249,7 @@ void IWM::run_for(const Cycles cycles) {
|
||||
// expected time since the data is not precisely spaced when read due to
|
||||
// variations in drive speed and other external factors". The error_margin
|
||||
// here implements the 'after' part of that contract.
|
||||
const auto error_margin = Cycles(bit_length_.as_integral() >> 1);
|
||||
const auto error_margin = Cycles(bit_length_.get() >> 1);
|
||||
|
||||
if(drive_is_rotating_[active_drive_]) {
|
||||
while(integer_cycles--) {
|
||||
@@ -263,7 +263,7 @@ void IWM::run_for(const Cycles cycles) {
|
||||
} else {
|
||||
while(cycles_since_shift_ + integer_cycles >= bit_length_ + error_margin) {
|
||||
const auto run_length = bit_length_ + error_margin - cycles_since_shift_;
|
||||
integer_cycles -= run_length.as_integral();
|
||||
integer_cycles -= run_length.get();
|
||||
cycles_since_shift_ += run_length;
|
||||
propose_shift(0);
|
||||
}
|
||||
@@ -282,7 +282,7 @@ void IWM::run_for(const Cycles cycles) {
|
||||
}
|
||||
shift_register_ <<= 1;
|
||||
|
||||
integer_cycles -= cycles_until_write.as_integral();
|
||||
integer_cycles -= cycles_until_write.get();
|
||||
cycles_since_shift_ = Cycles(0);
|
||||
|
||||
--output_bits_remaining_;
|
||||
@@ -347,7 +347,7 @@ void IWM::select_shift_mode() {
|
||||
// If writing mode just began, set the drive into write mode and cue up the first output byte.
|
||||
if(old_shift_mode != ShiftMode::Writing && shift_mode_ == ShiftMode::Writing) {
|
||||
if(drives_[active_drive_]) {
|
||||
drives_[active_drive_]->begin_writing(Storage::Time(1, clock_rate_ / bit_length_.as_integral()), false, false);
|
||||
drives_[active_drive_]->begin_writing(Storage::Time(1, clock_rate_ / bit_length_.get()), false, false);
|
||||
}
|
||||
shift_register_ = next_output_;
|
||||
write_handshake_ |= 0x80 | 0x40;
|
||||
@@ -386,7 +386,7 @@ void IWM::propose_shift(const uint8_t bit) {
|
||||
// shift in a 1 and start a new window wherever the first found 1 was.
|
||||
//
|
||||
// If no 1s are found, shift in a 0 and don't alter expectations as to window placement.
|
||||
const auto error_margin = Cycles(bit_length_.as_integral() >> 1);
|
||||
const auto error_margin = Cycles(bit_length_.get() >> 1);
|
||||
if(bit && cycles_since_shift_ < error_margin) return;
|
||||
|
||||
shift_register_ = uint8_t((shift_register_ << 1) | bit);
|
||||
|
||||
@@ -41,7 +41,7 @@ void RP5C01::run_for(const HalfCycles cycles) {
|
||||
if(sub_seconds_ < clock_rate_) {
|
||||
return;
|
||||
}
|
||||
const auto elapsed_seconds = int(sub_seconds_.as_integral() / clock_rate_.as_integral());
|
||||
const auto elapsed_seconds = int(sub_seconds_.get() / clock_rate_.get());
|
||||
sub_seconds_ %= clock_rate_;
|
||||
|
||||
// Update time within day.
|
||||
|
||||
@@ -22,7 +22,7 @@ template <bool include_clock>
|
||||
void Line<include_clock>::advance_writer(HalfCycles cycles) {
|
||||
if(cycles == HalfCycles(0)) return;
|
||||
|
||||
const auto integral_cycles = cycles.as_integral();
|
||||
const auto integral_cycles = cycles.get();
|
||||
remaining_delays_ = std::max(remaining_delays_ - integral_cycles, Cycles::IntType(0));
|
||||
if(events_.empty()) {
|
||||
write_cycles_since_delegate_call_ += integral_cycles;
|
||||
@@ -89,13 +89,13 @@ template <bool lsb_first, typename IntT> void Line<include_clock>::write_interna
|
||||
int count,
|
||||
IntT levels
|
||||
) {
|
||||
remaining_delays_ += count * cycles.as_integral();
|
||||
remaining_delays_ += count * cycles.get();
|
||||
|
||||
auto event = events_.size();
|
||||
events_.resize(events_.size() + size_t(count)*2);
|
||||
while(count--) {
|
||||
events_[event].type = Event::Delay;
|
||||
events_[event].delay = int(cycles.as_integral());
|
||||
events_[event].delay = cycles.as<int>();
|
||||
IntT bit;
|
||||
if constexpr (lsb_first) {
|
||||
bit = levels & 1;
|
||||
@@ -166,7 +166,7 @@ void Line<include_clock>::update_delegate(const bool level) {
|
||||
}
|
||||
|
||||
// Forward as many bits as occur.
|
||||
Storage::Time time_left(cycles_to_forward, int(clock_rate_.as_integral()));
|
||||
Storage::Time time_left(cycles_to_forward, clock_rate_.as<int>());
|
||||
const int bit = level ? 1 : 0;
|
||||
while(time_left >= time_left_in_bit_) {
|
||||
if(!read_delegate_->serial_line_did_produce_bit(this, bit)) {
|
||||
@@ -186,7 +186,7 @@ void Line<include_clock>::update_delegate(const bool level) {
|
||||
template <bool include_clock>
|
||||
Cycles::IntType Line<include_clock>::minimum_write_cycles_for_read_delegate_bit() {
|
||||
if(!read_delegate_) return 0;
|
||||
return 1 + (read_delegate_bit_length_ * unsigned(clock_rate_.as_integral())).template get<int>();
|
||||
return 1 + (read_delegate_bit_length_ * clock_rate_.as<unsigned int>()).template get<int>();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -910,7 +910,7 @@ public:
|
||||
//
|
||||
// 1Mhz devices.
|
||||
//
|
||||
const auto half_cycles = HalfCycles(duration.as_integral());
|
||||
const auto half_cycles = HalfCycles(duration.get());
|
||||
system_via_.run_for(half_cycles);
|
||||
system_via_port_handler_.advance_keyboard_scan(half_cycles);
|
||||
user_via_.run_for(half_cycles);
|
||||
|
||||
@@ -83,7 +83,7 @@ void Tape::run_for(const Cycles cycles) {
|
||||
TapePlayer::run_for(cycles);
|
||||
}
|
||||
} else {
|
||||
output_.cycles_into_pulse += unsigned(cycles.as_integral());
|
||||
output_.cycles_into_pulse += cycles.as<unsigned int>();
|
||||
while(output_.cycles_into_pulse > 1664) { // 1664 = the closest you can get to 1200 baud if you're looking for something
|
||||
output_.cycles_into_pulse -= 1664; // that divides the 125,000Hz clock that the sound divider runs off.
|
||||
push_tape_bit(1);
|
||||
|
||||
@@ -892,7 +892,7 @@ public:
|
||||
|
||||
// TODO (in the player, not here): adapt it to accept an input clock rate and
|
||||
// run_for as HalfCycles.
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(cycle.length.as_integral());
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(cycle.length.get());
|
||||
|
||||
// Pump the AY.
|
||||
ay_.run_for(cycle.length);
|
||||
@@ -1324,7 +1324,7 @@ private:
|
||||
if constexpr (has_fdc) {
|
||||
// Clock the FDC, if connected, using a lazy scale by two
|
||||
if(!fdc_is_sleeping_) {
|
||||
fdc_.run_for(Cycles(time_since_fdc_update_.as_integral()));
|
||||
fdc_.run_for(Cycles(time_since_fdc_update_.get()));
|
||||
}
|
||||
time_since_fdc_update_ = HalfCycles(0);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ void DiskIICard::perform_bus_operation(Select select, bool is_read, uint16_t add
|
||||
|
||||
void DiskIICard::run_for(Cycles cycles, int) {
|
||||
if(diskii_clocking_preference_ == ClockingHint::Preference::None) return;
|
||||
diskii_.run_for(Cycles(cycles.as_integral() * 2));
|
||||
diskii_.run_for(Cycles(cycles.get() * 2));
|
||||
}
|
||||
|
||||
void DiskIICard::set_disk(const std::shared_ptr<Storage::Disk::Disk> &disk, int drive) {
|
||||
|
||||
@@ -185,7 +185,7 @@ public:
|
||||
// Source: ** Understanding the Apple IIe by Jim Sather
|
||||
|
||||
// Determine column at offset.
|
||||
int mapped_column = column_ + int(offset.as_integral());
|
||||
int mapped_column = column_ + offset.as<int>();
|
||||
|
||||
// Map that backwards from the internal pixels-at-start generation to pixels-at-end
|
||||
// (so what was column 0 is now column 25).
|
||||
@@ -244,7 +244,7 @@ public:
|
||||
*/
|
||||
bool get_is_vertical_blank(Cycles offset) {
|
||||
// Determine column at offset.
|
||||
int mapped_column = column_ + int(offset.as_integral());
|
||||
int mapped_column = column_ + offset.as<int>();
|
||||
|
||||
// Map that backwards from the internal pixels-at-start generation to pixels-at-end
|
||||
// (so what was column 0 is now column 25).
|
||||
@@ -276,7 +276,7 @@ private:
|
||||
static constexpr int first_sync_column = 49; // Also a guess.
|
||||
static constexpr int sync_length = 4; // One of the two likely candidates.
|
||||
|
||||
int int_cycles = int(cycles.as_integral());
|
||||
auto int_cycles = cycles.as<int>();
|
||||
while(int_cycles) {
|
||||
const int cycles_this_line = std::min(65 - column_, int_cycles);
|
||||
const int ending_column = column_ + cycles_this_line;
|
||||
|
||||
@@ -873,7 +873,7 @@ public:
|
||||
|
||||
// Propagate time far and wide.
|
||||
cycles_since_clock_tick_ += duration;
|
||||
auto ticks = cycles_since_clock_tick_.divide(Cycles(CLOCK_RATE)).as_integral();
|
||||
auto ticks = cycles_since_clock_tick_.divide(Cycles(CLOCK_RATE)).get();
|
||||
while(ticks--) {
|
||||
clock_.update();
|
||||
video_.last_valid()->notify_clock_tick(); // The video controller marshalls the one-second interrupt.
|
||||
|
||||
@@ -556,7 +556,7 @@ private:
|
||||
forceinline void advance_time(HalfCycles duration) {
|
||||
time_since_video_update_ += duration;
|
||||
iwm_ += duration;
|
||||
ram_subcycle_ = (ram_subcycle_ + duration.as_integral()) & 15;
|
||||
ram_subcycle_ = (ram_subcycle_ + duration.get()) & 15;
|
||||
|
||||
// The VIA runs at one-tenth of the 68000's clock speed, in sync with the E clock.
|
||||
// See: Guide to the Macintosh Hardware Family p149 (PDF p188). Some extra division
|
||||
@@ -614,7 +614,7 @@ private:
|
||||
|
||||
// Consider updating the real-time clock.
|
||||
real_time_clock_ += duration;
|
||||
auto ticks = real_time_clock_.divide_cycles(Cycles(CLOCK_RATE)).as_integral();
|
||||
auto ticks = real_time_clock_.divide_cycles(Cycles(CLOCK_RATE)).get();
|
||||
while(ticks--) {
|
||||
clock_.update();
|
||||
// TODO: leave a delay between toggling the input rather than using this coupled hack.
|
||||
@@ -731,7 +731,7 @@ private:
|
||||
void run_for(HalfCycles duration) {
|
||||
// The 6522 enjoys a divide-by-ten, so multiply back up here to make the
|
||||
// divided-by-two clock the audio works on.
|
||||
audio_.time_since_update += HalfCycles(duration.as_integral() * 5);
|
||||
audio_.time_since_update += HalfCycles(duration.get() * 5);
|
||||
}
|
||||
|
||||
void flush() {
|
||||
|
||||
@@ -60,7 +60,7 @@ void Video::run_for(HalfCycles duration) {
|
||||
// the number of fetches.
|
||||
while(duration > HalfCycles(0)) {
|
||||
const auto pixel_start = frame_position_ % line_length;
|
||||
const int line = int((frame_position_ / line_length).as_integral());
|
||||
const auto line = (frame_position_ / line_length).as<int>();
|
||||
|
||||
const auto cycles_left_in_line = std::min(line_length - pixel_start, duration);
|
||||
|
||||
@@ -75,8 +75,8 @@ void Video::run_for(HalfCycles duration) {
|
||||
//
|
||||
// Then 12 lines of border, 3 of sync, 11 more of border.
|
||||
|
||||
const int first_word = int(pixel_start.as_integral()) >> 4;
|
||||
const int final_word = int((pixel_start + cycles_left_in_line).as_integral()) >> 4;
|
||||
const auto first_word = pixel_start.as<int>() >> 4;
|
||||
const auto final_word = (pixel_start + cycles_left_in_line).as<int>() >> 4;
|
||||
|
||||
if(first_word != final_word) {
|
||||
if(line < 342) {
|
||||
@@ -155,12 +155,12 @@ void Video::run_for(HalfCycles duration) {
|
||||
}
|
||||
|
||||
bool Video::vsync() {
|
||||
const auto line = (frame_position_ / line_length).as_integral();
|
||||
const auto line = (frame_position_ / line_length).get();
|
||||
return line >= 353 && line < 356;
|
||||
}
|
||||
|
||||
HalfCycles Video::next_sequence_point() {
|
||||
const auto line = (frame_position_ / line_length).as_integral();
|
||||
const auto line = (frame_position_ / line_length).get();
|
||||
if(line >= 353 && line < 356) {
|
||||
// Currently in vsync, so get time until start of line 357,
|
||||
// when vsync will end.
|
||||
|
||||
@@ -70,8 +70,8 @@ public:
|
||||
*/
|
||||
bool is_outputting(HalfCycles offset = HalfCycles(0)) {
|
||||
const auto offset_position = frame_position_ + offset % frame_length;
|
||||
const int column = int((offset_position % line_length).as_integral()) >> 4;
|
||||
const int line = int((offset_position / line_length).as_integral());
|
||||
const auto column = (offset_position % line_length).as<int>() >> 4;
|
||||
const auto line = (offset_position / line_length).as<int>();
|
||||
return line < 342 && column < 32;
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
Adjusts @c confidence_counter according to the results of the most recent run_for.
|
||||
*/
|
||||
void apply_confidence(Analyser::Dynamic::ConfidenceCounter &confidence_counter) override {
|
||||
if(cycle_count_.as_integral() < 200) return;
|
||||
if(cycle_count_.get() < 200) return;
|
||||
if(horizontal_counter_resets_ > 10)
|
||||
confidence_counter.add_miss();
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ private:
|
||||
|
||||
inline uint8_t update_audio() {
|
||||
const unsigned int clock_divisor = 57;
|
||||
int cycles_to_run_for = int(cycles_since_audio_update_.divide(clock_divisor).as_integral());
|
||||
auto cycles_to_run_for = cycles_since_audio_update_.divide(clock_divisor).as<int>();
|
||||
|
||||
int table_position = 0;
|
||||
for(int c = 0; c < 3; c++) {
|
||||
|
||||
@@ -148,7 +148,7 @@ Outputs::Display::ScanStatus TIA::get_scaled_scan_status() const {
|
||||
}
|
||||
|
||||
void TIA::run_for(const Cycles cycles) {
|
||||
int number_of_cycles = int(cycles.as_integral());
|
||||
auto number_of_cycles = cycles.as<int>();
|
||||
|
||||
// if part way through a line, definitely perform a partial, at most up to the end of the line
|
||||
if(horizontal_counter_) {
|
||||
@@ -181,7 +181,7 @@ void TIA::reset_horizontal_counter() {
|
||||
}
|
||||
|
||||
int TIA::get_cycles_until_horizontal_blank(const Cycles from_offset) {
|
||||
return (cycles_per_line - (horizontal_counter_ + from_offset.as_integral()) % cycles_per_line) % cycles_per_line;
|
||||
return (cycles_per_line - (horizontal_counter_ + from_offset.get()) % cycles_per_line) % cycles_per_line;
|
||||
}
|
||||
|
||||
void TIA::set_background_colour(uint8_t colour) {
|
||||
|
||||
@@ -44,7 +44,7 @@ bool IntelligentKeyboard::serial_line_did_produce_bit(Serial::Line<false> *, int
|
||||
}
|
||||
|
||||
ClockingHint::Preference IntelligentKeyboard::preferred_clocking() const {
|
||||
return output_line_.transmission_data_time_remaining().as_integral() ? ClockingHint::Preference::RealTime : ClockingHint::Preference::None;
|
||||
return output_line_.transmission_data_time_remaining().get() ? ClockingHint::Preference::RealTime : ClockingHint::Preference::None;
|
||||
}
|
||||
|
||||
void IntelligentKeyboard::run_for(HalfCycles duration) {
|
||||
|
||||
@@ -154,7 +154,7 @@ Outputs::Display::DisplayType Video::get_display_type() const {
|
||||
}
|
||||
|
||||
void Video::run_for(HalfCycles duration) {
|
||||
int integer_duration = int(duration.as_integral());
|
||||
auto integer_duration = duration.as<int>();
|
||||
assert(integer_duration >= 0);
|
||||
|
||||
while(integer_duration) {
|
||||
|
||||
@@ -380,7 +380,7 @@ public:
|
||||
|
||||
// The WD/etc runs at a nominal 8Mhz.
|
||||
if constexpr (has_disk_controller) {
|
||||
exdos_.run_for(Cycles(full_length.as_integral()));
|
||||
exdos_.run_for(Cycles(full_length.get()));
|
||||
}
|
||||
|
||||
switch(cycle.operation) {
|
||||
|
||||
@@ -53,7 +53,7 @@ void DiskROM::run_for(HalfCycles half_cycles) {
|
||||
// Input clock is going to be 7159090/2 Mhz, but the drive controller
|
||||
// needs an 8Mhz clock, so scale up. 8000000/7159090 simplifies to
|
||||
// 800000/715909.
|
||||
controller_cycles_ += 800000 * half_cycles.as_integral();
|
||||
controller_cycles_ += 800000 * half_cycles.get();
|
||||
WD::WD1770::run_for(Cycles(int(controller_cycles_ / 715909)));
|
||||
controller_cycles_ %= 715909;
|
||||
}
|
||||
|
||||
@@ -774,7 +774,7 @@ public:
|
||||
}
|
||||
|
||||
if(!tape_player_is_sleeping_)
|
||||
tape_player_.run_for(int(cycle.length.as_integral()));
|
||||
tape_player_.run_for(cycle.length.as<int>());
|
||||
|
||||
return addition;
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ void Microdisc::set_head_load_request(bool head_load) {
|
||||
|
||||
void Microdisc::run_for(const Cycles cycles) {
|
||||
if(head_load_request_counter_ < head_load_request_counter_target) {
|
||||
head_load_request_counter_ += cycles.as_integral();
|
||||
head_load_request_counter_ += cycles.get();
|
||||
if(head_load_request_counter_ >= head_load_request_counter_target) set_head_loaded(true);
|
||||
}
|
||||
WD::WD1770::run_for(cycles);
|
||||
|
||||
@@ -146,7 +146,7 @@ void VideoOutput::run_for(const Cycles cycles) {
|
||||
#define clamp(action) \
|
||||
if(cycles_run_for <= number_of_cycles) { action; } else cycles_run_for = number_of_cycles;
|
||||
|
||||
int number_of_cycles = int(cycles.as_integral());
|
||||
auto number_of_cycles = cycles.as<int>();
|
||||
while(number_of_cycles) {
|
||||
int h_counter = counter_ & 63;
|
||||
int cycles_run_for = 0;
|
||||
|
||||
@@ -42,7 +42,7 @@ void Video::flush() {
|
||||
void Video::flush(bool next_sync) {
|
||||
if(sync_) {
|
||||
// If in sync, that takes priority. Output the proper amount of sync.
|
||||
crt_.output_sync(int(time_since_update_.as_integral()));
|
||||
crt_.output_sync(time_since_update_.as<int>());
|
||||
} else {
|
||||
// If not presently in sync, then...
|
||||
|
||||
@@ -50,8 +50,8 @@ void Video::flush(bool next_sync) {
|
||||
// If there is output data queued, output it either if it's being interrupted by
|
||||
// sync, or if we're past its end anyway. Otherwise let it be.
|
||||
int data_length = int(line_data_pointer_ - line_data_);
|
||||
if(data_length < int(time_since_update_.as_integral()) || next_sync) {
|
||||
auto output_length = std::min(data_length, int(time_since_update_.as_integral()));
|
||||
if(data_length < time_since_update_.as<int>() || next_sync) {
|
||||
auto output_length = std::min(data_length, time_since_update_.as<int>());
|
||||
crt_.output_data(output_length);
|
||||
line_data_pointer_ = line_data_ = nullptr;
|
||||
time_since_update_ -= HalfCycles(output_length);
|
||||
|
||||
@@ -629,7 +629,7 @@ private:
|
||||
z80_.set_interrupt_line(video_.last_valid()->get_interrupt_line(), video_.last_sequence_point_overrun());
|
||||
}
|
||||
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(duration.as_integral());
|
||||
if(!tape_player_is_sleeping_) tape_player_.run_for(duration.get());
|
||||
|
||||
// Update automatic tape motor control, if enabled; if it's been
|
||||
// 0.5 seconds since software last possibly polled the tape, stop it.
|
||||
@@ -643,7 +643,7 @@ private:
|
||||
}
|
||||
|
||||
if constexpr (model == Model::Plus3) {
|
||||
fdc_ += Cycles(duration.as_integral());
|
||||
fdc_ += Cycles(duration.get());
|
||||
}
|
||||
|
||||
if(typer_) typer_->run_for(duration);
|
||||
|
||||
@@ -104,7 +104,7 @@ static CPU::MOS6502::Register registerForRegister(CSTestMachine6502Register reg)
|
||||
}
|
||||
|
||||
- (uint32_t)timestamp {
|
||||
return uint32_t(_processor->get_timestamp().as_integral());
|
||||
return _processor->get_timestamp().as<uint32_t>();
|
||||
}
|
||||
|
||||
- (void)setIrqLine:(BOOL)irqLine {
|
||||
|
||||
@@ -173,7 +173,7 @@ struct PortAccessDelegate191: public CPU::Z80::AllRAMProcessor::PortAccessDelega
|
||||
}
|
||||
|
||||
- (int)completedHalfCycles {
|
||||
return int(_processor->get_timestamp().as_integral());
|
||||
return _processor->get_timestamp().as<int>();
|
||||
}
|
||||
|
||||
- (void)setNmiLine:(BOOL)nmiLine {
|
||||
@@ -244,7 +244,7 @@ struct PortAccessDelegate191: public CPU::Z80::AllRAMProcessor::PortAccessDelega
|
||||
}
|
||||
capture.address = address;
|
||||
capture.value = value;
|
||||
capture.timeStamp = int(timeStamp.as_integral());
|
||||
capture.timeStamp = timeStamp.as<int>();
|
||||
|
||||
[_busOperationCaptures addObject:capture];
|
||||
}
|
||||
|
||||
@@ -31,14 +31,14 @@
|
||||
int c = 5;
|
||||
bool vsync = _video->vsync();
|
||||
while(c--) {
|
||||
auto remaining_time_in_state = _video->next_sequence_point().as_integral();
|
||||
auto remaining_time_in_state = _video->next_sequence_point().get();
|
||||
NSLog(@"Vsync %@ expected for %@ half-cycles", vsync ? @"on" : @"off", @(remaining_time_in_state));
|
||||
while(remaining_time_in_state--) {
|
||||
XCTAssertEqual(vsync, _video->vsync());
|
||||
_video->run_for(HalfCycles(1));
|
||||
|
||||
if(remaining_time_in_state)
|
||||
XCTAssertEqual(remaining_time_in_state, _video->next_sequence_point().as_integral());
|
||||
XCTAssertEqual(remaining_time_in_state, _video->next_sequence_point().get());
|
||||
}
|
||||
vsync ^= true;
|
||||
}
|
||||
|
||||
@@ -36,10 +36,10 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
|
||||
vdp.write(1, 0x8a);
|
||||
|
||||
// Get time until interrupt.
|
||||
auto time_until_interrupt = vdp.next_sequence_point().as_integral() - 1;
|
||||
auto time_until_interrupt = vdp.next_sequence_point().get() - 1;
|
||||
|
||||
// Check that an interrupt is now scheduled.
|
||||
NSAssert(time_until_interrupt != HalfCycles::max().as_integral() - 1, @"No interrupt scheduled");
|
||||
NSAssert(time_until_interrupt != HalfCycles::max().get() - 1, @"No interrupt scheduled");
|
||||
NSAssert(time_until_interrupt > 0, @"Interrupt is scheduled in the past");
|
||||
|
||||
// Check interrupt flag isn't set prior to the reported time.
|
||||
@@ -55,7 +55,7 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
|
||||
NSAssert(!vdp.get_interrupt_line(), @"Interrupt wasn't reset by status read");
|
||||
|
||||
// Check interrupt flag isn't set prior to the reported time.
|
||||
time_until_interrupt = vdp.next_sequence_point().as_integral() - 1;
|
||||
time_until_interrupt = vdp.next_sequence_point().get() - 1;
|
||||
vdp.run_for(HalfCycles(time_until_interrupt));
|
||||
NSAssert(!vdp.get_interrupt_line(), @"Interrupt line went active early [2]");
|
||||
|
||||
@@ -82,10 +82,10 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
|
||||
|
||||
// Clear the pending interrupt and ask about the next one (i.e. the first one).
|
||||
vdp.read(1);
|
||||
auto time_until_interrupt = vdp.next_sequence_point().as_integral() - 1;
|
||||
auto time_until_interrupt = vdp.next_sequence_point().get() - 1;
|
||||
|
||||
// Check that an interrupt is now scheduled.
|
||||
NSAssert(time_until_interrupt != HalfCycles::max().as_integral() - 1, @"No interrupt scheduled");
|
||||
NSAssert(time_until_interrupt != HalfCycles::max().get() - 1, @"No interrupt scheduled");
|
||||
NSAssert(time_until_interrupt > 0, @"Interrupt is scheduled in the past");
|
||||
|
||||
// Check interrupt flag isn't set prior to the reported time.
|
||||
@@ -116,10 +116,10 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
|
||||
|
||||
// Now run through an entire frame...
|
||||
int half_cycles = 262*228*2;
|
||||
auto last_time_until_interrupt = vdp.next_sequence_point().as_integral();
|
||||
auto last_time_until_interrupt = vdp.next_sequence_point().get();
|
||||
while(half_cycles--) {
|
||||
// Validate that an interrupt happened if one was expected, and clear anything that's present.
|
||||
NSAssert(vdp.get_interrupt_line() == (last_time_until_interrupt == HalfCycles::max().as_integral()), @"Unexpected interrupt state change; expected %d but got %d; position %d %d @ %d", (last_time_until_interrupt == 0), vdp.get_interrupt_line(), c, with_eof, half_cycles);
|
||||
NSAssert(vdp.get_interrupt_line() == (last_time_until_interrupt == HalfCycles::max().get()), @"Unexpected interrupt state change; expected %d but got %d; position %d %d @ %d", (last_time_until_interrupt == 0), vdp.get_interrupt_line(), c, with_eof, half_cycles);
|
||||
|
||||
if(vdp.get_interrupt_line()) {
|
||||
vdp.read(1);
|
||||
@@ -129,8 +129,8 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
|
||||
vdp.run_for(HalfCycles(1));
|
||||
|
||||
// Get the time until interrupt.
|
||||
auto time_until_interrupt = vdp.next_sequence_point().as_integral();
|
||||
NSAssert(time_until_interrupt != HalfCycles::max().as_integral() || vdp.get_interrupt_line(), @"No interrupt scheduled; position %d %d @ %d", c, with_eof, half_cycles);
|
||||
auto time_until_interrupt = vdp.next_sequence_point().get();
|
||||
NSAssert(time_until_interrupt != HalfCycles::max().get() || vdp.get_interrupt_line(), @"No interrupt scheduled; position %d %d @ %d", c, with_eof, half_cycles);
|
||||
NSAssert(time_until_interrupt >= 0, @"Interrupt is scheduled in the past; position %d %d @ %d", c, with_eof, half_cycles);
|
||||
|
||||
if(last_time_until_interrupt > 1) {
|
||||
@@ -148,11 +148,11 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
|
||||
- (void)testTimeUntilLine {
|
||||
VDP vdp;
|
||||
|
||||
auto time_until_line = vdp.get_time_until_line(-1).as_integral();
|
||||
auto time_until_line = vdp.get_time_until_line(-1).get();
|
||||
for(int c = 0; c < 262*228*5; ++c) {
|
||||
vdp.run_for(HalfCycles(1));
|
||||
|
||||
const auto time_remaining_until_line = vdp.get_time_until_line(-1).as_integral();
|
||||
const auto time_remaining_until_line = vdp.get_time_until_line(-1).get();
|
||||
--time_until_line;
|
||||
if(time_until_line) {
|
||||
NSAssert(
|
||||
|
||||
@@ -119,7 +119,7 @@ public:
|
||||
}
|
||||
|
||||
int get_cycle_count() {
|
||||
return int(duration_.as_integral()) >> 1;
|
||||
return duration_.as<int>() >> 1;
|
||||
}
|
||||
|
||||
void reset_cycle_count() {
|
||||
|
||||
@@ -391,7 +391,7 @@ private:
|
||||
at construction, filtering it and passing it on to the speaker's delegate if there is one.
|
||||
*/
|
||||
void run_for(const Cycles cycles) {
|
||||
process(size_t(cycles.as_integral()));
|
||||
process(cycles.as<size_t>());
|
||||
}
|
||||
|
||||
SampleSource &sample_source_;
|
||||
|
||||
@@ -950,7 +950,7 @@ template < class T,
|
||||
operation_indices.push_back(target.all_operations.size());
|
||||
for(std::size_t t = 0; t < lengths[c];) {
|
||||
// Skip zero-length bus cycles.
|
||||
if(table[c][t].type == MicroOp::BusOperation && table[c][t].machine_cycle.length.as_integral() == 0) {
|
||||
if(table[c][t].type == MicroOp::BusOperation && table[c][t].machine_cycle.length.get() == 0) {
|
||||
t++;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
using namespace Storage::Disk;
|
||||
|
||||
Controller::Controller(Cycles clock_rate) :
|
||||
clock_rate_multiplier_(128000000 / clock_rate.as_integral()),
|
||||
clock_rate_(clock_rate.as_integral() * clock_rate_multiplier_),
|
||||
clock_rate_multiplier_(128000000 / clock_rate.get()),
|
||||
clock_rate_(clock_rate.get() * clock_rate_multiplier_),
|
||||
pll_(100, *this),
|
||||
empty_drive_(int(clock_rate.as_integral()), 1, 1),
|
||||
empty_drive_(clock_rate.as<int>(), 1, 1),
|
||||
drive_(&empty_drive_) {
|
||||
empty_drive_.set_clocking_hint_observer(this);
|
||||
set_expected_bit_length(Time(1));
|
||||
@@ -64,7 +64,7 @@ void Controller::process_event(const Drive::Event &event) {
|
||||
}
|
||||
|
||||
void Controller::advance(const Cycles cycles) {
|
||||
if(is_reading_) pll_.run_for(Cycles(cycles.as_integral() * clock_rate_multiplier_));
|
||||
if(is_reading_) pll_.run_for(Cycles(cycles.get() * clock_rate_multiplier_));
|
||||
}
|
||||
|
||||
void Controller::process_write_completed() {
|
||||
|
||||
@@ -46,8 +46,8 @@ public:
|
||||
@c number_of_cycles The time to run the loop for.
|
||||
*/
|
||||
void run_for(const Cycles cycles) {
|
||||
offset_ += cycles.as_integral();
|
||||
phase_ += cycles.as_integral();
|
||||
offset_ += cycles.get();
|
||||
phase_ += cycles.get();
|
||||
if(phase_ >= window_length_) {
|
||||
auto windows_crossed = phase_ / window_length_;
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ void Drive::set_event_delegate(Storage::Disk::Drive::EventDelegate *const delega
|
||||
}
|
||||
|
||||
void Drive::advance(const Cycles cycles) {
|
||||
cycles_since_index_hole_ += cycles.as_integral();
|
||||
cycles_since_index_hole_ += cycles.get();
|
||||
if(event_delegate_) event_delegate_->advance(cycles);
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ void Drive::run_for(const Cycles cycles) {
|
||||
if(has_disk_) {
|
||||
Time zero(0);
|
||||
|
||||
auto number_of_cycles = cycles.as_integral();
|
||||
auto number_of_cycles = cycles.get();
|
||||
while(number_of_cycles) {
|
||||
auto cycles_until_next_event = get_cycles_until_next_event();
|
||||
auto cycles_to_run_for = std::min(cycles_until_next_event, number_of_cycles);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
using namespace SCSI;
|
||||
|
||||
Bus::Bus(const HalfCycles clock_rate) {
|
||||
cycles_to_time_ = 1.0 / double(clock_rate.as_integral());
|
||||
cycles_to_time_ = 1.0 / clock_rate.as<double>();
|
||||
|
||||
// NB: note that the dispatch times below are **ORDERED**
|
||||
// from least to greatest. Each box should contain the number
|
||||
@@ -87,7 +87,7 @@ ClockingHint::Preference Bus::preferred_clocking() const {
|
||||
}
|
||||
|
||||
void Bus::update_observers() {
|
||||
const auto time_elapsed = double(time_in_state_.as_integral()) * cycles_to_time_;
|
||||
const auto time_elapsed = time_in_state_.as<double>() * cycles_to_time_;
|
||||
for(auto &observer: observers_) {
|
||||
observer->scsi_bus_did_change(*this, state_, time_elapsed);
|
||||
}
|
||||
@@ -98,7 +98,7 @@ void Bus::run_for(const HalfCycles time) {
|
||||
time_in_state_ += time;
|
||||
|
||||
const auto old_index = dispatch_index_;
|
||||
const auto time_as_int = time_in_state_.as_integral();
|
||||
const auto time_as_int = time_in_state_.get();
|
||||
while(dispatch_index_ < dispatch_times_.size() && time_as_int >= dispatch_times_[dispatch_index_]) {
|
||||
++dispatch_index_;
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ TimedEventLoop::TimedEventLoop(Cycles::IntType input_clock_rate) :
|
||||
input_clock_rate_(input_clock_rate) {}
|
||||
|
||||
void TimedEventLoop::run_for(const Cycles cycles) {
|
||||
auto remaining_cycles = cycles.as_integral();
|
||||
auto remaining_cycles = cycles.get();
|
||||
#ifndef NDEBUG
|
||||
decltype(remaining_cycles) cycles_advanced = 0;
|
||||
#endif
|
||||
@@ -44,7 +44,7 @@ void TimedEventLoop::run_for(const Cycles cycles) {
|
||||
advance(remaining_cycles);
|
||||
}
|
||||
|
||||
assert(cycles_advanced == cycles.as_integral());
|
||||
assert(cycles_advanced == cycles.get());
|
||||
assert(cycles_until_event_ > 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user