diff --git a/Machines/Apple/AppleIIgs/MemoryMap.hpp b/Machines/Apple/AppleIIgs/MemoryMap.hpp index 2abeeaa0c..c20ac389f 100644 --- a/Machines/Apple/AppleIIgs/MemoryMap.hpp +++ b/Machines/Apple/AppleIIgs/MemoryMap.hpp @@ -228,12 +228,14 @@ class MemoryMap { }; #define MemoryMapRegion(map, address) map.regions[map.region_map[address >> 8]] -#define MemoryMapRead(region, address, value) *value = region.read ? region.read[address] : 0xff; +#define MemoryMapRead(region, address, value) *value = region.read ? region.read[address] : 0xff #define MemoryMapWrite(map, region, address, value) \ - region.write[address] = *value; \ - if(region.flags & (MemoryMap::Region::IsShadowed)) { \ - const uint32_t shadowed_address = (address & 0xffff) + (uint32_t(0xe1 - (region.flags & MemoryMap::Region::IsShadowedE0)) << 16); \ - map.regions[map.region_map[shadowed_address >> 8]].write[shadowed_address] = *value; \ + if(region.write) { \ + region.write[address] = *value; \ + if(region.flags & (MemoryMap::Region::IsShadowed)) { \ + const uint32_t shadowed_address = (address & 0xffff) + (uint32_t(0xe1 - (region.flags & MemoryMap::Region::IsShadowedE0)) << 16); \ + map.regions[map.region_map[shadowed_address >> 8]].write[shadowed_address] = *value; \ + } \ } } diff --git a/OSBindings/Mac/Clock SignalTests/IIgsMemoryMapTests.mm b/OSBindings/Mac/Clock SignalTests/IIgsMemoryMapTests.mm index e75d1aeb4..d97bf677d 100644 --- a/OSBindings/Mac/Clock SignalTests/IIgsMemoryMapTests.mm +++ b/OSBindings/Mac/Clock SignalTests/IIgsMemoryMapTests.mm @@ -10,11 +10,15 @@ #include "../../../Machines/Apple/AppleIIgs/MemoryMap.hpp" +namespace { + using MemoryMap = Apple::IIgs::MemoryMap; +} + @interface IIgsMemoryMapTests : XCTestCase @end @implementation IIgsMemoryMapTests { - Apple::IIgs::MemoryMap _memoryMap; + MemoryMap _memoryMap; std::vector _ram; std::vector _rom; } @@ -25,10 +29,37 @@ _memoryMap.set_storage(_ram, _rom); } -- (void)testNothing { +- (void)testHigherRAM { + // Fill memory via the map. + for(int address = 0x020000; address < 0x800000; ++address) { + const auto ®ion = MemoryMapRegion(_memoryMap, address); + const uint8_t value = uint8_t(address ^ (address >> 8)); + MemoryMapWrite(_memoryMap, region, address, &value); + } + + // Test by direct access. + for(int address = 0x020000; address < 0x800000; ++address) { + const uint8_t value = uint8_t(address ^ (address >> 8)); + XCTAssertEqual(_ram[address], value); + } } -- (void)testSomeOtherNothing { +- (void)testROMReadonly { + _rom[0] = 0xc0; + + // Test that ROM can be read in the correct location. + const uint32_t address = 0xfc0000; + const auto ®ion = MemoryMapRegion(_memoryMap, address); + uint8_t value; + MemoryMapRead(region, address, &value); + + XCTAssertEqual(value, 0xc0); + + // Try writing to it, and check that nothing happened. + value = 0xfc; + MemoryMapWrite(_memoryMap, region, address, &value); + + XCTAssertEqual(_rom[0], 0xc0); } @end