Mercurial > repos > blastem
changeset 2145:62a53c052d9b
PCM channel add should saturate on overflow, not wrap around
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 26 Mar 2022 02:01:55 -0700 |
parents | 10e4439d8f13 |
children | 0c0d4233d826 |
files | rf5c164.c rf5c164.h |
diffstat | 2 files changed, 13 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/rf5c164.c Sat Mar 26 00:54:47 2022 -0700 +++ b/rf5c164.c Sat Mar 26 02:01:55 2022 -0700 @@ -139,7 +139,6 @@ int16_t left = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] >> 4)) >> 5; int16_t right = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] & 0xF)) >> 5; //printf("chan %d, raw %X, sample %d, left %d, right %d, ptr %X (raw %X)\n", pcm->cur_channel, pcm->channels[pcm->cur_channel].sample, sample, left, right, pcm->channels[pcm->cur_channel].cur_ptr >> 11, pcm->channels[pcm->cur_channel].cur_ptr); - //TODO: saturating add pcm->left += left; pcm->right += right; } @@ -155,6 +154,16 @@ pcm->cur_channel++; pcm->cur_channel &= 7; if (!pcm->cur_channel) { + if (pcm->left > INT16_MAX) { + pcm->left = INT16_MAX; + } else if (pcm->left < INT16_MIN) { + pcm->left = INT16_MIN; + } + if (pcm->right > INT16_MAX) { + pcm->right = INT16_MAX; + } else if (pcm->right < INT16_MIN) { + pcm->right = INT16_MIN; + } render_put_stereo_sample(pcm->audio, pcm->left, pcm->right); pcm->left = pcm->right = 0; } @@ -185,7 +194,7 @@ for (int i = 0; i < 8; i++) { int mask = 1 << i; - if (changed & mask & value) { + if ((changed & mask) && !(mask & value)) { pcm->channels[i].state = START; } }
--- a/rf5c164.h Sat Mar 26 00:54:47 2022 -0700 +++ b/rf5c164.h Sat Mar 26 02:01:55 2022 -0700 @@ -17,8 +17,8 @@ uint16_t ram[64*1024]; uint16_t ram_bank; uint16_t pending_address; - int16_t left; - int16_t right; + int32_t left; + int32_t right; rf5c164_channel channels[8]; uint8_t pending_byte; uint8_t channel_enable;