mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-22 12:33:29 +00:00
Implement RCL.
This commit is contained in:
parent
bf832768e6
commit
1a0f848b21
@ -923,6 +923,54 @@ void setmoc(IntT &destination, uint8_t cl, Status &status) {
|
||||
if(cl) setmo(destination, status);
|
||||
}
|
||||
|
||||
template <Model model, typename IntT>
|
||||
inline void rcl(IntT &destination, uint8_t count, Status &status) {
|
||||
/*
|
||||
(* RCL and RCR instructions *)
|
||||
SIZE ← OperandSize
|
||||
CASE (determine count) OF
|
||||
SIZE = 8: tempCOUNT ← (COUNT AND 1FH) MOD 9;
|
||||
SIZE = 16: tempCOUNT ← (COUNT AND 1FH) MOD 17;
|
||||
SIZE = 32: tempCOUNT ← COUNT AND 1FH;
|
||||
ESAC;
|
||||
*/
|
||||
if constexpr (model != Model::i8086) {
|
||||
count &= 0x1f;
|
||||
}
|
||||
auto temp_count = count % (Numeric::bit_size<IntT>() + 1);
|
||||
|
||||
/*
|
||||
(* RCL instruction operation *)
|
||||
WHILE (tempCOUNT ≠ 0)
|
||||
DO
|
||||
tempCF ← MSB(DEST);
|
||||
DEST ← (DEST * 2) + CF;
|
||||
CF ← tempCF;
|
||||
tempCOUNT ← tempCOUNT – 1;
|
||||
OD;
|
||||
ELIHW;
|
||||
IF COUNT = 1
|
||||
THEN OF ← MSB(DEST) XOR CF;
|
||||
ELSE OF is undefined;
|
||||
FI;
|
||||
*/
|
||||
/*
|
||||
The CF flag contains the value of the bit shifted into it.
|
||||
The OF flag is affected only for single- bit rotates (see “Description” above);
|
||||
it is undefined for multi-bit rotates. The SF, ZF, AF, and PF flags are not affected.
|
||||
*/
|
||||
auto carry = status.carry_bit<IntT>();
|
||||
while(temp_count--) {
|
||||
const IntT temp_carry = (destination >> (Numeric::bit_size<IntT>() - 1)) & 1;
|
||||
destination = (destination << 1) | carry;
|
||||
carry = temp_carry;
|
||||
}
|
||||
status.set_from<Flag::Carry>(carry);
|
||||
status.set_from<Flag::Overflow>(
|
||||
((destination >> (Numeric::bit_size<IntT>() - 1)) & 1) ^ carry
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <
|
||||
@ -976,6 +1024,14 @@ template <
|
||||
flow_controller);
|
||||
};
|
||||
|
||||
const auto shift_count = [&]() -> uint8_t {
|
||||
switch(instruction.source().template source<false>()) {
|
||||
case Source::None: return 1;
|
||||
case Source::Immediate: return uint8_t(instruction.operand());
|
||||
default: return registers.cl();
|
||||
}
|
||||
};
|
||||
|
||||
// Some instructions use a pair of registers as an extended accumulator — DX:AX or EDX:EAX.
|
||||
// The two following return the high and low parts of that pair; they also work in Byte mode to return AH:AL,
|
||||
// i.e. AX split into high and low parts.
|
||||
@ -1075,6 +1131,8 @@ template <
|
||||
case Operation::JLE: jcc(status.condition<Condition::LessOrEqual>()); return;
|
||||
case Operation::JNLE: jcc(!status.condition<Condition::LessOrEqual>()); return;
|
||||
|
||||
case Operation::RCL: Primitive::rcl<model>(destination(), shift_count(), status); break;
|
||||
|
||||
case Operation::CLC: Primitive::clc(status); return;
|
||||
case Operation::CLD: Primitive::cld(status); return;
|
||||
case Operation::CLI: Primitive::cli(status); return;
|
||||
@ -1126,6 +1184,9 @@ template <
|
||||
// Dispatch to a function just like this that is specialised on data size.
|
||||
// Fetching will occur in that specialised function, per the overlapping
|
||||
// meaning of register names.
|
||||
|
||||
// TODO: incorporate and propagate address size.
|
||||
|
||||
switch(instruction.operation_size()) {
|
||||
case DataSize::Byte:
|
||||
perform<model, DataSize::Byte>(instruction, status, flow_controller, registers, memory, io);
|
||||
|
@ -415,10 +415,16 @@ struct FailedExecution {
|
||||
|
||||
// NOP
|
||||
@"90.json.gz",
|
||||
*/
|
||||
|
||||
// TODO: POP, POPF, PUSH, PUSHF
|
||||
// TODO: RCL, RCR, ROL, ROR, SAL, SAR, SHR
|
||||
// TODO: RCR, ROL, ROR, SAL, SAR, SHR
|
||||
|
||||
// RCL
|
||||
@"D0.2.json.gz", @"D2.2.json.gz",
|
||||
@"D1.2.json.gz", @"D3.2.json.gz",
|
||||
|
||||
/*
|
||||
@"F8.json.gz", // CLC
|
||||
@"FC.json.gz", // CLD
|
||||
@"FA.json.gz", // CLI
|
||||
@ -441,11 +447,9 @@ struct FailedExecution {
|
||||
@"86.json.gz", @"87.json.gz",
|
||||
@"91.json.gz", @"92.json.gz", @"93.json.gz", @"94.json.gz",
|
||||
@"95.json.gz", @"96.json.gz", @"97.json.gz",
|
||||
*/
|
||||
@"D7.json.gz", // XLAT
|
||||
|
||||
/*
|
||||
@"D6.json.gz", // SALC
|
||||
@"D7.json.gz", // XLAT
|
||||
@"D6.json.gz", // SALC
|
||||
@"D0.6.json.gz", @"D1.6.json.gz", // SETMO
|
||||
@"D2.6.json.gz", @"D3.6.json.gz", // SETMOC
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user