// // x86DataPointerTests.m // Clock Signal // // Created by Thomas Harte on 27/02/2022. // Copyright 2022 Thomas Harte. All rights reserved. // #import #include "../../../InstructionSets/x86/DataPointerResolver.hpp" #include using namespace InstructionSet::x86; @interface x86DataPointerTests : XCTestCase @end @implementation x86DataPointerTests - (void)test16bitSize1 { const DataPointer indirectPointer( Source::eAX, Source::eDI, 0 ); const DataPointer registerPointer( Source::eBX ); struct Registers { uint16_t ax = 0x1234, di = 0x00ee; uint8_t bl = 0xaa; template DataT read() { assert(is_sized(r)); switch(r) { case Register::AX: return ax; case Register::BL: return bl; case Register::DI: return di; default: return 0; } } template void write(DataT value) { assert(is_sized(r)); switch(r) { case Register::BL: bl = value; break; default: assert(false); } } } registers; struct Memory { std::map data; template DataT read(Source, uint32_t address) { if(address == 0x1234 + 0x00ee) return 0xff; return 0; } template void write(Source, uint32_t address, DataT value) { data[address] = value; } } memory; // TODO: construct this more formally; the code below just assumes size = 1, which is not a contractual guarantee. const auto instruction = Instruction(); using Resolver = DataPointerResolver; const uint8_t memoryValue = Resolver::read( registers, memory, instruction, indirectPointer ); registers.ax = 0x0100; Resolver::write( registers, memory, instruction, indirectPointer, 0xef ); XCTAssertEqual(memoryValue, 0xff); XCTAssertEqual(memory.data[0x01ee], 0xef); const uint8_t registerValue = Resolver::read( registers, memory, instruction, registerPointer ); Resolver::write( registers, memory, instruction, registerPointer, 0x93 ); XCTAssertEqual(registerValue, 0xaa); XCTAssertEqual(registers.bl, 0x93); } @end