gameboy_rom/opcodes.rs
1//! Types related to the opcodes of the Gameboy parser.
2
3/// An 8 bit register.
4///
5/// Includes the `DerefHL` variant which represents a memory access at the value
6/// contained in the `HL` 16 bit register.
7#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
8pub enum Register8 {
9 A,
10 B,
11 C,
12 D,
13 E,
14 H,
15 L,
16 DerefHL,
17}
18
19/// A 16 bit register.
20///
21/// Does not include `PC`, the program counter, used to indicate which
22/// instruction is being executed next.
23#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
24pub enum Register16 {
25 /// 16 bit register that's made up of 2 8 bit registers, `B` and `C`.
26 BC,
27 /// 16 bit register that's made up of 2 8 bit registers, `D` and `E`.
28 DE,
29 /// 16 bit register that's made up of 2 8 bit registers, `H` and `L`.
30 HL,
31 /// 16 bit register that's made up of 2 8 bit registers, `A` and `F`.
32 AF,
33 /// The stack pointer.
34 SP,
35}
36
37/// Flags relevant to the operation of the instruction.
38///
39/// This flag is used to specify which flag the Opcode cares about, it is not
40/// used to indicate which flags an instruction may set.
41///
42/// For example, `Opcode::Jp(Some(Flag::NZ), 0x1234)` says that the instruction
43/// is a `Jp` (jump) instruction that will jump to location 0x1234, if the `NZ`
44/// (not zero) flag is set.
45#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
46pub enum Flag {
47 /// The Carry flag.
48 C,
49 /// The Zero Flag.
50 Z,
51 /// The inverse of the Carry flag.
52 NC,
53 /// The inverse of the Zero flag.
54 NZ,
55}
56
57/// The instructions of the Gameboy.
58///
59/// The naming tends to be of the form: `ActionDestSrc` when there is ambiguity.
60///
61/// For example, `Opcode::StoreImm16AddrSp` means that the `SP` register should
62/// be stored at the address specified by the immediate 16 bit value.
63///
64/// These docs don't intend to include complete explanations of the instructions,
65/// though the comments below may provide a basic overview.
66#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
67pub enum Opcode {
68 /// No operation.
69 Nop,
70 /// The Gameboy enters a very low-power STOP state, graphics will not continue to draw.
71 Stop,
72 /// The Gameboy enters a low-power HALT state.
73 Halt,
74 /// Store an immediate value into a 16 bit register.
75 StoreImm16(Register16, u16),
76 /// Store an immediate value into an 8 bit register.
77 StoreImm8(Register8, u8),
78 /// Store A at (HL) and increment or decrement HL; true means inc
79 StoreAToHlAddr(bool),
80 /// Load A from (HL) and increment or decrement HL; true means inc
81 LoadAFromHlAddr(bool),
82 /// Store A to the value pointed at by register 16 (must be BC or DE)
83 StoreATo16(Register16),
84 /// Loads A from value pointed at by register 16 (must be BC or DE)
85 LoadAFromReg16Addr(Register16),
86 Mov8(Register8, Register8),
87 /// Relative jump based on flag to offset
88 Jr(Option<Flag>, u8),
89 /// Jump based on flag to offset
90 Jp(Option<Flag>, u16),
91 /// Increment an 8 bit regsiter.
92 Inc8(Register8),
93 /// Decrement an 8 bit regsiter.
94 Dec8(Register8),
95 /// Increment a 16 bit regsiter.
96 Inc16(Register16),
97 /// Decrement a 16 bit regsiter.
98 Dec16(Register16),
99 /// Push the value in the given register onto the stack.
100 Push(Register16),
101 /// Pop a value off the stack and load it into the given register.
102 Pop(Register16),
103 /// Add the given regsiter to the A.
104 Add(Register8),
105 /// Add the given regsiter to the A with carry.
106 Adc(Register8),
107 /// Subtract the given regsiter from the A.
108 Sub(Register8),
109 /// Subtract the given regsiter from the A with carry.
110 Sbc(Register8),
111 /// Bitwise AND the given register with the A.
112 And(Register8),
113 /// Bitwise XOR the given register with the A.
114 Xor(Register8),
115 /// Bitwise OR the given register with the A.
116 Or(Register8),
117 /// Compare the value of the given register with the A and set flags.
118 Cp(Register8),
119 /// Add an immediate value to the A.
120 Add8(u8),
121 /// Add an immediate value to the A with carry.
122 Adc8(u8),
123 /// Subtract an immediate value from the A.
124 Sub8(u8),
125 /// Subtract an immediate value from the A with carry.
126 Sbc8(u8),
127 /// Bitwise AND an immediate value with the A.
128 And8(u8),
129 /// Bitwise XOR an immediate value with the A.
130 Xor8(u8),
131 /// Bitwise OR an immediate value with the A.
132 Or8(u8),
133 /// Compare the immediate value with the A and set flags.
134 Cp8(u8),
135 /// Add the immediate value to the Program Counter and load it into SP.
136 /// TODO: check this explanation
137 AddSp8(u8),
138 /// Converts the value in A to its BCD form.
139 /// TODO: double check this
140 Daa,
141 /// TODO: document this
142 Scf,
143 /// Bitwise negate the value in the A.
144 Cpl,
145 /// TODO: document this (inverse of SCF?)
146 Ccf,
147 /// Rotate A left.
148 Rlca,
149 /// Rotate A left through carry.
150 Rla,
151 /// Rotate A right.
152 Rrca,
153 /// Rotate A right through carry.
154 Rra,
155 /// Stores SP at pointer given by immediate 16.
156 StoreImm16AddrSp(u16),
157 /// Adds a value to HL.
158 AddHl(Register16),
159 /// Conditionally adjusts the program counter and updates the stack pointer.
160 Ret(Option<Flag>),
161 /// Non-conditional `Ret` that also enables interrupts.
162 Reti,
163 /// Disable interrupts.
164 Di,
165 /// Enable interrupts.
166 Ei,
167 /// Conditionally update push the program counter onto the stack and adjusts
168 /// the program counter.
169 Call(Option<Flag>, u16),
170 /// Gets the value at memory address HL and jumps to it.
171 JpHl,
172 /// Contains eight possible values: between 0-8. Value should be multplied
173 /// by 8 to determine the reset location.
174 /// TODO: consider simplifying this
175 Rst(u8),
176 /// HL = SP + (PC + i8).
177 /// TODO: double check behavior of relative parameters.
178 LdHlSp8(i8),
179 /// Load the value of HL into SP.
180 LdSpHl,
181 /// stores A in (u8)
182 StoreHA(u8),
183 /// loads A from (u8)
184 LoadHA(u8),
185 /// stores A in (C)
186 StoreCA,
187 /// Loads A from (C)
188 LoadCA,
189 /// LD (a16), A
190 StoreAAtAddress(u16),
191 /// LD A, (a16)
192 LoadAFromAddress(u16),
193 /// # 0xCB instructions
194 ///
195 /// Rotate register left.
196 Rlc(Register8),
197 /// Rotate register right.
198 Rrc(Register8),
199 /// Rotate register right through carry.
200 Rr(Register8),
201 /// Rotate register left through carry.
202 Rl(Register8),
203 /// Arithmetic left shift on given register.
204 Sla(Register8),
205 /// Arithmetic right shift on given register.
206 Sra(Register8),
207 /// Swap low and high nibble (4 bits).
208 Swap(Register8),
209 /// Logical Right shift on given register.
210 Srl(Register8),
211 /// Set flags based on the given bit in register.
212 /// u8 is number between 0 and 7 (inclusive).
213 Bit(u8, Register8),
214 /// Reset the given bit in the register.
215 /// u8 is number between 0 and 7 (inclusive)
216 Res(u8, Register8),
217 /// Set the given bit in the register.
218 /// u8 is number between 0 and 7 (inclusive)
219 Set(u8, Register8),
220}