"You have taken your first step into a larger world." ―Obi-Wan Kenobi

Converted PlayStation DMA to an internal device to the CPU core. DMA to external devices can be set in the machine config, the old calls are still there until the rest of the code is converted. [smf]

The following MAME core changes have been required to allow internal devices to be configurable by the main machine config & to work with internal memory maps.
 device.machine_config_additions() are now processed as soon as the device is added, so sub devices can be configured straight away. 
 replacing or removing a device removes any devices owned by the device being removed, as now they are added straight away.
 device_t::subdevice() uses the machine config device list instead of the machine to find the device as the machine is not created until after all the devices have been created.
 devices in an internal address map are assumed to be owned by the CPU, while devices in a standard address maps are assumed to be siblings of the CPU.


A code review and regression test would be a good idea.
This commit is contained in:
smf- 2011-05-06 23:55:53 +00:00
parent edd7394ca8
commit d1b109625d
19 changed files with 742 additions and 581 deletions

2
.gitattributes vendored
View File

@ -374,6 +374,8 @@ src/emu/cpu/pps4/pps4.h svneol=native#text/plain
src/emu/cpu/pps4/pps4dasm.c svneol=native#text/plain src/emu/cpu/pps4/pps4dasm.c svneol=native#text/plain
src/emu/cpu/psx/dismips.c svneol=native#text/plain src/emu/cpu/psx/dismips.c svneol=native#text/plain
src/emu/cpu/psx/dismips.mak svneol=native#text/plain src/emu/cpu/psx/dismips.mak svneol=native#text/plain
src/emu/cpu/psx/dma.c svneol=native#text/plain
src/emu/cpu/psx/dma.h svneol=native#text/plain
src/emu/cpu/psx/gte.c svneol=native#text/plain src/emu/cpu/psx/gte.c svneol=native#text/plain
src/emu/cpu/psx/gte.h svneol=native#text/plain src/emu/cpu/psx/gte.h svneol=native#text/plain
src/emu/cpu/psx/psx.c svneol=native#text/plain src/emu/cpu/psx/psx.c svneol=native#text/plain

View File

@ -60,7 +60,7 @@ inline void map_handler_data::set_tag(const device_t &device, const char *tag)
m_tag = device.owner()->tag(); m_tag = device.owner()->tag();
} }
else else
m_tag = device.siblingtag(m_derived_tag, tag); m_tag = device.subtag(m_derived_tag, tag);
} }
@ -718,7 +718,7 @@ address_map::address_map(const device_t &device, address_spacenum spacenum)
// construct the standard map */ // construct the standard map */
if (memintf->address_map(spacenum) != NULL) if (memintf->address_map(spacenum) != NULL)
(*memintf->address_map(spacenum))(*this, device); (*memintf->address_map(spacenum))(*this, *device.owner());
// append the default device map (last so it can be overridden) */ // append the default device map (last so it can be overridden) */
if (spaceconfig->m_default_map != NULL) if (spaceconfig->m_default_map != NULL)

View File

@ -885,17 +885,20 @@ $(CPUOBJ)/mips/mips3drc.o: $(CPUSRC)/mips/mips3drc.c \
ifneq ($(filter PSX,$(CPUS)),) ifneq ($(filter PSX,$(CPUS)),)
OBJDIRS += $(CPUOBJ)/psx OBJDIRS += $(CPUOBJ)/psx
CPUOBJS += $(CPUOBJ)/psx/psx.o $(CPUOBJ)/psx/gte.o CPUOBJS += $(CPUOBJ)/psx/psx.o $(CPUOBJ)/psx/gte.o $(CPUOBJ)/psx/dma.o
DASMOBJS += $(CPUOBJ)/psx/psxdasm.o DASMOBJS += $(CPUOBJ)/psx/psxdasm.o
endif endif
$(CPUOBJ)/psx/psx.o: $(CPUSRC)/psx/psx.c \ $(CPUOBJ)/psx/psx.o: $(CPUSRC)/psx/psx.c \
$(CPUSRC)/psx/psx.h \ $(CPUSRC)/psx/psx.h \
$(CPUSRC)/psx/dma.h \
$(CPUSRC)/psx/gte.h \ $(CPUSRC)/psx/gte.h \
$(CPUOBJ)/psx/gte.o: $(CPUSRC)/psx/gte.c \ $(CPUOBJ)/psx/gte.o: $(CPUSRC)/psx/gte.c \
$(CPUSRC)/psx/gte.h $(CPUSRC)/psx/gte.h
$(CPUOBJ)/psx/dma.o: $(CPUSRC)/psx/dma.c \
$(CPUSRC)/psx/dma.h
#------------------------------------------------- #-------------------------------------------------
# Mitsubishi M37702 and M37710 (based on 65C816) # Mitsubishi M37702 and M37710 (based on 65C816)

428
src/emu/cpu/psx/dma.c Normal file
View File

@ -0,0 +1,428 @@
/*
* PlayStation DMA emulator
*
* Copyright 2003-2011 smf
*
*/
#include "emu.h"
#include "dma.h"
#include "includes/psx.h"
#define VERBOSE_LEVEL ( 0 )
INLINE void ATTR_PRINTF(3,4) verboselog( running_machine& machine, int n_level, const char *s_fmt, ... )
{
if( VERBOSE_LEVEL >= n_level )
{
va_list v;
char buf[ 32768 ];
va_start( v, s_fmt );
vsprintf( buf, s_fmt, v );
va_end( v );
logerror( "%s: %s", machine.describe_context(), buf );
}
}
const device_type PSX_DMA = &device_creator<psxdma_device>;
psxdma_device::psxdma_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, PSX_DMA, "PSX DMA", tag, owner, clock)
{
for( int index = 0; index < 7; index++ )
{
psx_dma_channel *dma = &channel[ index ];
dma->fn_read = NULL;
dma->fn_write = NULL;
}
}
void psxdma_device::device_reset()
{
int n;
n_dpcp = 0;
n_dicr = 0;
for( n = 0; n < 7; n++ )
{
dma_stop_timer( n );
}
}
void psxdma_device::device_post_load()
{
int n;
for( n = 0; n < 7; n++ )
{
dma_timer_adjust( n );
}
}
void psxdma_device::device_start()
{
for( int index = 0; index < 7; index++ )
{
psx_dma_channel *dma = &channel[ index ];
dma->timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(psxdma_device::dma_finished_callback), this));
machine().save().save_item( "psxdma", tag(), index, NAME(dma->n_base) );
machine().save().save_item( "psxdma", tag(), index, NAME(dma->n_blockcontrol) );
machine().save().save_item( "psxdma", tag(), index, NAME(dma->n_channelcontrol) );
machine().save().save_item( "psxdma", tag(), index, NAME(dma->n_ticks) );
machine().save().save_item( "psxdma", tag(), index, NAME(dma->b_running) );
}
save_item( NAME(n_dpcp) );
save_item( NAME(n_dicr) );
}
void psxdma_device::dma_start_timer( int index, UINT32 n_ticks )
{
psx_dma_channel *dma = &channel[ index ];
dma->timer->adjust( attotime::from_hz(33868800) * n_ticks, index);
dma->n_ticks = n_ticks;
dma->b_running = 1;
}
void psxdma_device::dma_stop_timer( int index )
{
psx_dma_channel *dma = &channel[ index ];
dma->timer->adjust( attotime::never);
dma->b_running = 0;
}
void psxdma_device::dma_timer_adjust( int index )
{
psx_dma_channel *dma = &channel[ index ];
if( dma->b_running )
{
dma_start_timer( index, dma->n_ticks );
}
else
{
dma_stop_timer( index );
}
}
void psxdma_device::dma_interrupt_update()
{
int n_int;
int n_mask;
n_int = ( n_dicr >> 24 ) & 0x7f;
n_mask = ( n_dicr >> 16 ) & 0xff;
if( ( n_mask & 0x80 ) != 0 && ( n_int & n_mask ) != 0 )
{
verboselog( machine(), 2, "dma_interrupt_update( %02x, %02x ) interrupt triggered\n", n_int, n_mask );
n_dicr |= 0x80000000;
psx_irq_set( machine(), PSX_IRQ_DMA );
}
else if( n_int != 0 )
{
verboselog( machine(), 2, "dma_interrupt_update( %02x, %02x ) interrupt not enabled\n", n_int, n_mask );
}
n_dicr &= 0x00ffffff | ( n_dicr << 8 );
}
void psxdma_device::dma_finished( int index )
{
psx_machine *p_psx = machine().driver_data<psx_state>()->m_p_psx;
UINT32 *p_n_psxram = p_psx->p_n_psxram;
psx_dma_channel *dma = &channel[ index ];
if( dma->n_channelcontrol == 0x01000401 && index == 2 )
{
UINT32 n_size;
UINT32 n_total;
UINT32 n_address = ( dma->n_base & 0xffffff );
UINT32 n_adrmask = p_psx->n_psxramsize - 1;
UINT32 n_nextaddress;
if( n_address != 0xffffff )
{
n_total = 0;
for( ;; )
{
if( n_address == 0xffffff )
{
dma->n_base = n_address;
dma_start_timer( index, 19000 );
return;
}
if( n_total > 65535 )
{
dma->n_base = n_address;
//FIXME:
// 16000 below is based on try and error.
// Mametesters.org: sfex20103red
//dma_start_timer( index, 16 );
dma_start_timer( index, 16000 );
return;
}
n_address &= n_adrmask;
n_nextaddress = p_n_psxram[ n_address / 4 ];
n_size = n_nextaddress >> 24;
(*dma->fn_write)( machine(), n_address + 4, n_size );
//FIXME:
// The following conditions will cause an endless loop.
// If stopping the transfer is correct I cannot judge
// The patch is meant as a hint for somebody who knows
// the hardware.
// Mametesters.org: psyforce0105u5red, raystorm0111u1red
if ((n_nextaddress & 0xffffff) != 0xffffff)
if (n_address == p_n_psxram[ (n_nextaddress & 0xffffff) / 4])
break;
if (n_address == (n_nextaddress & 0xffffff) )
break;
n_address = ( n_nextaddress & 0xffffff );
n_total += ( n_size + 1 );
}
}
}
dma->n_channelcontrol &= ~( ( 1L << 0x18 ) | ( 1L << 0x1c ) );
n_dicr |= 1 << ( 24 + index );
dma_interrupt_update();
dma_stop_timer( index );
}
void psxdma_device::dma_finished_callback(void *ptr, int param)
{
dma_finished(param);
}
void psxdma_device::install_read_handler( int index, psx_dma_read_handler p_fn_dma_read )
{
channel[ index ].fn_read = p_fn_dma_read;
}
void psxdma_device::install_write_handler( int index, psx_dma_read_handler p_fn_dma_write )
{
channel[ index ].fn_write = p_fn_dma_write;
}
WRITE32_MEMBER( psxdma_device::write )
{
psx_machine *p_psx = machine().driver_data<psx_state>()->m_p_psx;
UINT32 *p_n_psxram = p_psx->p_n_psxram;
int index = offset / 4;
psx_dma_channel *dma = &channel[ index ];
if( index < 7 )
{
switch( offset % 4 )
{
case 0:
verboselog( machine(), 2, "dmabase( %d ) = %08x\n", index, data );
dma->n_base = data;
break;
case 1:
verboselog( machine(), 2, "dmablockcontrol( %d ) = %08x\n", index, data );
dma->n_blockcontrol = data;
break;
case 2:
verboselog( machine(), 2, "dmachannelcontrol( %d ) = %08x\n", index, data );
dma->n_channelcontrol = data;
if( ( dma->n_channelcontrol & ( 1L << 0x18 ) ) != 0 && ( n_dpcp & ( 1 << ( 3 + ( index * 4 ) ) ) ) != 0 )
{
INT32 n_size;
UINT32 n_address;
UINT32 n_nextaddress;
UINT32 n_adrmask;
n_adrmask = p_psx->n_psxramsize - 1;
n_address = ( dma->n_base & n_adrmask );
n_size = dma->n_blockcontrol;
if( ( dma->n_channelcontrol & 0x200 ) != 0 )
{
UINT32 n_ba;
n_ba = dma->n_blockcontrol >> 16;
if( n_ba == 0 )
{
n_ba = 0x10000;
}
n_size = ( n_size & 0xffff ) * n_ba;
}
if( dma->n_channelcontrol == 0x01000000 &&
dma->fn_read != NULL )
{
verboselog( machine(), 1, "dma %d read block %08x %08x\n", index, n_address, n_size );
(*dma->fn_read)( machine(), n_address, n_size );
dma_finished( index );
}
else if (dma->n_channelcontrol == 0x11000000 && // CD DMA
dma->fn_read != NULL )
{
verboselog( machine(), 1, "dma %d read block %08x %08x\n", index, 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)( machine(), n_address, oursize );
dma_finished( index );
}
else if( dma->n_channelcontrol == 0x01000200 &&
dma->fn_read != NULL )
{
verboselog( machine(), 1, "dma %d read block %08x %08x\n", index, n_address, n_size );
(*dma->fn_read)( machine(), n_address, n_size );
if( index == 1 )
{
dma_start_timer( index, 26000 );
}
else
{
dma_finished( index );
}
}
else if( dma->n_channelcontrol == 0x01000201 &&
dma->fn_write != NULL )
{
verboselog( machine(), 1, "dma %d write block %08x %08x\n", index, n_address, n_size );
(*dma->fn_write)( machine(), n_address, n_size );
dma_finished( index );
}
else if( dma->n_channelcontrol == 0x11050100 &&
dma->fn_write != NULL )
{
/* todo: check this is a write not a read... */
verboselog( machine(), 1, "dma %d write block %08x %08x\n", index, n_address, n_size );
(*dma->fn_write)( machine(), n_address, n_size );
dma_finished( index );
}
else if( dma->n_channelcontrol == 0x11150100 &&
dma->fn_write != NULL )
{
/* todo: check this is a write not a read... */
verboselog( machine(), 1, "dma %d write block %08x %08x\n", index, n_address, n_size );
(*dma->fn_write)( machine(), n_address, n_size );
dma_finished( index );
}
else if( dma->n_channelcontrol == 0x01000401 &&
index == 2 &&
dma->fn_write != NULL )
{
verboselog( machine(), 1, "dma %d write linked list %08x\n",
index, dma->n_base );
dma_finished( index );
}
else if( dma->n_channelcontrol == 0x11000002 &&
index == 6 )
{
verboselog( machine(), 1, "dma 6 reverse clear %08x %08x\n",
dma->n_base, dma->n_blockcontrol );
if( n_size > 0 )
{
n_size--;
while( n_size > 0 )
{
n_nextaddress = ( n_address - 4 ) & 0xffffff;
p_n_psxram[ n_address / 4 ] = n_nextaddress;
n_address = n_nextaddress;
n_size--;
}
p_n_psxram[ n_address / 4 ] = 0xffffff;
}
dma_start_timer( index, 2150 );
}
else
{
verboselog( machine(), 1, "dma %d unknown mode %08x\n", index, dma->n_channelcontrol );
}
}
else if( dma->n_channelcontrol != 0 )
{
verboselog( machine(), 1, "psx_dma_w( %04x, %08x, %08x ) channel not enabled\n", offset, dma->n_channelcontrol, mem_mask );
}
break;
default:
verboselog( machine(), 1, "psx_dma_w( %04x, %08x, %08x ) Unknown dma channel register\n", offset, data, mem_mask );
break;
}
}
else
{
switch( offset % 4 )
{
case 0x0:
verboselog( machine(), 1, "psx_dma_w( %04x, %08x, %08x ) dpcp\n", offset, data, mem_mask );
n_dpcp = ( n_dpcp & ~mem_mask ) | data;
break;
case 0x1:
n_dicr = ( n_dicr & ( 0x80000000 | ~mem_mask ) ) |
( n_dicr & ~data & 0x7f000000 & mem_mask ) |
( data & 0x00ffffff & mem_mask );
if( ( n_dicr & 0x80000000 ) != 0 && ( n_dicr & 0x7f000000 ) == 0 )
{
verboselog( machine(), 2, "dma interrupt cleared\n" );
n_dicr &= ~0x80000000;
}
verboselog( machine(), 1, "psx_dma_w( %04x, %08x, %08x ) dicr -> %08x\n", offset, data, mem_mask, n_dicr );
break;
default:
verboselog( machine(), 0, "psx_dma_w( %04x, %08x, %08x ) Unknown dma control register\n", offset, data, mem_mask );
break;
}
}
}
READ32_MEMBER( psxdma_device::read )
{
int index = offset / 4;
psx_dma_channel *dma = &channel[ index ];
if( index < 7 )
{
switch( offset % 4 )
{
case 0:
verboselog( machine(), 1, "psx_dma_r dmabase[ %d ] ( %08x )\n", index, dma->n_base );
return dma->n_base;
case 1:
verboselog( machine(), 1, "psx_dma_r dmablockcontrol[ %d ] ( %08x )\n", index, dma->n_blockcontrol );
return dma->n_blockcontrol;
case 2:
verboselog( machine(), 1, "psx_dma_r dmachannelcontrol[ %d ] ( %08x )\n", index, dma->n_channelcontrol );
return dma->n_channelcontrol;
default:
verboselog( machine(), 0, "psx_dma_r( %08x, %08x ) Unknown dma channel register\n", offset, mem_mask );
break;
}
}
else
{
switch( offset % 4 )
{
case 0x0:
verboselog( machine(), 1, "psx_dma_r dpcp ( %08x )\n", n_dpcp );
return n_dpcp;
case 0x1:
verboselog( machine(), 1, "psx_dma_r dicr ( %08x )\n", n_dicr );
return n_dicr;
default:
verboselog( machine(), 0, "psx_dma_r( %08x, %08x ) Unknown dma control register\n", offset, mem_mask );
break;
}
}
return 0;
}

63
src/emu/cpu/psx/dma.h Normal file
View File

@ -0,0 +1,63 @@
/*
* PlayStation DMA emulator
*
* Copyright 2003-2011 smf
*
*/
#if !defined(PSXDMA_H)
#define PSXDMA_H (1)
#include "emu.h"
extern const device_type PSX_DMA;
typedef void ( *psx_dma_read_handler )( running_machine &, UINT32, INT32 );
typedef void ( *psx_dma_write_handler )( running_machine &, UINT32, INT32 );
typedef struct _psx_dma_channel psx_dma_channel;
struct _psx_dma_channel
{
UINT32 n_base;
UINT32 n_blockcontrol;
UINT32 n_channelcontrol;
emu_timer *timer;
psx_dma_read_handler fn_read;
psx_dma_write_handler fn_write;
UINT32 n_ticks;
UINT32 b_running;
};
class psxdma_device : public device_t
{
public:
psxdma_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
void install_read_handler( int n_channel, psx_dma_read_handler p_fn_dma_read );
void install_write_handler( int n_channel, psx_dma_read_handler p_fn_dma_write );
WRITE32_MEMBER( write );
READ32_MEMBER( read );
protected:
virtual void device_start();
virtual void device_reset();
virtual void device_post_load();
private:
void dma_start_timer( int n_channel, UINT32 n_ticks );
void dma_stop_timer( int n_channel );
void dma_timer_adjust( int n_channel );
void dma_interrupt_update();
void dma_finished( int n_channel );
void dma_finished_callback(void *ptr, int param);
void write( offs_t offset, UINT32 data, UINT32 mem_mask );
UINT32 read( offs_t offset, UINT32 mem_mask );
psx_dma_channel channel[7];
UINT32 n_dpcp;
UINT32 n_dicr;
};
#endif

View File

@ -1,5 +1,5 @@
/* /*
* Geometry Transformation Engine * PlayStation Geometry Transformation Engine emulator
* *
* Copyright 2003-2011 smf * Copyright 2003-2011 smf
* *

View File

@ -1,5 +1,5 @@
/* /*
* Geometry Transformation Engine * PlayStation Geometry Transformation Engine emulator
* *
* Copyright 2003-2011 smf * Copyright 2003-2011 smf
* *
@ -9,10 +9,10 @@
#pragma once #pragma once
#include "emu.h" #ifndef __PSXGTE_H__
#define __PSXGTE_H__
#ifndef __GTE_H__ #include "emu.h"
#define __GTE_H__
#define GTE_OP( op ) ( ( op >> 20 ) & 31 ) #define GTE_OP( op ) ( ( op >> 20 ) & 31 )
#define GTE_SF( op ) ( ( op >> 19 ) & 1 ) #define GTE_SF( op ) ( ( op >> 19 ) & 1 )

View File

@ -1,7 +1,7 @@
/* /*
* PlayStation CPU emulator by smf * PlayStation CPU emulator
* *
* Licensed to the MAME Team for distribution under the MAME license. * Copyright 2003-2011 smf
* *
* Known chip id's * Known chip id's
* CXD8530AQ * CXD8530AQ
@ -64,6 +64,7 @@
#include "emu.h" #include "emu.h"
#include "debugger.h" #include "debugger.h"
#include "psx.h" #include "psx.h"
#include "dma.h"
#include "includes/psx.h" #include "includes/psx.h"
#include "sound/spu.h" #include "sound/spu.h"
@ -186,33 +187,23 @@ static const UINT32 mtc0_writemask[]=
0x00000000 /* PRID */ 0x00000000 /* PRID */
}; };
static READ32_DEVICE_HANDLER( psx_berr_r ) READ32_MEMBER( psxcpu_device::berr_r )
{ {
downcast<psxcpu_device *>(device)->set_berr(); m_berr = 1;
return 0; return 0;
} }
static WRITE32_DEVICE_HANDLER( psx_berr_w ) WRITE32_MEMBER( psxcpu_device::berr_w )
{ {
downcast<psxcpu_device *>(device)->set_berr(); m_berr = 1;
} }
static READ32_DEVICE_HANDLER( psx_biu_r ) READ32_MEMBER( psxcpu_device::biu_r )
{
return downcast<psxcpu_device *>(device)->get_biu();
}
static WRITE32_DEVICE_HANDLER( psx_biu_w )
{
downcast<psxcpu_device *>(device)->set_biu( data, mem_mask );
}
UINT32 psxcpu_device::get_biu()
{ {
return m_biu; return m_biu;
} }
void psxcpu_device::set_biu( UINT32 data, UINT32 mem_mask ) WRITE32_MEMBER( psxcpu_device::biu_w )
{ {
UINT32 old = m_biu; UINT32 old = m_biu;
@ -1244,20 +1235,15 @@ void psxcpu_device::update_address_masks()
} }
} }
void psxcpu_device::set_berr()
{
m_berr = 1;
}
void psxcpu_device::update_scratchpad() void psxcpu_device::update_scratchpad()
{ {
if( ( m_biu & BIU_RAM ) == 0 ) if( ( m_biu & BIU_RAM ) == 0 )
{ {
m_program->install_legacy_readwrite_handler( *this, 0x1f800000, 0x1f8003ff, FUNC(psx_berr_r), FUNC(psx_berr_w) ); m_program->install_readwrite_handler( 0x1f800000, 0x1f8003ff, read32_delegate( FUNC(psxcpu_device::berr_r), this ), write32_delegate( FUNC(psxcpu_device::berr_w), this ) );
} }
else if( ( m_biu & BIU_DS ) == 0 ) else if( ( m_biu & BIU_DS ) == 0 )
{ {
m_program->install_legacy_read_handler( *this, 0x1f800000, 0x1f8003ff, FUNC(psx_berr_r) ); m_program->install_read_handler( 0x1f800000, 0x1f8003ff, read32_delegate( FUNC(psxcpu_device::berr_r), this ) );
m_program->nop_write( 0x1f800000, 0x1f8003ff); m_program->nop_write( 0x1f800000, 0x1f8003ff);
} }
else else
@ -1534,50 +1520,50 @@ int psxcpu_device::store_data_address_breakpoint( UINT32 address )
// On-board RAM and peripherals // On-board RAM and peripherals
static ADDRESS_MAP_START( psxcpu_internal_map, AS_PROGRAM, 32 ) static ADDRESS_MAP_START( psxcpu_internal_map, AS_PROGRAM, 32 )
AM_RANGE(0x00800000, 0x1effffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x00800000, 0x1effffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0x1f800000, 0x1f8003ff) AM_NOP /* scratchpad */ AM_RANGE(0x1f800000, 0x1f8003ff) AM_NOP /* scratchpad */
AM_RANGE(0x1f800400, 0x1f800fff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x1f800400, 0x1f800fff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0x1f801004, 0x1f80101f) AM_RAM AM_RANGE(0x1f801004, 0x1f80101f) AM_RAM
AM_RANGE(0x1f801020, 0x1f801023) AM_READWRITE(psx_com_delay_r, psx_com_delay_w) AM_RANGE(0x1f801020, 0x1f801023) AM_READWRITE(psx_com_delay_r, psx_com_delay_w)
AM_RANGE(0x1f801024, 0x1f80102f) AM_RAM AM_RANGE(0x1f801024, 0x1f80102f) AM_RAM
AM_RANGE(0x1f801040, 0x1f80105f) AM_READWRITE(psx_sio_r, psx_sio_w) AM_RANGE(0x1f801040, 0x1f80105f) AM_READWRITE(psx_sio_r, psx_sio_w)
AM_RANGE(0x1f801060, 0x1f80106f) AM_RAM AM_RANGE(0x1f801060, 0x1f80106f) AM_RAM
AM_RANGE(0x1f801070, 0x1f801077) AM_READWRITE(psx_irq_r, psx_irq_w) AM_RANGE(0x1f801070, 0x1f801077) AM_READWRITE(psx_irq_r, psx_irq_w)
AM_RANGE(0x1f801080, 0x1f8010ff) AM_READWRITE(psx_dma_r, psx_dma_w) AM_RANGE(0x1f801080, 0x1f8010ff) AM_DEVREADWRITE_MODERN("dma", psxdma_device, read, write)
AM_RANGE(0x1f801100, 0x1f80112f) AM_READWRITE(psx_counter_r, psx_counter_w) AM_RANGE(0x1f801100, 0x1f80112f) AM_READWRITE(psx_counter_r, psx_counter_w)
AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE(psx_gpu_r, psx_gpu_w) AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE(psx_gpu_r, psx_gpu_w)
AM_RANGE(0x1f801820, 0x1f801827) AM_READWRITE(psx_mdec_r, psx_mdec_w) AM_RANGE(0x1f801820, 0x1f801827) AM_READWRITE(psx_mdec_r, psx_mdec_w)
AM_RANGE(0x1f801c00, 0x1f801dff) AM_READWRITE16(spu_r, spu_w, 0xffffffff) AM_RANGE(0x1f801c00, 0x1f801dff) AM_READWRITE16(spu_r, spu_w, 0xffffffff)
AM_RANGE(0x1f802020, 0x1f802033) AM_RAM /* ?? */ AM_RANGE(0x1f802020, 0x1f802033) AM_RAM /* ?? */
AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP
AM_RANGE(0x20000000, 0x7fffffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x20000000, 0x7fffffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0x80800000, 0x9effffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x80800000, 0x9effffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0xa0800000, 0xbeffffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0xa0800000, 0xbeffffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0xc0000000, 0xfffdffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0xc0000000, 0xfffdffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0xfffe0130, 0xfffe0133) AM_DEVREADWRITE(DEVICE_SELF,psx_biu_r, psx_biu_w) AM_RANGE(0xfffe0130, 0xfffe0133) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, biu_r, biu_w)
ADDRESS_MAP_END ADDRESS_MAP_END
static ADDRESS_MAP_START( cxd8661r_internal_map, AS_PROGRAM, 32 ) static ADDRESS_MAP_START( cxd8661r_internal_map, AS_PROGRAM, 32 )
AM_RANGE(0x01000000, 0x1effffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x01000000, 0x1effffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0x1f800000, 0x1f8003ff) AM_NOP /* scratchpad */ AM_RANGE(0x1f800000, 0x1f8003ff) AM_NOP /* scratchpad */
AM_RANGE(0x1f800400, 0x1f800fff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x1f800400, 0x1f800fff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0x1f801004, 0x1f80101f) AM_RAM AM_RANGE(0x1f801004, 0x1f80101f) AM_RAM
AM_RANGE(0x1f801020, 0x1f801023) AM_READWRITE(psx_com_delay_r, psx_com_delay_w) AM_RANGE(0x1f801020, 0x1f801023) AM_READWRITE(psx_com_delay_r, psx_com_delay_w)
AM_RANGE(0x1f801024, 0x1f80102f) AM_RAM AM_RANGE(0x1f801024, 0x1f80102f) AM_RAM
AM_RANGE(0x1f801040, 0x1f80105f) AM_READWRITE(psx_sio_r, psx_sio_w) AM_RANGE(0x1f801040, 0x1f80105f) AM_READWRITE(psx_sio_r, psx_sio_w)
AM_RANGE(0x1f801060, 0x1f80106f) AM_RAM AM_RANGE(0x1f801060, 0x1f80106f) AM_RAM
AM_RANGE(0x1f801070, 0x1f801077) AM_READWRITE(psx_irq_r, psx_irq_w) AM_RANGE(0x1f801070, 0x1f801077) AM_READWRITE(psx_irq_r, psx_irq_w)
AM_RANGE(0x1f801080, 0x1f8010ff) AM_READWRITE(psx_dma_r, psx_dma_w) AM_RANGE(0x1f801080, 0x1f8010ff) AM_DEVREADWRITE_MODERN("dma", psxdma_device, read, write)
AM_RANGE(0x1f801100, 0x1f80112f) AM_READWRITE(psx_counter_r, psx_counter_w) AM_RANGE(0x1f801100, 0x1f80112f) AM_READWRITE(psx_counter_r, psx_counter_w)
AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE(psx_gpu_r, psx_gpu_w) AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE(psx_gpu_r, psx_gpu_w)
AM_RANGE(0x1f801820, 0x1f801827) AM_READWRITE(psx_mdec_r, psx_mdec_w) AM_RANGE(0x1f801820, 0x1f801827) AM_READWRITE(psx_mdec_r, psx_mdec_w)
AM_RANGE(0x1f801c00, 0x1f801dff) AM_READWRITE16(spu_r, spu_w, 0xffffffff) AM_RANGE(0x1f801c00, 0x1f801dff) AM_READWRITE16(spu_r, spu_w, 0xffffffff)
AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP
AM_RANGE(0x20000000, 0x7fffffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x20000000, 0x7fffffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0x81000000, 0x9effffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0x81000000, 0x9effffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0xa1000000, 0xbeffffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0xa1000000, 0xbeffffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0xc0000000, 0xfffdffff) AM_DEVREADWRITE(DEVICE_SELF,psx_berr_r, psx_berr_w) AM_RANGE(0xc0000000, 0xfffdffff) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, berr_r, berr_w)
AM_RANGE(0xfffe0130, 0xfffe0133) AM_DEVREADWRITE(DEVICE_SELF,psx_biu_r, psx_biu_w) AM_RANGE(0xfffe0130, 0xfffe0133) AM_DEVREADWRITE_MODERN(DEVICE_SELF, psxcpu_device, biu_r, biu_w)
ADDRESS_MAP_END ADDRESS_MAP_END
@ -3157,3 +3143,27 @@ UINT32 psxcpu_device::getcp3cr( int reg )
void psxcpu_device::setcp3cr( int reg, UINT32 value ) void psxcpu_device::setcp3cr( int reg, UINT32 value )
{ {
} }
void psxcpu_device::install_dma_read_handler( device_t &device, int channel, psx_dma_read_handler handler )
{
(downcast<psxdma_device*>(device.subdevice("dma")))->install_read_handler( channel, handler );
}
void psxcpu_device::install_dma_write_handler( device_t &device, int channel, psx_dma_write_handler handler )
{
(downcast<psxdma_device*>(device.subdevice("dma")))->install_write_handler( channel, handler );
}
static MACHINE_CONFIG_FRAGMENT( psx )
MCFG_DEVICE_ADD("dma", PSX_DMA, 0)
MACHINE_CONFIG_END
//-------------------------------------------------
// machine_config_additions - return a pointer to
// the device's machine fragment
//-------------------------------------------------
machine_config_constructor psxcpu_device::device_mconfig_additions() const
{
return MACHINE_CONFIG_NAME( psx );
}

View File

@ -1,17 +1,18 @@
/*************************************************************************** /*
* PlayStation CPU emulator
psx.h *
* Copyright 2003-2011 smf
Sony PlayStation CPU emulator. *
*/
***************************************************************************/
#pragma once #pragma once
#ifndef __PSXCPU_H__ #ifndef __PSXCPU_H__
#define __PSXCPU_H__ #define __PSXCPU_H__
#include "includes/psx.h"
#include "gte.h" #include "gte.h"
#include "dma.h"
//************************************************************************** //**************************************************************************
// CONSTANTS // CONSTANTS
@ -102,8 +103,11 @@ enum
// INTERFACE CONFIGURATION MACROS // INTERFACE CONFIGURATION MACROS
//************************************************************************** //**************************************************************************
//#define MCFG_PSXCPU_CONFIG(_config) #define MCFG_PSX_DMA_CHANNEL_READ( channel, handler ) \
// psxcpu_device::static_set_config(*device, _config); psxcpu_device::install_dma_read_handler( *device, channel, handler ); \
#define MCFG_PSX_DMA_CHANNEL_WRITE( channel, handler ) \
psxcpu_device::install_dma_write_handler( *device, channel, handler ); \
@ -120,9 +124,13 @@ public:
psxcpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); psxcpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
// public interfaces // public interfaces
void set_berr(); WRITE32_MEMBER( biu_w );
void set_biu( UINT32 data, UINT32 mem_mask ); READ32_MEMBER( biu_r );
UINT32 get_biu(); WRITE32_MEMBER( berr_w );
READ32_MEMBER( berr_r );
static void install_dma_read_handler( device_t &device, int channel, psx_dma_read_handler handler );
static void install_dma_write_handler( device_t &device, int channel, psx_dma_write_handler handler );
protected: protected:
psxcpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, address_map_constructor internal_map); psxcpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, address_map_constructor internal_map);
@ -131,6 +139,7 @@ protected:
virtual void device_start(); virtual void device_start();
virtual void device_reset(); virtual void device_reset();
virtual void device_post_load(); virtual void device_post_load();
machine_config_constructor device_mconfig_additions() const;
// device_execute_interface overrides // device_execute_interface overrides
virtual UINT32 execute_min_cycles() const { return 1; } virtual UINT32 execute_min_cycles() const { return 1; }

View File

@ -435,7 +435,7 @@ device_t *device_t::subdevice(const char *_tag) const
// build a fully-qualified name // build a fully-qualified name
astring tempstring; astring tempstring;
return machine().device(subtag(tempstring, _tag)); return mconfig().devicelist().find((const char *)subtag(tempstring, _tag));
} }

View File

@ -88,15 +88,6 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
throw emu_fatalerror("Machine configuration missing driver_device"); throw emu_fatalerror("Machine configuration missing driver_device");
driver_device::static_set_game(*root, gamedrv); driver_device::static_set_game(*root, gamedrv);
// process any device-specific machine configurations
for (device_t *device = m_devicelist.first(); device != NULL; device = device->next())
if (!device->configured())
{
machine_config_constructor additions = device->machine_config_additions();
if (additions != NULL)
(*additions)(*this, device);
}
// then notify all devices that their configuration is complete // then notify all devices that their configuration is complete
for (device_t *device = m_devicelist.first(); device != NULL; device = device->next()) for (device_t *device = m_devicelist.first(); device != NULL; device = device->next())
if (!device->configured()) if (!device->configured())
@ -124,6 +115,43 @@ screen_device *machine_config::first_screen() const
} }
//-------------------------------------------------
// device_add_subdevices - helper to add
// devices owned by the device
//-------------------------------------------------
void machine_config::device_add_subdevices(device_t *device)
{
machine_config_constructor additions = device->machine_config_additions();
if (additions != NULL)
(*additions)(*this, device);
}
//-------------------------------------------------
// device_remove_subdevices - helper to remove
// devices owned by the device
//-------------------------------------------------
void machine_config::device_remove_subdevices(const device_t *device)
{
if (device != NULL)
{
device_t *sub_device = m_devicelist.first();
while (sub_device != NULL)
{
device_t *next_device = sub_device->next();
if (sub_device->owner() == device)
{
device_remove_subdevices(sub_device);
m_devicelist.remove(sub_device->tag());
}
sub_device = next_device;
}
}
}
//------------------------------------------------- //-------------------------------------------------
// device_add - configuration helper to add a // device_add - configuration helper to add a
// new device // new device
@ -133,7 +161,9 @@ device_t *machine_config::device_add(device_t *owner, const char *tag, device_ty
{ {
astring tempstring; astring tempstring;
const char *fulltag = owner->subtag(tempstring, tag); const char *fulltag = owner->subtag(tempstring, tag);
return &m_devicelist.append(fulltag, *(*type)(*this, fulltag, owner, clock)); device_t *device = &m_devicelist.append(fulltag, *(*type)(*this, fulltag, owner, clock));
device_add_subdevices(device);
return device;
} }
@ -146,7 +176,10 @@ device_t *machine_config::device_replace(device_t *owner, const char *tag, devic
{ {
astring tempstring; astring tempstring;
const char *fulltag = owner->subtag(tempstring, tag); const char *fulltag = owner->subtag(tempstring, tag);
return &m_devicelist.replace_and_remove(fulltag, *(*type)(*this, fulltag, owner, clock)); device_remove_subdevices(m_devicelist.find(fulltag));
device_t *device = &m_devicelist.replace_and_remove(fulltag, *(*type)(*this, fulltag, owner, clock));
device_add_subdevices(device);
return device;
} }
@ -159,6 +192,7 @@ device_t *machine_config::device_remove(device_t *owner, const char *tag)
{ {
astring tempstring; astring tempstring;
const char *fulltag = owner->subtag(tempstring, tag); const char *fulltag = owner->subtag(tempstring, tag);
device_remove_subdevices(m_devicelist.find(fulltag));
m_devicelist.remove(fulltag); m_devicelist.remove(fulltag);
return NULL; return NULL;
} }

View File

@ -157,6 +157,9 @@ public:
device_t *device_find(device_t *owner, const char *tag); device_t *device_find(device_t *owner, const char *tag);
private: private:
void device_add_subdevices(device_t *device);
void device_remove_subdevices(const device_t *device);
const game_driver & m_gamedrv; const game_driver & m_gamedrv;
emu_options & m_options; emu_options & m_options;
device_list m_devicelist; // list of device configs device_list m_devicelist; // list of device configs

View File

@ -350,8 +350,6 @@ static MACHINE_START( konamigq )
/* init the scsi controller and hook up it's DMA */ /* init the scsi controller and hook up it's DMA */
am53cf96_init(machine, &scsi_intf); am53cf96_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(konamigq_exit), &machine)); machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(konamigq_exit), &machine));
psx_dma_install_read_handler(machine, 5, scsi_dma_read);
psx_dma_install_write_handler(machine, 5, scsi_dma_write);
state->save_pointer(NAME(state->m_p_n_pcmram), 0x380000); state->save_pointer(NAME(state->m_p_n_pcmram), 0x380000);
state->save_item(NAME(state->m_sndto000)); state->save_item(NAME(state->m_sndto000));
@ -367,7 +365,9 @@ static MACHINE_RESET( konamigq )
static MACHINE_CONFIG_START( konamigq, konamigq_state ) static MACHINE_CONFIG_START( konamigq, konamigq_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD( "maincpu", CXD8530BQ, XTAL_67_7376MHz ) MCFG_CPU_ADD( "maincpu", CXD8530BQ, XTAL_67_7376MHz )
MCFG_CPU_PROGRAM_MAP( konamigq_map) MCFG_PSX_DMA_CHANNEL_READ( 5, scsi_dma_read )
MCFG_PSX_DMA_CHANNEL_WRITE( 5, scsi_dma_write )
MCFG_CPU_PROGRAM_MAP( konamigq_map )
MCFG_CPU_VBLANK_INT("screen", psx_vblank) MCFG_CPU_VBLANK_INT("screen", psx_vblank)
MCFG_CPU_ADD( "soundcpu", M68000, 8000000 ) MCFG_CPU_ADD( "soundcpu", M68000, 8000000 )

View File

@ -296,8 +296,6 @@ static DRIVER_INIT( konamigv )
/* init the scsi controller and hook up it's DMA */ /* init the scsi controller and hook up it's DMA */
am53cf96_init(machine, &scsi_intf); am53cf96_init(machine, &scsi_intf);
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(konamigv_exit), &machine)); machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(konamigv_exit), &machine));
psx_dma_install_read_handler(machine, 5, scsi_dma_read);
psx_dma_install_write_handler(machine, 5, scsi_dma_write);
} }
static MACHINE_START( konamigv ) static MACHINE_START( konamigv )
@ -331,7 +329,9 @@ static void spu_irq(device_t *device, UINT32 data)
static MACHINE_CONFIG_START( konamigv, konamigv_state ) static MACHINE_CONFIG_START( konamigv, konamigv_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD( "maincpu", CXD8530BQ, XTAL_67_7376MHz ) MCFG_CPU_ADD( "maincpu", CXD8530BQ, XTAL_67_7376MHz )
MCFG_CPU_PROGRAM_MAP( konamigv_map) MCFG_PSX_DMA_CHANNEL_READ( 5, scsi_dma_read )
MCFG_PSX_DMA_CHANNEL_WRITE( 5, scsi_dma_write )
MCFG_CPU_PROGRAM_MAP( konamigv_map )
MCFG_CPU_VBLANK_INT("screen", psx_vblank) MCFG_CPU_VBLANK_INT("screen", psx_vblank)
MCFG_MACHINE_START( konamigv ) MCFG_MACHINE_START( konamigv )

View File

@ -1265,8 +1265,6 @@ static DRIVER_INIT( konami573 )
psx_driver_init(machine); psx_driver_init(machine);
atapi_init(machine); atapi_init(machine);
psx_dma_install_read_handler(machine, 5, cdrom_dma_read);
psx_dma_install_write_handler(machine, 5, cdrom_dma_write);
state->save_item( NAME(state->m_n_security_control) ); state->save_item( NAME(state->m_n_security_control) );
@ -2963,7 +2961,9 @@ static const adc083x_interface konami573_adc_interface = {
static MACHINE_CONFIG_START( konami573, ksys573_state ) static MACHINE_CONFIG_START( konami573, ksys573_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz ) MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz )
MCFG_CPU_PROGRAM_MAP( konami573_map) MCFG_PSX_DMA_CHANNEL_READ( 5, cdrom_dma_read )
MCFG_PSX_DMA_CHANNEL_WRITE( 5, cdrom_dma_write )
MCFG_CPU_PROGRAM_MAP( konami573_map )
MCFG_CPU_VBLANK_INT("screen", sys573_vblank) MCFG_CPU_VBLANK_INT("screen", sys573_vblank)
MCFG_MACHINE_RESET( konami573 ) MCFG_MACHINE_RESET( konami573 )

View File

@ -1600,8 +1600,6 @@ static DRIVER_INIT( namcos12 )
psx_driver_init(machine); psx_driver_init(machine);
psx_dma_install_read_handler( machine, 5, namcos12_rom_read );
memory_configure_bank(machine, "bank1", 0, machine.region( "user2" )->bytes() / 0x200000, machine.region( "user2" )->base(), 0x200000 ); memory_configure_bank(machine, "bank1", 0, machine.region( "user2" )->bytes() / 0x200000, machine.region( "user2" )->base(), 0x200000 );
state->m_s12_porta = 0; state->m_s12_porta = 0;
@ -1642,6 +1640,8 @@ static DRIVER_INIT( ghlpanic )
static MACHINE_CONFIG_START( coh700, namcos12_state ) static MACHINE_CONFIG_START( coh700, namcos12_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz ) MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz )
MCFG_PSX_DMA_CHANNEL_READ( 5, namcos12_rom_read )
MCFG_CPU_PROGRAM_MAP( namcos12_map) MCFG_CPU_PROGRAM_MAP( namcos12_map)
MCFG_CPU_VBLANK_INT("screen", psx_vblank) MCFG_CPU_VBLANK_INT("screen", psx_vblank)

View File

@ -848,8 +848,6 @@ static DRIVER_INIT( twinkle )
{ {
psx_driver_init(machine); psx_driver_init(machine);
am53cf96_init(machine, &scsi_intf); am53cf96_init(machine, &scsi_intf);
psx_dma_install_read_handler(machine, 5, scsi_dma_read);
psx_dma_install_write_handler(machine, 5, scsi_dma_write);
device_t *i2cmem = machine.device("security"); device_t *i2cmem = machine.device("security");
i2cmem_e0_write( i2cmem, 0 ); i2cmem_e0_write( i2cmem, 0 );
@ -882,6 +880,8 @@ static const i2cmem_interface i2cmem_interface =
static MACHINE_CONFIG_START( twinkle, twinkle_state ) static MACHINE_CONFIG_START( twinkle, twinkle_state )
/* basic machine hardware */ /* basic machine hardware */
MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz ) MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz )
MCFG_PSX_DMA_CHANNEL_READ( 5, scsi_dma_read )
MCFG_PSX_DMA_CHANNEL_WRITE( 5, scsi_dma_write )
MCFG_CPU_PROGRAM_MAP( main_map ) MCFG_CPU_PROGRAM_MAP( main_map )
MCFG_CPU_VBLANK_INT( "mainscreen", psx_vblank ) MCFG_CPU_VBLANK_INT( "mainscreen", psx_vblank )

View File

@ -6,6 +6,8 @@
#if !defined( PSX_H ) #if !defined( PSX_H )
#include "cpu/psx/dma.h"
#define PSX_RC_STOP ( 0x01 ) #define PSX_RC_STOP ( 0x01 )
#define PSX_RC_RESET ( 0x04 ) /* guess */ #define PSX_RC_RESET ( 0x04 ) /* guess */
#define PSX_RC_COUNTTARGET ( 0x08 ) #define PSX_RC_COUNTTARGET ( 0x08 )
@ -35,11 +37,108 @@
#define PSX_SIO_IN_DSR ( 2 ) /* ACK */ #define PSX_SIO_IN_DSR ( 2 ) /* ACK */
#define PSX_SIO_IN_CTS ( 4 ) #define PSX_SIO_IN_CTS ( 4 )
typedef void ( *psx_dma_read_handler )( running_machine &, UINT32, INT32 );
typedef void ( *psx_dma_write_handler )( running_machine &, UINT32, INT32 );
typedef void ( *psx_sio_handler )( running_machine &, int ); typedef void ( *psx_sio_handler )( running_machine &, int );
#define DCTSIZE ( 8 )
#define DCTSIZE2 ( DCTSIZE * DCTSIZE )
#define SIO_BUF_SIZE ( 8 )
#define SIO_STATUS_TX_RDY ( 1 << 0 )
#define SIO_STATUS_RX_RDY ( 1 << 1 )
#define SIO_STATUS_TX_EMPTY ( 1 << 2 )
#define SIO_STATUS_OVERRUN ( 1 << 4 )
#define SIO_STATUS_DSR ( 1 << 7 )
#define SIO_STATUS_IRQ ( 1 << 9 )
#define SIO_CONTROL_TX_ENA ( 1 << 0 )
#define SIO_CONTROL_IACK ( 1 << 4 )
#define SIO_CONTROL_RESET ( 1 << 6 )
#define SIO_CONTROL_TX_IENA ( 1 << 10 )
#define SIO_CONTROL_RX_IENA ( 1 << 11 )
#define SIO_CONTROL_DSR_IENA ( 1 << 12 )
#define SIO_CONTROL_DTR ( 1 << 13 )
#define MDEC_COS_PRECALC_BITS ( 21 )
typedef struct _psx_root psx_root;
struct _psx_root
{
emu_timer *timer;
UINT16 n_count;
UINT16 n_mode;
UINT16 n_target;
UINT64 n_start;
};
typedef struct _psx_sio psx_sio;
struct _psx_sio
{
UINT32 n_status;
UINT32 n_mode;
UINT32 n_control;
UINT32 n_baud;
UINT32 n_tx;
UINT32 n_rx;
UINT32 n_tx_prev;
UINT32 n_rx_prev;
UINT32 n_tx_data;
UINT32 n_rx_data;
UINT32 n_tx_shift;
UINT32 n_rx_shift;
UINT32 n_tx_bits;
UINT32 n_rx_bits;
emu_timer *timer;
psx_sio_handler fn_handler;
};
typedef struct _psx_mdec psx_mdec;
struct _psx_mdec
{
UINT32 n_decoded;
UINT32 n_offset;
UINT16 p_n_output[ 24 * 16 ];
INT32 p_n_quantize_y[ DCTSIZE2 ];
INT32 p_n_quantize_uv[ DCTSIZE2 ];
INT32 p_n_cos[ DCTSIZE2 ];
INT32 p_n_cos_precalc[ DCTSIZE2 * DCTSIZE2 ];
UINT32 n_0_command;
UINT32 n_0_address;
UINT32 n_0_size;
UINT32 n_1_command;
UINT32 n_1_status;
UINT16 p_n_clamp8[ 256 * 3 ];
UINT16 p_n_r5[ 256 * 3 ];
UINT16 p_n_g5[ 256 * 3 ];
UINT16 p_n_b5[ 256 * 3 ];
INT32 p_n_unpacked[ DCTSIZE2 * 6 * 2 ];
};
typedef struct _psx_machine psx_machine; typedef struct _psx_machine psx_machine;
struct _psx_machine
{
running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
running_machine *m_machine;
UINT32 *p_n_psxram;
size_t n_psxramsize;
UINT32 n_com_delay;
UINT32 n_irqdata;
UINT32 n_irqmask;
psx_root root[3];
psx_sio sio[2];
psx_mdec mdec;
};
typedef struct _psx_gpu psx_gpu; typedef struct _psx_gpu psx_gpu;
class psx_state : public driver_device class psx_state : public driver_device

View File

@ -12,124 +12,6 @@
#define VERBOSE_LEVEL ( 0 ) #define VERBOSE_LEVEL ( 0 )
#define DCTSIZE ( 8 )
#define DCTSIZE2 ( DCTSIZE * DCTSIZE )
#define SIO_BUF_SIZE ( 8 )
#define SIO_STATUS_TX_RDY ( 1 << 0 )
#define SIO_STATUS_RX_RDY ( 1 << 1 )
#define SIO_STATUS_TX_EMPTY ( 1 << 2 )
#define SIO_STATUS_OVERRUN ( 1 << 4 )
#define SIO_STATUS_DSR ( 1 << 7 )
#define SIO_STATUS_IRQ ( 1 << 9 )
#define SIO_CONTROL_TX_ENA ( 1 << 0 )
#define SIO_CONTROL_IACK ( 1 << 4 )
#define SIO_CONTROL_RESET ( 1 << 6 )
#define SIO_CONTROL_TX_IENA ( 1 << 10 )
#define SIO_CONTROL_RX_IENA ( 1 << 11 )
#define SIO_CONTROL_DSR_IENA ( 1 << 12 )
#define SIO_CONTROL_DTR ( 1 << 13 )
#define MDEC_COS_PRECALC_BITS ( 21 )
typedef struct _psx_dma_channel psx_dma_channel;
struct _psx_dma_channel
{
UINT32 n_base;
UINT32 n_blockcontrol;
UINT32 n_channelcontrol;
emu_timer *timer;
psx_dma_read_handler fn_read;
psx_dma_write_handler fn_write;
UINT32 n_ticks;
UINT32 b_running;
};
typedef struct _psx_root psx_root;
struct _psx_root
{
emu_timer *timer;
UINT16 n_count;
UINT16 n_mode;
UINT16 n_target;
UINT64 n_start;
};
typedef struct _psx_sio psx_sio;
struct _psx_sio
{
UINT32 n_status;
UINT32 n_mode;
UINT32 n_control;
UINT32 n_baud;
UINT32 n_tx;
UINT32 n_rx;
UINT32 n_tx_prev;
UINT32 n_rx_prev;
UINT32 n_tx_data;
UINT32 n_rx_data;
UINT32 n_tx_shift;
UINT32 n_rx_shift;
UINT32 n_tx_bits;
UINT32 n_rx_bits;
emu_timer *timer;
psx_sio_handler fn_handler;
};
typedef struct _psx_mdec psx_mdec;
struct _psx_mdec
{
UINT32 n_decoded;
UINT32 n_offset;
UINT16 p_n_output[ 24 * 16 ];
INT32 p_n_quantize_y[ DCTSIZE2 ];
INT32 p_n_quantize_uv[ DCTSIZE2 ];
INT32 p_n_cos[ DCTSIZE2 ];
INT32 p_n_cos_precalc[ DCTSIZE2 * DCTSIZE2 ];
UINT32 n_0_command;
UINT32 n_0_address;
UINT32 n_0_size;
UINT32 n_1_command;
UINT32 n_1_status;
UINT16 p_n_clamp8[ 256 * 3 ];
UINT16 p_n_r5[ 256 * 3 ];
UINT16 p_n_g5[ 256 * 3 ];
UINT16 p_n_b5[ 256 * 3 ];
INT32 p_n_unpacked[ DCTSIZE2 * 6 * 2 ];
};
struct _psx_machine
{
running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
running_machine *m_machine;
UINT32 *p_n_psxram;
size_t n_psxramsize;
UINT32 n_com_delay;
UINT32 n_irqdata;
UINT32 n_irqmask;
UINT32 n_dpcp;
UINT32 n_dicr;
psx_dma_channel channel[7];
psx_root root[3];
psx_sio sio[2];
psx_mdec mdec;
};
INLINE void ATTR_PRINTF(3,4) verboselog( psx_machine *p_psx, int n_level, const char *s_fmt, ... ) INLINE void ATTR_PRINTF(3,4) verboselog( psx_machine *p_psx, int n_level, const char *s_fmt, ... )
{ {
if( VERBOSE_LEVEL >= n_level ) if( VERBOSE_LEVEL >= n_level )
@ -243,355 +125,15 @@ void psx_irq_set( running_machine &machine, UINT32 data )
/* DMA */ /* DMA */
static void dma_start_timer( psx_machine *p_psx, int n_channel, UINT32 n_ticks )
{
psx_dma_channel *dma = &p_psx->channel[ n_channel ];
dma->timer->adjust( attotime::from_hz(33868800) * n_ticks, n_channel);
dma->n_ticks = n_ticks;
dma->b_running = 1;
}
static void dma_stop_timer( psx_machine *p_psx, int n_channel )
{
psx_dma_channel *dma = &p_psx->channel[ n_channel ];
dma->timer->adjust( attotime::never);
dma->b_running = 0;
}
static void dma_timer_adjust( psx_machine *p_psx, int n_channel )
{
psx_dma_channel *dma = &p_psx->channel[ n_channel ];
if( dma->b_running )
{
dma_start_timer( p_psx, n_channel, dma->n_ticks );
}
else
{
dma_stop_timer( p_psx, n_channel );
}
}
static void dma_interrupt_update( psx_machine *p_psx )
{
int n_int;
int n_mask;
n_int = ( p_psx->n_dicr >> 24 ) & 0x7f;
n_mask = ( p_psx->n_dicr >> 16 ) & 0xff;
if( ( n_mask & 0x80 ) != 0 && ( n_int & n_mask ) != 0 )
{
verboselog( p_psx, 2, "dma_interrupt_update( %02x, %02x ) interrupt triggered\n", n_int, n_mask );
p_psx->n_dicr |= 0x80000000;
psx_irq_set( p_psx->machine(), PSX_IRQ_DMA );
}
else if( n_int != 0 )
{
verboselog( p_psx, 2, "dma_interrupt_update( %02x, %02x ) interrupt not enabled\n", n_int, n_mask );
}
p_psx->n_dicr &= 0x00ffffff | ( p_psx->n_dicr << 8 );
}
static void dma_finished(psx_machine *p_psx, int n_channel)
{
UINT32 *p_n_psxram = p_psx->p_n_psxram;
psx_dma_channel *dma = &p_psx->channel[ n_channel ];
if( dma->n_channelcontrol == 0x01000401 && n_channel == 2 )
{
UINT32 n_size;
UINT32 n_total;
UINT32 n_address = ( dma->n_base & 0xffffff );
UINT32 n_adrmask = p_psx->n_psxramsize - 1;
UINT32 n_nextaddress;
if( n_address != 0xffffff )
{
n_total = 0;
for( ;; )
{
if( n_address == 0xffffff )
{
dma->n_base = n_address;
dma_start_timer( p_psx, n_channel, 19000 );
return;
}
if( n_total > 65535 )
{
dma->n_base = n_address;
//FIXME:
// 16000 below is based on try and error.
// Mametesters.org: sfex20103red
//dma_start_timer( p_psx, n_channel, 16 );
dma_start_timer( p_psx, n_channel, 16000 );
return;
}
n_address &= n_adrmask;
n_nextaddress = p_n_psxram[ n_address / 4 ];
n_size = n_nextaddress >> 24;
(*dma->fn_write)( p_psx->machine(), n_address + 4, n_size );
//FIXME:
// The following conditions will cause an endless loop.
// If stopping the transfer is correct I cannot judge
// The patch is meant as a hint for somebody who knows
// the hardware.
// Mametesters.org: psyforce0105u5red, raystorm0111u1red
if ((n_nextaddress & 0xffffff) != 0xffffff)
if (n_address == p_n_psxram[ (n_nextaddress & 0xffffff) / 4])
break;
if (n_address == (n_nextaddress & 0xffffff) )
break;
n_address = ( n_nextaddress & 0xffffff );
n_total += ( n_size + 1 );
}
}
}
dma->n_channelcontrol &= ~( ( 1L << 0x18 ) | ( 1L << 0x1c ) );
p_psx->n_dicr |= 1 << ( 24 + n_channel );
dma_interrupt_update(p_psx);
dma_stop_timer( p_psx, n_channel );
}
static TIMER_CALLBACK( dma_finished_callback )
{
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
dma_finished(p_psx, param);
}
void psx_dma_install_read_handler( running_machine &machine, int n_channel, psx_dma_read_handler p_fn_dma_read ) void psx_dma_install_read_handler( running_machine &machine, int n_channel, psx_dma_read_handler p_fn_dma_read )
{
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
p_psx->channel[ n_channel ].fn_read = p_fn_dma_read; {
psxcpu_device::install_dma_read_handler( *machine.device("maincpu"), n_channel, p_fn_dma_read );
} }
void psx_dma_install_write_handler( running_machine &machine, int n_channel, psx_dma_read_handler p_fn_dma_write ) void psx_dma_install_write_handler( running_machine &machine, int n_channel, psx_dma_read_handler p_fn_dma_write )
{ {
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx; psxcpu_device::install_dma_write_handler( *machine.device("maincpu"), n_channel, p_fn_dma_write );
p_psx->channel[ n_channel ].fn_write = p_fn_dma_write;
}
WRITE32_HANDLER( psx_dma_w )
{
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
UINT32 *p_n_psxram = p_psx->p_n_psxram;
int n_channel = offset / 4;
psx_dma_channel *dma = &p_psx->channel[ n_channel ];
if( n_channel < 7 )
{
switch( offset % 4 )
{
case 0:
verboselog( p_psx, 2, "dmabase( %d ) = %08x\n", n_channel, data );
dma->n_base = data;
break;
case 1:
verboselog( p_psx, 2, "dmablockcontrol( %d ) = %08x\n", n_channel, data );
dma->n_blockcontrol = data;
break;
case 2:
verboselog( p_psx, 2, "dmachannelcontrol( %d ) = %08x\n", n_channel, data );
dma->n_channelcontrol = data;
if( ( dma->n_channelcontrol & ( 1L << 0x18 ) ) != 0 && ( p_psx->n_dpcp & ( 1 << ( 3 + ( n_channel * 4 ) ) ) ) != 0 )
{
INT32 n_size;
UINT32 n_address;
UINT32 n_nextaddress;
UINT32 n_adrmask;
n_adrmask = p_psx->n_psxramsize - 1;
n_address = ( dma->n_base & n_adrmask );
n_size = dma->n_blockcontrol;
if( ( dma->n_channelcontrol & 0x200 ) != 0 )
{
UINT32 n_ba;
n_ba = dma->n_blockcontrol >> 16;
if( n_ba == 0 )
{
n_ba = 0x10000;
}
n_size = ( n_size & 0xffff ) * n_ba;
}
if( dma->n_channelcontrol == 0x01000000 &&
dma->fn_read != NULL )
{
verboselog( p_psx, 1, "dma %d read block %08x %08x\n", n_channel, n_address, n_size );
(*dma->fn_read)( space->machine(), n_address, n_size );
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 &&
dma->fn_read != NULL )
{
verboselog( p_psx, 1, "dma %d read block %08x %08x\n", n_channel, n_address, n_size );
(*dma->fn_read)( space->machine(), n_address, n_size );
if( n_channel == 1 )
{
dma_start_timer( p_psx, n_channel, 26000 );
}
else
{
dma_finished( p_psx, n_channel );
}
}
else if( dma->n_channelcontrol == 0x01000201 &&
dma->fn_write != NULL )
{
verboselog( p_psx, 1, "dma %d write block %08x %08x\n", n_channel, n_address, n_size );
(*dma->fn_write)( space->machine(), n_address, n_size );
dma_finished( p_psx, n_channel );
}
else if( dma->n_channelcontrol == 0x11050100 &&
dma->fn_write != NULL )
{
/* todo: check this is a write not a read... */
verboselog( p_psx, 1, "dma %d write block %08x %08x\n", n_channel, n_address, n_size );
(*dma->fn_write)( space->machine(), n_address, n_size );
dma_finished( p_psx, n_channel );
}
else if( dma->n_channelcontrol == 0x11150100 &&
dma->fn_write != NULL )
{
/* todo: check this is a write not a read... */
verboselog( p_psx, 1, "dma %d write block %08x %08x\n", n_channel, n_address, n_size );
(*dma->fn_write)( space->machine(), n_address, n_size );
dma_finished( p_psx, n_channel );
}
else if( dma->n_channelcontrol == 0x01000401 &&
n_channel == 2 &&
dma->fn_write != NULL )
{
verboselog( p_psx, 1, "dma %d write linked list %08x\n",
n_channel, dma->n_base );
dma_finished( p_psx, n_channel );
}
else if( dma->n_channelcontrol == 0x11000002 &&
n_channel == 6 )
{
verboselog( p_psx, 1, "dma 6 reverse clear %08x %08x\n",
dma->n_base, dma->n_blockcontrol );
if( n_size > 0 )
{
n_size--;
while( n_size > 0 )
{
n_nextaddress = ( n_address - 4 ) & 0xffffff;
p_n_psxram[ n_address / 4 ] = n_nextaddress;
n_address = n_nextaddress;
n_size--;
}
p_n_psxram[ n_address / 4 ] = 0xffffff;
}
dma_start_timer( p_psx, n_channel, 2150 );
}
else
{
verboselog( p_psx, 1, "dma %d unknown mode %08x\n", n_channel, dma->n_channelcontrol );
}
}
else if( dma->n_channelcontrol != 0 )
{
verboselog( p_psx, 1, "psx_dma_w( %04x, %08x, %08x ) channel not enabled\n", offset, dma->n_channelcontrol, mem_mask );
}
break;
default:
verboselog( p_psx, 1, "psx_dma_w( %04x, %08x, %08x ) Unknown dma channel register\n", offset, data, mem_mask );
break;
}
}
else
{
switch( offset % 4 )
{
case 0x0:
verboselog( p_psx, 1, "psx_dma_w( %04x, %08x, %08x ) dpcp\n", offset, data, mem_mask );
p_psx->n_dpcp = ( p_psx->n_dpcp & ~mem_mask ) | data;
break;
case 0x1:
p_psx->n_dicr = ( p_psx->n_dicr & ( 0x80000000 | ~mem_mask ) ) |
( p_psx->n_dicr & ~data & 0x7f000000 & mem_mask ) |
( data & 0x00ffffff & mem_mask );
if( ( p_psx->n_dicr & 0x80000000 ) != 0 && ( p_psx->n_dicr & 0x7f000000 ) == 0 )
{
verboselog( p_psx, 2, "dma interrupt cleared\n" );
p_psx->n_dicr &= ~0x80000000;
}
verboselog( p_psx, 1, "psx_dma_w( %04x, %08x, %08x ) dicr -> %08x\n", offset, data, mem_mask, p_psx->n_dicr );
break;
default:
verboselog( p_psx, 0, "psx_dma_w( %04x, %08x, %08x ) Unknown dma control register\n", offset, data, mem_mask );
break;
}
}
}
READ32_HANDLER( psx_dma_r )
{
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
int n_channel = offset / 4;
psx_dma_channel *dma = &p_psx->channel[ n_channel ];
if( n_channel < 7 )
{
switch( offset % 4 )
{
case 0:
verboselog( p_psx, 1, "psx_dma_r dmabase[ %d ] ( %08x )\n", n_channel, dma->n_base );
return dma->n_base;
case 1:
verboselog( p_psx, 1, "psx_dma_r dmablockcontrol[ %d ] ( %08x )\n", n_channel, dma->n_blockcontrol );
return dma->n_blockcontrol;
case 2:
verboselog( p_psx, 1, "psx_dma_r dmachannelcontrol[ %d ] ( %08x )\n", n_channel, dma->n_channelcontrol );
return dma->n_channelcontrol;
default:
verboselog( p_psx, 0, "psx_dma_r( %08x, %08x ) Unknown dma channel register\n", offset, mem_mask );
break;
}
}
else
{
switch( offset % 4 )
{
case 0x0:
verboselog( p_psx, 1, "psx_dma_r dpcp ( %08x )\n", p_psx->n_dpcp );
return p_psx->n_dpcp;
case 0x1:
verboselog( p_psx, 1, "psx_dma_r dicr ( %08x )\n", p_psx->n_dicr );
return p_psx->n_dicr;
default:
verboselog( p_psx, 0, "psx_dma_r( %08x, %08x ) Unknown dma control register\n", offset, mem_mask );
break;
}
}
return 0;
} }
/* Root Counters */ /* Root Counters */
@ -1595,21 +1137,12 @@ void psx_machine_init( running_machine &machine )
p_psx->n_irqdata = 0; p_psx->n_irqdata = 0;
p_psx->n_irqmask = 0; p_psx->n_irqmask = 0;
/* dma */
p_psx->n_dpcp = 0;
p_psx->n_dicr = 0;
p_psx->mdec.n_0_command = 0; p_psx->mdec.n_0_command = 0;
p_psx->mdec.n_0_address = 0; p_psx->mdec.n_0_address = 0;
p_psx->mdec.n_0_size = 0; p_psx->mdec.n_0_size = 0;
p_psx->mdec.n_1_command = 0; p_psx->mdec.n_1_command = 0;
p_psx->mdec.n_1_status = 0; p_psx->mdec.n_1_status = 0;
for( n = 0; n < 7; n++ )
{
dma_stop_timer( p_psx, n );
}
for( n = 0; n < 2; n++ ) for( n = 0; n < 2; n++ )
{ {
p_psx->sio[ n ].n_status = SIO_STATUS_TX_EMPTY | SIO_STATUS_TX_RDY; p_psx->sio[ n ].n_status = SIO_STATUS_TX_EMPTY | SIO_STATUS_TX_RDY;
@ -1637,11 +1170,6 @@ static void psx_postload(psx_machine *p_psx)
psx_irq_update(p_psx); psx_irq_update(p_psx);
for( n = 0; n < 7; n++ )
{
dma_timer_adjust( p_psx, n );
}
for( n = 0; n < 3; n++ ) for( n = 0; n < 3; n++ )
{ {
root_timer_adjust( p_psx, n ); root_timer_adjust( p_psx, n );
@ -1668,13 +1196,6 @@ void psx_driver_init( running_machine &machine )
p_psx->p_n_psxram = state->m_p_n_psxram; p_psx->p_n_psxram = state->m_p_n_psxram;
p_psx->n_psxramsize = state->m_n_psxramsize; p_psx->n_psxramsize = state->m_n_psxramsize;
for( n = 0; n < 7; n++ )
{
p_psx->channel[ n ].timer = machine.scheduler().timer_alloc( FUNC(dma_finished_callback), &machine );
p_psx->channel[ n ].fn_read = NULL;
p_psx->channel[ n ].fn_write = NULL;
}
for( n = 0; n < 3; n++ ) for( n = 0; n < 3; n++ )
{ {
p_psx->root[ n ].timer = machine.scheduler().timer_alloc( FUNC(root_finished )); p_psx->root[ n ].timer = machine.scheduler().timer_alloc( FUNC(root_finished ));
@ -1713,17 +1234,6 @@ void psx_driver_init( running_machine &machine )
state_save_register_global( machine, p_psx->n_irqdata ); state_save_register_global( machine, p_psx->n_irqdata );
state_save_register_global( machine, p_psx->n_irqmask ); state_save_register_global( machine, p_psx->n_irqmask );
for (n = 0; n < 7; n++ )
{
state_save_register_item( machine, "psxdma", NULL, n, p_psx->channel[n].n_base );
state_save_register_item( machine, "psxdma", NULL, n, p_psx->channel[n].n_blockcontrol );
state_save_register_item( machine, "psxdma", NULL, n, p_psx->channel[n].n_channelcontrol );
state_save_register_item( machine, "psxdma", NULL, n, p_psx->channel[n].n_ticks );
state_save_register_item( machine, "psxdma", NULL, n, p_psx->channel[n].b_running );
}
state_save_register_global( machine, p_psx->n_dpcp );
state_save_register_global( machine, p_psx->n_dicr );
for ( n = 0; n < 3; n++ ) for ( n = 0; n < 3; n++ )
{ {
state_save_register_item( machine, "psxroot", NULL, n, p_psx->root[n].n_count ); state_save_register_item( machine, "psxroot", NULL, n, p_psx->root[n].n_count );