From 1266bbb224d8bcfe732328e0ed1896d1d6695d22 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 5 Apr 2021 21:02:37 -0400 Subject: [PATCH] Makes the TMS a sequence-point-generating JustInTimeActor. --- ClockReceiver/ClockReceiver.hpp | 8 ++++++++ ClockReceiver/JustInTime.hpp | 10 +++++++++- Components/9918/9918.cpp | 6 +++--- Components/9918/9918.hpp | 8 ++++---- Machines/ColecoVision/ColecoVision.cpp | 14 +++----------- Machines/MSX/MSX.cpp | 13 +++---------- Machines/MasterSystem/MasterSystem.cpp | 14 +++----------- 7 files changed, 33 insertions(+), 40 deletions(-) diff --git a/ClockReceiver/ClockReceiver.hpp b/ClockReceiver/ClockReceiver.hpp index de2c23345..1a3ddfdb9 100644 --- a/ClockReceiver/ClockReceiver.hpp +++ b/ClockReceiver/ClockReceiver.hpp @@ -10,7 +10,9 @@ #define ClockReceiver_hpp #include "ForceInline.hpp" + #include +#include /* Informal pattern for all classes that run from a clock cycle: @@ -176,6 +178,9 @@ class Cycles: public WrappedInt { public: forceinline constexpr Cycles(IntType l) noexcept : WrappedInt(l) {} forceinline constexpr Cycles() noexcept : WrappedInt() {} + forceinline static constexpr Cycles max() { + return Cycles(std::numeric_limits::max()); + } private: friend WrappedInt; @@ -195,6 +200,9 @@ class HalfCycles: public WrappedInt { public: forceinline constexpr HalfCycles(IntType l) noexcept : WrappedInt(l) {} forceinline constexpr HalfCycles() noexcept : WrappedInt() {} + forceinline static constexpr HalfCycles max() { + return HalfCycles(std::numeric_limits::max()); + } forceinline constexpr HalfCycles(const Cycles &cycles) noexcept : WrappedInt(cycles.as_integral() * 2) {} diff --git a/ClockReceiver/JustInTime.hpp b/ClockReceiver/JustInTime.hpp index 273f79bcd..8d709559c 100644 --- a/ClockReceiver/JustInTime.hpp +++ b/ClockReceiver/JustInTime.hpp @@ -105,7 +105,9 @@ template ::value) { time_until_event_ -= rhs; if(time_until_event_ <= LocalTimeScale(0)) { + time_overrun_ = time_until_event_; flush(); + update_sequence_point(); return true; } } @@ -174,6 +176,12 @@ template get_interrupt_line()); + } time_since_sn76489_update_ += length; // Act only if necessary. @@ -263,7 +265,6 @@ class ConcreteMachine: case 5: *cycle.value = vdp_->read(address); z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line()); - time_until_interrupt_ = vdp_->get_time_until_interrupt(); break; case 7: { @@ -304,7 +305,6 @@ class ConcreteMachine: case 5: vdp_->write(address, *cycle.value); z80_.set_non_maskable_interrupt_line(vdp_->get_interrupt_line()); - time_until_interrupt_ = vdp_->get_time_until_interrupt(); break; case 7: @@ -341,13 +341,6 @@ class ConcreteMachine: } } - if(time_until_interrupt_ > 0) { - time_until_interrupt_ -= length; - if(time_until_interrupt_ <= HalfCycles(0)) { - z80_.set_non_maskable_interrupt_line(true, time_until_interrupt_); - } - } - return penalty; } @@ -408,7 +401,6 @@ class ConcreteMachine: bool joysticks_in_keypad_mode_ = false; HalfCycles time_since_sn76489_update_; - HalfCycles time_until_interrupt_; Analyser::Dynamic::ConfidenceCounter confidence_counter_; int pc_zero_accesses_ = 0; diff --git a/Machines/MSX/MSX.cpp b/Machines/MSX/MSX.cpp index 4b1ca673d..15b2bf9ef 100644 --- a/Machines/MSX/MSX.cpp +++ b/Machines/MSX/MSX.cpp @@ -419,7 +419,9 @@ class ConcreteMachine: // but otherwise runs without pause. const HalfCycles addition((cycle.operation == CPU::Z80::PartialMachineCycle::ReadOpcode) ? 2 : 0); const HalfCycles total_length = addition + cycle.length; - vdp_ += total_length; + if(vdp_ += total_length) { + z80_.set_interrupt_line(vdp_->get_interrupt_line(), vdp_.last_sequence_point_overrun()); + } time_since_ay_update_ += total_length; memory_slots_[0].cycles_since_update += total_length; memory_slots_[1].cycles_since_update += total_length; @@ -520,7 +522,6 @@ class ConcreteMachine: case 0x98: case 0x99: *cycle.value = vdp_->read(address); z80_.set_interrupt_line(vdp_->get_interrupt_line()); - time_until_interrupt_ = vdp_->get_time_until_interrupt(); break; case 0xa2: @@ -545,7 +546,6 @@ class ConcreteMachine: case 0x98: case 0x99: vdp_->write(address, *cycle.value); z80_.set_interrupt_line(vdp_->get_interrupt_line()); - time_until_interrupt_ = vdp_->get_time_until_interrupt(); break; case 0xa0: case 0xa1: @@ -606,12 +606,6 @@ class ConcreteMachine: if(!tape_player_is_sleeping_) tape_player_.run_for(int(cycle.length.as_integral())); - if(time_until_interrupt_ > 0) { - time_until_interrupt_ -= total_length; - if(time_until_interrupt_ <= HalfCycles(0)) { - z80_.set_interrupt_line(true, time_until_interrupt_); - } - } return addition; } @@ -785,7 +779,6 @@ class ConcreteMachine: uint8_t unpopulated_[8192]; HalfCycles time_since_ay_update_; - HalfCycles time_until_interrupt_; uint8_t key_states_[16]; int selected_key_line_ = 0; diff --git a/Machines/MasterSystem/MasterSystem.cpp b/Machines/MasterSystem/MasterSystem.cpp index f43e999ea..562f48967 100644 --- a/Machines/MasterSystem/MasterSystem.cpp +++ b/Machines/MasterSystem/MasterSystem.cpp @@ -214,7 +214,9 @@ class ConcreteMachine: } forceinline HalfCycles perform_machine_cycle(const CPU::Z80::PartialMachineCycle &cycle) { - vdp_ += cycle.length; + if(vdp_ += cycle.length) { + z80_.set_interrupt_line(vdp_->get_interrupt_line(), vdp_.last_sequence_point_overrun()); + } time_since_sn76489_update_ += cycle.length; if(cycle.is_terminal()) { @@ -266,7 +268,6 @@ class ConcreteMachine: case 0x80: case 0x81: *cycle.value = vdp_->read(address); z80_.set_interrupt_line(vdp_->get_interrupt_line()); - time_until_interrupt_ = vdp_->get_time_until_interrupt(); break; case 0xc0: { if(memory_control_ & 0x4) { @@ -330,7 +331,6 @@ class ConcreteMachine: case 0x80: case 0x81: // i.e. ports 0x80–0xbf. vdp_->write(address, *cycle.value); z80_.set_interrupt_line(vdp_->get_interrupt_line()); - time_until_interrupt_ = vdp_->get_time_until_interrupt(); break; case 0xc1: case 0xc0: // i.e. ports 0xc0–0xff. if(has_fm_audio_) { @@ -374,13 +374,6 @@ class ConcreteMachine: } } - if(time_until_interrupt_ > 0) { - time_until_interrupt_ -= cycle.length; - if(time_until_interrupt_ <= HalfCycles(0)) { - z80_.set_interrupt_line(true, time_until_interrupt_); - } - } - // The pause button is debounced and takes effect only one line before pixels // begin; time_until_debounce_ keeps track of the time until then. time_until_debounce_ -= cycle.length; @@ -505,7 +498,6 @@ class ConcreteMachine: bool reset_is_pressed_ = false, pause_is_pressed_ = false; HalfCycles time_since_sn76489_update_; - HalfCycles time_until_interrupt_; HalfCycles time_until_debounce_; uint8_t ram_[8*1024];