From ab69fe56c95724f60e5a875b5d32f2c2615cfc34 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 23 Sep 2021 18:13:51 -0400 Subject: [PATCH] Take a first shot at magical instant blitting. --- Machines/Amiga/Blitter.cpp | 36 +++++++++++++++++++++++++++++++++++- Machines/Amiga/Blitter.hpp | 6 ++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/Machines/Amiga/Blitter.cpp b/Machines/Amiga/Blitter.cpp index 652866fab..3aa4182c6 100644 --- a/Machines/Amiga/Blitter.cpp +++ b/Machines/Amiga/Blitter.cpp @@ -8,6 +8,8 @@ #include "Blitter.hpp" +#include "Minterms.h" + //#define NDEBUG #define LOG_PREFIX "[Blitter] " #include "../../Outputs/Log.hpp" @@ -36,6 +38,10 @@ void Blitter::set_size(uint16_t value) { width_ = (width_ & ~0x3f) | (value & 0x3f); height_ = (height_ & ~0x3ff) | (value >> 6); LOG("Set size to " << std::dec << width_ << ", " << height_); + + // Current assumption: writing this register informs the + // blitter that it should treat itself as about to start a new line. + a_ = b_ = 0; } void Blitter::set_minterms(uint16_t value) { @@ -53,6 +59,7 @@ void Blitter::set_horizontal_size(uint16_t value) { void Blitter::set_modulo(int channel, uint16_t value) { LOG("Set modulo size " << channel << " to " << PADHEX(4) << value); + modulos_[channel] = value; } void Blitter::set_data(int channel, uint16_t value) { @@ -114,12 +121,39 @@ bool Blitter::advance() { printf("!!! Line %08x\n", pointer_[3]); // ram_[pointer_[3] & ram_mask_] = 0x0001 << shifts_[0]; + ram_[pointer_[3] & ram_mask_] = 0xffff; } else { // Copy mode. printf("!!! Copy %08x\n", pointer_[3]); + ram_[pointer_[3] & ram_mask_] = 0x8000; + + // Quick hack: do the entire action atomically. Isn't life fabulous? + for(int y = 0; y < height_; y++) { + for(int x = 0; x < width_; x++) { + a_ = (a_ << 16) | ram_[pointer_[0] & ram_mask_]; + b_ = (b_ << 16) | ram_[pointer_[1] & ram_mask_]; + const uint16_t c = ram_[pointer_[2] & ram_mask_]; + + ram_[pointer_[3] & ram_mask_] = + apply_minterm( + uint16_t(a_ >> shifts_[0]), + uint16_t(b_ >> shifts_[1]), + c, + minterms_); + + ++pointer_[0]; + ++pointer_[1]; + ++pointer_[2]; + ++pointer_[3]; + } + + pointer_[0] += modulos_[0]; + pointer_[1] += modulos_[1]; + pointer_[2] += modulos_[2]; + pointer_[3] += modulos_[3]; + } } - ram_[pointer_[3] & ram_mask_] = 0xffff; height_ = 0; return true; diff --git a/Machines/Amiga/Blitter.hpp b/Machines/Amiga/Blitter.hpp index 68a4620e5..8a54b871a 100644 --- a/Machines/Amiga/Blitter.hpp +++ b/Machines/Amiga/Blitter.hpp @@ -41,10 +41,12 @@ class Blitter: public DMADevice<4> { bool advance(); private: - uint8_t minterms_; + uint8_t minterms_ = 0; int width_ = 0, height_ = 0; + uint32_t a_ = 0, b_ = 0; + uint16_t modulos_[4]{}; - int shifts_[2]; + int shifts_[2]{}; bool line_mode_ = false; };