summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Fors <peter.fors@mindkiller.com>2025-05-27 15:03:30 +0200
committerPeter Fors <peter.fors@mindkiller.com>2025-05-27 15:03:30 +0200
commit7cca3bdbec289328b537c8256b43dcfedc5d56b8 (patch)
tree181c22764d3d881ccd41d5c0282cd364d3f5197d
parenta8e0c141b0184d629504b9f0ee8dbc4fefb90934 (diff)
renaming
-rwxr-xr-xbuild.sh3
-rwxr-xr-xmapper_add.py8
-rw-r--r--mappers/mapper.c48
-rw-r--r--mappers/mapper.h10
-rw-r--r--mappers/mapper_000_0.c11
-rw-r--r--mappers/mapper_001_0.c24
-rw-r--r--mappers/mapper_002_2.c19
-rw-r--r--mappers/mapper_003_0.c16
-rw-r--r--mappers/mapper_003_1.c16
-rw-r--r--mappers/mapper_003_2.c16
-rw-r--r--mappers/mapper_007_2.c27
-rw-r--r--mappers/mapper_011_0.c18
-rw-r--r--mappers/mapper_066_0.c18
-rw-r--r--memory.c25
-rw-r--r--mknes.c100
-rw-r--r--mknes.h5
-rw-r--r--ppu.c29
-rw-r--r--ppu_registers.c8
18 files changed, 216 insertions, 185 deletions
diff --git a/build.sh b/build.sh
index 0660fbb..c796e72 100755
--- a/build.sh
+++ b/build.sh
@@ -6,6 +6,7 @@ PROJECT_NAME="mknes" # Change this for each new project
CC=gcc
# Base configuration common to all builds
+# CFLAGS="-std=gnu11 -mtune=generic "
CFLAGS="-std=gnu11 -mtune=generic "
CFLAGS+="-mbmi "
CFLAGS+="-mfunction-return=keep -mindirect-branch=keep "
@@ -45,8 +46,8 @@ fi
case "$BUILD_TYPE" in
"normal")
CFLAGS+=" -ggdb -fno-omit-frame-pointer -O2 -DDEBUG_INTERNAL"
+ # CFLAGS+=" -fsanitize=address,undefined,alignment,object-size,unreachable -fno-omit-frame-pointer"
# -pg # for gprof
-# -fsanitize=address,undefined,alignment,object-size,unreachable -fno-omit-frame-pointer"
;;
"release")
CFLAGS+=" -s -Wl,--strip-all -O2"
diff --git a/mapper_add.py b/mapper_add.py
index 151506b..7092ddb 100755
--- a/mapper_add.py
+++ b/mapper_add.py
@@ -12,11 +12,11 @@ def generate_mapper_files(mapper_id, submapper_id=0):
# Generate C file content
c_content = f"""#include "{filename}.h"
-static uint8_t {filename}_prg_read(struct nes_state *state, uint32_t addr) {{
+static uint8_t {filename}_prg_rom_read(struct nes_state *state, uint32_t addr) {{
return 0;
}}
-static void {filename}_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) {{
+static void {filename}_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {{
}}
static uint8_t {filename}_chr_read(struct nes_state *state, uint32_t addr) {{
@@ -37,8 +37,8 @@ static void {filename}_tick(struct nes_state *state) {{
}}
void {filename}_init(struct nes_state *state) {{
- state->mapper.prg_read = {filename}_prg_read;
- state->mapper.prg_write = {filename}_prg_write;
+ state->mapper.prg_rom_read = {filename}_prg_read;
+ state->mapper.prg_rom_write = {filename}_prg_rom_write;
state->mapper.chr_read = {filename}_chr_read;
state->mapper.chr_write = {filename}_chr_write;
state->mapper.ciram_read = {filename}_ciram_read;
diff --git a/mappers/mapper.c b/mappers/mapper.c
index 5636705..0b5612b 100644
--- a/mappers/mapper.c
+++ b/mappers/mapper.c
@@ -18,9 +18,32 @@ static void mapper_default_ciram_write(struct nes_state *state, uint32_t addr, u
state->ciram[addr] = value;
}
-static void mapper_default_prg_write(struct nes_state *state, uint32_t addr, uint8_t value) { }
-static void mapper_default_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { }
-static void mapper_default_tick(struct nes_state *state) { }
+// static void mapper_default_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) { }
+// static uint8_t mapper_default_prg_ram_read(struct nes_state *state, uint32_t addr) { return 0; }
+// static void mapper_default_prg_ram_write(struct nes_state *state, uint32_t addr, uint8_t value) { }
+// static void mapper_default_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) { }
+// static void mapper_default_tick(struct nes_state *state) { }
+
+__attribute__((naked)) void mapper_default_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ __asm__ __volatile__("ret");
+}
+
+__attribute__((naked)) uint8_t mapper_default_prg_ram_read(struct nes_state *state, uint32_t addr) {
+ __asm__ __volatile__("xor %%al, %%al\n\t" "ret" : : : "al");
+}
+
+__attribute__((naked)) void mapper_default_prg_ram_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ __asm__ __volatile__("ret");
+}
+
+__attribute__((naked)) void mapper_default_chr_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ __asm__ __volatile__("ret");
+}
+
+__attribute__((naked)) void mapper_default_tick(struct nes_state *state) {
+ __asm__ __volatile__("ret");
+}
+
#include "mapper_000_0.c"
#include "mapper_001_0.c"
@@ -46,14 +69,17 @@ static void (*mapper_table[4096])(struct nes_state *state) = {
[MAPPER_ID(66, 0)] = mapper_066_0_init,
};
+// NOTE(peter): The entries with 0x0 will always have to be supplied/set by the mapper!
static void mapper_reset(struct nes_state *state) {
- state->mapper.prg_read = 0;
- state->mapper.prg_write = mapper_default_prg_write;
- state->mapper.chr_read = 0;
- state->mapper.chr_write = mapper_default_chr_write;
- state->mapper.ciram_read = mapper_default_ciram_read;
- state->mapper.ciram_write = mapper_default_ciram_write;
- state->mapper.tick = mapper_default_tick;
+ state->mapper_function.prg_rom_read = 0x0;
+ state->mapper_function.prg_rom_write = mapper_default_prg_rom_write;
+ state->mapper_function.prg_ram_read = mapper_default_prg_ram_read;
+ state->mapper_function.prg_ram_write = mapper_default_prg_ram_write;
+ state->mapper_function.chr_read = 0x0;
+ state->mapper_function.chr_write = mapper_default_chr_write;
+ state->mapper_function.ciram_read = mapper_default_ciram_read;
+ state->mapper_function.ciram_write = mapper_default_ciram_write;
+ state->mapper_function.tick = 0;
}
static void mapper_setup(struct nes_state *state) {
@@ -64,7 +90,7 @@ static void mapper_setup(struct nes_state *state) {
if(mapper_table[mapper]) {
mapper_table[mapper](state);
} else {
- printf("Unsupported mapper %d_%x, falling back to NROM\n", state->ines.mapper, state->ines.submapper);
+ printf("Unsupported mapper %d_%x, falling back to NROM (mapper 0)\n", state->ines.mapper, state->ines.submapper);
mapper_table[0](state);
}
}
diff --git a/mappers/mapper.h b/mappers/mapper.h
index 20ee906..d4384ac 100644
--- a/mappers/mapper.h
+++ b/mappers/mapper.h
@@ -12,8 +12,10 @@
struct nes_state;
struct mapper_functions {
- uint8_t (*prg_read)(struct nes_state *state, uint32_t addr);
- void (*prg_write)(struct nes_state *state, uint32_t addr, uint8_t value);
+ uint8_t (*prg_rom_read)(struct nes_state *state, uint32_t addr);
+ void (*prg_rom_write)(struct nes_state *state, uint32_t addr, uint8_t value);
+ uint8_t (*prg_ram_read)(struct nes_state *state, uint32_t addr);
+ void (*prg_ram_write)(struct nes_state *state, uint32_t addr, uint8_t value);
uint8_t (*chr_read)(struct nes_state *state, uint32_t addr);
void (*chr_write)(struct nes_state *state, uint32_t addr, uint8_t value);
uint8_t (*ciram_read)(struct nes_state *state, uint32_t addr);
@@ -25,8 +27,8 @@ 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_0 m003_0;
+ struct mapper_003_1 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 cc7baf8..2faa002 100644
--- a/mappers/mapper_000_0.c
+++ b/mappers/mapper_000_0.c
@@ -1,8 +1,8 @@
__attribute__((section(".mapper_000_0")))
-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;
+static uint8_t mapper_000_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_000_0 *mapper = &state->mapper_data.m000_0;
return state->prg_rom[addr & mapper->mask];
}
@@ -14,9 +14,10 @@ static uint8_t mapper_000_0_chr_read(struct nes_state *state, uint32_t 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;
- state->mapper.chr_read = mapper_000_0_chr_read;
+ struct mapper_000_0 *mapper = &state->mapper_data.m000_0;
+
+ state->mapper_function.prg_rom_read = mapper_000_0_prg_rom_read;
+ state->mapper_function.chr_read = mapper_000_0_chr_read;
mapper->mask = (state->ines.prg_size == 16384) ? 0x3fff : 0x7fff;
}
diff --git a/mappers/mapper_001_0.c b/mappers/mapper_001_0.c
index 0a03a27..51d22a2 100644
--- a/mappers/mapper_001_0.c
+++ b/mappers/mapper_001_0.c
@@ -1,7 +1,7 @@
__attribute__((section(".mapper_001_0")))
-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;
+static uint8_t mapper_001_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
if(addr >= 0x8000) {
if(addr < 0xc000) {
return mapper->prg_rom_0[addr & 0x3fff];
@@ -13,8 +13,8 @@ static uint8_t mapper_001_0_prg_read(struct nes_state *state, uint32_t addr) {
}
__attribute__((section(".mapper_001_0")))
-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;
+static void mapper_001_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
if(addr < 0x8000) return;
if(value & 0x80) {
@@ -71,7 +71,7 @@ static void mapper_001_0_prg_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_001_0")))
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;
+ struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
if(mapper->control & 0x10) {
// 4KB mode
if(addr < 0x1000) {
@@ -103,7 +103,7 @@ static void mapper_001_0_ciram_write(struct nes_state *state, uint32_t addr, uin
__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;
+ struct mapper_001_0 *mapper = &state->mapper_data.m001_0;
mapper->control = 0x0c;
mapper->prg_rom_0 = state->prg_rom;
@@ -112,10 +112,10 @@ static void mapper_001_0_init(struct nes_state *state) {
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;
+ state->mapper_function.prg_rom_read = mapper_001_0_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_001_0_prg_rom_write;
+ state->mapper_function.chr_read = mapper_001_0_chr_read;
+ state->mapper_function.chr_write = mapper_001_0_chr_write;
+ state->mapper_function.ciram_read = mapper_001_0_ciram_read;
+ state->mapper_function.ciram_write = mapper_001_0_ciram_write;
}
diff --git a/mappers/mapper_002_2.c b/mappers/mapper_002_2.c
index 4dbea85..e6cddf7 100644
--- a/mappers/mapper_002_2.c
+++ b/mappers/mapper_002_2.c
@@ -1,8 +1,9 @@
__attribute__((section(".mapper_002_2")))
-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;
+static uint8_t mapper_002_2_prg_rom_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_002_2 *mapper = &state->mapper_data.m002_2;
+
if(addr >= 0x8000 && addr < 0xc000) {
return mapper->prg_bank0[addr & 0x3fff];
@@ -14,8 +15,8 @@ static uint8_t mapper_002_2_prg_read(struct nes_state *state, uint32_t addr) {
}
__attribute__((section(".mapper_002_2")))
-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;
+static void mapper_002_2_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_002_2 *mapper = &state->mapper_data.m002_2;
if(addr >= 0x8000) {
mapper->prg_bank0 = state->prg_rom + ((value & 0x0f) * 0x4000);
@@ -34,13 +35,13 @@ static void mapper_002_2_chr_write(struct nes_state *state, uint32_t addr, uint8
__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;
+ struct mapper_002_2 *mapper = &state->mapper_data.m002_2;
mapper->prg_bank0 = state->prg_rom;
mapper->prg_bank1 = state->prg_rom + state->ines.prg_size - 0x4000;
- state->mapper.prg_read = mapper_002_2_prg_read;
- state->mapper.prg_write = mapper_002_2_prg_write;
- state->mapper.chr_read = mapper_002_2_chr_read;
- state->mapper.chr_write = mapper_002_2_chr_write;
+ state->mapper_function.prg_rom_read = mapper_002_2_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_002_2_prg_rom_write;
+ state->mapper_function.chr_read = mapper_002_2_chr_read;
+ state->mapper_function.chr_write = mapper_002_2_chr_write;
}
diff --git a/mappers/mapper_003_0.c b/mappers/mapper_003_0.c
index ec38f35..8c754a3 100644
--- a/mappers/mapper_003_0.c
+++ b/mappers/mapper_003_0.c
@@ -1,12 +1,12 @@
__attribute__((section(".mapper_003_0")))
-static uint8_t mapper_003_0_prg_read(struct nes_state *state, uint32_t addr) {
+static uint8_t mapper_003_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
return state->prg_rom[addr & 0x7fff];
}
__attribute__((section(".mapper_003_0")))
-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;
+static void mapper_003_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_003_0 *mapper = &state->mapper_data.m003_0;
if(addr >= 0x8000) {
mapper->chr_ptr = state->chr_rom + (value & 3) * 0x2000;
@@ -15,17 +15,17 @@ static void mapper_003_0_prg_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_003_0")))
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;
+ struct mapper_003_0 *mapper = &state->mapper_data.m003_0;
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;
+ struct mapper_003_0 *mapper = &state->mapper_data.m003_0;
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;
+ state->mapper_function.prg_rom_read = mapper_003_0_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_003_0_prg_rom_write;
+ state->mapper_function.chr_read = mapper_003_0_chr_read;
}
diff --git a/mappers/mapper_003_1.c b/mappers/mapper_003_1.c
index 0032fbc..68e67c7 100644
--- a/mappers/mapper_003_1.c
+++ b/mappers/mapper_003_1.c
@@ -1,12 +1,12 @@
__attribute__((section(".mapper_003_1")))
-static uint8_t mapper_003_1_prg_read(struct nes_state *state, uint32_t addr) {
+static uint8_t mapper_003_1_prg_rom_read(struct nes_state *state, uint32_t addr) {
return state->prg_rom[addr & 0x7fff];
}
__attribute__((section(".mapper_003_1")))
-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;
+static void mapper_003_1_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_003_1 *mapper = &state->mapper_data.m003_1;
if(addr >= 0x8000) {
mapper->chr_ptr = state->chr_rom + (value & 3) * 0x2000;
@@ -15,17 +15,17 @@ static void mapper_003_1_prg_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_003_1")))
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;
+ struct mapper_003_1 *mapper = &state->mapper_data.m003_1;
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;
+ struct mapper_003_1 *mapper = &state->mapper_data.m003_1;
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;
+ state->mapper_function.prg_rom_read = mapper_003_1_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_003_1_prg_rom_write;
+ state->mapper_function.chr_read = mapper_003_1_chr_read;
}
diff --git a/mappers/mapper_003_2.c b/mappers/mapper_003_2.c
index 73cfdc6..9c0d40d 100644
--- a/mappers/mapper_003_2.c
+++ b/mappers/mapper_003_2.c
@@ -1,12 +1,12 @@
__attribute__((section(".mapper_003_2")))
-static uint8_t mapper_003_2_prg_read(struct nes_state *state, uint32_t addr) {
+static uint8_t mapper_003_2_prg_rom_read(struct nes_state *state, uint32_t addr) {
return state->prg_rom[addr & 0x7fff];
}
__attribute__((section(".mapper_003_2")))
-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;
+static void mapper_003_2_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_003_2 *mapper = &state->mapper_data.m003_2;
if(addr >= 0x8000) {
value &= state->prg_rom[addr & 0x7fff];
@@ -16,17 +16,17 @@ static void mapper_003_2_prg_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_003_2")))
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;
+ struct mapper_003_2 *mapper = &state->mapper_data.m003_2;
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;
+ struct mapper_003_2 *mapper = &state->mapper_data.m003_2;
mapper->chr_ptr = state->chr_rom;
- state->mapper.prg_read = mapper_003_2_prg_read;
- state->mapper.prg_write = mapper_003_2_prg_write;
- state->mapper.chr_read = mapper_003_2_chr_read;
+ state->mapper_function.prg_rom_read = mapper_003_2_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_003_2_prg_rom_write;
+ state->mapper_function.chr_read = mapper_003_2_chr_read;
}
diff --git a/mappers/mapper_007_2.c b/mappers/mapper_007_2.c
index c42bc62..7f5963f 100644
--- a/mappers/mapper_007_2.c
+++ b/mappers/mapper_007_2.c
@@ -1,7 +1,8 @@
__attribute__((section(".mapper_007_2")))
-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;
+static uint8_t mapper_007_2_prg_rom_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_007_2 *mapper = &state->mapper_data.m007_2;
+
if(addr >= 0x8000) {
return mapper->prg_rom[addr & 0x7fff];
}
@@ -9,8 +10,8 @@ static uint8_t mapper_007_2_prg_read(struct nes_state *state, uint32_t addr) {
}
__attribute__((section(".mapper_007_2")))
-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;
+static void mapper_007_2_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_007_2 *mapper = &state->mapper_data.m007_2;
if(addr >= 0x8000) {
uint32_t prg_off = (value & 0x0f) << 15;
uint32_t ciram_off = (value & 0x10) << 11;
@@ -34,26 +35,26 @@ static void mapper_007_2_chr_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_007_2")))
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;
+ struct mapper_007_2 *mapper = &state->mapper_data.m007_2;
return mapper->ciram[addr & 0x3ff];
}
__attribute__((section(".mapper_007_2")))
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;
+ struct mapper_007_2 *mapper = &state->mapper_data.m007_2;
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;
+ struct mapper_007_2 *mapper = &state->mapper_data.m007_2;
mapper->prg_rom = state->prg_rom;
mapper->ciram = 0;
- state->mapper.prg_read = mapper_007_2_prg_read;
- state->mapper.prg_write = mapper_007_2_prg_write;
- state->mapper.chr_read = mapper_007_2_chr_read;
- state->mapper.chr_write = mapper_007_2_chr_write;
- state->mapper.ciram_read = mapper_007_2_ciram_read;
- state->mapper.ciram_write = mapper_007_2_ciram_write;
+ state->mapper_function.prg_rom_read = mapper_007_2_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_007_2_prg_rom_write;
+ state->mapper_function.chr_read = mapper_007_2_chr_read;
+ state->mapper_function.chr_write = mapper_007_2_chr_write;
+ state->mapper_function.ciram_read = mapper_007_2_ciram_read;
+ state->mapper_function.ciram_write = mapper_007_2_ciram_write;
}
diff --git a/mappers/mapper_011_0.c b/mappers/mapper_011_0.c
index e5db02c..d324fcf 100644
--- a/mappers/mapper_011_0.c
+++ b/mappers/mapper_011_0.c
@@ -1,7 +1,7 @@
__attribute__((section(".mapper_011_0")))
-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;
+static uint8_t mapper_011_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_011_0 *mapper = &state->mapper_data.m011_0;
if(addr >= 0x8000) {
return mapper->prg_rom[addr - 0x8000];
@@ -10,8 +10,8 @@ static uint8_t mapper_011_0_prg_read(struct nes_state *state, uint32_t addr) {
}
__attribute__((section(".mapper_011_0")))
-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;
+static void mapper_011_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_011_0 *mapper = &state->mapper_data.m011_0;
if(addr >= 0x8000) {
mapper->prg_rom = state->prg_rom + ((value >> 4) & 7) * 0x8000;
@@ -21,20 +21,20 @@ static void mapper_011_0_prg_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_011_0")))
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;
+ struct mapper_011_0 *mapper = &state->mapper_data.m011_0;
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;
+ struct mapper_011_0 *mapper = &state->mapper_data.m011_0;
mapper->prg_rom = state->prg_rom;
mapper->chr_ptr = state->chr_rom;
- state->mapper.prg_read = mapper_011_0_prg_read;
- state->mapper.prg_write = mapper_011_0_prg_write;
- state->mapper.chr_read = mapper_011_0_chr_read;
+ state->mapper_function.prg_rom_read = mapper_011_0_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_011_0_prg_rom_write;
+ state->mapper_function.chr_read = mapper_011_0_chr_read;
}
diff --git a/mappers/mapper_066_0.c b/mappers/mapper_066_0.c
index 9629fb2..ccd00fe 100644
--- a/mappers/mapper_066_0.c
+++ b/mappers/mapper_066_0.c
@@ -1,7 +1,7 @@
__attribute__((section(".mapper_066_0")))
-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;
+static uint8_t mapper_066_0_prg_rom_read(struct nes_state *state, uint32_t addr) {
+ struct mapper_066_0 *mapper = &state->mapper_data.m066_0;
if(addr >= 0x8000) {
return state->prg_rom[addr & 0x7fff];
@@ -10,8 +10,8 @@ static uint8_t mapper_066_0_prg_read(struct nes_state *state, uint32_t addr) {
}
__attribute__((section(".mapper_066_0")))
-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;
+static void mapper_066_0_prg_rom_write(struct nes_state *state, uint32_t addr, uint8_t value) {
+ struct mapper_066_0 *mapper = &state->mapper_data.m066_0;
if(addr >= 0x8000) {
uint32_t prg_bank = (value >> 4) & 3;
@@ -24,19 +24,19 @@ static void mapper_066_0_prg_write(struct nes_state *state, uint32_t addr, uint8
__attribute__((section(".mapper_066_0")))
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;
+ struct mapper_066_0 *mapper = &state->mapper_data.m066_0;
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;
+ struct mapper_066_0 *mapper = &state->mapper_data.m066_0;
mapper->prg_offset = state->prg_rom;
mapper->chr_offset = state->chr_rom;
- state->mapper.prg_read = mapper_066_0_prg_read;
- state->mapper.prg_write = mapper_066_0_prg_write;
- state->mapper.chr_read = mapper_066_0_chr_read;
+ state->mapper_function.prg_rom_read = mapper_066_0_prg_rom_read;
+ state->mapper_function.prg_rom_write = mapper_066_0_prg_rom_write;
+ state->mapper_function.chr_read = mapper_066_0_chr_read;
}
diff --git a/memory.c b/memory.c
index 90ae8b6..55c7015 100644
--- a/memory.c
+++ b/memory.c
@@ -1,6 +1,5 @@
-
__attribute__((hot))
static inline uint8_t memory_read(struct nes_state *state, uint32_t offset) {
state->cpu.cycles++;
@@ -8,7 +7,10 @@ static inline uint8_t memory_read(struct nes_state *state, uint32_t offset) {
// apu_tick(state);
if(LIKELY(offset >= 0x6000)) { // MOST
- return state->mapper.prg_read(state, offset);
+ if(UNLIKELY(offset < 0x8000)) {
+ return state->mapper_function.prg_ram_read(state, offset);
+ }
+ return state->mapper_function.prg_rom_read(state, offset);
} else if(LIKELY(offset < 0x2000)) { // SECOND
return state->ram[offset & 0x07ff];
@@ -66,21 +68,20 @@ static inline void memory_write(struct nes_state *state, uint32_t offset, uint8_
// state->apu.irq_pending = 0;
// }
}
- } else if(offset >= 0x6000) {
- state->mapper.prg_write(state, offset, value);
+
+ } else if(offset >= 0x6000) { // NOTE(peter): Might need to move this upwards when we implement a mapper that has prg_ram_*
+ if(offset < 0x8000) {
+ state->mapper_function.prg_ram_write(state, offset, value);
+ } else {
+ state->mapper_function.prg_rom_write(state, offset, value);
+ }
}
}
+
static inline uint8_t memory_read_dma(struct nes_state *state, uint32_t offset) {
// Do not tick CPU/PPU/APU — caller handles timing
- if(LIKELY(offset < 0x2000)) {
- return state->ram[offset & 0x07ff];
-
- } else if(offset >= 0x6000) {
- return state->mapper.prg_read(state, offset);
-
- }
- return 0;
+ return state->ram[offset & 0x07ff];
}
static inline uint8_t memory_read_dummy(struct nes_state *state, uint32_t offset) {
diff --git a/mknes.c b/mknes.c
index 9e87a33..29d705e 100644
--- a/mknes.c
+++ b/mknes.c
@@ -121,65 +121,63 @@ int main(int argc, char **argv) {
init_opcode_ud_lut();
// protect_opcode_lut();
- struct nes_state *nstate = aligned_alloc(4096, (sizeof(struct nes_state) + 4095) & ~4096);
-
+ struct nes_state *nstate = aligned_alloc(4096, (sizeof(struct nes_state) + 4095) & ~4095);
ppu_reset(nstate);
- // ines2_load(&nstate, "data/0000/10-Yard Fight (USA, Europe).nes");
- // ines2_load(&nstate, "data/0000/Balloon Fight (USA).nes");
- // ines2_load(&nstate, "data/0000/Excitebike (Japan, USA).nes");
- // ines2_load(&nstate, "data/0000/Ice Climber (USA, Europe, Korea).nes");
- // ines2_load(&nstate, "data/0000/Kung Fu (Japan, USA).nes");
+ // ines2_load(nstate, "data/0000/10-Yard Fight (USA, Europe).nes");
+ // ines2_load(nstate, "data/0000/Balloon Fight (USA).nes");
+ // ines2_load(nstate, "data/0000/Excitebike (Japan, USA).nes");
+ // ines2_load(nstate, "data/0000/Ice Climber (USA, Europe, Korea).nes");
+ // ines2_load(nstate, "data/0000/Kung Fu (Japan, USA).nes");
ines2_load(nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).nes");
- // ines2_load(&nstate, "data/Super Mario Bros. (W) (V1.0) [!].nes");
- // ines2_load(&nstate, "data/Super Mario Bros. (JU) [!].nes");
- // ines2_load(&nstate, "data/0000/Urban Champion (World).nes");
- // ines2_load(&nstate, "data/0000/Wrecking Crew (World).nes");
- // ines2_load(&nstate, "data/0000/scanline.nes");
- // ines2_load(&nstate, "data/0000/Sayoonara!.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterChromaLuma.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest1.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest2.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3a.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3b.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3c.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3d.NES");
- // ines2_load(&nstate, "data/0000/raster_demos/RasterTest3e.NES");
- // ines2_load(&nstate, "data/0000/NEStress.NES");
- // ines2_load(&nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).zip");
- // ines2_load(&nstate, "data/0042/Super Mario Bros. + Duck Hunt (USA).zip");
- // ines2_load(&nstate, "data/0000/Xevious - The Avenger (USA).zip");
- // ines2_load(&nstate, "data/tv.nes");
-
- // ines2_load(&nstate, "data/Life Force (USA).zip"); // 2002
-
- // ines2_load(&nstate, "data/0003/Flipull - An Exciting Cube Game (Japan) (En).zip");
- // ines2_load(&nstate, "data/0003/Friday the 13th (USA).zip");
- // ines2_load(&nstate, "data/0003/Ghostbusters (Japan).zip");
- // ines2_load(&nstate, "data/0003/Gradius (USA).zip");
+ // ines2_load(nstate, "data/Super Mario Bros. (W) (V1.0) [!].nes");
+ // ines2_load(nstate, "data/Super Mario Bros. (JU) [!].nes");
+ // ines2_load(nstate, "data/0000/Urban Champion (World).nes");
+ // ines2_load(nstate, "data/0000/Wrecking Crew (World).nes");
+ // ines2_load(nstate, "data/0000/scanline.nes");
+ // ines2_load(nstate, "data/0000/Sayoonara!.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterChromaLuma.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest1.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest2.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest3.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest3a.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest3b.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest3c.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest3d.NES");
+ // ines2_load(nstate, "data/0000/raster_demos/RasterTest3e.NES");
+ // ines2_load(nstate, "data/0000/NEStress.NES");
+ // ines2_load(nstate, "data/0000/Super Mario Bros. (World) (HVC-SM).zip");
+ // ines2_load(nstate, "data/0042/Super Mario Bros. + Duck Hunt (USA).zip");
+ // ines2_load(nstate, "data/0000/Xevious - The Avenger (USA).zip");
+ // ines2_load(nstate, "data/tv.nes");
+
+ // ines2_load(nstate, "data/Life Force (USA).zip"); // 2002
+
+ // ines2_load(nstate, "data/0003/Flipull - An Exciting Cube Game (Japan) (En).zip");
+ // ines2_load(nstate, "data/0003/Friday the 13th (USA).zip");
+ // ines2_load(nstate, "data/0003/Ghostbusters (Japan).zip");
+ // ines2_load(nstate, "data/0003/Gradius (USA).zip");
// ines2_load(nstate, "data/0007/Battletoads (USA).zip");
- // ines2_load(&nstate, "data/0007/Beetlejuice (USA).zip");
- // ines2_load(&nstate, "data/0007/Cabal (USA).zip");
-
- // ines2_load(&nstate, "data/000b/Baby Boomer (USA) (Unl).zip");
- // ines2_load(&nstate, "data/000b/Captain Comic - The Adventure (USA) (Unl).zip");
- // ines2_load(&nstate, "data/000b/King Neptune's Adventure (USA) (Unl).zip");
+ // ines2_load(nstate, "data/0007/Beetlejuice (USA).zip");
+ // ines2_load(nstate, "data/0007/Cabal (USA).zip");
- // ines2_load(&nstate, "data/2002/Attack Animal Gakuen (Japan).zip");
- // ines2_load(&nstate, "data/2002/Ballblazer (Japan).zip");
- // ines2_load(&nstate, "data/2002/Best of the Best - Championship Karate (USA).zip");
+ // ines2_load(nstate, "data/000b/Baby Boomer (USA) (Unl).zip");
+ // ines2_load(nstate, "data/000b/Captain Comic - The Adventure (USA) (Unl).zip");
+ // ines2_load(nstate, "data/000b/King Neptune's Adventure (USA) (Unl).zip");
- // ines2_load(&nstate, "data/Blaster Master (USA).zip");
+ // ines2_load(nstate, "data/2002/Attack Animal Gakuen (Japan).zip");
+ // ines2_load(nstate, "data/2002/Ballblazer (Japan).zip");
+ // ines2_load(nstate, "data/2002/Best of the Best - Championship Karate (USA).zip");
+ // ines2_load(nstate, "data/Blaster Master (USA).zip");
mapper_setup(nstate);
- uint32_t lo = nstate->mapper.prg_read(nstate, 0xfffc);
- uint32_t hi = nstate->mapper.prg_read(nstate, 0xfffd);
+ uint32_t lo = nstate->mapper_function.prg_rom_read(nstate, 0xfffc);
+ uint32_t hi = nstate->mapper_function.prg_rom_read(nstate, 0xfffd);
nstate->cpu.pc = (hi << 8) | lo;
#if 1
- for(uint32_t i = 0; i < 0x5000; ++ i) {
+ for(uint32_t i = 0; i < 0x5000; ++i) {
while(!nstate->ppu.frame_ready) {
// PROFILE_NAMED("nes emulator");
cpu_tick(nstate);
@@ -230,12 +228,15 @@ int main(int argc, char **argv) {
timer_start(timer);
- while(!glfwWindowShouldClose(window)) {
+ for(;;) {
timer_wait(timer);
glfwPollEvents();
- uint8_t input = 0;
+ // exit
+ if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) break;
+ // Joypad input
+ uint8_t input = 0;
if(glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) { input |= (1 << 0); }
if(glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) { input |= (1 << 1); }
if(glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { input |= (1 << 2); }
@@ -244,7 +245,6 @@ int main(int argc, char **argv) {
if(glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS) { input |= (1 << 5); }
if(glfwGetKey(window, GLFW_KEY_LEFT) == GLFW_PRESS) { input |= (1 << 6); }
if(glfwGetKey(window, GLFW_KEY_RIGHT) == GLFW_PRESS) { input |= (1 << 7); }
-
nstate->ppu.input[0] = input;
while(!nstate->ppu.frame_ready) {
diff --git a/mknes.h b/mknes.h
index c169140..27d4f6e 100644
--- a/mknes.h
+++ b/mknes.h
@@ -106,9 +106,8 @@ struct ines_state {
struct nes_state {
struct ppu_state ppu;
- struct mapper_functions mapper;
- // union mapper_data map;
- char map[sizeof(union mapper_data)] __attribute__((aligned(64))); // NOTE(peter): Only way due to aliasing rules in the C standard.
+ struct mapper_functions mapper_function;
+ union mapper_data mapper_data;
struct cpu_state cpu;
struct ines_state ines;
// struct apu_state apu;
diff --git a/ppu.c b/ppu.c
index 1cb29b8..3096573 100644
--- a/ppu.c
+++ b/ppu.c
@@ -89,11 +89,11 @@ static inline void ppu_fetch_sprite_patterns(struct nes_state *state) {
addr = bank + tile * 16 + row;
if(attr & 0x40) {
- lsb = ppu_bitreverse_lut[state->mapper.chr_read(state, addr)];
- msb = ppu_bitreverse_lut[state->mapper.chr_read(state, addr + 8)];
+ lsb = ppu_bitreverse_lut[state->mapper_function.chr_read(state, addr)];
+ msb = ppu_bitreverse_lut[state->mapper_function.chr_read(state, addr + 8)];
} else {
- lsb = state->mapper.chr_read(state, addr);
- msb = state->mapper.chr_read(state, addr + 8);
+ lsb = state->mapper_function.chr_read(state, addr);
+ msb = state->mapper_function.chr_read(state, addr + 8);
}
ppu->sprite_shift_lo[i] = lsb;
@@ -232,12 +232,12 @@ static inline void ppu_tick(struct nes_state *state) {
switch(dot % 8) {
case 1: {
uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff);
- ppu->bg_next_tile_id = state->mapper.ciram_read(state, nt_addr);
+ ppu->bg_next_tile_id = state->mapper_function.ciram_read(state, nt_addr);
} break;
case 3: {
uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | ((ppu->vram_addr >> 4) & 0x38) | ((ppu->vram_addr >> 2) & 0x07);
- uint8_t attr = state->mapper.ciram_read(state, attr_addr & 0x0fff);
+ uint8_t attr = state->mapper_function.ciram_read(state, attr_addr & 0x0fff);
uint8_t shift = ((ppu->vram_addr >> 4) & 4) | (ppu->vram_addr & 2);
ppu->bg_next_tile_attrib = (attr >> shift) & 3;
} break;
@@ -247,7 +247,7 @@ static inline void ppu_tick(struct nes_state *state) {
uint32_t tile = ppu->bg_next_tile_id;
uint32_t fine_y = (ppu->vram_addr >> 12) & 7;
uint32_t addr_lsb = (base + tile * 16 + fine_y) & 0x1fff;
- ppu->bg_next_tile_lsb = state->mapper.chr_read(state, addr_lsb);
+ ppu->bg_next_tile_lsb = state->mapper_function.chr_read(state, addr_lsb);
} break;
case 7: {
@@ -255,7 +255,7 @@ static inline void ppu_tick(struct nes_state *state) {
uint32_t tile = ppu->bg_next_tile_id;
uint32_t fine_y = (ppu->vram_addr >> 12) & 7;
uint32_t addr_msb = (base + tile * 16 + fine_y + 8) & 0x1fff;
- ppu->bg_next_tile_msb = state->mapper.chr_read(state, addr_msb);
+ ppu->bg_next_tile_msb = state->mapper_function.chr_read(state, addr_msb);
} break;
case 0: {
@@ -331,12 +331,12 @@ static inline void ppu_tick(struct nes_state *state) {
switch(dot % 8) {
case 1: {
uint32_t nt_addr = 0x2000 | (ppu->vram_addr & 0x0fff);
- ppu->bg_next_tile_id = state->mapper.ciram_read(state, nt_addr);
+ ppu->bg_next_tile_id = state->mapper_function.ciram_read(state, nt_addr);
} break;
case 3: {
uint32_t attr_addr = 0x23c0 | (ppu->vram_addr & 0x0c00) | ((ppu->vram_addr >> 4) & 0x38) | ((ppu->vram_addr >> 2) & 0x07);
- uint8_t attr = state->mapper.ciram_read(state, attr_addr & 0x0fff);
+ uint8_t attr = state->mapper_function.ciram_read(state, attr_addr & 0x0fff);
uint8_t shift = ((ppu->vram_addr >> 4) & 4) | (ppu->vram_addr & 2);
ppu->bg_next_tile_attrib = (attr >> shift) & 3;
} break;
@@ -346,7 +346,7 @@ static inline void ppu_tick(struct nes_state *state) {
uint32_t tile = ppu->bg_next_tile_id;
uint32_t fine_y = (ppu->vram_addr >> 12) & 7;
uint32_t addr_lsb = (base + tile * 16 + fine_y) & 0x1fff;
- ppu->bg_next_tile_lsb = state->mapper.chr_read(state, addr_lsb);
+ ppu->bg_next_tile_lsb = state->mapper_function.chr_read(state, addr_lsb);
} break;
case 7: {
@@ -354,7 +354,7 @@ static inline void ppu_tick(struct nes_state *state) {
uint32_t tile = ppu->bg_next_tile_id;
uint32_t fine_y = (ppu->vram_addr >> 12) & 7;
uint32_t addr_msb = (base + tile * 16 + fine_y + 8) & 0x1fff;
- ppu->bg_next_tile_msb = state->mapper.chr_read(state, addr_msb);
+ ppu->bg_next_tile_msb = state->mapper_function.chr_read(state, addr_msb);
} break;
case 0: {
@@ -399,9 +399,7 @@ static inline void ppu_tick(struct nes_state *state) {
// state->input[0] = tas_input[tas_frame++];
ppu->reg_status |= 0x80;
- if(ppu->reg_ctrl & 0x80) {
- state->cpu.nmi_pending = 1;
- }
+ state->cpu.nmi_pending = (ppu->reg_ctrl & 0x80); // NOTE(peter): Set NMI if enabled.
}
if(UNLIKELY(scanline == 261) && dot == 1) {
@@ -428,5 +426,6 @@ static inline void ppu_tick(struct nes_state *state) {
ppu->dot = dot;
ppu->scanline = scanline;
+ if(UNLIKELY(state->mapper_function.tick)) state->mapper_function.tick(state);
}
}
diff --git a/ppu_registers.c b/ppu_registers.c
index 98e2c7d..0e67890 100644
--- a/ppu_registers.c
+++ b/ppu_registers.c
@@ -52,10 +52,10 @@ static inline void ppu_write(struct nes_state *state, uint32_t offset, uint8_t v
} else if(reg == 7) {
uint32_t addr = ppu->vram_addr;
if(addr < 0x2000) {
- state->mapper.chr_write(state, addr, value);
+ state->mapper_function.chr_write(state, addr, value);
} else if(LIKELY(addr < 0x3f00)) {
- state->mapper.ciram_write(state, addr, value);
+ state->mapper_function.ciram_write(state, addr, value);
} else if(addr < 0x4000) {
uint32_t pal_addr = addr & 0x1f;
@@ -94,11 +94,11 @@ static inline uint8_t ppu_read(struct nes_state *state, uint32_t offset) {
if(LIKELY(addr < 0x2000)) {
result = ppu->vram_read_buffer;
- ppu->vram_read_buffer = state->mapper.chr_read(state, addr);
+ ppu->vram_read_buffer = state->mapper_function.chr_read(state, addr);
} else if(LIKELY(addr < 0x3f00)) {
result = ppu->vram_read_buffer;
- ppu->vram_read_buffer = state->mapper.ciram_read(state, addr);
+ ppu->vram_read_buffer = state->mapper_function.ciram_read(state, addr);
} else if(addr < 0x4000) {
uint32_t pal_addr = addr & 0x1f;