From cf846f501a310769961050584c795f1db569c0e1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 12 Oct 2023 14:24:28 -0400 Subject: [PATCH] Implement LDS, LES. --- .../Implementation/PerformImplementation.hpp | 47 +++++++++++++++++-- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 6 ++- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index 88e35246a..691a13b83 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -55,6 +55,21 @@ uint32_t address( return address + *resolve(instruction, pointer.base(), pointer, registers, memory); } +template +uint32_t address( + InstructionT &instruction, + DataPointer pointer, + RegistersT ®isters, + MemoryT &memory +) { + switch(pointer.source()) { + default: return 0; + case Source::Indirect: return address(instruction, pointer, registers, memory); + case Source::IndirectNoBase: return address(instruction, pointer, registers, memory); + case Source::DirectAddress: return address(instruction, pointer, registers, memory); + } +} + template IntT *resolve( InstructionT &instruction, @@ -750,11 +765,11 @@ template ()) { default: case Source::Immediate: flow_controller.call(instruction.segment(), instruction.offset()); return; @@ -778,6 +793,25 @@ void call_far(InstructionT &instruction, flow_controller.call(segment, offset); } +template +void ld( + InstructionT &instruction, + uint16_t &destination, + MemoryT &memory, + RegistersT ®isters +) { + const auto pointer = instruction.source(); + auto source_address = address(instruction, pointer, registers, memory); + const Source source_segment = pointer.segment(instruction.segment_override()); + + destination = memory.template access(source_segment, source_address); + source_address += 2; + switch(selector) { + case Source::DS: registers.ds() = memory.template access(source_segment, source_address); break; + case Source::ES: registers.es() = memory.template access(source_segment, source_address); break; + } +} + template void int_(uint8_t vector, FlowControllerT &flow_controller) { flow_controller.interrupt(vector); @@ -966,8 +1000,11 @@ template < case Operation::INT: Primitive::int_(instruction.operand(), flow_controller); return; case Operation::INTO: Primitive::into(status, flow_controller); return; - case Operation::SAHF: Primitive::sahf(registers.ah(), status); return; - case Operation::LAHF: Primitive::lahf(registers.ah(), status); return; + case Operation::SAHF: Primitive::sahf(registers.ah(), status); return; + case Operation::LAHF: Primitive::lahf(registers.ah(), status); return; + + case Operation::LDS: if constexpr (data_size == DataSize::Word) Primitive::ld(instruction, destination(), memory, registers); return; + case Operation::LES: if constexpr (data_size == DataSize::Word) Primitive::ld(instruction, destination(), memory, registers); return; case Operation::JO: jcc(status.condition()); return; case Operation::JNO: jcc(!status.condition()); return; diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index ed157cf01..81a260344 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -371,11 +371,13 @@ struct FailedExecution { // INT, INT3 @"CC.json.gz", @"CD.json.gz", -*/ + @"9E.json.gz", // SAHF @"9F.json.gz", // LAHF +*/ + @"C5.json.gz", // LDS + @"C4.json.gz", // LES - // TODO: LDS, LES // TODO: LEA // TODO: CMPS, LODS, MOVS, SCAS, STOS