mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
psx: Remove quickload, may be handled differently later [O. Galibert]
This commit is contained in:
parent
0f15126428
commit
1e32d20867
@ -44,18 +44,10 @@ public:
|
||||
UINT8 m_cd_io_status;
|
||||
UINT8 m_cd_param[8];
|
||||
UINT8 m_cd_result[8];
|
||||
DECLARE_DIRECT_UPDATE_MEMBER(psx_default);
|
||||
DECLARE_DIRECT_UPDATE_MEMBER(psx_setopbase);
|
||||
DECLARE_MACHINE_RESET(psx);
|
||||
inline void ATTR_PRINTF(3,4) verboselog( int n_level, const char *s_fmt, ... );
|
||||
void psxexe_conv32( UINT32 *p_uint32 );
|
||||
int load_psxexe( cpu_device *cpu, unsigned char *p_n_file, int n_len );
|
||||
void cpe_set_register( cpu_device *cpu, int n_reg, int n_value );
|
||||
int load_cpe( cpu_device *cpu, unsigned char *p_n_file, int n_len );
|
||||
int load_psf( cpu_device *cpu, unsigned char *p_n_file, int n_len );
|
||||
void cd_dma_read( UINT32 *p_n_psxram, UINT32 n_address, INT32 n_size );
|
||||
void cd_dma_write( UINT32 *p_n_psxram, UINT32 n_address, INT32 n_size );
|
||||
DECLARE_QUICKLOAD_LOAD_MEMBER( psx_exe_load );
|
||||
required_device<psxcpu_device> m_maincpu;
|
||||
required_device<ram_device> m_ram;
|
||||
};
|
||||
@ -77,397 +69,6 @@ inline void ATTR_PRINTF(3,4) psx1_state::verboselog( int n_level, const char *s
|
||||
}
|
||||
|
||||
|
||||
void psx1_state::psxexe_conv32( UINT32 *p_uint32 )
|
||||
{
|
||||
UINT8 *p_uint8;
|
||||
|
||||
p_uint8 = (UINT8 *)p_uint32;
|
||||
|
||||
*( p_uint32 ) = p_uint8[ 0 ] |
|
||||
( p_uint8[ 1 ] << 8 ) |
|
||||
( p_uint8[ 2 ] << 16 ) |
|
||||
( p_uint8[ 3 ] << 24 );
|
||||
}
|
||||
|
||||
int psx1_state::load_psxexe( cpu_device *cpu, unsigned char *p_n_file, int n_len )
|
||||
{
|
||||
struct PSXEXE_HEADER
|
||||
{
|
||||
UINT8 id[ 8 ];
|
||||
UINT32 text; /* SCE only */
|
||||
UINT32 data; /* SCE only */
|
||||
UINT32 pc0;
|
||||
UINT32 gp0; /* SCE only */
|
||||
UINT32 t_addr;
|
||||
UINT32 t_size;
|
||||
UINT32 d_addr; /* SCE only */
|
||||
UINT32 d_size; /* SCE only */
|
||||
UINT32 b_addr; /* SCE only */
|
||||
UINT32 b_size; /* SCE only */
|
||||
UINT32 s_addr;
|
||||
UINT32 s_size;
|
||||
UINT32 SavedSP;
|
||||
UINT32 SavedFP;
|
||||
UINT32 SavedGP;
|
||||
UINT32 SavedRA;
|
||||
UINT32 SavedS0;
|
||||
UINT8 dummy[ 0x800 - 76 ];
|
||||
};
|
||||
|
||||
struct PSXEXE_HEADER *psxexe_header = (struct PSXEXE_HEADER *)p_n_file;
|
||||
|
||||
if( n_len >= sizeof( struct PSXEXE_HEADER ) &&
|
||||
memcmp( psxexe_header->id, "PS-X EXE", 8 ) == 0 )
|
||||
{
|
||||
psxexe_conv32( &psxexe_header->text );
|
||||
psxexe_conv32( &psxexe_header->data );
|
||||
psxexe_conv32( &psxexe_header->pc0 );
|
||||
psxexe_conv32( &psxexe_header->gp0 );
|
||||
psxexe_conv32( &psxexe_header->t_addr );
|
||||
psxexe_conv32( &psxexe_header->t_size );
|
||||
psxexe_conv32( &psxexe_header->d_addr );
|
||||
psxexe_conv32( &psxexe_header->d_size );
|
||||
psxexe_conv32( &psxexe_header->b_addr );
|
||||
psxexe_conv32( &psxexe_header->b_size );
|
||||
psxexe_conv32( &psxexe_header->s_addr );
|
||||
psxexe_conv32( &psxexe_header->s_size );
|
||||
psxexe_conv32( &psxexe_header->SavedSP );
|
||||
psxexe_conv32( &psxexe_header->SavedFP );
|
||||
psxexe_conv32( &psxexe_header->SavedGP );
|
||||
psxexe_conv32( &psxexe_header->SavedRA );
|
||||
psxexe_conv32( &psxexe_header->SavedS0 );
|
||||
|
||||
/* todo: check size.. */
|
||||
|
||||
logerror( "psx_exe_load: pc %08x\n", psxexe_header->pc0 );
|
||||
logerror( "psx_exe_load: org %08x\n", psxexe_header->t_addr );
|
||||
logerror( "psx_exe_load: len %08x\n", psxexe_header->t_size );
|
||||
logerror( "psx_exe_load: sp %08x\n", psxexe_header->s_addr );
|
||||
logerror( "psx_exe_load: len %08x\n", psxexe_header->s_size );
|
||||
|
||||
UINT8 *p_ram = m_ram->pointer();
|
||||
UINT32 n_ram = m_ram->size();
|
||||
|
||||
UINT8 *p_psxexe = p_n_file + sizeof( struct PSXEXE_HEADER );
|
||||
|
||||
UINT32 n_address = psxexe_header->t_addr;
|
||||
UINT32 n_size = psxexe_header->t_size;
|
||||
while( n_size != 0 )
|
||||
{
|
||||
p_ram[ BYTE4_XOR_LE( n_address ) % n_ram ] = *( p_psxexe );
|
||||
n_address++;
|
||||
p_psxexe++;
|
||||
n_size--;
|
||||
}
|
||||
|
||||
cpu->set_state_int( PSXCPU_PC, psxexe_header->pc0 );
|
||||
cpu->set_state_int( PSXCPU_R28, psxexe_header->gp0 );
|
||||
UINT32 n_stack = psxexe_header->s_addr + psxexe_header->s_size;
|
||||
if( n_stack != 0 )
|
||||
{
|
||||
cpu->set_state_int( PSXCPU_R29, n_stack );
|
||||
cpu->set_state_int( PSXCPU_R30, n_stack );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void psx1_state::cpe_set_register( cpu_device *cpu, int n_reg, int n_value )
|
||||
{
|
||||
if( n_reg < 0x80 && ( n_reg % 4 ) == 0 )
|
||||
{
|
||||
logerror( "psx_exe_load: r%-2d %08x\n", n_reg / 4, n_value );
|
||||
cpu->set_state_int( PSXCPU_R0 + ( n_reg / 4 ), n_value );
|
||||
}
|
||||
else if( n_reg == 0x80 )
|
||||
{
|
||||
logerror( "psx_exe_load: lo %08x\n", n_value );
|
||||
cpu->set_state_int( PSXCPU_LO, n_value );
|
||||
}
|
||||
else if( n_reg == 0x84 )
|
||||
{
|
||||
logerror( "psx_exe_load: hi %08x\n", n_value );
|
||||
cpu->set_state_int( PSXCPU_HI, n_value );
|
||||
}
|
||||
else if( n_reg == 0x88 )
|
||||
{
|
||||
logerror( "psx_exe_load: sr %08x\n", n_value );
|
||||
cpu->set_state_int( PSXCPU_CP0R12, n_value );
|
||||
}
|
||||
else if( n_reg == 0x8c )
|
||||
{
|
||||
logerror( "psx_exe_load: cause %08x\n", n_value );
|
||||
cpu->set_state_int( PSXCPU_CP0R13, n_value );
|
||||
}
|
||||
else if( n_reg == 0x90 )
|
||||
{
|
||||
logerror( "psx_exe_load: pc %08x\n", n_value );
|
||||
cpu->set_state_int( PSXCPU_PC, n_value );
|
||||
}
|
||||
else if( n_reg == 0x94 )
|
||||
{
|
||||
logerror( "psx_exe_load: prid %08x\n", n_value );
|
||||
cpu->set_state_int( PSXCPU_CP0R15, n_value );
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror( "psx_exe_load: invalid register %04x/%08x\n", n_reg, n_value );
|
||||
}
|
||||
}
|
||||
|
||||
int psx1_state::load_cpe( cpu_device *cpu, unsigned char *p_n_file, int n_len )
|
||||
{
|
||||
if( n_len >= 4 &&
|
||||
memcmp( p_n_file, "CPE\001", 4 ) == 0 )
|
||||
{
|
||||
int n_offset = 4;
|
||||
|
||||
for( ;; )
|
||||
{
|
||||
if( n_offset >= n_len || p_n_file[ n_offset ] > 8 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
switch( p_n_file[ n_offset++ ] )
|
||||
{
|
||||
case 0:
|
||||
/* end of file */
|
||||
return 1;
|
||||
case 1:
|
||||
/* read bytes */
|
||||
{
|
||||
int n_address = ( (int)p_n_file[ n_offset + 0 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 1 ] << 8 ) |
|
||||
( (int)p_n_file[ n_offset + 2 ] << 16 ) |
|
||||
( (int)p_n_file[ n_offset + 3 ] << 24 );
|
||||
int n_size = ( (int)p_n_file[ n_offset + 4 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 5 ] << 8 ) |
|
||||
( (int)p_n_file[ n_offset + 6 ] << 16 ) |
|
||||
( (int)p_n_file[ n_offset + 7 ] << 24 );
|
||||
|
||||
UINT8 *p_ram = m_ram->pointer();
|
||||
UINT32 n_ram = m_ram->size();
|
||||
|
||||
n_offset += 8;
|
||||
|
||||
logerror( "psx_exe_load: org %08x\n", n_address );
|
||||
logerror( "psx_exe_load: len %08x\n", n_size );
|
||||
|
||||
while( n_size > 0 )
|
||||
{
|
||||
p_ram[ BYTE4_XOR_LE( n_address ) % n_ram ] = p_n_file[ n_offset++ ];
|
||||
n_address++;
|
||||
n_size--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
/* run address: not tested */
|
||||
{
|
||||
int n_value = ( (int)p_n_file[ n_offset + 2 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 3 ] << 8 ) |
|
||||
( (int)p_n_file[ n_offset + 4 ] << 16 ) |
|
||||
( (int)p_n_file[ n_offset + 5 ] << 24 );
|
||||
|
||||
n_offset += 4;
|
||||
|
||||
cpe_set_register( cpu, 0x90, n_value );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
/* set reg to longword */
|
||||
{
|
||||
int n_reg = ( (int)p_n_file[ n_offset + 0 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 1 ] << 8 );
|
||||
int n_value = ( (int)p_n_file[ n_offset + 2 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 3 ] << 8 ) |
|
||||
( (int)p_n_file[ n_offset + 4 ] << 16 ) |
|
||||
( (int)p_n_file[ n_offset + 5 ] << 24 );
|
||||
|
||||
n_offset += 6;
|
||||
|
||||
cpe_set_register( cpu, n_reg, n_value );
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
/* set reg to word: not tested */
|
||||
{
|
||||
int n_reg = ( (int)p_n_file[ n_offset + 0 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 1 ] << 8 );
|
||||
int n_value = ( (int)p_n_file[ n_offset + 2 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 3 ] << 8 );
|
||||
|
||||
n_offset += 4;
|
||||
|
||||
cpe_set_register( cpu, n_reg, n_value );
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
/* set reg to byte: not tested */
|
||||
{
|
||||
int n_reg = ( (int)p_n_file[ n_offset + 0 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 1 ] << 8 );
|
||||
int n_value = ( (int)p_n_file[ n_offset + 2 ] << 0 );
|
||||
|
||||
n_offset += 3;
|
||||
|
||||
cpe_set_register( cpu, n_reg, n_value );
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
/* set reg to 3-byte: not tested */
|
||||
{
|
||||
int n_reg = ( (int)p_n_file[ n_offset + 0 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 1 ] << 8 );
|
||||
int n_value = ( (int)p_n_file[ n_offset + 2 ] << 0 ) |
|
||||
( (int)p_n_file[ n_offset + 3 ] << 8 ) |
|
||||
( (int)p_n_file[ n_offset + 4 ] << 16 );
|
||||
|
||||
n_offset += 5;
|
||||
|
||||
cpe_set_register( cpu, n_reg, n_value );
|
||||
break;
|
||||
}
|
||||
case 7:
|
||||
/* workspace: not tested */
|
||||
n_offset += 4;
|
||||
break;
|
||||
case 8:
|
||||
/* unit */
|
||||
{
|
||||
int n_unit = p_n_file[ n_offset + 0 ];
|
||||
|
||||
n_offset++;
|
||||
|
||||
logerror( "psx_exe_load: unit %08x\n", n_unit );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int psx1_state::load_psf( cpu_device *cpu, unsigned char *p_n_file, int n_len )
|
||||
{
|
||||
int n_return;
|
||||
unsigned long n_crc;
|
||||
unsigned long n_compressed;
|
||||
unsigned char *p_n_compressed;
|
||||
unsigned long n_uncompressed;
|
||||
dynamic_buffer p_n_uncompressed;
|
||||
|
||||
struct PSF_HEADER
|
||||
{
|
||||
unsigned char id[ 4 ];
|
||||
UINT32 reserved_size;
|
||||
UINT32 exe_size;
|
||||
UINT32 exe_crc;
|
||||
};
|
||||
|
||||
struct PSF_HEADER *psf_header = (struct PSF_HEADER *)p_n_file;
|
||||
|
||||
n_return = 0;
|
||||
|
||||
if( n_len >= sizeof( struct PSF_HEADER ) &&
|
||||
memcmp( p_n_file, "PSF", 3 ) == 0 )
|
||||
{
|
||||
psxexe_conv32( &psf_header->reserved_size );
|
||||
psxexe_conv32( &psf_header->exe_size );
|
||||
psxexe_conv32( &psf_header->exe_crc );
|
||||
|
||||
logerror( "psx_exe_load: reserved_size %08x\n", psf_header->reserved_size );
|
||||
logerror( "psx_exe_load: exe_size %08x\n", psf_header->exe_size );
|
||||
logerror( "psx_exe_load: exe_crc %08x\n", psf_header->exe_crc );
|
||||
|
||||
n_compressed = psf_header->exe_size;
|
||||
p_n_compressed = p_n_file + sizeof( struct PSF_HEADER ) + psf_header->reserved_size;
|
||||
|
||||
n_crc = crc32( crc32( 0L, Z_NULL, 0 ), p_n_compressed, n_compressed );
|
||||
if( n_crc != psf_header->exe_crc )
|
||||
{
|
||||
logerror( "psx_exe_load: psf invalid crc\n" );
|
||||
return 0;
|
||||
}
|
||||
|
||||
n_uncompressed = 0x200000;
|
||||
p_n_uncompressed.resize( n_uncompressed );
|
||||
|
||||
if( uncompress( &p_n_uncompressed[0], &n_uncompressed, p_n_compressed, n_compressed ) != Z_OK )
|
||||
{
|
||||
logerror( "psx_exe_load: psf uncompress failed\n" );
|
||||
}
|
||||
else if( !load_psxexe( cpu, &p_n_uncompressed[0], n_uncompressed ) )
|
||||
{
|
||||
logerror( "psx_exe_load: psf load failed\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
n_return = 1;
|
||||
}
|
||||
}
|
||||
return n_return;
|
||||
}
|
||||
|
||||
DIRECT_UPDATE_MEMBER(psx1_state::psx_default)
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
DIRECT_UPDATE_MEMBER(psx1_state::psx_setopbase)
|
||||
{
|
||||
if( address == 0x80030000 )
|
||||
{
|
||||
m_maincpu->space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(psx1_state::psx_default), this));
|
||||
|
||||
if( load_psxexe( m_maincpu, m_exe_buffer, m_exe_size ) ||
|
||||
load_cpe( m_maincpu, m_exe_buffer, m_exe_size ) ||
|
||||
load_psf( m_maincpu, m_exe_buffer, m_exe_size ) )
|
||||
{
|
||||
/* DEBUGGER_BREAK; */
|
||||
|
||||
address = m_maincpu->state_int( PSXCPU_PC );
|
||||
m_maincpu->set_state_int( PSXCPU_DELAYR, PSXCPU_DELAYR_PC );
|
||||
m_maincpu->set_state_int( PSXCPU_DELAYV, address );
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror( "psx_exe_load: invalid exe\n" );
|
||||
}
|
||||
|
||||
m_exe_size = 0;
|
||||
global_free_array( m_exe_buffer );
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
QUICKLOAD_LOAD_MEMBER( psx1_state, psx_exe_load )
|
||||
{
|
||||
address_space &space = m_maincpu->space( AS_PROGRAM );
|
||||
|
||||
m_exe_size = 0;
|
||||
m_exe_buffer = global_alloc_array( UINT8, quickload_size );
|
||||
if( m_exe_buffer == NULL )
|
||||
{
|
||||
logerror( "psx_exe_load: out of memory\n" );
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
if( image.fread( m_exe_buffer, quickload_size ) != quickload_size )
|
||||
{
|
||||
global_free_array( m_exe_buffer );
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
m_exe_size = quickload_size;
|
||||
space.set_direct_update_handler(direct_update_delegate(FUNC(psx1_state::psx_setopbase), this));
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
void psx1_state::cd_dma_read( UINT32 *p_n_psxram, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
UINT8 *psxram = (UINT8 *) p_n_psxram;
|
||||
@ -515,9 +116,6 @@ static MACHINE_CONFIG_START( psj, psx1_state )
|
||||
MCFG_SOUND_ROUTE( 0, "lspeaker", 1.00 )
|
||||
MCFG_SOUND_ROUTE( 1, "rspeaker", 1.00 )
|
||||
|
||||
/* quickload */
|
||||
MCFG_QUICKLOAD_ADD("quickload", psx1_state, psx_exe_load, "cpe,exe,psf,psx", 0)
|
||||
|
||||
MCFG_SOFTWARE_LIST_ADD("cd_list","psx")
|
||||
|
||||
MCFG_DEVICE_MODIFY( "maincpu" )
|
||||
@ -564,9 +162,6 @@ static MACHINE_CONFIG_START( pse, psx1_state )
|
||||
MCFG_SOUND_ROUTE( 0, "lspeaker", 1.00 )
|
||||
MCFG_SOUND_ROUTE( 1, "rspeaker", 1.00 )
|
||||
|
||||
/* quickload */
|
||||
MCFG_QUICKLOAD_ADD("quickload", psx1_state, psx_exe_load, "cpe,exe,psf,psx", 0)
|
||||
|
||||
MCFG_SOFTWARE_LIST_ADD("cd_list","psx")
|
||||
|
||||
MCFG_DEVICE_MODIFY( "maincpu" )
|
||||
|
Loading…
Reference in New Issue
Block a user