Skip to content

Commit 460e894

Browse files
committed
port recent MAME sound core updates
notable updates: - C6280: improve volume calculation - GameBoy: fix master volume - K054539: fix reverb buffer size - Pokey: emulatate "async mode", may affect channel frequencies - YRW258: fix sample interpolation
1 parent 5aa5147 commit 460e894

File tree

14 files changed

+563
-456
lines changed

14 files changed

+563
-456
lines changed

emu/SoundDevs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,5 +46,5 @@
4646
#define DEVID_K007232 0x2A
4747
#define DEVID_K005289 0x2B
4848
#define DEVID_MSM5205 0x2C // variants: MSM5205, MSM6585
49-
#define DEVID_MSM5232 0x2D
49+
#define DEVID_MSM5232 0x2D
5050
#endif // __SOUNDDEVS_H__

emu/cores/ay8910.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,21 +1041,22 @@ void ay8910_write_reg(ay8910_context *psg, UINT8 r, UINT8 v)
10411041
/* No action required */
10421042
break;
10431043
case AY_ENABLE:
1044-
if (psg->last_enable == 0xFF)
1045-
psg->last_enable = ~psg->regs[AY_ENABLE];
1046-
1047-
if ((psg->last_enable & 0x40) != (psg->regs[AY_ENABLE] & 0x40))
10481044
{
1049-
/* write out 0xff if port set to input */
1050-
//if (psg->port_a_write_cb != NULL)
1051-
// psg->port_a_write_cb(psg, 0, (psg->regs[AY_ENABLE] & 0x40) ? psg->regs[AY_PORTA] : 0xff);
1052-
}
1045+
UINT8 enable = psg->regs[AY_ENABLE] & 0x40;
1046+
if (enable != (psg->last_enable & 0x40))
1047+
{
1048+
// output is high-impedance if port is set to input
1049+
//if (psg->port_a_write_cb != NULL)
1050+
// psg->port_a_write_cb(psg, 0, enable ? psg->regs[AY_PORTA] : 0xff);
1051+
}
10531052

1054-
if ((psg->last_enable & 0x80) != (psg->regs[AY_ENABLE] & 0x80))
1055-
{
1056-
/* write out 0xff if port set to input */
1057-
//if (psg->port_b_write_cb != NULL)
1058-
// psg->port_b_write_cb(psg, 0, (psg->regs[AY_ENABLE] & 0x80) ? psg->regs[AY_PORTB] : 0xff);
1053+
enable = psg->regs[AY_ENABLE] & 0x80;
1054+
if (enable != (psg->last_enable & 0x80))
1055+
{
1056+
// output is high-impedance if port is set to input
1057+
//if (psg->port_b_write_cb != NULL)
1058+
// psg->port_b_write_cb(psg, 0, enable ? psg->regs[AY_PORTB] : 0xff);
1059+
}
10591060
}
10601061

10611062
psg->last_enable = psg->regs[AY_ENABLE] & 0xC0;
@@ -1441,7 +1442,7 @@ void ay8910_reset(void *chip)
14411442
psg->count_noise = 0;
14421443
psg->count_env = 0;
14431444
psg->prescale_noise = 0;
1444-
psg->last_enable = 0xFF; /* force a write */
1445+
psg->last_enable = 0xC0; /* force a write */
14451446
for (i = 0;i < AY_PORTA;i++)
14461447
ay8910_write_reg(psg,i,0);
14471448
//psg->ready = 1;
@@ -1527,7 +1528,7 @@ UINT8 ay8910_read(void *chip, UINT8 addr)
15271528
switch (r)
15281529
{
15291530
case AY_PORTA:
1530-
if ((psg->regs[AY_ENABLE] & 0x40) != 0)
1531+
if (psg->regs[AY_ENABLE] & 0x40)
15311532
emu_logf(&psg->logger, DEVLOG_WARN, "read from Port A set as output\n");
15321533
/*
15331534
even if the port is set as output, we still need to return the external
@@ -1545,7 +1546,7 @@ UINT8 ay8910_read(void *chip, UINT8 addr)
15451546
// emu_logf(&psg->logger, DEVLOG_WARN, "read Port A\n");
15461547
break;
15471548
case AY_PORTB:
1548-
if ((psg->regs[AY_ENABLE] & 0x80) != 0)
1549+
if (psg->regs[AY_ENABLE] & 0x80)
15491550
emu_logf(&psg->logger, DEVLOG_WARN, "read from Port B set as output\n");
15501551
//if (psg->port_b_read_cb != NULL)
15511552
// psg->regs[AY_PORTB] = psg->port_b_read_cb(psg, 0);

emu/cores/c140.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,17 +259,16 @@ static void c140_w(void *chip, UINT16 offset, UINT8 data)
259259
}
260260
}
261261
}
262-
else if (offset == 0x1fa)
262+
else if (offset == 0x1fa) // set INT1 timer
263263
{
264264
//info->int1_callback(CLEAR_LINE);
265265

266266
// timing not verified
267-
//unsigned div = info->REG[0x1f8] != 0 ? info->REG[0x1f8] : 256;
268-
//attotime interval = attotime::from_ticks(div * 2, info->baserate);
267+
//attotime interval = attotime::from_ticks((info->REG[0x1f8] + 1) * 2, info->baserate);
269268
//if (info->REG[0x1fe] & 0x01)
270269
// info->int1_timer->adjust(interval);
271270
}
272-
else if (offset == 0x1fe)
271+
else if (offset == 0x1fe) // enable INT1 timer
273272
{
274273
if (data & 0x01)
275274
{

emu/cores/c6280_mame.c

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -270,12 +270,18 @@ static void c6280mame_w(void *chip, UINT8 offset, UINT8 data)
270270

271271
static void c6280mame_update(void* param, UINT32 samples, DEV_SMPL **outputs)
272272
{
273+
static const UINT8 scale_tab[16] =
274+
{
275+
0x00, 0x03, 0x05, 0x07, 0x09, 0x0b, 0x0d, 0x0f,
276+
0x10, 0x13, 0x15, 0x17, 0x19, 0x1b, 0x1d, 0x1f
277+
};
278+
273279
int ch;
274280
UINT32 i;
275281
c6280_t *p = (c6280_t *)param;
276282

277-
UINT8 lmal = (p->balance >> 4) & 0x0F;
278-
UINT8 rmal = (p->balance >> 0) & 0x0F;
283+
UINT8 lmal = scale_tab[(p->balance >> 4) & 0x0F];
284+
UINT8 rmal = scale_tab[(p->balance >> 0) & 0x0F];
279285

280286
/* Clear buffer */
281287
memset(outputs[0], 0x00, samples * sizeof(DEV_SMPL));
@@ -286,85 +292,85 @@ static void c6280mame_update(void* param, UINT32 samples, DEV_SMPL **outputs)
286292
/* Only look at enabled channels */
287293
if((p->channel[ch].control & 0x80) && ! p->channel[ch].Muted)
288294
{
289-
UINT8 lal = (p->channel[ch].balance >> 4) & 0x0F;
290-
UINT8 ral = (p->channel[ch].balance >> 0) & 0x0F;
291-
UINT8 al = (p->channel[ch].control >> 1) & 0x0F; // only high 4 bit is affected to calculating volume, low 1 bit is independent
295+
t_channel* chan = &p->channel[ch];
296+
UINT8 lal = scale_tab[(chan->balance >> 4) & 0x0F];
297+
UINT8 ral = scale_tab[(chan->balance >> 0) & 0x0F];
298+
UINT8 al = chan->control & 0x1F;
292299
INT16 vll, vlr;
293300

294301
// verified from both patent and manual
295-
vll = (0xf - lmal) + (0xf - al) + (0xf - lal);
296-
if (vll > 0xf) vll = 0xf;
302+
vll = (0x1f - lmal) + (0x1f - al) + (0x1f - lal);
303+
if (vll > 0x1f) vll = 0x1f;
297304

298-
vlr = (0xf - rmal) + (0xf - al) + (0xf - ral);
299-
if (vlr > 0xf) vlr = 0xf;
305+
vlr = (0x1f - rmal) + (0x1f - al) + (0x1f - ral);
306+
if (vlr > 0x1f) vlr = 0x1f;
300307

301-
vll = p->volume_table[(vll << 1) | (~p->channel[ch].control & 1)];
302-
vlr = p->volume_table[(vlr << 1) | (~p->channel[ch].control & 1)];
308+
vll = p->volume_table[vll];
309+
vlr = p->volume_table[vlr];
303310

304311
/* Check channel mode */
305-
if((ch >= 4) && (p->channel[ch].noise_control & 0x80))
312+
if ((ch >= 4) && (chan->noise_control & 0x80))
306313
{
307314
/* Noise mode */
308-
UINT32 step = p->noise_freq_tab[(p->channel[ch].noise_control & 0x1F) ^ 0x1F];
309-
for(i = 0; i < samples; i += 1)
315+
UINT32 step = p->noise_freq_tab[(chan->noise_control & 0x1F) ^ 0x1F];
316+
for(i = 0; i < samples; i++)
310317
{
311-
INT16 data = (p->channel[ch].noise_seed & 1) ? 0x1F : 0;
312-
p->channel[ch].noise_counter += step;
313-
if(p->channel[ch].noise_counter >= 0x800)
318+
INT16 data = (chan->noise_seed & 1) ? 0x1F : 0;
319+
chan->noise_counter += step;
320+
if(chan->noise_counter >= 0x800)
314321
{
315-
UINT32 seed = p->channel[ch].noise_seed;
322+
UINT32 seed = chan->noise_seed;
316323
// based on Charles MacDonald's research
317324
UINT32 feedback = ((seed) ^ (seed >> 1) ^ (seed >> 11) ^ (seed >> 12) ^ (seed >> 17)) & 1;
318-
p->channel[ch].noise_seed = (p->channel[ch].noise_seed >> 1) ^ (feedback << 17);
325+
chan->noise_seed = (chan->noise_seed >> 1) ^ (feedback << 17);
319326
}
320-
p->channel[ch].noise_counter &= 0x7FF;
327+
chan->noise_counter &= 0x7FF;
321328
outputs[0][i] += (vll * (data - 16));
322329
outputs[1][i] += (vlr * (data - 16));
323330
}
324331
}
325-
else
326-
if(p->channel[ch].control & 0x40)
332+
else if (chan->control & 0x40)
327333
{
328334
/* DDA mode */
329335
for(i = 0; i < samples; i++)
330336
{
331-
outputs[0][i] += (vll * (p->channel[ch].dda - 16));
332-
outputs[1][i] += (vlr * (p->channel[ch].dda - 16));
337+
outputs[0][i] += (vll * (chan->dda - 16));
338+
outputs[1][i] += (vlr * (chan->dda - 16));
333339
}
334340
}
335341
else
336342
{
337-
//if ((p->lfo_control & 3) && (ch < 2))
338-
if ((p->lfo_control & 0x80) && (ch < 2))
343+
if ((p->lfo_control & 3) && (ch < 2))
339344
{
340345
if (ch == 0) // CH 0 only, CH 1 is muted
341346
{
342347
/* Waveform mode with LFO */
343-
UINT16 lfo_step = p->channel[1].frequency;
344-
for (i = 0; i < samples; i += 1)
348+
t_channel* lfo_srcchan = &p->channel[1];
349+
t_channel* lfo_dstchan = &p->channel[0];
350+
UINT16 lfo_step = lfo_srcchan->frequency;
351+
for (i = 0; i < samples; i++)
345352
{
346-
UINT32 step = p->channel[0].frequency;
353+
UINT32 step = lfo_dstchan->frequency;
347354
UINT8 offset;
348355
INT16 data;
349356
if (p->lfo_control & 0x80) // reset LFO
350357
{
351-
p->channel[1].counter = 0;
358+
lfo_srcchan->counter = 0;
352359
}
353360
else
354361
{
355-
int lfooffset = (p->channel[1].counter >> 12) & 0x1F;
356-
INT16 lfo_data = p->channel[1].waveform[lfooffset];
357-
p->channel[1].counter += p->wave_freq_tab[(lfo_step * p->lfo_frequency) & 0xfff]; // TODO : multiply? verify this from real hardware.
358-
p->channel[1].counter &= 0x1FFFF;
359-
p->channel[1].index = (p->channel[1].counter >> 12) & 0x1F;
360-
if (p->lfo_control & 3)
361-
step += ((lfo_data - 16) << (((p->lfo_control & 3)-1)<<1)); // verified from patent, TODO : same in real hardware?
362+
int lfooffset = (lfo_srcchan->counter >> 12) & 0x1F;
363+
INT16 lfo_data = lfo_srcchan->waveform[lfooffset];
364+
lfo_srcchan->counter += p->wave_freq_tab[(lfo_step * p->lfo_frequency) & 0xfff]; // verified from manual
365+
lfo_srcchan->counter &= 0x1FFFF;
366+
lfo_srcchan->index = (lfo_srcchan->counter >> 12) & 0x1F;
367+
step += ((lfo_data - 16) << (((p->lfo_control & 3) - 1) << 1)); // verified from manual
362368
}
363-
offset = (p->channel[0].counter >> 12) & 0x1F;
364-
data = p->channel[0].waveform[offset];
365-
p->channel[0].counter += p->wave_freq_tab[step & 0xfff];
366-
p->channel[0].counter &= 0x1FFFF;
367-
p->channel[0].index = (p->channel[0].counter >> 12) & 0x1F;
369+
offset = (lfo_dstchan->counter >> 12) & 0x1F;
370+
data = lfo_dstchan->waveform[offset];
371+
lfo_dstchan->counter += p->wave_freq_tab[step & 0xfff];
372+
lfo_dstchan->counter &= 0x1FFFF;
373+
lfo_dstchan->index = (lfo_dstchan->counter >> 12) & 0x1F;
368374
outputs[0][i] += (vll * (data - 16));
369375
outputs[1][i] += (vlr * (data - 16));
370376
}
@@ -373,14 +379,14 @@ static void c6280mame_update(void* param, UINT32 samples, DEV_SMPL **outputs)
373379
else
374380
{
375381
/* Waveform mode */
376-
UINT32 step = p->wave_freq_tab[p->channel[ch].frequency];
377-
for (i = 0; i < samples; i += 1)
382+
UINT32 step = p->wave_freq_tab[chan->frequency];
383+
for (i = 0; i < samples; i++)
378384
{
379-
UINT8 offset = (p->channel[ch].counter >> 12) & 0x1F;
380-
INT16 data = p->channel[ch].waveform[offset];
381-
p->channel[ch].counter += step;
382-
p->channel[ch].counter &= 0x1FFFF;
383-
p->channel[ch].index = (p->channel[ch].counter >> 12) & 0x1F;
385+
UINT8 offset = (chan->counter >> 12) & 0x1F;
386+
INT16 data = chan->waveform[offset];
387+
chan->counter += step;
388+
chan->counter &= 0x1FFFF;
389+
chan->index = (chan->counter >> 12) & 0x1F;
384390
outputs[0][i] += (vll * (data - 16));
385391
outputs[1][i] += (vlr * (data - 16));
386392
}
@@ -431,12 +437,12 @@ static void* device_start_c6280mame(UINT32 clock, UINT32 rate)
431437
/* Make volume table */
432438
/* PSG has 48dB volume range spread over 32 steps */
433439
step = 48.0 / 32.0;
434-
for (i = 0; i < 30; i++)
440+
for (i = 0; i < 31; i++)
435441
{
436442
info->volume_table[i] = (UINT16)level;
437443
level /= pow(10.0, step / 20.0);
438444
}
439-
info->volume_table[30] = info->volume_table[31] = 0;
445+
info->volume_table[31] = 0;
440446

441447
c6280mame_set_mute_mask(info, 0x00);
442448

emu/cores/es5503.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
2.1.3 (RB) - Fixed oscillator enable register off-by-1 which caused everything to be half a step sharp.
3737
2.2 (RB) - More precise one-shot even/swap odd behavior from hardware observations with Ian Brumby's SWAPTEST.
3838
2.3 (RB) - Sync & AM modes added, emulate the volume glitch for the highest-numbered enabled oscillator.
39+
2.3.1 (RB) - Fixed thinko in the volume glitch emulation and minor cleanup.
3940
*/
4041

4142
#include <stdlib.h>

0 commit comments

Comments
 (0)