mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +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);
|
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 <
|
template <
|
||||||
@ -976,6 +1024,14 @@ template <
|
|||||||
flow_controller);
|
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.
|
// 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,
|
// 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.
|
// 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::JLE: jcc(status.condition<Condition::LessOrEqual>()); return;
|
||||||
case Operation::JNLE: 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::CLC: Primitive::clc(status); return;
|
||||||
case Operation::CLD: Primitive::cld(status); return;
|
case Operation::CLD: Primitive::cld(status); return;
|
||||||
case Operation::CLI: Primitive::cli(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.
|
// Dispatch to a function just like this that is specialised on data size.
|
||||||
// Fetching will occur in that specialised function, per the overlapping
|
// Fetching will occur in that specialised function, per the overlapping
|
||||||
// meaning of register names.
|
// meaning of register names.
|
||||||
|
|
||||||
|
// TODO: incorporate and propagate address size.
|
||||||
|
|
||||||
switch(instruction.operation_size()) {
|
switch(instruction.operation_size()) {
|
||||||
case DataSize::Byte:
|
case DataSize::Byte:
|
||||||
perform<model, DataSize::Byte>(instruction, status, flow_controller, registers, memory, io);
|
perform<model, DataSize::Byte>(instruction, status, flow_controller, registers, memory, io);
|
||||||
|
@ -415,10 +415,16 @@ struct FailedExecution {
|
|||||||
|
|
||||||
// NOP
|
// NOP
|
||||||
@"90.json.gz",
|
@"90.json.gz",
|
||||||
|
*/
|
||||||
|
|
||||||
// TODO: POP, POPF, PUSH, PUSHF
|
// 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
|
@"F8.json.gz", // CLC
|
||||||
@"FC.json.gz", // CLD
|
@"FC.json.gz", // CLD
|
||||||
@"FA.json.gz", // CLI
|
@"FA.json.gz", // CLI
|
||||||
@ -441,11 +447,9 @@ struct FailedExecution {
|
|||||||
@"86.json.gz", @"87.json.gz",
|
@"86.json.gz", @"87.json.gz",
|
||||||
@"91.json.gz", @"92.json.gz", @"93.json.gz", @"94.json.gz",
|
@"91.json.gz", @"92.json.gz", @"93.json.gz", @"94.json.gz",
|
||||||
@"95.json.gz", @"96.json.gz", @"97.json.gz",
|
@"95.json.gz", @"96.json.gz", @"97.json.gz",
|
||||||
*/
|
|
||||||
@"D7.json.gz", // XLAT
|
|
||||||
|
|
||||||
/*
|
@"D7.json.gz", // XLAT
|
||||||
@"D6.json.gz", // SALC
|
@"D6.json.gz", // SALC
|
||||||
@"D0.6.json.gz", @"D1.6.json.gz", // SETMO
|
@"D0.6.json.gz", @"D1.6.json.gz", // SETMO
|
||||||
@"D2.6.json.gz", @"D3.6.json.gz", // SETMOC
|
@"D2.6.json.gz", @"D3.6.json.gz", // SETMOC
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user