1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-24 05:18:36 +00:00

Take initial swing at LLDT.

This commit is contained in:
Thomas Harte
2025-05-12 17:22:11 -04:00
parent 2572da872a
commit 275e75980c
4 changed files with 37 additions and 5 deletions
+3 -1
View File
@@ -82,7 +82,6 @@ struct SegmentDescriptor {
// Tested at loading (?): present(), privilege_level().
if(type == AccessType::Read && executable() && !readable()) {
throw_exception();
}
@@ -99,6 +98,9 @@ struct SegmentDescriptor {
/// @returns The base of this segment descriptor.
uint32_t base() const { return base_; }
/// @returns The offset of this segment descriptor.
uint32_t offset() const { return offset_; }
/// @returns The bounds of this segment descriptor; will be either [0, limit] or [limit, INT_MAX] depending on descriptor type.
/// Accesses must be `>= bounds().begin` and `<= bounds().end`.
DescriptorBounds bounds() const { return bounds_; }
@@ -124,6 +124,28 @@ void ldt(
context.segments.did_update(table);
}
template <typename AddressT, typename ContextT>
void lldt(
read_t<AddressT> source_segment,
ContextT &context
) {
const auto ldt =
descriptor_at<SegmentDescriptor>(
context.linear_memory,
context.registers.template get<DescriptorTable::Global>(),
source_segment & ~7);
DescriptorTablePointer location;
location.limit = ldt.base();
location.base = ldt.offset();
if constexpr (std::is_same_v<AddressT, uint16_t>) {
location.base &= 0xff'ff'ff;
}
context.registers.template set<DescriptorTable::Local>(location);
context.segments.did_update(DescriptorTable::Local);
}
template <DescriptorTable table, typename AddressT, typename InstructionT, typename ContextT>
void sdt(
read_t<AddressT> destination_address,
@@ -340,6 +340,13 @@ template <
assert(false);
}
break;
case Operation::LLDT:
if constexpr (ContextT::model >= Model::i80286) {
Primitive::lldt<AddressT>(source_r(), context);
} else {
assert(false);
}
break;
case Operation::SIDT:
if constexpr (ContextT::model >= Model::i80286) {
Primitive::sdt<DescriptorTable::Interrupt, AddressT>(source_indirect(), instruction, context);
+5 -4
View File
@@ -109,10 +109,11 @@ public:
template <DescriptorTable table>
void set(const DescriptorTablePointer location) {
static constexpr bool is_global = table == DescriptorTable::Global;
static_assert(is_global || table == DescriptorTable::Interrupt);
auto &target = is_global ? global_ : interrupt_;
target = location;
switch(table) {
case DescriptorTable::Local: local_ = location; break;
case DescriptorTable::Global: global_ = location; break;
case DescriptorTable::Interrupt: interrupt_ = location; break;
}
}
template <DescriptorTable table>