1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-29 04:33:04 +00:00

Unify DAA and DAS.

This commit is contained in:
Thomas Harte 2023-11-08 22:26:48 -05:00
parent 6b666bc92a
commit 8d2a2bcf4a
3 changed files with 45 additions and 65 deletions

View File

@ -47,6 +47,39 @@ void aaa(
ax.halves.low &= 0x0f;
}
template <typename ContextT>
void aas(
CPU::RegisterPair16 &ax,
ContextT &context
) {
/*
IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL AL 6;
AH AH 1;
AF 1;
CF 1;
ELSE
CF 0;
AF 0;
FI;
AL AL AND 0FH;
*/
/*
The AF and CF flags are set to 1 if there is a decimal borrow;
otherwise, they are cleared to 0. The OF, SF, ZF, and PF flags are undefined.
*/
if((ax.halves.low & 0x0f) > 9 || context.flags.template flag<Flag::AuxiliaryCarry>()) {
ax.halves.low -= 6;
--ax.halves.high;
context.flags.template set_from<Flag::Carry, Flag::AuxiliaryCarry>(1);
} else {
context.flags.template set_from<Flag::Carry, Flag::AuxiliaryCarry>(0);
}
ax.halves.low &= 0x0f;
}
template <typename ContextT>
void aad(
CPU::RegisterPair16 &ax,
@ -96,40 +129,9 @@ void aam(
context.flags.template set_from<uint8_t, Flag::Zero, Flag::Sign, Flag::ParityOdd>(ax.halves.low);
}
template <typename ContextT>
void aas(
CPU::RegisterPair16 &ax,
ContextT &context
) {
/*
IF ((AL AND 0FH) > 9) OR (AF = 1)
THEN
AL AL 6;
AH AH 1;
AF 1;
CF 1;
ELSE
CF 0;
AF 0;
FI;
AL AL AND 0FH;
*/
/*
The AF and CF flags are set to 1 if there is a decimal borrow;
otherwise, they are cleared to 0. The OF, SF, ZF, and PF flags are undefined.
*/
if((ax.halves.low & 0x0f) > 9 || context.flags.template flag<Flag::AuxiliaryCarry>()) {
ax.halves.low -= 6;
--ax.halves.high;
context.flags.template set_from<Flag::Carry, Flag::AuxiliaryCarry>(1);
} else {
context.flags.template set_from<Flag::Carry, Flag::AuxiliaryCarry>(0);
}
ax.halves.low &= 0x0f;
}
template <typename ContextT>
void daa(
/// If @c add is @c true, performs a DAA; otherwise perfoms a DAS.
template <bool add, typename ContextT>
void daas(
uint8_t &al,
ContextT &context
) {
@ -141,39 +143,18 @@ void daa(
}
if((al & 0x0f) > 0x09 || context.flags.template flag<Flag::AuxiliaryCarry>()) {
al += 0x06;
if constexpr (add) al += 0x06; else al -= 0x06;
context.flags.template set_from<Flag::AuxiliaryCarry>(1);
}
if(top_exceeded_threshold || context.flags.template flag<Flag::Carry>()) {
al += 0x60;
if constexpr (add) al += 0x60; else al -= 0x60;
context.flags.template set_from<Flag::Carry>(1);
}
context.flags.template set_from<uint8_t, Flag::Zero, Flag::Sign, Flag::ParityOdd>(al);
}
template <typename ContextT>
void das(
uint8_t &al,
ContextT &context
) {
const uint8_t old_al = al;
if((al & 0x0f) > 0x09 || context.flags.template flag<Flag::AuxiliaryCarry>()) {
al -= 0x06;
context.flags.template set_from<Flag::AuxiliaryCarry>(1);
}
if(old_al > 0x99 || context.flags.template flag<Flag::Carry>()) {
al -= 0x60;
context.flags.template set_from<Flag::Carry>(1);
}
context.flags.template set_from<uint8_t, Flag::Zero, Flag::Sign, Flag::ParityOdd>(al);
}
}
#endif /* BCD_h */

View File

@ -179,8 +179,8 @@ template <
case Operation::AAD: Primitive::aad(context.registers.axp(), instruction.operand(), context); return;
case Operation::AAM: Primitive::aam(context.registers.axp(), instruction.operand(), context); return;
case Operation::AAS: Primitive::aas(context.registers.axp(), context); return;
case Operation::DAA: Primitive::daa(context.registers.al(), context); return;
case Operation::DAS: Primitive::das(context.registers.al(), context); return;
case Operation::DAA: Primitive::daas<true>(context.registers.al(), context); return;
case Operation::DAS: Primitive::daas<false>(context.registers.al(), context); return;
case Operation::CBW: Primitive::cbw(pair_low()); return;
case Operation::CWD: Primitive::cwd(pair_high(), pair_low()); return;

View File

@ -394,8 +394,6 @@ struct FailedExecution {
NSString *path = [NSString stringWithUTF8String:TestSuiteHome];
NSSet *allowList = [NSSet setWithArray:@[
// Current execution failures:
// @"27.json.gz", // DAA
// @"2F.json.gz", // DAS
// @"D4.json.gz", // AAM
// @"F6.7.json.gz", // IDIV
// @"F7.7.json.gz", // IDIV
@ -459,8 +457,6 @@ struct FailedExecution {
return hexInstruction;
};
EACCES;
const auto decoded = decoder.decode(data.data(), data.size());
const bool sizeMatched = decoded.first == data.size();
if(assert) {
@ -576,6 +572,10 @@ struct FailedExecution {
execution_support.clear();
if([test[@"test_hash"] isEqualTo:@"503062cab62a583b2884554dfd332d01ab4cc7355b49a1b0523fcbf3e22777a4"]) {
printf("");
}
const uint16_t flags_mask = metadata[@"flags-mask"] ? [metadata[@"flags-mask"] intValue] : 0xffff;
NSDictionary *const initial_state = test[@"initial"];
NSDictionary *const final_state = test[@"final"];
@ -748,10 +748,9 @@ struct FailedExecution {
}
// Lock in current failure rate.
XCTAssertLessThanOrEqual(execution_failures.size(), 4138);
XCTAssertLessThanOrEqual(execution_failures.size(), 4009);
// Current accepted failures:
// * 65 instances of DAA with invalid BCD input, and 64 of DAS;
// * 2484 instances of LEA from a register, which officially has undefined results;
// * 42 instances of AAM 00h for which I can't figure out what to do with flags; and
// * 1486 instances of IDIV, most either with a rep or repne that on the 8086 specifically negatives the result,