Added GB_set_sample_rate_by_clocks API, split SGB_NO_SFC into PAL and NTSC; now they report the correct clock rate.

This commit is contained in:
Lior Halphon 2019-10-08 15:10:24 +03:00
parent ca370eee7e
commit dee29c118c
5 changed files with 37 additions and 11 deletions

View File

@ -1004,9 +1004,23 @@ void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate)
if (sample_rate) { if (sample_rate) {
gb->apu_output.highpass_rate = pow(0.999958, GB_get_clock_rate(gb) / (double)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); 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) void GB_apu_set_sample_callback(GB_gameboy_t *gb, GB_sample_callback_t callback)
{ {
gb->apu_output.sample_callback = 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) 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) { 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 */ gb->apu_output.cycles_per_sample = 2 * GB_get_clock_rate(gb) / (double)gb->apu_output.sample_rate; /* 2 * because we use 8MHz units */
} }

View File

@ -143,9 +143,12 @@ typedef struct {
GB_double_sample_t highpass_diff; GB_double_sample_t highpass_diff;
GB_sample_callback_t sample_callback; GB_sample_callback_t sample_callback;
bool rate_set_in_clocks;
} GB_apu_output_t; } GB_apu_output_t;
void GB_set_sample_rate(GB_gameboy_t *gb, unsigned sample_rate); 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_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); void GB_apu_set_sample_callback(GB_gameboy_t *gb, GB_sample_callback_t callback);
#ifdef GB_INTERNAL #ifdef GB_INTERNAL

View File

@ -712,7 +712,8 @@ static void reset_ram(GB_gameboy_t *gb)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_NTSC: /* Unverified*/
case GB_MODEL_SGB_PAL: /* 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++) { for (unsigned i = 0; i < gb->ram_size; i++) {
gb->ram[i] = GB_random(); gb->ram[i] = GB_random();
if (i & 0x100) { if (i & 0x100) {
@ -758,7 +759,8 @@ static void reset_ram(GB_gameboy_t *gb)
case GB_MODEL_DMG_B: case GB_MODEL_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_NTSC: /* Unverified*/
case GB_MODEL_SGB_PAL: /* 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:
case GB_MODEL_SGB2_NO_SFC: case GB_MODEL_SGB2_NO_SFC:
for (unsigned i = 0; i < sizeof(gb->hram); i++) { 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_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified */ case GB_MODEL_SGB_NTSC: /* Unverified */
case GB_MODEL_SGB_PAL: /* 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:
case GB_MODEL_SGB2_NO_SFC: case GB_MODEL_SGB2_NO_SFC:
for (unsigned i = 0; i < 8; i++) { 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_DMG_B:
case GB_MODEL_SGB_NTSC: /* Unverified*/ case GB_MODEL_SGB_NTSC: /* Unverified*/
case GB_MODEL_SGB_PAL: /* 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:
case GB_MODEL_SGB2_NO_SFC: { case GB_MODEL_SGB2_NO_SFC: {
uint8_t temp; 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) uint32_t GB_get_clock_rate(GB_gameboy_t *gb)
{ {
if (gb->model == GB_MODEL_SGB_NTSC) { if (gb->model & GB_MODEL_PAL_BIT) {
return SGB_NTSC_FREQUENCY * gb->clock_multiplier;
}
if (gb->model == GB_MODEL_SGB_PAL) {
return SGB_PAL_FREQUENCY * gb->clock_multiplier; 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; return CPU_FREQUENCY * gb->clock_multiplier;
} }

View File

@ -70,7 +70,9 @@ typedef enum {
GB_MODEL_SGB = 0x004, GB_MODEL_SGB = 0x004,
GB_MODEL_SGB_NTSC = GB_MODEL_SGB, GB_MODEL_SGB_NTSC = GB_MODEL_SGB,
GB_MODEL_SGB_PAL = GB_MODEL_SGB | GB_MODEL_PAL_BIT, 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_MGB = 0x100,
GB_MODEL_SGB2 = 0x101, GB_MODEL_SGB2 = 0x101,
GB_MODEL_SGB2_NO_SFC = GB_MODEL_SGB2 | GB_MODEL_NO_SFC_BIT, GB_MODEL_SGB2_NO_SFC = GB_MODEL_SGB2 | GB_MODEL_NO_SFC_BIT,

View File

@ -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_DMG_B:
case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_NTSC:
case GB_MODEL_SGB_PAL: 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:
case GB_MODEL_SGB2_NO_SFC: 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_DMG_B:
case GB_MODEL_SGB_NTSC: case GB_MODEL_SGB_NTSC:
case GB_MODEL_SGB_PAL: 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:
case GB_MODEL_SGB2_NO_SFC: case GB_MODEL_SGB2_NO_SFC:
case GB_MODEL_CGB_E: case GB_MODEL_CGB_E: