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