// // MemorySlotHandler.cpp // Clock Signal // // Created by Thomas Harte on 12/01/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // #include "MemorySlotHandler.hpp" #include using namespace MSX; PrimarySlot::PrimarySlot(MemorySlotChangeHandler &handler) : subslots_{handler, handler, handler, handler} {} MemorySlot::MemorySlot(MemorySlotChangeHandler &handler) : handler_(handler) { unmap(0x0000, 0x10000); } void PrimarySlot::set_secondary_paging(uint8_t value) { secondary_paging_ = value; } uint8_t PrimarySlot::secondary_paging() const { return secondary_paging_; } const uint8_t *PrimarySlot::read_pointer(int segment) const { const int subslot = (secondary_paging_ >> (segment & ~1)) & 3; return subslots_[subslot].read_pointer(segment); } uint8_t *PrimarySlot::write_pointer(int segment) const { const int subslot = (secondary_paging_ >> (segment & ~1)) & 3; return subslots_[subslot].write_pointer(segment); } const uint8_t *MemorySlot::read_pointer(int segment) const { return read_pointers_[segment]; } uint8_t *MemorySlot::write_pointer(int segment) const { return write_pointers_[segment]; } void MemorySlot::set_source(const std::vector &source) { source_ = source; } void MemorySlot::resize_source(std::size_t size) { source_.resize(size); } std::vector &MemorySlot::source() { return source_; } const std::vector &MemorySlot::source() const { return source_; } template void MemorySlot::map(std::size_t source_address, uint16_t destination_address, std::size_t length) { assert(!(destination_address & 8191)); assert(!(length & 8191)); assert(size_t(destination_address) + length <= 65536); for(std::size_t c = 0; c < (length >> 13); ++c) { source_address %= source_.size(); const int bank = int((destination_address >> 13) + c); read_pointers_[bank] = &source_[source_address]; if constexpr (type == AccessType::ReadWrite) { write_pointers_[bank] = read_pointers_[bank]; } source_address += 8192; } handler_.did_page(); } void MemorySlot::map_handler(uint16_t destination_address, std::size_t length) { assert(!(destination_address & 8191)); assert(!(length & 8191)); assert(size_t(destination_address) + length <= 65536); for(std::size_t c = 0; c < (length >> 13); ++c) { read_pointers_[(destination_address >> 13) + c] = nullptr; } handler_.did_page(); } void MemorySlot::unmap(uint16_t destination_address, std::size_t length) { assert(!(destination_address & 8191)); assert(!(length & 8191)); assert(size_t(destination_address) + length <= 65536); for(std::size_t c = 0; c < (length >> 13); ++c) { read_pointers_[(destination_address >> 13) + c] = unmapped.data(); write_pointers_[(destination_address >> 13) + c] = scratch.data(); } handler_.did_page(); } MemorySlot &PrimarySlot::subslot(int slot) { return subslots_[slot]; } template void MemorySlot::map(std::size_t source_address, uint16_t destination_address, std::size_t length); template void MemorySlot::map(std::size_t source_address, uint16_t destination_address, std::size_t length);