// // Logical.hpp // Clock Signal // // Created by Thomas Harte on 08/11/2023. // Copyright © 2023 Thomas Harte. All rights reserved. // #ifndef Logical_h #define Logical_h #include "../AccessType.hpp" namespace InstructionSet::x86::Primitive { template void and_( modify_t destination, read_t source, ContextT &context ) { /* DEST ← DEST AND SRC; */ /* The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result. The state of the AF flag is undefined. */ destination &= source; context.flags.template set_from(0); context.flags.template set_from(destination); } template void or_( modify_t destination, read_t source, ContextT &context ) { /* DEST ← DEST OR SRC; */ /* The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result. The state of the AF flag is undefined. */ destination |= source; context.flags.template set_from(0); context.flags.template set_from(destination); } template void xor_( modify_t destination, read_t source, ContextT &context ) { /* DEST ← DEST XOR SRC; */ /* The OF and CF flags are cleared; the SF, ZF, and PF flags are set according to the result. The state of the AF flag is undefined. */ destination ^= source; context.flags.template set_from(0); context.flags.template set_from(destination); } template void not_( modify_t destination ) { /* DEST ← NOT DEST; */ /* Flags affected: none. */ destination = ~destination; } template void cbw( IntT &ax ) { constexpr IntT test_bit = 1 << (sizeof(IntT) * 4 - 1); constexpr IntT low_half = (1 << (sizeof(IntT) * 4)) - 1; if(ax & test_bit) { ax |= ~low_half; } else { ax &= low_half; } } template void cwd( IntT &dx, IntT ax ) { dx = ax & Numeric::top_bit() ? IntT(~0) : IntT(0); } // TODO: changes to the interrupt flag do quite a lot more in protected mode. template void clc(ContextT &context) { context.flags.template set_from(0); } template void cld(ContextT &context) { context.flags.template set_from(0); } template void cli(ContextT &context) { context.flags.template set_from(0); } template void stc(ContextT &context) { context.flags.template set_from(1); } template void std(ContextT &context) { context.flags.template set_from(1); } template void sti(ContextT &context) { context.flags.template set_from(1); } template void cmc(ContextT &context) { context.flags.template set_from(!context.flags.template flag()); } template void salc( uint8_t &al, ContextT &context ) { al = context.flags.template flag() ? 0xff : 0x00; } template void setmo( write_t destination, ContextT &context ) { const auto result = destination = ~0; context.flags.template set_from(0); context.flags.template set_from(result); } } #endif /* Logical_h */