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.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

98 строки
2.6KB

  1. #include <stdlib.h>
  2. #include "map.h"
  3. typedef struct {
  4. uint8_t* prg_rom;
  5. int prg_rom_banks;
  6. uint8_t* chr_rom;
  7. int chr_rom_banks;
  8. uint8_t mirror;
  9. uint8_t vram[nes_vram_page_size * 2];
  10. uint8_t wram[nes_mem_wram_size];
  11. } nrom_mapper;
  12. static void nrom_reset(nes_mapper* nes_map) {}
  13. static int nrom_init(nes_mapper* nes_map, nes_cart* cart) {
  14. nrom_mapper* map = calloc(1, sizeof(nrom_mapper));
  15. nes_map->data = map;
  16. if (NULL != map) {
  17. map->prg_rom = cart->prg_rom;
  18. map->prg_rom_banks = cart->prg_rom_banks;
  19. map->chr_rom = cart->chr_rom;
  20. map->chr_rom_banks = cart->chr_rom_banks;
  21. map->mirror = (cart->flags & Cart_Flag_Horizontal) ? 0 : 1;
  22. }
  23. return (NULL == map ? -1 : 0);
  24. }
  25. static void nrom_done(nes_mapper* nes_map) {
  26. free(nes_map->data);
  27. }
  28. static inline uint8_t* nrom_prg_addr(nrom_mapper* map,
  29. uint16_t addr) {
  30. addr &= 0x7FFFU;
  31. if (map->prg_rom_banks == 1) {
  32. addr &= 0x3FFF;
  33. }
  34. return &(map->prg_rom[addr]);
  35. }
  36. static inline uint8_t* nrom_wram_addr(nrom_mapper* map,
  37. uint16_t addr) {
  38. return &(map->wram[addr & 0x1FFFU]);
  39. }
  40. static uint8_t nrom_read(nes_mapper* map, uint16_t addr) {
  41. uint8_t val = 0;
  42. if (addr >= nes_mem_rom_start) {
  43. val = *(nrom_prg_addr((nrom_mapper*)map->data, addr));
  44. } else if (addr >= nes_mem_wram_start) {
  45. val = *(nrom_wram_addr((nrom_mapper*)map->data, addr));
  46. }
  47. return val;
  48. }
  49. static void nrom_write(nes_mapper* map,
  50. uint16_t addr, uint8_t val) {
  51. if (addr < nes_mem_rom_start && addr >= nes_mem_wram_start) {
  52. *(nrom_wram_addr((nrom_mapper*)map->data, addr)) = val;
  53. }
  54. }
  55. static uint8_t* nrom_chr_addr(nes_mapper* nes_map,
  56. uint16_t addr) {
  57. return &(((nrom_mapper*)nes_map->data)->chr_rom[addr]);
  58. }
  59. static uint8_t* nrom_vram_addr(nes_mapper* nes_map,
  60. uint16_t addr) {
  61. nrom_mapper* map = (nrom_mapper*)nes_map->data;
  62. int page = addr >> 10U;
  63. page >>= map->mirror;
  64. addr = ((page & 1) << 10U) | (addr & 0x3FFU);
  65. return &map->vram[addr];
  66. }
  67. static void nrom_chr_write(nes_mapper* map,
  68. uint16_t addr, uint8_t val) {
  69. // ROM only.
  70. printf("CHR ROM Write: $%04x < %02x\n", addr, val);
  71. }
  72. nes_mapper mapper_nrom = {
  73. .name = "NROM",
  74. .init = nrom_init,
  75. .reset = nrom_reset,
  76. .done = nrom_done,
  77. .read = nrom_read,
  78. .write = nrom_write,
  79. .chr_addr = nrom_chr_addr,
  80. .vram_addr = nrom_vram_addr,
  81. .chr_write = nrom_chr_write,
  82. };