NESe (pronounced "Nessie") is a NES emulator based on the e6502 emulator, also written in C with a focus on speed and portability for use on embedded platforms, especially ARM.
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

152 lines
3.7KB

  1. #ifndef NES_PPU_H_
  2. #define NES_PPU_H_
  3. #include <stdint.h>
  4. struct nes_mapper_t;
  5. struct nes_cart_t;
  6. #define DBG_LOG(...) printf(__VA_ARGS__)
  7. #ifdef DEBUG_OAM
  8. #define OAM_LOG DBG_LOG
  9. #else
  10. #define OAM_LOG(...)
  11. #endif
  12. #ifdef DEBUG_VRAM
  13. #define VRAM_LOG DBG_LOG
  14. #else
  15. #define VRAM_LOG(...)
  16. #endif
  17. #ifdef DEBUG_PPU
  18. #define PPU_LOG DBG_LOG
  19. #else
  20. #define PPU_LOG(...)
  21. #endif
  22. #ifdef DEBUG_RENDER
  23. #define REND_LOG DBG_LOG
  24. #else
  25. #define REND_LOG(...)
  26. #endif
  27. #define nes_ppu_dots (341U)
  28. #define nes_ppu_prerender (1U)
  29. #define nes_ppu_height (240U)
  30. #define nes_ppu_postrender (1U)
  31. #define nes_ppu_vblank (20U)
  32. #define nes_ppu_active (nes_ppu_prerender + \
  33. nes_ppu_height + \
  34. nes_ppu_postrender)
  35. #define nes_ppu_frame (nes_ppu_active + nes_ppu_vblank)
  36. #define nes_ppu_active_cycles (nes_ppu_dots * nes_ppu_active)
  37. #define nes_ppu_vblank_cycles (nes_ppu_dots * nes_ppu_vblank)
  38. #define nes_ppu_frame_cycles (nes_ppu_dots * nes_ppu_frame)
  39. #define nes_ppu_scan_w (320U) // Effective NTSC horizontal rez
  40. #define nes_ppu_scan_h nes_ppu_height
  41. #define nes_ppu_blocks_w (32U)
  42. #define nes_ppu_blocks_h (30U)
  43. #define nes_ppu_render_w (nes_ppu_blocks_w * 8U)
  44. #define nes_ppu_render_h (nes_ppu_blocks_h * 8U)
  45. #define nes_ppu_mem_size (0x4000U)
  46. #define nes_ppu_mem_chr_start (0x0000U)
  47. #define nes_ppu_mem_chr_size (0x2000U)
  48. #define nes_ppu_mem_vram_start (0x2000U)
  49. #define nes_ppu_mem_vram_size (0x1000U)
  50. #define nes_ppu_mem_pal_start (0x3F00U)
  51. #define nes_ppu_mem_pal_size (0x0020U)
  52. #define nes_ppu_oam_size (256U)
  53. #define nes_ppu_oam_sprite_size (4U)
  54. #define nes_ppu_oam_sprite_count (nes_ppu_oam_size / \
  55. nes_ppu_oam_sprite_size)
  56. typedef enum {
  57. ppu_Control_Nametable_Mask = 0b00000011,
  58. ppu_Control_Scroll_Page_X = 0b00000001,
  59. ppu_Control_Scroll_Page_Y = 0b00000010,
  60. ppu_Control_VRAM_Inc = 0b00000100,
  61. ppu_Control_Sprite_Bank = 0b00001000,
  62. ppu_Control_Back_Bank = 0b00010000,
  63. ppu_Control_Sprite_Size = 0b00100000,
  64. ppu_Control_Master = 0b01000000,
  65. ppu_Control_VBlank = 0b10000000,
  66. } nes_ppu_Control;
  67. typedef enum {
  68. ppu_Status_Open_Bus_Mask = 0b00011111,
  69. ppu_Status_Overflow = 0b00100000,
  70. ppu_Status_Hit = 0b01000000,
  71. ppu_Status_VBlank = 0b10000000,
  72. } nes_ppu_Status;
  73. typedef enum {
  74. ppu_Mask_Greyscale = 0b00000001,
  75. ppu_Mask_Left_Back = 0b00000010,
  76. ppu_Mask_Left_Sprite = 0b00000100,
  77. ppu_Mask_Back = 0b00001000,
  78. ppu_Mask_Sprite = 0b00010000,
  79. ppu_Mask_More_Red = 0b00100000,
  80. ppu_Mask_More_Green = 0b01000000,
  81. ppu_Mask_More_Blue = 0b10000000,
  82. } nes_ppu_Mask;
  83. typedef struct {
  84. // Memory
  85. struct nes_mapper_t* mapper;
  86. uint8_t oam[nes_ppu_oam_size];
  87. uint8_t palette[nes_ppu_mem_pal_size];
  88. // Timing
  89. int frame;
  90. int scanline;
  91. int cycle;
  92. int hit_line;
  93. int hit_dot;
  94. // External registers
  95. uint8_t control;
  96. uint8_t mask;
  97. uint8_t status;
  98. uint8_t scroll_x;
  99. uint8_t scroll_y;
  100. uint16_t addr;
  101. uint8_t data;
  102. uint8_t oam_addr;
  103. // Internal Registers
  104. uint8_t latch;
  105. } nes_ppu;
  106. uint8_t nes_ppu_read(nes_ppu* ppu, uint16_t addr);
  107. void nes_ppu_write(nes_ppu* ppu, uint16_t addr, uint8_t val);
  108. void nes_ppu_reset(nes_ppu* ppu);
  109. int nes_ppu_init(nes_ppu* ppu, const struct nes_cart_t*);
  110. typedef enum {
  111. ppu_Result_Halt = -1,
  112. ppu_Result_Running = 0U,
  113. ppu_Result_VBlank_On,
  114. ppu_Result_VBlank_Off,
  115. ppu_Result_Ready,
  116. } nes_ppu_Result;
  117. nes_ppu_Result nes_ppu_run(nes_ppu* ppu, int cycles);
  118. #endif // NES_PPU_H_