mirror of
https://github.com/TomHarte/CLK.git
synced 2025-04-19 20:37:34 +00:00
Iterate towards LGDT/LIDT.
Specifically: add a means to get just an indirect address; add an enum for descriptor tables; add an `ldt` function for the global and interrupt tables, which currently just authorises the access and then stops.
This commit is contained in:
parent
3d19d0816b
commit
32c88da6c4
@ -85,4 +85,18 @@ void smsw(
|
||||
destination = context.registers.msw();
|
||||
}
|
||||
|
||||
template <DescriptorTable table, typename IntT, typename InstructionT, typename ContextT>
|
||||
void ldt(
|
||||
read_t<IntT> source_address,
|
||||
const InstructionT &instruction,
|
||||
ContextT &context
|
||||
) {
|
||||
context.memory.preauthorise_read(
|
||||
instruction.data_segment(),
|
||||
source_address,
|
||||
6);
|
||||
|
||||
assert(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<Source::Indirect, AddressT, AccessType::Read>(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<IntT, uint16_t>) {
|
||||
Primitive::smsw(destination_w(), context);
|
||||
@ -289,6 +297,20 @@ template <
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
case Operation::LIDT:
|
||||
if constexpr (ContextT::model >= Model::i80286) {
|
||||
Primitive::ldt<DescriptorTable::Interrupt, AddressT>(source_indirect(), instruction, context);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
case Operation::LGDT:
|
||||
if constexpr (ContextT::model >= Model::i80286) {
|
||||
Primitive::ldt<DescriptorTable::Global, AddressT>(source_indirect(), instruction, context);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
break;
|
||||
|
||||
case Operation::JO: jcc(context.flags.template condition<Condition::Overflow>()); return;
|
||||
case Operation::JNO: jcc(!context.flags.template condition<Condition::Overflow>()); return;
|
||||
|
@ -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()).
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user