summaryrefslogtreecommitdiff
path: root/mappers
diff options
context:
space:
mode:
Diffstat (limited to 'mappers')
-rw-r--r--mappers/mapper.c8
-rw-r--r--mappers/mapper.h6
-rw-r--r--mappers/mapper_000_0.c5
-rw-r--r--mappers/mapper_001_0.c121
-rw-r--r--mappers/mapper_001_0.h14
-rw-r--r--mappers/mapper_002_2.c5
-rw-r--r--mappers/mapper_003_0.c31
-rw-r--r--mappers/mapper_003_0.h4
-rw-r--r--mappers/mapper_003_1.c31
-rw-r--r--mappers/mapper_003_1.h4
-rw-r--r--mappers/mapper_003_2.c5
-rw-r--r--mappers/mapper_007_2.c8
-rw-r--r--mappers/mapper_011_0.c5
-rw-r--r--mappers/mapper_066_0.c4
14 files changed, 247 insertions, 4 deletions
diff --git a/mappers/mapper.c b/mappers/mapper.c
index 099b6d7..71caff1 100644
--- a/mappers/mapper.c
+++ b/mappers/mapper.c
@@ -23,7 +23,10 @@ static void mapper_default_chr_write(struct nes_state *state, uint32_t addr, uin
static void mapper_default_tick(struct nes_state *state) { }
#include "mapper_000_0.c"
+#include "mapper_001_0.c"
#include "mapper_002_2.c"
+#include "mapper_003_0.c"
+#include "mapper_003_1.c"
#include "mapper_003_2.c"
#include "mapper_007_2.c"
#include "mapper_011_0.c"
@@ -33,7 +36,10 @@ static void mapper_default_tick(struct nes_state *state) { }
static void (*mapper_table[4096])(struct nes_state *state) = {
[MAPPER_ID( 0, 0)] = mapper_000_0_init,
+ [MAPPER_ID( 1, 0)] = mapper_001_0_init,
[MAPPER_ID( 2, 2)] = mapper_002_2_init,
+ [MAPPER_ID( 3, 0)] = mapper_003_0_init,
+ [MAPPER_ID( 3, 1)] = mapper_003_1_init,
[MAPPER_ID( 3, 2)] = mapper_003_2_init,
[MAPPER_ID( 7, 2)] = mapper_007_2_init,
[MAPPER_ID(11, 0)] = mapper_011_0_init,
@@ -52,6 +58,8 @@ static void mapper_reset(struct nes_state *state) {
static void mapper_setup(struct nes_state *state) {
uint32_t mapper = state->ines.mapper << 4 | state->ines.submapper;
+ printf("Mapper %d_%x requested.\n", state->ines.mapper, state->ines.submapper);
+
mapper_reset(state);
if(mapper_table[mapper]) {
mapper_table[mapper](state);
diff --git a/mappers/mapper.h b/mappers/mapper.h
index 863201b..20ee906 100644
--- a/mappers/mapper.h
+++ b/mappers/mapper.h
@@ -1,6 +1,9 @@
#include "mapper_000_0.h"
+#include "mapper_001_0.h"
#include "mapper_002_2.h"
+#include "mapper_003_0.h"
+#include "mapper_003_1.h"
#include "mapper_003_2.h"
#include "mapper_007_2.h"
#include "mapper_011_0.h"
@@ -20,7 +23,10 @@ struct mapper_functions {
union mapper_data {
struct mapper_000_0 m000_0;
+ struct mapper_001_0 m001_0;
struct mapper_002_2 m002_2;
+ struct mapper_003_2 m003_0;
+ struct mapper_003_2 m003_1;
struct mapper_003_2 m003_2;
struct mapper_007_2 m007_2;
struct mapper_011_0 m011_0;
diff --git a/mappers/mapper_000_0.c b/mappers/mapper_000_0.c
index b79cdbf..8e46090 100644
--- a/mappers/mapper_000_0.c
+++ b/mappers/mapper_000_0.c
@@ -1,17 +1,18 @@
-__attribute__((hot))
+__attribute__((section(".mapper_000_0"), hot))
static uint8_t mapper_000_0_prg_read(struct nes_state *state, uint32_t addr) {
struct mapper_000_0 *mapper = (struct mapper_000_0 *)&state->map;
return state->prg_rom[addr & mapper->mask];
}
-__attribute__((hot))
+__attribute__((section(".mapper_000_0"), hot))
static uint8_t mapper_000_0_chr_read(struct nes_state *state, uint32_t addr) {
return state->chr_rom[addr];
}
+__attribute__((section(".mapper_000_0")))
static void mapper_000_0_init(struct nes_state *state) {
struct mapper_000_0 *mapper = (struct mapper_000_0 *)&state->map;
state->mapper.prg_read = mapper_000_0_prg_read;
diff --git a/mappers/mapper_001_0.c b/mappers/mapper_001_0.c
new file mode 100644
index 0000000..519738e
--- /dev/null
+++ b/mappers/mapper_001_0.c
@@ -0,0 +1,121 @@
+
+__attribute__((section(".mapper_001_0"), hot))
+static uint8_t mapper_001_0_prg_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_001_0 *mapper = (struct mapper_001_0 *)&state->map;
+ if(addr >= 0x8000) {
+ if(addr < 0xc000) {
+ return mapper->prg_rom_0[addr & 0x3fff];
+ } else {
+ return mapper->prg_rom_1[addr & 0x3fff];
+ }
+ }
+ return 0;
+}
+
+__attribute__((section(".mapper_001_0"), hot))
+static void mapper_001_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_001_0 *mapper = (struct mapper_001_0 *)&state->map;
+ if(addr < 0x8000) return;
+
+ if(value & 0x80) {
+ mapper->shift = 0;
+ mapper->shift_count = 0;
+ mapper->control |= 0x0c;
+ return;
+ }
+
+ mapper->shift |= (value & 1) << mapper->shift_count;
+ mapper->shift_count++;
+
+ if(mapper->shift_count == 5) {
+ uint32_t bank;
+ uint8_t reg = (addr >> 13) & 0x03;
+ switch(reg) {
+ case 0: {// Control
+ mapper->control = mapper->shift;
+ } break;
+
+ case 1: { // CHR bank 0
+ mapper->chr_bank0 = mapper->shift;
+ mapper->chr_bank_0 = state->chr_rom + (mapper->chr_bank0 * 0x1000);
+ } break;
+
+ case 2: { // CHR bank 1
+ mapper->chr_bank1 = mapper->shift;
+ mapper->chr_bank_1 = state->chr_rom + (mapper->chr_bank1 * 0x1000);
+ } break;
+
+ case 3: { // PRG bank
+ mapper->prg_bank = mapper->shift & 0x0f;
+ if(mapper->control & 0x08) {
+ // 16KB bank switching
+ if(mapper->control & 0x04) {
+ mapper->prg_rom_0 = state->prg_rom + 0x4000 * 0;
+ mapper->prg_rom_1 = state->prg_rom + 0x4000 * mapper->prg_bank;
+ } else {
+ mapper->prg_rom_0 = state->prg_rom + 0x4000 * mapper->prg_bank;
+ mapper->prg_rom_1 = state->prg_rom + 0x4000 * (state->ines.prg_size / 0x4000 - 1);
+ }
+ } else {
+ // 32KB mode
+ bank = (mapper->prg_bank & 0x0e) * 0x4000;
+ mapper->prg_rom_0 = state->prg_rom + bank;
+ mapper->prg_rom_1 = state->prg_rom + bank + 0x4000;
+ }
+ } break;
+ }
+ mapper->shift = 0;
+ mapper->shift_count = 0;
+ }
+}
+
+__attribute__((section(".mapper_001_0"), hot))
+static uint8_t mapper_001_0_chr_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_001_0 *mapper = (struct mapper_001_0 *)&state->map;
+ if(mapper->control & 0x10) {
+ // 4KB mode
+ if(addr < 0x1000) {
+ return mapper->chr_bank_0[addr];
+ } else {
+ return mapper->chr_bank_1[addr - 0x1000];
+ }
+ } else {
+ // 8KB mode
+ return mapper->chr_bank_0[addr];
+ }
+}
+
+__attribute__((section(".mapper_001_0"), hot))
+static void mapper_001_0_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ // CHR RAM write (if present)
+ state->chr_ram[addr] = value;
+}
+
+__attribute__((section(".mapper_001_0"), hot))
+static uint8_t mapper_001_0_ciram_read(struct nes_state *state, uint32_t addr) {
+ return state->ciram[addr & 0x3ff];
+}
+
+__attribute__((section(".mapper_001_0"), hot))
+static void mapper_001_0_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ state->ciram[addr & 0x3ff] = value;
+}
+
+__attribute__((section(".mapper_001_0")))
+static void mapper_001_0_init(struct nes_state *state) {
+ struct mapper_001_0 *mapper = (struct mapper_001_0 *)&state->map;
+
+ mapper->control = 0x0c;
+ mapper->prg_rom_0 = state->prg_rom;
+ mapper->prg_rom_1 = state->prg_rom + (state->ines.prg_size - 0x4000);
+
+ mapper->chr_bank_0 = state->chr_rom;
+ mapper->chr_bank_1 = state->chr_rom + 0x1000;
+
+ state->mapper.prg_read = mapper_001_0_prg_read;
+ state->mapper.prg_write = mapper_001_0_prg_write;
+ state->mapper.chr_read = mapper_001_0_chr_read;
+ state->mapper.chr_write = mapper_001_0_chr_write;
+ state->mapper.ciram_read = mapper_001_0_ciram_read;
+ state->mapper.ciram_write = mapper_001_0_ciram_write;
+}
diff --git a/mappers/mapper_001_0.h b/mappers/mapper_001_0.h
new file mode 100644
index 0000000..deb0e29
--- /dev/null
+++ b/mappers/mapper_001_0.h
@@ -0,0 +1,14 @@
+
+struct mapper_001_0 {
+ uint8_t shift;
+ uint8_t shift_count;
+ uint8_t control;
+ uint8_t prg_bank;
+ uint8_t chr_bank0;
+ uint8_t chr_bank1;
+
+ uint8_t *prg_rom_0;
+ uint8_t *prg_rom_1;
+ uint8_t *chr_bank_0;
+ uint8_t *chr_bank_1;
+} __attribute__((packed, aligned(64)));
diff --git a/mappers/mapper_002_2.c b/mappers/mapper_002_2.c
index 079fb0b..b88c95b 100644
--- a/mappers/mapper_002_2.c
+++ b/mappers/mapper_002_2.c
@@ -1,5 +1,6 @@
+__attribute__((section(".mapper_002_2"), hot))
static uint8_t mapper_002_2_prg_read(struct nes_state *state, uint32_t addr) {
struct mapper_002_2 *mapper = (struct mapper_002_2 *)&state->map;
@@ -12,6 +13,7 @@ static uint8_t mapper_002_2_prg_read(struct nes_state *state, uint32_t addr) {
return 0;
}
+__attribute__((section(".mapper_002_2"), hot))
static void mapper_002_2_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_002_2 *mapper = (struct mapper_002_2 *)&state->map;
@@ -20,14 +22,17 @@ static void mapper_002_2_prg_write(struct nes_state *state, uint32_t addr, uint8
}
}
+__attribute__((section(".mapper_002_2"), hot))
static uint8_t mapper_002_2_chr_read(struct nes_state *state, uint32_t addr) {
return state->chr_ram[addr];
}
+__attribute__((section(".mapper_002_2"), hot))
static void mapper_002_2_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) {
state->chr_ram[addr] = value;
}
+__attribute__((section(".mapper_002_2")))
static void mapper_002_2_init(struct nes_state *state) {
struct mapper_002_2 *mapper = (struct mapper_002_2 *)&state->map;
diff --git a/mappers/mapper_003_0.c b/mappers/mapper_003_0.c
new file mode 100644
index 0000000..e85d995
--- /dev/null
+++ b/mappers/mapper_003_0.c
@@ -0,0 +1,31 @@
+
+__attribute__((section(".mapper_003_0"), hot))
+static uint8_t mapper_003_0_prg_read(struct nes_state *state, uint32_t addr) {
+ return state->prg_rom[addr & 0x7fff];
+}
+
+__attribute__((section(".mapper_003_0"), hot))
+static void mapper_003_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_003_0 *mapper = (struct mapper_003_0 *)&state->map;
+
+ if(addr >= 0x8000) {
+ mapper->chr_ptr = state->chr_rom + (value & 3) * 0x2000;
+ }
+}
+
+__attribute__((section(".mapper_003_0"), hot))
+static uint8_t mapper_003_0_chr_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_003_0 *mapper = (struct mapper_003_0 *)&state->map;
+ return mapper->chr_ptr[addr];
+}
+
+__attribute__((section(".mapper_003_0")))
+static void mapper_003_0_init(struct nes_state *state) {
+ struct mapper_003_0 *mapper = (struct mapper_003_0 *)&state->map;
+
+ mapper->chr_ptr = state->chr_rom;
+
+ state->mapper.prg_read = mapper_003_0_prg_read;
+ state->mapper.prg_write = mapper_003_0_prg_write;
+ state->mapper.chr_read = mapper_003_0_chr_read;
+}
diff --git a/mappers/mapper_003_0.h b/mappers/mapper_003_0.h
new file mode 100644
index 0000000..f03b106
--- /dev/null
+++ b/mappers/mapper_003_0.h
@@ -0,0 +1,4 @@
+
+struct mapper_003_0 {
+ uint8_t *chr_ptr;
+} __attribute__((packed, aligned(64)));
diff --git a/mappers/mapper_003_1.c b/mappers/mapper_003_1.c
new file mode 100644
index 0000000..fd7cd27
--- /dev/null
+++ b/mappers/mapper_003_1.c
@@ -0,0 +1,31 @@
+
+__attribute__((section(".mapper_003_1"), hot))
+static uint8_t mapper_003_1_prg_read(struct nes_state *state, uint32_t addr) {
+ return state->prg_rom[addr & 0x7fff];
+}
+
+__attribute__((section(".mapper_003_1"), hot))
+static void mapper_003_1_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_003_1 *mapper = (struct mapper_003_1 *)&state->map;
+
+ if(addr >= 0x8000) {
+ mapper->chr_ptr = state->chr_rom + (value & 3) * 0x2000;
+ }
+}
+
+__attribute__((section(".mapper_003_1"), hot))
+static uint8_t mapper_003_1_chr_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_003_1 *mapper = (struct mapper_003_1 *)&state->map;
+ return mapper->chr_ptr[addr];
+}
+
+__attribute__((section(".mapper_003_1")))
+static void mapper_003_1_init(struct nes_state *state) {
+ struct mapper_003_1 *mapper = (struct mapper_003_1 *)&state->map;
+
+ mapper->chr_ptr = state->chr_rom;
+
+ state->mapper.prg_read = mapper_003_1_prg_read;
+ state->mapper.prg_write = mapper_003_1_prg_write;
+ state->mapper.chr_read = mapper_003_1_chr_read;
+}
diff --git a/mappers/mapper_003_1.h b/mappers/mapper_003_1.h
new file mode 100644
index 0000000..c233a1a
--- /dev/null
+++ b/mappers/mapper_003_1.h
@@ -0,0 +1,4 @@
+
+struct mapper_003_1 {
+ uint8_t *chr_ptr;
+} __attribute__((packed, aligned(64)));
diff --git a/mappers/mapper_003_2.c b/mappers/mapper_003_2.c
index e93916a..b780a8f 100644
--- a/mappers/mapper_003_2.c
+++ b/mappers/mapper_003_2.c
@@ -1,21 +1,26 @@
+__attribute__((section(".mapper_003_2"), hot))
static uint8_t mapper_003_2_prg_read(struct nes_state *state, uint32_t addr) {
return state->prg_rom[addr & 0x7fff];
}
+__attribute__((section(".mapper_003_2"), hot))
static void mapper_003_2_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_003_2 *mapper = (struct mapper_003_2 *)&state->map;
if(addr >= 0x8000) {
+ value &= state->prg_rom[addr & 0x7fff];
mapper->chr_ptr = state->chr_rom + (value & 3) * 0x2000;
}
}
+__attribute__((section(".mapper_003_2"), hot))
static uint8_t mapper_003_2_chr_read(struct nes_state *state, uint32_t addr) {
struct mapper_003_2 *mapper = (struct mapper_003_2 *)&state->map;
return mapper->chr_ptr[addr];
}
+__attribute__((section(".mapper_003_2")))
static void mapper_003_2_init(struct nes_state *state) {
struct mapper_003_2 *mapper = (struct mapper_003_2 *)&state->map;
diff --git a/mappers/mapper_007_2.c b/mappers/mapper_007_2.c
index ed56dd0..27125b9 100644
--- a/mappers/mapper_007_2.c
+++ b/mappers/mapper_007_2.c
@@ -1,5 +1,5 @@
-
+__attribute__((section(".mapper_007_2"), hot))
static uint8_t mapper_007_2_prg_read(struct nes_state *state, uint32_t addr) {
struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map;
if(addr >= 0x8000) {
@@ -8,6 +8,7 @@ static uint8_t mapper_007_2_prg_read(struct nes_state *state, uint32_t addr) {
return 0;
}
+__attribute__((section(".mapper_007_2"), hot))
static void mapper_007_2_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map;
if(addr >= 0x8000) {
@@ -21,24 +22,29 @@ static void mapper_007_2_prg_write(struct nes_state *state, uint32_t addr, uint8
}
}
+__attribute__((section(".mapper_007_2"), hot))
static uint8_t mapper_007_2_chr_read(struct nes_state *state, uint32_t addr) {
return state->chr_ram[addr];
}
+__attribute__((section(".mapper_007_2"), hot))
static void mapper_007_2_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) {
state->chr_ram[addr] = value;
}
+__attribute__((section(".mapper_007_2"), hot))
static uint8_t mapper_007_2_ciram_read(struct nes_state *state, uint32_t addr) {
struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map;
return mapper->ciram[addr & 0x3ff];
}
+__attribute__((section(".mapper_007_2"), hot))
static void mapper_007_2_ciram_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map;
mapper->ciram[addr & 0x3ff] = value;
}
+__attribute__((section(".mapper_007_2")))
static void mapper_007_2_init(struct nes_state *state) {
struct mapper_007_2 *mapper = (struct mapper_007_2 *)&state->map;
mapper->prg_rom = state->prg_rom;
diff --git a/mappers/mapper_011_0.c b/mappers/mapper_011_0.c
index ce390a0..d6d518c 100644
--- a/mappers/mapper_011_0.c
+++ b/mappers/mapper_011_0.c
@@ -1,5 +1,5 @@
-
+__attribute__((section(".mapper_011_0"), hot))
static uint8_t mapper_011_0_prg_read(struct nes_state *state, uint32_t addr) {
struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map;
@@ -9,6 +9,7 @@ static uint8_t mapper_011_0_prg_read(struct nes_state *state, uint32_t addr) {
return 0;
}
+__attribute__((section(".mapper_011_0"), hot))
static void mapper_011_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map;
@@ -18,12 +19,14 @@ static void mapper_011_0_prg_write(struct nes_state *state, uint32_t addr, uint8
}
}
+__attribute__((section(".mapper_011_0"), hot))
static uint8_t mapper_011_0_chr_read(struct nes_state *state, uint32_t addr) {
struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map;
return mapper->chr_ptr[addr];
}
+__attribute__((section(".mapper_011_0")))
static void mapper_011_0_init(struct nes_state *state) {
struct mapper_011_0 *mapper = (struct mapper_011_0 *)&state->map;
diff --git a/mappers/mapper_066_0.c b/mappers/mapper_066_0.c
index bf31720..7a8f49c 100644
--- a/mappers/mapper_066_0.c
+++ b/mappers/mapper_066_0.c
@@ -1,4 +1,5 @@
+__attribute__((section(".mapper_066_0"), hot))
static uint8_t mapper_066_0_prg_read(struct nes_state *state, uint32_t addr) {
struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map;
@@ -8,6 +9,7 @@ static uint8_t mapper_066_0_prg_read(struct nes_state *state, uint32_t addr) {
return 0;
}
+__attribute__((section(".mapper_066_0"), hot))
static void mapper_066_0_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {
struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map;
@@ -20,11 +22,13 @@ static void mapper_066_0_prg_write(struct nes_state *state, uint32_t addr, uint8
}
}
+__attribute__((section(".mapper_066_0"), hot))
static uint8_t mapper_066_0_chr_read(struct nes_state *state, uint32_t addr) {
struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map;
return mapper->chr_offset[addr];
}
+__attribute__((section(".mapper_066_0")))
static void mapper_066_0_init(struct nes_state *state) {
struct mapper_066_0 *mapper = (struct mapper_066_0 *)&state->map;