nes_rom.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. * MIT License
  3. *
  4. * Copyright (c) 2022 Dozingfiretruck
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in all
  14. * copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE.
  23. */
  24. #ifndef _NES_ROM_
  25. #define _NES_ROM_
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29. struct nes;
  30. typedef struct nes nes_t;
  31. /* NES 2.0: https://wiki.nesdev.org/w/index.php/NES_2.0 */
  32. #define TRAINER_SIZE (0x200)
  33. #define PRG_ROM_UNIT_SIZE (0x4000)
  34. #define CHR_ROM_UNIT_SIZE (0x2000)
  35. typedef struct {
  36. uint8_t identification[4]; /* 0-3 Identification String. Must be "NES<EOF>". */
  37. uint8_t prg_rom_size_l; /* 4 PRG-ROM size LSB */
  38. uint8_t chr_rom_size_l; /* 5 CHR-ROM size LSB */
  39. struct {
  40. uint8_t mirroring:1; /* D0 Hard-wired nametable mirroring type 0: Horizontal or mapper-controlled 1: Vertical */
  41. uint8_t save:1; /* D1 "Battery" and other non-volatile memory 0: Not present 1: Present */
  42. uint8_t trainer:1; /* D2 512-byte Trainer 0: Not present 1: Present between Header and PRG-ROM data */
  43. uint8_t four_screen:1; /* D3 Hard-wired four-screen mode 0: No 1: Yes */
  44. uint8_t mapper_number_l:4; /* D4-7 Mapper Number D0..D3 */
  45. };
  46. struct {
  47. uint8_t console_type:2; /* D0-1 Console type 0: Nintendo Entertainment System/Family Computer 1: Nintendo Vs. System 2: Nintendo Playchoice 10 3: Extended Console Type */
  48. uint8_t identifier2:2; /* D2-3 NES 2.0 identifier */
  49. uint8_t mapper_number_m:4; /* D4-7 Mapper Number D4..D7 */
  50. };
  51. struct {
  52. uint8_t mapper_number_h:4; /* D0-3 Mapper number D8..D11 */
  53. uint8_t submapper:4; /* D4-7 Submapper number */
  54. }; /* Mapper MSB/Submapper */
  55. struct {
  56. uint8_t prg_rom_size_m:4; /* D0-3 PRG-ROM size MSB */
  57. uint8_t chr_rom_size_m:4; /* D4-7 CHR-ROM size MSB */
  58. }; /* PRG-ROM/CHR-ROM size MSB */
  59. struct {
  60. uint8_t prg_ram_size_m:4; /* D0-3 PRG-RAM (volatile) shift count */
  61. uint8_t eeprom_size_m:4; /* D4-7 PRG-NVRAM/EEPROM (non-volatile) shift count */
  62. }; /* PRG-RAM/EEPROM size
  63. If the shift count is zero, there is no PRG-(NV)RAM.
  64. If the shift count is non-zero, the actual size is
  65. "64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7. */
  66. struct {
  67. uint8_t chr_ram_size_m:4; /* D0-3 CHR-RAM size (volatile) shift count */
  68. uint8_t chr_nvram_size_m:4; /* D4-7 CHR-NVRAM size (non-volatile) shift count */
  69. }; /* CHR-RAM size
  70. If the shift count is zero, there is no CHR-(NV)RAM.
  71. If the shift count is non-zero, the actual size is
  72. "64 << shift count" bytes, i.e. 8192 bytes for a shift count of 7. */
  73. struct {
  74. uint8_t timing_mode :2; /* D0-1 CPU/PPU timing mode
  75. 0: RP2C02 ("NTSC NES")
  76. 1: RP2C07 ("Licensed PAL NES")
  77. 2: Multiple-region
  78. 3: UMC 6527P ("Dendy") */
  79. uint8_t :6;
  80. }; /* CPU/PPU Timing */
  81. struct {
  82. uint8_t ppu_type:4; /* D0-3 Vs. PPU Type */
  83. uint8_t hardware_type:4; /* D4-7 Vs. Hardware Type */
  84. }; /* When Byte 7 AND 3 =1: Vs. System Type
  85. When Byte 7 AND 3 =3: Extended Console Type */
  86. struct {
  87. uint8_t miscellaneous_number:2; /* D0-1 Number of miscellaneous ROMs present */
  88. uint8_t :6;
  89. }; /* Miscellaneous ROMs */
  90. struct {
  91. uint8_t expansion_device:6; /* D0-5 Default Expansion Device */
  92. uint8_t :2;
  93. }; /* Default Expansion Device */
  94. } nes_header_info_t;
  95. typedef struct nes_rom_info{
  96. uint16_t prg_rom_size;
  97. uint16_t chr_rom_size;
  98. uint8_t* prg_rom;
  99. uint8_t* chr_rom;
  100. uint8_t* sram;
  101. uint16_t mapper_number; /* Mapper Number */
  102. uint8_t mirroring_type; /* 0: Horizontal or mapper-controlled 1: Vertical */
  103. uint8_t four_screen; /* 0: No 1: Yes */
  104. uint8_t save_ram; /* 0: Not present 1: Present */
  105. } nes_rom_info_t;
  106. #if (NES_USE_FS == 1)
  107. nes_t* nes_load_file(const char* file_path);
  108. #endif
  109. nes_t* nes_load_rom(const uint8_t* nes_rom);
  110. int nes_rom_free(nes_t* nes);
  111. #ifdef __cplusplus
  112. }
  113. #endif
  114. #endif// _NES_ROM_