From 8410cd184a1acce652338b09a5469df656b0db2b Mon Sep 17 00:00:00 2001 From: Nathaniel Walizer Date: Fri, 29 Nov 2024 20:26:32 -0800 Subject: [PATCH] Finish PPU memory mapping --- Makefile | 2 +- src/nese.c | 8 +++++++- src/ppu.c | 47 ++++++++++++++++++++++++++++++++++++++++------- src/ppu.h | 4 ++++ 4 files changed, 52 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 84620c9..5288a9d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC = gcc LD = $(CC) -CFLAGS = -Wall -Werror -Wshadow -I.. -g #-DE6502_DEBUG +CFLAGS = -Wall -Werror -Wshadow -I.. -g -DE6502_DEBUG LDFLAGS = OBJDIR = obj diff --git a/src/nese.c b/src/nese.c index 9d4be47..babc6ee 100644 --- a/src/nese.c +++ b/src/nese.c @@ -1,3 +1,6 @@ +#include +#include + #include "ines.h" @@ -36,6 +39,9 @@ static nes sys = {0}; int main(int argc, char* argv[]) { int status = 0; + int n_loops = (argc > 1) ? atoi(argv[1]) : 0; + if (n_loops <= 0) n_loops = INT_MAX; + status = ines_load(&sys.cart.rom, stdin); if (status == 0) { @@ -43,7 +49,7 @@ int main(int argc, char* argv[]) { nes_reset(&sys); int total_cycles = 0; - for (int i = 0; i < 15000; ++i) { + for (int i = 0; i < n_loops && status == 0; ++i) { int run = 0; status = nes_run(&sys, 1000, &run); total_cycles += run; diff --git a/src/ppu.c b/src/ppu.c index a760ae7..cc5ed9a 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -3,8 +3,8 @@ #include "ppu.h" -// TODO: Stubbed -// TODO: Retain open bus bits +// TODO: Retain open bus bits? + #define ppu_reg_ctrl (0x2000U) #define ppu_reg_mask (0x2001U) @@ -29,8 +29,22 @@ uint8_t nes_ppu_read(nes_ppu* ppu, uint16_t addr) { } else if (ppu_reg_data == addr) { val = ppu->data; - ppu->data = ppu->vram[ppu->addr - - nes_ppu_mem_vram_start]; + + if (ppu->addr < nes_ppu_mem_vram_start) { + ppu->data = ppu->chr_mem[ppu->addr]; + } else if (ppu->addr < nes_ppu_mem_vram_start + + nes_ppu_mem_vram_size) { + ppu->data = ppu->vram[ppu->addr - + nes_ppu_mem_vram_start]; + } else if (ppu->addr < nes_ppu_mem_pal_start) { + ppu->data = ppu->chr_mem[ppu->addr]; + } else if (ppu->addr < nes_ppu_mem_size) { + uint8_t pal_addr = + (ppu->addr - nes_ppu_mem_pal_start) & + (nes_ppu_mem_pal_size - 1); + ppu->data = ppu->palette[pal_addr]; + } + ppu->addr += (ppu->status & ppu_Control_VRAM_Inc) ? 32 : 1; } @@ -68,16 +82,35 @@ void nes_ppu_write(nes_ppu* ppu, uint16_t addr, uint8_t val) { } else if (ppu_reg_addr == addr) { if (ppu->latch) { - ppu->addr &= 0xFF00U; + ppu->addr &= 0x3F00U; ppu->addr |= val; + printf("PPU: VRAM ADDR %04x\n", ppu->addr); + } else { ppu->addr &= 0x00FFU; - ppu->addr |= (uint16_t)(val & 0x3FU) << 8; + ppu->addr |= (uint16_t)val << 8; } ppu->latch = !ppu->latch; } else if (ppu_reg_data == addr) { - ppu->vram[ppu->addr - nes_ppu_mem_vram_start] = val; + if (ppu->addr >= nes_ppu_mem_size) { + printf("!!! PPU: MEM OOB: %04x", ppu->addr); + + } else if (ppu->addr >= nes_ppu_mem_pal_start) { + uint8_t pal_addr = + (ppu->addr - nes_ppu_mem_pal_start) & + (nes_ppu_mem_pal_size - 1); + ppu->palette[pal_addr] = val; + + } else if (ppu->addr >= nes_ppu_mem_vram_start) { + uint16_t vram_addr = ppu->addr - nes_ppu_mem_vram_start; + if (vram_addr >= nes_ppu_mem_vram_size) { + printf("!!! PPU: VRAM OOB: %04x", vram_addr); + vram_addr &= (nes_ppu_mem_vram_size - 1); + } + ppu->vram[vram_addr] = val; + } + ppu->addr += (ppu->status & ppu_Control_VRAM_Inc) ? 32 : 1; } diff --git a/src/ppu.h b/src/ppu.h index 2ae3308..798240d 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -10,6 +10,9 @@ #define nes_ppu_postrender (1U) #define nes_ppu_vblank (20U) +#define nes_ppu_mem_size (0x4000U) +#define nes_ppu_mem_pal_start (0x3F00U) +#define nes_ppu_mem_pal_size (0x0020U) #define nes_ppu_mem_vram_start (0x2000U) #define nes_ppu_mem_vram_size (0x0800U) @@ -36,6 +39,7 @@ typedef struct { uint8_t* chr_mem; uint8_t oam[nes_ppu_oam_size]; uint8_t vram[nes_ppu_mem_vram_size]; + uint8_t palette[nes_ppu_mem_pal_size]; int frame; int scanline;