summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-07-21 13:53:04 -0400
committervin <git@vineetk.net>2024-07-21 13:53:04 -0400
commit7d148924e2fee1a2692d2c49a01e6770b630f906 (patch)
tree0fc1abc86a7dae9c249f9a796f4af2e9ebbaffff
parent2df7df5f5b0f325864f92c5a58f3c132cfff989e (diff)
start implementing PPU
-rw-r--r--cpu.c27
-rw-r--r--ppu.c15
-rw-r--r--ppu.h23
-rw-r--r--rom.h5
4 files changed, 64 insertions, 6 deletions
diff --git a/cpu.c b/cpu.c
index 8df2bf9..621fe5b 100644
--- a/cpu.c
+++ b/cpu.c
@@ -8,6 +8,7 @@
#include "cpu.h"
#include "opcodes.h"
#include "rom.h"
+#include "ppu.h"
#define MAX(a, b) ((a > b) ? a : b)
@@ -146,14 +147,23 @@ opcode_mem(enum addressing_mode mode)
}
static void
+tick(void)
+{
+ cycles++;
+ ppu_tick();
+ ppu_tick();
+ ppu_tick();
+}
+
+static void
branch(uint16_t addr, bool cond)
{
if (!cond)
return;
- cycles++;
+ tick();
if (((regs.pc + 1) & 0xFF00) != (addr & 0xFF00))
- cycles++;
+ tick();
regs.pc = addr;
}
@@ -946,18 +956,21 @@ interpret(void)
while (spaces--) putchar(' ');
- printf("A:%02X X:%02X Y:%02X P:%02X SP:%02X CYC:%d\n",
- regs.a, regs.x, regs.y, STATUS_TO_INT(), regs.sp, cycles);
+ printf("A:%02X X:%02X Y:%02X P:%02X SP:%02X PPU:%3d,%3d CYC:%d\n",
+ regs.a, regs.x, regs.y, STATUS_TO_INT(), regs.sp,
+ ppu.scanlines, ppu.cycles, cycles);
if (opcodes[op].memread)
opcodes[op].instr(peek(arg));
else
opcodes[op].instr(arg);
- cycles += opcodes[op].cycles;
+ for (uint8_t i = 0; i < opcodes[op].cycles; i++)
+ tick();
+
if (page_crossed) {
if (opcodes[op].page_cross)
- cycles++;
+ tick();
page_crossed = false;
}
}
@@ -976,6 +989,8 @@ cpu_init(void)
regs.status.unused = 1;
cycles += 7;
+ for (uint8_t i = 0; i < 7 * 3; i++)
+ ppu_tick();
}
int
diff --git a/ppu.c b/ppu.c
new file mode 100644
index 0000000..4ae0162
--- /dev/null
+++ b/ppu.c
@@ -0,0 +1,15 @@
+#include "ppu.h"
+
+struct ppu ppu = {0};
+
+void
+ppu_tick(void)
+{
+ ppu.cycles++;
+ if (ppu.cycles >= 341) {
+ ppu.cycles -= 341;
+ ppu.scanlines++;
+ }
+ if (ppu.scanlines >= 262)
+ ppu.scanlines -= 262;
+}
diff --git a/ppu.h b/ppu.h
new file mode 100644
index 0000000..1527b93
--- /dev/null
+++ b/ppu.h
@@ -0,0 +1,23 @@
+#ifndef PPU_H
+#define PPU_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "rom.h"
+
+struct ppu {
+ uint8_t oam[64*4];
+ uint8_t vram[2048];
+ uint8_t palette[16*2];
+ uint16_t cycles, scanlines;
+ /* copied from rom */
+ uint8_t *chr_rom;
+ size_t chr_rom_size;
+ enum screen_mirroring mirror;
+};
+extern struct ppu ppu;
+
+void ppu_tick(void);
+
+#endif /* PPU_H */
diff --git a/rom.h b/rom.h
index a52bda1..703fabd 100644
--- a/rom.h
+++ b/rom.h
@@ -1,3 +1,6 @@
+#ifndef ROM_H
+#define ROM_H
+
enum screen_mirroring {
M_HORIZONTAL,
M_VERTICAL,
@@ -15,3 +18,5 @@ struct Rom {
void parse_rom(const uint8_t *data, size_t data_len, struct Rom *rom);
void free_rom(struct Rom *rom);
+
+#endif /* ROM_H */