|
- #ifndef NES_PPU_H_
- #define NES_PPU_H_
-
- #include <stdint.h>
-
-
- struct nes_mapper_t;
- struct nes_cart_t;
-
-
- #define DBG_LOG(...) printf(__VA_ARGS__)
-
- #ifdef DEBUG_OAM
- #define OAM_LOG DBG_LOG
- #else
- #define OAM_LOG(...)
- #endif
- #ifdef DEBUG_VRAM
- #define VRAM_LOG DBG_LOG
- #else
- #define VRAM_LOG(...)
- #endif
- #ifdef DEBUG_PPU
- #define PPU_LOG DBG_LOG
- #else
- #define PPU_LOG(...)
- #endif
- #ifdef DEBUG_RENDER
- #define REND_LOG DBG_LOG
- #else
- #define REND_LOG(...)
- #endif
-
-
- #define nes_ppu_dots (341U)
- #define nes_ppu_prerender (1U)
- #define nes_ppu_height (240U)
- #define nes_ppu_postrender (1U)
- #define nes_ppu_vblank (20U)
-
- #define nes_ppu_active (nes_ppu_prerender + \
- nes_ppu_height + \
- nes_ppu_postrender)
-
- #define nes_ppu_frame (nes_ppu_active + nes_ppu_vblank)
-
- #define nes_ppu_active_cycles (nes_ppu_dots * nes_ppu_active)
- #define nes_ppu_vblank_cycles (nes_ppu_dots * nes_ppu_vblank)
-
- #define nes_ppu_frame_cycles (nes_ppu_dots * nes_ppu_frame)
-
- #define nes_ppu_scan_w (320U) // Effective NTSC horizontal rez
- #define nes_ppu_scan_h nes_ppu_height
-
- #define nes_ppu_blocks_w (32U)
- #define nes_ppu_blocks_h (30U)
-
- #define nes_ppu_render_w (nes_ppu_blocks_w * 8U)
- #define nes_ppu_render_h (nes_ppu_blocks_h * 8U)
-
- #define nes_ppu_mem_size (0x4000U)
- #define nes_ppu_mem_chr_start (0x0000U)
- #define nes_ppu_mem_chr_size (0x2000U)
- #define nes_ppu_mem_vram_start (0x2000U)
- #define nes_ppu_mem_vram_size (0x1000U)
- #define nes_ppu_mem_pal_start (0x3F00U)
- #define nes_ppu_mem_pal_size (0x0020U)
-
-
- #define nes_ppu_oam_size (256U)
-
- #define nes_ppu_oam_sprite_size (4U)
- #define nes_ppu_oam_sprite_count (nes_ppu_oam_size / \
- nes_ppu_oam_sprite_size)
-
- 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_Status_Open_Bus_Mask = 0b00011111,
- ppu_Status_Overflow = 0b00100000,
- ppu_Status_Hit = 0b01000000,
- ppu_Status_VBlank = 0b10000000,
- } nes_ppu_Status;
-
- 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 struct {
- // Memory
- struct nes_mapper_t* mapper;
- uint8_t oam[nes_ppu_oam_size];
- uint8_t palette[nes_ppu_mem_pal_size];
-
- // Timing
- int frame;
- int scanline;
- int cycle;
-
- int hit_line;
- int hit_dot;
-
- // External registers
- uint8_t control;
- uint8_t mask;
- uint8_t status;
- uint8_t scroll_x;
- uint8_t scroll_y;
- uint16_t addr;
- uint8_t data;
- uint8_t oam_addr;
-
- // Internal Registers
- uint8_t latch;
-
- } nes_ppu;
-
- uint8_t nes_ppu_read(nes_ppu* ppu, uint16_t addr);
- void nes_ppu_write(nes_ppu* ppu, uint16_t addr, uint8_t val);
- void nes_ppu_reset(nes_ppu* ppu);
- int nes_ppu_init(nes_ppu* ppu, const struct nes_cart_t*);
-
- typedef enum {
- ppu_Result_Halt = -1,
- ppu_Result_Running = 0U,
- ppu_Result_VBlank_On,
- ppu_Result_VBlank_Off,
- ppu_Result_Ready,
- } nes_ppu_Result;
-
- nes_ppu_Result nes_ppu_run(nes_ppu* ppu, int cycles);
-
-
- #endif // NES_PPU_H_
|