summaryrefslogtreecommitdiff
path: root/rom.c
diff options
context:
space:
mode:
authorvin <git@vineetk.net>2024-06-17 14:46:00 +0530
committervin <git@vineetk.net>2024-06-17 14:46:46 +0530
commit77d37dd455f804c79969979eb39d525b3c5ddfe7 (patch)
tree5cc5ba7972615cdc473f6897a80348c255725c6a /rom.c
parent1f6e3b054cd7a35c5eb8d908525a261ea83d44e7 (diff)
implement basic iNES and Mapper 0 ROM loading
It seems like the test ROM loads fine but the instructions are not, but that's exactly what the test ROM is for I suppose.
Diffstat (limited to 'rom.c')
-rw-r--r--rom.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/rom.c b/rom.c
new file mode 100644
index 0000000..d432cc2
--- /dev/null
+++ b/rom.c
@@ -0,0 +1,56 @@
1#include <stdint.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
5
6#include "rom.h"
7
8void
9parse_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
50void
51free_rom(struct Rom *rom)
52{
53 free(rom->prg_rom);
54 if (rom->chr_rom_size > 0)
55 free(rom->chr_rom);
56}