use crate::registers::ConditionCodes;
pub fn add8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let r16 = a as u16 + b as u16;
let result = r16 as u8;
cc.set_half_carry((a ^ b ^ result) & 0x10 != 0);
cc.set_nz8(result);
cc.set_overflow((a ^ result) & (b ^ result) & 0x80 != 0);
cc.set_carry(r16 > 0xFF);
result
}
pub fn adc8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let c = cc.carry() as u8;
let r16 = a as u16 + b as u16 + c as u16;
let result = r16 as u8;
cc.set_half_carry((a ^ b ^ result) & 0x10 != 0);
cc.set_nz8(result);
cc.set_overflow((a ^ result) & (b ^ result) & 0x80 != 0);
cc.set_carry(r16 > 0xFF);
result
}
pub fn sub8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let r16 = (a as u16).wrapping_sub(b as u16);
let result = r16 as u8;
cc.set_nz8(result);
cc.set_overflow((a ^ b) & (a ^ result) & 0x80 != 0);
cc.set_carry(a < b);
result
}
pub fn sbc8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let c = cc.carry() as u16;
let r16 = (a as u16).wrapping_sub(b as u16).wrapping_sub(c);
let result = r16 as u8;
cc.set_nz8(result);
cc.set_overflow((a ^ b) & (a ^ result) & 0x80 != 0);
cc.set_carry(r16 > 0xFF);
result
}
pub fn neg8(val: u8, cc: &mut ConditionCodes) -> u8 {
let result = (val as i8).wrapping_neg() as u8;
cc.set_nz8(result);
cc.set_overflow(val == 0x80);
cc.set_carry(val != 0x00);
result
}
pub fn com8(val: u8, cc: &mut ConditionCodes) -> u8 {
let result = !val;
cc.set_nz8(result);
cc.set_overflow(false);
cc.set_carry(true);
result
}
pub fn inc8(val: u8, cc: &mut ConditionCodes) -> u8 {
let result = val.wrapping_add(1);
cc.set_nz8(result);
cc.set_overflow(val == 0x7F);
result
}
pub fn dec8(val: u8, cc: &mut ConditionCodes) -> u8 {
let result = val.wrapping_sub(1);
cc.set_nz8(result);
cc.set_overflow(val == 0x80);
result
}
pub fn clr8(cc: &mut ConditionCodes) -> u8 {
cc.set_negative(false);
cc.set_zero(true);
cc.set_overflow(false);
cc.set_carry(false);
0
}
pub fn tst8(val: u8, cc: &mut ConditionCodes) {
cc.set_nz8(val);
cc.set_overflow(false);
}
pub fn and8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let result = a & b;
cc.set_nz8(result);
cc.set_overflow(false);
result
}
pub fn or8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let result = a | b;
cc.set_nz8(result);
cc.set_overflow(false);
result
}
pub fn eor8(a: u8, b: u8, cc: &mut ConditionCodes) -> u8 {
let result = a ^ b;
cc.set_nz8(result);
cc.set_overflow(false);
result
}
pub fn lsr8(val: u8, cc: &mut ConditionCodes) -> u8 {
cc.set_carry(val & 0x01 != 0);
let result = val >> 1;
cc.set_negative(false);
cc.set_zero(result == 0);
result
}
pub fn asr8(val: u8, cc: &mut ConditionCodes) -> u8 {
cc.set_carry(val & 0x01 != 0);
let result = ((val as i8) >> 1) as u8;
cc.set_nz8(result);
result
}
pub fn asl8(val: u8, cc: &mut ConditionCodes) -> u8 {
cc.set_carry(val & 0x80 != 0);
let result = val << 1;
cc.set_nz8(result);
cc.set_overflow((val ^ result) & 0x80 != 0);
result
}
pub fn rol8(val: u8, cc: &mut ConditionCodes) -> u8 {
let old_c = cc.carry() as u8;
cc.set_carry(val & 0x80 != 0);
let result = (val << 1) | old_c;
cc.set_nz8(result);
cc.set_overflow((val ^ result) & 0x80 != 0);
result
}
pub fn ror8(val: u8, cc: &mut ConditionCodes) -> u8 {
let old_c = cc.carry() as u8;
cc.set_carry(val & 0x01 != 0);
let result = (val >> 1) | (old_c << 7);
cc.set_nz8(result);
result
}
pub fn add16(a: u16, b: u16, cc: &mut ConditionCodes) -> u16 {
let r32 = a as u32 + b as u32;
let result = r32 as u16;
cc.set_nz16(result);
cc.set_overflow((a ^ result) & (b ^ result) & 0x8000 != 0);
cc.set_carry(r32 > 0xFFFF);
result
}
pub fn sub16(a: u16, b: u16, cc: &mut ConditionCodes) -> u16 {
let r32 = (a as u32).wrapping_sub(b as u32);
let result = r32 as u16;
cc.set_nz16(result);
cc.set_overflow((a ^ b) & (a ^ result) & 0x8000 != 0);
cc.set_carry(a < b);
result
}
pub fn ld16_flags(val: u16, cc: &mut ConditionCodes) {
cc.set_nz16(val);
cc.set_overflow(false);
}
pub fn ld8_flags(val: u8, cc: &mut ConditionCodes) {
cc.set_nz8(val);
cc.set_overflow(false);
}
pub fn daa(a: u8, cc: &mut ConditionCodes) -> u8 {
let mut correction: u8 = 0;
let mut carry = cc.carry();
if cc.half_carry() || (a & 0x0F) > 9 {
correction |= 0x06;
}
if carry || a > 0x99 {
correction |= 0x60;
carry = true;
}
let result = a.wrapping_add(correction);
cc.set_nz8(result);
cc.set_carry(carry);
result
}
pub fn mul(a: u8, b: u8, cc: &mut ConditionCodes) -> u16 {
let result = (a as u16) * (b as u16);
cc.set_zero(result == 0);
cc.set_carry(result & 0x0080 != 0); result
}
pub fn sex(b: u8, cc: &mut ConditionCodes) -> u16 {
let a = if b & 0x80 != 0 { 0xFF } else { 0x00 };
let d = ((a as u16) << 8) | (b as u16);
cc.set_negative(a == 0xFF);
cc.set_zero(b == 0);
d
}