From d3d02d9c80a2320cf05833238fb0d75c0f4e66bf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Mon, 4 Jul 2022 17:21:04 +0100
Subject: [PATCH] feat: more instructions

---
 examples/sdl/src/main.rs |  4 ++--
 src/inst.rs              | 38 +++++++++++++++++++++++++++++++++++---
 src/ppu.rs               |  6 ++++++
 3 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index 1a34b02f..1250a53a 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -81,12 +81,12 @@ fn main() {
     let mut game_boy = GameBoy::new();
     game_boy.load_boot_sgb();
     //game_boy.load_rom_file("../../res/roms.prop/tetris.gb");
-    game_boy.load_rom_file("../../res/roms/07-jr,jp,call,ret,rst.gb");
+    game_boy.load_rom_file("../../res/roms.prop/alleyway.gb");
+    //game_boy.load_rom_file("../../res/roms/07-jr,jp,call,ret,rst.gb");
     //game_boy.load_rom_file("../../res/roms/firstwhite.gb");
     //game_boy.load_rom_file("../../res/roms/opus5.gb");
     //game_boy.load_rom_file("../../res/roms/ld_r_r.gb");
     //game_boy.load_rom_file("../../res/roms/special.gb");
-    //game_boy.load_rom_file("../../res/roms/firstwhite.gb");
 
     let mut counter = 0;
 
diff --git a/src/inst.rs b/src/inst.rs
index 3983bbb8..1f461bd2 100644
--- a/src/inst.rs
+++ b/src/inst.rs
@@ -237,7 +237,7 @@ pub const INSTRUCTIONS: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (illegal, 4, "ILLEGAL"),
     (call_c_u16, 12, "CALL C, u16"),
     (illegal, 4, "ILLEGAL"),
-    (noimpl, 4, "! UNIMP !"),
+    (sbc_a_u8, 8, "SBC A, u8"),
     (rst_18h, 16, "RST 18h"),
     // 0xe opcodes
     (ld_mff00u8_a, 12, "LD [FF00+u8], A"),
@@ -318,7 +318,7 @@ pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (sla_a, 8, "SLA A"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
@@ -512,7 +512,7 @@ pub const EXTENDED: [(fn(&mut Cpu), u8, &'static str); 256] = [
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
     (noimpl, 4, "! UNIMP !"),
-    (noimpl, 4, "! UNIMP !"),
+    (set_3_mhl, 16, "SET 3, [HL]"),
     (noimpl, 4, "! UNIMP !"),
     // 0xe opcodes
     (noimpl, 4, "! UNIMP !"),
@@ -1635,6 +1635,11 @@ fn call_c_u16(cpu: &mut Cpu) {
     cpu.ticks = cpu.ticks.wrapping_add(12);
 }
 
+fn sbc_a_u8(cpu: &mut Cpu) {
+    let byte = cpu.read_u8();
+    cpu.a = sub_carry_set_flags(cpu, cpu.a, byte);
+}
+
 fn rst_18h(cpu: &mut Cpu) {
     rst(cpu, 0x0018);
 }
@@ -1760,6 +1765,10 @@ fn sla_b(cpu: &mut Cpu) {
     cpu.b = sla(cpu, cpu.b);
 }
 
+fn sla_a(cpu: &mut Cpu) {
+    cpu.a = sla(cpu, cpu.a);
+}
+
 fn swap_a(cpu: &mut Cpu) {
     cpu.a = swap(cpu, cpu.a)
 }
@@ -1787,6 +1796,13 @@ fn res_7_mhl(cpu: &mut Cpu) {
     cpu.mmu.write(hl, value);
 }
 
+fn set_3_mhl(cpu: &mut Cpu) {
+    let hl = cpu.hl();
+    let byte = cpu.mmu.read(hl);
+    let value = set(byte, 3);
+    cpu.mmu.write(hl, value);
+}
+
 fn set_4_a(cpu: &mut Cpu) {
     cpu.a = set(cpu.a, 4);
 }
@@ -1899,6 +1915,22 @@ fn sub_set_flags(cpu: &mut Cpu, first: u8, second: u8) -> u8 {
     result_b
 }
 
+fn sub_carry_set_flags(cpu: &mut Cpu, first: u8, second: u8) -> u8 {
+    let first = first as u32;
+    let second = second as u32;
+    let carry = cpu.get_carry() as u32;
+
+    let result = first.wrapping_sub(second).wrapping_sub(carry);
+    let result_b = result as u8;
+
+    cpu.set_sub(true);
+    cpu.set_zero(result_b == 0);
+    cpu.set_half_carry((first ^ second ^ result) & 0x10 == 0x10);
+    cpu.set_carry(result & 0x100 == 0x100);
+
+    result_b
+}
+
 fn add_u16_u16(cpu: &mut Cpu, first: u16, second: u16) -> u16 {
     let first = first as u32;
     let second = second as u32;
diff --git a/src/ppu.rs b/src/ppu.rs
index 497a3f9e..baa4c128 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -57,6 +57,9 @@ pub struct Ppu {
     /// The scroll X register that controls the X offset
     /// of the background.
     scx: u8,
+    // The line compare register that is going to be used
+    // in the STATE and associated interrupts.
+    lyc: u8,
     /// The current scan line in processing, should
     /// range between 0 (0x00) and 153 (0x99), representing
     /// the 154 lines plus 10 extra v-blank lines.
@@ -111,6 +114,7 @@ impl Ppu {
             palette_obj_1: [[0u8; RGB_SIZE]; PALETTE_SIZE],
             scy: 0x0,
             scx: 0x0,
+            lyc: 0x0,
             line: 0x0,
             mode: PpuMode::OamRead,
             mode_clock: 0,
@@ -214,6 +218,7 @@ impl Ppu {
             0x0042 => self.scy,
             0x0043 => self.scx,
             0x0044 => self.line,
+            0x0045 => self.lyc,
             addr => panic!("Reading from unknown PPU location 0x{:04x}", addr),
         }
     }
@@ -238,6 +243,7 @@ impl Ppu {
             }
             0x0042 => self.scy = value,
             0x0043 => self.scx = value,
+            0x0045 => self.lyc = value,
             0x0047 => {
                 for index in 0..PALETTE_SIZE {
                     match (value >> (index * 2)) & 3 {
-- 
GitLab