| @@ -56,7 +56,7 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { | |||
| int i_mapper = (hdr->flags_7 & ines_Mapper_Nibble_Hi) | | |||
| ((hdr->flags_6 & ines_Mapper_Nibble_Lo) >> 4); | |||
| const nes_Mapper *mapper = nes_mappers[i_mapper]; | |||
| if (NULL == mapper || NULL == mapper->init) { | |||
| if (NULL == mapper) { | |||
| LOGE("Mapper %d not supported", i_mapper); | |||
| status = -1; | |||
| } else { | |||
| @@ -78,6 +78,19 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { | |||
| LOGE("Failed to allocate mapper data"); | |||
| status = -1; | |||
| } else { | |||
| // Default PGM ROM | |||
| if (mem->n_rom_banks > 2) { | |||
| mem->rom_bank[0] = prg_rom_page(mem, 0); | |||
| mem->rom_bank[1] = prg_rom_page(mem, 1); | |||
| mem->rom_bank[2] = prg_rom_page(mem, 2); | |||
| mem->rom_bank[3] = prg_rom_page(mem, 3); | |||
| } else { | |||
| mem->rom_bank[0] = prg_rom_page(mem, 0); | |||
| mem->rom_bank[1] = prg_rom_page(mem, 1); | |||
| mem->rom_bank[2] = prg_rom_page(mem, 0); | |||
| mem->rom_bank[3] = prg_rom_page(mem, 1); | |||
| } | |||
| // PPU Bank 0 - 7: Default pattern tables | |||
| for (int page = 0; page < 8; ++page) { | |||
| mem->ppu.bank[page] = chr_page(&mem->ppu, page); | |||
| @@ -98,8 +111,10 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { | |||
| mem->sram_bank = mem->sram; | |||
| } | |||
| status = mem->mapper.init(&mem->mapper, | |||
| hdr, mem); | |||
| if (mem->mapper.init) { | |||
| status = mem->mapper.init(&mem->mapper, | |||
| hdr, mem); | |||
| } | |||
| } | |||
| // TODO: Deallocate mapper data when we're done | |||
| } | |||
| @@ -1,27 +1,8 @@ | |||
| #include "memory.h" | |||
| static int map000_init(nes_Mapper* map, const ines_Header* hdr, | |||
| nes_Memory* mem) { | |||
| if (mem->n_rom_banks > 2) { | |||
| mem->rom_bank[0] = prg_rom_page(mem, 0); | |||
| mem->rom_bank[1] = prg_rom_page(mem, 1); | |||
| mem->rom_bank[2] = prg_rom_page(mem, 2); | |||
| mem->rom_bank[3] = prg_rom_page(mem, 3); | |||
| } else { | |||
| mem->rom_bank[0] = prg_rom_page(mem, 0); | |||
| mem->rom_bank[1] = prg_rom_page(mem, 1); | |||
| mem->rom_bank[2] = prg_rom_page(mem, 0); | |||
| mem->rom_bank[3] = prg_rom_page(mem, 1); | |||
| } | |||
| return 0; | |||
| } | |||
| const nes_Mapper map000 = { | |||
| .name = "NROM", | |||
| .max_chr_banks = 8, | |||
| .data_size = 0, | |||
| .init = map000_init, | |||
| }; | |||
| @@ -0,0 +1,47 @@ | |||
| #include "memory.h" | |||
| typedef struct { | |||
| uint8_t bank; | |||
| } map003_data; | |||
| static inline void cnrom_set_bank(map003_data* data, | |||
| nes_Memory* mem, | |||
| uint8_t bank) { | |||
| data->bank = (bank % (mem->ppu.n_chr_banks / 8)); | |||
| mem->ppu.bank[0] = chr_page(&mem->ppu, (data->bank * 8) + 0); | |||
| mem->ppu.bank[1] = chr_page(&mem->ppu, (data->bank * 8) + 1); | |||
| mem->ppu.bank[2] = chr_page(&mem->ppu, (data->bank * 8) + 2); | |||
| mem->ppu.bank[3] = chr_page(&mem->ppu, (data->bank * 8) + 3); | |||
| mem->ppu.bank[4] = chr_page(&mem->ppu, (data->bank * 8) + 4); | |||
| mem->ppu.bank[5] = chr_page(&mem->ppu, (data->bank * 8) + 5); | |||
| mem->ppu.bank[6] = chr_page(&mem->ppu, (data->bank * 8) + 6); | |||
| mem->ppu.bank[7] = chr_page(&mem->ppu, (data->bank * 8) + 7); | |||
| } | |||
| static void map003_reset(nes_Mapper* map, nes_Memory* mem) { | |||
| cnrom_set_bank((map003_data*)map->data, mem, 0); | |||
| } | |||
| static int map003_init(nes_Mapper* map, const ines_Header* hdr, | |||
| nes_Memory* mem) { | |||
| map003_reset(map, mem); | |||
| return 0; | |||
| } | |||
| static int map003_write_rom(nes_Mapper* map, nes_Memory* mem, | |||
| uint16_t addr, uint8_t val) { | |||
| cnrom_set_bank((map003_data*)map->data, mem, val); | |||
| return 0; | |||
| } | |||
| const nes_Mapper map003 = { | |||
| .name = "CNROM", | |||
| .max_chr_banks = 8, | |||
| .data_size = sizeof(map003_data), | |||
| .init = map003_init, | |||
| .reset = map003_reset, | |||
| .write_rom = map003_write_rom, | |||
| }; | |||
| @@ -4,9 +4,11 @@ | |||
| extern const nes_Mapper map000; | |||
| extern const nes_Mapper map001; | |||
| extern const nes_Mapper map002; | |||
| extern const nes_Mapper map003; | |||
| const nes_Mapper* nes_mappers[256] = { | |||
| &map000, | |||
| &map001, | |||
| &map002, | |||
| &map003, | |||
| }; | |||