diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index a4c8fd0e8..bca5457e4 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -20,8 +20,44 @@ #include #include +namespace { + +enum class Zone { + LogicallyMappedRAM, + PhysicallyMappedRAM, + IOControllers, + LowROM, + HighROM, + VideoController, + DMAAndMEMC, + AddressTranslator, +}; +constexpr std::array zones(bool is_read) { + std::array zones{}; + for(size_t c = 0; c < zones.size(); c++) { + const auto address = c << 21; + if(address < 0x200'0000) { + zones[c] = Zone::LogicallyMappedRAM; + } else if(address < 0x300'0000) { + zones[c] = Zone::PhysicallyMappedRAM; + } else if(address < 0x340'0000) { + zones[c] = Zone::IOControllers; + } else if(address < 0x360'0000) { + zones[c] = is_read ? Zone::LowROM : Zone::VideoController; + } else if(address < 0x380'0000) { + zones[c] = is_read ? Zone::LowROM : Zone::DMAAndMEMC; + } else { + zones[c] = is_read ? Zone::HighROM : Zone::AddressTranslator; + } + } + return zones; +} + +} + namespace Archimedes { +/// Primarily models the MEMC. struct Memory { void set_rom(const std::vector &rom) { std::copy( @@ -35,7 +71,19 @@ struct Memory { (void)mode; (void)trans; - printf("W of %08x to %08x [%lu]\n", source, address, sizeof(IntT)); + switch (write_zones_[(address >> 21) & 31]) { + case Zone::DMAAndMEMC: +// if(mode != InstructionSet::ARM::Mode::Supervisor) return false; + if((address & 0b1110'0000'0000'0000'0000) == 0b1110'0000'0000'0000'0000) { + printf("MEMC Control: %04x\n", source); + break; + } + [[fallthrough]]; + + default: + printf("Unhandled W of %08x to %08x [%lu]\n", source, address, sizeof(IntT)); + break; + } if(has_moved_rom_ && address < ram_.size()) { *reinterpret_cast(&ram_[address]) = source; @@ -49,6 +97,14 @@ struct Memory { (void)mode; (void)trans; + switch (read_zones_[(address >> 21) & 31]) { + case Zone::PhysicallyMappedRAM: +// if(mode != InstructionSet::ARM::Mode::Supervisor) return false; + source = *reinterpret_cast(&ram_[address & (ram_.size() - 1)]); + return true; + + default: break; + } if(address >= 0x3800000) { has_moved_rom_ = true; source = *reinterpret_cast(&rom_[address - 0x3800000]); @@ -68,6 +124,9 @@ struct Memory { bool has_moved_rom_ = false; std::array ram_{}; std::array rom_; + + static constexpr std::array read_zones_ = zones(true); + static constexpr std::array write_zones_ = zones(false); }; class ConcreteMachine: