|
- #include <stdlib.h>
- #include <string.h>
-
- #include "map.h"
-
-
- typedef struct {
- uint8_t* prg_rom;
- int prg_rom_banks;
- uint8_t mirror;
-
- uint8_t bank;
- uint8_t vram[nes_vram_page_size * 2];
- uint8_t chr_ram[8 * 1024];
-
- uint8_t* prg_bank_lo;
- uint8_t* prg_bank_hi;
- } uxrom_mapper;
-
- static void uxrom_set_bank(uxrom_mapper* map, uint8_t bank) {
- map->bank = (bank % map->prg_rom_banks);
- map->prg_bank_lo = &map->prg_rom[
- map->bank * nes_prg_rom_page_size
- ];
- }
-
- 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 void* uxrom_init(nes_mapper* nes_map, nes_cart* cart) {
- uxrom_mapper* map = calloc(1, sizeof(uxrom_mapper));
- 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(map);
- }
- return map;
- }
-
- static void uxrom_done(void* data) {
- free(data);
- }
-
- static inline uint8_t* uxrom_prg_addr(uxrom_mapper* map,
- uint16_t addr) {
- uint8_t* bank = ( addr < 0xC000U ?
- map->prg_bank_lo : map->prg_bank_hi );
- return &(bank[addr & 0x3FFF]);
- }
-
-
- 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, addr));
- }
- return val;
- }
-
- 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(void* data, uint16_t addr) {
- return &((uxrom_mapper*)data)->chr_ram[addr];
- }
-
- 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(void* data,
- uint16_t addr, uint8_t val) {
- ((uxrom_mapper*)data)->chr_ram[addr] = val;
- }
-
-
- /* Save State */
-
- 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(void* _map, const void* data) {
- uxrom_mapper* map = (uxrom_mapper*)_map;
- const void* ptr = data;
-
- map->bank = *(uint32_t*)ptr;
- ptr += sizeof(uint32_t);
-
- memcpy(map->vram, ptr, sizeof(map->vram));
- ptr += sizeof(map->vram);
-
- memcpy(map->chr_ram, ptr, sizeof(map->chr_ram));
- ptr += sizeof(map->chr_ram);
-
- return (ptr - data);
- }
-
- int uxrom_state_write(const void* _map, void* data) {
- uxrom_mapper* map = (uxrom_mapper*)_map;
- void* ptr = data;
-
- uint32_t bank = map->bank;
- memcpy(ptr, &bank, sizeof(bank));
- ptr += sizeof(bank);
-
- memcpy(ptr, map->vram, sizeof(map->vram));
- ptr += sizeof(map->vram);
-
- memcpy(ptr, map->chr_ram, sizeof(map->chr_ram));
- ptr += sizeof(map->chr_ram);
-
- return (ptr - data);
- }
-
-
- nes_mapper mapper_uxrom = {
- .name = "UxROM",
- .init = uxrom_init,
- .reset = uxrom_reset,
- .done = uxrom_done,
- .read = uxrom_read,
- .write = uxrom_write,
- .chr_addr = uxrom_chr_addr,
- .vram_addr = uxrom_vram_addr,
- .chr_write = uxrom_chr_write,
-
- .state_size = uxrom_state_size,
- .state_read = uxrom_state_read,
- .state_write = uxrom_state_write,
- };
|