diff --git a/InstructionSets/ARM/Executor.hpp b/InstructionSets/ARM/Executor.hpp index b867fe82c..20ccad951 100644 --- a/InstructionSets/ARM/Executor.hpp +++ b/InstructionSets/ARM/Executor.hpp @@ -42,7 +42,7 @@ struct NullStatusHandler { template struct Executor { template - Executor(StatusObserverT &observer, Args &&...args) : status_observer_(observer), bus(std::forward(args)...) {} + Executor(StatusObserverT &observer, Args &&...args) : bus(std::forward(args)...), status_observer_(observer) {} template Executor(Args &&...args) : bus(std::forward(args)...) {} @@ -327,7 +327,7 @@ struct Executor { } } else { bool did_read; - uint32_t value; + uint32_t value = 0; if constexpr (flags.transfer_byte()) { uint8_t target; @@ -480,7 +480,7 @@ struct Executor { // undo the previous load. struct { uint32_t *target = nullptr; - uint32_t value; + uint32_t value = 0; } last_replacement; for(uint32_t c = 0; c < total; c++) { diff --git a/InstructionSets/ARM/Registers.hpp b/InstructionSets/ARM/Registers.hpp index d85bf6440..31bab96ab 100644 --- a/InstructionSets/ARM/Registers.hpp +++ b/InstructionSets/ARM/Registers.hpp @@ -272,6 +272,7 @@ struct Registers { case Condition::GT: return !le(); case Condition::LE: return le(); + default: case Condition::AL: return true; case Condition::NV: return false; } @@ -351,6 +352,7 @@ struct Registers { } switch(mode_) { + default: case Mode::User: return active_[offset]; case Mode::Supervisor: diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index e8e7f8895..b352ddb89 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -34,15 +34,13 @@ #include #include -namespace { - -Log::Logger logger; - -} - namespace Archimedes { #ifndef NDEBUG +namespace { +Log::Logger logger; +} + template struct HackyDebugger { void notify(uint32_t address, uint32_t instruction, Executor &executor) { @@ -452,7 +450,7 @@ class ConcreteMachine: int video_divider_ = 1; void tick_cpu() { - uint32_t instruction; + uint32_t instruction = 0; if(!executor_.bus.read(executor_.pc(), instruction, executor_.registers().mode(), false)) { // logger.info().append("Prefetch abort at %08x; last good was at %08x", executor_.pc(), last_pc); executor_.prefetch_abort(); diff --git a/Machines/Acorn/Archimedes/MemoryController.hpp b/Machines/Acorn/Archimedes/MemoryController.hpp index f76b6c91c..6e91b8ef2 100644 --- a/Machines/Acorn/Archimedes/MemoryController.hpp +++ b/Machines/Acorn/Archimedes/MemoryController.hpp @@ -71,13 +71,10 @@ struct MemoryController { template bool write(uint32_t address, IntT source, InstructionSet::ARM::Mode, bool trans) { - // User mode may only _write_ to logically-mapped RAM (subject to further testing below). - if(trans && address >= 0x200'0000) { - return false; - } - switch(write_zones_[(address >> 21) & 31]) { case Zone::DMAAndMEMC: { + if(trans) return false; + const auto buffer_address = [](uint32_t source) -> uint32_t { return (source & 0x1'fffc) << 2; }; @@ -110,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; @@ -126,19 +142,23 @@ struct MemoryController { } break; case Zone::IOControllers: + if(trans) return false; ioc_.template write(address, source); break; case Zone::VideoController: + if(trans) return false; // TODO: handle byte writes correctly. ioc_.video().write(source); break; case Zone::PhysicallyMappedRAM: + if(trans) return false; physical_ram(address) = source; break; case Zone::AddressTranslator: + if(trans) return false; // printf("Translator write at %08x; replaces %08x\n", address, pages_[address & 0x7f]); pages_[address & 0x7f] = address; map_dirty_ = true; @@ -154,13 +174,9 @@ struct MemoryController { template bool read(uint32_t address, IntT &source, InstructionSet::ARM::Mode, bool trans) { - // User mode may only read logically-maped RAM and ROM. - if(trans && address >= 0x200'0000 && address < 0x380'0000) { - return false; - } - switch (read_zones_[(address >> 21) & 31]) { case Zone::PhysicallyMappedRAM: + if(trans) return false; source = physical_ram(address); break; @@ -184,6 +200,7 @@ struct MemoryController { break; case Zone::IOControllers: + if(trans) return false; ioc_.template read(address, source); break; @@ -298,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. // @@ -339,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]); } diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme index 19b54b90e..474fa352e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme +++ b/OSBindings/Mac/Clock Signal.xcodeproj/xcshareddata/xcschemes/Clock Signal.xcscheme @@ -62,7 +62,7 @@ length_of_a_bit.clock_rate; reset(); + + return *this; } + void PCMSegmentEventSource::reset() { // start with the first bit to be considered the zeroth, and assume that it'll be // flux transitions for the foreseeable diff --git a/Storage/Disk/Track/PCMSegment.hpp b/Storage/Disk/Track/PCMSegment.hpp index f4a13e0d5..44b605989 100644 --- a/Storage/Disk/Track/PCMSegment.hpp +++ b/Storage/Disk/Track/PCMSegment.hpp @@ -163,6 +163,7 @@ class PCMSegmentEventSource { but a unique pointer into it. */ PCMSegmentEventSource(const PCMSegmentEventSource &); + PCMSegmentEventSource &operator =(const PCMSegmentEventSource &); /*! @returns the next event that will occur in this event stream.