nesemu/include/ppu.h

146 lines
3.1 KiB
C
Raw Normal View History

2024-01-06 14:27:09 -05:00
//
// Created by william on 12/30/23.
//
#include <stdbool.h>
#include <stddef.h>
#include "types.h"
#ifndef NESEMULATOR_PPU_H
#define NESEMULATOR_PPU_H
#define PPU_REGISTER_SIZE 0x8
#define PPU_VRAM_SIZE 0x4000
#define PPU_OAM_SIZE 0xff
2024-05-13 17:37:36 -04:00
#define PPU_RAM_BASE_ADDR 0x2000
#define PPU_RAM_MAX_ADDR 0x4000
#define PPU_RAM_BANK_SIZE 0x8
#define PPU_RAM_BANK_COUNT ((PPU_RAM_MAX_ADDR - PPU_RAM_BASE_ADDR) / PPU_RAM_BANK_SIZE)
2024-01-06 14:27:09 -05:00
#define PPU_REGISTER_CTRL 0x00
#define PPU_REGISTER_MASK 0x01
#define PPU_REGISTER_STATUS 0x02
#define PPU_REGISTER_OAM_ADDR 0x03
#define PPU_REGISTER_OAM_DATA 0x04
#define PPU_REGISTER_SCROLL 0x05
#define PPU_REGISTER_ADDR 0x06
#define PPU_REGISTER_DATA 0x07
2024-05-13 17:37:36 -04:00
#define PPU_CTRL_SCROLL_X 0x1
#define PPU_CTRL_SCROLL_Y 0x2
2024-01-06 14:27:09 -05:00
#define PPU_CTRL_BASE_NAMETABLE_ADDR 0x3
#define PPU_CTRL_VRAM_ADDR_INCREMENT 0x4
#define PPU_CTRL_SP_PATTERN_TABLE_ADDR 0x8
#define PPU_CTRL_BG_PATTERN_TABLE_ADDR 0x10
#define PPU_CTRL_SP_SIZE 0x20
#define PPU_CTRL_MODE_SELECT 0x40
#define PPU_CTRL_GEN_VBLANK_NMI 0x80
#define PPU_MASK_GREYSCALE 0x1
#define PPU_MASK_SHOW_BG_LEFT 0x2
#define PPU_MASK_SHOW_SP_LEFT 0x4
#define PPU_MASK_SHOW_BG 0x8
#define PPU_MASK_SHOW_SP 0x10
#define PPU_MASK_EMP_RED 0x20
#define PPU_MASK_EMP_GREEN 0x40
#define PPU_MASK_EMP_BLUE 0x80
#define PPU_STATUS_OPEN_BUS 0x1f
#define PPU_STATUS_SP_OVERFLOW 0x20
#define PPU_STATUS_SP_0_HIT 0x40
#define PPU_STATUS_VBLANK 0x80
#define PPU_MASK_NONE 0xff
2024-07-21 16:41:38 -04:00
#define PATTERN_TABLE_BYTES_SIZE 0x1000
#define NAMETABLE_BYTES_SIZE 0x0400
#define PALETTE_TABLE_BYTES_SIZE 0x0020
2024-05-23 22:44:52 -04:00
typedef struct ppu_memory {
2024-07-21 16:41:38 -04:00
byte nametable_0[NAMETABLE_BYTES_SIZE];
byte nametable_1[NAMETABLE_BYTES_SIZE];
byte palette[PALETTE_TABLE_BYTES_SIZE];
2024-05-23 22:44:52 -04:00
} PPUMemory;
2024-05-23 23:52:04 -04:00
typedef struct ppu_tile_fetch {
byte tile_id;
2024-05-23 23:52:04 -04:00
byte attribute_table;
byte pattern_table_tile_low;
byte pattern_table_tile_high;
} PPUTileFetch;
2024-08-17 17:38:15 -04:00
#if DEBUG
typedef union {
struct {
byte tile_debugger: 1;
byte tile_debugger_pattern_half: 2;
2024-08-17 17:38:15 -04:00
} flags;
byte flags_byte;
} PPUDebugFlags;
#endif
2024-06-16 19:22:40 -04:00
2024-01-06 14:27:09 -05:00
typedef struct ppu {
2024-05-23 22:44:52 -04:00
PPUMemory memory;
2024-08-17 17:38:15 -04:00
pixel pixels[256 * 240];
2024-05-23 22:44:52 -04:00
2024-05-23 23:52:04 -04:00
byte registers[8];
byte oam_dma_register;
2024-01-06 14:27:09 -05:00
byte oam[PPU_OAM_SIZE];
bool odd_frame;
2024-06-21 13:47:28 -04:00
byte x_scroll;
byte fine_x_scroll;
byte y_scroll;
2024-08-17 17:38:15 -04:00
byte x;
bool w;
2024-06-21 13:47:28 -04:00
2024-08-17 17:38:15 -04:00
byte ppu_addr_increment;
2024-05-23 22:44:52 -04:00
address ppu_address;
2024-06-21 13:47:28 -04:00
address temp_ppu_addr;
address bg_pattern_table_addr;
2024-05-17 13:16:21 -04:00
2024-06-21 13:47:28 -04:00
PPUTileFetch fetch;
2024-05-15 13:02:40 -04:00
unsigned long frame;
2024-05-17 13:16:21 -04:00
unsigned int scanline;
unsigned int cycle;
2024-08-17 17:38:15 -04:00
#if DEBUG
PPUDebugFlags debug;
#endif
2024-01-06 14:27:09 -05:00
} PPU;
2024-05-06 20:23:44 -04:00
PPU *ppu_get_state();
2024-01-06 14:27:09 -05:00
/**
* Initializes the PPU, according to the power up state.
* https://www.nesdev.org/wiki/PPU_power_up_state
*
* @param ppu
*/
2024-05-23 23:52:04 -04:00
void ppu_init();
2024-01-06 14:27:09 -05:00
/**
* Cycles the PPU.
*
* @param ppu
* @param ram
*/
2024-05-06 20:23:44 -04:00
void ppu_cycle();
2024-01-06 14:27:09 -05:00
/**
* Read a flag from the PPU registers.
*
* @param reg The register index
* @param mask The flag mask
*/
2024-05-06 20:23:44 -04:00
bool ppu_read_flag(size_t reg, byte mask);
2024-01-06 14:27:09 -05:00
2024-05-13 17:37:36 -04:00
byte ppu_read_reg(byte reg);
2024-05-15 13:02:40 -04:00
2024-05-13 17:37:36 -04:00
void ppu_write_reg(byte reg, byte data);
2024-01-06 14:27:09 -05:00
2024-06-21 13:47:28 -04:00
void ppu_write_oamaddr(byte data);
2024-05-29 21:38:52 -04:00
void ppu_write(address addr, byte data);
2024-01-06 14:27:09 -05:00
#endif //NESEMULATOR_PPU_H