1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-20 10:17:05 +00:00

Attempt VERR, VERW.

Without complete success; IBM's third invocation (which I think is a VERR) doesn't give the result that BIOS is looking for.
This commit is contained in:
Thomas Harte
2025-08-12 17:22:14 -04:00
parent ddd090d581
commit 0e498829f7
4 changed files with 67 additions and 3 deletions
+4
View File
@@ -38,6 +38,10 @@ enum class DescriptorType {
Invalid,
};
constexpr bool is_data_or_code(const DescriptorType type) {
return type <= DescriptorType::Stack;
}
enum DescriptorTypeFlag: uint8_t {
Accessed = 1 << 0,
Busy = 1 << 1,
@@ -252,4 +252,20 @@ void str(
destination = context.registers.task_state();
}
template <typename ContextT>
void verr(
read_t<uint16_t> source,
ContextT &context
) {
context.flags.template set_from<Flag::Zero>(!context.segments.template verify<false>(source));
}
template <typename ContextT>
void verw(
read_t<uint16_t> source,
ContextT &context
) {
context.flags.template set_from<Flag::Zero>(!context.segments.template verify<true>(source));
}
}
@@ -605,13 +605,33 @@ template <
}
break;
case Operation::VERR:
if constexpr (ContextT::model >= Model::i80286 && std::is_same_v<IntT, uint16_t>) {
if(is_real(context.cpu_control.mode())) {
throw Exception::exception<Vector::InvalidOpcode>();
return;
}
Primitive::verr(source_r(), context);
} else {
assert(false);
}
break;
case Operation::VERW:
if constexpr (ContextT::model >= Model::i80286 && std::is_same_v<IntT, uint16_t>) {
if(is_real(context.cpu_control.mode())) {
throw Exception::exception<Vector::InvalidOpcode>();
return;
}
Primitive::verw(source_r(), context);
} else {
assert(false);
}
break;
// TODO to reach a full 80286:
//
// LAR
// VERR
// VERW
// LSL
// STR
// LOADALL
}
+24
View File
@@ -32,6 +32,30 @@ public:
using Mode = InstructionSet::x86::Mode;
using Source = InstructionSet::x86::Source;
template <bool for_read>
bool verify(const uint16_t value) {
try {
const auto incoming = descriptor(value);
const auto description = incoming.description();
if(!is_data_or_code(description.type)) {
return false;
}
if(for_read && !description.readable) {
return false;
} else if(!description.writeable) {
return false;
}
// TODO: privilege level?
return true;
} catch (const InstructionSet::x86::Exception &e) {
return false;
}
}
void preauthorise(
const Source segment,
const uint16_t value