summaryrefslogtreecommitdiff
path: root/ppu.c
diff options
context:
space:
mode:
Diffstat (limited to 'ppu.c')
-rw-r--r--ppu.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/ppu.c b/ppu.c
index 5dc20a3..52837ad 100644
--- a/ppu.c
+++ b/ppu.c
@@ -2,6 +2,38 @@
2 2
3struct ppu ppu = {0}; 3struct ppu ppu = {0};
4 4
5static void
6vram_addr_inc(void)
7{
8 ppu.regs.v += (ppu.ctrl.inc_mode) ? 32 : 1;
9}
10
11static uint16_t
12vram_addr_mirror(uint16_t addr)
13{
14 uint8_t nametable;
15
16 addr &= 0x2fff;
17 addr -= 0x2000;
18 nametable = addr / 0x400;
19
20 switch (ppu.rom->mirror) {
21 case M_HORIZONTAL:
22 if (nametable == 1 || nametable == 2)
23 return addr - 0x400;
24 else if (nametable == 3)
25 return addr - 0x800;
26 break;
27 case M_VERTICAL:
28 if (nametable == 2 || nametable == 3)
29 return addr - 0x800;
30 default:
31 break;
32 };
33
34 return addr;
35}
36
5void 37void
6ppu_tick(void) 38ppu_tick(void)
7{ 39{
@@ -17,6 +49,36 @@ ppu_tick(void)
17uint8_t 49uint8_t
18ppu_read(uint16_t addr) 50ppu_read(uint16_t addr)
19{ 51{
52 uint8_t tmp;
53
54 switch (addr) {
55 case 0x2002:
56 tmp = (ppu.status.vblank << 7)
57 | (ppu.status.sprite0_hit << 6)
58 | (ppu.status.sprite_overflow << 5);
59
60 ppu.status.vblank = 0;
61 ppu.regs.w = 0;
62
63 return tmp;
64 case 0x2004:
65 return ppu.oam[ppu.oam_addr];
66 case 0x2007:
67 vram_addr_inc();
68
69 if (addr <= 0x1fff) {
70 tmp = ppu.last_read;
71 ppu.last_read = ppu.rom->chr_rom[ppu.regs.v];
72 return tmp;
73 } else if (addr <= 0x2fff) {
74 tmp = ppu.last_read;
75 ppu.last_read = ppu.vram[vram_addr_mirror(addr)];
76 return tmp;
77 }
78 default:
79 fprintf(stderr, "Invalid PPU read at address $%04\n", addr);
80 return 0;
81 }
20} 82}
21 83
22void 84void