From 9538491ee908bae75d288e9c73f4e97a382d2979 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 31 Oct 2023 21:55:22 -0400 Subject: [PATCH] Fix pushes and pops. --- .../Implementation/PerformImplementation.hpp | 34 ++++++++++--------- OSBindings/Mac/Clock SignalTests/8088Tests.mm | 4 ++- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index 1e77aba08..3e24922b0 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -193,18 +193,18 @@ namespace Primitive { // The below takes a reference in order properly to handle PUSH SP, which should place the value of SP after the // push onto the stack. -template +template void push(IntT &value, MemoryT &memory, RegistersT ®isters) { registers.sp_ -= sizeof(IntT); - memory.template access( + memory.template access( InstructionSet::x86::Source::SS, registers.sp_) = value; memory.template write_back(); } -template +template IntT pop(MemoryT &memory, RegistersT ®isters) { - const auto value = memory.template access( + const auto value = memory.template access( InstructionSet::x86::Source::SS, registers.sp_); registers.sp_ += sizeof(IntT); @@ -903,23 +903,25 @@ void jump_far(InstructionT &instruction, template void iret(RegistersT ®isters, FlowControllerT &flow_controller, MemoryT &memory, Status &status) { // TODO: all modes other than 16-bit real mode. - registers.ip() = pop(memory, registers); - registers.cs() = pop(memory, registers); - status.set(pop(memory, registers)); + memory.preauthorise_stack(sizeof(uint16_t) * 3); + registers.ip() = pop(memory, registers); + registers.cs() = pop(memory, registers); + status.set(pop(memory, registers)); flow_controller.did_iret(); } template void ret_near(InstructionT instruction, RegistersT ®isters, FlowControllerT &flow_controller, MemoryT &memory) { - registers.ip() = pop(memory, registers); + registers.ip() = pop(memory, registers); registers.sp() += instruction.operand(); flow_controller.did_near_ret(); } template void ret_far(InstructionT instruction, RegistersT ®isters, FlowControllerT &flow_controller, MemoryT &memory) { - registers.ip() = pop(memory, registers); - registers.cs() = pop(memory, registers); + memory.preauthorise_stack(sizeof(uint16_t) * 2); + registers.ip() = pop(memory, registers); + registers.cs() = pop(memory, registers); registers.sp() += instruction.operand(); flow_controller.did_far_ret(); } @@ -1368,13 +1370,13 @@ inline void shr(IntT &destination, uint8_t count, Status &status) { template void popf(MemoryT &memory, RegistersT ®isters, Status &status) { - status.set(pop(memory, registers)); + status.set(pop(memory, registers)); } template void pushf(MemoryT &memory, RegistersT ®isters, Status &status) { uint16_t value = status.get(); - push(value, memory, registers); + push(value, memory, registers); } template @@ -1785,10 +1787,10 @@ template < case Operation::XLAT: Primitive::xlat(instruction, memory, registers); return; - case Operation::POP: destination_w() = Primitive::pop(memory, registers); break; - case Operation::PUSH: Primitive::push(source_r(), memory, registers); break; - case Operation::POPF: Primitive::popf(memory, registers, status); break; - case Operation::PUSHF: Primitive::pushf(memory, registers, status); break; + case Operation::POP: destination_w() = Primitive::pop(memory, registers); break; + case Operation::PUSH: Primitive::push(source_r(), memory, registers); break; + case Operation::POPF: Primitive::popf(memory, registers, status); break; + case Operation::PUSHF: Primitive::pushf(memory, registers, status); break; case Operation::CMPS: Primitive::cmps(instruction, eCX(), eSI(), eDI(), memory, status, flow_controller); diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index 440f7c29d..7abe43f10 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -25,7 +25,7 @@ namespace { // The tests themselves are not duplicated in this repository; // provide their real path here. -constexpr char TestSuiteHome[] = "/Users/thomasharte/Projects/ProcessorTests/8088/v1"; +constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1"; using Status = InstructionSet::x86::Status; struct Registers { @@ -133,6 +133,8 @@ struct Memory { return physical_address << 4; } + void preauthorise_stack(uint32_t) {} + // Entry point used by the flow controller so that it can mark up locations at which the flags were written, // so that defined-flag-only masks can be applied while verifying RAM contents. template IntT &access(InstructionSet::x86::Source segment, uint16_t address, Tag tag) {