From 93d2a612ee33a65441de993f4c6820ceb42ddf57 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 29 Jul 2022 16:33:46 -0400 Subject: [PATCH] Add an explicit flush-pipeline step; some tests now pass. --- Machines/Amiga/Blitter.cpp | 17 ++++++++++++----- Machines/Amiga/Blitter.hpp | 19 ++++++++----------- .../Clock SignalTests/AmigaBlitterTests.mm | 1 + 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/Machines/Amiga/Blitter.cpp b/Machines/Amiga/Blitter.cpp index 312f28211..445ff9d07 100644 --- a/Machines/Amiga/Blitter.cpp +++ b/Machines/Amiga/Blitter.cpp @@ -344,7 +344,6 @@ bool Blitter::advance_dma() { x_ = 0; int loop_index_ = -1; write_phase_ = WritePhase::Starting; - stopping_ = false; while(true) { const auto next = sequencer_.next(); @@ -362,7 +361,6 @@ bool Blitter::advance_dma() { ++y_; if(y_ == height_) { sequencer_.complete(); - stopping_ = true; } pointer_[0] += modulos_[0] * channel_enables_[0] * direction_; pointer_[1] += modulos_[1] * channel_enables_[1] * direction_; @@ -389,10 +387,18 @@ bool Blitter::advance_dma() { case Channel::None: continue; case Channel::Write: break; + case Channel::FlushPipeline: + // HACK. REMOVE ONCE NON-BLOCKING. + posit_interrupt(InterruptFlag::Blitter); + height_ = 0; + // END HACK. + + if(write_phase_ == WritePhase::Full) { + ram_[write_address_ & ram_mask_] = write_value_; + } + return true; } - - a32_ = (a32_ << 16) | (a_data_ & transient_a_mask_); b32_ = (b32_ << 16) | b_data_; @@ -443,13 +449,14 @@ bool Blitter::advance_dma() { switch(write_phase_) { case WritePhase::Full: - ram_[write_address_ & ram_mask_] = output; + ram_[write_address_ & ram_mask_] = write_value_; [[fallthrough]]; case WritePhase::Starting: write_phase_ = WritePhase::Full; write_address_ = pointer_[3]; write_value_ = output; + pointer_[3] += direction_; continue; default: break; diff --git a/Machines/Amiga/Blitter.hpp b/Machines/Amiga/Blitter.hpp index 8cb11a7c5..98e0e9e49 100644 --- a/Machines/Amiga/Blitter.hpp +++ b/Machines/Amiga/Blitter.hpp @@ -27,16 +27,14 @@ class BlitterSequencer { public: enum class Channel { /// Tells the caller to calculate and load a new piece of output - /// into the output pipeline, + /// into the output pipeline. /// - /// If any inputs are enabled then a two-stage output pipeline applies: - /// if anything is already in the pipeline then it should now be written. - /// Then the new value should be placed into the pipeline ready for the - /// next write slot. - /// - /// If the pipeline is empty, this acts the same as @c None, indicating - /// an unused DMA slot. + /// If any inputs are enabled then a one-slot output pipeline applies: + /// output will rest in the pipeline for one write phase before being written. Write, + /// Indicates that a write should occur if anything is in the pipeline, otherwise + /// no activity should occur. + FlushPipeline, /// The caller should read from channel C. C, /// The caller should read from channel B. @@ -77,7 +75,7 @@ class BlitterSequencer { default: break; case Phase::Complete: - return std::make_pair(Channel::Write, loop_); + return std::make_pair(Channel::FlushPipeline, loop_); case Phase::PauseAndComplete: phase_ = Phase::Complete; @@ -211,11 +209,10 @@ class Blitter: public DMADevice<4, 4> { uint32_t write_address_ = 0xffff'ffff; uint16_t write_value_ = 0; enum WritePhase { - Starting, Full, Stopped + Starting, Full } write_phase_; int y_, x_; uint16_t transient_a_mask_; - bool stopping_; }; } diff --git a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm index 159bb7cc7..e325c0de1 100644 --- a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm +++ b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm @@ -315,6 +315,7 @@ using WriteVector = std::vector>; case Channel::C: [components addObject:[NSString stringWithFormat:@"C%d", next.second]]; break; case Channel::Write: + case Channel::FlushPipeline: if(is_first_write) { is_first_write = false; [components addObject:@"-"];