// // Created by william on 12/30/23. // #include #include #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 #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) #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 #define PPU_CTRL_SCROLL_X 0x1 #define PPU_CTRL_SCROLL_Y 0x2 #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 #define PATTERN_TABLE_BYTES_SIZE 0x1000 #define NAMETABLE_BYTES_SIZE 0x0400 #define PALETTE_TABLE_BYTES_SIZE 0x0020 typedef struct ppu_memory { byte nametable_0[NAMETABLE_BYTES_SIZE]; byte nametable_1[NAMETABLE_BYTES_SIZE]; byte palette[PALETTE_TABLE_BYTES_SIZE]; } PPUMemory; typedef struct ppu_tile_fetch { byte nametable; byte attribute_table; byte pattern_table_tile_low; byte pattern_table_tile_high; } PPUTileFetch; //typedef struct ppu_pixel { // byte r; // byte g; // byte b; //} PPUPixel; typedef unsigned int PPUPixel; typedef struct ppu_tile_queue { PPUTileFetch first_fetch; PPUTileFetch second_fetch; PPUTileFetch displayed_fetch; } PPUTileQueue; typedef struct ppu { PPUMemory memory; PPUPixel pixels[256 * 240]; byte registers[8]; byte oam_dma_register; byte oam[PPU_OAM_SIZE]; bool odd_frame; address v; address t; byte x; bool w; byte x_scroll; byte fine_x_scroll; byte y_scroll; byte ppu_addr_increment; address ppu_address; address temp_ppu_addr; address bg_pattern_table_addr; PPUTileFetch fetch; PPUTileQueue tile_queue; unsigned long frame; unsigned int scanline; unsigned int cycle; } PPU; PPU *ppu_get_state(); /** * Initializes the PPU, according to the power up state. * https://www.nesdev.org/wiki/PPU_power_up_state * * @param ppu */ void ppu_init(); /** * Cycles the PPU. * * @param ppu * @param ram */ void ppu_cycle(); /** * Read a flag from the PPU registers. * * @param reg The register index * @param mask The flag mask */ bool ppu_read_flag(size_t reg, byte mask); /** * Read a value from the PPU registers. Does not apply any offset to the value, a mask of 0x20 will either result in 0x20 (true) or 0x0 (false). * Read a value from the PPU registers. Does not apply any offset to the value, a mask of 0x20 will either result in 0x20 (true) or 0x0 (false). * * @param reg The register index * @param mask The value mask */ //void ppu_sig_read_register(byte reg); // //void ppu_sig_write_register(byte reg); byte ppu_read_reg(byte reg); void ppu_write_reg(byte reg, byte data); void ppu_write_oamaddr(byte data); void ppu_write(address addr, byte data); #endif //NESEMULATOR_PPU_H