// // LoadStore.hpp // Clock Signal // // Created by Thomas Harte on 08/11/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // #pragma once #include "InstructionSets/x86/AccessType.hpp" #include "InstructionSets/x86/Descriptors.hpp" #include "InstructionSets/x86/Descriptors.hpp" #include "InstructionSets/x86/MachineStatus.hpp" #include namespace InstructionSet::x86::Primitive { template void xchg( modify_t destination, modify_t source ) { /* TEMP ← DEST DEST ← SRC SRC ← TEMP */ std::swap(destination, source); } template void ld( const InstructionT &instruction, write_t destination, ContextT &context ) { const auto pointer = instruction.source(); uint16_t source_address = uint16_t(address(instruction, pointer, context)); const Source source_segment = instruction.data_segment(); context.memory.preauthorise_read(source_segment, source_address, 4); destination = context.memory.template access(source_segment, source_address); source_address += 2; switch(selector) { case Source::DS: context.registers.ds() = context.memory.template access(source_segment, source_address); break; case Source::ES: context.registers.es() = context.memory.template access(source_segment, source_address); break; } } template void lea( const Instruction &instruction, write_t destination, ContextT &context ) { // TODO: address size. destination = IntT(address(instruction, instruction.source(), context)); } template void xlat( const InstructionT &instruction, ContextT &context ) { AddressT address; if constexpr (std::is_same_v) { address = context.registers.bx() + context.registers.al(); } context.registers.al() = context.memory.template access(instruction.data_segment(), address); } template void mov( write_t destination, read_t source ) { destination = source; } template void smsw( write_t destination, ContextT &context ) { destination = context.registers.msw(); } template void lmsw( read_t source, ContextT &context ) { context.registers.set_msw(source); if(source & MachineStatus::ProtectedModeEnable) { context.cpu_control.set_mode(Mode::Protected286); } } template void ldt( read_t source_address, const InstructionT &instruction, ContextT &context ) { const auto segment = instruction.data_segment(); context.memory.preauthorise_read( segment, source_address, 6); DescriptorTablePointer location; location.limit = context.memory.template access(segment, source_address); location.base = context.memory.template access(segment, AddressT(source_address + 2)); if constexpr (std::is_same_v) { location.base &= 0xff'ff'ff; } context.registers.template set(location); context.segments.did_update(table); } template void sdt( read_t destination_address, const InstructionT &instruction, ContextT &context ) { const auto segment = instruction.data_segment(); context.memory.preauthorise_write( segment, destination_address, 6); const auto location = context.registers.template get
(); context.memory.template preauthorised_write(segment, destination_address, location.limit); context.memory.template preauthorised_write(segment, AddressT(destination_address + 2), location.base); } }