diff --git a/Machines/Amiga/Blitter.cpp b/Machines/Amiga/Blitter.cpp index e15cc4289..c4cd54a23 100644 --- a/Machines/Amiga/Blitter.cpp +++ b/Machines/Amiga/Blitter.cpp @@ -234,9 +234,19 @@ void Blitter::add_modulos() { } template +template bool Blitter::advance_dma() { if(!height_) return false; + // TODO: eliminate @c complete_immediately and this workaround. + // See commentary in Chipset.cpp. + if constexpr (complete_immediately) { + while(get_status() & 0x4000) { + advance_dma(); + } + return true; + } + if(line_mode_) { not_zero_flag_ = false; @@ -551,3 +561,7 @@ std::vector::Transaction> Blitter::get_ template class Amiga::Blitter; template class Amiga::Blitter; +template bool Amiga::Blitter::advance_dma(); +template bool Amiga::Blitter::advance_dma(); +template bool Amiga::Blitter::advance_dma(); +template bool Amiga::Blitter::advance_dma(); diff --git a/Machines/Amiga/Blitter.hpp b/Machines/Amiga/Blitter.hpp index 720202004..256137ae6 100644 --- a/Machines/Amiga/Blitter.hpp +++ b/Machines/Amiga/Blitter.hpp @@ -192,7 +192,7 @@ template class Blitter: public DMADevice<4, 4> { uint16_t get_status(); - bool advance_dma(); + template bool advance_dma(); struct Transaction { enum class Type { diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 3a6693543..c8accc853 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -654,8 +654,13 @@ template bool Chipset::perform_cycle() { } // Give first refusal to the Blitter (if enabled), otherwise pass on to the CPU. + // + // TODO: determine why I see Blitter issues if I don't allow it to complete immediately. + // All tests pass without immediate completion, and immediate completion just runs the + // non-immediate version until the busy flag is disabled. So probably a scheduling or + // signalling issue out here. constexpr auto BlitterEnabled = DMAFlag::AllBelow | DMAFlag::Blitter; - return (dma_control_ & BlitterEnabled) != BlitterEnabled || !blitter_.advance_dma(); + return (dma_control_ & BlitterEnabled) != BlitterEnabled || !blitter_.advance_dma(); } /// Performs all slots starting with @c first_slot and ending just before @c last_slot. diff --git a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm index bb744507b..9e0dfed68 100644 --- a/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm +++ b/OSBindings/Mac/Clock SignalTests/AmigaBlitterTests.mm @@ -60,7 +60,7 @@ struct Chipset { // Ensure all blitting is completed between register writes; none of the tests // in this test set are about illegal usage. while(blitter.get_status() & 0x4000) { - blitter.advance_dma(); + blitter.advance_dma(); } const auto transactions = blitter.get_and_reset_transactions(); @@ -190,7 +190,7 @@ struct Chipset { return; } - blitter.advance_dma(); + blitter.advance_dma(); const auto transactions = blitter.get_and_reset_transactions(); if(transactions.empty()) {