diff --git a/Components/9918/Implementation/9918.cpp b/Components/9918/Implementation/9918.cpp index ee91049a2..57c9c392a 100644 --- a/Components/9918/Implementation/9918.cpp +++ b/Components/9918/Implementation/9918.cpp @@ -885,9 +885,9 @@ void Base::commit_register(int reg, uint8_t value) { case 45: Storage::command_context_.arguments = value; - // b6: 0 = video RAM; 1 = expansion RAM. - // b5: MXD (???) - // b4: MXS + // b6: MXC, i.e. destination for INed/OUTed video data; 0 = video RAM; 1 = expansion RAM. + // b5: MXD, destination for command engine. + // b4: MXS, source for command engine. // b3: DIY // b2: DIX // b1: EQ diff --git a/Components/9918/Implementation/9918Base.hpp b/Components/9918/Implementation/9918Base.hpp index 44dddc5e7..de92521ec 100644 --- a/Components/9918/Implementation/9918Base.hpp +++ b/Components/9918/Implementation/9918Base.hpp @@ -437,9 +437,14 @@ template struct Base: public Storage { return; } + // Copy and mutate the RAM pointer. AddressT address = ram_pointer_; ++ram_pointer_; + // Determine the relevant RAM and its mask. + uint8_t *ram = ram_.data(); + AddressT mask = memory_mask(personality); + if constexpr (is_yamaha_vdp(personality)) { // The Yamaha increments only 14 bits of the address in TMS-compatible modes. if(this->underlying_mode_ < ScreenMode::YamahaText80) { @@ -452,6 +457,12 @@ template struct Base: public Storage { // them as if linear. address = (address >> 1) | (address << 16); } + + // Also check whether expansion RAM is the true target here. + if(Storage::command_context_.arguments & 0x40) { + ram = Storage::expansion_ram_.data(); + mask = AddressT(Storage::expansion_ram_.size() - 1); + } } switch(queued_access_) { @@ -490,10 +501,10 @@ template struct Base: public Storage { break; } } - ram_[address & memory_mask(personality)] = read_ahead_buffer_; + ram[address & mask] = read_ahead_buffer_; break; case MemoryAccess::Read: - read_ahead_buffer_ = ram_[address & memory_mask(personality)]; + read_ahead_buffer_ = ram[address & mask]; break; } queued_access_ = MemoryAccess::None; diff --git a/Components/9918/Implementation/Storage.hpp b/Components/9918/Implementation/Storage.hpp index 1ffc2ce38..5ea6be717 100644 --- a/Components/9918/Implementation/Storage.hpp +++ b/Components/9918/Implementation/Storage.hpp @@ -32,6 +32,8 @@ template <> struct Storage { template struct Storage> { using AddressT = uint32_t; + std::array expansion_ram_; + int selected_status_ = 0; int indirect_register_ = 0;