diff --git a/src/main.rs b/src/main.rs index f599a11..c1fd6ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ struct Inner { left: u8, } +#[derive(Clone, Copy)] union Register { as_u8s: Inner, as_u16: u16, diff --git a/src/processor.rs b/src/processor.rs index 94960a9..6c193e9 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -1,5 +1,12 @@ use crate::{Inner, Memory, Register, State}; +enum FLAGS { + Z = 7, + N = 6, + H = 5, + C = 4, +} + pub struct CPU { pub memory: Memory, pub state: State, @@ -12,15 +19,61 @@ impl CPU { 0x0 => { // noop } - 0x01 => { - self.state.bc = self.ld_immediate_word(); - } - 0x11 => { - self.state.de = self.ld_immediate_word(); - } - 0x21 => { - self.state.hl = self.ld_immediate_word(); + 0x01 => self.state.bc = self.ld_immediate_word(), + 0x02 => unsafe { + let address = self.state.bc.as_u16; + self.memory.set(address, self.state.af.as_u8s.left); + }, + 0x03 => unsafe { self.state.bc.as_u16 += 1 }, + 0x04 => unsafe { self.state.bc.as_u8s.left += 1 }, + 0x05 => unsafe { self.state.bc.as_u8s.left -= 1 }, + 0x06 => self.state.bc.as_u8s.left = self.ld_immediate_byte(), + 0x07 => panic!("RCLA instruction: 0x07"), + 0x08 => unsafe { + let address = self.ld_immediate_word().as_u16; + let word = self.state.sp; + self.store_word(address, word); + }, + 0x09 => unsafe { self.state.hl.as_u16 += self.state.bc.as_u16 }, + 0x0A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.bc.as_u16) }, + 0x0B => unsafe { self.state.bc.as_u16 -= 0x1 }, + 0x0C => unsafe { self.state.bc.as_u8s.right += 0x1 }, + 0x0D => unsafe { self.state.bc.as_u8s.right -= 0x1 }, + 0x0E => self.state.bc.as_u8s.right = self.ld_immediate_byte(), + 0x0F => panic!("RRCA instruction: 0x0F"), + 0x10 => panic!("STOP instruction"), + 0x11 => self.state.de = self.ld_immediate_word(), + 0x12 => unsafe { + let address = self.state.de.as_u16; + let data = self.state.af.as_u8s.left; + self.memory.set(address, data); + }, + 0x13 => unsafe { self.state.de.as_u16 -= 0x1 }, + 0x14 => unsafe { self.state.de.as_u8s.left += 0x1 }, + 0x15 => unsafe { self.state.de.as_u8s.left -= 0x1 }, + 0x16 => self.state.de.as_u8s.left = self.ld_immediate_byte(), + 0x17 => panic!("RLA instruction: 0x17"), + 0x18 => unsafe { self.state.pc.as_u16 += self.ld_immediate_byte() as u16 }, + 0x19 => unsafe { self.state.hl.as_u16 += self.state.de.as_u16 }, + 0x1A => unsafe { self.state.af.as_u8s.left = self.memory.get(self.state.de.as_u16) }, + 0x1B => unsafe { self.state.de.as_u16 -= 1 }, + 0x1C => unsafe { self.state.de.as_u8s.right += 1 }, + 0x1D => unsafe { self.state.de.as_u8s.right -= 1 }, + 0x1E => self.state.de.as_u8s.right = self.ld_immediate_byte(), + 0x1F => panic!("RRA instruction: 0x1F"), + 0x20 => { + let jump_size = self.ld_immediate_byte(); + if self.get_flag(FLAGS::Z) == 0 { + unsafe { self.state.pc.as_u16 += jump_size as u16 } + } } + 0x21 => self.state.hl = self.ld_immediate_word(), + 0x22 => unsafe { + self.memory + .set(self.state.hl.as_u16, self.state.af.as_u8s.left); + self.state.hl.as_u16 += 1; + }, + 0x23 => unsafe { self.state.hl.as_u16 += 1 }, 0x2C => { unsafe { self.state.hl.as_u8s.right += 1; @@ -73,6 +126,13 @@ impl CPU { }; } + fn store_word(&mut self, address: u16, word: Register) { + unsafe { + self.memory.set(address, word.as_u8s.left); + self.memory.set(address + 1, word.as_u8s.right); + }; + } + fn ld_immediate_word(&mut self) -> Register { Register { as_u8s: Inner { @@ -85,4 +145,10 @@ impl CPU { fn ld_immediate_byte(&mut self) -> u8 { self.next_opcode() } + + fn get_flag(&mut self, flag: FLAGS) -> u8 { + unsafe { + return self.state.af.as_u8s.right & (1 << flag as u8); + } + } }