PSX: add DMA mode used for CD transfers on home system, fix DMA bug that caused home system to freeze. [pSXAuthor, Harmony, R. Belmont]

This commit is contained in:
R. Belmont 2011-02-14 03:39:51 +00:00
parent 8799e8e38f
commit 06d479c54f

View File

@ -434,6 +434,19 @@ WRITE32_HANDLER( psx_dma_w )
(*dma->fn_read)( space->machine, n_address, n_size ); (*dma->fn_read)( space->machine, n_address, n_size );
dma_finished( p_psx, n_channel ); dma_finished( p_psx, n_channel );
} }
else if( dma->n_channelcontrol == 0x11000000 && // CD DMA
dma->fn_read != NULL )
{
verboselog( p_psx, 1, "dma %d read block %08x %08x\n", n_channel, n_address, n_size );
// pSX's CD DMA size calc formula
int oursize = (dma->n_blockcontrol>>16);
oursize = (oursize > 1) ? oursize : 1;
oursize *= (dma->n_blockcontrol&0xffff);
(*dma->fn_read)( space->machine, n_address, oursize );
dma_finished( p_psx, n_channel );
}
else if( dma->n_channelcontrol == 0x01000200 && else if( dma->n_channelcontrol == 0x01000200 &&
dma->fn_read != NULL ) dma->fn_read != NULL )
{ {
@ -501,7 +514,7 @@ WRITE32_HANDLER( psx_dma_w )
} }
else else
{ {
verboselog( p_psx, 0, "dma %d unknown mode %08x\n", n_channel, dma->n_channelcontrol ); verboselog( p_psx, 1, "dma %d unknown mode %08x\n", n_channel, dma->n_channelcontrol );
} }
} }
else if( dma->n_channelcontrol != 0 ) else if( dma->n_channelcontrol != 0 )
@ -523,17 +536,12 @@ WRITE32_HANDLER( psx_dma_w )
p_psx->n_dpcp = ( p_psx->n_dpcp & ~mem_mask ) | data; p_psx->n_dpcp = ( p_psx->n_dpcp & ~mem_mask ) | data;
break; break;
case 0x1: case 0x1:
p_psx->n_dicr = ( p_psx->n_dicr & ~mem_mask ) | if (data & 0x80000000)
( mem_mask & 0x80000000 & p_psx->n_dicr ) |
( ~data & mem_mask & 0x7f000000 & p_psx->n_dicr ) |
( data & mem_mask & 0x00ffffff );
#if 0
/* todo: find out whether to do this instead of dma_interrupt_update() */
if( ( p_psx->n_dicr & 0x7f000000 ) != 0 )
{ {
p_psx->n_dicr &= ~0x80000000; p_psx->n_dicr = ((p_psx->n_dicr &~ data) & 0xff000000) | (p_psx->n_dicr & 0x00ffffff);
} }
#endif p_psx->n_dicr = data & 0x00ffffff;
verboselog( p_psx, 1, "psx_dma_w( %04x, %08x, %08x ) dicr -> %08x\n", offset, data, mem_mask, p_psx->n_dicr ); verboselog( p_psx, 1, "psx_dma_w( %04x, %08x, %08x ) dicr -> %08x\n", offset, data, mem_mask, p_psx->n_dicr );
dma_interrupt_update(p_psx); dma_interrupt_update(p_psx);
break; break;