add basic ppu register reading

This commit is contained in:
Vineet K 2024-09-01 15:39:32 -04:00
parent f591b4adf2
commit 2084552c53
3 changed files with 75 additions and 6 deletions

4
cpu.c
View File

@ -28,9 +28,7 @@
#define MEMORY_MIRROR(addr) \ #define MEMORY_MIRROR(addr) \
if (addr < 0x2000) \ if (addr < 0x2000) \
addr &= 0x07FF; \ addr &= 0x07FF;
else if (addr < 0x4000) \
addr &= 0x2007;
#define PUSH(b) \ #define PUSH(b) \
(memwrite(0x0100 + regs.sp--, b)) (memwrite(0x0100 + regs.sp--, b))

62
ppu.c
View File

@ -2,6 +2,38 @@
struct ppu ppu = {0}; 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 void
ppu_tick(void) ppu_tick(void)
{ {
@ -17,6 +49,36 @@ ppu_tick(void)
uint8_t uint8_t
ppu_read(uint16_t addr) 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 void

15
ppu.h
View File

@ -7,12 +7,23 @@
#include "rom.h" #include "rom.h"
struct ppu { struct ppu {
uint8_t oam[64*4];
uint8_t vram[2048]; uint8_t vram[2048];
uint8_t oam[64*4];
uint8_t oam_addr; /* $2003 */
uint8_t palette[16*2]; uint8_t palette[16*2];
uint16_t cycles, scanlines; uint16_t cycles, scanlines;
struct rom *rom; 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 */ struct ppu_ctrl { /* $2000 */
uint8_t nmi_enable : 1; uint8_t nmi_enable : 1;
uint8_t master_slave : 1; uint8_t master_slave : 1;
@ -36,8 +47,6 @@ struct ppu {
uint8_t sprite_overflow : 1; uint8_t sprite_overflow : 1;
uint8_t pad : 5; uint8_t pad : 5;
} status; } status;
uint8_t oam_addr; /* $2003 */
uint8_t oam_data; /* $2004 */
}; };
extern struct ppu ppu; extern struct ppu ppu;