diff --git a/Machines/Acorn/Archimedes/MemoryController.hpp b/Machines/Acorn/Archimedes/MemoryController.hpp index a5e8828e4..6e91b8ef2 100644 --- a/Machines/Acorn/Archimedes/MemoryController.hpp +++ b/Machines/Acorn/Archimedes/MemoryController.hpp @@ -107,6 +107,25 @@ struct MemoryController { high_rom_access_time_ = ROMAccessTime((address >> 6) & 3); low_rom_access_time_ = ROMAccessTime((address >> 4) & 3); page_size_ = PageSize((address >> 2) & 3); + switch(page_size_) { + default: + case PageSize::kb4: + page_address_shift_ = 12; + page_adddress_mask_ = 0x0fff; + break; + case PageSize::kb8: + page_address_shift_ = 13; + page_adddress_mask_ = 0x1fff; + break; + case PageSize::kb16: + page_address_shift_ = 14; + page_adddress_mask_ = 0x3fff; + break; + case PageSize::kb32: + page_address_shift_ = 15; + page_adddress_mask_ = 0x7fff; + break; + } logger.info().append("MEMC Control: %08x -> OS:%d sound:%d video:%d refresh:%d high:%d low:%d size:%d", address, os_mode_, sound_dma_enable_, video_dma_enable_, dynamic_ram_refresh_, high_rom_access_time_, low_rom_access_time_, page_size_); map_dirty_ = true; @@ -296,6 +315,8 @@ struct MemoryController { kb16 = 0b10, kb32 = 0b11, } page_size_ = PageSize::kb4; + int page_address_shift_ = 12; + uint32_t page_adddress_mask_ = 0xffff; // Address translator. // @@ -337,33 +358,14 @@ struct MemoryController { } address = aligned(address); address &= 0x1ff'ffff; - size_t page; - - // TODO: eliminate switch here. - switch(page_size_) { - default: - case PageSize::kb4: - page = address >> 12; - address &= 0x0fff; - break; - case PageSize::kb8: - page = address >> 13; - address &= 0x1fff; - break; - case PageSize::kb16: - page = address >> 14; - address &= 0x3fff; - break; - case PageSize::kb32: - page = address >> 15; - address &= 0x7fff; - break; - } + const size_t page = address >> page_address_shift_; const auto &map = mapping(trans, os_mode_); if(!map[page]) { return nullptr; } + + address &= page_adddress_mask_; return reinterpret_cast(&map[page][address]); }