diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index ba58f397d..2643aab21 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -661,6 +661,25 @@ void inc(IntT &destination, Status &status) { status.auxiliary_carry = ((destination - 1) ^ destination) & 0x10; } +template +inline void jump(bool condition, IntT displacement, RegistersT ®isters, FlowControllerT &flow_controller) { + /* + IF condition + THEN + EIP ← EIP + SignExtend(DEST); + IF OperandSize = 16 + THEN + EIP ← EIP AND 0000FFFFH; + FI; + FI; + */ + + // TODO: proper behaviour in 32-bit. + if(condition) { + flow_controller.jump(registers.ip() + displacement); + } +} + template void dec(IntT &destination, Status &status) { /* @@ -900,6 +919,119 @@ template < Primitive::call_far(instruction, flow_controller, registers, memory); return; + case Operation::JO: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNO: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JB: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNB: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JZ: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNZ: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JBE: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNBE: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JS: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNS: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JP: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNP: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JL: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNL: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JLE: + Primitive::jump( + status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::JNLE: + Primitive::jump( + !status.condition(), + instruction.displacement(), + registers, + flow_controller); + break; + case Operation::CLC: Primitive::clc(status); return; case Operation::CLD: Primitive::cld(status); return; case Operation::CLI: Primitive::cli(status); return; diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index e0f929e15..0c3134854 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -220,6 +220,10 @@ class FlowController { registers_.ip_ = offset; } + void jump(uint16_t address) { + registers_.ip_ = address; + } + void halt() {} void wait() {} @@ -323,20 +327,35 @@ struct FailedExecution { @"F6.7.json.gz", @"F7.7.json.gz",*/ // INC - @"40.json.gz", @"41.json.gz", @"42.json.gz", @"43.json.gz", - @"44.json.gz", @"45.json.gz", @"46.json.gz", @"47.json.gz", - @"FE.0.json.gz", - @"FF.0.json.gz", +// @"40.json.gz", @"41.json.gz", @"42.json.gz", @"43.json.gz", +// @"44.json.gz", @"45.json.gz", @"46.json.gz", @"47.json.gz", +// @"FE.0.json.gz", +// @"FF.0.json.gz", // DEC - @"48.json.gz", @"49.json.gz", @"4A.json.gz", @"4B.json.gz", - @"4C.json.gz", @"4D.json.gz", @"4E.json.gz", @"4F.json.gz", - @"FE.1.json.gz", - @"FF.1.json.gz", +// @"48.json.gz", @"49.json.gz", @"4A.json.gz", @"4B.json.gz", +// @"4C.json.gz", @"4D.json.gz", @"4E.json.gz", @"4F.json.gz", +// @"FE.1.json.gz", +// @"FF.1.json.gz", // TODO: IN, OUT - // TODO: JO, JNO, JB, JNB, JZ, JNZ, JBE, JNBE, JS, JNS, JP, JNP, JL, JNL, JLE, JNLE, + @"70.json.gz", // JO + @"71.json.gz", // JNO + @"72.json.gz", // JB + @"73.json.gz", // JNB + @"74.json.gz", // JZ + @"75.json.gz", // JNZ + @"76.json.gz", // JBE + @"77.json.gz", // JNBE + @"78.json.gz", // JS + @"79.json.gz", // JNS + @"7A.json.gz", // JP + @"7B.json.gz", // JNP + @"7C.json.gz", // JL + @"7D.json.gz", // JNL + @"7E.json.gz", // JLE + @"7F.json.gz", // JNLE // CALL /* @"E8.json.gz", @"FF.2.json.gz",