From 93e90b09a01a4da09057d1c39110673d1ff15a3b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 20 Oct 2023 21:46:47 -0400 Subject: [PATCH] Implement MOVS, STOS, revealing an issue in the memory handler. --- .../Implementation/PerformImplementation.hpp | 38 +++++++++++++++++++ OSBindings/Mac/Clock SignalTests/8088Tests.mm | 8 +++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index 1160b2aaf..57343b294 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -1417,6 +1417,38 @@ void lods(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, IntT &e repeat(instruction, eCX, flow_controller); } +template +void movs(const InstructionT &instruction, AddressT &eCX, AddressT &eSI, AddressT &eDI, MemoryT &memory, Status &status, FlowControllerT &flow_controller) { + if(repetition_over(instruction, eCX)) { + return; + } + + Source source_segment = instruction.segment_override(); + if(source_segment == Source::None) source_segment = Source::DS; + + memory.template access(Source::ES, eDI) = memory.template access(source_segment, eSI); + + eSI += status.direction() * sizeof(IntT); + eDI += status.direction() * sizeof(IntT); + + repeat(instruction, eCX, flow_controller); +} + +template +void stos(const InstructionT &instruction, AddressT &eCX, AddressT &eDI, IntT &eAX, MemoryT &memory, Status &status, FlowControllerT &flow_controller) { + if(repetition_over(instruction, eCX)) { + return; + } + + Source destination_segment = instruction.segment_override(); + if(destination_segment == Source::None) destination_segment = Source::DS; + + memory.template access(destination_segment, eDI) = eAX; + + eDI += status.direction() * sizeof(IntT); + + repeat(instruction, eCX, flow_controller); +} } @@ -1664,6 +1696,12 @@ template < case Operation::LODS: Primitive::lods(instruction, eCX(), eSI(), pair_low(), memory, status, flow_controller); break; + case Operation::MOVS: + Primitive::movs(instruction, eCX(), eSI(), eDI(), memory, status, flow_controller); + break; + case Operation::STOS: + Primitive::stos(instruction, eCX(), eDI(), pair_low(), memory, status, flow_controller); + break; } // Write to memory if required to complete this operation. diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index b4086eff4..e63655c66 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -401,13 +401,19 @@ struct FailedExecution { @"C4.json.gz", // LES @"8D.json.gz", // LEA - // TODO: MOVS, SCAS, STOS + // TODO: SCAS, INS, OUTS */ + // MOVS + @"A4.json.gz", @"A5.json.gz", + // CMPS @"A6.json.gz", @"A7.json.gz", // LODS @"AC.json.gz", @"AD.json.gz", + + // STOS + @"AA.json.gz", @"AB.json.gz", /* @"E0.json.gz", // LOOPNE @"E1.json.gz", // LOOPE