Okay, this code will pass for all possible combinations of:
lda #$xx; clc; sed; adc #$yy
void op_adc_b(uint8_t r0, uint8_t r1, uint8_t &a, uint8_t &p) {
int r;
if(decimal) {
uint8_t n0 = (r0 ) & 15;
uint8_t n1 = (r0 >> 4) & 15;
n0 += (r1 & 15) + carry;
if(n0 > 9) {
n0 = (n0 - 10) & 15;
n1++;
}
n1 += ((r1 >> 4) & 15);
if(n1 > 9) {
n1 = (n1 - 10) & 15;
carry = 1;
} else {
carry = 0;
}
r = (n1 << 4) | n0;
uint8_t L = r1 & 0x0f;
uint8_t H = r1 & 0xf0;
if((r1 & 0x80) == 0) {
overflow = (r0 >= (0x7a - r1)) && (r0 <= 0x7f);
if(L >= 0x0b && H <= 0x60) {
uint8_t M = 0x6f - (H & 0x7f);
if(r0 >= (M - (L - 0xb)) && r0 <= M) overflow = false;
}
} else {
overflow = (r0 >= 0x80) && (r0 <= (0xf9 - (r1 - 0x80)));
if(L >= 0x0b && H <= 0xe0) {
uint8_t M = 0xef - (H & 0x7f);
if(r0 >= (M - (L - 0xb)) && r0 <= M) overflow = true;
}
}
} else {
r = r0 + r1 + carry;
carry = r > 0xff;
overflow = ~(r0 ^ r1) & (r0 ^ r) & 0x80;
}
negative = r & 0x80;
zero = (uint8_t)r == 0;
a = r;
p = 0x24 | (negative << 7) | (overflow << 6) | (decimal << 3) | (zero << 1) | (carry << 0);
}
Don't ask me why or how ...
Core part:
uint8_t L = r1 & 0x0f;
uint8_t H = r1 & 0xf0;
if((r1 & 0x80) == 0) {
overflow = (r0 >= (0x7a - r1)) && (r0 <= 0x7f);
if(L >= 0x0b && H <= 0x60) {
uint8_t M = 0x6f - (H & 0x7f);
if(r0 >= (M - (L - 0xb)) && r0 <= M) overflow = false;
}
} else {
overflow = (r0 >= 0x80) && (r0 <= (0xf9 - (r1 - 0x80)));
if(L >= 0x0b && H <= 0xe0) {
uint8_t M = 0xef - (H & 0x7f);
if(r0 >= (M - (L - 0xb)) && r0 <= M) overflow = true;
}
}
---
This code fails the test: if(((~(i^j))&0x8)&((i^k)&0x8))