psx: Remove quickload, may be handled differently later [O. Galibert]

This commit is contained in:
Olivier Galibert 2015-06-23 09:04:23 +02:00
parent 0f15126428
commit 1e32d20867

View File

@ -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" )