| @@ -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) | | int i_mapper = (hdr->flags_7 & ines_Mapper_Nibble_Hi) | | ||||
| ((hdr->flags_6 & ines_Mapper_Nibble_Lo) >> 4); | ((hdr->flags_6 & ines_Mapper_Nibble_Lo) >> 4); | ||||
| const nes_Mapper *mapper = nes_mappers[i_mapper]; | const nes_Mapper *mapper = nes_mappers[i_mapper]; | ||||
| if (NULL == mapper || NULL == mapper->init) { | |||||
| if (NULL == mapper) { | |||||
| LOGE("Mapper %d not supported", i_mapper); | LOGE("Mapper %d not supported", i_mapper); | ||||
| status = -1; | status = -1; | ||||
| } else { | } else { | ||||
| @@ -78,6 +78,19 @@ int nes_cart_load_mem(void* data, int size, nes* sys) { | |||||
| LOGE("Failed to allocate mapper data"); | LOGE("Failed to allocate mapper data"); | ||||
| status = -1; | status = -1; | ||||
| } else { | } 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 | // PPU Bank 0 - 7: Default pattern tables | ||||
| for (int page = 0; page < 8; ++page) { | for (int page = 0; page < 8; ++page) { | ||||
| mem->ppu.bank[page] = chr_page(&mem->ppu, 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; | 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 | // TODO: Deallocate mapper data when we're done | ||||
| } | } | ||||
| @@ -1,27 +1,8 @@ | |||||
| #include "memory.h" | #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 = { | const nes_Mapper map000 = { | ||||
| .name = "NROM", | .name = "NROM", | ||||
| .max_chr_banks = 8, | .max_chr_banks = 8, | ||||
| .data_size = 0, | .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 map000; | ||||
| extern const nes_Mapper map001; | extern const nes_Mapper map001; | ||||
| extern const nes_Mapper map002; | extern const nes_Mapper map002; | ||||
| extern const nes_Mapper map003; | |||||
| const nes_Mapper* nes_mappers[256] = { | const nes_Mapper* nes_mappers[256] = { | ||||
| &map000, | &map000, | ||||
| &map001, | &map001, | ||||
| &map002, | &map002, | ||||
| &map003, | |||||
| }; | }; | ||||