diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 158ae9c84..e86e07dc2 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -220,31 +220,29 @@ template void Chipset::output() { template bool Chipset::perform_cycle() { constexpr auto BlitterFlag = DMAMask::value; + constexpr auto BitplaneFlag = DMAMask::value; constexpr auto CopperFlag = DMAMask::value; constexpr auto DiskFlag = DMAMask::value; - if constexpr (cycle & 1) { - // Odd slot priority is: - // - // 1. Bitplanes. - // 2. Copper, if interested. - // 3. Blitter. - // 4. CPU. - if((dma_control_ & CopperFlag) == CopperFlag) { - if(copper_.advance(uint16_t(((y_ & 0xff) << 8) | (cycle & 0xfe)))) { - return false; - } - } else { - copper_.stop(); - } + // Update state as to whether bitplane fetching should happen now. + // + // TODO: figure out how the hard stops factor into this. + fetch_horizontal_ |= cycle == display_window_start_[0]; + fetch_horizontal_ &= cycle != display_window_stop_[0]; - } else { - // Even slot use/priority: + // Top priority: bitplane collection. + if(fetch_horizontal_ && fetch_vertical_ && (dma_control_ & BitplaneFlag) == BitplaneFlag) { + // TODO: offer a cycle for bitplane collection. + // Probably need to indicate odd or even? + } + + if constexpr (cycle & 1) { + // Odd slot use/priority: // - // 1. Bitplane fetches. - // 2. Disk, then audio, then sprites depending on region. - // 3. Blitter. - // 4. CPU. + // 1. Bitplane fetches [dealt with above]. + // 2. Refresh, disk, audio, or sprites. Depending on region. + // + // Blitter and CPU priority is dealt with below. if constexpr (cycle >= 4 && cycle <= 6) { if((dma_control_ & DiskFlag) == DiskFlag) { if(disk_.advance()) { @@ -252,6 +250,18 @@ template bool Chipset::perform_cycle() { } } } + } else { + // Bitplanes being dealt with, specific odd-cycle responsibility + // is just possibly to pass to the Copper. + // + // The Blitter and CPU are dealt with outside of the odd/even test. + if((dma_control_ & CopperFlag) == CopperFlag) { + if(copper_.advance(uint16_t(((y_ & 0xff) << 8) | (cycle & 0xfe)))) { + return false; + } + } else { + copper_.stop(); + } } // Down here: give first refusal to the Blitter, otherwise @@ -335,6 +345,9 @@ template Chipset::Changes Chipset::run(HalfCycles length) { line_cycle_ = 0; ++y_; + fetch_vertical_ |= y_ == display_window_start_[1]; + fetch_vertical_ &= y_ != display_window_stop_[1]; + if(y_ == frame_height_) { ++changes.vsyncs; interrupt_requests_ |= InterruptMask::value; diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 2c917b700..f0644773f 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -137,17 +137,30 @@ class Chipset { void set_image_data(int slot, uint16_t value); } sprites_[8]; - // MARK: - Raster. + // MARK: - Raster position and state. - int line_cycle_ = 0, y_ = 0; + // Definitions related to PAL/NTSC. int line_length_ = 227; int frame_height_ = 312; int vertical_blank_height_ = 29; + // Current raster position. + int line_cycle_ = 0, y_ = 0; + +// class Bitplanes: public DMADevice { +// +// }; + // Parameters affecting bitplane collection and output. uint16_t display_window_start_[2] = {0, 0}; uint16_t display_window_stop_[2] = {0, 0}; uint16_t fetch_window_[2] = {0, 0}; + // Ephemeral bitplane collection state. + bool fetch_vertical_ = false, fetch_horizontal_ = false; + + using BitplaneData = std::array; + BitplaneData next; + // MARK: - Copper. class Copper: public DMADevice {