1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 05:29:23 +00:00

Simplify 'get_next_sequence_point' -> 'next_sequence_point'.

This commit is contained in:
Thomas Harte 2023-09-10 18:00:49 -04:00
parent 211a6e5114
commit 8efb6a9226
27 changed files with 41 additions and 41 deletions

View File

@ -26,7 +26,7 @@
Machines that accumulate HalfCycle time but supply to a Cycle-counted device may supply a Machines that accumulate HalfCycle time but supply to a Cycle-counted device may supply a
separate @c TargetTimeScale at template declaration. separate @c TargetTimeScale at template declaration.
If the held object implements get_next_sequence_point() then it'll be used to flush implicitly If the held object implements @c next_sequence_point() then it'll be used to flush implicitly
as and when sequence points are hit. Callers can use will_flush() to predict these. as and when sequence points are hit. Callers can use will_flush() to predict these.
If the held object is a subclass of ClockingHint::Source, this template will register as an If the held object is a subclass of ClockingHint::Source, this template will register as an
@ -40,7 +40,7 @@ template <class T, class LocalTimeScale = HalfCycles, int multiplier = 1, int di
private: private:
/*! /*!
A std::unique_ptr deleter which causes an update_sequence_point to occur on the actor supplied A std::unique_ptr deleter which causes an update_sequence_point to occur on the actor supplied
to it at construction if it implements get_next_sequence_point(). Otherwise destruction is a no-op. to it at construction if it implements @c next_sequence_point(). Otherwise destruction is a no-op.
**Does not delete the object.** **Does not delete the object.**
@ -247,9 +247,9 @@ template <class T, class LocalTimeScale = HalfCycles, int multiplier = 1, int di
// going to be applied then do a direct max -> max translation rather than // going to be applied then do a direct max -> max translation rather than
// allowing the arithmetic to overflow. // allowing the arithmetic to overflow.
if constexpr (divider == 1 && std::is_same_v<LocalTimeScale, TargetTimeScale>) { if constexpr (divider == 1 && std::is_same_v<LocalTimeScale, TargetTimeScale>) {
time_until_event_ = object_.get_next_sequence_point(); time_until_event_ = object_.next_sequence_point();
} else { } else {
const auto time = object_.get_next_sequence_point(); const auto time = object_.next_sequence_point();
if(time == TargetTimeScale::max()) { if(time == TargetTimeScale::max()) {
time_until_event_ = LocalTimeScale::max(); time_until_event_ = LocalTimeScale::max();
} else { } else {
@ -272,7 +272,7 @@ template <class T, class LocalTimeScale = HalfCycles, int multiplier = 1, int di
bool did_flush_ = false; bool did_flush_ = false;
template <typename S, typename = void> struct has_sequence_points : std::false_type {}; template <typename S, typename = void> struct has_sequence_points : std::false_type {};
template <typename S> struct has_sequence_points<S, decltype(void(std::declval<S &>().get_next_sequence_point()))> : std::true_type {}; template <typename S> struct has_sequence_points<S, decltype(void(std::declval<S &>().next_sequence_point()))> : std::true_type {};
ClockingHint::Preference clocking_preference_ = ClockingHint::Preference::JustInTime; ClockingHint::Preference clocking_preference_ = ClockingHint::Preference::JustInTime;
void set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference clocking) { void set_component_prefers_clocking(ClockingHint::Source *, ClockingHint::Preference clocking) {

View File

@ -207,7 +207,7 @@ void MFP68901::run_for(HalfCycles time) {
} }
} }
HalfCycles MFP68901::get_next_sequence_point() { HalfCycles MFP68901::next_sequence_point() {
return HalfCycles::max(); return HalfCycles::max();
} }

View File

@ -40,7 +40,7 @@ class MFP68901: public ClockingHint::Source {
/// so that mechanism can also be used to reduce the quantity of calls into this class. /// so that mechanism can also be used to reduce the quantity of calls into this class.
/// ///
/// @discussion TODO, alas. /// @discussion TODO, alas.
HalfCycles get_next_sequence_point(); HalfCycles next_sequence_point();
/// Sets the current level of either of the timer event inputs — TAI and TBI in datasheet terms. /// Sets the current level of either of the timer event inputs — TAI and TBI in datasheet terms.
void set_timer_event_input(int channel, bool value); void set_timer_event_input(int channel, bool value);

View File

@ -108,7 +108,7 @@ template <Personality personality> class TMS9918: private Base<personality> {
If get_interrupt_line is true now of if get_interrupt_line would If get_interrupt_line is true now of if get_interrupt_line would
never return true, returns HalfCycles::max(). never return true, returns HalfCycles::max().
*/ */
HalfCycles get_next_sequence_point() const; HalfCycles next_sequence_point() const;
/*! /*!
Returns the amount of time until the nominated line interrupt position is Returns the amount of time until the nominated line interrupt position is

View File

@ -1268,7 +1268,7 @@ uint8_t TMS9918<personality>::get_current_line() const {
return uint8_t(source_row); return uint8_t(source_row);
} }
template <Personality personality> template <Personality personality>
HalfCycles TMS9918<personality>::get_next_sequence_point() const { HalfCycles TMS9918<personality>::next_sequence_point() const {
if(!this->generate_interrupts_ && !this->enable_line_interrupts_) return HalfCycles::max(); if(!this->generate_interrupts_ && !this->enable_line_interrupts_) return HalfCycles::max();
if(get_interrupt_line()) return HalfCycles::max(); if(get_interrupt_line()) return HalfCycles::max();

View File

@ -1171,7 +1171,7 @@ class ConcreteMachine:
machine_->update_audio(); machine_->update_audio();
} }
~AudioUpdater() { ~AudioUpdater() {
machine_->cycles_until_audio_event_ = machine_->sound_glu_.get_next_sequence_point(); machine_->cycles_until_audio_event_ = machine_->sound_glu_.next_sequence_point();
} }
private: private:
ConcreteMachine *machine_; ConcreteMachine *machine_;

View File

@ -218,7 +218,7 @@ uint8_t GLU::get_address_high() {
// MARK: - Update logic. // MARK: - Update logic.
Cycles GLU::get_next_sequence_point() const { Cycles GLU::next_sequence_point() const {
uint32_t result = std::numeric_limits<decltype(result)>::max(); uint32_t result = std::numeric_limits<decltype(result)>::max();
for(int c = 0; c < local_.oscillator_count; c++) { for(int c = 0; c < local_.oscillator_count; c++) {

View File

@ -31,7 +31,7 @@ class GLU: public Outputs::Speaker::SampleSource {
uint8_t get_address_high(); uint8_t get_address_high();
void run_for(Cycles); void run_for(Cycles);
Cycles get_next_sequence_point() const; Cycles next_sequence_point() const;
bool get_interrupt_line(); bool get_interrupt_line();
// SampleSource. // SampleSource.

View File

@ -191,7 +191,7 @@ void Video::advance(Cycles cycles) {
} }
} }
Cycles Video::get_next_sequence_point() const { Cycles Video::next_sequence_point() const {
const int cycles_into_row = cycles_into_frame_ % CyclesPerLine; const int cycles_into_row = cycles_into_frame_ % CyclesPerLine;
const int row = cycles_into_frame_ / CyclesPerLine; const int row = cycles_into_frame_ / CyclesPerLine;

View File

@ -60,7 +60,7 @@ class Video: public Apple::II::VideoSwitches<Cycles> {
Outputs::Display::DisplayType get_display_type() const; Outputs::Display::DisplayType get_display_type() const;
/// Determines the period until video might autonomously update its interrupt lines. /// Determines the period until video might autonomously update its interrupt lines.
Cycles get_next_sequence_point() const; Cycles next_sequence_point() const;
/// Sets the Mega II interrupt enable state — 1/4-second and VBL interrupts are /// Sets the Mega II interrupt enable state — 1/4-second and VBL interrupts are
/// generated here. /// generated here.

View File

@ -575,7 +575,7 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
video_.run_for(time_until_video_event_); video_.run_for(time_until_video_event_);
time_since_video_update_ -= time_until_video_event_; time_since_video_update_ -= time_until_video_event_;
time_until_video_event_ = video_.get_next_sequence_point(); time_until_video_event_ = video_.next_sequence_point();
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !video_.vsync()); via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::One, !video_.vsync());
} }
@ -626,7 +626,7 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
forceinline void update_video() { forceinline void update_video() {
video_.run_for(time_since_video_update_.flush<HalfCycles>()); video_.run_for(time_since_video_update_.flush<HalfCycles>());
time_until_video_event_ = video_.get_next_sequence_point(); time_until_video_event_ = video_.next_sequence_point();
} }
Inputs::Mouse &get_mouse() final { Inputs::Mouse &get_mouse() final {

View File

@ -170,7 +170,7 @@ bool Video::vsync() {
return line >= 353 && line < 356; return line >= 353 && line < 356;
} }
HalfCycles Video::get_next_sequence_point() { HalfCycles Video::next_sequence_point() {
const auto line = (frame_position_ / line_length).as_integral(); const auto line = (frame_position_ / line_length).as_integral();
if(line >= 353 && line < 356) { if(line >= 353 && line < 356) {
// Currently in vsync, so get time until start of line 357, // Currently in vsync, so get time until start of line 357,

View File

@ -80,7 +80,7 @@ class Video {
@returns the amount of time until there is next a transition on the @returns the amount of time until there is next a transition on the
vsync signal. vsync signal.
*/ */
HalfCycles get_next_sequence_point(); HalfCycles next_sequence_point();
private: private:
DeferredAudio &audio_; DeferredAudio &audio_;

View File

@ -395,7 +395,7 @@ bool Video::display_enabled() {
return public_state_.display_enable; return public_state_.display_enable;
} }
HalfCycles Video::get_next_sequence_point() { HalfCycles Video::next_sequence_point() {
// The next sequence point will be whenever display_enabled, vsync or hsync next changes. // The next sequence point will be whenever display_enabled, vsync or hsync next changes.
// Sequence of events within a standard line: // Sequence of events within a standard line:

View File

@ -68,7 +68,7 @@ class Video {
@returns the number of cycles until there is next a change in the hsync, @returns the number of cycles until there is next a change in the hsync,
vsync or display_enable outputs. vsync or display_enable outputs.
*/ */
HalfCycles get_next_sequence_point(); HalfCycles next_sequence_point();
/*! /*!
@returns @c true if the horizontal sync output is currently active; @c false otherwise. @returns @c true if the horizontal sync output is currently active; @c false otherwise.

View File

@ -370,7 +370,7 @@ void VideoOutput::setup_base_address() {
// MARK: - Interrupts // MARK: - Interrupts
Cycles VideoOutput::get_next_sequence_point() { Cycles VideoOutput::next_sequence_point() {
if(output_position_ < real_time_clock_interrupt_1) { if(output_position_ < real_time_clock_interrupt_1) {
return real_time_clock_interrupt_1 - output_position_; return real_time_clock_interrupt_1 - output_position_;
} }

View File

@ -61,7 +61,7 @@ class VideoOutput {
This result may be mutated by calls to @c write. This result may be mutated by calls to @c write.
*/ */
Cycles get_next_sequence_point(); Cycles next_sequence_point();
/*! /*!
@returns a bit mask of all interrupts that have been triggered since the last call to get_interrupt(). @returns a bit mask of all interrupts that have been triggered since the last call to get_interrupt().

View File

@ -315,7 +315,7 @@ void TimedInterruptSource::run_for(Cycles duration) {
update_channel(1, rate_ == InterruptRate::ToneGenerator1, cycles.as<int>()); update_channel(1, rate_ == InterruptRate::ToneGenerator1, cycles.as<int>());
} }
Cycles TimedInterruptSource::get_next_sequence_point() const { Cycles TimedInterruptSource::next_sequence_point() const {
// Since both the 1kHz and 50Hz timers are integer dividers of the 1Hz timer, there's no need // Since both the 1kHz and 50Hz timers are integer dividers of the 1Hz timer, there's no need
// to factor that one in when determining the next sequence point for either of those. // to factor that one in when determining the next sequence point for either of those.
switch(rate_) { switch(rate_) {

View File

@ -144,7 +144,7 @@ class TimedInterruptSource {
/// @returns The amount of time from now until the earliest that /// @returns The amount of time from now until the earliest that
/// @c get_new_interrupts() _might_ have new interrupts to report. /// @c get_new_interrupts() _might_ have new interrupts to report.
Cycles get_next_sequence_point() const; Cycles next_sequence_point() const;
private: private:
static constexpr Cycles clock_rate{250000}; static constexpr Cycles clock_rate{250000};

View File

@ -467,7 +467,7 @@ void Nick::set_output_type(OutputType type, bool force_flush) {
// MARK: - Sequence points. // MARK: - Sequence points.
Cycles Nick::get_next_sequence_point() const { Cycles Nick::next_sequence_point() const {
constexpr int load_point = 16; // i.e. 16 cycles after the start of the line, the constexpr int load_point = 16; // i.e. 16 cycles after the start of the line, the
// interrupt line may change. That is, after the // interrupt line may change. That is, after the
// second byte of the mode line has been read. // second byte of the mode line has been read.

View File

@ -38,7 +38,7 @@ class Nick {
Outputs::Display::ScanStatus get_scaled_scan_status() const; Outputs::Display::ScanStatus get_scaled_scan_status() const;
/// @returns The amount of time until the next potential change in interrupt output. /// @returns The amount of time until the next potential change in interrupt output.
Cycles get_next_sequence_point() const; Cycles next_sequence_point() const;
/*! /*!
@returns The current state of the interrupt line @c true for active; @returns The current state of the interrupt line @c true for active;

View File

@ -315,7 +315,7 @@ template <Timing timing> class Video {
/*! /*!
@returns The amount of time until the next change in the interrupt line, that being the only internally-observeable output. @returns The amount of time until the next change in the interrupt line, that being the only internally-observeable output.
*/ */
HalfCycles get_next_sequence_point() { HalfCycles next_sequence_point() {
constexpr auto timings = get_timings(); constexpr auto timings = get_timings();
// Is the frame still ahead of this interrupt? // Is the frame still ahead of this interrupt?

View File

@ -124,7 +124,7 @@ struct VideoTester {
display_enable = _video->display_enabled(); display_enable = _video->display_enabled();
vsync = _video->vsync(); vsync = _video->vsync();
hsync = _video->hsync(); hsync = _video->hsync();
next_event = _video->get_next_sequence_point(); next_event = _video->next_sequence_point();
} else { } else {
NSAssert(display_enable == _video->display_enabled(), @"Unannounced change in display enabled at cycle %zu [%d before next sequence point]", c, next_event.as<int>()); NSAssert(display_enable == _video->display_enabled(), @"Unannounced change in display enabled at cycle %zu [%d before next sequence point]", c, next_event.as<int>());
NSAssert(vsync == _video->vsync(), @"Unannounced change in vsync at cycle %zu [%d before next sequence point]", c, next_event.as<int>()); NSAssert(vsync == _video->vsync(), @"Unannounced change in vsync at cycle %zu [%d before next sequence point]", c, next_event.as<int>());

View File

@ -38,7 +38,7 @@
int toggles = 0; int toggles = 0;
int interrupts = 0; int interrupts = 0;
uint8_t dividerState = _interruptSource->get_divider_state() & 1; uint8_t dividerState = _interruptSource->get_divider_state() & 1;
int nextSequencePoint = _interruptSource->get_next_sequence_point().as<int>(); int nextSequencePoint = _interruptSource->next_sequence_point().as<int>();
for(int c = 0; c < 250000 * 5; c++) { for(int c = 0; c < 250000 * 5; c++) {
// Advance one cycle. Clock is 500,000 Hz. // Advance one cycle. Clock is 500,000 Hz.
@ -55,7 +55,7 @@
const uint8_t newInterrupts = _interruptSource->get_new_interrupts(); const uint8_t newInterrupts = _interruptSource->get_new_interrupts();
if(newInterrupts) { if(newInterrupts) {
XCTAssertEqual(nextSequencePoint, 0); XCTAssertEqual(nextSequencePoint, 0);
nextSequencePoint = _interruptSource->get_next_sequence_point().as<int>(); nextSequencePoint = _interruptSource->next_sequence_point().as<int>();
if(newInterrupts & 0x02) { if(newInterrupts & 0x02) {
++interrupts; ++interrupts;
@ -66,7 +66,7 @@
} }
} }
XCTAssertEqual(nextSequencePoint, _interruptSource->get_next_sequence_point().as<int>(), @"At cycle %d", c); XCTAssertEqual(nextSequencePoint, _interruptSource->next_sequence_point().as<int>(), @"At cycle %d", c);
} }
XCTAssertEqual(toggles, int(expectedInterruptsPerSecond * 5.0)); XCTAssertEqual(toggles, int(expectedInterruptsPerSecond * 5.0));

View File

@ -46,7 +46,7 @@
- (void)testInterruptPrediction { - (void)testInterruptPrediction {
// Run for the number of cycles implied by the number of lines. // Run for the number of cycles implied by the number of lines.
int next_sequence_point = _nick->get_next_sequence_point().as<int>(); int next_sequence_point = _nick->next_sequence_point().as<int>();
bool last_interrupt_line = _nick->get_interrupt_line(); bool last_interrupt_line = _nick->get_interrupt_line();
for(int c = 0; c < _totalLines*912; c++) { for(int c = 0; c < _totalLines*912; c++) {
@ -61,9 +61,9 @@
last_interrupt_line = interrupt_line; last_interrupt_line = interrupt_line;
if(!next_sequence_point) { if(!next_sequence_point) {
next_sequence_point = _nick->get_next_sequence_point().as<int>(); next_sequence_point = _nick->next_sequence_point().as<int>();
} else { } else {
const int expected_next_sequence_point = _nick->get_next_sequence_point().as<int>(); const int expected_next_sequence_point = _nick->next_sequence_point().as<int>();
XCTAssertEqual(next_sequence_point, expected_next_sequence_point); XCTAssertEqual(next_sequence_point, expected_next_sequence_point);
} }
} }

View File

@ -31,14 +31,14 @@
int c = 5; int c = 5;
bool vsync = _video->vsync(); bool vsync = _video->vsync();
while(c--) { while(c--) {
auto remaining_time_in_state = _video->get_next_sequence_point().as_integral(); auto remaining_time_in_state = _video->next_sequence_point().as_integral();
NSLog(@"Vsync %@ expected for %@ half-cycles", vsync ? @"on" : @"off", @(remaining_time_in_state)); NSLog(@"Vsync %@ expected for %@ half-cycles", vsync ? @"on" : @"off", @(remaining_time_in_state));
while(remaining_time_in_state--) { while(remaining_time_in_state--) {
XCTAssertEqual(vsync, _video->vsync()); XCTAssertEqual(vsync, _video->vsync());
_video->run_for(HalfCycles(1)); _video->run_for(HalfCycles(1));
if(remaining_time_in_state) if(remaining_time_in_state)
XCTAssertEqual(remaining_time_in_state, _video->get_next_sequence_point().as_integral()); XCTAssertEqual(remaining_time_in_state, _video->next_sequence_point().as_integral());
} }
vsync ^= true; vsync ^= true;
} }

View File

@ -36,7 +36,7 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
vdp.write(1, 0x8a); vdp.write(1, 0x8a);
// Get time until interrupt. // Get time until interrupt.
auto time_until_interrupt = vdp.get_next_sequence_point().as_integral() - 1; auto time_until_interrupt = vdp.next_sequence_point().as_integral() - 1;
// Check that an interrupt is now scheduled. // 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().as_integral() - 1, @"No interrupt scheduled");
@ -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"); NSAssert(!vdp.get_interrupt_line(), @"Interrupt wasn't reset by status read");
// Check interrupt flag isn't set prior to the reported time. // Check interrupt flag isn't set prior to the reported time.
time_until_interrupt = vdp.get_next_sequence_point().as_integral() - 1; time_until_interrupt = vdp.next_sequence_point().as_integral() - 1;
vdp.run_for(HalfCycles(time_until_interrupt)); vdp.run_for(HalfCycles(time_until_interrupt));
NSAssert(!vdp.get_interrupt_line(), @"Interrupt line went active early [2]"); NSAssert(!vdp.get_interrupt_line(), @"Interrupt line went active early [2]");
@ -82,7 +82,7 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
// Clear the pending interrupt and ask about the next one (i.e. the first one). // Clear the pending interrupt and ask about the next one (i.e. the first one).
vdp.read(1); vdp.read(1);
auto time_until_interrupt = vdp.get_next_sequence_point().as_integral() - 1; auto time_until_interrupt = vdp.next_sequence_point().as_integral() - 1;
// Check that an interrupt is now scheduled. // 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().as_integral() - 1, @"No interrupt scheduled");
@ -116,7 +116,7 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
// Now run through an entire frame... // Now run through an entire frame...
int half_cycles = 262*228*2; int half_cycles = 262*228*2;
auto last_time_until_interrupt = vdp.get_next_sequence_point().as_integral(); auto last_time_until_interrupt = vdp.next_sequence_point().as_integral();
while(half_cycles--) { while(half_cycles--) {
// Validate that an interrupt happened if one was expected, and clear anything that's present. // 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().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);
@ -129,7 +129,7 @@ using VDP = TI::TMS::TMS9918<TI::TMS::Personality::SMSVDP>;
vdp.run_for(HalfCycles(1)); vdp.run_for(HalfCycles(1));
// Get the time until interrupt. // Get the time until interrupt.
auto time_until_interrupt = vdp.get_next_sequence_point().as_integral(); 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); NSAssert(time_until_interrupt != HalfCycles::max().as_integral() || 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); NSAssert(time_until_interrupt >= 0, @"Interrupt is scheduled in the past; position %d %d @ %d", c, with_eof, half_cycles);