# HG changeset patch # User Michael Pavone # Date 1661148848 25200 # Node ID 2648081f3100b3ccd9a14db4b53e3a3d6b204495 # Parent 40290a92388632997ac1e6e99c9749fb794cf774 Implement Game Gear PSG panning diff -r 40290a923886 -r 2648081f3100 psg.c --- a/psg.c Sun Aug 21 22:56:32 2022 -0700 +++ b/psg.c Sun Aug 21 23:14:08 2022 -0700 @@ -13,11 +13,12 @@ void psg_init(psg_context * context, uint32_t master_clock, uint32_t clock_div) { memset(context, 0, sizeof(*context)); - context->audio = render_audio_source("PSG", master_clock, clock_div, 1); + context->audio = render_audio_source("PSG", master_clock, clock_div, 2); context->clock_inc = clock_div; for (int i = 0; i < 4; i++) { context->volume[i] = 0xF; } + context->pan = 0xFF; } void psg_free(psg_context *context) @@ -110,18 +111,33 @@ } } - int16_t accum = 0; + int16_t left_accum = 0, right_accum = 0; + uint8_t pan_left = 0x10, pan_right = 0x1; for (int i = 0; i < 3; i++) { if (context->output_state[i]) { - accum += volume_table[context->volume[i]]; + int16_t value = volume_table[context->volume[i]]; + if (context->pan & pan_left) { + left_accum += value; + } + if (context->pan & pan_right) { + right_accum += value; + } + pan_left <<= 1; + pan_right <<= 1; } } if (context->noise_out) { - accum += volume_table[context->volume[3]]; + int16_t value = volume_table[context->volume[3]]; + if (context->pan & pan_left) { + left_accum += value; + } + if (context->pan & pan_right) { + right_accum += value; + } } - render_put_mono_sample(context->audio, accum); + render_put_stereo_sample(context->audio, left_accum, right_accum); context->cycles += context->clock_inc; } diff -r 40290a923886 -r 2648081f3100 psg.h --- a/psg.h Sun Aug 21 22:56:32 2022 -0700 +++ b/psg.h Sun Aug 21 23:14:08 2022 -0700 @@ -25,6 +25,7 @@ uint8_t noise_use_tone; uint8_t noise_type; uint8_t latch; + uint8_t pan; } psg_context; diff -r 40290a923886 -r 2648081f3100 sms.c --- a/sms.c Sun Aug 21 22:56:32 2022 -0700 +++ b/sms.c Sun Aug 21 23:14:08 2022 -0700 @@ -212,16 +212,12 @@ //TODO: implement link port return vcontext; } - -static uint8_t psg_pan_read(uint32_t location, void *vcontext) -{ - //TODO: implement PSG pan - return 0xFF; -} - static void *psg_pan_write(uint32_t location, void *vcontext, uint8_t value) { - //TODO: implement PSG pan + z80_context *z80 = vcontext; + sms_context *sms = z80->system; + psg_run(sms->psg, z80->Z80_CYCLE); + sms->psg->pan = value; return vcontext; } static memmap_chunk io_map[] = { @@ -233,7 +229,7 @@ static memmap_chunk io_gg[] = { {0x00, 0x07, 0xFF, .read_8 = gg_io_read, .write_8 = gg_io_write}, - {0x07, 0x08, 0xFF, .read_8 = psg_pan_read, .write_8 = psg_pan_write}, + {0x07, 0x08, 0xFF, .write_8 = psg_pan_write}, {0x08, 0x40, 0xFF, .write_8 = memory_io_write}, {0x40, 0x80, 0xFF, .read_8 = hv_read, .write_8 = sms_psg_write}, {0x80, 0xC0, 0xFF, .read_8 = vdp_read, .write_8 = vdp_write},