#include #include #include #include #include "rom.h" void parse_rom(const uint8_t *data, size_t data_len, struct rom *rom) { size_t prg_rom_offset = 16; size_t chr_rom_offset = 0; if (data_len < 16) { fprintf(stderr, "Invalid ROM: size less than 16 bytes\n"); exit(1); } if (data[0] != 'N' || data[1] != 'E' || data[2] != 'S' || data[3] != 0x1A) { fprintf(stderr, "Invalid ROM: not in iNES format\n"); exit(1); } /* trainer data present */ if (data[6] & (1 << 2)) prg_rom_offset += 512; rom->prg_rom_size = data[4] * 0x4000; rom->prg_rom = calloc(rom->prg_rom_size, 1); memcpy(rom->prg_rom, data + prg_rom_offset, rom->prg_rom_size); rom->chr_rom_size = data[5] * 0x2000; if (rom->chr_rom_size > 0) { rom->chr_rom = calloc(rom->chr_rom_size, 1); chr_rom_offset = prg_rom_offset + rom->prg_rom_size; memcpy(rom->chr_rom, data + chr_rom_offset, rom->chr_rom_size); } if ((data[6] & (1 << 3)) != 0) rom->mirror = M_FOUR; else if ((data[6] & 1) == 1) rom->mirror = M_VERTICAL; else if ((data[6] & 1) == 0) rom->mirror = M_HORIZONTAL; rom->mapper = (data[6] & (0xF << 4)) >> 4; rom->mapper |= data[7] & (0xF << 4); } void free_rom(struct rom *rom) { free(rom->prg_rom); if (rom->chr_rom_size > 0) free(rom->chr_rom); }