mirror of
https://github.com/TomHarte/CLK.git
synced 2024-07-07 23:29:06 +00:00
JustInTimeActors can now specify a clock divider.
This commit is contained in:
parent
516d78f5a8
commit
d7982aa84e
@ -139,10 +139,10 @@ template <class T> class WrappedInt {
|
|||||||
Severs from @c this the effect of dividing by @c divisor; @c this will end up with
|
Severs from @c this the effect of dividing by @c divisor; @c this will end up with
|
||||||
the value of @c this modulo @c divisor and @c divided by @c divisor is returned.
|
the value of @c this modulo @c divisor and @c divided by @c divisor is returned.
|
||||||
*/
|
*/
|
||||||
forceinline T divide(const T &divisor) {
|
template <typename Result = T> forceinline Result divide(const T &divisor) {
|
||||||
T result(length_ / divisor.length_);
|
Result r;
|
||||||
length_ %= divisor.length_;
|
static_cast<T *>(this)->fill(r, divisor);
|
||||||
return result;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -177,6 +177,11 @@ class Cycles: public WrappedInt<Cycles> {
|
|||||||
result.length_ = length_;
|
result.length_ = length_;
|
||||||
length_ = 0;
|
length_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fill(Cycles &result, const Cycles &divisor) {
|
||||||
|
result.length_ = length_ / divisor.length_;
|
||||||
|
length_ %= divisor.length_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Describes an integer number of half cycles: single clock signal transitions.
|
/// Describes an integer number of half cycles: single clock signal transitions.
|
||||||
@ -215,6 +220,16 @@ class HalfCycles: public WrappedInt<HalfCycles> {
|
|||||||
result.length_ = length_;
|
result.length_ = length_;
|
||||||
length_ = 0;
|
length_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fill(Cycles &result, const HalfCycles &divisor) {
|
||||||
|
result = Cycles(length_ / (divisor.length_ << 1));
|
||||||
|
length_ %= (divisor.length_ << 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill(HalfCycles &result, const HalfCycles &divisor) {
|
||||||
|
result.length_ = length_ / divisor.length_;
|
||||||
|
length_ %= divisor.length_;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a specialisation of WrappedInt::flush for converting HalfCycles to Cycles
|
// Create a specialisation of WrappedInt::flush for converting HalfCycles to Cycles
|
||||||
|
@ -21,7 +21,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.
|
||||||
*/
|
*/
|
||||||
template <class T, class LocalTimeScale = HalfCycles, class TargetTimeScale = LocalTimeScale> class JustInTimeActor {
|
template <class T, int divider = 1, class LocalTimeScale = HalfCycles, class TargetTimeScale = LocalTimeScale> class JustInTimeActor {
|
||||||
public:
|
public:
|
||||||
/// Constructs a new JustInTimeActor using the same construction arguments as the included object.
|
/// Constructs a new JustInTimeActor using the same construction arguments as the included object.
|
||||||
template<typename... Args> JustInTimeActor(Args&&... args) : object_(std::forward<Args>(args)...) {}
|
template<typename... Args> JustInTimeActor(Args&&... args) : object_(std::forward<Args>(args)...) {}
|
||||||
@ -44,8 +44,14 @@ template <class T, class LocalTimeScale = HalfCycles, class TargetTimeScale = Lo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Flushes all accumulated time.
|
/// Flushes all accumulated time.
|
||||||
inline void flush() {
|
void flush() {
|
||||||
if(!is_flushed_) object_.run_for(time_since_update_.template flush<TargetTimeScale>());
|
if(!is_flushed_) {
|
||||||
|
if(divider == 1) {
|
||||||
|
object_.run_for(time_since_update_.template flush<TargetTimeScale>());
|
||||||
|
} else {
|
||||||
|
object_.run_for(time_since_update_.template divide<TargetTimeScale>(LocalTimeScale(divider)));
|
||||||
|
}
|
||||||
|
}
|
||||||
is_flushed_ = true;
|
is_flushed_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,18 +89,20 @@ void ACIA::run_for(HalfCycles length) {
|
|||||||
const int transmit_advance = length.as_int();
|
const int transmit_advance = length.as_int();
|
||||||
const auto write_data_time_remaining = transmit.write_data_time_remaining();
|
const auto write_data_time_remaining = transmit.write_data_time_remaining();
|
||||||
|
|
||||||
if(transmit_advance > write_data_time_remaining) {
|
if(write_data_time_remaining) {
|
||||||
if(next_transmission_ != NoTransmission) {
|
if(transmit_advance > write_data_time_remaining) {
|
||||||
transmit.flush_writing();
|
if(next_transmission_ != NoTransmission) {
|
||||||
consider_transmission();
|
transmit.flush_writing();
|
||||||
transmit.advance_writer(transmit_advance - write_data_time_remaining);
|
consider_transmission();
|
||||||
|
transmit.advance_writer(transmit_advance - write_data_time_remaining);
|
||||||
|
} else {
|
||||||
|
transmit.advance_writer(transmit_advance);
|
||||||
|
update_clocking_observer();
|
||||||
|
interrupt_request_ |= transmit_interrupt_enabled_;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
transmit.advance_writer(transmit_advance);
|
transmit.advance_writer(transmit_advance);
|
||||||
update_clocking_observer();
|
|
||||||
interrupt_request_ |= transmit_interrupt_enabled_;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
transmit.advance_writer(transmit_advance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reception.
|
// Reception.
|
||||||
|
@ -656,9 +656,11 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
return mouse_;
|
return mouse_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using IWMActor = JustInTimeActor<IWM, 1, HalfCycles, Cycles>;
|
||||||
|
|
||||||
class VIAPortHandler: public MOS::MOS6522::PortHandler {
|
class VIAPortHandler: public MOS::MOS6522::PortHandler {
|
||||||
public:
|
public:
|
||||||
VIAPortHandler(ConcreteMachine &machine, RealTimeClock &clock, Keyboard &keyboard, DeferredAudio &audio, JustInTimeActor<IWM, HalfCycles, Cycles> &iwm, Inputs::QuadratureMouse &mouse) :
|
VIAPortHandler(ConcreteMachine &machine, RealTimeClock &clock, Keyboard &keyboard, DeferredAudio &audio, IWMActor &iwm, Inputs::QuadratureMouse &mouse) :
|
||||||
machine_(machine), clock_(clock), keyboard_(keyboard), audio_(audio), iwm_(iwm), mouse_(mouse) {}
|
machine_(machine), clock_(clock), keyboard_(keyboard), audio_(audio), iwm_(iwm), mouse_(mouse) {}
|
||||||
|
|
||||||
using Port = MOS::MOS6522::Port;
|
using Port = MOS::MOS6522::Port;
|
||||||
@ -764,14 +766,14 @@ template <Analyser::Static::Macintosh::Target::Model model> class ConcreteMachin
|
|||||||
RealTimeClock &clock_;
|
RealTimeClock &clock_;
|
||||||
Keyboard &keyboard_;
|
Keyboard &keyboard_;
|
||||||
DeferredAudio &audio_;
|
DeferredAudio &audio_;
|
||||||
JustInTimeActor<IWM, HalfCycles, Cycles> &iwm_;
|
IWMActor &iwm_;
|
||||||
Inputs::QuadratureMouse &mouse_;
|
Inputs::QuadratureMouse &mouse_;
|
||||||
};
|
};
|
||||||
|
|
||||||
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
||||||
|
|
||||||
DriveSpeedAccumulator drive_speed_accumulator_;
|
DriveSpeedAccumulator drive_speed_accumulator_;
|
||||||
JustInTimeActor<IWM, HalfCycles, Cycles> iwm_;
|
IWMActor iwm_;
|
||||||
|
|
||||||
DeferredAudio audio_;
|
DeferredAudio audio_;
|
||||||
Video video_;
|
Video video_;
|
||||||
|
@ -347,6 +347,8 @@ class ConcreteMachine:
|
|||||||
forceinline void advance_time(HalfCycles length) {
|
forceinline void advance_time(HalfCycles length) {
|
||||||
cycles_since_audio_update_ += length;
|
cycles_since_audio_update_ += length;
|
||||||
mfp_ += length;
|
mfp_ += length;
|
||||||
|
keyboard_acia_ += length;
|
||||||
|
midi_acia_ += length;
|
||||||
|
|
||||||
while(length >= cycles_until_video_event_) {
|
while(length >= cycles_until_video_event_) {
|
||||||
length -= cycles_until_video_event_;
|
length -= cycles_until_video_event_;
|
||||||
@ -366,12 +368,12 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
|
||||||
JustInTimeActor<Video, HalfCycles> video_;
|
JustInTimeActor<Video> video_;
|
||||||
HalfCycles cycles_until_video_event_;
|
HalfCycles cycles_until_video_event_;
|
||||||
|
|
||||||
JustInTimeActor<Motorola::MFP68901::MFP68901, HalfCycles> mfp_;
|
JustInTimeActor<Motorola::MFP68901::MFP68901> mfp_;
|
||||||
JustInTimeActor<Motorola::ACIA::ACIA, HalfCycles> keyboard_acia_;
|
JustInTimeActor<Motorola::ACIA::ACIA, 10> keyboard_acia_;
|
||||||
JustInTimeActor<Motorola::ACIA::ACIA, HalfCycles> midi_acia_;
|
JustInTimeActor<Motorola::ACIA::ACIA, 10> midi_acia_;
|
||||||
|
|
||||||
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||||
GI::AY38910::AY38910 ay_;
|
GI::AY38910::AY38910 ay_;
|
||||||
|
@ -397,7 +397,7 @@ class ConcreteMachine:
|
|||||||
}
|
}
|
||||||
|
|
||||||
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
||||||
JustInTimeActor<TI::TMS::TMS9918, HalfCycles> vdp_;
|
JustInTimeActor<TI::TMS::TMS9918, 1, HalfCycles> vdp_;
|
||||||
|
|
||||||
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||||
TI::SN76489 sn76489_;
|
TI::SN76489 sn76489_;
|
||||||
|
@ -752,7 +752,7 @@ class ConcreteMachine:
|
|||||||
};
|
};
|
||||||
|
|
||||||
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
||||||
JustInTimeActor<TI::TMS::TMS9918, HalfCycles> vdp_;
|
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
||||||
Intel::i8255::i8255<i8255PortHandler> i8255_;
|
Intel::i8255::i8255<i8255PortHandler> i8255_;
|
||||||
|
|
||||||
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||||
|
@ -414,7 +414,7 @@ class ConcreteMachine:
|
|||||||
Target::Region region_;
|
Target::Region region_;
|
||||||
Target::PagingScheme paging_scheme_;
|
Target::PagingScheme paging_scheme_;
|
||||||
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
CPU::Z80::Processor<ConcreteMachine, false, false> z80_;
|
||||||
JustInTimeActor<TI::TMS::TMS9918, HalfCycles> vdp_;
|
JustInTimeActor<TI::TMS::TMS9918> vdp_;
|
||||||
|
|
||||||
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
Concurrency::DeferringAsyncTaskQueue audio_queue_;
|
||||||
TI::SN76489 sn76489_;
|
TI::SN76489 sn76489_;
|
||||||
|
Loading…
Reference in New Issue
Block a user