1use super::environment::Environment;
2use super::registers::Flag;
3
4pub type Operator = fn(&mut Environment, u8, u8) -> u8;
5
6pub fn operator_add(env: &mut Environment, a: u8, b: u8) -> u8 {
7 env.state.reg.clear_flag(Flag::C);
8 operator_adc(env, a, b)
9}
10
11pub fn operator_adc(env: &mut Environment, a: u8, b: u8) -> u8 {
12 let aa = a as u16;
13 let bb = b as u16;
14 let mut vv = aa + bb;
15 if env.state.reg.get_flag(Flag::C) {
16 vv += 1;
17 }
18 env.state.reg.update_arithmetic_flags(aa, bb, vv, false, true);
19 vv as u8
20}
21
22pub fn operator_add16(env: &mut Environment, aa: u16, bb: u16) -> u16 {
23 let aaaa = aa as u32;
24 let bbbb = bb as u32;
25 let vvvv = aaaa + bbbb;
26
27 env.state.reg.update_add16_flags(aaaa, bbbb, vvvv);
28 vvvv as u16
29}
30
31pub fn operator_adc16(env: &mut Environment, aa: u16, bb: u16) -> u16 {
32 let aaaa = aa as u32;
33 let bbbb = bb as u32;
34 let mut vvvv = aaaa.wrapping_add(bbbb);
35 if env.state.reg.get_flag(Flag::C) {
36 vvvv = vvvv.wrapping_add(1);
37 }
38 let vv = vvvv as u16;
39
40 env.state.reg.update_arithmetic_flags_16(aaaa, bbbb, vvvv, false);
42 env.state.reg.put_flag(Flag::Z, vv == 0);
43 vv
44}
45
46pub fn operator_sbc16(env: &mut Environment, aa: u16, bb: u16) -> u16 {
47 let aaaa = aa as u32;
48 let bbbb = bb as u32;
49 let mut vvvv = aaaa.wrapping_sub(bbbb);
50 if env.state.reg.get_flag(Flag::C) {
51 vvvv = vvvv.wrapping_sub(1);
52 }
53 let vv = vvvv as u16;
54
55 env.state.reg.update_arithmetic_flags_16(aaaa, bbbb, vvvv, true);
57 env.state.reg.put_flag(Flag::Z, vv == 0);
58 vv
59}
60
61pub fn operator_inc(env: &mut Environment, a: u8) -> u8 {
62 let aa = a as u16;
63 let vv = aa + 1;
64 env.state.reg.update_arithmetic_flags(aa, 0, vv, false, false);
65 vv as u8
66}
67
68pub fn operator_sub(env: &mut Environment, a: u8, b: u8) -> u8 {
69 env.state.reg.clear_flag(Flag::C);
70 operator_sbc(env, a, b)
71}
72
73pub fn operator_sbc(env: &mut Environment, a: u8, b: u8) -> u8 {
74 let aa = a as u16;
75 let bb = b as u16;
76 let mut vv = aa.wrapping_sub(bb);
77 if env.state.reg.get_flag(Flag::C) {
78 vv = vv.wrapping_sub(1);
79 }
80 env.state.reg.update_arithmetic_flags(aa, bb, vv, true, true);
81 vv as u8
82}
83
84pub fn operator_dec(env: &mut Environment, a: u8) -> u8 {
85 let aa = a as u16;
86 let vv = aa.wrapping_sub(1);
87 env.state.reg.update_arithmetic_flags(aa, 0, vv, true, false);
88 vv as u8
89}
90
91pub fn operator_and(env: &mut Environment, a: u8, b: u8) -> u8 {
92 let v = a & b;
93 env.state.reg.update_logic_flags(a, b, v, true);
94 v
95}
96
97pub fn operator_xor(env: &mut Environment, a: u8, b: u8) -> u8 {
98 let v = a ^ b;
99 env.state.reg.update_logic_flags(a, b, v, false);
100 v
101}
102
103pub fn operator_or(env: &mut Environment, a: u8, b: u8) -> u8 {
104 let v = a | b;
105 env.state.reg.update_logic_flags(a, b, v, false);
106 v
107}
108
109pub fn operator_cp(env: &mut Environment, a: u8, b: u8) -> u8 {
110 env.state.reg.clear_flag(Flag::C);
111 operator_sub(env, a, b);
112
113 env.state.reg.update_undocumented_flags(b);
115 a }