From dee29c118cbded7703c2f7edcbc7230ffb70b844 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Tue, 8 Oct 2019 15:10:24 +0300 Subject: [PATCH] Added GB_set_sample_rate_by_clocks API, split SGB_NO_SFC into PAL and NTSC; now they report the correct clock rate. --- Core/apu.c | 15 +++++++++++++++ Core/apu.h | 3 +++ Core/gb.c | 20 ++++++++++++-------- Core/gb.h | 4 +++- Core/memory.c | 6 ++++-- 5 files changed, 37 insertions(+), 11 deletions(-) diff --git a/Core/apu.c b/Core/apu.c index 55898b2..3be92d6 100644 --- a/Core/apu.c +++ b/Core/apu.c @@ -1004,9 +1004,23 @@ void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate) if (sample_rate) { gb->apu_output.highpass_rate = pow(0.999958, GB_get_clock_rate(gb) / (double)sample_rate); } + gb->apu_output.rate_set_in_clocks = false; GB_apu_update_cycles_per_sample(gb); } +void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, unsigned cycles_per_sample) +{ + + if (cycles_per_sample == 0) { + GB_set_sample_rate(gb, 0); + return; + } + gb->apu_output.cycles_per_sample = cycles_per_sample; + gb->apu_output.sample_rate = GB_get_clock_rate(gb) / cycles_per_sample * 2; + gb->apu_output.highpass_rate = pow(0.999958, cycles_per_sample); + gb->apu_output.rate_set_in_clocks = true; +} + void GB_apu_set_sample_callback(GB_gameboy_t *gb, GB_sample_callback_t callback) { gb->apu_output.sample_callback = callback; @@ -1019,6 +1033,7 @@ void GB_set_highpass_filter_mode(GB_gameboy_t *gb, GB_highpass_mode_t mode) void GB_apu_update_cycles_per_sample(GB_gameboy_t *gb) { + if (gb->apu_output.rate_set_in_clocks) return; if (gb->apu_output.sample_rate) { gb->apu_output.cycles_per_sample = 2 * GB_get_clock_rate(gb) / (double)gb->apu_output.sample_rate; /* 2 * because we use 8MHz units */ } diff --git a/Core/apu.h b/Core/apu.h index 7f8acfc..ee6055b 100644 --- a/Core/apu.h +++ b/Core/apu.h @@ -143,9 +143,12 @@ typedef struct { GB_double_sample_t highpass_diff; GB_sample_callback_t sample_callback; + + bool rate_set_in_clocks; } GB_apu_output_t; void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate); +void GB_set_sample_rate_by_clocks(GB_gameboy_t *gb, unsigned cycles_per_sample); /* Cycles are in 8MHz units */ void GB_set_highpass_filter_mode(GB_gameboy_t *gb, GB_highpass_mode_t mode); void GB_apu_set_sample_callback(GB_gameboy_t *gb, GB_sample_callback_t callback); #ifdef GB_INTERNAL diff --git a/Core/gb.c b/Core/gb.c index 6604e4f..93ac9d7 100644 --- a/Core/gb.c +++ b/Core/gb.c @@ -712,7 +712,8 @@ static void reset_ram(GB_gameboy_t *gb) case GB_MODEL_DMG_B: case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_PAL: /* Unverified */ - case GB_MODEL_SGB_NO_SFC: + case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */ + case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */ for (unsigned i = 0; i < gb->ram_size; i++) { gb->ram[i] = GB_random(); if (i & 0x100) { @@ -758,7 +759,8 @@ static void reset_ram(GB_gameboy_t *gb) case GB_MODEL_DMG_B: case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_PAL: /* Unverified */ - case GB_MODEL_SGB_NO_SFC: + case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */ + case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */ case GB_MODEL_SGB2: case GB_MODEL_SGB2_NO_SFC: for (unsigned i = 0; i < sizeof(gb->hram); i++) { @@ -783,7 +785,8 @@ static void reset_ram(GB_gameboy_t *gb) case GB_MODEL_DMG_B: case GB_MODEL_SGB_NTSC: /* Unverified */ case GB_MODEL_SGB_PAL: /* Unverified */ - case GB_MODEL_SGB_NO_SFC: /* Unverified */ + case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */ + case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */ case GB_MODEL_SGB2: case GB_MODEL_SGB2_NO_SFC: for (unsigned i = 0; i < 8; i++) { @@ -811,7 +814,8 @@ static void reset_ram(GB_gameboy_t *gb) case GB_MODEL_DMG_B: case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_PAL: /* Unverified */ - case GB_MODEL_SGB_NO_SFC: /* Unverified */ + case GB_MODEL_SGB_NTSC_NO_SFC: /* Unverified */ + case GB_MODEL_SGB_PAL_NO_SFC: /* Unverified */ case GB_MODEL_SGB2: case GB_MODEL_SGB2_NO_SFC: { uint8_t temp; @@ -1017,12 +1021,12 @@ void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier) uint32_t GB_get_clock_rate(GB_gameboy_t *gb) { - if (gb->model == GB_MODEL_SGB_NTSC) { - return SGB_NTSC_FREQUENCY * gb->clock_multiplier; - } - if (gb->model == GB_MODEL_SGB_PAL) { + if (gb->model & GB_MODEL_PAL_BIT) { return SGB_PAL_FREQUENCY * gb->clock_multiplier; } + if ((gb->model & ~GB_MODEL_NO_SFC_BIT) == GB_MODEL_SGB) { + return SGB_NTSC_FREQUENCY * gb->clock_multiplier; + } return CPU_FREQUENCY * gb->clock_multiplier; } diff --git a/Core/gb.h b/Core/gb.h index 59a11c2..dbd9e16 100644 --- a/Core/gb.h +++ b/Core/gb.h @@ -70,7 +70,9 @@ typedef enum { GB_MODEL_SGB = 0x004, GB_MODEL_SGB_NTSC = GB_MODEL_SGB, GB_MODEL_SGB_PAL = GB_MODEL_SGB | GB_MODEL_PAL_BIT, - GB_MODEL_SGB_NO_SFC = GB_MODEL_SGB | GB_MODEL_NO_SFC_BIT, + GB_MODEL_SGB_NTSC_NO_SFC = GB_MODEL_SGB | GB_MODEL_NO_SFC_BIT, + GB_MODEL_SGB_NO_SFC = GB_MODEL_SGB_NTSC_NO_SFC, + GB_MODEL_SGB_PAL_NO_SFC = GB_MODEL_SGB | GB_MODEL_NO_SFC_BIT | GB_MODEL_PAL_BIT, // GB_MODEL_MGB = 0x100, GB_MODEL_SGB2 = 0x101, GB_MODEL_SGB2_NO_SFC = GB_MODEL_SGB2 | GB_MODEL_NO_SFC_BIT, diff --git a/Core/memory.c b/Core/memory.c index 4c4a702..c481ad2 100644 --- a/Core/memory.c +++ b/Core/memory.c @@ -273,7 +273,8 @@ static uint8_t read_high_memory(GB_gameboy_t *gb, uint16_t addr) case GB_MODEL_DMG_B: case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_PAL: - case GB_MODEL_SGB_NO_SFC: + case GB_MODEL_SGB_NTSC_NO_SFC: + case GB_MODEL_SGB_PAL_NO_SFC: case GB_MODEL_SGB2: case GB_MODEL_SGB2_NO_SFC: ; @@ -591,7 +592,8 @@ static void write_high_memory(GB_gameboy_t *gb, uint16_t addr, uint8_t value) case GB_MODEL_DMG_B: case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_PAL: - case GB_MODEL_SGB_NO_SFC: + case GB_MODEL_SGB_NTSC_NO_SFC: + case GB_MODEL_SGB_PAL_NO_SFC: case GB_MODEL_SGB2: case GB_MODEL_SGB2_NO_SFC: case GB_MODEL_CGB_E: