diff --git a/retro-core/components/nofrendo/nes/mem.c b/retro-core/components/nofrendo/nes/mem.c index 10ce5d9e8..dc2f29b9c 100644 --- a/retro-core/components/nofrendo/nes/mem.c +++ b/retro-core/components/nofrendo/nes/mem.c @@ -54,17 +54,23 @@ static const mem_write_handler_t write_handlers[] = /* Set 2KB memory page */ void mem_setpage(uint32 page, uint8 *ptr) { - ASSERT(page < 32); - ASSERT(ptr); + if (page >= MEM_PAGECOUNT) + { + MESSAGE_ERROR("Invalid page #%d (max: %d) !\n", page, MEM_PAGECOUNT); + return; + } - mem.pages[page] = ptr - (page * MEM_PAGESIZE); + if (ptr) + mem.pages[page] = ptr - (page * MEM_PAGESIZE); + else + mem.pages[page] = NULL; - if (!MEM_PAGE_HAS_HANDLERS(mem.pages_read[page])) + if (mem.pages_read[page] != MEM_PAGE_HAS_HANDLERS) { mem.pages_read[page] = mem.pages[page]; } - if (!MEM_PAGE_HAS_HANDLERS(mem.pages_write[page])) + if (mem.pages_write[page] != MEM_PAGE_HAS_HANDLERS) { mem.pages_write[page] = mem.pages[page]; } @@ -73,16 +79,16 @@ void mem_setpage(uint32 page, uint8 *ptr) /* Get 2KB memory page */ uint8 *mem_getpage(uint32 page) { - ASSERT(page < 32); - - uint8 *page_ptr = mem.pages[page]; - - if (MEM_PAGE_IS_VALID_PTR(page_ptr)) + if (page >= MEM_PAGECOUNT) { - return page_ptr + (page * MEM_PAGESIZE); + MESSAGE_ERROR("Invalid page #%d (max: %d) !\n", page, MEM_PAGECOUNT); + return NULL; } - return page_ptr; + if (!mem.pages[page]) + return NULL; + + return mem.pages[page] + (page * MEM_PAGESIZE); } /* read a byte of 6502 memory space */ @@ -91,7 +97,7 @@ IRAM_ATTR uint8 mem_getbyte(uint32 address) uint8 *page = mem.pages_read[address >> MEM_PAGESHIFT]; /* Special memory handlers */ - if (MEM_PAGE_HAS_HANDLERS(page)) + if (page == MEM_PAGE_HAS_HANDLERS) { for (mem_read_handler_t *mr = mem.read_handlers; mr->read_func != NULL; mr++) { @@ -102,16 +108,13 @@ IRAM_ATTR uint8 mem_getbyte(uint32 address) } /* Unmapped region */ - if (page == NULL) + if (page == MEM_PAGE_NOT_MAPPED) { MESSAGE_DEBUG("Read unmapped region: $%4X\n", address); return 0xFF; } - /* Paged memory */ - else - { - return page[address]; - } + + return page[address]; } /* write a byte of data to 6502 memory space */ @@ -120,7 +123,7 @@ IRAM_ATTR void mem_putbyte(uint32 address, uint8 value) uint8 *page = mem.pages_write[address >> MEM_PAGESHIFT]; /* Special memory handlers */ - if (MEM_PAGE_HAS_HANDLERS(page)) + if (page == MEM_PAGE_HAS_HANDLERS) { for (mem_write_handler_t *mw = mem.write_handlers; mw->write_func != NULL; mw++) { @@ -134,15 +137,13 @@ IRAM_ATTR void mem_putbyte(uint32 address, uint8 value) } /* Unmapped region */ - if (page == NULL) + if (page == MEM_PAGE_NOT_MAPPED) { MESSAGE_DEBUG("Write to unmapped region: $%2X to $%4X\n", address, value); + return; } - /* Paged memory */ - else - { - page[address] = value; - } + + page[address] = value; } IRAM_ATTR uint32 mem_getword(uint32 address) @@ -154,12 +155,17 @@ void mem_reset(void) { memset(&mem, 0, sizeof(mem)); - mem_setpage(0, mem.ram); + mem_setpage(0, mem.ram); // $000 - $7FF mem_setpage(1, mem.ram); // $800 - $FFF mirror mem_setpage(2, mem.ram); // $1000 - $07FF mirror mem_setpage(3, mem.ram); // $1800 - $1FFF mirror - int num_read_handlers = 0, num_write_handlers = 0; + for (size_t i = 4; i < MEM_PAGECOUNT; ++i) + { + mem_setpage(i, MEM_PAGE_NOT_MAPPED); + } + + size_t num_read_handlers = 0, num_write_handlers = 0; mapper_t *mapper = nes_getptr()->mapper; // NES cartridge handlers @@ -189,13 +195,13 @@ void mem_reset(void) for (mem_read_handler_t *mr = mem.read_handlers; mr->read_func != NULL; mr++) { for (int i = mr->min_range; i < mr->max_range; i++) - mem.pages_read[i >> MEM_PAGESHIFT] = MEM_PAGE_USE_HANDLERS; + mem.pages_read[i >> MEM_PAGESHIFT] = MEM_PAGE_HAS_HANDLERS; } for (mem_write_handler_t *mw = mem.write_handlers; mw->write_func != NULL; mw++) { for (int i = mw->min_range; i < mw->max_range; i++) - mem.pages_write[i >> MEM_PAGESHIFT] = MEM_PAGE_USE_HANDLERS; + mem.pages_write[i >> MEM_PAGESHIFT] = MEM_PAGE_HAS_HANDLERS; } ASSERT(num_read_handlers <= MEM_HANDLERS_MAX); diff --git a/retro-core/components/nofrendo/nes/mem.h b/retro-core/components/nofrendo/nes/mem.h index 2229c9911..62413001e 100644 --- a/retro-core/components/nofrendo/nes/mem.h +++ b/retro-core/components/nofrendo/nes/mem.h @@ -32,12 +32,8 @@ #define MEM_RAMSIZE 0x800 // This is kind of a hack, but for speed... -#define MEM_PAGE_USE_HANDLERS ((uint8*)1) -#define MEM_PAGE_READ_ONLY ((uint8*)2) -#define MEM_PAGE_WRITE_ONLY ((uint8*)3) - -#define MEM_PAGE_HAS_HANDLERS(page) ((page) == MEM_PAGE_USE_HANDLERS) -#define MEM_PAGE_IS_VALID_PTR(page) ((page) > ((uint8*)100)) +#define MEM_PAGE_HAS_HANDLERS ((uint8*)1) +#define MEM_PAGE_NOT_MAPPED NULL #define MEM_HANDLERS_MAX 32 diff --git a/retro-core/components/nofrendo/nes/mmc.c b/retro-core/components/nofrendo/nes/mmc.c index 31cc14ad8..90873cd78 100644 --- a/retro-core/components/nofrendo/nes/mmc.c +++ b/retro-core/components/nofrendo/nes/mmc.c @@ -30,6 +30,7 @@ static rom_t *cart; /* PRG-ROM/RAM bankswitching */ void mmc_bankprg(unsigned size, unsigned address, int bank, uint8 *base) { + // ASSERT(size == 8 || size == 16 || size == 32); size_t banks = 16; // if (base == PRG_ANY) @@ -46,40 +47,31 @@ void mmc_bankprg(unsigned size, unsigned address, int bank, uint8 *base) banks = cart->prg_ram_banks; } - if (base == NULL) - { - MESSAGE_ERROR("MMC: Invalid pointer! Addr: $%04X Bank: %d Size: %d\n", address, bank, size); - abort(); - } - - switch (size) - { - case 8: - base += ((bank >= 0 ? bank : (banks) + bank) % (banks)) << 13; - break; - - case 16: - base += ((bank >= 0 ? bank : (banks / 2) + bank) % (banks / 2)) << 14; - break; + banks /= (size / 8); - case 32: - base += ((bank >= 0 ? bank : (banks / 4) + bank) % (banks / 4)) << 15; - break; + if (bank < 0) + bank += banks; - default: - MESSAGE_ERROR("MMC: Invalid bank size! Addr: $%04X Bank: %d Size: %d\n", address, bank, size); - abort(); + if (base == NULL || banks == 0 || bank < 0) // || bank > banks) + { + MESSAGE_ERROR("MMC: Bogus PRG mapping! Address: $%04X, Size: %dKB, Bank: %d, Banks: %d, Base: %p\n", + address, size, bank, banks, base); + return; } - for (int i = 0; i < (size * 0x400 / MEM_PAGESIZE); i++) + bank %= banks; + base += bank * (size * 1024); + + for (size_t i = 0, num = (size * 1024 / MEM_PAGESIZE); i < num; ++i) { - mem_setpage((address >> MEM_PAGESHIFT) + i, base + i * MEM_PAGESIZE); + mem_setpage((address >> MEM_PAGESHIFT) + i, &base[i * MEM_PAGESIZE]); } } /* CHR-ROM/RAM bankswitching */ void mmc_bankchr(unsigned size, unsigned address, int bank, uint8 *base) { + // ASSERT(size == 1 || size == 2 || size == 4 || size == 8); size_t banks = 128; if (base == CHR_ANY) @@ -96,32 +88,22 @@ void mmc_bankchr(unsigned size, unsigned address, int bank, uint8 *base) banks = cart->chr_ram_banks; } - switch (size) + banks *= (8 / size); + + if (bank < 0) + bank += banks; + + if (base == NULL || banks == 0 || bank < 0) // || bank > banks) { - case 1: - bank = (bank >= 0 ? bank : (banks * 8) + bank) % (banks * 8); - ppu_setpage(1, address >> 10, &base[bank << 10] - address); - break; - - case 2: - bank = (bank >= 0 ? bank : (banks * 4) + bank) % (banks * 4); - ppu_setpage(2, address >> 10, &base[bank << 11] - address); - break; - - case 4: - bank = (bank >= 0 ? bank : (banks * 2) + bank) % (banks * 2); - ppu_setpage(4, address >> 10, &base[bank << 12] - address); - break; - - case 8: - bank = (bank >= 0 ? bank : (banks) + bank) % (banks); - ppu_setpage(8, 0, &base[bank << 13]); - break; - - default: - MESSAGE_ERROR("MMC: Invalid CHR bank size %d\n", size); - abort(); + MESSAGE_ERROR("MMC: Bogus CHR mapping! Address: $%04X, Size: %dKB, Bank: %d, Banks: %d, Base: %p\n", + address, size, bank, banks, base); + return; } + + bank %= banks; + base += bank * (size * 1024); + + ppu_setpage(size, address >> 10, base - address); } /* Mapper initialization routine */ diff --git a/retro-core/components/nofrendo/nes/ppu.c b/retro-core/components/nofrendo/nes/ppu.c index 3d976cfb7..2db6ba862 100644 --- a/retro-core/components/nofrendo/nes/ppu.c +++ b/retro-core/components/nofrendo/nes/ppu.c @@ -337,7 +337,7 @@ IRAM_ATTR void ppu_write(uint32 address, uint8 value) } } -void ppu_setopt(ppu_option_t n, uint8_t val) +void ppu_setopt(ppu_option_t n, int val) { // Some options need special care switch (n) @@ -349,7 +349,7 @@ void ppu_setopt(ppu_option_t n, uint8_t val) ppu.options[n] = val; } -uint8_t ppu_getopt(ppu_option_t n) +int ppu_getopt(ppu_option_t n) { return ppu.options[n]; } diff --git a/retro-core/components/nofrendo/nes/ppu.h b/retro-core/components/nofrendo/nes/ppu.h index 655f30e4e..b58a24ce2 100644 --- a/retro-core/components/nofrendo/nes/ppu.h +++ b/retro-core/components/nofrendo/nes/ppu.h @@ -132,7 +132,7 @@ typedef struct bool vram_present; /* Misc runtime options */ - uint8_t options[16]; + int options[16]; } ppu_t; /* Mirroring / Paging */ @@ -144,12 +144,11 @@ uint8 *ppu_getnametable(int nt); /* Control */ ppu_t *ppu_init(void); -void ppu_refresh(void); void ppu_reset(void); void ppu_shutdown(void); bool ppu_enabled(void); -void ppu_setopt(ppu_option_t n, uint8_t val); -uint8_t ppu_getopt(ppu_option_t n); +void ppu_setopt(ppu_option_t n, int val); +int ppu_getopt(ppu_option_t n); void ppu_setlatchfunc(ppu_latchfunc_t func); void ppu_setvreadfunc(ppu_vreadfunc_t func); diff --git a/retro-core/components/nofrendo/nes/rom.c b/retro-core/components/nofrendo/nes/rom.c index 65215f6a2..6d7122496 100644 --- a/retro-core/components/nofrendo/nes/rom.c +++ b/retro-core/components/nofrendo/nes/rom.c @@ -146,7 +146,7 @@ rom_t *rom_loadmem(uint8 *data, size_t size) if (entry->prg_ram != rom.prg_ram_banks) { MESSAGE_WARN("ROM: prg_ram_banks mismatch! (DB: %d, ROM: %d)\n", entry->prg_ram, rom.prg_ram_banks); - // rom.prg_rom_banks = entry->prg_ram; + // rom.prg_ram_banks = entry->prg_ram; } if (entry->chr_rom > -1 && entry->chr_rom != rom.chr_rom_banks)