emu_nes/ppu.c

91 lines
1.4 KiB
C
Raw Normal View History

2024-07-21 13:53:04 -04:00
#include "ppu.h"
struct ppu ppu = {0};
2024-09-01 15:39:32 -04:00
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;
}
2024-07-21 13:53:04 -04:00
void
ppu_tick(void)
{
ppu.cycles++;
if (ppu.cycles >= 341) {
ppu.cycles -= 341;
ppu.scanlines++;
}
if (ppu.scanlines >= 262)
ppu.scanlines -= 262;
}
2024-08-31 22:25:12 -04:00
uint8_t
ppu_read(uint16_t addr)
{
2024-09-01 15:39:32 -04:00
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;
}
2024-08-31 22:25:12 -04:00
}
void
ppu_write(uint16_t addr, uint8_t byte)
{
static uint8_t prev;
prev = byte;
}