rom.c (1312B)
1 #include <stdint.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 6 #include "rom.h" 7 8 void 9 parse_rom(const uint8_t *data, size_t data_len, struct rom *rom) 10 { 11 size_t prg_rom_offset = 16; 12 size_t chr_rom_offset = 0; 13 14 if (data_len < 16) { 15 fprintf(stderr, "Invalid ROM: size less than 16 bytes\n"); 16 exit(1); 17 } 18 19 if (data[0] != 'N' || data[1] != 'E' || data[2] != 'S' || data[3] != 0x1A) { 20 fprintf(stderr, "Invalid ROM: not in iNES format\n"); 21 exit(1); 22 } 23 24 /* trainer data present */ 25 if (data[6] & (1 << 2)) 26 prg_rom_offset += 512; 27 28 rom->prg_rom_size = data[4] * 0x4000; 29 rom->prg_rom = calloc(rom->prg_rom_size, 1); 30 memcpy(rom->prg_rom, data + prg_rom_offset, rom->prg_rom_size); 31 32 rom->chr_rom_size = data[5] * 0x2000; 33 if (rom->chr_rom_size > 0) { 34 rom->chr_rom = calloc(rom->chr_rom_size, 1); 35 chr_rom_offset = prg_rom_offset + rom->prg_rom_size; 36 memcpy(rom->chr_rom, data + chr_rom_offset, rom->chr_rom_size); 37 } 38 39 if ((data[6] & (1 << 3)) != 0) 40 rom->mirror = M_FOUR; 41 else if ((data[6] & 1) == 1) 42 rom->mirror = M_VERTICAL; 43 else if ((data[6] & 1) == 0) 44 rom->mirror = M_HORIZONTAL; 45 46 rom->mapper = (data[6] & (0xF << 4)) >> 4; 47 rom->mapper |= data[7] & (0xF << 4); 48 } 49 50 void 51 free_rom(struct rom *rom) 52 { 53 free(rom->prg_rom); 54 if (rom->chr_rom_size > 0) 55 free(rom->chr_rom); 56 }