diff --git a/InstructionSets/x86/Implementation/LoadStore.hpp b/InstructionSets/x86/Implementation/LoadStore.hpp index a2086f828..3ae2a609c 100644 --- a/InstructionSets/x86/Implementation/LoadStore.hpp +++ b/InstructionSets/x86/Implementation/LoadStore.hpp @@ -85,4 +85,18 @@ void smsw( destination = context.registers.msw(); } +template +void ldt( + read_t source_address, + const InstructionT &instruction, + ContextT &context +) { + context.memory.preauthorise_read( + instruction.data_segment(), + source_address, + 6); + + assert(false); +} + } diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index d91fe0e50..307cfd7f2 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -115,6 +115,13 @@ template < } }; + // Currently a special case for descriptor loading; assumes an indirect operand and returns the + // address indicated. Unlike [source/destination]_r it doesn't read an IntT from that address, + // since those instructions load an atypical six bytes. + const auto source_indirect = [&]() -> AddressT { + return address(instruction, instruction.source(), context); + }; + // Some instructions use a pair of registers as an extended accumulator — DX:AX or EDX:EAX. // The two following return the high and low parts of that pair; they also work in Byte mode to return AH:AL, // i.e. AX split into high and low parts. @@ -282,6 +289,7 @@ template < context.segments.did_update(instruction.destination().source()); } break; + case Operation::SMSW: if constexpr (ContextT::model >= Model::i80286 && std::is_same_v) { Primitive::smsw(destination_w(), context); @@ -289,6 +297,20 @@ template < assert(false); } break; + case Operation::LIDT: + if constexpr (ContextT::model >= Model::i80286) { + Primitive::ldt(source_indirect(), instruction, context); + } else { + assert(false); + } + break; + case Operation::LGDT: + if constexpr (ContextT::model >= Model::i80286) { + Primitive::ldt(source_indirect(), instruction, context); + } else { + assert(false); + } + break; case Operation::JO: jcc(context.flags.template condition()); return; case Operation::JNO: jcc(!context.flags.template condition()); return; diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index d292e9fa2..644dd462c 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -551,6 +551,10 @@ constexpr Operation rep_operation(Operation operation, Repetition repetition) { } } +enum class DescriptorTable { + Global, Local, Interrupt, +}; + /// Provides a 32-bit-style scale, index and base; to produce the address this represents, /// calcluate base() + (index() << scale()). ///