diff --git a/InstructionSets/x86/Implementation/FlowControl.hpp b/InstructionSets/x86/Implementation/FlowControl.hpp index a92a094a2..a247a42ed 100644 --- a/InstructionSets/x86/Implementation/FlowControl.hpp +++ b/InstructionSets/x86/Implementation/FlowControl.hpp @@ -213,7 +213,27 @@ void into( ContextT &context ) { if(context.flags.template flag()) { - interrupt(Interrupt::OnOverflow, context); + interrupt(Interrupt::Overflow, context); + } +} + +template +void bound( + const InstructionT &instruction, + read_t destination, + read_t source, + ContextT &context +) { + using sIntT = typename std::make_signed::type; + + const auto source_segment = instruction.data_segment(); + context.memory.preauthorise_read(source_segment, source, 2*sizeof(IntT)); + const sIntT lower_bound = sIntT(context.memory.template access(source_segment, source)); + source += 2; + const sIntT upper_bound = sIntT(context.memory.template access(source_segment, source)); + + if(sIntT(destination) < lower_bound || sIntT(destination) > upper_bound) { + interrupt(Interrupt::BoundRangeExceeded, context); } } diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index cd4c1b48e..a0a1fe684 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -328,8 +328,8 @@ template < } break; } else { - // TODO: perform BOUND as of the 80186. static_assert(int(Operation::SETMOC) == int(Operation::BOUND)); + Primitive::bound(instruction, destination_r(), source_r(), context); } return; diff --git a/InstructionSets/x86/Interrupts.hpp b/InstructionSets/x86/Interrupts.hpp index 51366f11d..f47db4acf 100644 --- a/InstructionSets/x86/Interrupts.hpp +++ b/InstructionSets/x86/Interrupts.hpp @@ -12,11 +12,26 @@ namespace InstructionSet::x86 { enum Interrupt { - DivideError = 0, - SingleStep = 1, - NMI = 2, - OneByte = 3, - OnOverflow = 4, + DivideError = 0, + SingleStep = 1, + NMI = 2, + Breakpoint = 3, + Overflow = 4, + BoundRangeExceeded = 5, + InvalidOpcode = 6, + DeviceNotAvailable = 7, + DoubleFault = 8, + CoprocessorSegmentOverrun = 9, + InvalidTSS = 10, + SegmentNotPresent = 11, + StackSegmentFault = 12, + GeneralProtectionFault = 13, + PageFault = 14, + /* 15 is reserved */ + FloatingPointException = 16, + AlignmentCheck = 17, + MachineCheck = 18, + }; }