From e6420f5a75d4e6e1ff57b7ed27f366b6188dad49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Sat, 2 Jul 2022 23:22:31 +0100 Subject: [PATCH] feat: more instructions added --- examples/sdl/src/main.rs | 2 +- src/cpu.rs | 14 +++++++++++ src/inst.rs | 50 +++++++++++++++++++++++++++++++++++----- src/mmu.rs | 12 ++++------ 4 files changed, 64 insertions(+), 14 deletions(-) diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs index 0b39bd95..5cf73b2f 100644 --- a/examples/sdl/src/main.rs +++ b/examples/sdl/src/main.rs @@ -75,7 +75,7 @@ fn main() { let mut game_boy = GameBoy::new(); game_boy.load_boot_default(); - game_boy.load_rom("../../res/roms/firstwhite.gb"); + game_boy.load_rom("../../res/roms/ld_r_r.gb"); let mut counter = 0; diff --git a/src/cpu.rs b/src/cpu.rs index 04cd30ec..d16da5f4 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -137,6 +137,20 @@ impl Cpu { f } + #[inline(always)] + pub fn set_f(&mut self, value: u8) { + self.zero = value & 0x80 == 0x80; + self.sub = value & 0x40 == 0x40; + self.half_carry = value & 0x20 == 0x20; + self.carry = value & 0x10 == 0x10; + } + + #[inline(always)] + pub fn set_af(&mut self, value: u16) { + self.a = (value >> 8) as u8; + self.set_f(value as u8); + } + #[inline(always)] pub fn set_bc(&mut self, value: u16) { self.b = (value >> 8) as u8; diff --git a/src/inst.rs b/src/inst.rs index db94b51c..c1b64f12 100644 --- a/src/inst.rs +++ b/src/inst.rs @@ -21,9 +21,9 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [ // 0x1 opcodes (noimpl, 4, "! UNIMP !"), (ld_de_u16, 12, "LD DE, u16"), - (noimpl, 4, "! UNIMP !"), + (ld_mde_a, 8, "LD [DE], A"), (inc_de, 8, "INC DE"), - (noimpl, 4, "! UNIMP !"), + (inc_d, 4, "INC D"), (dec_d, 4, "DEC D"), (ld_d_u8, 8, "LD D, u8"), (rla, 4, "RLA"), @@ -31,7 +31,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [ (noimpl, 4, "! UNIMP !"), (ld_a_mde, 8, "LD A, [DE]"), (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), + (inc_e, 4, "INC E"), (dec_e, 4, "DEC E"), (ld_e_u8, 8, "LD E, u8"), (noimpl, 4, "! UNIMP !"), @@ -241,11 +241,11 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [ (noimpl, 4, "! UNIMP !"), // 0xe opcodes (ld_mff00u8_a, 12, "LD [FF00+u8], A"), - (noimpl, 4, "! UNIMP !"), + (pop_hl, 12, "POP HL"), (ld_mff00c_a, 8, "LD [FF00+C], A"), (noimpl, 4, "! UNIMP !"), (noimpl, 4, "! UNIMP !"), - (noimpl, 4, "! UNIMP !"), + (push_hl, 16, "PUSH HL"), (and_a_u8, 8, "AND A, u8"), (noimpl, 4, "! UNIMP !"), (noimpl, 4, "! UNIMP !"), @@ -258,7 +258,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [ (rst_18h, 16, "RST 18h"), // 0xf opcodes (ld_a_mff00u8, 12, "LD A, [FF00+u8]"), - (noimpl, 4, "! UNIMP !"), + (pop_af, 12, "POP AF"), (noimpl, 4, "! UNIMP !"), (di, 4, "DI"), (noimpl, 4, "! UNIMP !"), @@ -567,10 +567,24 @@ fn ld_de_u16(cpu: &mut Cpu) { cpu.set_de(word); } +fn ld_mde_a(cpu: &mut Cpu) { + cpu.mmu.write(cpu.de(), cpu.a); +} + fn inc_de(cpu: &mut Cpu) { cpu.set_de(cpu.de().wrapping_add(1)); } +fn inc_d(cpu: &mut Cpu) { + let value = cpu.d.wrapping_add(1); + + cpu.set_sub(false); + cpu.set_zero(value == 0); + cpu.set_half_carry((value & 0xf) == 0xf); + + cpu.d = value; +} + fn dec_d(cpu: &mut Cpu) { let d = cpu.d; let value = d.wrapping_sub(1); @@ -609,6 +623,16 @@ fn ld_a_mde(cpu: &mut Cpu) { cpu.a = byte; } +fn inc_e(cpu: &mut Cpu) { + let value = cpu.e.wrapping_add(1); + + cpu.set_sub(false); + cpu.set_zero(value == 0); + cpu.set_half_carry((value & 0xf) == 0xf); + + cpu.e = value; +} + fn dec_e(cpu: &mut Cpu) { let e = cpu.e; let value = e.wrapping_sub(1); @@ -893,10 +917,19 @@ fn ld_mff00u8_a(cpu: &mut Cpu) { cpu.mmu.write(0xff00 + byte as u16, cpu.a); } +fn pop_hl(cpu: &mut Cpu) { + let word = cpu.pop_word(); + cpu.set_hl(word); +} + fn ld_mff00c_a(cpu: &mut Cpu) { cpu.mmu.write(0xff00 + cpu.c as u16, cpu.a); } +fn push_hl(cpu: &mut Cpu) { + cpu.push_word(cpu.hl()); +} + fn and_a_u8(cpu: &mut Cpu) { let byte = cpu.read_u8(); @@ -922,6 +955,11 @@ fn ld_a_mff00u8(cpu: &mut Cpu) { cpu.a = cpu.mmu.read(0xff00 + byte as u16); } +fn pop_af(cpu: &mut Cpu) { + let word = cpu.pop_word(); + cpu.set_af(word); +} + fn di(cpu: &mut Cpu) { cpu.disable_int(); } diff --git a/src/mmu.rs b/src/mmu.rs index 97bbcca4..4eab0ec2 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -140,14 +140,12 @@ impl Mmu { 0x40 | 0x60 | 0x70 => { self.ppu.write(addr, value); } - 0x50 => { - match addr & 0x00ff { - 0x50 => self.boot_active = false, - _ => { - println!("Writing to unknown IO control 0x{:04x}", addr); - } + 0x50 => match addr & 0x00ff { + 0x50 => self.boot_active = false, + _ => { + println!("Writing to unknown IO control 0x{:04x}", addr); } - } + }, _ => { println!("Writing to unknown IO control 0x{:04x}", addr); } -- GitLab