// instruction execute
static ALWAYS_INLINE void cpu_z80_adc_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
int data = cpu_z80_read_byte(self, lvalue);
+
int result0 = (data & 0xf) + (rvalue & 0xf) + self->regs.bit.cf;
int result1 = result0 + (data & 0x70) + (rvalue & 0x70);
int result2 = result1 + (data & 0x80) + (rvalue & 0x80);
+
cpu_z80_write_byte(self, lvalue, result2 & 0xff);
self->regs.bit.cf = result2 >> 8;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_adc_word(struct cpu_z80 *self, int lvalue, int rvalue) {
int data = cpu_z80_read_word(self, lvalue);
+
int result0 = (data & 0xfff) + (rvalue & 0xfff) + self->regs.bit.cf;
int result1 = result0 + (data & 0x7000) + (rvalue & 0x7000);
int result2 = result1 + (data & 0x8000) + (rvalue & 0x8000);
+
cpu_z80_write_word(self, lvalue, result2 & 0xffff);
self->regs.bit.cf = result2 >> 16;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_add_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
int data = cpu_z80_read_byte(self, lvalue);
+
int result0 = (data & 0xf) + (rvalue & 0xf);
int result1 = result0 + (data & 0x70) + (rvalue & 0x70);
int result2 = result1 + (data & 0x80) + (rvalue & 0x80);
+
cpu_z80_write_byte(self, lvalue, result2 & 0xff);
self->regs.bit.cf = result2 >> 8;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_add_word(struct cpu_z80 *self, int lvalue, int rvalue) {
int data = cpu_z80_read_word(self, lvalue);
+
int result0 = (data & 0xfff) + (rvalue & 0xfff);
int result1 = result0 + (data & 0xf000) + (rvalue & 0xf000);
+
cpu_z80_write_word(self, lvalue, result1 & 0xffff);
self->regs.bit.cf = result1 >> 16;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_and(struct cpu_z80 *self, int rvalue) {
int result = self->regs.byte.a & rvalue;
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
self->regs.byte.a = result;
self->regs.bit.cf = false;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_bit(struct cpu_z80 *self, int n, int rvalue) {
int result = rvalue & (1 << n);
+
self->regs.bit.nf = false;
self->regs.bit.pvf = result == 0;
self->regs.bit.hf = true;
int result0 = (self->regs.byte.a & 0xf) - (rvalue & 0xf);
int result1 = result0 + (self->regs.byte.a & 0x70) - (rvalue & 0x70);
int result2 = result1 + (self->regs.byte.a & 0x80) - (rvalue & 0x80);
+
self->regs.bit.cf = (result2 >> 8) & 1;
self->regs.bit.nf = true;
self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
static ALWAYS_INLINE void cpu_z80_cpd(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl--);
+
int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
int result2 = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result2;
self->regs.bit.nf = true;
self->regs.bit.pvf = result2 != 0;
static ALWAYS_INLINE void cpu_z80_cpdr(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl--);
+
int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
int result2 = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result2;
self->regs.bit.nf = true;
self->regs.bit.pvf = result2 != 0;
self->regs.bit.hf = (result0 >> 4) & 1;
self->regs.bit.zf = (result1 & 0xff) == 0;
self->regs.bit.sf = (result1 >> 7) & 1;
+
if ((result1 & 0xff) && result2)
self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_cpi(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl++);
+
int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
int result2 = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result2;
self->regs.bit.nf = true;
self->regs.bit.pvf = result2 != 0;
static ALWAYS_INLINE void cpu_z80_cpir(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl++);
+
int result0 = (self->regs.byte.a & 0xf) - (data & 0xf);
int result1 = result0 + (self->regs.byte.a & 0xf0) - (data & 0xf0);
int result2 = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result2;
self->regs.bit.nf = true;
self->regs.bit.pvf = result2 != 0;
self->regs.bit.hf = (result0 >> 4) & 1;
self->regs.bit.zf = (result1 & 0xff) == 0;
self->regs.bit.sf = (result1 >> 7) & 1;
+
if ((result1 & 0xff) && result2)
self->regs.word.pc -= 2;
}
self->regs.bit.hf = true;
}
+// see https://github.com/kosarev/z80.git (MIT licensed)
+// void do_i8080_daa() {
+// fast_u8 a = self().on_get_a();
+// flag_set flags = get_flags();
+// fast_u8 f = flags.get_hf_cf();
+//
+// fast_u8 r = a;
+// fast_u8 t = r + 6;
+// fast_u8 hfv = a ^ t;
+// if((hfv | f) & hf_mask)
+// r = t;
+//
+// fast_u16 t2 = r + 0x60;
+// fast_u16 w = ((t2 >> 8) | f) << 8;
+// if(w & 0x100)
+// r = mask8(t2);
+//
+// self().on_set_a(r);
+// flags.set(hfv & hf_mask, (w | r) & 0x1ff);
+// set_flags(flags); }
+// void do_z80_daa() {
+// fast_u8 a = self().on_get_a();
+// fast_u8 f = self().on_get_f();
+// bool cf = f & cf_mask;
+// bool hf = f & hf_mask;
+// bool nf = f & nf_mask;
+//
+// fast_u8 d = 0x00;
+// if(cf || a >= 0x9a) {
+// d |= 0x60;
+// f |= cf_mask;
+// }
+// if(hf || (a & 0x0f) >= 0x0a) {
+// d |= 0x06;
+// }
+//
+// if(!nf) {
+// f = (f & cf_mask) | ((a & 0x0f) >= 0x0a ? hf_mask : 0);
+// a = add8(a, d);
+// } else {
+// f = (f & cf_mask) | (hf && (a & 0x0f) <= 0x05 ? hf_mask : 0) |
+// nf_mask;
+// a = sub8(a, d);
+// }
+// f |= (a & (sf_mask | xf_mask | yf_mask)) | pf_log(a) | zf_ari(a);
+//
+// self().on_set_a(a);
+// self().on_set_f(f); }
static ALWAYS_INLINE void cpu_z80_daa(struct cpu_z80 *self) {
+ int correction = 0;
+ if (self->regs.bit.hf || (self->regs.byte.a & 0xf) >= 0xa)
+ correction = 6;
+ if (self->regs.bit.cf || self->regs.byte.a >= 0x9a) {
+ correction |= 0x60;
+ self->regs.bit.cf = true;
+ }
+
int result0, result1;
if (self->regs.bit.nf) {
- result0 = (self->regs.byte.a & 0xf);
- if (self->regs.bit.hf || result0 >= 0xa)
- result0 -= 6;
- result1 = result0 + (self->regs.byte.a & 0xf0);
-#if 1 // insane (match z80 for a=9e cf=0 nf=1 hf=0)
- if (self->regs.bit.cf || self->regs.byte.a >= 0x9a)
-#else // sane (but does not match z80)
- if (self->regs.bit.cf || result1 >= 0xa0)
-#endif
- result1 -= 0x60;
+ result0 = (self->regs.byte.a & 0xf) - (correction & 0xf);
+ result1 = result0 + (self->regs.byte.a & 0xf0) - (correction & 0xf0);
}
else {
- result0 = (self->regs.byte.a & 0xf);
- if (self->regs.bit.hf || result0 >= 0xa)
- result0 += 6;
- result1 =
- result0 +
- (self->regs.byte.a & 0xf0);
- if (self->regs.bit.cf || result1 >= 0xa0)
- result1 += 0x60;
+ result0 = (self->regs.byte.a & 0xf) + (correction & 0xf);
+ result1 = result0 + (self->regs.byte.a & 0xf0) + (correction & 0xf0);
}
+
int parity = result1;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
self->regs.byte.a = result1 & 0xff;
- self->regs.bit.cf |= (result1 >> 8) & 1;
+ //self->regs.bit.cf |= (result1 >> 8) & 1;
self->regs.bit.pvf = (parity & 1) == 0;
self->regs.bit.hf = (result0 >> 4) & 1;
self->regs.bit.zf = (result1 & 0xff) == 0;
static ALWAYS_INLINE void cpu_z80_dec_byte(struct cpu_z80 *self, int lvalue) {
int data = cpu_z80_read_byte(self, lvalue);
+
int result0 = (data & 0xf) - 1;
int result1 = result0 + (data & 0x70);
int result2 = result1 + (data & 0x80);
+
cpu_z80_write_byte(self, lvalue, result2 & 0xff);
self->regs.bit.nf = true;
self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
cpu_z80_write_byte(self, lvalue, rvalue);
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_inc_byte(struct cpu_z80 *self, int lvalue) {
int data = cpu_z80_read_byte(self, lvalue);
+
int result0 = (data & 0xf) + 1;
int result1 = result0 + (data & 0x70);
int result2 = result1 + (data & 0x80);
+
cpu_z80_write_byte(self, lvalue, result2 & 0xff);
self->regs.bit.nf = false;
self->regs.bit.pvf = ((result1 >> 7) ^ (result2 >> 8)) & 1;
static ALWAYS_INLINE void cpu_z80_ldd(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl--);
cpu_z80_write_byte(self, self->regs.word.de--, data);
+
int result = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result;
self->regs.bit.nf = false;
self->regs.bit.pvf = result != 0;
static ALWAYS_INLINE void cpu_z80_lddr(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl--);
cpu_z80_write_byte(self, self->regs.word.de--, data);
+
int result = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result;
self->regs.bit.nf = false;
self->regs.bit.pvf = result != 0;
self->regs.bit.hf = false;
+
if (result)
self->regs.word.pc -= 2;
}
static ALWAYS_INLINE void cpu_z80_ldi(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl++);
cpu_z80_write_byte(self, self->regs.word.de++, data);
+
int result = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result;
self->regs.bit.nf = false;
self->regs.bit.pvf = result != 0;
static ALWAYS_INLINE void cpu_z80_ldir(struct cpu_z80 *self) {
int data = cpu_z80_read_byte(self, self->regs.word.hl++);
cpu_z80_write_byte(self, self->regs.word.de++, data);
+
int result = (self->regs.word.bc - 1) & 0xffff;
+
self->regs.word.bc = result;
self->regs.bit.nf = false;
self->regs.bit.pvf = result != 0;
self->regs.bit.hf = false;
+
if (result)
self->regs.word.pc -= 2;
}
int result0 = -(self->regs.byte.a & 0xf);
int result1 = result0 - (self->regs.byte.a & 0x70);
int result2 = result1 - (self->regs.byte.a & 0x80);
+
self->regs.byte.a = result2 & 0xff;
self->regs.bit.cf = (result2 >> 8) & 1;
self->regs.bit.nf = true;
static ALWAYS_INLINE void cpu_z80_or(struct cpu_z80 *self, int rvalue) {
int result = self->regs.byte.a | rvalue;
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
self->regs.byte.a = result;
self->regs.bit.cf = false;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_res(struct cpu_z80 *self, int n, int lvalue0, int lvalue1) {
int result = cpu_z80_read_byte(self, lvalue0) & ~(1 << n);
+
cpu_z80_write_byte(self, lvalue0, result);
- cpu_z80_write_byte(self, lvalue1, result); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, result); // for undocumented DDCB/FDCB
}
static ALWAYS_INLINE void cpu_z80_ret(struct cpu_z80 *self, bool pred) {
static ALWAYS_INLINE void cpu_z80_rl(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = self->regs.bit.cf | (data << 1);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result & 0xff;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result >> 8;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_rla(struct cpu_z80 *self) {
int result = self->regs.bit.cf | (self->regs.byte.a << 1);
+
self->regs.byte.a = result & 0xff;
self->regs.bit.cf = result >> 8;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_rlc(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = (data >> 7) | (data << 1);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result & 0xff;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result >> 8;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_rlca(struct cpu_z80 *self) {
int result = (self->regs.byte.a >> 7) | (self->regs.byte.a << 1);
+
self->regs.byte.a = result & 0xff;
self->regs.bit.cf = result >> 8;
self->regs.bit.nf = false;
int result =
(self->regs.byte.a & 0xf) |
(cpu_z80_read_byte(self, self->regs.word.hl) << 4);
+
cpu_z80_write_byte(self, self->regs.word.hl, result & 0xff);
result = (result >> 8) | (self->regs.byte.a & 0xf0);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
self->regs.byte.a = result;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_rr(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = data | (self->regs.bit.cf << 8);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result >> 1;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result & 1;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 2) == 0;
static ALWAYS_INLINE void cpu_z80_rra(struct cpu_z80 *self) {
int result = self->regs.byte.a | (self->regs.bit.cf << 8);
+
self->regs.byte.a = result >> 1;
self->regs.bit.cf = result & 1;
self->regs.bit.nf = false;
static ALWAYS_INLINE void cpu_z80_rrc(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = data | ((data & 1) << 8);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result >> 1;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result & 1;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 2) == 0;
static ALWAYS_INLINE void cpu_z80_rrca(struct cpu_z80 *self) {
int result = self->regs.byte.a | ((self->regs.byte.a & 1) << 8);
+
self->regs.byte.a = result >> 1;
self->regs.bit.cf = result & 1;
self->regs.bit.nf = false;
int result =
cpu_z80_read_byte(self, self->regs.word.hl) |
((self->regs.byte.a & 0xf) << 8);
+
cpu_z80_write_byte(self, self->regs.word.hl, result >> 4);
result = (result & 0xf) | (self->regs.byte.a & 0xf0);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
self->regs.byte.a = result;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_sbc_byte(struct cpu_z80 *self, int lvalue, int rvalue) {
int data = cpu_z80_read_byte(self, lvalue);
+
int result0 = (data & 0xf) - (rvalue & 0xf) - self->regs.bit.cf;
int result1 = result0 + (data & 0x70) - (rvalue & 0x70);
int result2 = result1 + (data & 0x80) - (rvalue & 0x80);
+
cpu_z80_write_byte(self, lvalue, result2 & 0xff);
self->regs.bit.cf = (result2 >> 8) & 1;
self->regs.bit.nf = true;
static ALWAYS_INLINE void cpu_z80_sbc_word(struct cpu_z80 *self, int lvalue, int rvalue) {
int data = cpu_z80_read_word(self, lvalue);
+
int result0 = (data & 0xfff) - (rvalue & 0xfff) - self->regs.bit.cf;
int result1 = result0 + (data & 0x7000) - (rvalue & 0x7000);
int result2 = result1 + (data & 0x8000) - (rvalue & 0x8000);
+
cpu_z80_write_word(self, lvalue, result2 & 0xffff);
self->regs.bit.cf = (result2 >> 16) & 1;
self->regs.bit.nf = true;
static ALWAYS_INLINE void cpu_z80_set(struct cpu_z80 *self, int n, int lvalue0, int lvalue1) {
int result = cpu_z80_read_byte(self, lvalue0) | (1 << n);
+
cpu_z80_write_byte(self, lvalue0, result);
- cpu_z80_write_byte(self, lvalue1, result); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, result); // for undocumented DDCB/FDCB
}
static ALWAYS_INLINE void cpu_z80_sla(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = data << 1;
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result & 0xff;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result >> 8;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_sll(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = 1 | (data << 1);
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result & 0xff;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result >> 8;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 1) == 0;
static ALWAYS_INLINE void cpu_z80_sra(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = data | ((data << 1) & 0x100); // sign extend
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result >> 1;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result & 1;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 2) == 0;
static ALWAYS_INLINE void cpu_z80_srl(struct cpu_z80 *self, int lvalue0, int lvalue1) {
int data = cpu_z80_read_byte(self, lvalue0);
+
int result = data;
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
data = result >> 1;
cpu_z80_write_byte(self, lvalue0, data);
- cpu_z80_write_byte(self, lvalue1, data); // undocumented DDCB/FDCB versions
+ cpu_z80_write_byte(self, lvalue1, data); // for undocumented DDCB/FDCB
+
self->regs.bit.cf = result & 1;
self->regs.bit.nf = false;
self->regs.bit.pvf = (parity & 2) == 0;
int result0 = (self->regs.byte.a & 0xf) - (rvalue & 0xf);
int result1 = result0 + (self->regs.byte.a & 0x70) - (rvalue & 0x70);
int result2 = result1 + (self->regs.byte.a & 0x80) - (rvalue & 0x80);
+
self->regs.byte.a = result2 & 0xff;
self->regs.bit.cf = (result2 >> 8) & 1;
self->regs.bit.nf = true;
static ALWAYS_INLINE void cpu_z80_xor(struct cpu_z80 *self, int rvalue) {
int result = self->regs.byte.a ^ rvalue;
+
int parity = result;
parity ^= parity >> 4;
parity ^= parity >> 2;
parity ^= parity >> 1;
+
self->regs.byte.a = result;
self->regs.bit.cf = false;
self->regs.bit.nf = false;