diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 46abacfab..e9ed2fd77 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -614,7 +614,7 @@ template bool Chipset::perform_cycle() { constexpr auto sprite_id = (cycle - 0x16) >> 2; static_assert(sprite_id >= 0 && sprite_id < std::tuple_size::value); - if(sprites_[sprite_id].advance_dma((~cycle&2) >> 1, y_)) { + if(sprites_[sprite_id].advance_dma((~cycle&2) >> 1, y_, y_ == vertical_blank_height_)) { return false; } } diff --git a/Machines/Amiga/Sprites.cpp b/Machines/Amiga/Sprites.cpp index 8d3a16afc..d29679a3e 100644 --- a/Machines/Amiga/Sprites.cpp +++ b/Machines/Amiga/Sprites.cpp @@ -62,7 +62,7 @@ void Sprite::set_image_data(int slot, uint16_t value) { visible |= slot == 0; } -bool Sprite::advance_dma(int offset, int y) { +bool Sprite::advance_dma(int offset, int y, bool is_first_line) { assert(offset == 0 || offset == 1); // Determine which word would be fetched, if DMA occurs. @@ -73,7 +73,10 @@ bool Sprite::advance_dma(int offset, int y) { // value in the sprite control words, the next two words fetched from the // sprite data structure are written into the sprite control registers // instead of being sent to the color registers" - if(y == v_stop_) { + // + // Guesswork, primarily from observing Spindizzy Worlds: the first line after + // vertical blank also triggers a control reload. Seek to verify. + if(y == v_stop_ || is_first_line) { if(offset) { // Second control word: stop position (mostly). set_stop_and_control(next_word); diff --git a/Machines/Amiga/Sprites.hpp b/Machines/Amiga/Sprites.hpp index f15f97ad8..a2c05da4e 100644 --- a/Machines/Amiga/Sprites.hpp +++ b/Machines/Amiga/Sprites.hpp @@ -23,7 +23,7 @@ class Sprite: public DMADevice<1> { void set_stop_and_control(uint16_t value); void set_image_data(int slot, uint16_t value); - bool advance_dma(int offset, int y); + bool advance_dma(int offset, int y, bool is_first_line); uint16_t data[2]{}; bool attached = false;