mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Adds notes to self; implements get_next_sequence_point for video, allowing per-line interrupts.
This commit is contained in:
parent
7e39550fc0
commit
9206ab5dc3
@ -50,11 +50,13 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
||||
/// Flushes all accumulated time and returns a pointer to the included object.
|
||||
forceinline T *operator->() {
|
||||
flush();
|
||||
// TODO: I actually need to update time_until_event_ after the access occurring here has ended.
|
||||
// So I guess I need to supply some sort of proxy object and jump on its destructor?
|
||||
return &object_;
|
||||
}
|
||||
|
||||
/// Acts exactly as per the standard ->, but preserves constness.
|
||||
forceinline const T *operator->() const {
|
||||
forceinline const T *operator -> () const {
|
||||
auto non_const_this = const_cast<JustInTimeActor<T, multiplier, divider, LocalTimeScale, TargetTimeScale> *>(this);
|
||||
non_const_this->flush();
|
||||
return &object_;
|
||||
@ -78,6 +80,7 @@ template <class T, int multiplier = 1, int divider = 1, class LocalTimeScale = H
|
||||
object_.run_for(duration);
|
||||
}
|
||||
|
||||
// TODO: this probably shouldn't be per-flush(), merely per-operator-> and when a previous point is passed.
|
||||
if constexpr (has_sequence_points<T>::value) {
|
||||
time_until_event_ = object_.get_next_sequence_point();
|
||||
assert(time_until_event_ > LocalTimeScale(0));
|
||||
|
@ -685,6 +685,8 @@ class ConcreteMachine:
|
||||
while(ticks--) {
|
||||
clock_.update();
|
||||
video_.last_valid()->notify_clock_tick(); // The video controller marshalls the one-second interrupt.
|
||||
// TODO: I think I may have made a false assumption here; does
|
||||
// the VGC have an independent 1-second interrupt?
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
|
@ -104,6 +104,21 @@ void VideoBase::advance(Cycles cycles) {
|
||||
}
|
||||
}
|
||||
|
||||
Cycles VideoBase::get_next_sequence_point() const {
|
||||
const int cycles_into_row = cycles_into_frame_ % CyclesPerLine;
|
||||
const int row = cycles_into_frame_ / CyclesPerLine;
|
||||
|
||||
constexpr int sequence_point_offset = (5 + 8) * CyclesPerTick;
|
||||
|
||||
// Handle every case that doesn't involve wrapping to the next row 0.
|
||||
if(row <= 200) {
|
||||
if(cycles_into_row < sequence_point_offset) return Cycles(sequence_point_offset - cycles_into_row);
|
||||
if(row < 200) return Cycles(CyclesPerLine + sequence_point_offset - cycles_into_row);
|
||||
}
|
||||
|
||||
return Cycles(CyclesPerLine + sequence_point_offset - cycles_into_row + (Lines - row - 1)*CyclesPerLine);
|
||||
}
|
||||
|
||||
void VideoBase::output_row(int row, int start, int end) {
|
||||
// Reasoned guesswork ahoy!
|
||||
//
|
||||
@ -192,7 +207,8 @@ void VideoBase::output_row(int row, int start, int end) {
|
||||
palette_[c] = PaletteConvulve(entry);
|
||||
}
|
||||
|
||||
// TODO: obey line_control_ & 0x40 interrupt control bit.
|
||||
// Post an interrupt if requested.
|
||||
if(line_control_ & 0x40) set_interrupts(0x20);
|
||||
}
|
||||
|
||||
if(next_pixel_) {
|
||||
|
@ -56,6 +56,9 @@ class VideoBase: public Apple::II::VideoSwitches<Cycles> {
|
||||
/// Gets the type of output.
|
||||
Outputs::Display::DisplayType get_display_type() const;
|
||||
|
||||
/// Determines the period until video might autonomously update its interrupt lines.
|
||||
Cycles get_next_sequence_point() const;
|
||||
|
||||
private:
|
||||
Outputs::CRT::CRT crt_;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user