intel8080/
cpu.rs

1use crate::bit;
2use crate::flags::Flags;
3use crate::bus::Bus;
4use crate::register::Registers;
5use std::time::SystemTime;
6
7mod snapshot;
8
9const CYCLES: [u8; 256] = [
10    4, 10, 7, 5, 5, 5, 7, 4, 4, 10, 7, 5, 5, 5, 7, 4, 4, 10, 7, 5, 5, 5, 7, 4, 4, 10, 7, 5, 5, 5,
11    7, 4, 4, 10, 16, 5, 5, 5, 7, 4, 4, 10, 16, 5, 5, 5, 7, 4, 4, 10, 13, 5, 10, 10, 10, 4, 4, 10,
12    13, 5, 5, 5, 7, 4, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5,
13    5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 5, 5, 5, 5, 5, 5, 7, 5, 7, 7, 7, 7, 7, 7, 7, 7, 5,
14    5, 5, 5, 5, 5, 7, 5, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4,
15    4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, 4,
16    4, 4, 4, 4, 4, 7, 4, 5, 10, 10, 10, 11, 11, 7, 11, 5, 10, 10, 10, 11, 17, 7, 11, 5, 10, 10, 10,
17    11, 11, 7, 11, 5, 10, 10, 10, 11, 17, 7, 11, 5, 10, 10, 18, 11, 11, 7, 11, 5, 5, 10, 5, 11, 17,
18    7, 11, 5, 10, 10, 4, 11, 11, 7, 11, 5, 5, 10, 4, 11, 17, 7, 11,
19];
20
21pub struct Debug {
22    /// Enables / Disables the debug string generation
23    pub switch: bool,
24    /// Debug for IO messages
25    pub io: bool,
26    /// The debug information string
27    pub string: String,
28}
29
30pub struct CPU {
31    pub reg: Registers,
32    pub flags: Flags,
33    pub pc: u16,
34    pub sp: u16,
35    pub bus: Bus,
36    pub halt: bool,
37    /// Interrupt request : true / false, instruction to execute (normally a RST command)
38    pub int: (bool, u8),
39    /// Interrupt enable bit
40    pub inte: bool,
41    /// Outputs CPU state and disassembled code to stdout after each execute()
42    /// ```text
43    /// 3E 0f     MVI A,$0f
44    /// PC : 0x0003	SP : 0xff00	S : 0	Z : 0	A : 0	P : 0	C : 0
45    /// B : 0x00	C : 0x00	D : 0x00	E : 0x00	H : 0x00	L : 0x00 ...
46    /// ```
47    pub debug: Debug,
48    // Defaults to 1/60FPS = 16ms
49    slice_duration: u32,
50    // Defaults to 35000 cycles per 16ms slice (2.1 Mhz).
51    // cycles = clock speed in Hz / required frames-per-second
52    slice_max_cycles: u32,
53    slice_current_cycles: u32,
54    slice_start_time: SystemTime,
55}
56
57impl Debug {
58    pub fn new() -> Debug {
59        Debug {
60            switch: false,
61            io: false,
62            string: String::new(),
63        }
64    }
65}
66
67impl CPU {
68    /// Creates a new CPU instance and its 16 bits address bus.
69    pub fn new(size: u16) -> CPU {
70        CPU {
71            reg: Registers::new(),
72            flags: Flags::new(),
73            pc: 0,
74            sp: 0,
75            bus: Bus::new(size),
76            halt: false,
77            int: (false, 0),
78            inte: false,
79            debug: Debug::new(),
80            slice_duration: 16,
81            slice_max_cycles: 35000,
82            slice_current_cycles: 0,
83            slice_start_time: SystemTime::now(),
84        }
85    }
86
87    // Increment functions
88    fn inr(&mut self, n: u8) -> u8 {
89        let r = n.wrapping_add(1);
90        self.flags.z = r == 0x00;
91        self.flags.s = bit::get(r, 7);
92        self.flags.p = r.count_ones() & 0x01 == 0x00;
93        self.flags.a = (n & 0x0f) + 0x01 > 0x0f;
94        r
95    }
96
97    // Decrement functions
98    fn dcr(&mut self, n: u8) -> u8 {
99        let r = n.wrapping_sub(1);
100        self.flags.z = r == 0x00;
101        self.flags.s = bit::get(r, 7);
102        self.flags.p = r.count_ones() & 0x01 == 0x00;
103        self.flags.a = (r & 0x0f) != 0x0f;
104        r
105    }
106
107    // ADD register or memory to Accumulator
108    fn add(&mut self, n: u8) {
109        let a = self.reg.a;
110        let r = a.wrapping_add(n);
111        self.flags.z = r == 0x00;
112        self.flags.s = bit::get(r, 7);
113        self.flags.p = r.count_ones() & 0x01 == 0x00;
114        self.flags.a = (a & 0x0f) + (n & 0x0f) > 0x0f;
115        self.flags.c = u16::from(a) + u16::from(n) > 0xff;
116        self.reg.a = r;
117    }
118
119    // ADD register or memory to Accumulator with carry
120    fn adc(&mut self, n: u8) {
121        let c: u8 = match self.flags.c {
122            false => 0,
123            true => 1,
124        };
125        let a = self.reg.a;
126        let r = a.wrapping_add(n).wrapping_add(c);
127        self.flags.z = r == 0x00;
128        self.flags.s = bit::get(r, 7);
129        self.flags.p = r.count_ones() & 0x01 == 0x00;
130        self.flags.a = (a & 0x0f) + (n & 0x0f) + c > 0x0f;
131        self.flags.c = u16::from(a) + u16::from(n) + u16::from(c) > 0xff;
132        self.reg.a = r;
133    }
134
135    // SUB register or memory from Accumulator
136    fn sub(&mut self, n: u8) {
137        let a = self.reg.a;
138        let r = a.wrapping_sub(n);
139        self.flags.z = r == 0x00;
140        self.flags.s = bit::get(r, 7);
141        self.flags.p = r.count_ones() & 0x01 == 0x00;
142        self.flags.a = (a as i8 & 0x0f) - (n as i8 & 0x0f) >= 0x00;
143        self.flags.c = u16::from(a) < u16::from(n);
144        self.reg.a = r;
145    }
146
147    // SBB register or memory from Accumulator with borrow
148    fn sbb(&mut self, n: u8) {
149        let c: u8 = match self.flags.c {
150            false => 0,
151            true => 1,
152        };
153        let a = self.reg.a;
154        let r = a.wrapping_sub(n.wrapping_add(c));
155        self.flags.z = r == 0x00;
156        self.flags.s = bit::get(r, 7);
157        self.flags.p = r.count_ones() & 0x01 == 0x00;
158        self.flags.a = (a as i8 & 0x0f) - (n as i8 & 0x0f) - (c as i8) >= 0x00;
159        self.flags.c = u16::from(a) < u16::from(n) + u16::from(c);
160        self.reg.a = r;
161    }
162
163    // ANA Logical AND register or memory with accumulator
164    fn ana(&mut self, n: u8) {
165        let r = self.reg.a & n;
166        self.flags.z = r == 0x00;
167        self.flags.s = bit::get(r, 7);
168        self.flags.p = r.count_ones() & 0x01 == 0x00;
169        self.flags.a = (n | self.reg.a) & 0x08 != 0;
170        self.flags.c = false;
171        self.reg.a = r;
172    }
173
174    // XRA Logical Exclusive-OR register or memory with accumulator
175    fn xra(&mut self, n: u8) {
176        let a = self.reg.a;
177        let r = a ^ n;
178        self.flags.z = r == 0x00;
179        self.flags.s = bit::get(r, 7);
180        self.flags.p = r.count_ones() & 0x01 == 0x00;
181        self.flags.c = false;
182        self.flags.a = false;
183        self.reg.a = r;
184    }
185
186    // ORA Logical AND register or memory with accumulator
187    fn ora(&mut self, n: u8) {
188        let r = self.reg.a | n;
189        self.flags.z = r == 0x00;
190        self.flags.s = bit::get(r, 7);
191        self.flags.p = r.count_ones() & 0x01 == 0x00;
192        self.flags.c = false;
193        self.flags.a = false;
194        self.reg.a = r;
195    }
196
197    // CMP Compare register or memory with accumulator
198    fn cmp(&mut self, n: u8) {
199        let r = self.reg.a;
200        self.sub(n);
201        self.reg.a = r;
202    }
203
204    // Rotate accumulator left
205    fn rlc(&mut self) {
206        self.flags.c = bit::get(self.reg.a, 7);
207        self.reg.a = (self.reg.a << 1) | u8::from(self.flags.c);
208    }
209
210    // Rotate accumulator right
211    fn rrc(&mut self) {
212        self.flags.c = bit::get(self.reg.a, 0);
213        self.reg.a = if self.flags.c {
214            0x80 | (self.reg.a >> 1)
215        } else {
216            self.reg.a >> 1
217        };
218    }
219
220    // RAL Rotate accumulator left through carry
221    fn ral(&mut self) {
222        let c = self.flags.c;
223        self.flags.c = bit::get(self.reg.a, 7);
224        self.reg.a = match c {
225            true => (self.reg.a << 1) | 0x01,
226            false => self.reg.a << 1,
227        }
228    }
229
230    // RAR Rotate accumulator right through carry
231    fn rar(&mut self) {
232        let c = self.flags.c;
233        self.flags.c = bit::get(self.reg.a, 0);
234        self.reg.a = match c {
235            true => (self.reg.a >> 1) | 0x80,
236            false => self.reg.a >> 1,
237        }
238    }
239
240    // DAD Double add
241    fn dad(&mut self, n: u16) {
242        let h = self.reg.get_hl();
243        let r = h.wrapping_add(n);
244        self.reg.set_hl(r);
245        self.flags.c = u32::from(h) + u32::from(n) > 0xffff;
246    }
247
248    // XCHG Exchange reg
249    fn xchg(&mut self) {
250        let d = self.reg.d;
251        let e = self.reg.e;
252        let h = self.reg.h;
253        let l = self.reg.l;
254        self.reg.d = h;
255        self.reg.e = l;
256        self.reg.h = d;
257        self.reg.l = e;
258    }
259
260    // XTHL Exchange stack
261    fn xthl(&mut self) {
262        let pointed_by_sp = self.bus.read_word(self.sp);
263        let hl = self.reg.get_hl();
264        self.bus.write_word(self.sp, hl);
265        self.reg.set_hl(pointed_by_sp);
266    }
267
268    // Decimal adjust accumulator
269    fn daa(&mut self) {
270        let mut inc_a: u8 = 0;
271        let mut c = self.flags.c;
272        let lsb = self.reg.a & 0x0F;
273        if (lsb > 9) || self.flags.a {
274            inc_a += 0x06;
275        }
276
277        let msb = self.reg.a >> 4;
278        if (msb > 9) || self.flags.c || (msb >= 9 && lsb > 9) {
279            inc_a += 0x60;
280            c = true;
281        }
282
283        self.add(inc_a);
284        self.flags.c = c;
285        self.flags.z = self.reg.a == 0x00;
286        self.flags.s = bit::get(self.reg.a, 7);
287        self.flags.p = self.reg.a.count_ones() & 0x01 == 0x00;
288    }
289
290    // subroutine stack push
291    fn subroutine_stack_push(&mut self) {
292        self.sp = self.sp.wrapping_sub(2);
293        self.bus.write_word(self.sp, self.pc.wrapping_add(3));
294    }
295
296    // subroutine stack pop
297    fn subroutine_stack_pop(&mut self) {
298        self.pc = self.bus.read_word(self.sp);
299        self.sp = self.sp.wrapping_add(2);
300    }
301
302    // interrupt stack push
303    fn interrupt_stack_push(&mut self) {
304        self.sp = self.sp.wrapping_sub(2);
305        self.bus.write_word(self.sp, self.pc);
306    }
307
308    /// Sets CPU frequency (MHz)
309    /// ```rust
310    /// use intel8080::cpu::CPU;
311    /// let mut c = CPU::new(0xFFFF);
312    /// c.set_freq(1.7);            // CPU will run at 1.7 Mhz
313    /// ```
314    pub fn set_freq(&mut self, f: f32) {
315        let cycles = (f * 1000000 as f32) / (1000 / self.slice_duration) as f32;
316        self.slice_max_cycles = cycles as u32;
317    }
318
319    /// Fetches and executes one instruction from (pc). Returns the sleep time when slice_max_cycles is reached.
320    pub fn execute_timed(&mut self) -> Option<u32> {
321        let mut sleep_time: Option<u32> = None;
322        if self.slice_current_cycles > self.slice_max_cycles {
323            self.slice_current_cycles = 0;
324            // d = time taken to execute the slice_max_cycles
325            if let Ok(d) = self.slice_start_time.elapsed() {
326                sleep_time = Some(self.slice_duration.saturating_sub(d.as_millis() as u32));
327                self.slice_start_time = SystemTime::now();
328            }
329        }
330        let cycles = self.execute();
331        self.slice_current_cycles += cycles;
332        sleep_time
333    }
334
335    /// Fetches and executes one instruction from (pc). Returns the number of consumed clock cycles. No execution speed limit.
336    pub fn execute(&mut self) -> u32 {
337        if self.halt {
338            return 0;
339        };
340
341        // Saving current PC for debug output
342        let pc = self.pc;
343
344        let opcode = match self.inte {
345            false => self.bus.read_byte(self.pc),
346            // interrupts enabled : is there a pending interrupt ?
347            true => match self.int.0 {
348                false => self.bus.read_byte(self.pc),
349                true => self.int.1,
350            },
351        };
352
353        let mut cycles = CYCLES[opcode as usize].into();
354
355        // if opcode is RST : is it called via an interrupt, or via the program ?
356        let direct_rst = if self.inte && self.int.0 { false } else { true };
357
358        // interrupts enable and pending interrupt : we disable interrupts and clear interrupt request
359        if self.inte && self.int.0 {
360            self.inte = false;
361            self.int = (false, 0);
362        }
363
364        match opcode {
365            /* Carry bit instructions */
366            0x3f => self.flags.c = !self.flags.c, // CMC
367            0x37 => self.flags.c = true,          // STC
368
369            /* Single register instructions */
370            // INR Increment Register or Memory
371            0x04 => self.reg.b = self.inr(self.reg.b), // INR B
372            0x0C => self.reg.c = self.inr(self.reg.c), // INR C
373            0x14 => self.reg.d = self.inr(self.reg.d), // INR D
374            0x1C => self.reg.e = self.inr(self.reg.e), // INR E
375            0x24 => self.reg.h = self.inr(self.reg.h), // INR H
376            0x2C => self.reg.l = self.inr(self.reg.l), // INR L
377            0x3C => self.reg.a = self.inr(self.reg.a), // INR A
378            0x34 => {
379                // INR (HL)
380                let addr = self.reg.get_hl();
381                let r = self.inr(self.bus.read_byte(addr));
382                self.bus.write_byte(addr, r);
383            }
384
385            // DCR Decrement Register or Memory
386            0x05 => self.reg.b = self.dcr(self.reg.b), // DCR B
387            0x0D => self.reg.c = self.dcr(self.reg.c), // DCR C
388            0x15 => self.reg.d = self.dcr(self.reg.d), // DCR D
389            0x1D => self.reg.e = self.dcr(self.reg.e), // DCR E
390            0x25 => self.reg.h = self.dcr(self.reg.h), // DCR H
391            0x2D => self.reg.l = self.dcr(self.reg.l), // DCR L
392            0x3D => self.reg.a = self.dcr(self.reg.a), // DCR A
393            0x35 => {
394                // DCR (HL)
395                let addr = self.reg.get_hl();
396                let r = self.dcr(self.bus.read_byte(addr));
397                self.bus.write_byte(addr, r);
398            }
399
400            // CMA Complement Accumulator
401            0x2F => self.reg.a = !self.reg.a, // CMA
402
403            // Decimal adjust accumulator
404            0x27 => self.daa(),
405
406            // NOP No Operation
407            0x00 => {} // NOP
408
409            // MOV Data transfer instructions
410            0x40 => {}                       // MOV B,B
411            0x41 => self.reg.b = self.reg.c, // MOV B,C
412            0x42 => self.reg.b = self.reg.d, // MOV B,D
413            0x43 => self.reg.b = self.reg.e, // MOV B,E
414            0x44 => self.reg.b = self.reg.h, // MOV B,H
415            0x45 => self.reg.b = self.reg.l, // MOV B,L
416            0x46 => {
417                // MOV B,(HL)
418                let addr = self.reg.get_hl();
419                self.reg.b = self.bus.read_byte(addr)
420            }
421            0x47 => self.reg.b = self.reg.a, // MOV B,A
422
423            0x48 => self.reg.c = self.reg.b, // MOV C,B                                                     // MOV B,B
424            0x49 => {}                       // MOV C,C
425            0x4A => self.reg.c = self.reg.d, // MOV C,D
426            0x4B => self.reg.c = self.reg.e, // MOV C,E
427            0x4C => self.reg.c = self.reg.h, // MOV C,H
428            0x4D => self.reg.c = self.reg.l, // MOV C,L
429            0x4E => {
430                // MOV C,(HL)
431                let addr = self.reg.get_hl();
432                self.reg.c = self.bus.read_byte(addr)
433            }
434            0x4F => self.reg.c = self.reg.a, // MOV C,A
435
436            0x50 => self.reg.d = self.reg.b, // MOV D,B                                                     // MOV B,B
437            0x51 => self.reg.d = self.reg.c, // MOV D,C
438            0x52 => {}                       // MOV D,D
439            0x53 => self.reg.d = self.reg.e, // MOV D,E
440            0x54 => self.reg.d = self.reg.h, // MOV D,H
441            0x55 => self.reg.d = self.reg.l, // MOV D,L
442            0x56 => {
443                // MOV D,(HL)
444                let addr = self.reg.get_hl();
445                self.reg.d = self.bus.read_byte(addr)
446            }
447            0x57 => self.reg.d = self.reg.a, // MOV D,A
448
449            0x58 => self.reg.e = self.reg.b, // MOV E,B                                                     // MOV B,B
450            0x59 => self.reg.e = self.reg.c, // MOV E,C
451            0x5A => self.reg.e = self.reg.d, // MOV E,D
452            0x5B => {}                       // MOV E,E
453            0x5C => self.reg.e = self.reg.h, // MOV E,H
454            0x5D => self.reg.e = self.reg.l, // MOV E,L
455            0x5E => {
456                // MOV E,(HL)
457                let addr = self.reg.get_hl();
458                self.reg.e = self.bus.read_byte(addr)
459            }
460            0x5F => self.reg.e = self.reg.a, // MOV E,A
461
462            0x60 => self.reg.h = self.reg.b, // MOV H,B                                                     // MOV B,B
463            0x61 => self.reg.h = self.reg.c, // MOV H,C
464            0x62 => self.reg.h = self.reg.d, // MOV H,D
465            0x63 => self.reg.h = self.reg.e, // MOV H,E
466            0x64 => {}                       // MOV H,H
467            0x65 => self.reg.h = self.reg.l, // MOV H,L
468            0x66 => {
469                // MOV H,(HL)
470                let addr = self.reg.get_hl();
471                self.reg.h = self.bus.read_byte(addr)
472            }
473            0x67 => self.reg.h = self.reg.a, // MOV H,A
474
475            0x68 => self.reg.l = self.reg.b, // MOV L,B                                                     // MOV B,B
476            0x69 => self.reg.l = self.reg.c, // MOV L,C
477            0x6A => self.reg.l = self.reg.d, // MOV L,D
478            0x6B => self.reg.l = self.reg.e, // MOV L,E
479            0x6C => self.reg.l = self.reg.h, // MOV L,H
480            0x6D => {}                       // MOV L,L
481            0x6E => {
482                // MOV L,(HL)
483                let addr = self.reg.get_hl();
484                self.reg.l = self.bus.read_byte(addr)
485            }
486            0x6F => self.reg.l = self.reg.a, // MOV L,A
487
488            0x70 => {
489                // MOV (HL), B
490                let addr = self.reg.get_hl();
491                self.bus.write_byte(addr, self.reg.b)
492            }
493            0x71 => {
494                // MOV (HL), C
495                let addr = self.reg.get_hl();
496                self.bus.write_byte(addr, self.reg.c)
497            }
498            0x72 => {
499                // MOV (HL), D
500                let addr = self.reg.get_hl();
501                self.bus.write_byte(addr, self.reg.d)
502            }
503            0x73 => {
504                // MOV (HL), E
505                let addr = self.reg.get_hl();
506                self.bus.write_byte(addr, self.reg.e)
507            }
508            0x74 => {
509                // MOV (HL), H
510                let addr = self.reg.get_hl();
511                self.bus.write_byte(addr, self.reg.h)
512            }
513            0x75 => {
514                // MOV (HL), L
515                let addr = self.reg.get_hl();
516                self.bus.write_byte(addr, self.reg.l)
517            }
518
519            0x76 => self.halt = true, // HLT
520
521            0x77 => {
522                // MOV (HL), A
523                let addr = self.reg.get_hl();
524                self.bus.write_byte(addr, self.reg.a)
525            }
526
527            0x78 => self.reg.a = self.reg.b, // MOV A,B                                                     // MOV B,B
528            0x79 => self.reg.a = self.reg.c, // MOV A,C
529            0x7A => self.reg.a = self.reg.d, // MOV A,D
530            0x7B => self.reg.a = self.reg.e, // MOV A,E
531            0x7C => self.reg.a = self.reg.h, // MOV A,H
532            0x7D => self.reg.a = self.reg.l, // MOV A,L
533            0x7E => {
534                // MOV A,(HL)
535                let addr = self.reg.get_hl();
536                self.reg.a = self.bus.read_byte(addr)
537            }
538            0x7F => {} // MOV A,A
539
540            // STAX Store accumulator
541            0x02 => {
542                // STAX B
543                let addr = self.reg.get_bc();
544                self.bus.write_byte(addr, self.reg.a)
545            }
546            0x12 => {
547                // STAX D
548                let addr = self.reg.get_de();
549                self.bus.write_byte(addr, self.reg.a)
550            }
551
552            // LDAX Load accumulator
553            0x0A => {
554                // LDAX B
555                let addr = self.reg.get_bc();
556                self.reg.a = self.bus.read_byte(addr)
557            }
558            0x1A => {
559                // LDAX D
560                let addr = self.reg.get_de();
561                self.reg.a = self.bus.read_byte(addr)
562            }
563
564            /* Register or Memory to Accumulator instructions*/
565            // ADD register or memory to accumulator
566            0x80 => self.add(self.reg.b), // ADD B
567            0x81 => self.add(self.reg.c), // ADD C
568            0x82 => self.add(self.reg.d), // ADD D
569            0x83 => self.add(self.reg.e), // ADD E
570            0x84 => self.add(self.reg.h), // ADD H
571            0x85 => self.add(self.reg.l), // ADD L
572            0x86 => {
573                // ADD (HL)
574                let addr = self.reg.get_hl();
575                let n = self.bus.read_byte(addr);
576                self.add(n)
577            }
578            0x87 => self.add(self.reg.a), // ADD A
579
580            // ADC Add register or memory to accumulator with carry
581            0x88 => self.adc(self.reg.b), // ADC B
582            0x89 => self.adc(self.reg.c), // ADC C
583            0x8A => self.adc(self.reg.d), // ADC D
584            0x8B => self.adc(self.reg.e), // ADC E
585            0x8C => self.adc(self.reg.h), // ADC H
586            0x8D => self.adc(self.reg.l), // ADC L
587            0x8E => {
588                // ADC (HL)
589                let addr = self.reg.get_hl();
590                let n = self.bus.read_byte(addr);
591                self.adc(n)
592            }
593            0x8F => self.adc(self.reg.a), // ADC A
594
595            // SUB Substract register or memory to accumulator
596            0x90 => self.sub(self.reg.b), // SUB B
597            0x91 => self.sub(self.reg.c), // SUB C
598            0x92 => self.sub(self.reg.d), // SUB D
599            0x93 => self.sub(self.reg.e), // SUB E
600            0x94 => self.sub(self.reg.h), // SUB H
601            0x95 => self.sub(self.reg.l), // SUB L
602            0x96 => {
603                // SUB (HL)
604                let addr = self.reg.get_hl();
605                let n = self.bus.read_byte(addr);
606                self.sub(n)
607            }
608            0x97 => self.sub(self.reg.a), // SUB A
609
610            // SBB Substract register or memory to accumulator with borrow
611            0x98 => self.sbb(self.reg.b), // SBB B
612            0x99 => self.sbb(self.reg.c), // SBB C
613            0x9A => self.sbb(self.reg.d), // SBB D
614            0x9B => self.sbb(self.reg.e), // SBB E
615            0x9C => self.sbb(self.reg.h), // SBB H
616            0x9D => self.sbb(self.reg.l), // SBB L
617            0x9E => {
618                // SBB (HL)
619                let addr = self.reg.get_hl();
620                let n = self.bus.read_byte(addr);
621                self.sbb(n)
622            }
623            0x9F => self.sbb(self.reg.a), // SBB A
624
625            // ANA Logical AND register or memory with accumulator
626            0xA0 => self.ana(self.reg.b), // ANA B
627            0xA1 => self.ana(self.reg.c), // ANA C
628            0xA2 => self.ana(self.reg.d), // ANA D
629            0xA3 => self.ana(self.reg.e), // ANA E
630            0xA4 => self.ana(self.reg.h), // ANA H
631            0xA5 => self.ana(self.reg.l), // ANA L
632            0xA6 => {
633                // ANA (HL)
634                let addr = self.reg.get_hl();
635                let n = self.bus.read_byte(addr);
636                self.ana(n)
637            }
638            0xA7 => self.ana(self.reg.a), // ANA A
639
640            // XRA Logical Exclusive-OR register or memory with accumulator
641            0xA8 => self.xra(self.reg.b), // XRA B
642            0xA9 => self.xra(self.reg.c), // XRA C
643            0xAA => self.xra(self.reg.d), // XRA D
644            0xAB => self.xra(self.reg.e), // XRA E
645            0xAC => self.xra(self.reg.h), // XRA H
646            0xAD => self.xra(self.reg.l), // XRA L
647            0xAE => {
648                // XNA (HL)
649                let addr = self.reg.get_hl();
650                let n = self.bus.read_byte(addr);
651                self.xra(n)
652            }
653            0xAF => self.xra(self.reg.a), // XRA A
654
655            // ORA Logical OR register or memory with accumulator
656            0xB0 => self.ora(self.reg.b), // ORA B
657            0xB1 => self.ora(self.reg.c), // ORA C
658            0xB2 => self.ora(self.reg.d), // ORA D
659            0xB3 => self.ora(self.reg.e), // ORA E
660            0xB4 => self.ora(self.reg.h), // ORA H
661            0xB5 => self.ora(self.reg.l), // ORA L
662            0xB6 => {
663                // ORA (HL)
664                let addr = self.reg.get_hl();
665                let n = self.bus.read_byte(addr);
666                self.ora(n)
667            }
668            0xB7 => self.ora(self.reg.a), // ORA A
669
670            // CMP Compare register or memory with accumulator
671            0xB8 => self.cmp(self.reg.b), // CMP B
672            0xB9 => self.cmp(self.reg.c), // CMP C
673            0xBA => self.cmp(self.reg.d), // CMP D
674            0xBB => self.cmp(self.reg.e), // CMP E
675            0xBC => self.cmp(self.reg.h), // CMP H
676            0xBD => self.cmp(self.reg.l), // CMP L
677            0xBE => {
678                // CMP (HL)
679                let addr = self.reg.get_hl();
680                let n = self.bus.read_byte(addr);
681                self.cmp(n)
682            }
683            0xBF => self.cmp(self.reg.a), // CMP A
684
685            /* Rotate accumulator instructions */
686            0x07 => self.rlc(), // RLC
687            0x0F => self.rrc(), // RRC
688            0x17 => self.ral(), // RAL
689            0x1F => self.rar(), // RAR
690
691            /* Register pair instructions */
692            // PUSH data onto stack
693            0xC5 => {
694                // PUSH B
695                self.sp = self.sp.wrapping_sub(2);
696                self.bus.write_word(self.sp, self.reg.get_bc());
697            }
698            0xD5 => {
699                // PUSH D
700                self.sp = self.sp.wrapping_sub(2);
701                self.bus.write_word(self.sp, self.reg.get_de());
702            }
703            0xE5 => {
704                // PUSH H
705                self.sp = self.sp.wrapping_sub(2);
706                self.bus.write_word(self.sp, self.reg.get_hl());
707            }
708            0xF5 => {
709                // PUSH PSW
710                self.sp = self.sp.wrapping_sub(2);
711                self.bus.write_byte(self.sp, self.flags.as_byte());
712                self.bus.write_byte(self.sp + 1, self.reg.a);
713            }
714
715            // POP data off stack
716            0xC1 => {
717                // POP B
718                self.reg.set_bc(self.bus.read_word(self.sp));
719                self.sp = self.sp.wrapping_add(2);
720            }
721
722            0xD1 => {
723                // POP D
724                self.reg.set_de(self.bus.read_word(self.sp));
725                self.sp = self.sp.wrapping_add(2);
726            }
727
728            0xE1 => {
729                // POP H
730                self.reg.set_hl(self.bus.read_word(self.sp));
731                self.sp = self.sp.wrapping_add(2);
732            }
733
734            0xF1 => {
735                // POP PSW
736                self.reg.a = self.bus.read_byte((self.sp) + 1);
737                let bflags = self.bus.read_byte(self.sp);
738                self.flags.from_byte(bflags);
739                self.sp = self.sp.wrapping_add(2);
740            }
741
742            // DAD Double add
743            0x09 => {
744                // DAD B
745                let reg = self.reg.get_bc();
746                self.dad(reg);
747            }
748            0x19 => {
749                // DAD D
750                let reg = self.reg.get_de();
751                self.dad(reg);
752            }
753            0x29 => {
754                // DAD H
755                let reg = self.reg.get_hl();
756                self.dad(reg);
757            }
758            0x39 => {
759                // DAD SP
760                let reg = self.sp;
761                self.dad(reg);
762            }
763
764            // INX Increment register pair
765            0x03 => {
766                // INX B
767                let mut b = self.reg.get_bc();
768                b = b.wrapping_add(1);
769                self.reg.set_bc(b);
770            }
771
772            0x13 => {
773                // INX D
774                let mut d = self.reg.get_de();
775                d = d.wrapping_add(1);
776                self.reg.set_de(d);
777            }
778
779            0x23 => {
780                // INX H
781                let mut h = self.reg.get_hl();
782                h = h.wrapping_add(1);
783                self.reg.set_hl(h);
784            }
785
786            0x33 => self.sp = self.sp.wrapping_add(1), // INX SP
787
788            // DCX Decrement register pair
789            0x0B => {
790                // DCX B
791                let mut b = self.reg.get_bc();
792                b = b.wrapping_sub(1);
793                self.reg.set_bc(b);
794            }
795
796            0x1B => {
797                // DCX D
798                let mut d = self.reg.get_de();
799                d = d.wrapping_sub(1);
800                self.reg.set_de(d);
801            }
802
803            0x2B => {
804                // DCX H
805                let mut h = self.reg.get_hl();
806                h = h.wrapping_sub(1);
807                self.reg.set_hl(h);
808            }
809
810            0x3B => self.sp = self.sp.wrapping_sub(1), // DCX SP
811
812            // XCHG Exchange reg
813            0xEB => self.xchg(),
814
815            // XTHL Exchange stack
816            0xE3 => self.xthl(),
817
818            // SPHL Load SP from H and L
819            0xF9 => self.sp = self.reg.get_hl(),
820
821            /* Immediate instructions */
822            // LXI Move immediate data
823            0x01 => {
824                // LXI B
825                let d16 = self.bus.read_word(self.pc + 1);
826                self.reg.set_bc(d16);
827            }
828            0x11 => {
829                // LXI D
830                let d16 = self.bus.read_word(self.pc + 1);
831                self.reg.set_de(d16);
832            }
833            0x21 => {
834                // LXI H
835                let d16 = self.bus.read_word(self.pc + 1);
836                self.reg.set_hl(d16);
837            }
838            0x31 => {
839                // LXI SP
840                let d16 = self.bus.read_word(self.pc + 1);
841                self.sp = d16;
842            }
843            // MVI Move immediate data
844            0x06 => {
845                // MVI B,d8
846                let d8 = self.bus.read_byte(self.pc + 1);
847                self.reg.b = d8;
848            }
849            0x0E => {
850                // MVI C,d8
851                let d8 = self.bus.read_byte(self.pc + 1);
852                self.reg.c = d8;
853            }
854            0x16 => {
855                // MVI D,d8
856                let d8 = self.bus.read_byte(self.pc + 1);
857                self.reg.d = d8;
858            }
859            0x1E => {
860                // MVI E,d8
861                let d8 = self.bus.read_byte(self.pc + 1);
862                self.reg.e = d8;
863            }
864            0x26 => {
865                // MVI H,d8
866                let d8 = self.bus.read_byte(self.pc + 1);
867                self.reg.h = d8;
868            }
869            0x2E => {
870                // MVI L,d8
871                let d8 = self.bus.read_byte(self.pc + 1);
872                self.reg.l = d8;
873            }
874            0x36 => {
875                // MVI (HL),d8
876                let d8 = self.bus.read_byte(self.pc + 1);
877                let addr = self.reg.get_hl();
878                self.bus.write_byte(addr, d8);
879            }
880            0x3E => {
881                // MVI A,d8
882                let d8 = self.bus.read_byte(self.pc + 1);
883                self.reg.a = d8;
884            }
885
886            // ADI add immediate to accumulator
887            0xC6 => {
888                // ADI
889                let n = self.bus.read_byte(self.pc + 1);
890                self.add(n);
891            }
892
893            // ACI add immediate to accumulator with carry
894            0xCE => {
895                // ACI
896                let n = self.bus.read_byte(self.pc + 1);
897                self.adc(n);
898            }
899
900            // SUI substract immediate from accumulator
901            0xD6 => {
902                // SUI
903                let n = self.bus.read_byte(self.pc + 1);
904                self.sub(n);
905            }
906
907            // SBI substract immediate from accumulator with borrow
908            0xDE => {
909                // SBI
910                let n = self.bus.read_byte(self.pc + 1);
911                self.sbb(n);
912            }
913
914            // ANI and immediate with accumulator
915            0xE6 => {
916                // ANI
917                let n = self.bus.read_byte(self.pc + 1);
918                self.ana(n);
919            }
920
921            // XRI exclusive-or immediate with accumulator
922            0xEE => {
923                // XRI
924                let n = self.bus.read_byte(self.pc + 1);
925                self.xra(n);
926            }
927
928            // ORI or immediate with accumulator
929            0xF6 => {
930                // ORI
931                let n = self.bus.read_byte(self.pc + 1);
932                self.ora(n);
933            }
934
935            // CPI compare immediate with accumulator
936            0xFE => {
937                // CPI
938                let n = self.bus.read_byte(self.pc + 1);
939                self.cmp(n);
940            }
941
942            /* Direct addressing instructions */
943            // STA Store accumulator direct
944            0x32 => {
945                // STA
946                let addr = self.bus.read_word(self.pc + 1);
947                self.bus.write_byte(addr, self.reg.a);
948            }
949
950            // LDA Store accumulator direct
951            0x3A => {
952                // LDA
953                let addr = self.bus.read_word(self.pc + 1);
954                self.reg.a = self.bus.read_byte(addr);
955            }
956
957            // SHLD Store H and L direct
958            0x22 => {
959                // SHLD
960                let d = self.reg.get_hl();
961                let addr = self.bus.read_word(self.pc + 1);
962                self.bus.write_word(addr, d);
963            }
964
965            // LHLD Load H and L direct
966            0x2A => {
967                // LHLD
968                let addr = self.bus.read_word(self.pc + 1);
969                let d = self.bus.read_word(addr);
970                self.reg.set_hl(d);
971            }
972
973            /* JUMP instructions */
974            // Load program counter
975            0xE9 => {
976                self.pc = self.reg.get_hl();
977            } // PCHL
978            // JMP Jump
979            0xC3 => {
980                // JMP
981                let addr = self.bus.read_word(self.pc + 1);
982                self.pc = addr;
983            }
984            // JC Jump if carry
985            0xDA => {
986                // JC
987                let addr = self.bus.read_word(self.pc + 1);
988                if self.flags.c {
989                    self.pc = addr;
990                } else {
991                    self.pc += 3
992                }
993            }
994            // JNC Jump if no carry
995            0xD2 => {
996                // JNC
997                let addr = self.bus.read_word(self.pc + 1);
998                if !self.flags.c {
999                    self.pc = addr;
1000                } else {
1001                    self.pc += 3
1002                }
1003            }
1004            // JZ Jump if zero
1005            0xCA => {
1006                // JZ
1007                let addr = self.bus.read_word(self.pc + 1);
1008                if self.flags.z {
1009                    self.pc = addr;
1010                } else {
1011                    self.pc += 3
1012                }
1013            }
1014            // JNZ Jump if not zero
1015            0xC2 => {
1016                // JNZ
1017                let addr = self.bus.read_word(self.pc + 1);
1018                if !self.flags.z {
1019                    self.pc = addr;
1020                } else {
1021                    self.pc += 3
1022                }
1023            }
1024            // JM Jump if minus
1025            0xFA => {
1026                // JM
1027                let addr = self.bus.read_word(self.pc + 1);
1028                if self.flags.s {
1029                    self.pc = addr;
1030                } else {
1031                    self.pc += 3
1032                }
1033            }
1034            // JP Jump if positive
1035            0xF2 => {
1036                // JP
1037                let addr = self.bus.read_word(self.pc + 1);
1038                if !self.flags.s {
1039                    self.pc = addr;
1040                } else {
1041                    self.pc += 3
1042                }
1043            }
1044            // JPE Jump if parity even
1045            0xEA => {
1046                // JPE
1047                let addr = self.bus.read_word(self.pc + 1);
1048                if self.flags.p {
1049                    self.pc = addr;
1050                } else {
1051                    self.pc += 3
1052                }
1053            }
1054            // JPO Jump if parity odd
1055            0xE2 => {
1056                // JPO
1057                let addr = self.bus.read_word(self.pc + 1);
1058                if !self.flags.p {
1059                    self.pc = addr;
1060                } else {
1061                    self.pc += 3
1062                }
1063            }
1064
1065            /* Call subroutine instructions */
1066            // CALL
1067            0xCD => {
1068                // CALL
1069                let addr = self.bus.read_word(self.pc + 1);
1070                self.subroutine_stack_push();
1071                self.pc = addr;
1072            }
1073            // CC Call if carry
1074            0xDC => {
1075                // CC
1076                let addr = self.bus.read_word(self.pc + 1);
1077                if self.flags.c {
1078                    self.subroutine_stack_push();
1079                    self.pc = addr;
1080                } else {
1081                    self.pc += 3
1082                }
1083            }
1084            // CNC Call if no carry
1085            0xD4 => {
1086                // CNC
1087                let addr = self.bus.read_word(self.pc + 1);
1088                if !self.flags.c {
1089                    self.subroutine_stack_push();
1090                    self.pc = addr;
1091                    cycles += 6;
1092                } else {
1093                    self.pc += 3
1094                }
1095            }
1096            // CZ Call if zero
1097            0xCC => {
1098                // CZ
1099                let addr = self.bus.read_word(self.pc + 1);
1100                if self.flags.z {
1101                    self.subroutine_stack_push();
1102                    self.pc = addr;
1103                    cycles += 6;
1104                } else {
1105                    self.pc += 3
1106                }
1107            }
1108            // CNZ Call if not zero
1109            0xC4 => {
1110                // CNZ
1111                let addr = self.bus.read_word(self.pc + 1);
1112                if !self.flags.z {
1113                    self.subroutine_stack_push();
1114                    self.pc = addr;
1115                    cycles += 6;
1116                } else {
1117                    self.pc += 3
1118                }
1119            }
1120            // CM Call if minus
1121            0xFC => {
1122                // CM
1123                let addr = self.bus.read_word(self.pc + 1);
1124                if self.flags.s {
1125                    self.subroutine_stack_push();
1126                    self.pc = addr;
1127                    cycles += 6;
1128                } else {
1129                    self.pc += 3
1130                }
1131            }
1132            // CP Call if plus
1133            0xF4 => {
1134                // CP
1135                let addr = self.bus.read_word(self.pc + 1);
1136                if !self.flags.s {
1137                    self.subroutine_stack_push();
1138                    self.pc = addr;
1139                    cycles += 6;
1140                } else {
1141                    self.pc += 3
1142                }
1143            }
1144            // CPE Call if parity even
1145            0xEC => {
1146                // CPE
1147                let addr = self.bus.read_word(self.pc + 1);
1148                if self.flags.p {
1149                    self.subroutine_stack_push();
1150                    self.pc = addr;
1151                    cycles += 6;
1152                } else {
1153                    self.pc += 3
1154                }
1155            }
1156            // CPO Call if parity odd
1157            0xE4 => {
1158                // CPO
1159                let addr = self.bus.read_word(self.pc + 1);
1160                if !self.flags.p {
1161                    self.subroutine_stack_push();
1162                    self.pc = addr;
1163                    cycles += 6;
1164                } else {
1165                    self.pc += 3
1166                }
1167            }
1168
1169            /* Return from subroutine instructions */
1170            // RET Return
1171            0xC9 => self.subroutine_stack_pop(), // RET
1172            // RC Return if carry
1173            0xD8 => {
1174                if self.flags.c {
1175                    self.subroutine_stack_pop();
1176                    cycles += 6;
1177                } else {
1178                    self.pc += 1;
1179                }
1180            } // RC
1181            // RNC Return if no carry
1182            0xD0 => {
1183                if !self.flags.c {
1184                    self.subroutine_stack_pop();
1185                    cycles += 6;
1186                } else {
1187                    self.pc += 1;
1188                }
1189            } // RNC
1190            // RZ Return if zero
1191            0xC8 => {
1192                if self.flags.z {
1193                    self.subroutine_stack_pop();
1194                    cycles += 6;
1195                } else {
1196                    self.pc += 1;
1197                }
1198            } // RZ
1199            // RNZ Return if not zero
1200            0xC0 => {
1201                if !self.flags.z {
1202                    self.subroutine_stack_pop();
1203                    cycles += 6;
1204                } else {
1205                    self.pc += 1;
1206                }
1207            } // RNZ
1208            // RM Return if minus
1209            0xF8 => {
1210                if self.flags.s {
1211                    self.subroutine_stack_pop();
1212                    cycles += 6;
1213                } else {
1214                    self.pc += 1;
1215                }
1216            } // RM
1217            // RP Return if plus
1218            0xF0 => {
1219                if !self.flags.s {
1220                    self.subroutine_stack_pop();
1221                    cycles += 6;
1222                } else {
1223                    self.pc += 1;
1224                }
1225            } // RP
1226            // RPE Return if parity even
1227            0xE8 => {
1228                if self.flags.p {
1229                    self.subroutine_stack_pop();
1230                    cycles += 6;
1231                } else {
1232                    self.pc += 1;
1233                }
1234            } // RPE
1235            // RPO Return if parity odd
1236            0xE0 => {
1237                if !self.flags.p {
1238                    self.subroutine_stack_pop();
1239                    cycles += 6;
1240                } else {
1241                    self.pc += 1;
1242                }
1243            } // RPO
1244
1245            /* Interrupt flip-flop instructions */
1246            // EI Enable interrupts
1247            0xFB => self.inte = true,
1248            // DI Disable Interrupts
1249            0xF3 => self.inte = false,
1250
1251            /* RST (Restart) instructions */
1252            0xC7 => {
1253                // RST 0
1254                match direct_rst {
1255                    false => self.interrupt_stack_push(),
1256                    true => {
1257                        self.pc += 1;
1258                        self.interrupt_stack_push();
1259                    }
1260                }
1261                self.pc = 0x0000;
1262            }
1263
1264            0xCF => {
1265                // RST 1
1266                match direct_rst {
1267                    false => self.interrupt_stack_push(),
1268                    true => {
1269                        self.pc += 1;
1270                        self.interrupt_stack_push();
1271                    }
1272                }
1273                self.pc = 0x0008;
1274            }
1275
1276            0xD7 => {
1277                // RST 2
1278                match direct_rst {
1279                    false => self.interrupt_stack_push(),
1280                    true => {
1281                        self.pc += 1;
1282                        self.interrupt_stack_push();
1283                    }
1284                }
1285                self.pc = 0x0010;
1286            }
1287
1288            0xDF => {
1289                // RST 3
1290                match direct_rst {
1291                    false => self.interrupt_stack_push(),
1292                    true => {
1293                        self.pc += 1;
1294                        self.interrupt_stack_push();
1295                    }
1296                }
1297                self.pc = 0x0018;
1298            }
1299
1300            0xE7 => {
1301                // RST 4
1302                match direct_rst {
1303                    false => self.interrupt_stack_push(),
1304                    true => {
1305                        self.pc += 1;
1306                        self.interrupt_stack_push();
1307                    }
1308                }
1309                self.pc = 0x0020;
1310            }
1311
1312            0xEF => {
1313                // RST 5
1314                match direct_rst {
1315                    false => self.interrupt_stack_push(),
1316                    true => {
1317                        self.pc += 1;
1318                        self.interrupt_stack_push();
1319                    }
1320                }
1321                self.pc = 0x0028;
1322            }
1323
1324            0xF7 => {
1325                // RST 6
1326                match direct_rst {
1327                    false => self.interrupt_stack_push(),
1328                    true => {
1329                        self.pc += 1;
1330                        self.interrupt_stack_push();
1331                    }
1332                }
1333                self.pc = 0x0030;
1334            }
1335
1336            0xFF => {
1337                // RST 7
1338                match direct_rst {
1339                    false => self.interrupt_stack_push(),
1340                    true => {
1341                        self.pc += 1;
1342                        self.interrupt_stack_push();
1343                    }
1344                }
1345                self.pc = 0x0038;
1346            }
1347
1348            /* Input / output instructions */
1349            // IN Input
1350            0xDB => {
1351                // To implement yourself
1352            }
1353
1354            // OUT Output
1355            0xD3 => {
1356                // To implement yourself
1357            }
1358
1359            _ => {}
1360        }
1361
1362        if self.debug.switch {
1363            self.debug.string = match opcode {
1364            0xC7 | 0xCF | 0xD7 | 0xDF | 0xE7 | 0xEF | 0xF7 | 0xFF =>  String::from("RST"),
1365            _ => format!("{}\nPC : {:#06x}\tSP : {:#06x}\tS : {}\tZ : {}\tA : {}\tP : {}\tC : {}\nB : {:#04x}\tC : {:#04x}\tD : {:#04x}\tE : {:#04x}\tH : {:#04x}\tL : {:#04x}\tA : {:#04x}\t(SP) : {:#06x}\n", self.dasm(pc), pc, self.sp, self.flags.s as i32, self.flags.z as i32, self.flags.a as i32, self.flags.p as i32, self.flags.c as i32, self.reg.b, self.reg.c, self.reg.d, self.reg.e, self.reg.h, self.reg.l, self.reg.a, self.bus.read_word(self.sp)),
1366            }
1367        }
1368
1369        match opcode {
1370            0xe9 | 0xc3 | 0xDA | 0xD2 | 0xCA | 0xC2 | 0xFA | 0xF2 | 0xEA | 0xE2 | 0xCD | 0xDC
1371            | 0xD4 | 0xCC | 0xC4 | 0xFC | 0xF4 | 0xEC | 0xE4 | 0xC9 | 0xD8 | 0xD0 | 0xC8 | 0xC0
1372            | 0xF8 | 0xF0 | 0xE8 | 0xE0 | 0xC7 | 0xCF | 0xD7 | 0xDF | 0xE7 | 0xEF | 0xF7 | 0xFF => {
1373            }
1374            0x06 | 0x0E | 0x16 | 0x1E | 0x26 | 0x2E | 0x36 | 0x3E | 0xC6 | 0xCE | 0xD6 | 0xDE
1375            | 0xE6 | 0xEE | 0xF6 | 0xFE | 0xDB | 0xD3 => self.pc += 2,
1376            0x32 | 0x3A | 0x22 | 0x2A | 0x01 | 0x11 | 0x21 | 0x31 => self.pc += 3,
1377            _ => self.pc += 1,
1378        }
1379
1380        cycles
1381    }
1382}