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.
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

152 líneas
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_