diff --git a/src/cart.c b/src/cart.c index dbaebfe..be210aa 100644 --- a/src/cart.c +++ b/src/cart.c @@ -63,7 +63,8 @@ int nes_cart_init_mem(nes_cart* cart, void* mem, int len) { } // Don't initialize the mapper until all flags are set! - status = nes_map_init(cart->mapper, cart); + cart->map_data = nes_map_init(cart->mapper, cart); + status = (NULL == cart->map_data ? -1 : 0); } return status; @@ -71,8 +72,9 @@ int nes_cart_init_mem(nes_cart* cart, void* mem, int len) { void nes_cart_done(nes_cart* cart) { if (NULL != cart->mapper) { - nes_map_done(cart->mapper); + nes_map_done(cart->mapper, cart->map_data); cart->mapper = NULL; + cart->map_data = NULL; } if (NULL != cart->ines_mem) { unmap_file(cart->ines_mem, cart->ines_size); diff --git a/src/cart.h b/src/cart.h index eaa61c5..aaf4183 100644 --- a/src/cart.h +++ b/src/cart.h @@ -17,7 +17,9 @@ typedef struct nes_cart_t { uint8_t* chr_rom; int chr_rom_banks; nes_Cart_Flags flags; + struct nes_mapper_t* mapper; + void* map_data; void* ines_mem; int ines_size; diff --git a/src/map/cnrom.c b/src/map/cnrom.c index fa68dd1..9d63c3a 100644 --- a/src/map/cnrom.c +++ b/src/map/cnrom.c @@ -24,27 +24,26 @@ static void cnrom_set_bank(cnrom_mapper* map, uint8_t bank) { ]; } -static void cnrom_reset(nes_mapper* nes_map) { - cnrom_mapper* map = (cnrom_mapper*)nes_map->data; +static void cnrom_reset(void* _map) { + cnrom_mapper* map = (cnrom_mapper*)_map; cnrom_set_bank(map, 0); } -static int cnrom_init(nes_mapper* nes_map, nes_cart* cart) { +static void* cnrom_init(nes_mapper* nes_map, nes_cart* cart) { cnrom_mapper* map = calloc(1, sizeof(cnrom_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; - cnrom_reset(nes_map); + cnrom_reset(map); } - return (NULL == map ? -1 : 0); + return map; } -static void cnrom_done(nes_mapper* nes_map) { - free(nes_map->data); +static void cnrom_done(void* _map) { + free(_map); } static inline uint8_t* cnrom_prg_addr(cnrom_mapper* map, @@ -57,37 +56,34 @@ static inline uint8_t* cnrom_prg_addr(cnrom_mapper* map, } -static uint8_t cnrom_read(nes_mapper* map, uint16_t addr) { +static uint8_t cnrom_read(void* _map, uint16_t addr) { uint8_t val = 0; if (addr >= nes_mem_rom_start) { - val = *(cnrom_prg_addr((cnrom_mapper*)map->data, addr)); + val = *(cnrom_prg_addr((cnrom_mapper*)_map, addr)); } return val; } -static void cnrom_write(nes_mapper* nes_map, - uint16_t addr, uint8_t val) { - cnrom_mapper* map = (cnrom_mapper*)nes_map->data; +static void cnrom_write(void* _map, uint16_t addr, uint8_t val) { + cnrom_mapper* map = (cnrom_mapper*)_map; if (addr >= nes_mem_rom_start) { cnrom_set_bank(map, val); } } -static uint8_t* cnrom_chr_addr(nes_mapper* nes_map, - uint16_t addr) { - return &((cnrom_mapper*)nes_map->data)->chr_bank[addr]; +static uint8_t* cnrom_chr_addr(void* _map, uint16_t addr) { + return &((cnrom_mapper*)_map)->chr_bank[addr]; } -static uint8_t* cnrom_vram_addr(nes_mapper* nes_map, - uint16_t addr) { - cnrom_mapper* map = (cnrom_mapper*)nes_map->data; +static uint8_t* cnrom_vram_addr(void* _map, uint16_t addr) { + cnrom_mapper* map = (cnrom_mapper*)_map; int page = addr >> 10U; page >>= map->mirror; addr = ((page & 1) << 10U) | (addr & 0x3FFU); return &map->vram[addr]; } -static void cnrom_chr_write(nes_mapper* nes_map, +static void cnrom_chr_write(void* _map, uint16_t addr, uint8_t val) { // ROM only. } @@ -95,13 +91,13 @@ static void cnrom_chr_write(nes_mapper* nes_map, /* Save State */ -int cnrom_state_size(const nes_mapper* nes_map) { - cnrom_mapper* map = (cnrom_mapper*)nes_map->data; +static int cnrom_state_size(const void* _map) { + cnrom_mapper* map = (cnrom_mapper*)_map; return (sizeof(map->bank) + sizeof(map->vram)); } -int cnrom_state_read(nes_mapper* nes_map, const void* data) { - cnrom_mapper* map = (cnrom_mapper*)nes_map->data; +static int cnrom_state_read(void* _map, const void* data) { + cnrom_mapper* map = (cnrom_mapper*)_map; const void* ptr = data; memcpy(&map->bank, ptr, sizeof(map->bank)); @@ -115,8 +111,8 @@ int cnrom_state_read(nes_mapper* nes_map, const void* data) { return (ptr - data); } -int cnrom_state_write(const nes_mapper* nes_map, void* data) { - cnrom_mapper* map = (cnrom_mapper*)nes_map->data; +static int cnrom_state_write(const void* _map, void* data) { + cnrom_mapper* map = (cnrom_mapper*)_map; void* ptr = data; memcpy(ptr, &map->bank, sizeof(map->bank)); diff --git a/src/map/mmc1.c b/src/map/mmc1.c index 6df73b3..29b9e25 100644 --- a/src/map/mmc1.c +++ b/src/map/mmc1.c @@ -90,8 +90,8 @@ static void mmc1_update_prg(mmc1_mapper* map) { map->prg_bank[1] = &map->prg_rom[bank_1 * nes_prg_rom_page_size]; } -static void mmc1_reset(nes_mapper* nes_map) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; +static void mmc1_reset(void* data) { + mmc1_mapper* map = (mmc1_mapper*)data; map->reg_shift = 0b10000; map->reg_control = 0b01100; map->reg_chr_0 = 0; @@ -102,9 +102,8 @@ static void mmc1_reset(nes_mapper* nes_map) { mmc1_update_vram(map); } -static int mmc1_init(nes_mapper* nes_map, nes_cart* cart) { +static void* mmc1_init(nes_mapper* nes_map, nes_cart* cart) { mmc1_mapper* map = calloc(1, sizeof(mmc1_mapper)); - nes_map->data = map; if (NULL != map) { map->prg_rom = cart->prg_rom; map->prg_rom_banks = cart->prg_rom_banks; @@ -121,15 +120,15 @@ static int mmc1_init(nes_mapper* nes_map, nes_cart* cart) { map->battery = !!(cart->flags & Cart_Flag_Battery); - mmc1_reset(nes_map); + mmc1_reset(map); } - return (NULL == map ? -1 : 0); + return map; } -static void mmc1_done(nes_mapper* nes_map) { - if (NULL != nes_map->data) { - free(((mmc1_mapper*)nes_map->data)->chr_ram); - free(nes_map->data); +static void mmc1_done(void* data) { + if (NULL != data) { + free(((mmc1_mapper*)data)->chr_ram); + free(data); } } @@ -145,19 +144,18 @@ static inline uint8_t* mmc1_wram_addr(mmc1_mapper* map, return &(map->wram[addr & 0x1FFFU]); } -static uint8_t mmc1_read(nes_mapper* map, uint16_t addr) { +static uint8_t mmc1_read(void* data, uint16_t addr) { uint8_t val = 0; if (addr >= nes_mem_rom_start) { - val = *(mmc1_prg_addr((mmc1_mapper*)map->data, addr)); + val = *(mmc1_prg_addr((mmc1_mapper*)data, addr)); } else if (addr >= nes_mem_wram_start) { - val = *(mmc1_wram_addr((mmc1_mapper*)map->data, addr)); + val = *(mmc1_wram_addr((mmc1_mapper*)data, addr)); } return val; } -static void mmc1_write(nes_mapper* nes_map, - uint16_t addr, uint8_t val) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; +static void mmc1_write(void* data, uint16_t addr, uint8_t val) { + mmc1_mapper* map = (mmc1_mapper*)data; if (addr >= nes_mem_rom_start) { MAP_LOG("Write $%04x < %02x", addr, val); if (val & 0x80U) { @@ -201,53 +199,51 @@ static void mmc1_write(nes_mapper* nes_map, } } -static uint8_t* mmc1_chr_addr(nes_mapper* nes_map, - uint16_t addr) { +static uint8_t* mmc1_chr_addr(void* data, uint16_t addr) { int page = (addr >> 12) & 1; addr &= 0xFFFU; - return &((mmc1_mapper*)nes_map->data)->chr_bank[page][addr]; + return &((mmc1_mapper*)data)->chr_bank[page][addr]; } -static void mmc1_chr_write(nes_mapper* nes_map, +static void mmc1_chr_write(void* data, uint16_t addr, uint8_t val) { - if (NULL != ((mmc1_mapper*)nes_map->data)->chr_ram) { - *(mmc1_chr_addr(nes_map, addr)) = val; + if (NULL != ((mmc1_mapper*)data)->chr_ram) { + *(mmc1_chr_addr(data, addr)) = val; } } -static uint8_t* mmc1_vram_addr(nes_mapper* nes_map, - uint16_t addr) { +static uint8_t* mmc1_vram_addr(void* data, uint16_t addr) { int page = (addr >> 10) & 3; int loc = addr & 0x3FFU; // MAP_LOG("VRAM $%04x -> %p", addr, ((mmc1_mapper*)nes_map->data)->vram_bank[page]); - return &((mmc1_mapper*)nes_map->data)->vram_bank[page][loc]; + return &((mmc1_mapper*)data)->vram_bank[page][loc]; } -static void* mmc1_sram(nes_mapper* nes_map) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; +static void* mmc1_sram(void* data) { + mmc1_mapper* map = (mmc1_mapper*)data; return (map->battery ? map->wram : NULL); } -static int mmc1_sram_size(nes_mapper* nes_map) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; +static int mmc1_sram_size(void* data) { + mmc1_mapper* map = (mmc1_mapper*)data; return (map->battery ? sizeof(map->wram) : 0); } /* Save State */ -int mmc1_state_size(const nes_mapper* nes_map) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; +static int mmc1_state_size(const void* _map) { + mmc1_mapper* map = (mmc1_mapper*)_map; return ( (void*)map + sizeof(*map) - (void*)&(map->reg_shift)); } -int mmc1_state_read(nes_mapper* nes_map, const void* data) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; +static int mmc1_state_read(void* _map, const void* data) { + mmc1_mapper* map = (mmc1_mapper*)_map; - int size = mmc1_state_size(nes_map); + int size = mmc1_state_size(_map); memcpy(&(map->reg_shift), data, size); mmc1_update_prg(map); @@ -257,9 +253,9 @@ int mmc1_state_read(nes_mapper* nes_map, const void* data) { return size; } -int mmc1_state_write(const nes_mapper* nes_map, void* data) { - mmc1_mapper* map = (mmc1_mapper*)nes_map->data; - int size = mmc1_state_size(nes_map); +static int mmc1_state_write(const void* _map, void* data) { + mmc1_mapper* map = (mmc1_mapper*)_map; + int size = mmc1_state_size(_map); memcpy(data, &(map->reg_shift), size); return size; } @@ -267,6 +263,7 @@ int mmc1_state_write(const nes_mapper* nes_map, void* data) { nes_mapper mapper_mmc1 = { .name = "MMC1", + .init = mmc1_init, .reset = mmc1_reset, .done = mmc1_done, diff --git a/src/map/mmc3.c b/src/map/mmc3.c index bc70e65..1437a6f 100644 --- a/src/map/mmc3.c +++ b/src/map/mmc3.c @@ -3,6 +3,7 @@ #include "map.h" + typedef enum { mmc3_Flag_Horizontal = 0b00000001, mmc3_Flag_IRQ_Enabled = 0b00000010, @@ -25,6 +26,8 @@ typedef struct { uint8_t* chr_rom; int chr_rom_banks; // 4 KB / 1 KB = 4 + nes_mapper* mapper; + uint8_t* prg_bank[4]; // 8 KB uint8_t* chr_bank[8]; // 1 KB uint8_t* vram_bank[4]; @@ -146,8 +149,8 @@ static inline void mmc3_update_vram(mmc3_mapper* map) { } } -static void mmc3_reset(nes_mapper* nes_map) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static void mmc3_reset(void* data) { + mmc3_mapper* map = (mmc3_mapper*)data; map->irq_count = 0; map->irq_latch = 0; mmc3_update_rom_mode(map, 0); @@ -155,10 +158,10 @@ static void mmc3_reset(nes_mapper* nes_map) { mmc3_update_vram(map); } -static int mmc3_init(nes_mapper* nes_map, nes_cart* cart) { +static void* mmc3_init(nes_mapper* nes_map, nes_cart* cart) { mmc3_mapper* map = calloc(1, sizeof(mmc3_mapper)); - nes_map->data = map; if (NULL != map) { + map->mapper = nes_map; map->flags = (cart->flags & Cart_Flag_Horizontal) ? mmc3_Flag_Horizontal : 0; map->prg_rom = cart->prg_rom; @@ -179,18 +182,18 @@ static int mmc3_init(nes_mapper* nes_map, nes_cart* cart) { map->bank_select = mmc3_Bank_Select_PRG | mmc3_Bank_Select_CHR; - mmc3_reset(nes_map); + mmc3_reset(map); } - return (NULL == map ? -1 : 0); + return map; } -static void mmc3_done(nes_mapper* nes_map) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static void mmc3_done(void* data) { + mmc3_mapper* map = (mmc3_mapper*)data; if (NULL != map) { if (map->flags & mmc3_Flag_CHR_RAM) { free(map->chr_rom); } - free(nes_map->data); + free(map); } } @@ -204,9 +207,9 @@ static inline uint8_t* mmc3_wram_addr(mmc3_mapper* map, return &(map->wram[addr & 0x1FFFU]); } -static uint8_t mmc3_read(nes_mapper* nes_map, uint16_t addr) { +static uint8_t mmc3_read(void* data, uint16_t addr) { uint8_t* ptr = NULL; - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + mmc3_mapper* map = (mmc3_mapper*)data; if (addr >= nes_mem_rom_start) { ptr = mmc3_prg_addr(map, addr); } else if ( addr >= nes_mem_wram_start && @@ -222,9 +225,9 @@ static uint8_t mmc3_read(nes_mapper* nes_map, uint16_t addr) { return val; } -static void mmc3_write(nes_mapper* nes_map, +static void mmc3_write(void* data, uint16_t addr, uint8_t val) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + mmc3_mapper* map = (mmc3_mapper*)data; if (addr >= nes_mem_rom_start) MAP_LOG("$%04x < %02x", addr, val); @@ -284,13 +287,13 @@ static void mmc3_write(nes_mapper* nes_map, map->flags |= mmc3_Flag_IRQ_Enabled; } else { map->flags &= ~mmc3_Flag_IRQ_Enabled; - nes_map_trigger_irq(nes_map, 0); + nes_map_trigger_irq(map->mapper, 0); } } } -static void mmc3_scanline(nes_mapper* nes_map) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static void mmc3_scanline(void* data) { + mmc3_mapper* map = (mmc3_mapper*)data; if ( map->irq_count <= 0 || (map->flags & mmc3_Flag_IRQ_Reload)) { @@ -303,42 +306,42 @@ static void mmc3_scanline(nes_mapper* nes_map) { if ( map->irq_count <= 0 && (map->flags & mmc3_Flag_IRQ_Enabled)) { MAP_LOG("IRQ Trigger"); - nes_map_trigger_irq(nes_map, 1); + nes_map_trigger_irq(map->mapper, 1); map->irq_count = 0; } } -static uint8_t* mmc3_chr_addr(nes_mapper* nes_map, +static uint8_t* mmc3_chr_addr(void* data, uint16_t addr) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + mmc3_mapper* map = (mmc3_mapper*)data; return &map->chr_bank[(addr >> 10) & 7][addr & 0x3FFU]; } -static uint8_t* mmc3_vram_addr(nes_mapper* nes_map, +static uint8_t* mmc3_vram_addr(void* data, uint16_t addr) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + mmc3_mapper* map = (mmc3_mapper*)data; return &map->vram_bank[(addr >> 10) & 3][addr & 0x3FFU]; } -static void mmc3_chr_write(nes_mapper* nes_map, +static void mmc3_chr_write(void* data, uint16_t addr, uint8_t val) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; + mmc3_mapper* map = (mmc3_mapper*)data; if (map->flags & mmc3_Flag_CHR_RAM) { - *(mmc3_chr_addr(nes_map, addr)) = val; + *(mmc3_chr_addr(data, addr)) = val; } // MAP_LOG("CHR ROM Write: $%04x < %02x\n", addr, val); } -static void* mmc3_sram(nes_mapper* nes_map) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static void* mmc3_sram(void* data) { + mmc3_mapper* map = (mmc3_mapper*)data; return ( (map->flags & mmc3_Flag_Battery) ? map->wram : NULL); } -static int mmc3_sram_size(nes_mapper* nes_map) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static int mmc3_sram_size(void* data) { + mmc3_mapper* map = (mmc3_mapper*)data; return ( (map->flags & mmc3_Flag_Battery) ? sizeof(map->wram) : 0); } @@ -346,19 +349,19 @@ static int mmc3_sram_size(nes_mapper* nes_map) { /* Save State */ -int mmc3_state_size(const nes_mapper* nes_map) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static int mmc3_state_size(const void* data) { + const mmc3_mapper* map = (mmc3_mapper*)data; return ( (map->wram - map->r) + sizeof(map->wram) + sizeof(map->vram)); } -int mmc3_state_read(nes_mapper* nes_map, const void* data) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; +static int mmc3_state_read(void* _map, const void* data) { + mmc3_mapper* map = (mmc3_mapper*)_map; uint8_t old_bank_select = map->bank_select; - int size = mmc3_state_size(nes_map); + int size = mmc3_state_size(_map); memcpy(map->r, data, size); uint8_t new_bank_select = map->bank_select; @@ -370,9 +373,9 @@ int mmc3_state_read(nes_mapper* nes_map, const void* data) { return size; } -int mmc3_state_write(const nes_mapper* nes_map, void* data) { - mmc3_mapper* map = (mmc3_mapper*)nes_map->data; - int size = mmc3_state_size(nes_map); +static int mmc3_state_write(const void* _map, void* data) { + mmc3_mapper* map = (mmc3_mapper*)_map; + int size = mmc3_state_size(_map); memcpy(data, map->r, size); return size; } @@ -380,6 +383,7 @@ int mmc3_state_write(const nes_mapper* nes_map, void* data) { nes_mapper mapper_mmc3 = { .name = "MMC3", + .init = mmc3_init, .reset = mmc3_reset, .done = mmc3_done, diff --git a/src/map/nrom.c b/src/map/nrom.c index 526d9ca..49e37de 100644 --- a/src/map/nrom.c +++ b/src/map/nrom.c @@ -15,11 +15,10 @@ typedef struct { } nrom_mapper; -static void nrom_reset(nes_mapper* nes_map) {} +static void nrom_reset(void* data) {} -static int nrom_init(nes_mapper* nes_map, nes_cart* cart) { +static void* 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; @@ -31,16 +30,16 @@ static int nrom_init(nes_mapper* nes_map, nes_cart* cart) { map->chr_rom_banks = cart->chr_rom_banks; map->mirror = (cart->flags & Cart_Flag_Horizontal) ? 0 : 1; } - return (NULL == map ? -1 : 0); + return map; } -static void nrom_done(nes_mapper* nes_map) { - nrom_mapper* map = (nrom_mapper*)nes_map->data; +static void nrom_done(void* data) { + nrom_mapper* map = (nrom_mapper*)data; if (NULL != map) { if (map->chr_rom_banks <= 0) { free(map->chr_rom); } - free(nes_map->data); + free(data); } } @@ -58,42 +57,39 @@ static inline uint8_t* nrom_wram_addr(nrom_mapper* map, return &(map->wram[addr & 0x1FFFU]); } -static uint8_t nrom_read(nes_mapper* map, uint16_t addr) { +static uint8_t nrom_read(void* data, uint16_t addr) { uint8_t val = 0; if (addr >= nes_mem_rom_start) { - val = *(nrom_prg_addr((nrom_mapper*)map->data, addr)); + val = *(nrom_prg_addr((nrom_mapper*)data, addr)); } else if (addr >= nes_mem_wram_start) { - val = *(nrom_wram_addr((nrom_mapper*)map->data, addr)); + val = *(nrom_wram_addr((nrom_mapper*)data, addr)); } return val; } -static void nrom_write(nes_mapper* map, - uint16_t addr, uint8_t val) { +static void nrom_write(void* data, 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; + *(nrom_wram_addr((nrom_mapper*)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_chr_addr(void* data, uint16_t addr) { + return &(((nrom_mapper*)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; +static uint8_t* nrom_vram_addr(void* data, uint16_t addr) { + nrom_mapper* map = (nrom_mapper*)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* nes_map, +static void nrom_chr_write(void* data, uint16_t addr, uint8_t val) { - nrom_mapper* map = (nrom_mapper*)nes_map->data; + nrom_mapper* map = (nrom_mapper*)data; if (map->chr_rom_banks <= 0) { - *(nrom_chr_addr(nes_map, addr)) = val; + *(nrom_chr_addr(data, addr)) = val; } // printf("CHR ROM Write: $%04x < %02x\n", addr, val); } @@ -101,20 +97,20 @@ static void nrom_chr_write(nes_mapper* nes_map, /* Save State */ -int nrom_state_size(const nes_mapper* nes_map) { - nrom_mapper* map = (nrom_mapper*)nes_map->data; +static int nrom_state_size(const void* _map) { + nrom_mapper* map = (nrom_mapper*)_map; return (sizeof(map->vram) + sizeof(map->wram)); } -int nrom_state_read(nes_mapper* nes_map, const void* data) { - nrom_mapper* map = (nrom_mapper*)nes_map->data; +static int nrom_state_read(void* _map, const void* data) { + nrom_mapper* map = (nrom_mapper*)_map; memcpy(map->vram, data, sizeof(map->vram)); memcpy(map->wram, data + sizeof(map->vram), sizeof(map->wram)); return (sizeof(map->vram) + sizeof(map->wram)); } -int nrom_state_write(const nes_mapper* nes_map, void* data) { - nrom_mapper* map = (nrom_mapper*)nes_map->data; +static int nrom_state_write(const void* _map, void* data) { + nrom_mapper* map = (nrom_mapper*)_map; memcpy(data, map->vram, sizeof(map->vram)); memcpy(data + sizeof(map->vram), map->wram, sizeof(map->wram)); return (sizeof(map->vram) + sizeof(map->wram)); diff --git a/src/map/uxrom.c b/src/map/uxrom.c index 45c7de1..4dbad8e 100644 --- a/src/map/uxrom.c +++ b/src/map/uxrom.c @@ -24,28 +24,27 @@ static void uxrom_set_bank(uxrom_mapper* map, uint8_t bank) { ]; } -static void uxrom_reset(nes_mapper* nes_map) { - uxrom_mapper* map = (uxrom_mapper*)nes_map->data; +static void uxrom_reset(void* data) { + uxrom_mapper* map = (uxrom_mapper*)data; uxrom_set_bank(map, 0); map->prg_bank_lo = map->prg_rom; } -static int uxrom_init(nes_mapper* nes_map, nes_cart* cart) { +static void* uxrom_init(nes_mapper* nes_map, nes_cart* cart) { uxrom_mapper* map = calloc(1, sizeof(uxrom_mapper)); - nes_map->data = map; if (NULL != map) { map->prg_rom = cart->prg_rom; map->prg_rom_banks = cart->prg_rom_banks; map->mirror = (cart->flags & Cart_Flag_Horizontal) ? 0 : 1; map->prg_bank_hi = &map->prg_rom[(map->prg_rom_banks - 1) * nes_prg_rom_page_size]; - uxrom_reset(nes_map); + uxrom_reset(map); } - return (NULL == map ? -1 : 0); + return map; } -static void uxrom_done(nes_mapper* nes_map) { - free(nes_map->data); +static void uxrom_done(void* data) { + free(data); } static inline uint8_t* uxrom_prg_addr(uxrom_mapper* map, @@ -56,53 +55,50 @@ static inline uint8_t* uxrom_prg_addr(uxrom_mapper* map, } -static uint8_t uxrom_read(nes_mapper* map, uint16_t addr) { +static uint8_t uxrom_read(void* _map, uint16_t addr) { uint8_t val = 0; if (addr >= nes_mem_rom_start) { - val = *(uxrom_prg_addr((uxrom_mapper*)map->data, addr)); + val = *(uxrom_prg_addr((uxrom_mapper*)_map, addr)); } return val; } -static void uxrom_write(nes_mapper* nes_map, - uint16_t addr, uint8_t val) { - uxrom_mapper* map = (uxrom_mapper*)nes_map->data; +static void uxrom_write(void* _map, uint16_t addr, uint8_t val) { + uxrom_mapper* map = (uxrom_mapper*)_map; if (addr >= nes_mem_rom_start) { uxrom_set_bank(map, val); } } -static uint8_t* uxrom_chr_addr(nes_mapper* nes_map, - uint16_t addr) { - return &((uxrom_mapper*)nes_map->data)->chr_ram[addr]; +static uint8_t* uxrom_chr_addr(void* data, uint16_t addr) { + return &((uxrom_mapper*)data)->chr_ram[addr]; } -static uint8_t* uxrom_vram_addr(nes_mapper* nes_map, - uint16_t addr) { - uxrom_mapper* map = (uxrom_mapper*)nes_map->data; +static uint8_t* uxrom_vram_addr(void* data, uint16_t addr) { + uxrom_mapper* map = (uxrom_mapper*)data; int page = addr >> 10U; page >>= map->mirror; addr = ((page & 1) << 10U) | (addr & 0x3FFU); return &map->vram[addr]; } -static void uxrom_chr_write(nes_mapper* nes_map, +static void uxrom_chr_write(void* data, uint16_t addr, uint8_t val) { - ((uxrom_mapper*)nes_map->data)->chr_ram[addr] = val; + ((uxrom_mapper*)data)->chr_ram[addr] = val; } /* Save State */ -int uxrom_state_size(const nes_mapper* nes_map) { - uxrom_mapper* map = (uxrom_mapper*)nes_map->data; +int uxrom_state_size(const void* _map) { + uxrom_mapper* map = (uxrom_mapper*)_map; return ( sizeof(uint32_t) + sizeof(map->vram) + sizeof(map->chr_ram)); } -int uxrom_state_read(nes_mapper* nes_map, const void* data) { - uxrom_mapper* map = (uxrom_mapper*)nes_map->data; +int uxrom_state_read(void* _map, const void* data) { + uxrom_mapper* map = (uxrom_mapper*)_map; const void* ptr = data; map->bank = *(uint32_t*)ptr; @@ -117,8 +113,8 @@ int uxrom_state_read(nes_mapper* nes_map, const void* data) { return (ptr - data); } -int uxrom_state_write(const nes_mapper* nes_map, void* data) { - uxrom_mapper* map = (uxrom_mapper*)nes_map->data; +int uxrom_state_write(const void* _map, void* data) { + uxrom_mapper* map = (uxrom_mapper*)_map; void* ptr = data; uint32_t bank = map->bank; diff --git a/src/mapper.h b/src/mapper.h index 6d53c1e..8a13eec 100644 --- a/src/mapper.h +++ b/src/mapper.h @@ -12,45 +12,42 @@ struct nes_cart_t; typedef struct nes_mapper_t { - void* data; - const char* name; - int (*init)(struct nes_mapper_t*, struct nes_cart_t* cart); - void (*reset)(struct nes_mapper_t*); - void (*done)(struct nes_mapper_t*); + void* (*init)(struct nes_mapper_t*, struct nes_cart_t* cart); + void (*reset)(void*); + void (*done)(void*); - uint8_t (*read)(struct nes_mapper_t*, uint16_t addr); - void (*write)(struct nes_mapper_t*, uint16_t addr, uint8_t val); + uint8_t (*read)(void*, uint16_t addr); + void (*write)(void*, uint16_t addr, uint8_t val); - uint8_t* (*chr_addr)(struct nes_mapper_t*, uint16_t addr); - uint8_t* (*vram_addr)(struct nes_mapper_t*, uint16_t addr); - void (*chr_write)(struct nes_mapper_t*, uint16_t addr, uint8_t val); + uint8_t* (*chr_addr)(void*, uint16_t addr); + uint8_t* (*vram_addr)(void*, uint16_t addr); + void (*chr_write)(void*, uint16_t addr, uint8_t val); - void (*scanline)(struct nes_mapper_t*); - void (*irq_callback)(void*, int); + void (*scanline)(void*); + void (*irq_callback)(void* irq_arg, int); void* irq_arg; - void* (*sram)(struct nes_mapper_t*); - int (*sram_size)(struct nes_mapper_t*); - - int (*state_size)(const struct nes_mapper_t*); - int (*state_read)(struct nes_mapper_t*, const void*); - int (*state_write)(const struct nes_mapper_t*, void*); + void* (*sram)(void*); + int (*sram_size)(void*); + int (*state_size)(const void* map); + int (*state_read)(void* map, const void* data); + int (*state_write)(const void* map, void* data); } nes_mapper; -static inline int nes_map_init(nes_mapper* map, - struct nes_cart_t* cart) { +static inline void* nes_map_init(nes_mapper* map, + struct nes_cart_t* cart) { return map->init(map, cart); } -static inline void nes_map_reset(nes_mapper* map) { - map->reset(map); +static inline void nes_map_reset(nes_mapper* map, void* data) { + map->reset(data); } -static inline void nes_map_done(nes_mapper* map) { - map->done(map); +static inline void nes_map_done(nes_mapper* map, void* data) { + map->done(data); } static inline void nes_map_set_irq(nes_mapper* map, @@ -66,44 +63,51 @@ static inline void nes_map_trigger_irq(nes_mapper* map, } static inline uint8_t nes_map_read(nes_mapper* map, - uint16_t addr) { - return map->read(map, addr); + void* data, + uint16_t addr) { + return map->read(data, addr); } static inline void nes_map_write(nes_mapper* map, - uint16_t addr, - uint8_t val) { - map->write(map, addr, val); + void* data, + uint16_t addr, + uint8_t val) { + map->write(data, addr, val); } static inline uint8_t* nes_map_chr_addr(nes_mapper* map, - uint16_t addr) { - return map->chr_addr(map, addr); + void* data, + uint16_t addr) { + return map->chr_addr(data, addr); } static inline uint8_t nes_chr_read(nes_mapper* map, - uint16_t addr) { - return *(nes_map_chr_addr(map, addr)); + void* data, + uint16_t addr) { + return *(nes_map_chr_addr(map, data, addr)); } -static inline void nes_chr_write(nes_mapper* map, - uint16_t addr, uint8_t val) { - return map->chr_write(map, addr, val); +static inline void nes_chr_write(nes_mapper* map, void* data, + uint16_t addr, uint8_t val) { + return map->chr_write(data, addr, val); } static inline uint8_t* nes_map_vram_addr(nes_mapper* map, + void* data, uint16_t addr) { - return map->vram_addr(map, addr & 0x1FFFU); + return map->vram_addr(data, addr & 0x1FFFU); } static inline uint8_t nes_vram_read(nes_mapper* map, + void* data, uint16_t addr) { - return *(nes_map_vram_addr(map, addr)); + return *(nes_map_vram_addr(map, data, addr)); } static inline void nes_vram_write(nes_mapper* map, + void* data, uint16_t addr, uint8_t val) { - *(nes_map_vram_addr(map, addr)) = val; + *(nes_map_vram_addr(map, data, addr)) = val; } diff --git a/src/nes.c b/src/nes.c index 1ddbf09..7dd89bd 100644 --- a/src/nes.c +++ b/src/nes.c @@ -23,7 +23,8 @@ uint8_t nes_mem_read(nes* sys, uint16_t addr) { val = nes_apu_read(&sys->apu, addr); } else { - val = nes_map_read(sys->cart.mapper, addr); + val = nes_map_read(sys->cart.mapper, + sys->cart.map_data, addr); } return val; @@ -55,7 +56,8 @@ void nes_mem_write(nes* sys, uint16_t addr, uint8_t val) { nes_apu_write(&sys->apu, addr, val); } else { - nes_map_write(sys->cart.mapper, addr, val); + nes_map_write(sys->cart.mapper, sys->cart.map_data, + addr, val); } } @@ -84,6 +86,7 @@ void nes_done(nes* sys) { int nes_setup_cart(nes* sys) { nes_map_set_irq(sys->cart.mapper, nes_irq, sys); sys->ppu.mapper = sys->cart.mapper; + sys->ppu.map_data = sys->cart.map_data; nes_reset(sys); return 0; } diff --git a/src/ppu.c b/src/ppu.c index d70afe5..53a0a8d 100644 --- a/src/ppu.c +++ b/src/ppu.c @@ -43,12 +43,14 @@ uint8_t nes_ppu_read(nes_ppu* ppu, uint16_t addr) { if (ppu->addr < nes_ppu_mem_vram_start) { PPU_LOG("PPU: CHR MEM READ %04x > %02x\n", ppu->addr, val); - ppu->data = nes_chr_read(ppu->mapper, ppu->addr); + ppu->data = nes_chr_read(ppu->mapper, + ppu->map_data, + ppu->addr); } else if (ppu->addr < nes_ppu_mem_vram_start + nes_ppu_mem_vram_size) { VRAM_LOG("PPU: VRAM READ %04x > %02x\n", ppu->addr, val); ppu->data = nes_vram_read( - ppu->mapper, + ppu->mapper, ppu->map_data, ppu->addr - nes_ppu_mem_vram_start ); } else if (ppu->addr < nes_ppu_mem_pal_start) { @@ -186,11 +188,13 @@ void nes_ppu_write(nes_ppu* ppu, uint16_t addr, uint8_t val) { } #endif // DEBUG_VRAM // printf("PPU: VRAM %04x < %02x\n", vram_addr, val); - nes_vram_write(ppu->mapper, vram_addr, val); + nes_vram_write(ppu->mapper, ppu->map_data, + vram_addr, val); } else { // PPU_LOG("PPU: CHR MEM WRITE %04x > %02x\n", ppu->addr, val); - nes_chr_write(ppu->mapper, ppu->addr, val); + nes_chr_write(ppu->mapper, ppu->map_data, + ppu->addr, val); } ppu->addr += (ppu->control & ppu_Control_VRAM_Inc) ? @@ -212,6 +216,7 @@ void nes_ppu_reset(nes_ppu* ppu) { int nes_ppu_init(nes_ppu* ppu, const nes_cart* cart) { ppu->mapper = cart->mapper; + ppu->map_data = cart->map_data; ppu->status = 0; ppu->oam_addr = 0; ppu->addr = 0; @@ -237,7 +242,7 @@ nes_ppu_Result nes_ppu_run(nes_ppu* ppu, int cycles) { ppu->scanline < nes_ppu_render && (ppu->mask & (ppu_Mask_Back | ppu_Mask_Sprite)) && ppu->cycle < 260 && next_cycle >= 260) { - ppu->mapper->scanline(ppu->mapper); + ppu->mapper->scanline(ppu->map_data); } ppu->cycle = next_cycle; diff --git a/src/ppu.h b/src/ppu.h index 12a4acb..ee5a1e3 100644 --- a/src/ppu.h +++ b/src/ppu.h @@ -151,6 +151,7 @@ typedef struct { // System Interface struct nes_mapper_t* mapper; + void* map_data; } nes_ppu; uint8_t nes_ppu_read(nes_ppu* ppu, uint16_t addr); diff --git a/src/save.c b/src/save.c index b5f9ff3..2f64fd2 100644 --- a/src/save.c +++ b/src/save.c @@ -20,9 +20,9 @@ int load_sram(nes_cart* cart, const char* cart_filename) { int status = -1; int sram_size = cart->mapper->sram_size ? - cart->mapper->sram_size(cart->mapper) : 0; + cart->mapper->sram_size(cart->map_data) : 0; void* sram = cart->mapper->sram ? - cart->mapper->sram(cart->mapper) : NULL; + cart->mapper->sram(cart->map_data) : NULL; if (sram_size > 0 && NULL != sram) { char sram_filename[FILENAME_MAX] = {0}; @@ -39,9 +39,9 @@ int save_sram(const nes_cart* cart, const char* cart_filename) { if (NULL != cart->mapper) { int sram_size = cart->mapper->sram_size ? - cart->mapper->sram_size(cart->mapper) : 0; + cart->mapper->sram_size(cart->map_data) : 0; const void* sram = cart->mapper->sram ? - cart->mapper->sram(cart->mapper) : NULL; + cart->mapper->sram(cart->map_data) : NULL; if (sram_size > 0 && NULL != sram) { char sram_filename[FILENAME_MAX] = {0}; @@ -230,7 +230,7 @@ int state_size(const nes* sys) { size += szChunkHeader + ram_state_size(sys); // Cart should already be loaded size += szChunkHeader + - sys->cart.mapper->state_size(sys->cart.mapper); + sys->cart.mapper->state_size(sys->cart.map_data); return size; } @@ -273,8 +273,10 @@ int state_write(const nes* sys, void* mem, int size) { ptr += ram_state_write(sys, ptr); const nes_mapper* mapper = sys->cart.mapper; - ptr = write_header(ptr, tag_mapper, mapper->state_size(mapper)); - ptr += mapper->state_write(mapper, ptr); + const void* map_data = sys->cart.map_data; + ptr = write_header(ptr, tag_mapper, + mapper->state_size(map_data)); + ptr += mapper->state_write(map_data, ptr); return (ptr - mem); } @@ -336,7 +338,7 @@ int state_read(nes* sys, const void* mem, int mem_size) { } else if (tag_mapper == tag) { n_read = sys->cart.mapper->state_read( - sys->cart.mapper, ptr + sys->cart.map_data, ptr ); loaded |= Component_Mapper; diff --git a/src/sdl_render.c b/src/sdl_render.c index d4fe204..78ed2f7 100644 --- a/src/sdl_render.c +++ b/src/sdl_render.c @@ -33,7 +33,7 @@ static SDL_Color nes_palette[64] = { static inline uint8_t* chr_mem(const nes_ppu* ppu, uint16_t addr) { - return ppu->mapper->chr_addr(ppu->mapper, addr); + return ppu->mapper->chr_addr(ppu->map_data, addr); } @@ -243,6 +243,7 @@ static inline void render_bg_scanline_area( y = y % 8; int bank = (ppu->control & ppu_Control_Back_Bank) ? 0x100 : 0; const uint8_t* indexes = nes_map_vram_addr(ppu->mapper, + ppu->map_data, page << 10); const uint8_t* attrs = indexes + 960U; const uint8_t* index = indexes +