Mercurial > repos > blastem
comparison rf5c164.c @ 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 | b0dcf5c9f353 |
children | 4fbe1e7c4a73 |
comparison
equal
deleted
inserted
replaced
2144:10e4439d8f13 | 2145:62a53c052d9b |
---|---|
137 } | 137 } |
138 sample *= pcm->channels[pcm->cur_channel].regs[ENV]; | 138 sample *= pcm->channels[pcm->cur_channel].regs[ENV]; |
139 int16_t left = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] >> 4)) >> 5; | 139 int16_t left = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] >> 4)) >> 5; |
140 int16_t right = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] & 0xF)) >> 5; | 140 int16_t right = (sample * (pcm->channels[pcm->cur_channel].regs[PAN] & 0xF)) >> 5; |
141 //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); | 141 //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); |
142 //TODO: saturating add | |
143 pcm->left += left; | 142 pcm->left += left; |
144 pcm->right += right; | 143 pcm->right += right; |
145 } | 144 } |
146 write_if_not_sounding(pcm); | 145 write_if_not_sounding(pcm); |
147 CHECK; | 146 CHECK; |
153 case 11: | 152 case 11: |
154 write_always(pcm); | 153 write_always(pcm); |
155 pcm->cur_channel++; | 154 pcm->cur_channel++; |
156 pcm->cur_channel &= 7; | 155 pcm->cur_channel &= 7; |
157 if (!pcm->cur_channel) { | 156 if (!pcm->cur_channel) { |
157 if (pcm->left > INT16_MAX) { | |
158 pcm->left = INT16_MAX; | |
159 } else if (pcm->left < INT16_MIN) { | |
160 pcm->left = INT16_MIN; | |
161 } | |
162 if (pcm->right > INT16_MAX) { | |
163 pcm->right = INT16_MAX; | |
164 } else if (pcm->right < INT16_MIN) { | |
165 pcm->right = INT16_MIN; | |
166 } | |
158 render_put_stereo_sample(pcm->audio, pcm->left, pcm->right); | 167 render_put_stereo_sample(pcm->audio, pcm->left, pcm->right); |
159 pcm->left = pcm->right = 0; | 168 pcm->left = pcm->right = 0; |
160 } | 169 } |
161 CHECK_LOOP; | 170 CHECK_LOOP; |
162 } | 171 } |
183 uint8_t changed = pcm->channel_enable ^ value; | 192 uint8_t changed = pcm->channel_enable ^ value; |
184 pcm->channel_enable = value; | 193 pcm->channel_enable = value; |
185 for (int i = 0; i < 8; i++) | 194 for (int i = 0; i < 8; i++) |
186 { | 195 { |
187 int mask = 1 << i; | 196 int mask = 1 << i; |
188 if (changed & mask & value) { | 197 if ((changed & mask) && !(mask & value)) { |
189 pcm->channels[i].state = START; | 198 pcm->channels[i].state = START; |
190 } | 199 } |
191 } | 200 } |
192 } else if (address <= ST) { | 201 } else if (address <= ST) { |
193 //See note in first step of rf5c164_run | 202 //See note in first step of rf5c164_run |