Added sanity checks to all RAM accesses in the GUS code, fixes #3790.
This commit is contained in:
@@ -427,7 +427,8 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
if (gus->voices < 14)
|
||||
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0));
|
||||
else
|
||||
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14]));
|
||||
gus->samp_latch = (uint64_t) (TIMER_USEC *
|
||||
(1000000.0 / gusfreqs[gus->voices - 14]));
|
||||
break;
|
||||
|
||||
case 0x41: /*DMA*/
|
||||
@@ -437,15 +438,28 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
while (c < 65536) {
|
||||
int dma_result;
|
||||
if (val & 0x04) {
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
|
||||
d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8);
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) |
|
||||
((gus->dmaaddr & 0x1ffff) << 1);
|
||||
|
||||
if (gus_addr < gus->gus_end_ram)
|
||||
d = gus->ram[gus_addr];
|
||||
else
|
||||
d = 0x00;
|
||||
|
||||
if ((gus_addr + 1) < gus->gus_end_ram)
|
||||
d |= (gus->ram[gus_addr + 1] << 8);
|
||||
|
||||
if (val & 0x80)
|
||||
d ^= 0x8080;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
if (dma_result == DMA_NODATA)
|
||||
break;
|
||||
} else {
|
||||
d = gus->ram[gus->dmaaddr];
|
||||
if (gus->dmaaddr < gus->gus_end_ram)
|
||||
d = gus->ram[gus->dmaaddr];
|
||||
else
|
||||
d = 0x00;
|
||||
|
||||
if (val & 0x80)
|
||||
d ^= 0x80;
|
||||
dma_result = dma_channel_write(gus->dma, d);
|
||||
@@ -453,7 +467,7 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
}
|
||||
gus->dmaaddr++;
|
||||
gus->dmaaddr &= 0xFFFFF;
|
||||
gus->dmaaddr &= 0xfffff;
|
||||
c++;
|
||||
if (dma_result & DMA_OVER)
|
||||
break;
|
||||
@@ -467,18 +481,25 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
if (d == DMA_NODATA)
|
||||
break;
|
||||
if (val & 0x04) {
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1);
|
||||
uint32_t gus_addr = (gus->dmaaddr & 0xc0000) |
|
||||
((gus->dmaaddr & 0x1ffff) << 1);
|
||||
if (val & 0x80)
|
||||
d ^= 0x8080;
|
||||
gus->ram[gus_addr] = d & 0xff;
|
||||
gus->ram[gus_addr + 1] = (d >> 8) & 0xff;
|
||||
|
||||
if (gus_addr < gus->gus_end_ram)
|
||||
gus->ram[gus_addr] = d & 0xff;
|
||||
|
||||
if ((gus_addr + 1) < gus->gus_end_ram)
|
||||
gus->ram[gus_addr + 1] = (d >> 8) & 0xff;
|
||||
} else {
|
||||
if (val & 0x80)
|
||||
d ^= 0x80;
|
||||
gus->ram[gus->dmaaddr] = d;
|
||||
|
||||
if (gus->dmaaddr < gus->gus_end_ram)
|
||||
gus->ram[gus->dmaaddr] = d;
|
||||
}
|
||||
gus->dmaaddr++;
|
||||
gus->dmaaddr &= 0xFFFFF;
|
||||
gus->dmaaddr &= 0xfffff;
|
||||
c++;
|
||||
if (d & DMA_OVER)
|
||||
break;
|
||||
@@ -494,28 +515,20 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
break;
|
||||
|
||||
case 0x43: /*Address low*/
|
||||
gus->addr = (gus->addr & 0xF00FF) | (val << 8);
|
||||
gus->addr = (gus->addr & 0xf00ff) | (val << 8);
|
||||
break;
|
||||
case 0x44: /*Address high*/
|
||||
gus->addr = (gus->addr & 0xFFFF) | ((val << 16) & 0xF0000);
|
||||
gus->addr = (gus->addr & 0x0ffff) | ((val << 16) & 0xf0000);
|
||||
break;
|
||||
case 0x45: /*Timer control*/
|
||||
if (!(val & 4))
|
||||
gus->irqstatus &= ~4;
|
||||
if (!(val & 8))
|
||||
gus->irqstatus &= ~8;
|
||||
if (!(val & 0x20)) {
|
||||
if (!(val & 0x20))
|
||||
gus->ad_status &= ~0x18;
|
||||
#ifdef OLD_NMI_BEHAVIOR
|
||||
nmi = 0;
|
||||
#endif
|
||||
}
|
||||
if (!(val & 0x02)) {
|
||||
if (!(val & 0x02))
|
||||
gus->ad_status &= ~0x01;
|
||||
#ifdef OLD_NMI_BEHAVIOR
|
||||
nmi = 0;
|
||||
#endif
|
||||
}
|
||||
gus->tctrl = val;
|
||||
gus->sb_ctrl = val;
|
||||
gus_update_int_status(gus);
|
||||
@@ -540,7 +553,7 @@ writegus(uint16_t addr, uint8_t val, void *priv)
|
||||
case 0x307: /*DRAM access*/
|
||||
if (gus->addr < gus->gus_end_ram)
|
||||
gus->ram[gus->addr] = val;
|
||||
gus->addr &= 0xFFFFF;
|
||||
gus->addr &= 0xfffff;
|
||||
break;
|
||||
case 0x208:
|
||||
case 0x388:
|
||||
@@ -874,8 +887,7 @@ readgus(uint16_t addr, void *priv)
|
||||
break;
|
||||
|
||||
case 0x307: /*DRAM access*/
|
||||
val = gus->ram[gus->addr];
|
||||
gus->addr &= 0xFFFFF;
|
||||
gus->addr &= 0xfffff;
|
||||
if (gus->addr < gus->gus_end_ram)
|
||||
val = gus->ram[gus->addr];
|
||||
else
|
||||
@@ -1034,21 +1046,41 @@ gus_poll_wave(void *priv)
|
||||
if (gus->ctrl[d] & 4) {
|
||||
addr = gus->cur[d] >> 9;
|
||||
addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE);
|
||||
if (!(gus->freq[d] >> 10)) /*Interpolate*/
|
||||
{
|
||||
vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511));
|
||||
vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511);
|
||||
if (!(gus->freq[d] >> 10)) {
|
||||
/* Interpolate */
|
||||
if (((addr + 1) & 0xfffff) < gus->gus_end_ram)
|
||||
vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80) *
|
||||
(511 - (gus->cur[d] & 511));
|
||||
else
|
||||
vl = 0;
|
||||
|
||||
if (((addr + 3) & 0xfffff) < gus->gus_end_ram)
|
||||
vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xfffff] ^ 0x80) - 0x80) *
|
||||
(gus->cur[d] & 511);
|
||||
|
||||
v = vl >> 9;
|
||||
} else
|
||||
v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80);
|
||||
} else if (((addr + 1) & 0xfffff) < gus->gus_end_ram)
|
||||
v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80);
|
||||
else
|
||||
v = 0x0000;
|
||||
} else {
|
||||
if (!(gus->freq[d] >> 10)) /*Interpolate*/
|
||||
{
|
||||
vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511));
|
||||
vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511);
|
||||
if (!(gus->freq[d] >> 10)) {
|
||||
/* Interpolate */
|
||||
if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram)
|
||||
vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80)) *
|
||||
(511 - (gus->cur[d] & 511));
|
||||
else
|
||||
vl = 0;
|
||||
|
||||
if ((((gus->cur[d] >> 9) + 1) & 0xfffff) < gus->gus_end_ram)
|
||||
vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xfffff] ^ 0x80) - 0x80)) *
|
||||
(gus->cur[d] & 511);
|
||||
|
||||
v = vl >> 9;
|
||||
} else
|
||||
v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80);
|
||||
} else if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram)
|
||||
v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80);
|
||||
else
|
||||
v = 0x0000;
|
||||
}
|
||||
|
||||
if ((gus->rcur[d] >> 14) > 4095)
|
||||
|
Reference in New Issue
Block a user