diff --git a/Machines/Amiga/Blitter.cpp b/Machines/Amiga/Blitter.cpp index 4795f4cbc..1e4d38a69 100644 --- a/Machines/Amiga/Blitter.cpp +++ b/Machines/Amiga/Blitter.cpp @@ -14,8 +14,6 @@ using namespace Amiga; -Blitter::Blitter(uint16_t *ram, size_t size) : ram_(ram), ram_mask_(uint32_t(size-1)) {} - void Blitter::set_control(int index, uint16_t value) { LOG("Set control " << index << " to " << PADHEX(4) << value); } @@ -61,6 +59,6 @@ uint16_t Blitter::get_status() { } bool Blitter::advance() { - ram_[addresses_[3] & ram_mask_] = 0xffff; + ram_[(pointer_[3] >> 1) & ram_mask_] = 0xffff; return false; } diff --git a/Machines/Amiga/Blitter.hpp b/Machines/Amiga/Blitter.hpp index b8a372dcf..af182152c 100644 --- a/Machines/Amiga/Blitter.hpp +++ b/Machines/Amiga/Blitter.hpp @@ -13,12 +13,13 @@ #include <cstdint> #include "../../ClockReceiver/ClockReceiver.hpp" +#include "DMADevice.hpp" namespace Amiga { -class Blitter { +class Blitter: public DMADevice<4> { public: - Blitter(uint16_t *ram, size_t size); + using DMADevice::DMADevice; // Various setters; it's assumed that address decoding is handled externally. // @@ -28,10 +29,6 @@ class Blitter { void set_first_word_mask(uint16_t value); void set_last_word_mask(uint16_t value); - template <int id, int shift> 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); @@ -44,10 +41,6 @@ class Blitter { bool advance(); private: - uint16_t *const ram_; - const uint32_t ram_mask_; - - 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 12895da07..dc775ffa6 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -33,7 +33,7 @@ template <DMAFlag... Flags> struct DMAMask: Mask<DMAFlag, Flags...> {}; } Chipset::Chipset(uint16_t *ram, size_t size) : - blitter_(ram, size), + blitter_(*this, ram, size), bitplanes_(*this, ram, size), copper_(*this, ram, size), disk_(*this, ram, size), diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 271a19106..fd4f02a4b 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -15,6 +15,7 @@ #include "../../Processors/68000/68000.hpp" #include "../../Outputs/CRT/CRT.hpp" +#include "DMADevice.hpp" #include "Blitter.hpp" namespace Amiga { @@ -94,33 +95,7 @@ class Chipset { Outputs::Display::DisplayType get_display_type() const; private: - // MARK: - Common base for DMA components. - - class DMADeviceBase { - public: - DMADeviceBase(Chipset &chipset, uint16_t *ram, size_t size) : chipset_(chipset), ram_(ram), ram_mask_(uint32_t(size - 1)) {} - - protected: - Chipset &chipset_; - uint16_t *ram_ = nullptr; - uint32_t ram_mask_ = 0; - }; - friend DMADeviceBase; - - template <size_t num_addresses> class DMADevice: public DMADeviceBase { - public: - using DMADeviceBase::DMADeviceBase; - - /// Writes the word @c value to the address register @c id, shifting it by @c shift (0 or 16) first. - template <int id, int shift> void set_pointer(uint16_t value) { - static_assert(id < num_addresses); - static_assert(shift == 0 || shift == 16); - pointer_[id] = (pointer_[id] & (0xffff'0000 >> shift)) | uint32_t(value << shift); - } - - protected: - std::array<uint32_t, num_addresses> pointer_{}; - }; + friend class DMADeviceBase; // MARK: - Interrupts. diff --git a/Machines/Amiga/DMADevice.hpp b/Machines/Amiga/DMADevice.hpp new file mode 100644 index 000000000..9b1fe10ec --- /dev/null +++ b/Machines/Amiga/DMADevice.hpp @@ -0,0 +1,48 @@ +// +// DMADevice.hpp +// Clock Signal +// +// Created by Thomas Harte on 14/09/2021. +// Copyright © 2021 Thomas Harte. All rights reserved. +// + +#ifndef DMADevice_hpp +#define DMADevice_hpp + +#include <array> +#include <cstddef> +#include <cstdint> + +namespace Amiga { + +class Chipset; + +class DMADeviceBase { + public: + DMADeviceBase(Chipset &chipset, uint16_t *ram, size_t size) : + chipset_(chipset), ram_(ram), ram_mask_(uint32_t((size - 1) >> 1)) {} + + protected: + Chipset &chipset_; + uint16_t *const ram_ = nullptr; + const uint32_t ram_mask_ = 0; +}; + +template <size_t num_addresses> class DMADevice: public DMADeviceBase { + public: + using DMADeviceBase::DMADeviceBase; + + /// Writes the word @c value to the address register @c id, shifting it by @c shift (0 or 16) first. + template <int id, int shift> void set_pointer(uint16_t value) { + static_assert(id < num_addresses); + static_assert(shift == 0 || shift == 16); + pointer_[id] = (pointer_[id] & (0xffff'0000 >> shift)) | uint32_t(value << shift); + } + + protected: + std::array<uint32_t, num_addresses> pointer_{}; +}; + +} + +#endif /* DMADevice_hpp */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 8fa9ea1c8..29f7af521 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1961,6 +1961,7 @@ 4BC57CD82436A62900FBC404 /* State.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = State.cpp; sourceTree = "<group>"; }; 4BC5C3DF22C994CC00795658 /* 68000MoveTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000MoveTests.mm; sourceTree = "<group>"; }; 4BC5FC2F20CDDDEE00410AA0 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/AppleIIOptions.xib"; sourceTree = SOURCE_ROOT; }; + 4BC6236A26F178DA00F83DFE /* DMADevice.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DMADevice.hpp; sourceTree = "<group>"; }; 4BC751B11D157E61006C31D9 /* 6522Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6522Tests.swift; sourceTree = "<group>"; }; 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = "<group>"; }; 4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = "<group>"; }; @@ -4284,6 +4285,7 @@ 4BC080D726A25ADA00D03FD8 /* Amiga.hpp */, 4B9EC0E026AA260C0060A31F /* Blitter.hpp */, 4B9EC0E526AA4A660060A31F /* Chipset.hpp */, + 4BC6236A26F178DA00F83DFE /* DMADevice.hpp */, 4B9EC0E926B384080060A31F /* Keyboard.hpp */, ); path = Amiga;