From 9137a109762b5375205296376de9e44d5cc2c929 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Wed, 6 Jul 2022 13:04:10 +0100
Subject: [PATCH] fix: initial support for tetris tile screen

---
 examples/web/index.ts |  2 +-
 src/cpu.rs            |  4 ++--
 src/mmu.rs            | 22 +++++++++++++---------
 src/pad.rs            | 24 ++++++++++++------------
 src/ppu.rs            |  5 +++++
 5 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/examples/web/index.ts b/examples/web/index.ts
index 5f20f7c0..c21f46eb 100644
--- a/examples/web/index.ts
+++ b/examples/web/index.ts
@@ -49,7 +49,7 @@ const KEYS: Record<string, number> = {
 };
 
 // @ts-ignore: ts(2580)
-const ROM_PATH = require("../../res/roms/firstwhite.gb");
+const ROM_PATH = require("../../res/roms.prop/tetris.gb");
 
 // Enumeration that describes the multiple pixel
 // formats and the associated byte size.
diff --git a/src/cpu.rs b/src/cpu.rs
index f4f874e9..83dddb51 100644
--- a/src/cpu.rs
+++ b/src/cpu.rs
@@ -113,8 +113,8 @@ impl Cpu {
 
         if self.ime {
             // @todo aggregate all of this interrupts in the MMU
-            if self.mmu.ppu().int_vblank() {
-                println!("VAI FAZER HANDLING VBLANK");
+            if (self.mmu.ie & 0x01 == 0x01) && self.mmu.ppu().int_vblank() {
+                println!("Going to run V-Blank interrupt handler");
                 let pc = self.pc;
                 self.disable_int();
                 self.push_word(pc);
diff --git a/src/mmu.rs b/src/mmu.rs
index 4a67cda4..71db7029 100644
--- a/src/mmu.rs
+++ b/src/mmu.rs
@@ -13,6 +13,10 @@ pub struct Mmu {
     rom: [u8; ROM_SIZE],
     ram: [u8; RAM_SIZE],
     eram: [u8; RAM_SIZE],
+
+    /// Registers that controls the interrupts that are considered
+    /// to be enabled and should be triggered.
+    pub ie: u8,
 }
 
 impl Mmu {
@@ -25,6 +29,7 @@ impl Mmu {
             rom: [0u8; ROM_SIZE],
             ram: [0u8; RAM_SIZE],
             eram: [0u8; ERAM_SIZE],
+            ie: 0x0,
         }
     }
 
@@ -77,12 +82,11 @@ impl Mmu {
             0xf000 => match addr & 0x0f00 {
                 0x000 | 0x100 | 0x200 | 0x300 | 0x400 | 0x500 | 0x600 | 0x700 | 0x800 | 0x900
                 | 0xa00 | 0xb00 | 0xc00 | 0xd00 => self.ram[(addr & 0x1fff) as usize],
-                0xe00 => {
-                    println!("Reading from PPU OAM - NOT IMPLEMENTED");
-                    0x00
-                }
+                0xe00 => self.ppu.oam[(addr & 0x009f) as usize],
                 0xf00 => {
-                    if addr >= 0xff80 {
+                    if addr == 0xffff {
+                        self.ie
+                    } else if addr >= 0xff80 {
                         self.ppu.hram[(addr & 0x007f) as usize]
                     } else {
                         match addr & 0x00f0 {
@@ -147,11 +151,11 @@ impl Mmu {
                 | 0xa00 | 0xb00 | 0xc00 | 0xd00 => {
                     self.ram[(addr & 0x1fff) as usize] = value;
                 }
-                0xe00 => {
-                    println!("Writing to PPU OAM at 0x{:04x}", addr);
-                }
+                0xe00 => self.ppu.oam[(addr & 0x009f) as usize] = value,
                 0xf00 => {
-                    if addr >= 0xff80 {
+                    if addr == 0xffff {
+                        self.ie = value;
+                    } else if addr >= 0xff80 {
                         self.ppu.hram[(addr & 0x007f) as usize] = value;
                     } else {
                         match addr & 0x00f0 {
diff --git a/src/pad.rs b/src/pad.rs
index 1b7e5412..785b8f89 100644
--- a/src/pad.rs
+++ b/src/pad.rs
@@ -37,26 +37,26 @@ impl Pad {
                 let mut value;
                 match self.selection {
                     PadSelection::Action => {
-                        value = if self.a { 0x01 } else { 0x00 }
-                            | if self.b { 0x02 } else { 0x00 }
-                            | if self.select { 0x04 } else { 0x00 }
-                            | if self.start { 0x08 } else { 0x00 }
+                        value = if self.a { 0x00 } else { 0x01 }
+                            | if self.b { 0x00 } else { 0x02 }
+                            | if self.select { 0x00 } else { 0x04 }
+                            | if self.start { 0x00 } else { 0x08 }
                     }
                     PadSelection::Direction => {
-                        value = if self.right { 0x01 } else { 0x00 }
-                            | if self.left { 0x02 } else { 0x00 }
-                            | if self.up { 0x04 } else { 0x00 }
-                            | if self.down { 0x08 } else { 0x00 }
+                        value = if self.right { 0x00 } else { 0x01 }
+                            | if self.left { 0x00 } else { 0x02 }
+                            | if self.up { 0x00 } else { 0x04 }
+                            | if self.down { 0x00 } else { 0x08 }
                     }
                 }
                 value |= if self.selection == PadSelection::Direction {
-                    0x00
-                } else {
                     0x10
-                } | if self.selection == PadSelection::Action {
-                    0x00
                 } else {
+                    0x00
+                } | if self.selection == PadSelection::Action {
                     0x20
+                } else {
+                    0x00
                 };
                 value
             }
diff --git a/src/ppu.rs b/src/ppu.rs
index d0e97be2..76406d41 100644
--- a/src/ppu.rs
+++ b/src/ppu.rs
@@ -9,6 +9,7 @@ use wasm_bindgen::prelude::*;
 
 pub const VRAM_SIZE: usize = 8192;
 pub const HRAM_SIZE: usize = 128;
+pub const OAM_SIZE: usize = 260;
 pub const PALETTE_SIZE: usize = 4;
 pub const RGB_SIZE: usize = 3;
 
@@ -99,6 +100,9 @@ pub struct Ppu {
     /// High RAM memory that should provide extra speed for regular
     /// operations.
     pub hram: [u8; HRAM_SIZE],
+    /// OAM RAM (Sprite Attribute Table ) used for the storage of the
+    /// sprite attributes for each of the 40 sprites of the Game Boy.
+    pub oam: [u8; OAM_SIZE],
     /// The current set of processed tiles that are store in the
     /// PPU related structures.
     tiles: [Tile; TILE_COUNT],
@@ -172,6 +176,7 @@ impl Ppu {
             frame_buffer: Box::new([0u8; DISPLAY_WIDTH * DISPLAY_HEIGHT * RGB_SIZE]),
             vram: [0u8; VRAM_SIZE],
             hram: [0u8; HRAM_SIZE],
+            oam: [0u8; OAM_SIZE],
             tiles: [Tile { buffer: [0u8; 64] }; TILE_COUNT],
             palette: [[0u8; RGB_SIZE]; PALETTE_SIZE],
             palette_obj_0: [[0u8; RGB_SIZE]; PALETTE_SIZE],
-- 
GitLab