// // Stack.hpp // Clock Signal // // Created by Thomas Harte on 08/11/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // #ifndef Stack_hpp #define Stack_hpp #include "../AccessType.hpp" namespace InstructionSet::x86::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 void push( IntT &value, ContextT &context ) { context.registers.sp_ -= sizeof(IntT); if constexpr (preauthorised) { context.memory.template preauthorised_write(Source::SS, context.registers.sp_, value); } else { context.memory.template access( Source::SS, context.registers.sp_) = value; } context.memory.template write_back(); } template IntT pop( ContextT &context ) { const auto value = context.memory.template access( Source::SS, context.registers.sp_); context.registers.sp_ += sizeof(IntT); return value; } template void sahf( uint8_t &ah, ContextT &context ) { /* EFLAGS(SF:ZF:0:AF:0:PF:1:CF) ← AH; */ context.flags.template set_from(ah); context.flags.template set_from(!(ah & 0x40)); context.flags.template set_from(ah & 0x10); context.flags.template set_from(!(ah & 0x04)); context.flags.template set_from(ah & 0x01); } template void lahf( uint8_t &ah, ContextT &context ) { /* AH ← EFLAGS(SF:ZF:0:AF:0:PF:1:CF); */ ah = (context.flags.template flag() ? 0x80 : 0x00) | (context.flags.template flag() ? 0x40 : 0x00) | (context.flags.template flag() ? 0x10 : 0x00) | (context.flags.template flag() ? 0x00 : 0x04) | 0x02 | (context.flags.template flag() ? 0x01 : 0x00); } template void popf( ContextT &context ) { context.flags.set(pop(context)); } template void pushf( ContextT &context ) { uint16_t value = context.flags.get(); push(value, context); } } #endif /* Stack_hpp */