gbi/cpu/
mod.rs

1mod ld_tests;
2mod control_tests;
3mod alu_tests;
4mod jump_branch_tests;
5use crate::ram::{self, Ram};
6
7type Reg = usize;
8const REG_A:Reg = 0;
9const REG_B:Reg = 1;
10const REG_C:Reg = 2;
11const REG_D:Reg = 3;
12const REG_E:Reg = 4;
13const REG_F:Reg = 5;
14const REG_H:Reg = 6;
15const REG_L:Reg = 7;
16
17//in an AF situation, A is msh, F is lsh, little endian
18
19type Flag = u8;
20const FLAG_Z:Flag = 7;
21const FLAG_N:Flag = 6;
22const FLAG_H:Flag = 5;
23const FLAG_C:Flag = 4;
24
25const ZERO_INSTRUCTION_TIME_TABLE:[u8;0x100] = //M-cycle timings
26    [1,3,2,2,1,1,2,1,5,2,2,2,1,1,2,1,
27     1,3,2,2,1,1,2,1,3,2,2,2,1,1,2,1,
28     2,3,2,2,1,1,2,1,2,2,2,2,1,1,2,1,
29     2,3,2,2,3,3,3,1,2,2,2,2,1,1,2,1,
30     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
31     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
32     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
33     2,2,2,2,2,2,1,2,1,1,1,1,1,1,2,1,
34     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
35     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
36     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
37     1,1,1,1,1,1,2,1,1,1,1,1,1,1,2,1,
38     2,3,3,4,3,4,2,4,2,4,3,1,3,6,2,4,
39     1,3,3,0,3,4,2,4,2,4,3,0,3,0,2,4,
40     3,3,2,0,0,4,2,4,4,1,4,0,0,0,2,4,
41     3,3,2,1,0,4,2,4,3,2,4,1,0,0,2,4];
42
43const CB_INSTRUCTION_TIME_TABLE:[u8;0x100] = //M-Cycle timings
44    [2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
45     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
46     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
47     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
48     2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,
49     2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,
50     2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,
51     2,2,2,2,2,2,3,2,2,2,2,2,2,2,3,2,
52     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
53     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
54     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
55     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
56     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
57     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
58     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2,
59     2,2,2,2,2,2,4,2,2,2,2,2,2,2,4,2];
60
61#[derive(Clone, Copy)]
62pub struct ProgramCounter
63{
64    pub reg: u16,
65    pub should_increment: bool,
66    pub current_instruction_width: u16,
67    pub current_instruction_cycles: u8
68}
69
70pub struct Cpu
71{
72    regs: [u8;8],
73    sp: u16,
74    pc: ProgramCounter,
75    ime: bool,
76    pub halted: bool,
77    pub stopped: bool
78}
79
80impl Cpu
81{
82    pub fn new() -> Cpu
83    {
84        Cpu
85        {
86            regs: [0x01, 0x00, 0x13, 0x00, 0xD8, 0xB0, 0x01, 0x4D],
87            sp: 0,
88            pc: ProgramCounter
89            {
90                reg: 0, should_increment: true, current_instruction_width: 1, current_instruction_cycles: 0
91            },
92            ime: false,
93            halted: false,
94            stopped: false
95        }
96    }
97    //Format [name]_[param1]_[param2]
98    //r is a register
99    //sp/pc are stack pointer and program counter
100    //hl is hl register, a alone is a register, etc.
101    //a suffix means parameter is an address (dereference)
102    //i(num) is a signed value
103
104    fn aux_read_flag(&self, param: Flag) -> bool
105    {
106        (self.regs[REG_F] & 1 << param) != 0
107    }
108
109    fn aux_write_flag(&mut self, param: Flag, data: bool)
110    {
111        if data
112        {
113            self.regs[REG_F] = self.regs[REG_F] | (1 << param);
114        }
115        else
116        {
117            self.regs[REG_F] = self.regs[REG_F] & (!(1 << param));
118        }
119    }
120
121    fn halt(&mut self)
122    {
123        self.halted = true;
124    }
125
126    fn stop(&mut self)
127    {
128        self.halted = true;
129        self.stopped = true;
130    }
131
132    fn ld_r16_16(&mut self, msh_reg: Reg, lsh_reg: Reg, msh_num: u8, lsh_num: u8)
133    {
134        self.regs[msh_reg] = msh_num;
135        self.regs[lsh_reg] = lsh_num;
136    }
137
138    fn ld_hl_sp_plus(&mut self, p1: i8)
139    {
140        let conv = p1.unsigned_abs() as u16;
141        let negative = p1 < 0;
142        if negative
143        {
144            let bytes = u16::to_le_bytes(self.sp - conv);
145            self.regs[REG_H] = bytes[1];
146            self.regs[REG_L] = bytes[0];
147        }
148        else
149        {
150            let bytes = u16::to_le_bytes(self.sp + conv);
151            self.regs[REG_H] = bytes[1];
152            self.regs[REG_L] = bytes[0];
153        }
154    }
155
156    fn ld_sp_16(&mut self, msh_num: u8, lsh_num: u8)
157    {
158        self.sp = u16::from_le_bytes([lsh_num, msh_num]);
159    }
160
161    fn ld_r8_8(&mut self, p1: Reg, p2: u8)
162    {
163        self.regs[p1] = p2;
164    }
165
166    fn ld_r16a_8(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg, p2: u8)
167    {
168        ram.write_rp(self.regs[msh], self.regs[lsh], p2);
169    }
170
171    fn ld_16a_r8(&mut self, ram: &mut Ram, msh: u8, lsh: u8, p2: Reg)
172    {
173        ram.write_rp(msh, lsh, self.regs[p2]);
174    }
175
176    fn ld_16a_sp(&mut self, ram: &mut Ram, msh: u8, lsh: u8)
177    {
178        let bytes = self.sp.to_le_bytes();
179        ram.write_rp(msh, lsh, bytes[0]);
180
181        let result = self.aux_inc_16(msh, lsh);
182        ram.write_rp(result.1, result.0, bytes[1]);
183    }
184
185    fn ld_r8_r8(&mut self, p1: Reg, p2: Reg)
186    {
187        self.regs[p1] = self.regs[p2];
188    }
189
190    fn ld_sp_r16(&mut self, msh: Reg, lsh: Reg)
191    {
192        self.sp = u16::from_le_bytes([self.regs[lsh], self.regs[msh]]);
193    }
194
195    fn ld_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
196    {
197        let x = ram.read_rp(self.regs[msh], self.regs[lsh]);
198        self.regs[p1] = x;
199    }
200
201    fn ld_r8_16a(&mut self, ram: &mut Ram, p1: Reg, msh: u8, lsh: u8)
202    {
203        let x = ram.read_rp(msh, lsh);
204        self.regs[p1] = x;
205    }
206
207    fn ld_r16a_r8(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg, p2: Reg)
208    {
209        ram.write_rp(self.regs[msh], self.regs[lsh], self.regs[p2]);
210    }
211
212    // TODO: See if the flags are modified
213
214    ///Returns (lsh, msh)
215    fn aux_inc_16(&mut self, msh: u8, lsh: u8) -> (u8, u8)
216    {
217        let lsh_result = u8::overflowing_add(lsh, 1);
218        let msh_result = u8::overflowing_add(msh, lsh_result.1 as u8);
219        (lsh_result.0, msh_result.0)
220    }
221
222    fn inc_r16(&mut self, msh: Reg, lsh: Reg)
223    {
224        let lsh_result = u8::overflowing_add(self.regs[lsh], 1);
225        self.regs[lsh] = lsh_result.0;
226        let msh_result = u8::overflowing_add(self.regs[msh], lsh_result.1 as u8);
227        self.regs[msh] = msh_result.0;
228    }
229
230    fn inc_sp(&mut self)
231    {
232        let result = u16::overflowing_add(self.sp, 1);
233        self.sp = result.0;
234    }
235
236    fn inc_r8(&mut self, reg: Reg)
237    {
238        let result = u8::overflowing_add(self.regs[reg], 1);
239        self.regs[reg] = result.0;
240
241        self.aux_write_flag(FLAG_Z, result.0 == 0);
242        self.aux_write_flag(FLAG_N, false);
243        self.aux_write_flag(FLAG_H, result.1);
244    }
245
246    fn inc_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
247    {
248        let result = ram.read_rp(
249            self.regs[msh], self.regs[lsh]).overflowing_add(1);
250        ram.write_rp(self.regs[msh], self.regs[lsh], result.0);
251
252        self.aux_write_flag(FLAG_Z, result.0 == 0);
253        self.aux_write_flag(FLAG_N, false);
254        self.aux_write_flag(FLAG_H, result.1);
255    }
256
257    fn dec_r8(&mut self, reg: Reg)
258    {
259        let result = u8::overflowing_sub(self.regs[reg], 1);
260        self.regs[reg] = result.0;
261
262        self.aux_write_flag(FLAG_Z, result.0 == 0);
263        self.aux_write_flag(FLAG_N, true);
264        self.aux_write_flag(FLAG_H, result.1);
265    }
266
267    fn dec_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
268    {
269        let result = ram.read_rp(
270            self.regs[msh], self.regs[lsh]).overflowing_sub(1);
271        ram.write_rp(self.regs[msh], self.regs[lsh], result.0);
272
273        self.aux_write_flag(FLAG_Z, result.0 == 0);
274        self.aux_write_flag(FLAG_N, true);
275        self.aux_write_flag(FLAG_H, result.1);
276    }
277
278    fn dec_r16(&mut self, msh: Reg, lsh: Reg)
279    {
280        let lsh_result = u8::overflowing_sub(self.regs[lsh], 1);
281        self.regs[lsh] = lsh_result.0;
282        let msh_result = u8::overflowing_sub(self.regs[msh], lsh_result.1 as u8);
283        self.regs[msh] = msh_result.0;
284    }
285
286    fn dec_sp(&mut self)
287    {
288        let result = u16::overflowing_sub(self.sp, 1);
289        self.sp = result.0;
290    }
291
292    fn add_r8_r8(&mut self, p1: Reg, p2: Reg)
293    {
294        let half_carry_pre = ((self.regs[p1] ^ self.regs[p2]) >> 4) & 1;
295        let result = self.regs[p1].overflowing_add(self.regs[p2]);
296        self.regs[p1] = result.0;
297        let half_carry_post = (result.0 >> 4) & 1;
298
299        self.aux_write_flag(FLAG_Z, result.0 == 0);
300        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
301        self.aux_write_flag(FLAG_N, false);
302        self.aux_write_flag(FLAG_C, result.1);
303    }
304
305    fn add_r8_8(&mut self, p1: Reg, p2: u8)
306    {
307        let half_carry_pre = ((self.regs[p1] ^ p2) >> 4) & 1;
308        let result = self.regs[p1].overflowing_add(p2);
309        self.regs[p1] = result.0;
310        let half_carry_post = (result.0 >> 4) & 1;
311
312        self.aux_write_flag(FLAG_Z, result.0 == 0);
313        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
314        self.aux_write_flag(FLAG_N, false);
315        self.aux_write_flag(FLAG_C, result.1);
316    }
317
318    fn add_r16_r16(&mut self, p1_msh: Reg, p1_lsh: Reg, p2_msh: Reg, p2_lsh: Reg)
319    {
320        let z = self.aux_read_flag(FLAG_Z);
321        self.add_r8_r8(p1_lsh, p2_lsh);
322        self.adc_r8_r8(p1_msh, p2_msh);
323
324        self.aux_write_flag(FLAG_Z, z);
325        self.aux_write_flag(FLAG_N, false);
326    }
327
328    fn add_r16_sp(&mut self, p1_msh: Reg, p1_lsh: Reg)
329    {
330        let z = self.aux_read_flag(FLAG_Z);
331        let reg = self.sp.to_le_bytes();
332
333        //ADD
334        let result = self.regs[p1_lsh].overflowing_add(reg[0]);
335        self.regs[p1_lsh] = result.0;
336        self.aux_write_flag(FLAG_C, result.1);
337
338        //ADC
339        let carry = self.aux_read_flag(FLAG_C) as u8;
340        let half_carry_pre1 = ((self.regs[p1_msh] ^ reg[1]) >> 4) & 1;
341        let result1 = self.regs[p1_msh].overflowing_add(reg[1]);
342        let half_carry_post1 = (result1.0 >> 4) & 1;
343        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
344        let result2 = result1.0.overflowing_add(carry);
345        self.regs[p1_msh] = result2.0;
346        let half_carry_post2 = (result2.0 >> 4) & 1;
347
348        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
349        self.aux_write_flag(FLAG_N, false);
350        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
351        self.aux_write_flag(FLAG_Z, z);
352    }
353
354    fn add_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
355    {
356        let p2 = ram.read_rp(self.regs[msh], self.regs[lsh]);
357        let half_carry_pre = ((self.regs[p1] ^ p2) >> 4) & 1;
358        let result = self.regs[p1].overflowing_add(p2);
359        self.regs[p1] = result.0;
360        let half_carry_post = (result.0 >> 4) & 1;
361
362        self.aux_write_flag(FLAG_Z, result.0 == 0);
363        self.aux_write_flag(FLAG_H, half_carry_pre == half_carry_post);
364        self.aux_write_flag(FLAG_N, false);
365        self.aux_write_flag(FLAG_C, result.1);
366    }
367
368    fn add_sp_i8(&mut self, p1: i8)
369    {
370        let conv = p1.unsigned_abs() as u16;
371        let negative = p1 < 0;
372        if negative
373        {
374            self.sp -= conv;
375        }
376        else
377        {
378            self.sp += conv;
379        }
380    }
381
382    fn adc_r8_r8(&mut self, p1: Reg, p2: Reg)
383    {
384        let carry = self.aux_read_flag(FLAG_C) as u8;
385        let half_carry_pre1 = ((self.regs[p1] ^ self.regs[p2]) >> 4) & 1;
386        let result1 = self.regs[p1].overflowing_add(self.regs[p2]);
387        let half_carry_post1 = (result1.0 >> 4) & 1;
388        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
389        let result2 = result1.0.overflowing_add(carry);
390        self.regs[p1] = result2.0;
391        let half_carry_post2 = (result2.0 >> 4) & 1;
392
393        self.aux_write_flag(FLAG_Z, result2.0 == 0);
394        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
395        self.aux_write_flag(FLAG_N, false);
396        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
397    }
398
399    fn adc_r8_8(&mut self, p1: Reg, p2: u8)
400    {
401        let carry = self.aux_read_flag(FLAG_C) as u8;
402        let half_carry_pre1 = ((self.regs[p1] ^ p2) >> 4) & 1;
403        let result1 = self.regs[p1].overflowing_add(p2);
404        let half_carry_post1 = (result1.0 >> 4) & 1;
405        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
406        let result2 = result1.0.overflowing_add(carry);
407        self.regs[p1] = result2.0;
408        let half_carry_post2 = (result2.0 >> 4) & 1;
409
410        self.aux_write_flag(FLAG_Z, result2.0 == 0);
411        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
412        self.aux_write_flag(FLAG_N, false);
413        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
414    }
415
416    fn adc_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
417    {
418        let carry = self.aux_read_flag(FLAG_C) as u8;
419        let p2 = ram.read_rp(self.regs[msh], self.regs[lsh]);
420        let half_carry_pre1 = ((self.regs[p1] ^ p2) >> 4) & 1;
421        let result1 = self.regs[p1].overflowing_add(p2);
422        let half_carry_post1 = (result1.0 >> 4) & 1;
423        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
424        let result2 = result1.0.overflowing_add(carry);
425        self.regs[p1] = result2.0;
426        let half_carry_post2 = (result2.0 >> 4) & 1;
427
428        self.aux_write_flag(FLAG_Z, result2.0 == 0);
429        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
430        self.aux_write_flag(FLAG_N, false);
431        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
432    }
433
434    //TODO: Check subtraction half carry calculations
435    fn sub_r8_r8(&mut self, p1: Reg, p2: Reg)
436    {
437        let half_carry_pre = ((self.regs[p1] ^ self.regs[p2]) >> 4) & 1;
438        let result = self.regs[p1].overflowing_sub(self.regs[p2]);
439        self.regs[p1] = result.0;
440        let half_carry_post = (result.0 >> 4) & 1;
441
442        self.aux_write_flag(FLAG_Z, result.0 == 0);
443        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
444        self.aux_write_flag(FLAG_N, true);
445        self.aux_write_flag(FLAG_C, result.1);
446    }
447
448    fn sub_r8_8(&mut self, p1: Reg, p2: u8)
449    {
450        let half_carry_pre = ((self.regs[p1] ^ p2) >> 4) & 1;
451        let result = self.regs[p1].overflowing_sub(p2);
452        self.regs[p1] = result.0;
453        let half_carry_post = (result.0 >> 4) & 1;
454
455        self.aux_write_flag(FLAG_Z, result.0 == 0);
456        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
457        self.aux_write_flag(FLAG_N, true);
458        self.aux_write_flag(FLAG_C, result.1);
459    }
460
461    fn sub_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
462    {
463        let p2 = ram.read_rp(self.regs[msh], self.regs[lsh]);
464        let half_carry_pre = ((self.regs[p1] ^ p2) >> 4) & 1;
465        let result = self.regs[p1].overflowing_add(p2);
466        self.regs[p1] = result.0;
467        let half_carry_post = (result.0 >> 4) & 1;
468
469        self.aux_write_flag(FLAG_Z, result.0 == 0);
470        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
471        self.aux_write_flag(FLAG_N, true);
472        self.aux_write_flag(FLAG_C, result.1);
473    }
474
475    fn sbc_r8_r8(&mut self, p1: Reg, p2: Reg)
476    {
477        let carry = self.aux_read_flag(FLAG_C) as u8;
478        let half_carry_pre1 = ((self.regs[p1] ^ self.regs[p2]) >> 4) & 1;
479        let result1 = self.regs[p1].overflowing_sub(self.regs[p2]);
480        let half_carry_post1 = (result1.0 >> 4) & 1;
481        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
482        let result2 = result1.0.overflowing_sub(carry);
483        self.regs[p1] = result2.0;
484        let half_carry_post2 = (result2.0 >> 4) & 1;
485
486        self.aux_write_flag(FLAG_Z, result2.0 == 0);
487        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
488        self.aux_write_flag(FLAG_N, true);
489        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
490    }
491
492    fn sbc_r8_8(&mut self, p1: Reg, p2: u8)
493    {
494        let carry = self.aux_read_flag(FLAG_C) as u8;
495        let half_carry_pre1 = ((self.regs[p1] ^ p2) >> 4) & 1;
496        let result1 = self.regs[p1].overflowing_sub(p2);
497        let half_carry_post1 = (result1.0 >> 4) & 1;
498        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
499        let result2 = result1.0.overflowing_sub(carry);
500        self.regs[p1] = result2.0;
501        let half_carry_post2 = (result2.0 >> 4) & 1;
502
503        self.aux_write_flag(FLAG_Z, result2.0 == 0);
504        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
505        self.aux_write_flag(FLAG_N, true);
506        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
507    }
508
509    fn sbc_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
510    {
511        let carry = self.aux_read_flag(FLAG_C) as u8;
512        let p2 = ram.read_rp(self.regs[msh], self.regs[lsh]);
513        let half_carry_pre1 = ((self.regs[p1] ^ p2) >> 4) & 1;
514        let result1 = self.regs[p1].overflowing_sub(p2);
515        let half_carry_post1 = (result1.0 >> 4) & 1;
516        let half_carry_pre2 = ((result1.0 ^ carry) >> 4) & 1;
517        let result2 = result1.0.overflowing_sub(carry);
518        self.regs[p1] = result2.0;
519        let half_carry_post2 = (result2.0 >> 4) & 1;
520
521        self.aux_write_flag(FLAG_Z, result2.0 == 0);
522        self.aux_write_flag(FLAG_H, half_carry_pre1 != half_carry_post1 || half_carry_pre2 != half_carry_post2);
523        self.aux_write_flag(FLAG_N, true);
524        self.aux_write_flag(FLAG_C, result1.1 || result2.1);
525    }
526
527    fn and_r8_r8(&mut self, p1: Reg, p2: Reg)
528    {
529        self.regs[p1] &= self.regs[p2];
530
531        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
532        self.aux_write_flag(FLAG_H, true);
533        self.aux_write_flag(FLAG_N, false);
534        self.aux_write_flag(FLAG_C, false);
535    }
536
537    fn and_r8_8(&mut self, p1: Reg, p2: u8)
538    {
539        self.regs[p1] &= p2;
540
541        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
542        self.aux_write_flag(FLAG_H, true);
543        self.aux_write_flag(FLAG_N, false);
544        self.aux_write_flag(FLAG_C, false);
545    }
546
547    fn and_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
548    {
549        self.regs[p1] &= ram.read_rp(self.regs[msh], self.regs[lsh]);
550
551        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
552        self.aux_write_flag(FLAG_H, true);
553        self.aux_write_flag(FLAG_N, false);
554        self.aux_write_flag(FLAG_C, false);
555    }
556
557    fn xor_r8_r8(&mut self, p1: Reg, p2: Reg)
558    {
559        self.regs[p1] ^= self.regs[p2];
560
561        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
562        self.aux_write_flag(FLAG_H, false);
563        self.aux_write_flag(FLAG_N, false);
564        self.aux_write_flag(FLAG_C, false);
565    }
566
567    fn xor_r8_8(&mut self, p1: Reg, p2: u8)
568    {
569        self.regs[p1] ^= p2;
570
571        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
572        self.aux_write_flag(FLAG_H, false);
573        self.aux_write_flag(FLAG_N, false);
574        self.aux_write_flag(FLAG_C, false);
575    }
576
577    fn xor_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
578    {
579        self.regs[p1] ^= ram.read_rp(self.regs[msh], self.regs[lsh]);
580
581        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
582        self.aux_write_flag(FLAG_H, false);
583        self.aux_write_flag(FLAG_N, false);
584        self.aux_write_flag(FLAG_C, false);
585    }
586
587    fn or_r8_r8(&mut self, p1: Reg, p2: Reg)
588    {
589        self.regs[p1] |= self.regs[p2];
590
591        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
592        self.aux_write_flag(FLAG_H, false);
593        self.aux_write_flag(FLAG_N, false);
594        self.aux_write_flag(FLAG_C, false);
595    }
596
597    fn or_r8_8(&mut self, p1: Reg, p2: u8)
598    {
599        self.regs[p1] |= p2;
600
601        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
602        self.aux_write_flag(FLAG_H, false);
603        self.aux_write_flag(FLAG_N, false);
604        self.aux_write_flag(FLAG_C, false);
605    }
606
607    fn or_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
608    {
609        self.regs[p1] |= ram.read_rp(self.regs[msh], self.regs[lsh]);
610
611        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
612        self.aux_write_flag(FLAG_H, false);
613        self.aux_write_flag(FLAG_N, false);
614        self.aux_write_flag(FLAG_C, false);
615    }
616
617    fn cp_r8_r8(&mut self, p1: Reg, p2: Reg)
618    {
619        let half_carry_pre = ((self.regs[p1] ^ self.regs[p2]) >> 4) & 1;
620        let result = self.regs[p1].overflowing_sub(self.regs[p2]);
621        self.regs[p1] = result.0;
622        let half_carry_post = (result.0 >> 4) & 1;
623
624        self.aux_write_flag(FLAG_Z, result.0 == 0);
625        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
626        self.aux_write_flag(FLAG_N, true);
627        self.aux_write_flag(FLAG_C, result.1);
628    }
629
630    fn cp_r8_8(&mut self, p1: Reg, p2: u8)
631    {
632        let half_carry_pre = ((self.regs[p1] ^ p2) >> 4) & 1;
633        let result = self.regs[p1].overflowing_sub(p2);
634        self.regs[p1] = result.0;
635        let half_carry_post = (result.0 >> 4) & 1;
636
637        self.aux_write_flag(FLAG_Z, result.0 == 0);
638        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
639        self.aux_write_flag(FLAG_N, true);
640        self.aux_write_flag(FLAG_C, result.1);
641    }
642
643    fn cp_r8_r16a(&mut self, ram: &mut Ram, p1: Reg, msh: Reg, lsh: Reg)
644    {
645        let p2 = ram.read_rp(self.regs[msh], self.regs[lsh]);
646        let half_carry_pre = ((self.regs[p1] ^ p2) >> 4) & 1;
647        let result = self.regs[p1].overflowing_add(p2);
648        self.regs[p1] = result.0;
649        let half_carry_post = (result.0 >> 4) & 1;
650
651        self.aux_write_flag(FLAG_Z, result.0 == 0);
652        self.aux_write_flag(FLAG_H, half_carry_pre != half_carry_post);
653        self.aux_write_flag(FLAG_N, true);
654        self.aux_write_flag(FLAG_C, result.1);
655    }
656
657    fn daa(&mut self)
658    {
659        let c_before = self.aux_read_flag(FLAG_C);
660        let bits_47 = (self.regs[REG_A] >> 4) & 0b00001111;
661        let h_before = self.aux_read_flag(FLAG_H);
662        let bits_03 = self.regs[REG_A] & 0b00001111;
663        if self.aux_read_flag(FLAG_N) == true //Add preceded instruction
664        {
665            match (c_before, bits_47, h_before, bits_03)
666            {
667                (false, 0x0..=0x9, false, 0x0..=0x9) => {
668                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x00);
669                    self.aux_write_flag(FLAG_C, false);
670                },
671                (false, 0x0..=0x8, false, 0xA..=0xF) => {
672                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x06);
673                    self.aux_write_flag(FLAG_C, false);
674                },
675                (false, 0x0..=0x9, true, 0x0..=0x3) => {
676                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x06);
677                    self.aux_write_flag(FLAG_C, false);
678                },
679                (false, 0xA..=0xF, false, 0x0..=0x9) => {
680                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x60);
681                    self.aux_write_flag(FLAG_C, true);
682                },
683                (false, 0x9..=0xF, false, 0xA..=0xF) => {
684                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x66);
685                    self.aux_write_flag(FLAG_C, true);
686                },
687                (false, 0xA..=0xF, true, 0x0..=0x3) => {
688                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x66);
689                    self.aux_write_flag(FLAG_C, true);
690                },
691                (true, 0x0..=0x2, false, 0x0..=0x9) => {
692                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x60);
693                    self.aux_write_flag(FLAG_C, true);
694                },
695                (true, 0x0..=0x2, false, 0xA..=0xF) => {
696                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x66);
697                    self.aux_write_flag(FLAG_C, true);
698                },
699                (true, 0x0..=0x3, true, 0x0..=0x3) => {
700                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x66);
701                    self.aux_write_flag(FLAG_C, true);
702                },
703                _ => panic!("Invalid BDC conversion")
704            }
705        }
706        else //subtract preceded instruction
707        {
708            match (c_before, bits_47, h_before, bits_03)
709            {
710                (false, 0x0..=0x9, false, 0x0..=0x9) => {
711                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x00);
712                    self.aux_write_flag(FLAG_C, false);
713                },
714                (false, 0x0..=0x8, true, 0x6..=0xF) => {
715                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0xFA);
716                    self.aux_write_flag(FLAG_C, false);
717                },
718                (true, 0x7..=0xF, false, 0x0..=0x9) => {
719                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0xA0);
720                    self.aux_write_flag(FLAG_C, true);
721                },
722                (true, 0x6..=0xF, true, 0x6..=0xF) => {
723                    self.regs[REG_A] = self.regs[REG_A].wrapping_add(0x9A);
724                    self.aux_write_flag(FLAG_C, true);
725                },
726                _ => panic!("Invalid BDC conversion")
727            }
728        }
729    }
730
731    fn cpl(&mut self)
732    {
733        self.regs[REG_A] = !self.regs[REG_A];
734        self.aux_write_flag(FLAG_N, true);
735        self.aux_write_flag(FLAG_H, true);
736    }
737
738    fn ccf(&mut self)
739    {
740        self.aux_write_flag(FLAG_C, !self.aux_read_flag(FLAG_C));
741        self.aux_write_flag(FLAG_N, false);
742        self.aux_write_flag(FLAG_H, false);
743    }
744
745    fn scf(&mut self)
746    {
747        self.aux_write_flag(FLAG_C, true);
748        self.aux_write_flag(FLAG_N, false);
749        self.aux_write_flag(FLAG_H, false);
750    }
751
752    fn jp_pc_16(&mut self, msh: u8, lsh: u8)
753    {
754        self.pc.reg = u16::from_le_bytes([lsh, msh]);
755        self.pc.should_increment = false;
756    }
757
758    fn jp_flag_pc_16(&mut self, flag: Flag, msh: u8, lsh: u8)
759    {
760        if self.aux_read_flag(flag) == true
761        {
762            self.jp_pc_16(msh, lsh);
763        }
764    }
765
766    fn jp_nflag_pc_16(&mut self, flag: Flag, msh: u8, lsh: u8)
767    {
768        if self.aux_read_flag(flag) == false
769        {
770            self.jp_pc_16(msh, lsh);
771        }
772    }
773
774    fn jr_i8(&mut self, p1: i8)
775    {
776        let conv = p1.unsigned_abs() as u16;
777        let negative = p1 < 0;
778        if negative
779        {
780            self.pc.reg -= conv;
781        }
782        else
783        {
784            self.pc.reg += conv;
785        }
786        self.pc.should_increment = false;
787    }
788
789    fn jr_flag_i8(&mut self, flag: Flag, p1: i8)
790    {
791        if self.aux_read_flag(flag) == true
792        {
793            self.jr_i8(p1);
794        }
795    }
796
797    fn jr_nflag_i8(&mut self, flag: Flag, p1: i8)
798    {
799        if self.aux_read_flag(flag) == false
800        {
801            self.jr_i8(p1);
802        }
803    }
804
805    fn call_16(&mut self, ram: &mut Ram, msh: u8, lsh: u8)
806    {
807        let pc_bytes = self.pc.reg.to_le_bytes();
808        ram.write(self.sp - 1, pc_bytes[1]);
809        ram.write(self.sp - 2, pc_bytes[0]);
810        self.pc.reg = u16::from_le_bytes([lsh, msh]);
811        self.sp -= 2;
812    }
813
814    fn call_flag_16(&mut self, ram: &mut Ram, flag: Flag, msh: u8, lsh: u8)
815    {
816        if self.aux_read_flag(flag) == true
817        {
818            self.call_16(ram, msh, lsh);
819        }
820    }
821
822    fn call_nflag_16(&mut self, ram: &mut Ram, flag: Flag, msh: u8, lsh: u8)
823    {
824        if self.aux_read_flag(flag) == false
825        {
826            self.call_16(ram, msh, lsh);
827        }
828    }
829
830    fn ret(&mut self, ram: &mut Ram)
831    {
832        let sp_lsh = ram.read(self.sp);
833        let sp_msh = ram.read(self.sp + 1);
834        self.pc.reg = u16::from_le_bytes([sp_lsh, sp_msh]);
835        self.sp += 2;
836    }
837
838    fn ret_flag(&mut self, ram: &mut Ram, flag: Flag)
839    {
840        if self.aux_read_flag(flag) == true
841        {
842            self.ret(ram);
843        }
844    }
845
846    fn ret_nflag(&mut self, ram: &mut Ram, flag: Flag)
847    {
848        if self.aux_read_flag(flag) == false
849        {
850            self.ret(ram);
851        }
852    }
853
854    fn rst(&mut self, ram: &mut Ram, loc: u8)
855    {
856        let pc_bytes = self.pc.reg.to_le_bytes();
857        ram.write(self.sp - 1, pc_bytes[1]);
858        ram.write(self.sp - 2, pc_bytes[0]);
859        self.sp -= 2;
860        self.pc.reg = u16::from_le_bytes([loc, 0]);
861    }
862
863
864    //--------------------16 BIT OPCODES--------------------
865
866    fn rlc_r8(&mut self, p1: Reg)
867    {
868        self.aux_write_flag(FLAG_C, (self.regs[p1] >> 7) & 1 != 0);
869        self.regs[p1] = self.regs[p1].rotate_left(1);
870
871        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
872        self.aux_write_flag(FLAG_N, false);
873        self.aux_write_flag(FLAG_H, false);
874    }
875
876    fn rlca(&mut self)
877    {
878        self.aux_write_flag(FLAG_C, (self.regs[REG_A] >> 7) & 1 != 0);
879        self.regs[REG_A] = self.regs[REG_A].rotate_left(1);
880
881        self.aux_write_flag(FLAG_Z, false);
882        self.aux_write_flag(FLAG_N, false);
883        self.aux_write_flag(FLAG_H, false);
884    }
885
886    fn rlc_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
887    {
888        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
889        self.aux_write_flag(FLAG_C, (p1 >> 7) & 1 != 0);
890        let result = p1.rotate_left(1);
891        ram.write_rp(self.regs[msh], self.regs[lsh], result);
892
893        self.aux_write_flag(FLAG_Z, result == 0);
894        self.aux_write_flag(FLAG_N, false);
895        self.aux_write_flag(FLAG_H, false);
896    }
897
898    fn rrc_r8(&mut self, p1: Reg)
899    {
900        self.aux_write_flag(FLAG_C, self.regs[p1] & 1 != 0);
901        self.regs[p1] = self.regs[p1].rotate_right(1);
902
903        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
904        self.aux_write_flag(FLAG_N, false);
905        self.aux_write_flag(FLAG_H, false);
906    }
907
908    fn rrca(&mut self)
909    {
910        self.aux_write_flag(FLAG_C, self.regs[REG_A] & 1 != 0);
911        self.regs[REG_A] = self.regs[REG_A].rotate_right(1);
912
913        self.aux_write_flag(FLAG_Z, false);
914        self.aux_write_flag(FLAG_N, false);
915        self.aux_write_flag(FLAG_H, false);
916    }
917
918    fn rrc_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
919    {
920        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
921        self.aux_write_flag(FLAG_C, p1 & 1 != 0);
922        let result = p1.rotate_right(1);
923        ram.write_rp(self.regs[msh], self.regs[lsh], result);
924
925        self.aux_write_flag(FLAG_Z, result == 0);
926        self.aux_write_flag(FLAG_N, false);
927        self.aux_write_flag(FLAG_H, false);
928    }
929
930    fn rl_r8(&mut self, p1: Reg)
931    {
932        let cin = self.aux_read_flag(FLAG_C) as u8;
933        self.aux_write_flag(FLAG_C, (self.regs[p1] >> 7) & 1 != 0);
934        self.regs[p1] = (self.regs[p1] << 1u8) | cin;
935
936        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
937        self.aux_write_flag(FLAG_N, false);
938        self.aux_write_flag(FLAG_H, false);
939    }
940
941    fn rla(&mut self)
942    {
943        let cin = self.aux_read_flag(FLAG_C) as u8;
944        self.aux_write_flag(FLAG_C, (self.regs[REG_A] >> 7) & 1 != 0);
945        self.regs[REG_A] = (self.regs[REG_A] << 1u8) | cin;
946
947        self.aux_write_flag(FLAG_Z, false);
948        self.aux_write_flag(FLAG_N, false);
949        self.aux_write_flag(FLAG_H, false);
950    }
951
952    fn rl_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
953    {
954        let cin = self.aux_read_flag(FLAG_C) as u8;
955        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
956        self.aux_write_flag(FLAG_C, (p1 >> 7) & 1 != 0);
957        let result = (p1 << 1u8) | cin;
958        ram.write_rp(self.regs[msh], self.regs[lsh], result);
959
960        self.aux_write_flag(FLAG_Z, result == 0);
961        self.aux_write_flag(FLAG_N, false);
962        self.aux_write_flag(FLAG_H, false);
963    }
964
965    fn rr_r8(&mut self, p1: Reg)
966    {
967        let cin = self.aux_read_flag(FLAG_C) as u8;
968        self.aux_write_flag(FLAG_C, self.regs[p1] & 1 != 0);
969        self.regs[p1] = (self.regs[p1] >> 1u8) | (cin << 7u8);
970
971        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
972        self.aux_write_flag(FLAG_N, false);
973        self.aux_write_flag(FLAG_H, false);
974    }
975
976    fn rra(&mut self)
977    {
978        let cin = self.aux_read_flag(FLAG_C) as u8;
979        self.aux_write_flag(FLAG_C, self.regs[REG_A] & 1 != 0);
980        self.regs[REG_A] = (self.regs[REG_A] >> 1u8) | (cin << 7u8);
981
982        self.aux_write_flag(FLAG_Z, false);
983        self.aux_write_flag(FLAG_N, false);
984        self.aux_write_flag(FLAG_H, false);
985    }
986
987    fn rr_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
988    {
989        let cin = self.aux_read_flag(FLAG_C) as u8;
990        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
991        self.aux_write_flag(FLAG_C, p1 & 1 != 0);
992        let result = (p1 >> 1u8) | (cin << 7u8);
993        ram.write_rp(self.regs[msh], self.regs[lsh], result);
994
995        self.aux_write_flag(FLAG_Z, result == 0);
996        self.aux_write_flag(FLAG_N, false);
997        self.aux_write_flag(FLAG_H, false);
998    }
999
1000    fn sla_r8(&mut self, p1: Reg)
1001    {
1002        self.aux_write_flag(FLAG_C, (self.regs[p1] >> 7) & 1 != 0);
1003        self.regs[p1] <<= 1u8;
1004
1005        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
1006        self.aux_write_flag(FLAG_N, false);
1007        self.aux_write_flag(FLAG_H, false);
1008    }
1009
1010    fn sla_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
1011    {
1012        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
1013        self.aux_write_flag(FLAG_C, (p1 >> 7) & 1 != 0);
1014        let result = p1 << 1u8;
1015        ram.write_rp(self.regs[msh], self.regs[lsh], result);
1016
1017        self.aux_write_flag(FLAG_Z, result == 0);
1018        self.aux_write_flag(FLAG_N, false);
1019        self.aux_write_flag(FLAG_H, false);
1020    }
1021
1022    fn sra_r8(&mut self, p1: Reg)
1023    {
1024        self.aux_write_flag(FLAG_C, self.regs[p1] & 1 != 0);
1025        self.regs[p1] = (self.regs[p1] >> 1u8) | (self.regs[p1] & 0b10000000u8); //fill with leftmost
1026
1027        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
1028        self.aux_write_flag(FLAG_N, false);
1029        self.aux_write_flag(FLAG_H, false);
1030    }
1031
1032    fn sra_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
1033    {
1034        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
1035        self.aux_write_flag(FLAG_C, p1 & 1 != 0);
1036        let result =( p1 >> 1u8) | (p1 | 0b10000000u8);
1037        ram.write_rp(self.regs[msh], self.regs[lsh], result);
1038
1039        self.aux_write_flag(FLAG_Z, result == 0);
1040        self.aux_write_flag(FLAG_N, false);
1041        self.aux_write_flag(FLAG_H, false);
1042    }
1043
1044    fn srl_r8(&mut self, p1: Reg)
1045    {
1046        self.aux_write_flag(FLAG_C, self.regs[p1] & 1 != 0);
1047        self.regs[p1] >>= 1u8; //fill with leftmost
1048
1049        self.aux_write_flag(FLAG_Z, self.regs[p1] == 0);
1050        self.aux_write_flag(FLAG_N, false);
1051        self.aux_write_flag(FLAG_H, false);
1052    }
1053
1054    fn srl_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
1055    {
1056        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
1057        self.aux_write_flag(FLAG_C, p1 & 1 != 0);
1058        let result = p1 >> 1u8;
1059        ram.write_rp(self.regs[msh], self.regs[lsh], result);
1060
1061        self.aux_write_flag(FLAG_Z, result == 0);
1062        self.aux_write_flag(FLAG_N, false);
1063        self.aux_write_flag(FLAG_H, false);
1064    }
1065
1066    fn swap_r8(&mut self, p1: Reg)
1067    {
1068        let lower_to_upper_half = self.regs[p1] << 4u8;
1069        let upper_to_lower_half = self.regs[p1] >> 4u8;
1070        self.regs[p1] = lower_to_upper_half | upper_to_lower_half;
1071    }
1072
1073    fn swap_r16a(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
1074    {
1075        let p1 = ram.read_rp(self.regs[msh], self.regs[lsh]);
1076        let lower_to_upper_half = p1 << 4u8;
1077        let upper_to_lower_half = p1 >> 4u8;
1078        ram.write_rp(self.regs[msh], self.regs[lsh], lower_to_upper_half | upper_to_lower_half);
1079    }
1080
1081    fn bit_r8(&mut self, p1: u8, p2: Reg)
1082    {
1083        self.aux_write_flag(FLAG_H, true);
1084        self.aux_write_flag(FLAG_N, false);
1085        self.aux_write_flag(FLAG_Z, (self.regs[p2] & (1u8 << p1)) == 0);
1086    }
1087
1088    fn bit_r16a(&mut self, ram: &mut Ram, p1: u8, msh: Reg, lsh: Reg)
1089    {
1090        self.aux_write_flag(FLAG_H, true);
1091        self.aux_write_flag(FLAG_N, false);
1092        self.aux_write_flag(FLAG_Z,
1093            (ram.read_rp(self.regs[msh], self.regs[lsh]) & (1u8 << p1)) == 0);
1094    }
1095
1096    fn res_r8(&mut self, p1: u8, p2: Reg)
1097    {
1098        self.regs[p2] &= !(1u8 << p1);
1099    }
1100
1101    fn res_r16a(&mut self, ram: &mut Ram, p1: u8, msh: Reg, lsh: Reg)
1102    {
1103        ram.write_rp(self.regs[msh], self.regs[lsh],
1104            ram.read_rp(self.regs[msh], self.regs[lsh]) & (!(1u8 << p1)));
1105    }
1106
1107    fn set_r8(&mut self, p1: u8, p2: Reg)
1108    {
1109        self.regs[p2] |= 1u8 << p1;
1110    }
1111
1112    fn set_r16a(&mut self, ram: &mut Ram, p1: u8, msh: Reg, lsh: Reg)
1113    {
1114        ram.write_rp(self.regs[msh], self.regs[lsh],
1115            ram.read_rp(self.regs[msh], self.regs[lsh]) | (1u8 << p1));
1116    }
1117
1118    fn push_r16(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
1119    {
1120        ram.write(self.sp - 1, self.regs[msh]);
1121        ram.write(self.sp - 2, self.regs[lsh]);
1122        self.sp -= 2;
1123    }
1124
1125    fn push_pc(&mut self, ram: &mut Ram)
1126    {
1127        let bytes = self.pc.reg.to_le_bytes();
1128        ram.write(self.sp - 1, bytes[1]);
1129        ram.write(self.sp - 2, bytes[0]);
1130        self.sp -= 2;
1131    }
1132
1133    fn pop_r16(&mut self, ram: &mut Ram, msh: Reg, lsh: Reg)
1134    {
1135        self.regs[lsh] = ram.read(self.sp);
1136        self.regs[msh] = ram.read(self.sp + 1);
1137        self.sp += 2;
1138    }
1139
1140    //----------INTERRUPT MANAGEMENT----------
1141
1142    fn reti(&mut self, ram: &mut Ram)
1143    {
1144        let l_bytes = ram.read(self.sp);
1145        self.inc_sp();
1146        let h_bytes = ram.read(self.sp);
1147        self.inc_sp();
1148        self.pc.reg = u16::from_le_bytes([l_bytes, h_bytes]);
1149        self.ime = true;
1150    }
1151
1152    fn ei(&mut self)
1153    {
1154        self.ime = true;
1155    }
1156
1157    fn di(&mut self)
1158    {
1159        self.ime = false;
1160    }
1161
1162    //----------EXECUTION FUNCTIONS----------
1163
1164    fn aux_inc_pc(&mut self)
1165    {
1166        if self.pc.should_increment
1167        {
1168            self.pc.reg += 1;
1169            self.pc.current_instruction_width = 0;
1170        }
1171        else
1172        {
1173            self.pc.should_increment = true;
1174        }
1175    }
1176
1177    fn aux_read_pc(&self,  ram: &mut Ram) -> u8
1178    {
1179        ram.read(self.pc.reg)
1180    }
1181
1182    fn aux_read_immediate_data(&mut self, ram: &mut Ram) -> u8
1183    {
1184        self.pc.reg += 1;
1185        self.pc.current_instruction_width += 1;
1186        ram.read(self.pc.reg)
1187    }
1188
1189    pub fn execute(&mut self, ram: &mut Ram)
1190    {
1191        if self.pc.current_instruction_cycles > 1
1192        {
1193            self.pc.current_instruction_cycles -= 1;
1194            return;
1195        }
1196
1197        //Fetch
1198        let valid_interrupts = ram.read(ram::IF) & ram.read(ram::IE);
1199        if self.ime
1200        {
1201            if valid_interrupts != 0
1202            {
1203                self.ime = false;
1204                self.push_pc(ram);
1205            }
1206            if valid_interrupts & ram::INTERRUPT_VB != 0
1207            {
1208                self.pc.reg = 0x0040;
1209            }
1210            else if valid_interrupts & ram::INTERRUPT_LCDC != 0
1211            {
1212                self.pc.reg = 0x0048;
1213            }
1214            else if valid_interrupts & ram::INTERRUPT_TIMA != 0
1215            {
1216                self.pc.reg = 0x0050;
1217            }
1218            else if valid_interrupts & ram::INTERRUPT_SIO_TRANSFER_COMPLETE != 0
1219            {
1220                self.pc.reg = 0x0058;
1221            }
1222            else if valid_interrupts & ram::INTERRUPT_P1X_NEG_EDGE != 0
1223            {
1224                self.pc.reg = 0x0060;
1225            }
1226
1227        }
1228
1229        if self.halted
1230        {
1231            if valid_interrupts != 0
1232            {
1233                self.halted = false;
1234            }
1235            else
1236            {
1237                return;
1238            }
1239        }
1240
1241        let instruction = self.aux_read_pc(ram);
1242
1243        #[cfg(feature = "cpu-debug")]
1244        println!("Instruction: 0x{:02X?}, Program Counter: 0x{:02X?}", instruction, &self.pc.reg);
1245
1246        if instruction != 0xCB
1247        {
1248            match instruction
1249            {
1250                0x00 => {/* NOP */},
1251                0x01 => {
1252                    let lsh = self.aux_read_immediate_data(ram);
1253                    let msh = self.aux_read_immediate_data(ram);
1254                    self.ld_r16_16(REG_B, REG_C, msh, lsh);
1255                },
1256                0x02 => {self.ld_r16a_r8(ram, REG_B, REG_C, REG_A);},
1257                0x03 => {self.inc_r16(REG_B, REG_C);},
1258                0x04 => {self.inc_r8(REG_B);},
1259                0x05 => {self.dec_r8(REG_B);},
1260                0x06 => {
1261                    let num = self.aux_read_immediate_data(ram);
1262                    self.ld_r8_8(REG_B, num);
1263                },
1264                0x07 => {self.rlca();},
1265                0x08 => {
1266                    let lsh = self.aux_read_immediate_data(ram);
1267                    let msh = self.aux_read_immediate_data(ram);
1268                    self.ld_16a_sp(ram, msh, lsh);
1269                },
1270                0x09 => {self.add_r16_r16(REG_H, REG_L, REG_B, REG_C);},
1271                0x0A => {self.ld_r8_r16a(ram, REG_A, REG_B, REG_C);},
1272                0x0B => {self.dec_r16(REG_B, REG_C);},
1273                0x0C => {self.inc_r8(REG_C);},
1274                0x0D => {self.dec_r8(REG_C);},
1275                0x0E => {
1276                    let num = self.aux_read_immediate_data(ram);
1277                    self.ld_r8_8(REG_C, num);
1278                },
1279                0x0F => {self.rrca();},
1280                0x10 => {self.stop();},
1281                0x11 => {
1282                    let lsh = self.aux_read_immediate_data(ram);
1283                    let msh = self.aux_read_immediate_data(ram);
1284                    self.ld_r16_16(REG_D, REG_E, msh, lsh);
1285                },
1286                0x12 => {self.ld_r16a_r8(ram, REG_D, REG_E, REG_A);},
1287                0x13 => {self.inc_r16(REG_D, REG_E);},
1288                0x14 => {self.inc_r8(REG_D);},
1289                0x15 => {self.dec_r8(REG_D);},
1290                0x16 => {
1291                    let num = self.aux_read_immediate_data(ram);
1292                    self.ld_r8_8(REG_D, num);
1293                },
1294                0x17 => {self.rla();},
1295                0x18 => {
1296                    let immediate = self.aux_read_immediate_data(ram) as i8;
1297                    self.jr_i8(immediate);
1298                },
1299                0x19 => {self.add_r16_r16(REG_H, REG_L, REG_D, REG_E);},
1300                0x1A => {self.ld_r8_r16a(ram, REG_A, REG_D, REG_E);},
1301                0x1B => {self.dec_r16(REG_D, REG_E);},
1302                0x1C => {self.inc_r8(REG_E);},
1303                0x1D => {self.dec_r8(REG_E);},
1304                0x1E => {
1305                    let num = self.aux_read_immediate_data(ram);
1306                    self.ld_r8_8(REG_E, num);
1307                },
1308                0x1F => {self.rra();},
1309                0x20 => {
1310                    let immediate = self.aux_read_immediate_data(ram) as i8;
1311                    self.jr_nflag_i8(FLAG_Z, immediate);
1312                },
1313                0x21 => {
1314                    let lsh = self.aux_read_immediate_data(ram);
1315                    let msh = self.aux_read_immediate_data(ram);
1316                    self.ld_r16_16(REG_H, REG_L, msh, lsh);
1317                },
1318                0x22 => {
1319                    self.ld_r16a_r8(ram, REG_H, REG_L, REG_A);
1320                    self.inc_r16(REG_H, REG_L);
1321                },
1322                0x23 => {self.inc_r16(REG_H, REG_L);},
1323                0x24 => {self.inc_r8(REG_H);},
1324                0x25 => {self.dec_r8(REG_H);},
1325                0x26 => {
1326                    let num = self.aux_read_immediate_data(ram);
1327                    self.ld_r8_8(REG_H, num);
1328                },
1329                0x27 => {self.daa();},
1330                0x28 => {
1331                    let immediate = self.aux_read_immediate_data(ram) as i8;
1332                    self.jr_flag_i8(FLAG_Z, immediate);
1333                },
1334                0x29 => {self.add_r16_r16(REG_H, REG_L, REG_H, REG_L)},
1335                0x2A => {
1336                    self.ld_r8_r16a(ram, REG_A, REG_H, REG_L);
1337                    self.inc_r16(REG_H, REG_L);
1338                },
1339                0x2B => {self.dec_r16(REG_H, REG_L);},
1340                0x2C => {self.inc_r8(REG_L);},
1341                0x2D => {self.dec_r8(REG_L);},
1342                0x2E => {
1343                    let num = self.aux_read_immediate_data(ram);
1344                    self.ld_r8_8(REG_L, num);
1345                },
1346                0x2F => {self.cpl();},
1347                0x30 => {
1348                    let immediate = self.aux_read_immediate_data(ram) as i8;
1349                    self.jr_nflag_i8(FLAG_C, immediate);
1350                },
1351                0x31 => {
1352                    let lsh = self.aux_read_immediate_data(ram);
1353                    let msh = self.aux_read_immediate_data(ram);
1354                    self.ld_sp_16( msh, lsh);
1355                },
1356                0x32 => {
1357                    self.ld_r16a_r8(ram, REG_H, REG_L, REG_A);
1358                    self.dec_r16(REG_H, REG_L);
1359                },
1360                0x33 => {self.inc_sp();},
1361                0x34 => {self.inc_r16a(ram, REG_H, REG_L);},
1362                0x35 => {self.dec_r16a(ram, REG_H, REG_L);},
1363                0x36 => {
1364                    let num = self.aux_read_immediate_data(ram);
1365                    self.ld_r16a_8(ram, REG_H, REG_L, num);
1366                },
1367                0x37 => {self.scf();},
1368                0x38 => {
1369                    let immediate = self.aux_read_immediate_data(ram) as i8;
1370                    self.jr_flag_i8(FLAG_C, immediate);
1371                },
1372                0x39 => {self.add_r16_sp(REG_H, REG_L);},
1373                0x3A => {
1374                    self.ld_r8_r16a(ram, REG_A, REG_H, REG_L);
1375                    self.dec_r16(REG_H, REG_L);
1376                },
1377                0x3B => {self.dec_sp();},
1378                0x3C => {self.inc_r8(REG_A);},
1379                0x3D => {self.dec_r8(REG_A);},
1380                0x3E => {
1381                    let num = self.aux_read_immediate_data(ram);
1382                    self.ld_r8_8(REG_A, num);
1383                },
1384                0x3F => {self.ccf();},
1385                0x40 => {self.ld_r8_r8(REG_B, REG_B);},
1386                0x41 => {self.ld_r8_r8(REG_B, REG_C);},
1387                0x42 => {self.ld_r8_r8(REG_B, REG_D);},
1388                0x43 => {self.ld_r8_r8(REG_B, REG_E);},
1389                0x44 => {self.ld_r8_r8(REG_B, REG_H);},
1390                0x45 => {self.ld_r8_r8(REG_B, REG_L);},
1391                0x46 => {self.ld_r8_r16a(ram, REG_B, REG_H, REG_L);},
1392                0x47 => {self.ld_r8_r8(REG_B, REG_A);},
1393                0x48 => {self.ld_r8_r8(REG_C, REG_B);},
1394                0x49 => {self.ld_r8_r8(REG_C, REG_C);},
1395                0x4A => {self.ld_r8_r8(REG_C, REG_D);},
1396                0x4B => {self.ld_r8_r8(REG_C, REG_E);},
1397                0x4C => {self.ld_r8_r8(REG_C, REG_H);},
1398                0x4D => {self.ld_r8_r8(REG_C, REG_L);},
1399                0x4E => {self.ld_r8_r16a(ram, REG_C, REG_H, REG_L);},
1400                0x4F => {self.ld_r8_r8(REG_C, REG_A);},
1401                0x50 => {self.ld_r8_r8(REG_D, REG_B);},
1402                0x51 => {self.ld_r8_r8(REG_D, REG_C);},
1403                0x52 => {self.ld_r8_r8(REG_D, REG_D);},
1404                0x53 => {self.ld_r8_r8(REG_D, REG_E);},
1405                0x54 => {self.ld_r8_r8(REG_D, REG_H);},
1406                0x55 => {self.ld_r8_r8(REG_D, REG_L);},
1407                0x56 => {self.ld_r8_r16a(ram, REG_D, REG_H, REG_L);},
1408                0x57 => {self.ld_r8_r8(REG_D, REG_A);},
1409                0x58 => {self.ld_r8_r8(REG_E, REG_B);},
1410                0x59 => {self.ld_r8_r8(REG_E, REG_C);},
1411                0x5A => {self.ld_r8_r8(REG_E, REG_D);},
1412                0x5B => {self.ld_r8_r8(REG_E, REG_E);},
1413                0x5C => {self.ld_r8_r8(REG_E, REG_H);},
1414                0x5D => {self.ld_r8_r8(REG_E, REG_L);},
1415                0x5E => {self.ld_r8_r16a(ram, REG_E, REG_H, REG_L);},
1416                0x5F => {self.ld_r8_r8(REG_E, REG_A);},
1417                0x60 => {self.ld_r8_r8(REG_H, REG_B);},
1418                0x61 => {self.ld_r8_r8(REG_H, REG_C);},
1419                0x62 => {self.ld_r8_r8(REG_H, REG_D);},
1420                0x63 => {self.ld_r8_r8(REG_H, REG_E);},
1421                0x64 => {self.ld_r8_r8(REG_H, REG_H);},
1422                0x65 => {self.ld_r8_r8(REG_H, REG_L);},
1423                0x66 => {self.ld_r8_r16a(ram, REG_H, REG_H, REG_L);},
1424                0x67 => {self.ld_r8_r8(REG_H, REG_A);},
1425                0x68 => {self.ld_r8_r8(REG_L, REG_B);},
1426                0x69 => {self.ld_r8_r8(REG_L, REG_C);},
1427                0x6A => {self.ld_r8_r8(REG_L, REG_D);},
1428                0x6B => {self.ld_r8_r8(REG_L, REG_E);},
1429                0x6C => {self.ld_r8_r8(REG_L, REG_H);},
1430                0x6D => {self.ld_r8_r8(REG_L, REG_L);},
1431                0x6E => {self.ld_r8_r16a(ram, REG_L, REG_H, REG_L);},
1432                0x6F => {self.ld_r8_r8(REG_L, REG_A);},
1433                0x70 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_B);},
1434                0x71 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_C);},
1435                0x72 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_D);},
1436                0x73 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_E);},
1437                0x74 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_H);},
1438                0x75 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_L);},
1439                0x76 => {self.halt();},
1440                0x77 => {self.ld_r16a_r8(ram, REG_H, REG_L, REG_A);},
1441                0x78 => {self.ld_r8_r8(REG_A, REG_B);},
1442                0x79 => {self.ld_r8_r8(REG_A, REG_C);},
1443                0x7A => {self.ld_r8_r8(REG_A, REG_D);},
1444                0x7B => {self.ld_r8_r8(REG_A, REG_E);},
1445                0x7C => {self.ld_r8_r8(REG_A, REG_H);},
1446                0x7D => {self.ld_r8_r8(REG_A, REG_L);},
1447                0x7E => {self.ld_r8_r16a(ram, REG_A, REG_H, REG_L);},
1448                0x7F => {self.ld_r8_r8(REG_A, REG_A);},
1449                0x80 => {self.add_r8_r8(REG_A, REG_B);},
1450                0x81 => {self.add_r8_r8(REG_A, REG_C);},
1451                0x82 => {self.add_r8_r8(REG_A, REG_D);},
1452                0x83 => {self.add_r8_r8(REG_A, REG_E);},
1453                0x84 => {self.add_r8_r8(REG_A, REG_H);},
1454                0x85 => {self.add_r8_r8(REG_A, REG_L);},
1455                0x86 => {self.add_r8_r16a(ram, REG_A, REG_H, REG_L);},
1456                0x87 => {self.add_r8_r8(REG_A, REG_A);},
1457                0x88 => {self.adc_r8_r8(REG_A, REG_B);},
1458                0x89 => {self.adc_r8_r8(REG_A, REG_C);},
1459                0x8A => {self.adc_r8_r8(REG_A, REG_D);},
1460                0x8B => {self.adc_r8_r8(REG_A, REG_E);},
1461                0x8C => {self.adc_r8_r8(REG_A, REG_H);},
1462                0x8D => {self.adc_r8_r8(REG_A, REG_L);},
1463                0x8E => {self.adc_r8_r16a(ram, REG_A, REG_H, REG_L);},
1464                0x8F => {self.adc_r8_r8(REG_A, REG_A);},
1465                0x90 => {self.sub_r8_r8(REG_A, REG_B);},
1466                0x91 => {self.sub_r8_r8(REG_A, REG_C);},
1467                0x92 => {self.sub_r8_r8(REG_A, REG_D);},
1468                0x93 => {self.sub_r8_r8(REG_A, REG_E);},
1469                0x94 => {self.sub_r8_r8(REG_A, REG_H);},
1470                0x95 => {self.sub_r8_r8(REG_A, REG_L);},
1471                0x96 => {self.sub_r8_r16a(ram, REG_A, REG_H, REG_L);},
1472                0x97 => {self.sub_r8_r8(REG_A, REG_A);},
1473                0x98 => {self.sbc_r8_r8(REG_A, REG_B);},
1474                0x99 => {self.sbc_r8_r8(REG_A, REG_C);},
1475                0x9A => {self.sbc_r8_r8(REG_A, REG_D);},
1476                0x9B => {self.sbc_r8_r8(REG_A, REG_E);},
1477                0x9C => {self.sbc_r8_r8(REG_A, REG_H);},
1478                0x9D => {self.sbc_r8_r8(REG_A, REG_L);},
1479                0x9E => {self.sbc_r8_r16a(ram, REG_A, REG_H, REG_L);},
1480                0x9F => {self.sbc_r8_r8(REG_A, REG_A);},
1481                0xA0 => {self.and_r8_r8(REG_A, REG_B);},
1482                0xA1 => {self.and_r8_r8(REG_A, REG_C);},
1483                0xA2 => {self.and_r8_r8(REG_A, REG_D);},
1484                0xA3 => {self.and_r8_r8(REG_A, REG_E);},
1485                0xA4 => {self.and_r8_r8(REG_A, REG_H);},
1486                0xA5 => {self.and_r8_r8(REG_A, REG_L);},
1487                0xA6 => {self.and_r8_r16a(ram, REG_A, REG_H, REG_L);},
1488                0xA7 => {self.and_r8_r8(REG_A, REG_A);},
1489                0xA8 => {self.xor_r8_r8(REG_A, REG_B);},
1490                0xA9 => {self.xor_r8_r8(REG_A, REG_C);},
1491                0xAA => {self.xor_r8_r8(REG_A, REG_D);},
1492                0xAB => {self.xor_r8_r8(REG_A, REG_E);},
1493                0xAC => {self.xor_r8_r8(REG_A, REG_H);},
1494                0xAD => {self.xor_r8_r8(REG_A, REG_L);},
1495                0xAE => {self.xor_r8_r16a(ram, REG_A, REG_H, REG_L);},
1496                0xAF => {self.xor_r8_r8(REG_A, REG_A);},
1497                0xB0 => {self.or_r8_r8(REG_A, REG_B);},
1498                0xB1 => {self.or_r8_r8(REG_A, REG_C);},
1499                0xB2 => {self.or_r8_r8(REG_A, REG_D);},
1500                0xB3 => {self.or_r8_r8(REG_A, REG_E);},
1501                0xB4 => {self.or_r8_r8(REG_A, REG_H);},
1502                0xB5 => {self.or_r8_r8(REG_A, REG_L);},
1503                0xB6 => {self.or_r8_r16a(ram, REG_A, REG_H, REG_L);},
1504                0xB7 => {self.or_r8_r8(REG_A, REG_A);},
1505                0xB8 => {self.cp_r8_r8(REG_A, REG_B);},
1506                0xB9 => {self.cp_r8_r8(REG_A, REG_C);},
1507                0xBA => {self.cp_r8_r8(REG_A, REG_D);},
1508                0xBB => {self.cp_r8_r8(REG_A, REG_E);},
1509                0xBC => {self.cp_r8_r8(REG_A, REG_H);},
1510                0xBD => {self.cp_r8_r8(REG_A, REG_L);},
1511                0xBE => {self.cp_r8_r16a(ram, REG_A, REG_H, REG_L);},
1512                0xBF => {self.cp_r8_r8(REG_A, REG_A);},
1513                0xC0 => {self.ret_nflag(ram, FLAG_Z);},
1514                0xC1 => {self.pop_r16(ram, REG_B, REG_C);},
1515                0xC2 => {
1516                    let lsh = self.aux_read_immediate_data(ram);
1517                    let msh = self.aux_read_immediate_data(ram);
1518                    self.jp_nflag_pc_16(FLAG_Z, msh, lsh);
1519                },
1520                0xC3 => {
1521                    let lsh = self.aux_read_immediate_data(ram);
1522                    let msh = self.aux_read_immediate_data(ram);
1523                    self.jp_pc_16(msh, lsh);
1524                },
1525                0xC4 => {
1526                    let lsh = self.aux_read_immediate_data(ram);
1527                    let msh = self.aux_read_immediate_data(ram);
1528                    self.call_nflag_16(ram, FLAG_Z, msh, lsh);
1529                },
1530                0xC5 => {self.push_r16(ram, REG_B, REG_C);},
1531                0xC6 => {
1532                    let num = self.aux_read_immediate_data(ram);
1533                    self.add_r8_8(REG_A, num);
1534                },
1535                0xC7 => {self.rst(ram, 0x00);},
1536                0xC8 => {self.ret_flag(ram, FLAG_Z);},
1537                0xC9 => {self.ret(ram);},
1538                0xCA => {
1539                    let lsh = self.aux_read_immediate_data(ram);
1540                    let msh = self.aux_read_immediate_data(ram);
1541                    self.jp_flag_pc_16(FLAG_Z, msh, lsh);
1542                },
1543                0xCB => {/*Prefix for the next instruction, handled earlier*/},
1544                0xCC => {
1545                    let lsh = self.aux_read_immediate_data(ram);
1546                    let msh = self.aux_read_immediate_data(ram);
1547                    self.call_flag_16(ram, FLAG_Z, msh, lsh);
1548                },
1549                0xCD => {let lsh = self.aux_read_immediate_data(ram);
1550                    let msh = self.aux_read_immediate_data(ram);
1551                    self.call_16(ram, msh, lsh);},
1552                0xCE => {
1553                    let num = self.aux_read_immediate_data(ram);
1554                    self.adc_r8_8(REG_A, num);
1555                },
1556                0xCF => {self.rst(ram, 0x08);},
1557                0xD0 => {self.ret_nflag(ram, FLAG_C);},
1558                0xD1 => {self.pop_r16(ram, REG_D, REG_E);},
1559                0xD2 => {
1560                    let lsh = self.aux_read_immediate_data(ram);
1561                    let msh = self.aux_read_immediate_data(ram);
1562                    self.jp_nflag_pc_16(FLAG_C, msh, lsh);
1563                },
1564                0xD3 => {self.invalid_instruction(0xD3);},
1565                0xD4 => {
1566                    let lsh = self.aux_read_immediate_data(ram);
1567                    let msh = self.aux_read_immediate_data(ram);
1568                    self.call_nflag_16(ram, FLAG_C, msh, lsh);
1569                },
1570                0xD5 => {self.push_r16(ram, REG_D, REG_E);},
1571                0xD6 => {
1572                    let num = self.aux_read_immediate_data(ram);
1573                    self.sub_r8_8(REG_A, num);
1574                },
1575                0xD7 => {self.rst(ram, 0x10);},
1576                0xD8 => {self.ret_flag(ram, FLAG_C);},
1577                0xD9 => {self.reti(ram);},
1578                0xDA => {
1579                    let lsh = self.aux_read_immediate_data(ram);
1580                    let msh = self.aux_read_immediate_data(ram);
1581                    self.jp_flag_pc_16(FLAG_C, msh, lsh);
1582                },
1583                0xDB => {self.invalid_instruction(0xDB);},
1584                0xDC => {
1585                    let lsh = self.aux_read_immediate_data(ram);
1586                    let msh = self.aux_read_immediate_data(ram);
1587                    self.call_flag_16(ram, FLAG_C, msh, lsh);
1588                },
1589                0xDD => {self.invalid_instruction(0xDD);},
1590                0xDE => {
1591                    let num = self.aux_read_immediate_data(ram);
1592                    self.sbc_r8_8(REG_A, num);
1593                },
1594                0xDF => {self.rst(ram, 0x18);},
1595                0xE0 => {
1596                    let lsh = self.aux_read_immediate_data(ram);
1597                    self.ld_16a_r8(ram, 0xFF, lsh, REG_A);
1598                },
1599                0xE1 => {self.pop_r16(ram, REG_H, REG_L);},
1600                0xE2 => {self.ld_16a_r8(ram, 0xFF, self.regs[REG_C], REG_A);},
1601                0xE3 => {self.invalid_instruction(0xE3);},
1602                0xE4 => {self.invalid_instruction(0xE4);},
1603                0xE5 => {self.push_r16(ram, REG_H, REG_L);},
1604                0xE6 => {
1605                    let num = self.aux_read_immediate_data(ram);
1606                    self.and_r8_8(REG_A, num);
1607                },
1608                0xE7 => {self.rst(ram, 0x20);},
1609                0xE8 => {
1610                    let immediate = self.aux_read_immediate_data(ram) as i8;
1611                    self.add_sp_i8(immediate);
1612                },
1613                0xE9 => {self.jp_pc_16(self.regs[REG_H], self.regs[REG_L]);},
1614                0xEA => {
1615                    let lsh = self.aux_read_immediate_data(ram);
1616                    let msh = self.aux_read_immediate_data(ram);
1617                    self.ld_16a_r8(ram, msh, lsh, REG_A);
1618                },
1619                0xEB => {self.invalid_instruction(0xEB);},
1620                0xEC => {self.invalid_instruction(0xEC);},
1621                0xED => {self.invalid_instruction(0xED);},
1622                0xEE => {
1623                    let num = self.aux_read_immediate_data(ram);
1624                    self.xor_r8_8(REG_A, num);
1625                },
1626                0xEF => {self.rst(ram, 0x28);},
1627                0xF0 => {
1628                    let lsh = self.aux_read_immediate_data(ram);
1629                    self.ld_r8_16a(ram, REG_A, 0xFF, lsh)
1630                },
1631                0xF1 => {self.pop_r16(ram, REG_A, REG_F);},
1632                0xF2 => {self.ld_r8_16a(ram, REG_A, 0xFF, self.regs[REG_C]);},
1633                0xF3 => {self.di();},
1634                0xF4 => {self.invalid_instruction(0xF4);},
1635                0xF5 => {self.push_r16(ram, REG_A, REG_F);},
1636                0xF6 => {
1637                    let num = self.aux_read_immediate_data(ram);
1638                    self.or_r8_8(REG_A, num);
1639                },
1640                0xF7 => {self.rst(ram, 0x30);},
1641                0xF8 => {
1642                    let immediate = self.aux_read_immediate_data(ram) as i8;
1643                    self.ld_hl_sp_plus(immediate);
1644                },
1645                0xF9 => {self.ld_sp_r16( REG_H, REG_L);},
1646                0xFA => {
1647                    let lsh = self.aux_read_immediate_data(ram);
1648                    let msh = self.aux_read_immediate_data(ram);
1649                    self.ld_r8_16a(ram, REG_A, msh, lsh);
1650                },
1651                0xFB => {self.ei();},
1652                0xFC => {self.invalid_instruction(0xFC);},
1653                0xFD => {self.invalid_instruction(0xFD);},
1654                0xFE => {
1655                    let num = self.aux_read_immediate_data(ram);
1656                    self.cp_r8_8(REG_A, num);
1657                },
1658                0xFF => {self.rst(ram, 0x38);}
1659            }
1660
1661            self.pc.current_instruction_cycles += ZERO_INSTRUCTION_TIME_TABLE[instruction as usize];
1662        }
1663        else
1664        {
1665            let cb_instruction = self.aux_read_immediate_data(ram);
1666
1667            // println!("Instruction: 0x{:02X?}, Program Counter: 0x{:02X?}", cb_instruction, self.pc.reg);
1668
1669            match cb_instruction //CB Prefix
1670            {
1671                0x00 => {self.rlc_r8(REG_B);},
1672                0x01 => {self.rlc_r8(REG_C);},
1673                0x02 => {self.rlc_r8(REG_D);},
1674                0x03 => {self.rlc_r8(REG_E);},
1675                0x04 => {self.rlc_r8(REG_H);},
1676                0x05 => {self.rlc_r8(REG_L);},
1677                0x06 => {self.rlc_r16a(ram, REG_H, REG_L);},
1678                0x07 => {self.rlc_r8(REG_A);},
1679                0x08 => {self.rrc_r8(REG_B);},
1680                0x09 => {self.rrc_r8(REG_C);},
1681                0x0A => {self.rrc_r8(REG_D);},
1682                0x0B => {self.rrc_r8(REG_E);},
1683                0x0C => {self.rrc_r8(REG_H);},
1684                0x0D => {self.rrc_r8(REG_L);},
1685                0x0E => {self.rrc_r16a(ram, REG_H, REG_L);},
1686                0x0F => {self.rrc_r8(REG_A);},
1687                0x10 => {self.rl_r8(REG_B);},
1688                0x11 => {self.rl_r8(REG_C);},
1689                0x12 => {self.rl_r8(REG_D);},
1690                0x13 => {self.rl_r8(REG_E);},
1691                0x14 => {self.rl_r8(REG_H);},
1692                0x15 => {self.rl_r8(REG_L);},
1693                0x16 => {self.rl_r16a(ram, REG_H, REG_L);},
1694                0x17 => {self.rl_r8(REG_A);},
1695                0x18 => {self.rr_r8(REG_B);},
1696                0x19 => {self.rr_r8(REG_C);},
1697                0x1A => {self.rr_r8(REG_D);},
1698                0x1B => {self.rr_r8(REG_E);},
1699                0x1C => {self.rr_r8(REG_H);},
1700                0x1D => {self.rr_r8(REG_L);},
1701                0x1E => {self.rr_r16a(ram, REG_H, REG_L);},
1702                0x1F => {self.rr_r8(REG_A);},
1703                0x20 => {self.sla_r8(REG_B);},
1704                0x21 => {self.sla_r8(REG_C);},
1705                0x22 => {self.sla_r8(REG_D);},
1706                0x23 => {self.sla_r8(REG_E);},
1707                0x24 => {self.sla_r8(REG_H);},
1708                0x25 => {self.sla_r8(REG_L);},
1709                0x26 => {self.sla_r16a(ram, REG_H, REG_L);},
1710                0x27 => {self.sla_r8(REG_A);},
1711                0x28 => {self.sra_r8(REG_B);},
1712                0x29 => {self.sra_r8(REG_C);},
1713                0x2A => {self.sra_r8(REG_D);},
1714                0x2B => {self.sra_r8(REG_E);},
1715                0x2C => {self.sra_r8(REG_H);},
1716                0x2D => {self.sra_r8(REG_L);},
1717                0x2E => {self.sra_r16a(ram, REG_H, REG_L);},
1718                0x2F => {self.sra_r8(REG_A);},
1719                0x30 => {self.swap_r8(REG_B);},
1720                0x31 => {self.swap_r8(REG_C);},
1721                0x32 => {self.swap_r8(REG_D);},
1722                0x33 => {self.swap_r8(REG_E);},
1723                0x34 => {self.swap_r8(REG_H);},
1724                0x35 => {self.swap_r8(REG_L);},
1725                0x36 => {self.swap_r16a(ram, REG_H, REG_L);},
1726                0x37 => {self.swap_r8(REG_A);},
1727                0x38 => {self.srl_r8(REG_B);},
1728                0x39 => {self.srl_r8(REG_C);},
1729                0x3A => {self.srl_r8(REG_D);},
1730                0x3B => {self.srl_r8(REG_E);},
1731                0x3C => {self.srl_r8(REG_H);},
1732                0x3D => {self.srl_r8(REG_L);},
1733                0x3E => {self.srl_r16a(ram, REG_H, REG_L);},
1734                0x3F => {self.srl_r8(REG_A);},
1735                0x40 => {self.bit_r8(0, REG_B);},
1736                0x41 => {self.bit_r8(0, REG_C);},
1737                0x42 => {self.bit_r8(0, REG_D);},
1738                0x43 => {self.bit_r8(0, REG_E);},
1739                0x44 => {self.bit_r8(0, REG_H);},
1740                0x45 => {self.bit_r8(0, REG_L);},
1741                0x46 => {self.bit_r16a(ram, 0, REG_H, REG_L);},
1742                0x47 => {self.bit_r8(0, REG_A);},
1743                0x48 => {self.bit_r8(1, REG_B);},
1744                0x49 => {self.bit_r8(1, REG_C);},
1745                0x4A => {self.bit_r8(1, REG_D);},
1746                0x4B => {self.bit_r8(1, REG_E);},
1747                0x4C => {self.bit_r8(1, REG_H);},
1748                0x4D => {self.bit_r8(1, REG_L);},
1749                0x4E => {self.bit_r16a(ram, 1, REG_H, REG_L);},
1750                0x4F => {self.bit_r8(1, REG_A);},
1751                0x50 => {self.bit_r8(2, REG_B);},
1752                0x51 => {self.bit_r8(2, REG_C);},
1753                0x52 => {self.bit_r8(2, REG_D);},
1754                0x53 => {self.bit_r8(2, REG_E);},
1755                0x54 => {self.bit_r8(2, REG_H);},
1756                0x55 => {self.bit_r8(2, REG_L);},
1757                0x56 => {self.bit_r16a(ram, 2, REG_H, REG_L);},
1758                0x57 => {self.bit_r8(2, REG_A);},
1759                0x58 => {self.bit_r8(3, REG_B);},
1760                0x59 => {self.bit_r8(3, REG_C);},
1761                0x5A => {self.bit_r8(3, REG_D);},
1762                0x5B => {self.bit_r8(3, REG_E);},
1763                0x5C => {self.bit_r8(3, REG_H);},
1764                0x5D => {self.bit_r8(3, REG_L);},
1765                0x5E => {self.bit_r16a(ram, 3, REG_H, REG_L);},
1766                0x5F => {self.bit_r8(3, REG_A);},
1767                0x60 => {self.bit_r8(4, REG_B);},
1768                0x61 => {self.bit_r8(4, REG_C);},
1769                0x62 => {self.bit_r8(4, REG_D);},
1770                0x63 => {self.bit_r8(4, REG_E);},
1771                0x64 => {self.bit_r8(4, REG_H);},
1772                0x65 => {self.bit_r8(4, REG_L);},
1773                0x66 => {self.bit_r16a(ram, 4, REG_H, REG_L);},
1774                0x67 => {self.bit_r8(4, REG_A);},
1775                0x68 => {self.bit_r8(5, REG_B);},
1776                0x69 => {self.bit_r8(5, REG_C);},
1777                0x6A => {self.bit_r8(5, REG_D);},
1778                0x6B => {self.bit_r8(5, REG_E);},
1779                0x6C => {self.bit_r8(5, REG_H);},
1780                0x6D => {self.bit_r8(5, REG_L);},
1781                0x6E => {self.bit_r16a(ram, 5, REG_H, REG_L);},
1782                0x6F => {self.bit_r8(5, REG_A);},
1783                0x70 => {self.bit_r8(6, REG_B);},
1784                0x71 => {self.bit_r8(6, REG_C);},
1785                0x72 => {self.bit_r8(6, REG_D);},
1786                0x73 => {self.bit_r8(6, REG_E);},
1787                0x74 => {self.bit_r8(6, REG_H);},
1788                0x75 => {self.bit_r8(6, REG_L);},
1789                0x76 => {self.bit_r16a(ram, 6, REG_H, REG_L);},
1790                0x77 => {self.bit_r8(6, REG_A);},
1791                0x78 => {self.bit_r8(7, REG_B);},
1792                0x79 => {self.bit_r8(7, REG_C);},
1793                0x7A => {self.bit_r8(7, REG_D);},
1794                0x7B => {self.bit_r8(7, REG_E);},
1795                0x7C => {self.bit_r8(7, REG_H);},
1796                0x7D => {self.bit_r8(7, REG_L);},
1797                0x7E => {self.bit_r16a(ram, 7, REG_H, REG_L);},
1798                0x7F => {self.bit_r8(7, REG_A);},
1799                0x80 => {self.res_r8(0, REG_B);},
1800                0x81 => {self.res_r8(0, REG_C);},
1801                0x82 => {self.res_r8(0, REG_D);},
1802                0x83 => {self.res_r8(0, REG_E);},
1803                0x84 => {self.res_r8(0, REG_H);},
1804                0x85 => {self.res_r8(0, REG_L);},
1805                0x86 => {self.res_r16a(ram, 0, REG_H, REG_L);},
1806                0x87 => {self.res_r8(0, REG_A);},
1807                0x88 => {self.res_r8(1, REG_B);},
1808                0x89 => {self.res_r8(1, REG_C);},
1809                0x8A => {self.res_r8(1, REG_D);},
1810                0x8B => {self.res_r8(1, REG_E);},
1811                0x8C => {self.res_r8(1, REG_H);},
1812                0x8D => {self.res_r8(1, REG_L);},
1813                0x8E => {self.res_r16a(ram, 1, REG_H, REG_L);},
1814                0x8F => {self.res_r8(1, REG_A);},
1815                0x90 => {self.res_r8(2, REG_B);},
1816                0x91 => {self.res_r8(2, REG_C);},
1817                0x92 => {self.res_r8(2, REG_D);},
1818                0x93 => {self.res_r8(2, REG_E);},
1819                0x94 => {self.res_r8(2, REG_H);},
1820                0x95 => {self.res_r8(2, REG_L);},
1821                0x96 => {self.res_r16a(ram, 2, REG_H, REG_L);},
1822                0x97 => {self.res_r8(2, REG_A);},
1823                0x98 => {self.res_r8(3, REG_B);},
1824                0x99 => {self.res_r8(3, REG_C);},
1825                0x9A => {self.res_r8(3, REG_D);},
1826                0x9B => {self.res_r8(3, REG_E);},
1827                0x9C => {self.res_r8(3, REG_H);},
1828                0x9D => {self.res_r8(3, REG_L);},
1829                0x9E => {self.res_r16a(ram, 3, REG_H, REG_L);},
1830                0x9F => {self.res_r8(3, REG_A);},
1831                0xA0 => {self.res_r8(4, REG_B);},
1832                0xA1 => {self.res_r8(4, REG_C);},
1833                0xA2 => {self.res_r8(4, REG_D);},
1834                0xA3 => {self.res_r8(4, REG_E);},
1835                0xA4 => {self.res_r8(4, REG_H);},
1836                0xA5 => {self.res_r8(4, REG_L);},
1837                0xA6 => {self.res_r16a(ram, 4, REG_H, REG_L);},
1838                0xA7 => {self.res_r8(4, REG_A);},
1839                0xA8 => {self.res_r8(5, REG_B);},
1840                0xA9 => {self.res_r8(5, REG_C);},
1841                0xAA => {self.res_r8(5, REG_D);},
1842                0xAB => {self.res_r8(5, REG_E);},
1843                0xAC => {self.res_r8(5, REG_H);},
1844                0xAD => {self.res_r8(5, REG_L);},
1845                0xAE => {self.res_r16a(ram, 5, REG_H, REG_L);},
1846                0xAF => {self.res_r8(5, REG_A);},
1847                0xB0 => {self.res_r8(6, REG_B);},
1848                0xB1 => {self.res_r8(6, REG_C);},
1849                0xB2 => {self.res_r8(6, REG_D);},
1850                0xB3 => {self.res_r8(6, REG_E);},
1851                0xB4 => {self.res_r8(6, REG_H);},
1852                0xB5 => {self.res_r8(6, REG_L);},
1853                0xB6 => {self.res_r16a(ram, 6, REG_H, REG_L);},
1854                0xB7 => {self.res_r8(6, REG_A);},
1855                0xB8 => {self.res_r8(7, REG_B);},
1856                0xB9 => {self.res_r8(7, REG_C);},
1857                0xBA => {self.res_r8(7, REG_D);},
1858                0xBB => {self.res_r8(7, REG_E);},
1859                0xBC => {self.res_r8(7, REG_H);},
1860                0xBD => {self.res_r8(7, REG_L);},
1861                0xBE => {self.res_r16a(ram, 7, REG_H, REG_L);},
1862                0xBF => {self.res_r8(7, REG_A);},
1863                0xC0 => {self.set_r8(0, REG_B);},
1864                0xC1 => {self.set_r8(0, REG_C);},
1865                0xC2 => {self.set_r8(0, REG_D);},
1866                0xC3 => {self.set_r8(0, REG_E);},
1867                0xC4 => {self.set_r8(0, REG_H);},
1868                0xC5 => {self.set_r8(0, REG_L);},
1869                0xC6 => {self.set_r16a(ram, 0, REG_H, REG_L);},
1870                0xC7 => {self.set_r8(0, REG_A);},
1871                0xC8 => {self.set_r8(1, REG_B);},
1872                0xC9 => {self.set_r8(1, REG_C);},
1873                0xCA => {self.set_r8(1, REG_D);},
1874                0xCB => {self.set_r8(1, REG_E);},
1875                0xCC => {self.set_r8(1, REG_H);},
1876                0xCD => {self.set_r8(1, REG_L);},
1877                0xCE => {self.set_r16a(ram, 1, REG_H, REG_L);},
1878                0xCF => {self.set_r8(1, REG_A);},
1879                0xD0 => {self.set_r8(2, REG_B);},
1880                0xD1 => {self.set_r8(2, REG_C);},
1881                0xD2 => {self.set_r8(2, REG_D);},
1882                0xD3 => {self.set_r8(2, REG_E);},
1883                0xD4 => {self.set_r8(2, REG_H);},
1884                0xD5 => {self.set_r8(2, REG_L);},
1885                0xD6 => {self.set_r16a(ram, 2, REG_H, REG_L);},
1886                0xD7 => {self.set_r8(2, REG_A);},
1887                0xD8 => {self.set_r8(3, REG_B);},
1888                0xD9 => {self.set_r8(3, REG_C);},
1889                0xDA => {self.set_r8(3, REG_D);},
1890                0xDB => {self.set_r8(3, REG_E);},
1891                0xDC => {self.set_r8(3, REG_H);},
1892                0xDD => {self.set_r8(3, REG_L);},
1893                0xDE => {self.set_r16a(ram, 3, REG_H, REG_L);},
1894                0xDF => {self.set_r8(3, REG_A);},
1895                0xE0 => {self.set_r8(4, REG_B);},
1896                0xE1 => {self.set_r8(4, REG_C);},
1897                0xE2 => {self.set_r8(4, REG_D);},
1898                0xE3 => {self.set_r8(4, REG_E);},
1899                0xE4 => {self.set_r8(4, REG_H);},
1900                0xE5 => {self.set_r8(4, REG_L);},
1901                0xE6 => {self.set_r16a(ram, 4, REG_H, REG_L);},
1902                0xE7 => {self.set_r8(4, REG_A);},
1903                0xE8 => {self.set_r8(5, REG_B);},
1904                0xE9 => {self.set_r8(5, REG_C);},
1905                0xEA => {self.set_r8(5, REG_D);},
1906                0xEB => {self.set_r8(5, REG_E);},
1907                0xEC => {self.set_r8(5, REG_H);},
1908                0xED => {self.set_r8(5, REG_L);},
1909                0xEE => {self.set_r16a(ram, 5, REG_H, REG_L);},
1910                0xEF => {self.set_r8(5, REG_A);},
1911                0xF0 => {self.set_r8(6, REG_B);},
1912                0xF1 => {self.set_r8(6, REG_C);},
1913                0xF2 => {self.set_r8(6, REG_D);},
1914                0xF3 => {self.set_r8(6, REG_E);},
1915                0xF4 => {self.set_r8(6, REG_H);},
1916                0xF5 => {self.set_r8(6, REG_L);},
1917                0xF6 => {self.set_r16a(ram, 6, REG_H, REG_L);},
1918                0xF7 => {self.set_r8(6, REG_A);},
1919                0xF8 => {self.set_r8(7, REG_B);},
1920                0xF9 => {self.set_r8(7, REG_C);},
1921                0xFA => {self.set_r8(7, REG_D);},
1922                0xFB => {self.set_r8(7, REG_E);},
1923                0xFC => {self.set_r8(7, REG_H);},
1924                0xFD => {self.set_r8(7, REG_L);},
1925                0xFE => {self.set_r16a(ram, 7, REG_H, REG_L);},
1926                0xFF => {self.set_r8(7, REG_A);}
1927            }
1928
1929            self.pc.current_instruction_cycles += CB_INSTRUCTION_TIME_TABLE[cb_instruction as usize];
1930        }
1931
1932        self.aux_inc_pc();
1933    }
1934
1935    fn invalid_instruction(&self, opcode: u8)
1936    {
1937        panic!("Tried to execute invalid instruction {:X?}", opcode);
1938    }
1939
1940    // regs: [u8;8],
1941    // sp: u16,
1942    // ram: Ram,
1943    // pc: ProgramCounter
1944    #[allow(dead_code)]
1945    fn aux_get_reg(&self, regnum: usize) -> u8 { self.regs[regnum] }
1946    #[allow(dead_code)]
1947    fn aux_get_sp(&self) -> u16 { self.sp }
1948    #[allow(dead_code)]
1949    fn aux_get_pc(&self) -> ProgramCounter { self.pc }
1950
1951}