Skip to content

Commit

Permalink
Merge pull request #1394 from TomHarte/ElectronFlicker
Browse files Browse the repository at this point in the history
Electron: don't miss interrupts early in the frame.
  • Loading branch information
TomHarte authored Aug 27, 2024
2 parents 051f054 + b5932ed commit 7e3a331
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 11 deletions.
3 changes: 3 additions & 0 deletions Machines/Acorn/Electron/Electron.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,9 @@ template <bool has_scsi_bus> class ConcreteMachine:
}

inline void signal_interrupt(Interrupt interrupt) {
if(!interrupt) {
return;
}
interrupt_status_ |= interrupt;
evaluate_interrupts();
}
Expand Down
31 changes: 20 additions & 11 deletions Machines/Acorn/Electron/Video.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,27 @@ void VideoOutput::run_for(const Cycles cycles) {
const auto start_position = output_position_;
output_position_ = (output_position_ + number_of_cycles) % cycles_per_frame;

if(
(start_position < real_time_clock_interrupt_1 && output_position_ >= real_time_clock_interrupt_1) ||
(start_position < real_time_clock_interrupt_2 && output_position_ >= real_time_clock_interrupt_2)
) {
interrupts_ = Electron::Interrupt(interrupts_ | Electron::Interrupt::RealTimeClock);
}
const auto test_range = [&](int start, int end) {
if(
(start < real_time_clock_interrupt_1 && end >= real_time_clock_interrupt_1) ||
(start < real_time_clock_interrupt_2 && end >= real_time_clock_interrupt_2)
) {
interrupts_ = Electron::Interrupt(interrupts_ | Electron::Interrupt::RealTimeClock);
}

if(
(start_position < display_end_interrupt_1 && output_position_ >= display_end_interrupt_1) ||
(start_position < display_end_interrupt_2 && output_position_ >= display_end_interrupt_2)
) {
interrupts_ = Electron::Interrupt(interrupts_ | Electron::Interrupt::DisplayEnd);
if(
(start < display_end_interrupt_1 && end >= display_end_interrupt_1) ||
(start < display_end_interrupt_2 && end >= display_end_interrupt_2)
) {
interrupts_ = Electron::Interrupt(interrupts_ | Electron::Interrupt::DisplayEnd);
}
};

if(output_position_ >= start_position) {
test_range(start_position, output_position_);
} else {
test_range(start_position, cycles_per_frame);
test_range(0, output_position_);
}

while(number_of_cycles) {
Expand Down

0 comments on commit 7e3a331

Please sign in to comment.