added out of bounds check for readmem

This commit is contained in:
Michaël Banaan Ananas 2011-08-18 13:49:09 +00:00
parent ad281de086
commit a93a2948fc

View File

@ -79,6 +79,7 @@ struct _ymz280b_state
{
sound_stream * stream; /* which stream are we using */
UINT8 *region_base; /* pointer to the base of the region */
UINT32 region_size;
UINT8 current_register; /* currently accessible register */
UINT8 status_register; /* current status register */
UINT8 irq_state; /* current IRQ state */
@ -140,6 +141,20 @@ INLINE ymz280b_state *get_safe_token(device_t *device)
}
INLINE UINT8 ymz280b_read_memory(UINT8 *base, UINT32 size, UINT32 offset)
{
if (offset < size)
return base[offset];
/* 16MB chip limit */
else if (offset > 0xffffff)
return base[offset & 0xffffff];
else
return 0;
}
INLINE void update_irq_state(ymz280b_state *chip)
{
int irq_bits = chip->status_register & chip->irq_mask;
@ -263,7 +278,7 @@ static void compute_tables(void)
***********************************************************************************************/
static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, UINT32 size, INT16 *buffer, int samples)
{
int position = voice->position;
int signal = voice->signal;
@ -277,7 +292,7 @@ static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer
while (samples)
{
/* compute the new amplitude and update the current step */
val = base[position / 2] >> ((~position & 1) << 2);
val = ymz280b_read_memory(base, size, position / 2) >> ((~position & 1) << 2);
signal += (step * diff_lookup[val & 15]) / 8;
/* clamp to the maximum */
@ -316,7 +331,7 @@ static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer
while (samples)
{
/* compute the new amplitude and update the current step */
val = base[position / 2] >> ((~position & 1) << 2);
val = ymz280b_read_memory(base, size, position / 2) >> ((~position & 1) << 2);
signal += (step * diff_lookup[val & 15]) / 8;
/* clamp to the maximum */
@ -379,7 +394,7 @@ static int generate_adpcm(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer
***********************************************************************************************/
static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, UINT32 size, INT16 *buffer, int samples)
{
int position = voice->position;
int val;
@ -391,7 +406,7 @@ static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer,
while (samples)
{
/* fetch the current value */
val = base[position / 2];
val = ymz280b_read_memory(base, size, position / 2);
/* output to the buffer, scaling by the volume */
*buffer++ = (INT8)val * 256;
@ -416,7 +431,7 @@ static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer,
while (samples)
{
/* fetch the current value */
val = base[position / 2];
val = ymz280b_read_memory(base, size, position / 2);
/* output to the buffer, scaling by the volume */
*buffer++ = (INT8)val * 256;
@ -453,7 +468,7 @@ static int generate_pcm8(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer,
***********************************************************************************************/
static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer, int samples)
static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, UINT32 size, INT16 *buffer, int samples)
{
int position = voice->position;
int val;
@ -465,7 +480,7 @@ static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer
while (samples)
{
/* fetch the current value */
val = (INT16)((base[position / 2 + 1] << 8) + base[position / 2]);
val = (INT16)((ymz280b_read_memory(base, size, position / 2 + 1) << 8) + ymz280b_read_memory(base, size, position / 2));
/* output to the buffer, scaling by the volume */
*buffer++ = val;
@ -490,7 +505,7 @@ static int generate_pcm16(struct YMZ280BVoice *voice, UINT8 *base, INT16 *buffer
while (samples)
{
/* fetch the current value */
val = (INT16)((base[position / 2 + 1] << 8) + base[position / 2]);
val = (INT16)((ymz280b_read_memory(base, size, position / 2 + 1) << 8) + ymz280b_read_memory(base, size, position / 2));
/* output to the buffer, scaling by the volume */
*buffer++ = val;
@ -589,9 +604,9 @@ static STREAM_UPDATE( ymz280b_update )
/* generate them into our buffer */
switch (voice->playing << 7 | voice->mode)
{
case 0x81: samples_left = generate_adpcm(voice, chip->region_base, chip->scratch, new_samples); break;
case 0x82: samples_left = generate_pcm8(voice, chip->region_base, chip->scratch, new_samples); break;
case 0x83: samples_left = generate_pcm16(voice, chip->region_base, chip->scratch, new_samples); break;
case 0x81: samples_left = generate_adpcm(voice, chip->region_base, chip->region_size, chip->scratch, new_samples); break;
case 0x82: samples_left = generate_pcm8(voice, chip->region_base, chip->region_size, chip->scratch, new_samples); break;
case 0x83: samples_left = generate_pcm16(voice, chip->region_base, chip->region_size, chip->scratch, new_samples); break;
default: samples_left = 0; memset(chip->scratch, 0, new_samples * sizeof(chip->scratch[0])); break;
}
@ -681,6 +696,7 @@ static DEVICE_START( ymz280b )
/* initialize the rest of the structure */
chip->master_clock = (double)device->clock() / 384.0;
chip->region_base = *device->region();
chip->region_size = device->region()->bytes();
chip->irq_callback = intf->irq_callback;
/* create the stream */
@ -964,7 +980,9 @@ static int compute_status(ymz280b_state *chip)
/* ROM/RAM readback? */
if (chip->current_register == 0x86)
{
return chip->region_base[chip->rom_readback_addr];
result = ymz280b_read_memory(chip->region_base, chip->region_size, chip->rom_readback_addr);
chip->rom_readback_addr = (chip->rom_readback_addr + 1) & 0xffffff;
return result;
}
/* force an update */
@ -994,9 +1012,14 @@ READ8_DEVICE_HANDLER( ymz280b_r )
if ((offset & 1) == 0)
{
/* read from external memory */
UINT8 read = chip->ext_ram_read.isnull() ? 0 : chip->ext_ram_read(chip->rom_readback_addr);
UINT8 result;
if (chip->ext_ram_read.isnull())
result = chip->ext_ram_read(chip->rom_readback_addr);
else
result = ymz280b_read_memory(chip->region_base, chip->region_size, chip->rom_readback_addr);
chip->rom_readback_addr = (chip->rom_readback_addr + 1) & 0xffffff;
return read;
return result;
}
else
return compute_status(chip);