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) @@ -145,15 +146,24 @@ opcode_mem(enum addressing_mode mode) return val; } +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 +#include + +#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 */