|
- #ifndef NESE_PPU_H_
- #define NESE_PPU_H_
-
- #include <stdint.h>
-
- #include "serdes.h"
-
-
- #define nes_ppu_render_w (256U)
- #define nes_ppu_render_h (240U)
-
- #define nes_ppu_scanline_dots (341U)
- #define nes_ppu_prerender_line (0U)
- #define nes_ppu_visible_line (1U)
- #define nes_ppu_postrender_line (241U)
- #define nes_ppu_vblank_line (242U)
- #define nes_ppu_frame_end_line (262U)
-
- typedef struct {
- uint8_t y;
- uint8_t index;
- uint8_t attr;
- uint8_t x;
- } oam_sprite;
-
- typedef enum {
- oam_Attr_Pal_Mask = 0b00000011,
- oam_Attr_Background = 0b00100000,
- oam_Attr_Flip_X = 0b01000000,
- oam_Attr_Flip_Y = 0b10000000,
- } oam_Attribute;
-
-
- typedef enum {
- ppu_reg_ctrl = 0,
- ppu_reg_mask,
- ppu_reg_status,
- ppu_reg_oam_addr,
- ppu_reg_oam_data,
- ppu_reg_scroll,
- ppu_reg_addr,
- ppu_reg_data,
- } ppu_reg_offset;
-
- typedef enum {
- ppu_Control_Nametable_Mask = 0b00000011,
- ppu_Control_Scroll_Page_X = 0b00000001,
- ppu_Control_Scroll_Page_Y = 0b00000010,
- ppu_Control_VRAM_Inc = 0b00000100,
- ppu_Control_Sprite_Bank = 0b00001000,
- ppu_Control_Back_Bank = 0b00010000,
- ppu_Control_Sprite_Size = 0b00100000,
- ppu_Control_Master = 0b01000000,
- ppu_Control_VBlank = 0b10000000,
- } nes_ppu_Control;
-
- typedef enum {
- ppu_Mask_Greyscale = 0b00000001,
- ppu_Mask_Left_Back = 0b00000010,
- ppu_Mask_Left_Sprite = 0b00000100,
- ppu_Mask_Back = 0b00001000,
- ppu_Mask_Sprite = 0b00010000,
- ppu_Mask_More_Red = 0b00100000,
- ppu_Mask_More_Green = 0b01000000,
- ppu_Mask_More_Blue = 0b10000000,
- } nes_ppu_Mask;
-
- typedef enum {
- ppu_Status_Open_Bus_Mask = 0b00011111,
- ppu_Status_Overflow = 0b00100000,
- ppu_Status_Hit = 0b01000000,
- ppu_Status_VBlank = 0b10000000,
- } nes_ppu_Status;
-
-
- #define NES_CHR_ROM_PAGE_SIZE (0x0400U)
- #define NES_VRAM_PAGE_SIZE (0x0400U)
-
- #define NES_PPU_SPRITE_COUNT (64U)
-
- #define NES_PPU_CHR_SIZE (0x2000U)
- #define NES_PPU_VRAM_SIZE (0x1000U)
- #define NES_PPU_RAM_SIZE (0x4000U)
- #define NES_PPU_OAM_SIZE (NES_PPU_SPRITE_COUNT * 4U)
- #define NES_PPU_PAL_START (0x3F00U)
-
- typedef struct {
- // Dynamic memory banks
- uint8_t* chr;
- uint8_t* bank[16];
-
- // Nullable buffer
- uint8_t* chr_ram;
-
- // Registers &c.
- uint8_t ctrl;
- uint8_t mask;
- uint8_t status;
- uint8_t oam_addr;
- uint16_t addr; // aka "v"
- uint8_t data;
- uint8_t x; // Fine X scroll
- uint16_t t; // temp VRAM addr
- uint8_t latch; // aka "w" - TODO: Could this be a flag?
- uint8_t addr_inc; // Auto-increment (1 or 32)
-
- // Static memory banks
- int n_chr_banks;
- uint8_t palette[32]; // Rendering palette with transparency masked
- uint8_t vram[NES_PPU_VRAM_SIZE];
- uint8_t pal_bank[NES_CHR_ROM_PAGE_SIZE]; // Raw palette data mirrored in banks 12-15, also pal
- uint8_t oam[NES_PPU_OAM_SIZE];
- } nes_PPU_Memory;
-
-
- static inline uint8_t* chr_page(nes_PPU_Memory* mem,
- int page) {
- return &mem->chr[page * NES_CHR_ROM_PAGE_SIZE];
- }
-
- static inline uint8_t* vram_page(nes_PPU_Memory* mem,
- int page) {
- return &mem->vram[page * NES_VRAM_PAGE_SIZE];
- }
-
- #define nes_PPU_Nametable_Bank_Index (8U)
-
- typedef enum {
- nes_Mirror_Horizontal = 0,
- nes_Mirror_Vertical,
- nes_Mirror_Only_0,
- nes_Mirror_Only_1,
- nes_Mirror_Four,
- } nes_Nametable_Mirroring;
-
- void nes_ppu_set_mirroring(nes_PPU_Memory* mem,
- nes_Nametable_Mirroring mirror);
-
- typedef struct {
- int scanline;
- int hit_line;
- uint8_t screen_data[nes_ppu_render_w * nes_ppu_render_h];
- } nes_PPU;
-
- void nes_ppu_init(nes_PPU*, nes_PPU_Memory*);
-
- void nes_ppu_find_hit_line(nes_PPU*, nes_PPU_Memory*);
-
- void nes_ppu_render_line(nes_PPU*, nes_PPU_Memory*);
-
-
- extern const Serdes_Item nes_ppu_memory_serdes[];
-
-
- #endif // NESE_PPU_H_
|