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 @@
28 28
29#define MEMORY_MIRROR(addr) \ 29#define MEMORY_MIRROR(addr) \
30 if (addr < 0x2000) \ 30 if (addr < 0x2000) \
31 addr &= 0x07FF; \ 31 addr &= 0x07FF;
32 else if (addr < 0x4000) \
33 addr &= 0x2007;
34 32
35#define PUSH(b) \ 33#define PUSH(b) \
36 (memwrite(0x0100 + regs.sp--, b)) 34 (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 @@
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
diff --git a/ppu.h b/ppu.h
index ffd66d7..c5483e1 100644
--- a/ppu.h
+++ b/ppu.h
@@ -7,12 +7,23 @@
7#include "rom.h" 7#include "rom.h"
8 8
9struct ppu { 9struct ppu {
10 uint8_t oam[64*4];
11 uint8_t vram[2048]; 10 uint8_t vram[2048];
11 uint8_t oam[64*4];
12 uint8_t oam_addr; /* $2003 */
12 uint8_t palette[16*2]; 13 uint8_t palette[16*2];
13 uint16_t cycles, scanlines; 14 uint16_t cycles, scanlines;
14 struct rom *rom; 15 struct rom *rom;
15 16
17 uint8_t last_read;
18
19 struct ppu_regs {
20 uint16_t v : 15; /* current vram address */
21 uint16_t t : 15; /* temporary vram address */
22 uint8_t x : 3; /* fine x scroll */
23 uint8_t w : 1; /* first/second write toggle */
24 uint8_t padding : 6;
25 } regs;
26
16 struct ppu_ctrl { /* $2000 */ 27 struct ppu_ctrl { /* $2000 */
17 uint8_t nmi_enable : 1; 28 uint8_t nmi_enable : 1;
18 uint8_t master_slave : 1; 29 uint8_t master_slave : 1;
@@ -36,8 +47,6 @@ struct ppu {
36 uint8_t sprite_overflow : 1; 47 uint8_t sprite_overflow : 1;
37 uint8_t pad : 5; 48 uint8_t pad : 5;
38 } status; 49 } status;
39 uint8_t oam_addr; /* $2003 */
40 uint8_t oam_data; /* $2004 */
41}; 50};
42extern struct ppu ppu; 51extern struct ppu ppu;
43 52