Fixed terminal count on auto-init DMA. Fixed sound on All New World of Lemmings when using GUS.

This commit is contained in:
TomW 2014-08-24 14:08:17 +01:00
commit 4817a53619
2 changed files with 16 additions and 5 deletions

View file

@ -251,6 +251,7 @@ void _dma_write(uint32_t addr, uint8_t val)
int dma_channel_read(int channel) int dma_channel_read(int channel)
{ {
uint16_t temp; uint16_t temp;
int tc = 0;
if (dma.command & 0x04) if (dma.command & 0x04)
return DMA_NODATA; return DMA_NODATA;
@ -272,6 +273,7 @@ int dma_channel_read(int channel)
dma.cc[channel]--; dma.cc[channel]--;
if (dma.cc[channel] < 0) if (dma.cc[channel] < 0)
{ {
tc = 1;
if (dma.mode[channel] & 0x10) /*Auto-init*/ if (dma.mode[channel] & 0x10) /*Auto-init*/
{ {
dma.cc[channel] = dma.cb[channel]; dma.cc[channel] = dma.cb[channel];
@ -282,7 +284,7 @@ int dma_channel_read(int channel)
dma.stat |= (1 << channel); dma.stat |= (1 << channel);
} }
if (dma.m & (1 << channel)) if (tc)
return temp | DMA_OVER; return temp | DMA_OVER;
return temp; return temp;
} }
@ -302,6 +304,7 @@ int dma_channel_read(int channel)
dma16.cc[channel]--; dma16.cc[channel]--;
if (dma16.cc[channel] < 0) if (dma16.cc[channel] < 0)
{ {
tc = 1;
if (dma16.mode[channel] & 0x10) /*Auto-init*/ if (dma16.mode[channel] & 0x10) /*Auto-init*/
{ {
dma16.cc[channel] = dma16.cb[channel]; dma16.cc[channel] = dma16.cb[channel];
@ -312,7 +315,7 @@ int dma_channel_read(int channel)
dma16.stat |= (1 << channel); dma16.stat |= (1 << channel);
} }
if (dma.m & (1 << channel)) if (tc)
return temp | DMA_OVER; return temp | DMA_OVER;
return temp; return temp;
} }

View file

@ -374,12 +374,17 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
c=0; c=0;
while (c<65536) while (c<65536)
{ {
int dma_result;
d = gus->ram[gus->dmaaddr]; d = gus->ram[gus->dmaaddr];
if (val & 0x80) d ^= 0x80; if (val & 0x80) d ^= 0x80;
if (dma_channel_write(gus->dma, d) == DMA_NODATA) break; dma_result = dma_channel_write(gus->dma, d);
if (dma_result == DMA_NODATA)
break;
gus->dmaaddr++; gus->dmaaddr++;
gus->dmaaddr&=0xFFFFF; gus->dmaaddr&=0xFFFFF;
c++; c++;
if (dma_result & DMA_OVER)
break;
} }
// printf("GUS->MEM Transferred %i bytes\n",c); // printf("GUS->MEM Transferred %i bytes\n",c);
gus->dmactrl=val&~0x40; gus->dmactrl=val&~0x40;
@ -391,12 +396,15 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
while (c<65536) while (c<65536)
{ {
d = dma_channel_read(gus->dma); d = dma_channel_read(gus->dma);
if (d == DMA_NODATA) break; if (d == DMA_NODATA)
break;
if (val&0x80) d^=0x80; if (val&0x80) d^=0x80;
gus->ram[gus->dmaaddr]=d; gus->ram[gus->dmaaddr]=d;
gus->dmaaddr++; gus->dmaaddr++;
gus->dmaaddr&=0xFFFFF; gus->dmaaddr&=0xFFFFF;
c++; c++;
if (d & DMA_OVER)
break;
} }
// printf("MEM->GUS Transferred %i bytes\n",c); // printf("MEM->GUS Transferred %i bytes\n",c);
gus->dmactrl=val&~0x40; gus->dmactrl=val&~0x40;