diff --git a/Machines/Amiga/Blitter.cpp b/Machines/Amiga/Blitter.cpp index 3de54c9f0..333558f29 100644 --- a/Machines/Amiga/Blitter.cpp +++ b/Machines/Amiga/Blitter.cpp @@ -28,16 +28,15 @@ void Blitter::set_last_word_mask(uint16_t value) { LOG("Set last word mask: " << PADHEX(4) << value); } -void Blitter::set_pointer(int channel, int shift, uint16_t value) { - LOG("Set pointer " << channel << " shift " << shift << " to " << PADHEX(4) << value); -} - void Blitter::set_size(uint16_t value) { - LOG("Set size " << PADHEX(4) << value); + width_ = (width_ & ~0x3f) | (value & 0x3f); + height_ = (height_ & ~0x3ff) | (value >> 6); + LOG("Set size to " << std::dec << width_ << ", " << height_); } void Blitter::set_minterms(uint16_t value) { LOG("Set minterms " << PADHEX(4) << value); + minterms_ = value & 0xff; } void Blitter::set_vertical_size(uint16_t value) { @@ -61,9 +60,6 @@ uint16_t Blitter::get_status() { return 0; } -int Blitter::get_remaining_accesses() { - return 0; -} - -void Blitter::run_for(int) { +bool Blitter::advance() { + return false; } diff --git a/Machines/Amiga/Blitter.hpp b/Machines/Amiga/Blitter.hpp index 028b7c4c6..7cebc1529 100644 --- a/Machines/Amiga/Blitter.hpp +++ b/Machines/Amiga/Blitter.hpp @@ -27,7 +27,11 @@ class Blitter { void set_control(int index, uint16_t value); void set_first_word_mask(uint16_t value); void set_last_word_mask(uint16_t value); - void set_pointer(int channel, int shift, uint16_t value); + + template void set_pointer(uint16_t value) { + addresses_[id] = (addresses_[id] & (0xffff'0000 >> shift)) | uint32_t(value << shift); + } + void set_size(uint16_t value); void set_minterms(uint16_t value); void set_vertical_size(uint16_t value); @@ -37,16 +41,15 @@ class Blitter { uint16_t get_status(); - /// @returns The number of accesses required to complete the current - /// operation, if any, or 0 if no operation is pending. - int get_remaining_accesses(); - - /// Performs the next n accesses. - void run_for(int accesses); + bool advance(); private: uint16_t *const ram_; const size_t ram_size_; + + uint32_t addresses_[4]; + uint8_t minterms_; + int width_ = 0, height_ = 0; }; } diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 0edc6c56a..65c37be16 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -225,8 +225,8 @@ template bool Chipset::perform_cycle() { if constexpr (cycle & 1) { // Odd slot priority is: // - // 1. Copper, if interested. - // 2. Bitplane. + // 1. Bitplanes. + // 2. Copper, if interested. // 3. Blitter. // 4. CPU. if((dma_control_ & CopperFlag) == CopperFlag) { @@ -246,12 +246,16 @@ template bool Chipset::perform_cycle() { // 4. CPU. if constexpr (cycle >= 4 && cycle <= 6) { if((dma_control_ & DiskFlag) == DiskFlag) { - disk_.advance(); + if(disk_.advance()) { + return false; + } } } } - return true; + // Down here: give first refusal to the Blitter, otherwise + // pass on to the CPU. + return !blitter_.advance(); } template int Chipset::advance_slots(int first_slot, int last_slot) { @@ -547,14 +551,14 @@ void Chipset::perform(const CPU::MC68000::Microcycle &cycle) { case Write(0x044): blitter_.set_first_word_mask(cycle.value16()); break; case Write(0x046): blitter_.set_last_word_mask(cycle.value16()); break; - case Write(0x048): blitter_.set_pointer(2, 16, cycle.value16()); break; - case Write(0x04a): blitter_.set_pointer(2, 0, cycle.value16()); break; - case Write(0x04c): blitter_.set_pointer(1, 16, cycle.value16()); break; - case Write(0x04e): blitter_.set_pointer(1, 0, cycle.value16()); break; - case Write(0x050): blitter_.set_pointer(0, 16, cycle.value16()); break; - case Write(0x052): blitter_.set_pointer(0, 0, cycle.value16()); break; - case Write(0x054): blitter_.set_pointer(3, 16, cycle.value16()); break; - case Write(0x056): blitter_.set_pointer(3, 0, cycle.value16()); break; + case Write(0x048): blitter_.set_pointer<2, 16>(cycle.value16()); break; + case Write(0x04a): blitter_.set_pointer<2, 0>(cycle.value16()); break; + case Write(0x04c): blitter_.set_pointer<1, 16>(cycle.value16()); break; + case Write(0x04e): blitter_.set_pointer<1, 0>(cycle.value16()); break; + case Write(0x050): blitter_.set_pointer<0, 16>(cycle.value16()); break; + case Write(0x052): blitter_.set_pointer<0, 0>(cycle.value16()); break; + case Write(0x054): blitter_.set_pointer<3, 16>(cycle.value16()); break; + case Write(0x056): blitter_.set_pointer<3, 0>(cycle.value16()); break; case Write(0x058): blitter_.set_size(cycle.value16()); break; case Write(0x05a): blitter_.set_minterms(cycle.value16()); break; @@ -680,8 +684,8 @@ void Chipset::Sprite::set_image_data(int slot, uint16_t value) { // MARK: - Disk. -void Chipset::DiskDMA::advance() { - if(!dma_enable_) return; +bool Chipset::DiskDMA::advance() { + if(!dma_enable_) return false; if(!write_) { // TODO: run an actual PLL, collect actual disk data. @@ -693,8 +697,12 @@ void Chipset::DiskDMA::advance() { if(!length_) { chipset_.posit_interrupt(InterruptFlag::DiskBlock); } + + return true; } } + + return false; } // MARK: - CRT connection. diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 598a8a55c..2c917b700 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -225,7 +225,7 @@ class Chipset { } } - void advance(); + bool advance(); private: uint32_t address_;