#include #include "map.h" typedef struct { uint8_t* prg_rom; int prg_rom_banks; uint8_t* chr_rom; int chr_rom_banks; uint8_t mirror; uint8_t vram[nes_vram_page_size * 2]; uint8_t wram[nes_mem_wram_size]; } nrom_mapper; static void nrom_reset(nes_mapper* nes_map) {} static int nrom_init(nes_mapper* nes_map, nes_cart* cart) { nrom_mapper* map = calloc(1, sizeof(nrom_mapper)); nes_map->data = map; if (NULL != map) { map->prg_rom = cart->prg_rom; map->prg_rom_banks = cart->prg_rom_banks; map->chr_rom = cart->chr_rom; map->chr_rom_banks = cart->chr_rom_banks; map->mirror = (cart->flags & Cart_Flag_Horizontal) ? 0 : 1; } return (NULL == map ? -1 : 0); } static void nrom_done(nes_mapper* nes_map) { free(nes_map->data); } static inline uint8_t* nrom_prg_addr(nrom_mapper* map, uint16_t addr) { addr &= 0x7FFFU; if (map->prg_rom_banks == 1) { addr &= 0x3FFF; } return &(map->prg_rom[addr]); } static inline uint8_t* nrom_wram_addr(nrom_mapper* map, uint16_t addr) { return &(map->wram[addr & 0x1FFFU]); } static uint8_t nrom_read(nes_mapper* map, uint16_t addr) { uint8_t val = 0; if (addr >= nes_mem_rom_start) { val = *(nrom_prg_addr((nrom_mapper*)map->data, addr)); } else if (addr >= nes_mem_wram_start) { val = *(nrom_wram_addr((nrom_mapper*)map->data, addr)); } return val; } static void nrom_write(nes_mapper* map, uint16_t addr, uint8_t val) { if (addr < nes_mem_rom_start && addr >= nes_mem_wram_start) { *(nrom_wram_addr((nrom_mapper*)map->data, addr)) = val; } } static uint8_t* nrom_chr_addr(nes_mapper* nes_map, uint16_t addr) { return &(((nrom_mapper*)nes_map->data)->chr_rom[addr]); } static uint8_t* nrom_vram_addr(nes_mapper* nes_map, uint16_t addr) { nrom_mapper* map = (nrom_mapper*)nes_map->data; int page = addr >> 10U; page >>= map->mirror; addr = ((page & 1) << 10U) | (addr & 0x3FFU); return &map->vram[addr]; } static void nrom_chr_write(nes_mapper* map, uint16_t addr, uint8_t val) { // ROM only. printf("CHR ROM Write: $%04x < %02x\n", addr, val); } nes_mapper mapper_nrom = { .name = "NROM", .init = nrom_init, .reset = nrom_reset, .done = nrom_done, .read = nrom_read, .write = nrom_write, .chr_addr = nrom_chr_addr, .vram_addr = nrom_vram_addr, .chr_write = nrom_chr_write, };