diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 25f00d6f1..fd545bf6c 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -146,7 +146,6 @@ void Chipset::output_pixels(int cycles_until_sync) { const uint32_t playfield = bitplane_pixels_.get(is_high_res_); // Output playfield pixels, if a buffer was allocated. - // TODO: HAM. if(pixels_) { if(hold_and_modify_) { apply_ham(uint8_t(playfield >> 16)); @@ -507,18 +506,28 @@ template bool Chipset::perform_cycle() { // // Top priority: bitplane collection. - // TODO: mask off fetch_window_'s lower bits. (Dependant on high/low-res?) - // Also: fetch_stop_ and that + 12/8 is the best I can discern from the Hardware Reference, - // but very obviously isn't how the actual hardware works. Explore on that. - fetch_horizontal_ |= cycle == fetch_window_[0]; - if(cycle == fetch_window_[1]) fetch_stop_ = cycle + (is_high_res_ ? 12 : 8); - fetch_horizontal_ &= cycle != fetch_stop_; - if((dma_control_ & BitplaneFlag) == BitplaneFlag) { - if(fetch_vertical_ && fetch_horizontal_ && bitplanes_.advance_dma(cycle)) { + if(cycle == fetch_window_[0]) { +// printf("Enabled: %d; ", cycle); + horizontal_fetch_ = HorizontalFetch::Enabled; + horizontal_offset_ = cycle; + } + if(horizontal_fetch_ != HorizontalFetch::Disabled) { + if(!((cycle - horizontal_offset_)&7)) { + if(horizontal_fetch_ == HorizontalFetch::StopRequested) { +// printf("Disabled: %d\n", cycle); + horizontal_fetch_ = HorizontalFetch::Disabled; + } + } + + if(horizontal_fetch_ != HorizontalFetch::Disabled && (dma_control_ & BitplaneFlag) == BitplaneFlag && fetch_vertical_ && bitplanes_.advance_dma(cycle - horizontal_offset_)) { did_fetch_ = true; return false; } } + if(cycle == fetch_window_[1]) { +// printf("Disabling: %d; ", cycle); + horizontal_fetch_ = HorizontalFetch::StopRequested; + } // Contradictory snippets from the Hardware Reference manual: // @@ -712,8 +721,7 @@ template Chipset::Changes Chipset::run(HalfCycles length) { previous_bitplanes_.clear(); } did_fetch_ = false; - fetch_horizontal_ = false; - fetch_stop_ = 0xffff; + horizontal_fetch_ = HorizontalFetch::Disabled; if(y_ == short_field_height_ + is_long_field_) { ++vsyncs; @@ -921,7 +929,7 @@ void Chipset::write(uint32_t address, uint16_t value, bool allow_conversion) { if(fetch_window_[0] != value) { LOG("Fetch window start set to " << std::dec << value); } - fetch_window_[0] = value; + fetch_window_[0] = value & 0xfe; break; case 0x094: // DDFSTOP // TODO: something in my interpretation of ddfstart and ddfstop @@ -929,7 +937,7 @@ void Chipset::write(uint32_t address, uint16_t value, bool allow_conversion) { if(fetch_window_[1] != value) { LOG("Fetch window stop set to " << std::dec << fetch_window_[1]); } - fetch_window_[1] = value; + fetch_window_[1] = value & 0xfe; break; // Bitplanes. diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 93529d5a3..518468594 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -166,10 +166,14 @@ class Chipset: private ClockingHint::Observer { uint16_t fetch_window_[2] = {0, 0}; // Ephemeral bitplane collection state. - bool fetch_vertical_ = false, fetch_horizontal_ = false; + bool fetch_vertical_ = false; bool display_horizontal_ = false; bool did_fetch_ = false; - uint16_t fetch_stop_ = 0xffff; + + int horizontal_offset_ = 0; + enum HorizontalFetch { + Disabled, Enabled, StopRequested + } horizontal_fetch_ = HorizontalFetch::Disabled; // Output state. uint16_t border_colour_ = 0;