1
0
mirror of https://github.com/TomHarte/CLK.git synced 2026-04-21 02:17:08 +00:00

Continue trying to flesh out exceptions.

This commit is contained in:
Thomas Harte
2025-04-02 23:27:02 -04:00
parent 3be8de6fb0
commit 88d34012c4
3 changed files with 54 additions and 21 deletions
+3 -1
View File
@@ -110,11 +110,13 @@ private:
};
struct Exception {
Interrupt cause;
uint8_t cause;
bool internal = true;
ExceptionCode code;
Exception() = default;
constexpr Exception(const Interrupt cause) noexcept : cause(cause) {}
constexpr Exception(const uint8_t external_cause) noexcept : cause(external_cause), internal(false) {}
constexpr Exception(const Interrupt cause, const ExceptionCode code) noexcept : cause(cause), code(code) {}
};
+48 -17
View File
@@ -740,10 +740,7 @@ public:
// Signal interrupt.
context_.flow_controller.unhalt();
InstructionSet::x86::interrupt(
pics_.pic[0].acknowledge(),
context_
);
perform_fault({pics_.pic[0].acknowledge()});
}
// Do nothing if currently halted.
@@ -794,7 +791,8 @@ public:
// if(decoded_ip_ >= 0x7c00 && decoded_ip_ < 0x7c00 + 1024) {
if(should_log) {
const auto next = to_string(decoded_, InstructionSet::x86::Model::i8086);
// if(next != previous) {
static std::string previous;
if(next != previous) {
std::cout << std::hex << decoded_ip_ << " " << next;
if(decoded_.second.operation() == InstructionSet::x86::Operation::INT) {
@@ -808,8 +806,8 @@ public:
}
std::cout << std::endl;
// previous = next;
// }
previous = next;
}
}
if(decoded_.second.operation() == InstructionSet::x86::Operation::Invalid) {
@@ -836,18 +834,51 @@ public:
}
void perform_fault(const InstructionSet::x86::Exception exception) {
assert(uses_8086_exceptions(x86_model));
if constexpr (uses_8086_exceptions(x86_model)) {
perform_real_interrupt(exception.cause);
} else {
using Interrupt = InstructionSet::x86::Interrupt;
// Regress the IP if this is an exception that posts the instruction's IP.
if(!posts_next_ip(Interrupt(exception.cause))) {
context_.registers.ip() = decoded_ip_;
}
if(!context_.registers.msw() & InstructionSet::x86::MachineStatus::ProtectedModeEnable) {
perform_real_interrupt(exception.cause);
return;
}
try {
printf("TODO!");
// TODO, I think:
//
// (1) push e.code if this is an exception that has a code;
// (2) if in protected mode, do _something_ with the IDT?
// (3) do the stuff of `InstructionSet::x86::interrupt` but possibly catch another exception.
//
// ... upon another exception: double fault.
// ... upon a third: reset.
} catch (const InstructionSet::x86::Exception exception) {
perform_double_fault(exception);
}
}
}
void perform_real_interrupt(const uint8_t code) {
try {
InstructionSet::x86::interrupt(
code,
context_
);
} catch (const InstructionSet::x86::Exception exception) {
perform_double_fault(exception);
}
}
void perform_double_fault(const InstructionSet::x86::Exception exception) {
printf("DOUBLE TODO!");
(void)exception;
printf("TODO!");
// TODO, I think:
//
// (1) push e.code if this is an exception that has a code;
// (2) if in protected mode, do _something_ with the IDT?
// (3) do the stuff of `InstructionSet::x86::interrupt` but possibly catch another exception.
//
// ... upon another exception: double fault.
// ... upon a third: reset.
}
// MARK: - ScanProducer.
+3 -3
View File
@@ -130,7 +130,7 @@ public:
return !awaiting_eoi_ && (requests_ & ~mask_);
}
int acknowledge() {
uint8_t acknowledge() {
in_service_ = 0x01;
int id = 0;
while(!(in_service_ & requests_) && in_service_) {
@@ -142,11 +142,11 @@ public:
eoi_target_ = id;
awaiting_eoi_ = !auto_eoi_;
requests_ &= ~in_service_;
return vector_base_ + id;
return uint8_t(vector_base_ + id);
}
// Spurious interrupt.
return vector_base_ + 7;
return uint8_t(vector_base_ + 7);
}
private: