1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-08-09 05:25:01 +00:00
Files
CLK/InstructionSets/x86/Interrupts.hpp

117 lines
2.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// Interrupts.hpp
// Clock Signal
//
// Created by Thomas Harte on 06/10/2023.
// Copyright © 2023 Thomas Harte. All rights reserved.
//
#pragma once
namespace InstructionSet::x86 {
enum Interrupt {
//
// Present on all devices.
//
DivideError = 0,
SingleStep = 1,
NMI = 2,
Breakpoint = 3,
Overflow = 4,
BoundRangeExceeded = 5,
//
// Added by the 80286
//
InvalidOpcode = 6,
DeviceNotAvailable = 7,
DoubleFault = 8,
CoprocessorSegmentOverrun = 9,
InvalidTSS = 10,
SegmentNotPresent = 11,
StackSegmentFault = 12,
GeneralProtectionFault = 13,
FloatingPointException = 16,
//
// Added by the 80286
//
PageFault = 14,
AlignmentCheck = 17,
MachineCheck = 18,
};
constexpr bool has_error_code(const Interrupt interrupt) {
switch(interrupt) {
default: assert(false); // 386 exceptions; I don't know yet.
case Interrupt::DivideError:
case Interrupt::SingleStep:
case Interrupt::NMI:
case Interrupt::Breakpoint:
case Interrupt::Overflow:
case Interrupt::BoundRangeExceeded:
case Interrupt::InvalidOpcode:
case Interrupt::DeviceNotAvailable:
case Interrupt::CoprocessorSegmentOverrun:
case Interrupt::FloatingPointException:
return false;
case Interrupt::DoubleFault:
case Interrupt::InvalidTSS:
case Interrupt::SegmentNotPresent:
case Interrupt::StackSegmentFault:
case Interrupt::GeneralProtectionFault:
return true;
}
}
constexpr bool posts_next_instruction_ip(const Interrupt interrupt) {
switch(interrupt) {
default:
return false;
case Interrupt::SingleStep:
case Interrupt::Breakpoint:
case Interrupt::Overflow:
return false;
}
}
struct Code {
uint16_t value = 0;
Code() = default;
Code(
const uint16_t index,
const bool is_local,
const bool is_interrupt,
const bool was_external) noexcept :
value(
index |
(is_local ? 0x4 : 0x0) |
(is_interrupt ? 0x2 : 0x0) |
(was_external ? 0x1 : 0x0)
) {}
// i.e.:
// b3b15: IDT/GDT/LDT entry
// b2: 1 => in LDT; 0 => in GDT;
// b1: 1 => in IDT, ignore b2; 0 => use b2;
// b0:
// 1 => trigger was external to program code;
// 0 => trigger was caused by the instruction described by the CS:IP that is on the stack.
};
struct Exception {
Interrupt cause;
Code code;
Exception() = default;
constexpr Exception(const Interrupt cause) noexcept : cause(cause) {}
constexpr Exception(const Interrupt cause, const Code code) noexcept : cause(cause), code(code) {}
};
}