1use super::opcode::Opcode;
2use super::environment::Environment;
3use super::registers::{Flag, Reg16, Reg8};
4use super::operators::{Operator, operator_cp};
5
6pub fn build_operator_a_r(r: Reg8, (op, name): (Operator, &str)) -> Opcode {
7 if r != Reg8::_HL && r != Reg8::H && r != Reg8::L {
8 Opcode::new(
10 format!("{name} A, {r}"),
11 move |env: &mut Environment| {
12 let a = env.state.reg.a();
13 let b = env.state.reg.get8(r);
14 let v = op(env, a, b);
15 env.state.reg.set_a(v);
16 }
17 )
18 } else {
19 Opcode::new(
20 format!("{name} A, {r}"),
21 move |env: &mut Environment| {
22 let a = env.state.reg.a();
23 let b = env.reg8_ext(r);
24 let v = op(env, a, b);
25
26 env.state.reg.set_a(v);
27 }
28 )
29 }
30}
31
32pub fn build_operator_a_n((op, name): (Operator, &str)) -> Opcode {
33 Opcode::new(
34 format!("{name} A, n"),
35 move |env: &mut Environment| {
36 let a = env.state.reg.a();
37 let b = env.advance_pc();
38 let v = op(env, a, b);
39
40 env.state.reg.set_a(v);
41 }
42 )
43}
44
45pub fn build_cp_block((inc, repeat, postfix) : (bool, bool, &'static str)) -> Opcode {
46 Opcode::new(
47 format!("CP{postfix}"),
48 move |env: &mut Environment| {
49 let a = env.state.reg.a();
50 let b = env.reg8_ext(Reg8::_HL);
51 let c_bak = env.state.reg.get_flag(Flag::C);
52 operator_cp(env, a, b);
53 let bc = env.state.reg.inc_dec16(Reg16::BC, false );
54 env.state.reg.inc_dec16(Reg16::HL, inc);
55
56 let mut n = a.wrapping_sub(b);
58 if env.state.reg.get_flag(Flag::H) {
59 n = n.wrapping_sub(1);
60 }
61 env.state.reg.update_undocumented_flags_block(n);
62 env.state.reg.set_flag(Flag::N);
63 env.state.reg.put_flag(Flag::P, bc != 0);
64 env.state.reg.put_flag(Flag::C, c_bak); if repeat && bc != 0 && a != b {
68 env.set_branch_taken();
70 let pc = env.state.reg.pc().wrapping_sub(2);
71 env.state.reg.set_pc(pc);
72 }
73 }
74 )
75}