mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Fixed noise period on AY8910. [Dr. Venom, Couriersud]
This commit is contained in:
parent
733dae59df
commit
354cacc1c7
@ -9,6 +9,13 @@
|
||||
|
||||
Mostly rewritten by couriersud in 2008
|
||||
|
||||
Public documentation:
|
||||
|
||||
- http://privatfrickler.de/blick-auf-den-chip-soundchip-general-instruments-ay-3-8910/
|
||||
Die pictures of the AY8910
|
||||
|
||||
- US Patent 4933980
|
||||
|
||||
Games using ADSR: gyruss
|
||||
|
||||
A list with more games using ADSR can be found here:
|
||||
@ -144,6 +151,7 @@ has twice the steps, happening twice as fast.
|
||||
#define TONE_VOLUME(_psg, _chan) ( (_psg)->regs[AY_AVOL + (_chan)] & 0x0f)
|
||||
#define TONE_ENVELOPE(_psg, _chan) (((_psg)->regs[AY_AVOL + (_chan)] >> 4) & (((_psg)->device->type() == AY8914) ? 3 : 1))
|
||||
#define ENVELOPE_PERIOD(_psg) (((_psg)->regs[AY_EFINE] | ((_psg)->regs[AY_ECOARSE]<<8)))
|
||||
#define NOISE_OUTPUT(_psg) ((_psg)->rng & 1)
|
||||
|
||||
/*************************************
|
||||
*
|
||||
@ -171,7 +179,7 @@ struct ay8910_context
|
||||
INT32 last_enable;
|
||||
INT32 count[NUM_CHANNELS];
|
||||
UINT8 output[NUM_CHANNELS];
|
||||
UINT8 output_noise;
|
||||
UINT8 prescale_noise;
|
||||
INT32 count_noise;
|
||||
INT32 count_env;
|
||||
INT8 env_step;
|
||||
@ -485,7 +493,6 @@ static void ay8910_write_reg(ay8910_context *psg, int r, int v)
|
||||
/* write out 0xff if port set to input */
|
||||
psg->portBwrite(0, (psg->regs[AY_ENABLE] & 0x80) ? psg->regs[AY_PORTB] : 0xff);
|
||||
}
|
||||
|
||||
psg->last_enable = psg->regs[AY_ENABLE];
|
||||
break;
|
||||
case AY_ESHAPE:
|
||||
@ -577,37 +584,33 @@ static STREAM_UPDATE( ay8910_update )
|
||||
if (psg->count[chan] >= TONE_PERIOD(psg, chan))
|
||||
{
|
||||
psg->output[chan] ^= 1;
|
||||
psg->count[chan] = 0;;
|
||||
psg->count[chan] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
psg->count_noise++;
|
||||
if (psg->count_noise >= NOISE_PERIOD(psg))
|
||||
{
|
||||
/* Is noise output going to change? */
|
||||
if ((psg->rng + 1) & 2) /* (bit0^bit1)? */
|
||||
{
|
||||
psg->output_noise ^= 1;
|
||||
}
|
||||
/* toggle the prescaler output. Noise is no different to
|
||||
* channels.
|
||||
*/
|
||||
psg->count_noise = 0;
|
||||
psg->prescale_noise ^= 1;
|
||||
|
||||
/* The Random Number Generator of the 8910 is a 17-bit shift */
|
||||
/* register. The input to the shift register is bit0 XOR bit3 */
|
||||
/* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */
|
||||
if ( psg->prescale_noise)
|
||||
{
|
||||
/* The Random Number Generator of the 8910 is a 17-bit shift */
|
||||
/* register. The input to the shift register is bit0 XOR bit3 */
|
||||
/* (bit0 is the output). This was verified on AY-3-8910 and YM2149 chips. */
|
||||
|
||||
/* The following is a fast way to compute bit17 = bit0^bit3. */
|
||||
/* Instead of doing all the logic operations, we only check */
|
||||
/* bit0, relying on the fact that after three shifts of the */
|
||||
/* register, what now is bit3 will become bit0, and will */
|
||||
/* invert, if necessary, bit14, which previously was bit17. */
|
||||
if (psg->rng & 1)
|
||||
psg->rng ^= 0x24000; /* This version is called the "Galois configuration". */
|
||||
psg->rng >>= 1;
|
||||
psg->count_noise = 0;
|
||||
psg->rng ^= (((psg->rng & 1) ^ ((psg->rng >> 3) & 1)) << 17);
|
||||
psg->rng >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (chan = 0; chan < NUM_CHANNELS; chan++)
|
||||
{
|
||||
psg->vol_enabled[chan] = (psg->output[chan] | TONE_ENABLEQ(psg, chan)) & (psg->output_noise | NOISE_ENABLEQ(psg, chan));
|
||||
psg->vol_enabled[chan] = (psg->output[chan] | TONE_ENABLEQ(psg, chan)) & (NOISE_OUTPUT(psg) | NOISE_ENABLEQ(psg, chan));
|
||||
}
|
||||
|
||||
/* update envelope */
|
||||
@ -712,7 +715,7 @@ static void ay8910_statesave(ay8910_context *psg, device_t *device)
|
||||
device->save_item(NAME(psg->env_volume));
|
||||
|
||||
device->save_item(NAME(psg->output));
|
||||
device->save_item(NAME(psg->output_noise));
|
||||
device->save_item(NAME(psg->prescale_noise));
|
||||
|
||||
device->save_item(NAME(psg->env_step));
|
||||
device->save_item(NAME(psg->hold));
|
||||
@ -804,7 +807,7 @@ void ay8910_reset_ym(void *chip)
|
||||
psg->count[2] = 0;
|
||||
psg->count_noise = 0;
|
||||
psg->count_env = 0;
|
||||
psg->output_noise = 0x01;
|
||||
psg->prescale_noise = 0;
|
||||
psg->last_enable = -1; /* force a write */
|
||||
for (i = 0;i < AY_PORTA;i++)
|
||||
ay8910_write_reg(psg,i,0);
|
||||
|
Loading…
Reference in New Issue
Block a user