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:
parent
41dc728c9b
commit
192513656a
@ -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; \
|
||||
|
@ -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.
|
||||
|
||||
/* b7–b9 */
|
||||
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.
|
||||
|
||||
/* b0–b4 */
|
||||
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 {
|
||||
|
@ -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"];
|
||||
|
Loading…
x
Reference in New Issue
Block a user