From 159f3cb7800b92ee69a71991f98d332af2d77fc7 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 12 May 2025 23:17:34 -0400 Subject: [PATCH] Add SLDT. --- InstructionSets/x86/Implementation/LoadStore.hpp | 9 +++++++++ .../x86/Implementation/PerformImplementation.hpp | 11 +++++++++++ InstructionSets/x86/Perform.hpp | 3 +++ Machines/PCCompatible/Registers.hpp | 6 ++++++ 4 files changed, 29 insertions(+) diff --git a/InstructionSets/x86/Implementation/LoadStore.hpp b/InstructionSets/x86/Implementation/LoadStore.hpp index a78461f71..699e9d941 100644 --- a/InstructionSets/x86/Implementation/LoadStore.hpp +++ b/InstructionSets/x86/Implementation/LoadStore.hpp @@ -164,9 +164,18 @@ void lldt( } context.registers.template set(location); + context.registers.set_ldtr(source_segment); context.segments.did_update(DescriptorTable::Local); } +template +void sldt( + write_t segment, + ContextT &context +) { + segment = AddressT(context.registers.ldtr()); +} + template void sdt( read_t destination_address, diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index cd62718dc..6c11f54b5 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -347,6 +347,7 @@ template < assert(false); } break; + case Operation::SIDT: if constexpr (ContextT::model >= Model::i80286) { Primitive::sdt(source_indirect(), instruction, context); @@ -361,6 +362,16 @@ template < assert(false); } break; + case Operation::SLDT: + // TODO: + // "When the destination operand is a memory location, the segment selector is written to memory as a + // 16-bit quantity, regardless of the operand size." + if constexpr (ContextT::model >= Model::i80286) { + Primitive::sldt(destination_w(), 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/Perform.hpp b/InstructionSets/x86/Perform.hpp index 3090b33f8..5a9591bf4 100644 --- a/InstructionSets/x86/Perform.hpp +++ b/InstructionSets/x86/Perform.hpp @@ -66,6 +66,9 @@ template concept has_msw = requires(RegistersT registers) { { registers.set_msw(uint16_t{}) } -> std::same_as; { registers.msw() } -> std::same_as; + + { registers.set_ldtr(uint16_t{}) } -> std::same_as; + { registers.ldtr() } -> std::same_as; }; template diff --git a/Machines/PCCompatible/Registers.hpp b/Machines/PCCompatible/Registers.hpp index a7037ebed..547babfb5 100644 --- a/Machines/PCCompatible/Registers.hpp +++ b/Machines/PCCompatible/Registers.hpp @@ -107,6 +107,11 @@ public: msw; } + uint16_t ldtr() const { return ldtr_; } + void set_ldtr(const uint16_t ldtr) { + ldtr_ = ldtr; + } + int privilege_level() const { return 0; // TODO. } @@ -138,6 +143,7 @@ public: private: uint16_t machine_status_; DescriptorTablePointer global_, interrupt_, local_; + uint16_t ldtr_; }; }