#include "cart.h" #include "filemap.h" #include "ines.h" #include "mapper.h" int nes_cart_init_mem(nes_cart* cart, void* mem, int len) { int status = 0; ines_Header *hdr = (ines_Header*)mem; void* ptr = &hdr[1]; cart->ines_mem = mem; cart->ines_size = len; status = ines_check_mem(hdr); if (0 == status && (hdr->flags_6 & ines_Flag_Trainer)) { // Skip trainer ptr += ines_trainer_size; } if (0 == status) { int prg_size = nes_prg_rom_page_size * hdr->prg_size_lsb; if (prg_size <= 0) { INES_ERR("Bad program ROM size: %#x", prg_size); status = -1; } else { INES_INFO("%d KB PRG ROM", prg_size / 1024); cart->prg_rom = ptr; cart->prg_rom_banks = hdr->prg_size_lsb; } ptr += prg_size; } if (0 == status) { int chr_size = nes_chr_page_size * hdr->chr_size_lsb; INES_INFO("%d KB CHR ROM", chr_size / 1024); cart->chr_rom = ptr; cart->chr_rom_banks = hdr->chr_size_lsb * 2; ptr += chr_size; int index = (hdr->flags_6 & ines_Mapper_Nibble_Lo) >> 4 | (hdr->flags_7 & ines_Mapper_Nibble_Hi); cart->mapper = nes_mappers[index]; if (NULL == cart->mapper) { INES_ERR("No mapper found for type %d", index); status = -1; } else if (NULL != cart->mapper->name) { INES_INFO("Mapper: %s", cart->mapper->name); } } if (0 == status) { if (hdr->flags_6 & ines_Flag_Horizontal) { cart->flags |= Cart_Flag_Horizontal; } else { cart->flags &= ~Cart_Flag_Horizontal; } // Don't initialize the mapper until all flags are set! status = nes_map_init(cart->mapper, cart); } return status; } void nes_cart_done(nes_cart* cart) { if (NULL != cart->ines_mem) { unmap_file(cart->ines_mem, cart->ines_size); cart->ines_mem = NULL; } } int nes_cart_init_file(nes_cart* cart, FILE* file) { int status = 0; int size = -1; void* mem = NULL; // Get file size status = fseek(file, 0, SEEK_END); if (0 != status) { INES_ERR("Failed to check file size"); } else { size = ftell(file); } // Map file if (0 == status) { mem = map_file(file, size); if (NULL == mem) { INES_ERR("Failed to map file (%d bytes)", size); status = -1; } } // Check in memory; unmap on failure if (0 == status) { status = nes_cart_init_mem(cart, mem, size); if (0 != status) { unmap_file(file, size); } } return status; }