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.
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

98 linhas
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. };