summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-09-01 15:39:32 -0400
committervin <git@vineetk.net>2024-09-01 15:39:32 -0400
commit2084552c536a8299a3578c8b9b687cff98e6d9a3 (patch)
tree0a4db4405e2dfaf4d9ee63c1f86b2836790bfbe1
parentf591b4adf2cfe5d7cde5ecccf95879bfe09cf57a (diff)
add basic ppu register reading
-rw-r--r--cpu.c4
-rw-r--r--ppu.c62
-rw-r--r--ppu.h15
3 files changed, 75 insertions, 6 deletions
diff --git a/cpu.c b/cpu.c
index 97ece60..a04c603 100644
--- a/cpu.c
+++ b/cpu.c
@@ -28,9 +28,7 @@
#define MEMORY_MIRROR(addr) \
if (addr < 0x2000) \
- addr &= 0x07FF; \
- else if (addr < 0x4000) \
- addr &= 0x2007;
+ addr &= 0x07FF;
#define PUSH(b) \
(memwrite(0x0100 + regs.sp--, b))
diff --git a/ppu.c b/ppu.c
index 5dc20a3..52837ad 100644
--- a/ppu.c
+++ b/ppu.c
@@ -2,6 +2,38 @@
struct ppu ppu = {0};
+static void
+vram_addr_inc(void)
+{
+ ppu.regs.v += (ppu.ctrl.inc_mode) ? 32 : 1;
+}
+
+static uint16_t
+vram_addr_mirror(uint16_t addr)
+{
+ uint8_t nametable;
+
+ addr &= 0x2fff;
+ addr -= 0x2000;
+ nametable = addr / 0x400;
+
+ switch (ppu.rom->mirror) {
+ case M_HORIZONTAL:
+ if (nametable == 1 || nametable == 2)
+ return addr - 0x400;
+ else if (nametable == 3)
+ return addr - 0x800;
+ break;
+ case M_VERTICAL:
+ if (nametable == 2 || nametable == 3)
+ return addr - 0x800;
+ default:
+ break;
+ };
+
+ return addr;
+}
+
void
ppu_tick(void)
{
@@ -17,6 +49,36 @@ ppu_tick(void)
uint8_t
ppu_read(uint16_t addr)
{
+ uint8_t tmp;
+
+ switch (addr) {
+ case 0x2002:
+ tmp = (ppu.status.vblank << 7)
+ | (ppu.status.sprite0_hit << 6)
+ | (ppu.status.sprite_overflow << 5);
+
+ ppu.status.vblank = 0;
+ ppu.regs.w = 0;
+
+ return tmp;
+ case 0x2004:
+ return ppu.oam[ppu.oam_addr];
+ case 0x2007:
+ vram_addr_inc();
+
+ if (addr <= 0x1fff) {
+ tmp = ppu.last_read;
+ ppu.last_read = ppu.rom->chr_rom[ppu.regs.v];
+ return tmp;
+ } else if (addr <= 0x2fff) {
+ tmp = ppu.last_read;
+ ppu.last_read = ppu.vram[vram_addr_mirror(addr)];
+ return tmp;
+ }
+ default:
+ fprintf(stderr, "Invalid PPU read at address $%04\n", addr);
+ return 0;
+ }
}
void
diff --git a/ppu.h b/ppu.h
index ffd66d7..c5483e1 100644
--- a/ppu.h
+++ b/ppu.h
@@ -7,12 +7,23 @@
#include "rom.h"
struct ppu {
- uint8_t oam[64*4];
uint8_t vram[2048];
+ uint8_t oam[64*4];
+ uint8_t oam_addr; /* $2003 */
uint8_t palette[16*2];
uint16_t cycles, scanlines;
struct rom *rom;
+ uint8_t last_read;
+
+ struct ppu_regs {
+ uint16_t v : 15; /* current vram address */
+ uint16_t t : 15; /* temporary vram address */
+ uint8_t x : 3; /* fine x scroll */
+ uint8_t w : 1; /* first/second write toggle */
+ uint8_t padding : 6;
+ } regs;
+
struct ppu_ctrl { /* $2000 */
uint8_t nmi_enable : 1;
uint8_t master_slave : 1;
@@ -36,8 +47,6 @@ struct ppu {
uint8_t sprite_overflow : 1;
uint8_t pad : 5;
} status;
- uint8_t oam_addr; /* $2003 */
- uint8_t oam_data; /* $2004 */
};
extern struct ppu ppu;