1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-09 00:37:27 +00:00

After much guesswork, fix SBCD and thereby pass flamewing tests.

This commit is contained in:
Thomas Harte 2022-05-12 11:39:01 -04:00
parent 41dc728c9b
commit 192513656a
3 changed files with 25 additions and 17 deletions

View File

@ -790,13 +790,21 @@ template <
#define sbcd(d) \
/* Perform the BCD arithmetic by evaluating the two nibbles separately. */ \
const int unadjusted_result = destination - source - (status.extend_flag ? 1 : 0); \
int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag ? 1 : 0); \
if(result & 0xf0) result -= 0x06; \
result += (destination & 0xf0) - (source & 0xf0); \
status.extend_flag = status.carry_flag = decltype(status.carry_flag)(unadjusted_result & 0x300); \
if(unadjusted_result & 0x100) result -= 0x60; \
\
/* Set all flags essentially as if this were normal subtraction. */ \
int top = (destination & 0xf0) - (source & 0xf0); \
if(unadjusted_result & 0x100) top -= 0x60; \
\
int result = (destination & 0xf) - (source & 0xf) - (status.extend_flag ? 1 : 0); \
if(result & 0xf0) { \
result -= 0x06; \
status.extend_flag = status.carry_flag = Status::FlagT((unadjusted_result - 0x6) & 0x300); \
} else { \
status.extend_flag = status.carry_flag = Status::FlagT(unadjusted_result & 0x300); \
} \
\
result += top; \
\
/* Set all remaining flags essentially as if this were normal subtraction. */ \
status.zero_result |= result & 0xff; \
status.negative_flag = result & 0x80; \
status.overflow_flag = unadjusted_result & ~result & 0x80; \

View File

@ -15,6 +15,8 @@ namespace InstructionSet {
namespace M68k {
struct Status {
using FlagT = uint_fast32_t;
enum ConditionCode: uint16_t {
Carry = (1 << 0),
Overflow = (1 << 1),
@ -29,20 +31,20 @@ struct Status {
};
/* b15 */
uint_fast32_t trace_flag = 0; // The trace flag is set if this value is non-zero.
FlagT trace_flag = 0; // The trace flag is set if this value is non-zero.
/* b13 */
int is_supervisor = 0; // 1 => processor is in supervisor mode; 0 => it isn't.
int is_supervisor = 0; // 1 => processor is in supervisor mode; 0 => it isn't.
/* b7b9 */
int interrupt_level = 0; // The direct integer value of the current interrupt level.
int interrupt_level = 0; // The direct integer value of the current interrupt level.
/* b0b4 */
uint_fast32_t zero_result = 0; // The zero flag is set if this value is zero.
uint_fast32_t carry_flag = 0; // The carry flag is set if this value is non-zero.
uint_fast32_t extend_flag = 0; // The extend flag is set if this value is non-zero.
uint_fast32_t overflow_flag = 0; // The overflow flag is set if this value is non-zero.
uint_fast32_t negative_flag = 0; // The negative flag is set if this value is non-zero.
FlagT zero_result = 0; // The zero flag is set if this value is zero.
FlagT carry_flag = 0; // The carry flag is set if this value is non-zero.
FlagT extend_flag = 0; // The extend flag is set if this value is non-zero.
FlagT overflow_flag = 0; // The overflow flag is set if this value is non-zero.
FlagT negative_flag = 0; // The negative flag is set if this value is non-zero.
/// Gets the current condition codes.
constexpr uint16_t ccr() const {

View File

@ -86,8 +86,6 @@ using namespace InstructionSet::M68k;
}
}
return;
// Test NBCD.
for(int source = 0; source < 256; source++) {
for(int flags = 0; flags < 4; flags++) {
@ -96,7 +94,7 @@ using namespace InstructionSet::M68k;
CPU::SlicedInt32 s, d;
s.l = source;
perform<Model::M68000, NullFlowController, Operation::SBCD>(
perform<Model::M68000, NullFlowController, Operation::NBCD>(
Preinstruction(), s, d, status, flow_controller);
[self validate:bytes source:source dest:0 flags:flags result:s.l status:status operation:@"NBCD"];