mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
"Why do you take this apart now? I'm trying to get us out of here and you pull both of these. Put them back together right now." --Han Solo
MDEC is now an internal device of the PlayStation CPU [smf] PlayStation DMA uses delegates so devices can be hooked up. device_t::siblingdevice() uses device list on mconfig() so it can work before the machine is constructed. moved unused console code back to mess.
This commit is contained in:
parent
59ff551237
commit
7940e28ae2
9
.gitattributes
vendored
9
.gitattributes
vendored
@ -378,6 +378,8 @@ 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.h svneol=native#text/plain
|
||||
src/emu/cpu/psx/mdec.c svneol=native#text/plain
|
||||
src/emu/cpu/psx/mdec.h svneol=native#text/plain
|
||||
src/emu/cpu/psx/psx.c svneol=native#text/plain
|
||||
src/emu/cpu/psx/psx.h svneol=native#text/plain
|
||||
src/emu/cpu/psx/psxdasm.c svneol=native#text/plain
|
||||
@ -2466,7 +2468,6 @@ src/mame/drivers/psattack.c svneol=native#text/plain
|
||||
src/mame/drivers/psikyo.c svneol=native#text/plain
|
||||
src/mame/drivers/psikyo4.c svneol=native#text/plain
|
||||
src/mame/drivers/psikyosh.c svneol=native#text/plain
|
||||
src/mame/drivers/psx.c svneol=native#text/plain
|
||||
src/mame/drivers/psychic5.c svneol=native#text/plain
|
||||
src/mame/drivers/pturn.c svneol=native#text/plain
|
||||
src/mame/drivers/puckpkmn.c svneol=native#text/plain
|
||||
@ -3884,12 +3885,6 @@ src/mame/machine/pgmprot.c svneol=native#text/plain
|
||||
src/mame/machine/pitnrun.c svneol=native#text/plain
|
||||
src/mame/machine/playch10.c svneol=native#text/plain
|
||||
src/mame/machine/psx.c svneol=native#text/plain
|
||||
src/mame/machine/psxcard.c svneol=native#text/plain
|
||||
src/mame/machine/psxcard.h svneol=native#text/plain
|
||||
src/mame/machine/psxcd.c svneol=native#text/plain
|
||||
src/mame/machine/psxcd.h svneol=native#text/plain
|
||||
src/mame/machine/psxcddrv.c svneol=native#text/plain
|
||||
src/mame/machine/psxcddrv.h svneol=native#text/plain
|
||||
src/mame/machine/pxa255.h svneol=native#text/plain
|
||||
src/mame/machine/qix.c svneol=native#text/plain
|
||||
src/mame/machine/r2crypt.c svneol=native#text/plain
|
||||
|
@ -885,7 +885,7 @@ $(CPUOBJ)/mips/mips3drc.o: $(CPUSRC)/mips/mips3drc.c \
|
||||
|
||||
ifneq ($(filter PSX,$(CPUS)),)
|
||||
OBJDIRS += $(CPUOBJ)/psx
|
||||
CPUOBJS += $(CPUOBJ)/psx/psx.o $(CPUOBJ)/psx/gte.o $(CPUOBJ)/psx/dma.o
|
||||
CPUOBJS += $(CPUOBJ)/psx/psx.o $(CPUOBJ)/psx/gte.o $(CPUOBJ)/psx/dma.o $(CPUOBJ)/psx/mdec.o
|
||||
DASMOBJS += $(CPUOBJ)/psx/psxdasm.o
|
||||
endif
|
||||
|
||||
@ -893,6 +893,7 @@ $(CPUOBJ)/psx/psx.o: $(CPUSRC)/psx/psx.c \
|
||||
$(CPUSRC)/psx/psx.h \
|
||||
$(CPUSRC)/psx/dma.h \
|
||||
$(CPUSRC)/psx/gte.h \
|
||||
$(CPUSRC)/psx/mdec.h \
|
||||
|
||||
$(CPUOBJ)/psx/gte.o: $(CPUSRC)/psx/gte.c \
|
||||
$(CPUSRC)/psx/gte.h
|
||||
@ -900,6 +901,11 @@ $(CPUOBJ)/psx/gte.o: $(CPUSRC)/psx/gte.c \
|
||||
$(CPUOBJ)/psx/dma.o: $(CPUSRC)/psx/dma.c \
|
||||
$(CPUSRC)/psx/dma.h
|
||||
|
||||
$(CPUOBJ)/psx/mdec.o: $(CPUSRC)/psx/mdec.c \
|
||||
$(CPUSRC)/psx/mdec.h
|
||||
|
||||
|
||||
|
||||
#-------------------------------------------------
|
||||
# Mitsubishi M37702 and M37710 (based on 65C816)
|
||||
#-------------------------------------------------
|
||||
|
@ -33,8 +33,8 @@ psxdma_device::psxdma_device(const machine_config &mconfig, const char *tag, dev
|
||||
{
|
||||
psx_dma_channel *dma = &channel[ index ];
|
||||
|
||||
dma->fn_read = NULL;
|
||||
dma->fn_write = NULL;
|
||||
dma->read_set = false;
|
||||
dma->write_set = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,8 +135,8 @@ void psxdma_device::dma_interrupt_update()
|
||||
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 )
|
||||
@ -171,7 +171,7 @@ void psxdma_device::dma_finished( int index )
|
||||
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 );
|
||||
dma->fn_write( n_address + 4, n_size );
|
||||
//FIXME:
|
||||
// The following conditions will cause an endless loop.
|
||||
// If stopping the transfer is correct I cannot judge
|
||||
@ -202,14 +202,16 @@ 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 )
|
||||
void psxdma_device::install_read_handler( int index, psx_dma_read_delegate p_fn_dma_read )
|
||||
{
|
||||
channel[ index ].fn_read = p_fn_dma_read;
|
||||
channel[ index ].read_set = true;
|
||||
}
|
||||
|
||||
void psxdma_device::install_write_handler( int index, psx_dma_read_handler p_fn_dma_write )
|
||||
void psxdma_device::install_write_handler( int index, psx_dma_read_delegate p_fn_dma_write )
|
||||
{
|
||||
channel[ index ].fn_write = p_fn_dma_write;
|
||||
channel[ index ].write_set = true;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( psxdma_device::write )
|
||||
@ -258,14 +260,14 @@ WRITE32_MEMBER( psxdma_device::write )
|
||||
}
|
||||
|
||||
if( dma->n_channelcontrol == 0x01000000 &&
|
||||
dma->fn_read != NULL )
|
||||
dma->read_set )
|
||||
{
|
||||
verboselog( machine(), 1, "dma %d read block %08x %08x\n", index, n_address, n_size );
|
||||
(*dma->fn_read)( machine(), n_address, n_size );
|
||||
dma->fn_read( n_address, n_size );
|
||||
dma_finished( index );
|
||||
}
|
||||
else if (dma->n_channelcontrol == 0x11000000 && // CD DMA
|
||||
dma->fn_read != NULL )
|
||||
dma->read_set )
|
||||
{
|
||||
verboselog( machine(), 1, "dma %d read block %08x %08x\n", index, n_address, n_size );
|
||||
|
||||
@ -274,14 +276,14 @@ WRITE32_MEMBER( psxdma_device::write )
|
||||
oursize = (oursize > 1) ? oursize : 1;
|
||||
oursize *= (dma->n_blockcontrol&0xffff);
|
||||
|
||||
(*dma->fn_read)( machine(), n_address, oursize );
|
||||
dma->fn_read( n_address, oursize );
|
||||
dma_finished( index );
|
||||
}
|
||||
else if( dma->n_channelcontrol == 0x01000200 &&
|
||||
dma->fn_read != NULL )
|
||||
dma->read_set )
|
||||
{
|
||||
verboselog( machine(), 1, "dma %d read block %08x %08x\n", index, n_address, n_size );
|
||||
(*dma->fn_read)( machine(), n_address, n_size );
|
||||
dma->fn_read( n_address, n_size );
|
||||
if( index == 1 )
|
||||
{
|
||||
dma_start_timer( index, 26000 );
|
||||
@ -292,31 +294,31 @@ WRITE32_MEMBER( psxdma_device::write )
|
||||
}
|
||||
}
|
||||
else if( dma->n_channelcontrol == 0x01000201 &&
|
||||
dma->fn_write != NULL )
|
||||
dma->write_set )
|
||||
{
|
||||
verboselog( machine(), 1, "dma %d write block %08x %08x\n", index, n_address, n_size );
|
||||
(*dma->fn_write)( machine(), n_address, n_size );
|
||||
dma->fn_write( n_address, n_size );
|
||||
dma_finished( index );
|
||||
}
|
||||
else if( dma->n_channelcontrol == 0x11050100 &&
|
||||
dma->fn_write != NULL )
|
||||
dma->write_set )
|
||||
{
|
||||
/* 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->fn_write( n_address, n_size );
|
||||
dma_finished( index );
|
||||
}
|
||||
else if( dma->n_channelcontrol == 0x11150100 &&
|
||||
dma->fn_write != NULL )
|
||||
dma->write_set )
|
||||
{
|
||||
/* 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->fn_write( n_address, n_size );
|
||||
dma_finished( index );
|
||||
}
|
||||
else if( dma->n_channelcontrol == 0x01000401 &&
|
||||
index == 2 &&
|
||||
dma->fn_write != NULL )
|
||||
dma->write_set )
|
||||
{
|
||||
verboselog( machine(), 1, "dma %d write linked list %08x\n",
|
||||
index, dma->n_base );
|
||||
|
@ -5,16 +5,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#if !defined(PSXDMA_H)
|
||||
#pragma once
|
||||
|
||||
#define PSXDMA_H (1)
|
||||
#ifndef __PSXDMA_H__
|
||||
#define __PSXDMA_H__
|
||||
|
||||
#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 delegate<void (UINT32, INT32)> psx_dma_read_delegate;
|
||||
typedef delegate<void (UINT32, INT32)> psx_dma_write_delegate;
|
||||
|
||||
typedef struct _psx_dma_channel psx_dma_channel;
|
||||
struct _psx_dma_channel
|
||||
@ -23,8 +24,10 @@ struct _psx_dma_channel
|
||||
UINT32 n_blockcontrol;
|
||||
UINT32 n_channelcontrol;
|
||||
emu_timer *timer;
|
||||
psx_dma_read_handler fn_read;
|
||||
psx_dma_write_handler fn_write;
|
||||
psx_dma_read_delegate fn_read;
|
||||
bool read_set;
|
||||
psx_dma_write_delegate fn_write;
|
||||
bool write_set;
|
||||
UINT32 n_ticks;
|
||||
UINT32 b_running;
|
||||
};
|
||||
@ -34,8 +37,8 @@ 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 );
|
||||
void install_read_handler( int n_channel, psx_dma_read_delegate p_fn_dma_read );
|
||||
void install_write_handler( int n_channel, psx_dma_read_delegate p_fn_dma_write );
|
||||
|
||||
WRITE32_MEMBER( write );
|
||||
READ32_MEMBER( read );
|
||||
|
570
src/emu/cpu/psx/mdec.c
Normal file
570
src/emu/cpu/psx/mdec.c
Normal file
@ -0,0 +1,570 @@
|
||||
/*
|
||||
* PlayStation Motion Decoder emulator
|
||||
*
|
||||
* Copyright 2003-2011 smf
|
||||
*
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "dma.h"
|
||||
#include "mdec.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_MDEC = &device_creator<psxmdec_device>;
|
||||
|
||||
psxmdec_device::psxmdec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, PSX_MDEC, "PSX MDEC", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void psxmdec_device::device_reset()
|
||||
{
|
||||
n_0_command = 0;
|
||||
n_0_address = 0;
|
||||
n_0_size = 0;
|
||||
n_1_command = 0;
|
||||
n_1_status = 0;
|
||||
n_offset = 0;
|
||||
n_decoded = 0;
|
||||
}
|
||||
|
||||
void psxmdec_device::device_post_load()
|
||||
{
|
||||
mdec_cos_precalc();
|
||||
}
|
||||
|
||||
void psxmdec_device::device_start()
|
||||
{
|
||||
for( int n = 0; n < 256; n++ )
|
||||
{
|
||||
p_n_clamp8[ n ] = 0;
|
||||
p_n_clamp8[ n + 256 ] = n;
|
||||
p_n_clamp8[ n + 512 ] = 255;
|
||||
|
||||
p_n_r5[ n ] = 0;
|
||||
p_n_r5[ n + 256 ] = ( n >> 3 );
|
||||
p_n_r5[ n + 512 ] = ( 255 >> 3 );
|
||||
|
||||
p_n_g5[ n ] = 0;
|
||||
p_n_g5[ n + 256 ] = ( n >> 3 ) << 5;
|
||||
p_n_g5[ n + 512 ] = ( 255 >> 3 ) << 5;
|
||||
|
||||
p_n_b5[ n ] = 0;
|
||||
p_n_b5[ n + 256 ] = ( n >> 3 ) << 10;
|
||||
p_n_b5[ n + 512 ] = ( 255 >> 3 ) << 10;
|
||||
}
|
||||
|
||||
state_save_register_global( machine(), n_0_command );
|
||||
state_save_register_global( machine(), n_0_address );
|
||||
state_save_register_global( machine(), n_0_size );
|
||||
state_save_register_global( machine(), n_1_command );
|
||||
state_save_register_global( machine(), n_1_status );
|
||||
state_save_register_global_array( machine(), p_n_quantize_y );
|
||||
state_save_register_global_array( machine(), p_n_quantize_uv );
|
||||
state_save_register_global_array( machine(), p_n_cos );
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
INLINE void psxwriteword( UINT32 *p_n_psxram, UINT32 n_address, UINT16 n_data )
|
||||
{
|
||||
*( (UINT16 *)( (UINT8 *)p_n_psxram + WORD_XOR_LE( n_address ) ) ) = n_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
INLINE UINT16 psxreadword( UINT32 *p_n_psxram, UINT32 n_address )
|
||||
{
|
||||
return *( (UINT16 *)( (UINT8 *)p_n_psxram + WORD_XOR_LE( n_address ) ) );
|
||||
}
|
||||
|
||||
static const UINT32 m_p_n_mdec_zigzag[ DCTSIZE2 ] =
|
||||
{
|
||||
0, 1, 8, 16, 9, 2, 3, 10,
|
||||
17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34,
|
||||
27, 20, 13, 6, 7, 14, 21, 28,
|
||||
35, 42, 49, 56, 57, 50, 43, 36,
|
||||
29, 22, 15, 23, 30, 37, 44, 51,
|
||||
58, 59, 52, 45, 38, 31, 39, 46,
|
||||
53, 60, 61, 54, 47, 55, 62, 63
|
||||
};
|
||||
|
||||
void psxmdec_device::mdec_cos_precalc()
|
||||
{
|
||||
UINT32 n_x;
|
||||
UINT32 n_y;
|
||||
UINT32 n_u;
|
||||
UINT32 n_v;
|
||||
INT32 *p_n_precalc = p_n_cos_precalc;
|
||||
|
||||
for( n_y = 0; n_y < 8; n_y++ )
|
||||
{
|
||||
for( n_x = 0; n_x < 8; n_x++ )
|
||||
{
|
||||
for( n_v = 0; n_v < 8; n_v++ )
|
||||
{
|
||||
for( n_u = 0; n_u < 8; n_u++ )
|
||||
{
|
||||
*( p_n_precalc++ ) =
|
||||
( ( p_n_cos[ ( n_u * 8 ) + n_x ] *
|
||||
p_n_cos[ ( n_v * 8 ) + n_y ] ) >> ( 30 - MDEC_COS_PRECALC_BITS ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void psxmdec_device::mdec_idct( INT32 *p_n_src, INT32 *p_n_dst )
|
||||
{
|
||||
INT32 *p_n_precalc = p_n_cos_precalc;
|
||||
|
||||
for( UINT32 n_yx = 0; n_yx < DCTSIZE2; n_yx++ )
|
||||
{
|
||||
INT32 p_n_z[ 8 ];
|
||||
INT32 *p_n_data = p_n_src;
|
||||
|
||||
memset( p_n_z, 0, sizeof( p_n_z ) );
|
||||
|
||||
for( UINT32 n_vu = 0; n_vu < DCTSIZE2 / 8; n_vu++ )
|
||||
{
|
||||
p_n_z[ 0 ] += p_n_data[ 0 ] * p_n_precalc[ 0 ];
|
||||
p_n_z[ 1 ] += p_n_data[ 1 ] * p_n_precalc[ 1 ];
|
||||
p_n_z[ 2 ] += p_n_data[ 2 ] * p_n_precalc[ 2 ];
|
||||
p_n_z[ 3 ] += p_n_data[ 3 ] * p_n_precalc[ 3 ];
|
||||
p_n_z[ 4 ] += p_n_data[ 4 ] * p_n_precalc[ 4 ];
|
||||
p_n_z[ 5 ] += p_n_data[ 5 ] * p_n_precalc[ 5 ];
|
||||
p_n_z[ 6 ] += p_n_data[ 6 ] * p_n_precalc[ 6 ];
|
||||
p_n_z[ 7 ] += p_n_data[ 7 ] * p_n_precalc[ 7 ];
|
||||
p_n_data += 8;
|
||||
p_n_precalc += 8;
|
||||
}
|
||||
|
||||
*( p_n_dst++ ) = ( p_n_z[ 0 ] + p_n_z[ 1 ] + p_n_z[ 2 ] + p_n_z[ 3 ] +
|
||||
p_n_z[ 4 ] + p_n_z[ 5 ] + p_n_z[ 6 ] + p_n_z[ 7 ] ) >> ( MDEC_COS_PRECALC_BITS + 2 );
|
||||
}
|
||||
}
|
||||
|
||||
INLINE UINT16 mdec_unpack_run( UINT16 n_packed )
|
||||
{
|
||||
return n_packed >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_unpack_val( UINT16 n_packed )
|
||||
{
|
||||
return ( ( (INT32)n_packed ) << 22 ) >> 22;
|
||||
}
|
||||
|
||||
UINT32 psxmdec_device::mdec_unpack( UINT32 n_address )
|
||||
{
|
||||
psx_machine *p_psx = machine().driver_data<psx_state>()->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
|
||||
UINT8 n_z;
|
||||
INT32 n_qscale;
|
||||
UINT16 n_packed;
|
||||
INT32 *p_n_block;
|
||||
INT32 p_n_unpacked[ 64 ];
|
||||
INT32 *p_n_q;
|
||||
|
||||
p_n_q = p_n_quantize_uv;
|
||||
p_n_block = m_p_n_unpacked;
|
||||
|
||||
for( UINT32 n_block = 0; n_block < 6; n_block++ )
|
||||
{
|
||||
memset( p_n_unpacked, 0, sizeof( p_n_unpacked ) );
|
||||
|
||||
if( n_block == 2 )
|
||||
{
|
||||
p_n_q = p_n_quantize_y;
|
||||
}
|
||||
n_packed = psxreadword( p_n_psxram, n_address );
|
||||
n_address += 2;
|
||||
if( n_packed == 0xfe00 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
n_qscale = mdec_unpack_run( n_packed );
|
||||
p_n_unpacked[ 0 ] = mdec_unpack_val( n_packed ) * p_n_q[ 0 ];
|
||||
|
||||
n_z = 0;
|
||||
for( ;; )
|
||||
{
|
||||
n_packed = psxreadword( p_n_psxram, n_address );
|
||||
n_address += 2;
|
||||
|
||||
if( n_packed == 0xfe00 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
n_z += mdec_unpack_run( n_packed ) + 1;
|
||||
if( n_z > 63 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
p_n_unpacked[ m_p_n_mdec_zigzag[ n_z ] ] = ( mdec_unpack_val( n_packed ) * p_n_q[ n_z ] * n_qscale ) / 8;
|
||||
}
|
||||
mdec_idct( p_n_unpacked, p_n_block );
|
||||
p_n_block += DCTSIZE2;
|
||||
}
|
||||
return n_address;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cr_to_r( INT32 n_cr )
|
||||
{
|
||||
return ( 1435 * n_cr ) >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cr_to_g( INT32 n_cr )
|
||||
{
|
||||
return ( -731 * n_cr ) >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cb_to_g( INT32 n_cb )
|
||||
{
|
||||
return ( -351 * n_cb ) >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cb_to_b( INT32 n_cb )
|
||||
{
|
||||
return ( 1814 * n_cb ) >> 10;
|
||||
}
|
||||
|
||||
UINT16 psxmdec_device::mdec_clamp_r5( INT32 n_r ) const
|
||||
{
|
||||
return p_n_r5[ n_r + 128 + 256 ];
|
||||
}
|
||||
|
||||
UINT16 psxmdec_device::mdec_clamp_g5( INT32 n_g ) const
|
||||
{
|
||||
return p_n_g5[ n_g + 128 + 256 ];
|
||||
}
|
||||
|
||||
UINT16 psxmdec_device::mdec_clamp_b5( INT32 n_b ) const
|
||||
{
|
||||
return p_n_b5[ n_b + 128 + 256 ];
|
||||
}
|
||||
|
||||
void psxmdec_device::mdec_makergb15( UINT32 n_address, INT32 n_r, INT32 n_g, INT32 n_b, INT32 *p_n_y, UINT16 n_stp )
|
||||
{
|
||||
p_n_output[ WORD_XOR_LE( n_address + 0 ) / 2 ] = n_stp |
|
||||
mdec_clamp_r5( p_n_y[ 0 ] + n_r ) |
|
||||
mdec_clamp_g5( p_n_y[ 0 ] + n_g ) |
|
||||
mdec_clamp_b5( p_n_y[ 0 ] + n_b );
|
||||
|
||||
p_n_output[ WORD_XOR_LE( n_address + 2 ) / 2 ] = n_stp |
|
||||
mdec_clamp_r5( p_n_y[ 1 ] + n_r ) |
|
||||
mdec_clamp_g5( p_n_y[ 1 ] + n_g ) |
|
||||
mdec_clamp_b5( p_n_y[ 1 ] + n_b );
|
||||
}
|
||||
|
||||
void psxmdec_device::mdec_yuv2_to_rgb15( void )
|
||||
{
|
||||
INT32 n_r;
|
||||
INT32 n_g;
|
||||
INT32 n_b;
|
||||
INT32 n_cb;
|
||||
INT32 n_cr;
|
||||
INT32 *p_n_cb;
|
||||
INT32 *p_n_cr;
|
||||
INT32 *p_n_y;
|
||||
UINT32 n_x;
|
||||
UINT32 n_y;
|
||||
UINT32 n_z;
|
||||
UINT16 n_stp;
|
||||
int n_address = 0;
|
||||
|
||||
if( ( n_0_command & ( 1L << 25 ) ) != 0 )
|
||||
{
|
||||
n_stp = 0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_stp = 0x0000;
|
||||
}
|
||||
|
||||
p_n_cr = &m_p_n_unpacked[ 0 ];
|
||||
p_n_cb = &m_p_n_unpacked[ DCTSIZE2 ];
|
||||
p_n_y = &m_p_n_unpacked[ DCTSIZE2 * 2 ];
|
||||
|
||||
for( n_z = 0; n_z < 2; n_z++ )
|
||||
{
|
||||
for( n_y = 0; n_y < 4; n_y++ )
|
||||
{
|
||||
for( n_x = 0; n_x < 4; n_x++ )
|
||||
{
|
||||
n_cr = *( p_n_cr );
|
||||
n_cb = *( p_n_cb );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb15( ( n_address + 0 ), n_r, n_g, n_b, p_n_y, n_stp );
|
||||
mdec_makergb15( ( n_address + 32 ), n_r, n_g, n_b, p_n_y + 8, n_stp );
|
||||
|
||||
n_cr = *( p_n_cr + 4 );
|
||||
n_cb = *( p_n_cb + 4 );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb15( ( n_address + 16 ), n_r, n_g, n_b, p_n_y + DCTSIZE2, n_stp );
|
||||
mdec_makergb15( ( n_address + 48 ), n_r, n_g, n_b, p_n_y + DCTSIZE2 + 8, n_stp );
|
||||
|
||||
p_n_cr++;
|
||||
p_n_cb++;
|
||||
p_n_y += 2;
|
||||
n_address += 4;
|
||||
}
|
||||
p_n_cr += 4;
|
||||
p_n_cb += 4;
|
||||
p_n_y += 8;
|
||||
n_address += 48;
|
||||
}
|
||||
p_n_y += DCTSIZE2;
|
||||
}
|
||||
n_decoded = ( 16 * 16 ) / 2;
|
||||
}
|
||||
|
||||
UINT16 psxmdec_device::mdec_clamp8( INT32 n_r ) const
|
||||
{
|
||||
return p_n_clamp8[ n_r + 128 + 256 ];
|
||||
}
|
||||
|
||||
void psxmdec_device::mdec_makergb24( UINT32 n_address, INT32 n_r, INT32 n_g, INT32 n_b, INT32 *p_n_y, UINT32 n_stp )
|
||||
{
|
||||
p_n_output[ WORD_XOR_LE( n_address + 0 ) / 2 ] = ( mdec_clamp8( p_n_y[ 0 ] + n_g ) << 8 ) | mdec_clamp8( p_n_y[ 0 ] + n_r );
|
||||
p_n_output[ WORD_XOR_LE( n_address + 2 ) / 2 ] = ( mdec_clamp8( p_n_y[ 1 ] + n_r ) << 8 ) | mdec_clamp8( p_n_y[ 0 ] + n_b );
|
||||
p_n_output[ WORD_XOR_LE( n_address + 4 ) / 2 ] = ( mdec_clamp8( p_n_y[ 1 ] + n_b ) << 8 ) | mdec_clamp8( p_n_y[ 1 ] + n_g );
|
||||
}
|
||||
|
||||
void psxmdec_device::mdec_yuv2_to_rgb24( void )
|
||||
{
|
||||
INT32 n_r;
|
||||
INT32 n_g;
|
||||
INT32 n_b;
|
||||
INT32 n_cb;
|
||||
INT32 n_cr;
|
||||
INT32 *p_n_cb;
|
||||
INT32 *p_n_cr;
|
||||
INT32 *p_n_y;
|
||||
UINT32 n_x;
|
||||
UINT32 n_y;
|
||||
UINT32 n_z;
|
||||
UINT32 n_stp;
|
||||
int n_address = 0;
|
||||
|
||||
if( ( n_0_command & ( 1L << 25 ) ) != 0 )
|
||||
{
|
||||
n_stp = 0x80008000;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_stp = 0x00000000;
|
||||
}
|
||||
|
||||
p_n_cr = &m_p_n_unpacked[ 0 ];
|
||||
p_n_cb = &m_p_n_unpacked[ DCTSIZE2 ];
|
||||
p_n_y = &m_p_n_unpacked[ DCTSIZE2 * 2 ];
|
||||
|
||||
for( n_z = 0; n_z < 2; n_z++ )
|
||||
{
|
||||
for( n_y = 0; n_y < 4; n_y++ )
|
||||
{
|
||||
for( n_x = 0; n_x < 4; n_x++ )
|
||||
{
|
||||
n_cr = *( p_n_cr );
|
||||
n_cb = *( p_n_cb );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb24( ( n_address + 0 ), n_r, n_g, n_b, p_n_y, n_stp );
|
||||
mdec_makergb24( ( n_address + 48 ), n_r, n_g, n_b, p_n_y + 8, n_stp );
|
||||
|
||||
n_cr = *( p_n_cr + 4 );
|
||||
n_cb = *( p_n_cb + 4 );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb24( ( n_address + 24 ), n_r, n_g, n_b, p_n_y + DCTSIZE2, n_stp );
|
||||
mdec_makergb24( ( n_address + 72 ), n_r, n_g, n_b, p_n_y + DCTSIZE2 + 8, n_stp );
|
||||
|
||||
p_n_cr++;
|
||||
p_n_cb++;
|
||||
p_n_y += 2;
|
||||
n_address += 6;
|
||||
}
|
||||
p_n_cr += 4;
|
||||
p_n_cb += 4;
|
||||
p_n_y += 8;
|
||||
n_address += 72;
|
||||
}
|
||||
p_n_y += DCTSIZE2;
|
||||
}
|
||||
n_decoded = ( 24 * 16 ) / 2;
|
||||
}
|
||||
|
||||
void psxmdec_device::dma_write( UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psx_machine *p_psx = machine().driver_data<psx_state>()->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
int n_index;
|
||||
|
||||
verboselog( machine(), 2, "mdec0_write( %08x, %08x )\n", n_address, n_size );
|
||||
|
||||
switch( n_0_command >> 28 )
|
||||
{
|
||||
case 0x3:
|
||||
verboselog( machine(), 1, "mdec decode %08x %08x %08x\n", n_0_command, n_address, n_size );
|
||||
n_0_address = n_address;
|
||||
n_0_size = n_size * 4;
|
||||
n_1_status |= ( 1L << 29 );
|
||||
break;
|
||||
case 0x4:
|
||||
verboselog( machine(), 1, "mdec quantize table %08x %08x %08x\n", n_0_command, n_address, n_size );
|
||||
n_index = 0;
|
||||
while( n_size > 0 )
|
||||
{
|
||||
if( n_index < DCTSIZE2 )
|
||||
{
|
||||
p_n_quantize_y[ n_index + 0 ] = ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xff;
|
||||
p_n_quantize_y[ n_index + 1 ] = ( p_n_psxram[ n_address / 4 ] >> 8 ) & 0xff;
|
||||
p_n_quantize_y[ n_index + 2 ] = ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xff;
|
||||
p_n_quantize_y[ n_index + 3 ] = ( p_n_psxram[ n_address / 4 ] >> 24 ) & 0xff;
|
||||
}
|
||||
else if( n_index < DCTSIZE2 * 2 )
|
||||
{
|
||||
p_n_quantize_uv[ n_index + 0 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xff;
|
||||
p_n_quantize_uv[ n_index + 1 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 8 ) & 0xff;
|
||||
p_n_quantize_uv[ n_index + 2 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xff;
|
||||
p_n_quantize_uv[ n_index + 3 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 24 ) & 0xff;
|
||||
}
|
||||
n_index += 4;
|
||||
n_address += 4;
|
||||
n_size--;
|
||||
}
|
||||
break;
|
||||
case 0x6:
|
||||
verboselog( machine(), 1, "mdec cosine table %08x %08x %08x\n", n_0_command, n_address, n_size );
|
||||
n_index = 0;
|
||||
while( n_size > 0 )
|
||||
{
|
||||
p_n_cos[ n_index + 0 ] = (INT16)( ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xffff );
|
||||
p_n_cos[ n_index + 1 ] = (INT16)( ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xffff );
|
||||
n_index += 2;
|
||||
n_address += 4;
|
||||
n_size--;
|
||||
}
|
||||
mdec_cos_precalc();
|
||||
break;
|
||||
default:
|
||||
verboselog( machine(), 0, "mdec unknown command %08x %08x %08x\n", n_0_command, n_address, n_size );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void psxmdec_device::dma_read( UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psx_machine *p_psx = machine().driver_data<psx_state>()->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
UINT32 n_this;
|
||||
UINT32 n_nextaddress;
|
||||
|
||||
verboselog( machine(), 2, "mdec1_read( %08x, %08x )\n", n_address, n_size );
|
||||
if( ( n_0_command & ( 1L << 29 ) ) != 0 && n_0_size != 0 )
|
||||
{
|
||||
while( n_size > 0 )
|
||||
{
|
||||
if( n_decoded == 0 )
|
||||
{
|
||||
if( (int)n_0_size <= 0 )
|
||||
{
|
||||
mame_printf_debug( "ran out of data %08x\n", n_size );
|
||||
n_0_size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
n_nextaddress = mdec_unpack( n_0_address );
|
||||
n_0_size -= n_nextaddress - n_0_address;
|
||||
n_0_address = n_nextaddress;
|
||||
|
||||
if( ( n_0_command & ( 1L << 27 ) ) != 0 )
|
||||
{
|
||||
mdec_yuv2_to_rgb15();
|
||||
}
|
||||
else
|
||||
{
|
||||
mdec_yuv2_to_rgb24();
|
||||
}
|
||||
n_offset = 0;
|
||||
}
|
||||
|
||||
n_this = n_decoded;
|
||||
if( n_this > n_size )
|
||||
{
|
||||
n_this = n_size;
|
||||
}
|
||||
n_decoded -= n_this;
|
||||
|
||||
memcpy( (UINT8 *)p_n_psxram + n_address, (UINT8 *)p_n_output + n_offset, n_this * 4 );
|
||||
n_offset += n_this * 4;
|
||||
n_address += n_this * 4;
|
||||
n_size -= n_this;
|
||||
}
|
||||
|
||||
if( (int)n_0_size < 0 )
|
||||
{
|
||||
mame_printf_debug( "ran out of data %d\n", n_0_size );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mame_printf_debug( "mdec1_read no conversion :%08x:%08x:\n", n_0_command, n_0_size );
|
||||
}
|
||||
n_1_status &= ~( 1L << 29 );
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( psxmdec_device::write )
|
||||
{
|
||||
switch( offset )
|
||||
{
|
||||
case 0:
|
||||
verboselog( machine(), 2, "mdec 0 command %08x\n", data );
|
||||
n_0_command = data;
|
||||
break;
|
||||
case 1:
|
||||
verboselog( machine(), 2, "mdec 1 command %08x\n", data );
|
||||
n_1_command = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER( psxmdec_device::read )
|
||||
{
|
||||
switch( offset )
|
||||
{
|
||||
case 0:
|
||||
verboselog( machine(), 2, "mdec 0 status %08x\n", 0 );
|
||||
return 0;
|
||||
case 1:
|
||||
verboselog( machine(), 2, "mdec 1 status %08x\n", n_1_status );
|
||||
return n_1_status;
|
||||
}
|
||||
return 0;
|
||||
}
|
74
src/emu/cpu/psx/mdec.h
Normal file
74
src/emu/cpu/psx/mdec.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* PlayStation DMA emulator
|
||||
*
|
||||
* Copyright 2003-2011 smf
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __PSXMDEC_H__
|
||||
#define __PSXMDEC_H__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
extern const device_type PSX_MDEC;
|
||||
|
||||
#define DCTSIZE ( 8 )
|
||||
#define DCTSIZE2 ( DCTSIZE * DCTSIZE )
|
||||
|
||||
#define MDEC_COS_PRECALC_BITS ( 21 )
|
||||
|
||||
class psxmdec_device : public device_t
|
||||
{
|
||||
public:
|
||||
psxmdec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
WRITE32_MEMBER( write );
|
||||
READ32_MEMBER( read );
|
||||
|
||||
void dma_write( UINT32 n_address, INT32 n_size );
|
||||
void dma_read( UINT32 n_address, INT32 n_size );
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_post_load();
|
||||
|
||||
private:
|
||||
void mdec_cos_precalc();
|
||||
void mdec_idct( INT32 *p_n_src, INT32 *p_n_dst );
|
||||
UINT32 mdec_unpack( UINT32 n_address );
|
||||
UINT16 mdec_clamp_r5( INT32 n_r ) const;
|
||||
UINT16 mdec_clamp_g5( INT32 n_g ) const;
|
||||
UINT16 mdec_clamp_b5( INT32 n_b ) const;
|
||||
UINT16 mdec_clamp8( INT32 n_r ) const;
|
||||
void mdec_yuv2_to_rgb15( void );
|
||||
void mdec_yuv2_to_rgb24( void );
|
||||
void mdec_makergb15( UINT32 n_address, INT32 n_r, INT32 n_g, INT32 n_b, INT32 *p_n_y, UINT16 n_stp );
|
||||
void mdec_makergb24( UINT32 n_address, INT32 n_r, INT32 n_g, INT32 n_b, INT32 *p_n_y, UINT32 n_stp );
|
||||
|
||||
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 m_p_n_unpacked[ DCTSIZE2 * 6 * 2 ];
|
||||
};
|
||||
|
||||
#endif
|
@ -66,6 +66,7 @@
|
||||
#include "debugger.h"
|
||||
#include "psx.h"
|
||||
#include "dma.h"
|
||||
#include "mdec.h"
|
||||
#include "includes/psx.h"
|
||||
#include "sound/spu.h"
|
||||
|
||||
@ -1533,7 +1534,7 @@ static ADDRESS_MAP_START( psxcpu_internal_map, AS_PROGRAM, 32, psxcpu_device )
|
||||
AM_RANGE(0x1f801080, 0x1f8010ff) AM_DEVREADWRITE( "dma", psxdma_device, read, write )
|
||||
AM_RANGE(0x1f801100, 0x1f80112f) AM_READWRITE_LEGACY( psx_counter_r, psx_counter_w )
|
||||
AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE_LEGACY( psx_gpu_r, psx_gpu_w )
|
||||
AM_RANGE(0x1f801820, 0x1f801827) AM_READWRITE_LEGACY( psx_mdec_r, psx_mdec_w )
|
||||
AM_RANGE(0x1f801820, 0x1f801827) AM_DEVREADWRITE( "mdec", psxmdec_device, read, write )
|
||||
AM_RANGE(0x1f801c00, 0x1f801dff) AM_READWRITE16_LEGACY( spu_r, spu_w, 0xffffffff )
|
||||
AM_RANGE(0x1f802020, 0x1f802033) AM_RAM /* ?? */
|
||||
AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP
|
||||
@ -1557,8 +1558,9 @@ static ADDRESS_MAP_START( cxd8661r_internal_map, AS_PROGRAM, 32, psxcpu_device )
|
||||
AM_RANGE(0x1f801080, 0x1f8010ff) AM_DEVREADWRITE( "dma", psxdma_device, read, write )
|
||||
AM_RANGE(0x1f801100, 0x1f80112f) AM_READWRITE_LEGACY( psx_counter_r, psx_counter_w )
|
||||
AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE_LEGACY( psx_gpu_r, psx_gpu_w )
|
||||
AM_RANGE(0x1f801820, 0x1f801827) AM_READWRITE_LEGACY( psx_mdec_r, psx_mdec_w )
|
||||
AM_RANGE(0x1f801820, 0x1f801827) AM_DEVREADWRITE( "mdec", psxmdec_device, read, write )
|
||||
AM_RANGE(0x1f801c00, 0x1f801dff) AM_READWRITE16_LEGACY( spu_r, spu_w, 0xffffffff )
|
||||
AM_RANGE(0x1f802020, 0x1f802033) AM_RAM /* ?? */
|
||||
AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP
|
||||
AM_RANGE(0x20000000, 0x7fffffff) AM_READWRITE( berr_r, berr_w )
|
||||
AM_RANGE(0x81000000, 0x9effffff) AM_READWRITE( berr_r, berr_w )
|
||||
@ -3145,18 +3147,34 @@ 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 )
|
||||
static psxcpu_device *getcpu( device_t &device, const char *cputag )
|
||||
{
|
||||
(downcast<psxdma_device*>(device.subdevice("dma")))->install_read_handler( channel, handler );
|
||||
if( strcmp( cputag, DEVICE_SELF ) == 0 )
|
||||
{
|
||||
return downcast<psxcpu_device *>( &device );
|
||||
}
|
||||
|
||||
return downcast<psxcpu_device *>( device.siblingdevice( cputag ) );
|
||||
}
|
||||
|
||||
void psxcpu_device::install_dma_write_handler( device_t &device, int channel, psx_dma_write_handler handler )
|
||||
void psxcpu_device::install_dma_read_handler( device_t &device, const char *cputag, int channel, psx_dma_read_delegate handler )
|
||||
{
|
||||
(downcast<psxdma_device*>(device.subdevice("dma")))->install_write_handler( channel, handler );
|
||||
psxdma_device *dma = downcast<psxdma_device *>( getcpu( device, cputag )->subdevice("dma") );
|
||||
dma->install_read_handler( channel, handler );
|
||||
}
|
||||
|
||||
void psxcpu_device::install_dma_write_handler( device_t &device, const char *cputag, int channel, psx_dma_write_delegate handler )
|
||||
{
|
||||
psxdma_device *dma = downcast<psxdma_device *>( getcpu( device, cputag )->subdevice("dma") );
|
||||
dma->install_write_handler( channel, handler );
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_FRAGMENT( psx )
|
||||
MCFG_DEVICE_ADD("dma", PSX_DMA, 0)
|
||||
|
||||
MCFG_DEVICE_ADD("mdec", PSX_MDEC, 0)
|
||||
MCFG_PSX_DMA_CHANNEL_WRITE( DEVICE_SELF, 0, psx_dma_write_delegate( FUNC( psxmdec_device::dma_write ), (psxmdec_device *) device ) )
|
||||
MCFG_PSX_DMA_CHANNEL_READ( DEVICE_SELF, 1, psx_dma_read_delegate( FUNC( psxmdec_device::dma_read ), (psxmdec_device *) device ) )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -103,11 +103,11 @@ enum
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_PSX_DMA_CHANNEL_READ( channel, handler ) \
|
||||
psxcpu_device::install_dma_read_handler( *device, channel, handler ); \
|
||||
#define MCFG_PSX_DMA_CHANNEL_READ( cputag, channel, handler ) \
|
||||
psxcpu_device::install_dma_read_handler( *owner, cputag, channel, handler ); \
|
||||
|
||||
#define MCFG_PSX_DMA_CHANNEL_WRITE( channel, handler ) \
|
||||
psxcpu_device::install_dma_write_handler( *device, channel, handler ); \
|
||||
#define MCFG_PSX_DMA_CHANNEL_WRITE( cputag, channel, handler ) \
|
||||
psxcpu_device::install_dma_write_handler( *owner, cputag, channel, handler ); \
|
||||
|
||||
|
||||
|
||||
@ -129,8 +129,8 @@ public:
|
||||
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 );
|
||||
static void install_dma_read_handler( device_t &device, const char *cputag, int channel, psx_dma_read_delegate handler );
|
||||
static void install_dma_write_handler( device_t &device, const char *cputag, int channel, psx_dma_write_delegate handler );
|
||||
|
||||
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);
|
||||
|
@ -452,7 +452,7 @@ device_t *device_t::siblingdevice(const char *_tag) const
|
||||
|
||||
// build a fully-qualified name
|
||||
astring tempstring;
|
||||
return machine().device(siblingtag(tempstring, _tag));
|
||||
return mconfig().devicelist().find((const char *)siblingtag(tempstring, _tag));
|
||||
}
|
||||
|
||||
|
||||
|
@ -3090,18 +3090,16 @@ void spu_device::flush_cdda(const unsigned int sector)
|
||||
|
||||
// MAME I/O stuff. This can get cleaner when machine/psx.c does.
|
||||
|
||||
static void spu_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void spu_dma_read( spu_device *spu, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
spu_device *spu = machine.device<spu_device>("spu");
|
||||
UINT8 *psxram = (UINT8 *)memory_get_shared(machine, "share1");
|
||||
UINT8 *psxram = (UINT8 *)memory_get_shared(spu->machine(), "share1");
|
||||
|
||||
spu->start_dma(psxram + n_address, false, n_size*4);
|
||||
}
|
||||
|
||||
static void spu_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void spu_dma_write( spu_device *spu, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
spu_device *spu = machine.device<spu_device>("spu");
|
||||
UINT8 *psxram = (UINT8 *)memory_get_shared(machine, "share1");
|
||||
UINT8 *psxram = (UINT8 *)memory_get_shared(spu->machine(), "share1");
|
||||
|
||||
// printf("SPU DMA write from %x, size %x\n", n_address, n_size);
|
||||
|
||||
@ -3119,8 +3117,8 @@ READ16_HANDLER( spu_r )
|
||||
|
||||
if (!spu->installed_dma_hooks)
|
||||
{
|
||||
psx_dma_install_read_handler(space->machine(), 4, spu_dma_read);
|
||||
psx_dma_install_write_handler(space->machine(), 4, spu_dma_write);
|
||||
psx_dma_install_read_handler( space->machine(), 4, psx_dma_read_delegate( FUNC( spu_dma_read ), spu ) );
|
||||
psx_dma_install_write_handler( space->machine(), 4, psx_dma_write_delegate( FUNC( spu_dma_write ), spu ) );
|
||||
spu->installed_dma_hooks = true;
|
||||
}
|
||||
|
||||
@ -3138,8 +3136,8 @@ WRITE16_HANDLER( spu_w )
|
||||
|
||||
if (!spu->installed_dma_hooks)
|
||||
{
|
||||
psx_dma_install_read_handler(space->machine(), 4, spu_dma_read);
|
||||
psx_dma_install_write_handler(space->machine(), 4, spu_dma_write);
|
||||
psx_dma_install_read_handler( space->machine(), 4, psx_dma_read_delegate( FUNC( spu_dma_read ), spu ) );
|
||||
psx_dma_install_write_handler( space->machine(), 4, psx_dma_write_delegate( FUNC( spu_dma_write ), spu ) );
|
||||
spu->installed_dma_hooks = true;
|
||||
}
|
||||
|
||||
|
@ -270,9 +270,8 @@ static const k054539_interface k054539_config =
|
||||
|
||||
/* SCSI */
|
||||
|
||||
static void scsi_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void scsi_dma_read( konamigq_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
konamigq_state *state = machine.driver_data<konamigq_state>();
|
||||
UINT32 *p_n_psxram = state->m_p_n_psxram;
|
||||
UINT8 *sector_buffer = state->m_sector_buffer;
|
||||
int i;
|
||||
@ -306,7 +305,7 @@ static void scsi_dma_read( running_machine &machine, UINT32 n_address, INT32 n_s
|
||||
}
|
||||
}
|
||||
|
||||
static void scsi_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void scsi_dma_write( konamigq_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
}
|
||||
|
||||
@ -365,11 +364,12 @@ static MACHINE_RESET( konamigq )
|
||||
static MACHINE_CONFIG_START( konamigq, konamigq_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", CXD8530BQ, 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( konamigq_map )
|
||||
MCFG_CPU_VBLANK_INT("screen", psx_vblank)
|
||||
|
||||
MCFG_PSX_DMA_CHANNEL_READ( "maincpu", 5, psx_dma_read_delegate( FUNC( scsi_dma_read ), (konamigq_state *) owner ) )
|
||||
MCFG_PSX_DMA_CHANNEL_WRITE( "maincpu", 5, psx_dma_write_delegate( FUNC( scsi_dma_write ), (konamigq_state *) owner ) )
|
||||
|
||||
MCFG_CPU_ADD( "soundcpu", M68000, 8000000 )
|
||||
MCFG_CPU_PROGRAM_MAP( konamigq_sound_map)
|
||||
MCFG_CPU_PERIODIC_INT( irq2_line_hold, 480 )
|
||||
|
@ -183,9 +183,8 @@ ADDRESS_MAP_END
|
||||
|
||||
/* SCSI */
|
||||
|
||||
static void scsi_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void scsi_dma_read( konamigv_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
konamigv_state *state = machine.driver_data<konamigv_state>();
|
||||
UINT32 *p_n_psxram = state->m_p_n_psxram;
|
||||
UINT8 *sector_buffer = state->m_sector_buffer;
|
||||
int i;
|
||||
@ -229,9 +228,8 @@ static void scsi_dma_read( running_machine &machine, UINT32 n_address, INT32 n_s
|
||||
}
|
||||
}
|
||||
|
||||
static void scsi_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void scsi_dma_write( konamigv_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
konamigv_state *state = machine.driver_data<konamigv_state>();
|
||||
UINT32 *p_n_psxram = state->m_p_n_psxram;
|
||||
UINT8 *sector_buffer = state->m_sector_buffer;
|
||||
int i;
|
||||
@ -329,11 +327,12 @@ static void spu_irq(device_t *device, UINT32 data)
|
||||
static MACHINE_CONFIG_START( konamigv, konamigv_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", CXD8530BQ, 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( konamigv_map )
|
||||
MCFG_CPU_VBLANK_INT("screen", psx_vblank)
|
||||
|
||||
MCFG_PSX_DMA_CHANNEL_READ( "maincpu", 5, psx_dma_read_delegate( FUNC( scsi_dma_read ), (konamigv_state *) owner ) )
|
||||
MCFG_PSX_DMA_CHANNEL_WRITE( "maincpu", 5, psx_dma_write_delegate( FUNC( scsi_dma_write ), (konamigv_state *) owner ) )
|
||||
|
||||
MCFG_MACHINE_START( konamigv )
|
||||
MCFG_MACHINE_RESET( konamigv )
|
||||
|
||||
|
@ -1072,25 +1072,23 @@ static WRITE32_HANDLER( atapi_reset_w )
|
||||
}
|
||||
}
|
||||
|
||||
static void cdrom_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void cdrom_dma_read( ksys573_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
verboselog( machine, 2, "cdrom_dma_read( %08x, %08x )\n", n_address, n_size );
|
||||
verboselog( state->machine(), 2, "cdrom_dma_read( %08x, %08x )\n", n_address, n_size );
|
||||
// mame_printf_debug("DMA read: address %08x size %08x\n", n_address, n_size);
|
||||
}
|
||||
|
||||
static void cdrom_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void cdrom_dma_write( ksys573_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
ksys573_state *state = machine.driver_data<ksys573_state>();
|
||||
|
||||
verboselog( machine, 2, "cdrom_dma_write( %08x, %08x )\n", n_address, n_size );
|
||||
verboselog( state->machine(), 2, "cdrom_dma_write( %08x, %08x )\n", n_address, n_size );
|
||||
// mame_printf_debug("DMA write: address %08x size %08x\n", n_address, n_size);
|
||||
|
||||
state->m_atapi_xferbase = n_address;
|
||||
|
||||
verboselog( machine, 2, "atapi_xfer_end: %d %d\n", state->m_atapi_xferlen, state->m_atapi_xfermod );
|
||||
verboselog( state->machine(), 2, "atapi_xfer_end: %d %d\n", state->m_atapi_xferlen, state->m_atapi_xfermod );
|
||||
|
||||
// set a transfer complete timer (Note: CYCLES_PER_SECTOR can't be lower than 2000 or the BIOS ends up "out of order")
|
||||
state->m_atapi_timer->adjust(machine.device<cpu_device>("maincpu")->cycles_to_attotime((ATAPI_CYCLES_PER_SECTOR * (state->m_atapi_xferlen/2048))));
|
||||
state->m_atapi_timer->adjust(state->machine().device<cpu_device>("maincpu")->cycles_to_attotime((ATAPI_CYCLES_PER_SECTOR * (state->m_atapi_xferlen/2048))));
|
||||
}
|
||||
|
||||
static WRITE32_HANDLER( security_w )
|
||||
@ -2961,11 +2959,12 @@ static const adc083x_interface konami573_adc_interface = {
|
||||
static MACHINE_CONFIG_START( konami573, ksys573_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", CXD8530CQ, XTAL_67_7376MHz )
|
||||
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_PSX_DMA_CHANNEL_READ( "maincpu", 5, psx_dma_read_delegate( FUNC( cdrom_dma_read ), (ksys573_state *) owner ) )
|
||||
MCFG_PSX_DMA_CHANNEL_WRITE( "maincpu", 5, psx_dma_write_delegate( FUNC( cdrom_dma_write ), (ksys573_state *) owner ) )
|
||||
|
||||
MCFG_MACHINE_RESET( konami573 )
|
||||
|
||||
// onboard flash
|
||||
|
@ -1147,9 +1147,8 @@ static WRITE32_HANDLER( dmaoffset_w )
|
||||
verboselog( space->machine(), 1, "dmaoffset_w( %08x, %08x, %08x ) %08x\n", offset, data, mem_mask, state->m_n_dmaoffset );
|
||||
}
|
||||
|
||||
static void namcos12_rom_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void namcos12_rom_read( namcos12_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
namcos12_state *state = machine.driver_data<namcos12_state>();
|
||||
const char *n_region;
|
||||
int n_offset;
|
||||
|
||||
@ -1163,26 +1162,26 @@ static void namcos12_rom_read( running_machine &machine, UINT32 n_address, INT32
|
||||
{
|
||||
n_region = "user2";
|
||||
n_offset = state->m_n_tektagdmaoffset & 0x7fffffff;
|
||||
verboselog( machine, 1, "namcos12_rom_read( %08x, %08x ) tektagt %08x\n", n_address, n_size, n_offset );
|
||||
verboselog( state->machine(), 1, "namcos12_rom_read( %08x, %08x ) tektagt %08x\n", n_address, n_size, n_offset );
|
||||
}
|
||||
else if( ( state->m_n_dmaoffset >= 0x80000000 ) || ( state->m_n_dmabias == 0x1f300000 ) )
|
||||
{
|
||||
n_region = "user1";
|
||||
n_offset = state->m_n_dmaoffset & 0x003fffff;
|
||||
verboselog( machine, 1, "namcos12_rom_read( %08x, %08x ) boot %08x\n", n_address, n_size, n_offset );
|
||||
verboselog( state->machine(), 1, "namcos12_rom_read( %08x, %08x ) boot %08x\n", n_address, n_size, n_offset );
|
||||
}
|
||||
else
|
||||
{
|
||||
n_region = "user2";
|
||||
n_offset = state->m_n_dmaoffset & 0x7fffffff;
|
||||
verboselog( machine, 1, "namcos12_rom_read( %08x, %08x ) game %08x\n", n_address, n_size, n_offset );
|
||||
verboselog( state->machine(), 1, "namcos12_rom_read( %08x, %08x ) game %08x\n", n_address, n_size, n_offset );
|
||||
}
|
||||
|
||||
source = (UINT16 *) machine.region( n_region )->base();
|
||||
n_romleft = ( machine.region( n_region )->bytes() - n_offset ) / 4;
|
||||
source = (UINT16 *) state->machine().region( n_region )->base();
|
||||
n_romleft = ( state->machine().region( n_region )->bytes() - n_offset ) / 4;
|
||||
if( n_size > n_romleft )
|
||||
{
|
||||
verboselog( machine, 1, "namcos12_rom_read dma truncated %d to %d passed end of rom\n", n_size, n_romleft );
|
||||
verboselog( state->machine(), 1, "namcos12_rom_read dma truncated %d to %d passed end of rom\n", n_size, n_romleft );
|
||||
n_size = n_romleft;
|
||||
}
|
||||
|
||||
@ -1190,7 +1189,7 @@ static void namcos12_rom_read( running_machine &machine, UINT32 n_address, INT32
|
||||
n_ramleft = ( state->m_n_psxramsize - n_address ) / 4;
|
||||
if( n_size > n_ramleft )
|
||||
{
|
||||
verboselog( machine, 1, "namcos12_rom_read dma truncated %d to %d passed end of ram\n", n_size, n_ramleft );
|
||||
verboselog( state->machine(), 1, "namcos12_rom_read dma truncated %d to %d passed end of ram\n", n_size, n_ramleft );
|
||||
n_size = n_ramleft;
|
||||
}
|
||||
|
||||
@ -1640,11 +1639,11 @@ static DRIVER_INIT( ghlpanic )
|
||||
static MACHINE_CONFIG_START( coh700, namcos12_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", CXD8661R, XTAL_100MHz )
|
||||
MCFG_PSX_DMA_CHANNEL_READ( 5, namcos12_rom_read )
|
||||
|
||||
MCFG_CPU_PROGRAM_MAP( namcos12_map)
|
||||
MCFG_CPU_VBLANK_INT("screen", psx_vblank)
|
||||
|
||||
MCFG_PSX_DMA_CHANNEL_READ( "maincpu", 5, psx_dma_read_delegate( FUNC( namcos12_rom_read ), (namcos12_state *) owner ) )
|
||||
|
||||
MCFG_CPU_ADD("sub", H83002, 16737350 )
|
||||
MCFG_CPU_PROGRAM_MAP( s12h8rwmap)
|
||||
MCFG_CPU_IO_MAP( s12h8iomap)
|
||||
|
@ -1,964 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
Sony Playstaion
|
||||
===============
|
||||
Preliminary driver by smf
|
||||
Additional development by pSXAuthor and R. Belmont
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/psx/psx.h"
|
||||
#include "imagedev/snapquik.h"
|
||||
#include "imagedev/chd_cd.h"
|
||||
#include "includes/psx.h"
|
||||
#include "sound/spu.h"
|
||||
#include "debugger.h"
|
||||
#include "zlib.h"
|
||||
#include "machine/psxcd.h"
|
||||
#include "machine/psxcard.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UINT8 n_shiftin;
|
||||
UINT8 n_shiftout;
|
||||
int n_bits;
|
||||
int n_state;
|
||||
int n_byte;
|
||||
int b_lastclock;
|
||||
int b_ack;
|
||||
} pad_t;
|
||||
|
||||
|
||||
class psx1_state : public psx_state
|
||||
{
|
||||
public:
|
||||
psx1_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: psx_state(mconfig, type, tag) { }
|
||||
|
||||
UINT8 *m_exe_buffer;
|
||||
int m_exe_size;
|
||||
pad_t m_pad[ 2 ];
|
||||
int m_cd_param_p;
|
||||
int m_cd_result_p;
|
||||
int m_cd_result_c;
|
||||
int m_cd_result_ready;
|
||||
int m_cd_reset;
|
||||
UINT8 m_cd_stat;
|
||||
UINT8 m_cd_io_status;
|
||||
UINT8 m_cd_param[8];
|
||||
UINT8 m_cd_result[8];
|
||||
};
|
||||
|
||||
|
||||
#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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void 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 );
|
||||
}
|
||||
|
||||
static int load_psxexe( device_t *cpu, unsigned char *p_n_file, int n_len )
|
||||
{
|
||||
psx_state *state = cpu->machine().driver_data<psx_state>();
|
||||
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 )
|
||||
{
|
||||
UINT8 *p_ram;
|
||||
UINT8 *p_psxexe;
|
||||
UINT32 n_stack;
|
||||
UINT32 n_ram;
|
||||
UINT32 n_address;
|
||||
UINT32 n_size;
|
||||
|
||||
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 );
|
||||
|
||||
p_ram = (UINT8 *)state->m_p_n_psxram;
|
||||
n_ram = state->m_n_psxramsize;
|
||||
|
||||
p_psxexe = p_n_file + sizeof( struct PSXEXE_HEADER );
|
||||
|
||||
n_address = psxexe_header->t_addr;
|
||||
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_reg( cpu, PSXCPU_PC, psxexe_header->pc0 );
|
||||
cpu_set_reg( cpu, PSXCPU_R28, psxexe_header->gp0 );
|
||||
n_stack = psxexe_header->s_addr + psxexe_header->s_size;
|
||||
if( n_stack != 0 )
|
||||
{
|
||||
cpu_set_reg( cpu, PSXCPU_R29, n_stack );
|
||||
cpu_set_reg( cpu, PSXCPU_R30, n_stack );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpe_set_register( device_t *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_reg( cpu, PSXCPU_R0 + ( n_reg / 4 ), n_value );
|
||||
}
|
||||
else if( n_reg == 0x80 )
|
||||
{
|
||||
logerror( "psx_exe_load: lo %08x\n", n_value );
|
||||
cpu_set_reg( cpu, PSXCPU_LO, n_value );
|
||||
}
|
||||
else if( n_reg == 0x84 )
|
||||
{
|
||||
logerror( "psx_exe_load: hi %08x\n", n_value );
|
||||
cpu_set_reg( cpu, PSXCPU_HI, n_value );
|
||||
}
|
||||
else if( n_reg == 0x88 )
|
||||
{
|
||||
logerror( "psx_exe_load: sr %08x\n", n_value );
|
||||
cpu_set_reg( cpu, PSXCPU_CP0R12, n_value );
|
||||
}
|
||||
else if( n_reg == 0x8c )
|
||||
{
|
||||
logerror( "psx_exe_load: cause %08x\n", n_value );
|
||||
cpu_set_reg( cpu, PSXCPU_CP0R13, n_value );
|
||||
}
|
||||
else if( n_reg == 0x90 )
|
||||
{
|
||||
logerror( "psx_exe_load: pc %08x\n", n_value );
|
||||
cpu_set_reg( cpu, PSXCPU_PC, n_value );
|
||||
}
|
||||
else if( n_reg == 0x94 )
|
||||
{
|
||||
logerror( "psx_exe_load: prid %08x\n", n_value );
|
||||
cpu_set_reg( cpu, PSXCPU_CP0R15, n_value );
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror( "psx_exe_load: invalid register %04x/%08x\n", n_reg, n_value );
|
||||
}
|
||||
}
|
||||
|
||||
static int load_cpe( device_t *cpu, unsigned char *p_n_file, int n_len )
|
||||
{
|
||||
psx_state *state = cpu->machine().driver_data<psx_state>();
|
||||
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 = (UINT8 *)state->m_p_n_psxram;
|
||||
UINT32 n_ram = state->m_n_psxramsize;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int load_psf( device_t *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;
|
||||
unsigned char *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 = (unsigned char *)malloc( n_uncompressed );
|
||||
|
||||
if( uncompress( p_n_uncompressed, &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, n_uncompressed ) )
|
||||
{
|
||||
logerror( "psx_exe_load: psf load failed\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
n_return = 1;
|
||||
}
|
||||
|
||||
free( p_n_uncompressed );
|
||||
}
|
||||
return n_return;
|
||||
}
|
||||
|
||||
DIRECT_UPDATE_HANDLER( psx_default )
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
DIRECT_UPDATE_HANDLER( psx_setopbase )
|
||||
{
|
||||
psx1_state *state = machine.driver_data<psx1_state>();
|
||||
if( address == 0x80030000 )
|
||||
{
|
||||
device_t *cpu = machine.device("maincpu");
|
||||
|
||||
machine.device("maincpu")->memory().space(AS_PROGRAM)->set_direct_update_handler(direct_update_delegate(FUNC(psx_default), &machine));
|
||||
|
||||
if( load_psxexe( cpu, state->m_exe_buffer, state->m_exe_size ) ||
|
||||
load_cpe( cpu, state->m_exe_buffer, state->m_exe_size ) ||
|
||||
load_psf( cpu, state->m_exe_buffer, state->m_exe_size ) )
|
||||
{
|
||||
/* DEBUGGER_BREAK; */
|
||||
|
||||
address = cpu_get_reg( cpu, PSXCPU_PC );
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror( "psx_exe_load: invalid exe\n" );
|
||||
}
|
||||
|
||||
state->m_exe_size = 0;
|
||||
free( state->m_exe_buffer );
|
||||
}
|
||||
return address;
|
||||
}
|
||||
|
||||
static QUICKLOAD_LOAD( psx_exe_load )
|
||||
{
|
||||
psx1_state *state = image.device().machine().driver_data<psx1_state>();
|
||||
address_space *space = image.device().machine().device( "maincpu")->memory().space( AS_PROGRAM );
|
||||
|
||||
state->m_exe_size = 0;
|
||||
state->m_exe_buffer = (UINT8*)malloc( quickload_size );
|
||||
if( state->m_exe_buffer == NULL )
|
||||
{
|
||||
logerror( "psx_exe_load: out of memory\n" );
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
if( image.fread( state->m_exe_buffer, quickload_size ) != quickload_size )
|
||||
{
|
||||
free( state->m_exe_buffer );
|
||||
return IMAGE_INIT_FAIL;
|
||||
}
|
||||
state->m_exe_size = quickload_size;
|
||||
space->set_direct_update_handler(direct_update_delegate(FUNC(psx_setopbase), &image.device().machine()));
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
/* PAD emulation */
|
||||
|
||||
#define PAD_STATE_IDLE ( 0 )
|
||||
#define PAD_STATE_LISTEN ( 1 )
|
||||
#define PAD_STATE_ACTIVE ( 2 )
|
||||
#define PAD_STATE_READ ( 3 )
|
||||
#define PAD_STATE_UNLISTEN ( 4 )
|
||||
#define PAD_STATE_MEMCARD ( 5 )
|
||||
|
||||
#define PAD_TYPE_STANDARD ( 4 )
|
||||
#define PAD_BYTES_STANDARD ( 2 )
|
||||
|
||||
#define PAD_CMD_START ( 0x01 )
|
||||
#define PAD_CMD_READ ( 0x42 ) /* B */
|
||||
|
||||
#define PAD_DATA_OK ( 0x5a ) /* Z */
|
||||
#define PAD_DATA_IDLE ( 0xff )
|
||||
|
||||
static TIMER_CALLBACK(psx_pad_ack)
|
||||
{
|
||||
psx1_state *state = machine.driver_data<psx1_state>();
|
||||
int n_port = param;
|
||||
pad_t *pad = &state->m_pad[ n_port ];
|
||||
|
||||
if( pad->n_state != PAD_STATE_IDLE )
|
||||
{
|
||||
psx_sio_input( machine, 0, PSX_SIO_IN_DSR, pad->b_ack * PSX_SIO_IN_DSR );
|
||||
if( !pad->b_ack )
|
||||
{
|
||||
pad->b_ack = 1;
|
||||
machine.scheduler().timer_set(attotime::from_usec( 2 ), FUNC(psx_pad_ack) , n_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void psx_pad( running_machine &machine, int n_port, int n_data )
|
||||
{
|
||||
psx1_state *state = machine.driver_data<psx1_state>();
|
||||
pad_t *pad = &state->m_pad[ n_port ];
|
||||
int b_sel;
|
||||
int b_clock;
|
||||
int b_data;
|
||||
int b_ack;
|
||||
int b_ready;
|
||||
static const char *const portnames[] = { "IN0", "IN1", "IN2", "IN3" };
|
||||
psxcard_device *psxcard = NULL;
|
||||
|
||||
if (n_port == 0)
|
||||
{
|
||||
psxcard = machine.device<psxcard_device>("card1");
|
||||
}
|
||||
else
|
||||
{
|
||||
psxcard = machine.device<psxcard_device>("card2");
|
||||
}
|
||||
|
||||
b_sel = ( n_data & PSX_SIO_OUT_DTR ) / PSX_SIO_OUT_DTR;
|
||||
b_clock = ( n_data & PSX_SIO_OUT_CLOCK ) / PSX_SIO_OUT_CLOCK;
|
||||
b_data = ( n_data & PSX_SIO_OUT_DATA ) / PSX_SIO_OUT_DATA;
|
||||
b_ready = 0;
|
||||
b_ack = 0;
|
||||
|
||||
if( b_sel )
|
||||
{
|
||||
pad->n_state = PAD_STATE_IDLE;
|
||||
}
|
||||
|
||||
switch( pad->n_state )
|
||||
{
|
||||
case PAD_STATE_LISTEN:
|
||||
case PAD_STATE_ACTIVE:
|
||||
case PAD_STATE_READ:
|
||||
case PAD_STATE_MEMCARD:
|
||||
if( pad->b_lastclock && !b_clock )
|
||||
{
|
||||
psx_sio_input( machine, 0, PSX_SIO_IN_DATA, ( pad->n_shiftout & 1 ) * PSX_SIO_IN_DATA );
|
||||
pad->n_shiftout >>= 1;
|
||||
}
|
||||
if( !pad->b_lastclock && b_clock )
|
||||
{
|
||||
pad->n_shiftin >>= 1;
|
||||
pad->n_shiftin |= b_data << 7;
|
||||
pad->n_bits++;
|
||||
|
||||
if( pad->n_bits == 8 )
|
||||
{
|
||||
pad->n_bits = 0;
|
||||
b_ready = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
pad->b_lastclock = b_clock;
|
||||
|
||||
switch( pad->n_state )
|
||||
{
|
||||
case PAD_STATE_IDLE:
|
||||
if( !b_sel )
|
||||
{
|
||||
pad->n_state = PAD_STATE_LISTEN;
|
||||
pad->n_shiftout = PAD_DATA_IDLE;
|
||||
pad->n_bits = 0;
|
||||
}
|
||||
break;
|
||||
case PAD_STATE_LISTEN:
|
||||
if( b_ready )
|
||||
{
|
||||
if( pad->n_shiftin == PAD_CMD_START )
|
||||
{
|
||||
pad->n_state = PAD_STATE_ACTIVE;
|
||||
pad->n_shiftout = ( PAD_TYPE_STANDARD << 4 ) | ( PAD_BYTES_STANDARD >> 1 );
|
||||
b_ack = 1;
|
||||
}
|
||||
else if( psxcard->transfer(pad->n_shiftin, &pad->n_shiftout) )
|
||||
{
|
||||
pad->n_state = PAD_STATE_MEMCARD;
|
||||
b_ack = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pad->n_state = PAD_STATE_UNLISTEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PAD_STATE_MEMCARD:
|
||||
if( b_ready )
|
||||
{
|
||||
if( psxcard->transfer(pad->n_shiftin, &pad->n_shiftout) )
|
||||
{
|
||||
b_ack = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
b_ack = 0;
|
||||
pad->n_state = PAD_STATE_IDLE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PAD_STATE_ACTIVE:
|
||||
if( b_ready )
|
||||
{
|
||||
if( pad->n_shiftin == PAD_CMD_READ )
|
||||
{
|
||||
pad->n_state = PAD_STATE_READ;
|
||||
pad->n_shiftout = PAD_DATA_OK;
|
||||
pad->n_byte = 0;
|
||||
b_ack = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pad->n_state = PAD_STATE_UNLISTEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PAD_STATE_READ:
|
||||
if( b_ready )
|
||||
{
|
||||
if( pad->n_byte < PAD_BYTES_STANDARD )
|
||||
{
|
||||
pad->n_shiftout = input_port_read(machine, portnames[pad->n_byte + ( n_port * PAD_BYTES_STANDARD )]);
|
||||
pad->n_byte++;
|
||||
b_ack = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
pad->n_state = PAD_STATE_LISTEN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( b_ack )
|
||||
{
|
||||
pad->b_ack = 0;
|
||||
machine.scheduler().timer_set(attotime::from_usec( 10 ), FUNC(psx_pad_ack), n_port);
|
||||
}
|
||||
}
|
||||
|
||||
static void psx_sio0( running_machine &machine, int n_data )
|
||||
{
|
||||
/* todo: raise data & ack when nothing is driving it low */
|
||||
psx_pad( machine, 0, n_data );
|
||||
psx_pad( machine, 1, n_data ^ PSX_SIO_OUT_DTR );
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
static void cd_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psxcd_device *psxcd = machine.device<psxcd_device>("psxcd");
|
||||
UINT8 *psxram = (UINT8 *)memory_get_shared(machine, "share1");
|
||||
|
||||
psxcd->start_dma(psxram + n_address, n_size*4);
|
||||
}
|
||||
|
||||
static void cd_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
printf("cd_dma_write?!: addr %x, size %x\n", n_address, n_size);
|
||||
}
|
||||
|
||||
static READ8_HANDLER( psx_cd_r )
|
||||
{
|
||||
psxcd_device *psxcd = space->machine().device<psxcd_device>(PSXCD_TAG);
|
||||
|
||||
return psxcd->read_byte(offset);
|
||||
}
|
||||
|
||||
static WRITE8_HANDLER( psx_cd_w )
|
||||
{
|
||||
psxcd_device *psxcd = space->machine().device<psxcd_device>(PSXCD_TAG);
|
||||
|
||||
psxcd->write_byte(offset, data);
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( psx_map, AS_PROGRAM, 32 )
|
||||
AM_RANGE(0x00000000, 0x001fffff) AM_RAM AM_SHARE("share1") /* ram */
|
||||
AM_RANGE(0x1f801800, 0x1f801803) AM_READWRITE8(psx_cd_r, psx_cd_w, 0xffffffff)
|
||||
AM_RANGE(0x1fc00000, 0x1fc7ffff) AM_ROM AM_SHARE("share2") AM_REGION("user1", 0) /* bios */
|
||||
AM_RANGE(0x80000000, 0x801fffff) AM_RAM AM_SHARE("share1") /* ram mirror */
|
||||
AM_RANGE(0x80600000, 0x807fffff) AM_RAM AM_SHARE("share1") /* ram mirror */
|
||||
AM_RANGE(0x9fc00000, 0x9fc7ffff) AM_ROM AM_SHARE("share2") /* bios mirror */
|
||||
AM_RANGE(0xa0000000, 0xa01fffff) AM_RAM AM_SHARE("share1") /* ram mirror */
|
||||
AM_RANGE(0xbfc00000, 0xbfc7ffff) AM_ROM AM_SHARE("share2") /* bios mirror */
|
||||
AM_RANGE(0xfffe0130, 0xfffe0133) AM_WRITENOP
|
||||
ADDRESS_MAP_END
|
||||
|
||||
|
||||
static MACHINE_RESET( psx )
|
||||
{
|
||||
psx_machine_init(machine);
|
||||
psx_sio_install_handler( machine, 0, psx_sio0 );
|
||||
|
||||
psx_dma_install_read_handler(machine, 3, cd_dma_read);
|
||||
psx_dma_install_write_handler(machine, 3, cd_dma_write);
|
||||
}
|
||||
|
||||
static DRIVER_INIT( psx )
|
||||
{
|
||||
psx_driver_init(machine);
|
||||
}
|
||||
|
||||
static INPUT_PORTS_START( psx )
|
||||
PORT_START("IN0")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1)
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT ) PORT_PLAYER(1)
|
||||
|
||||
PORT_START("IN1")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Square")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Cross")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Circle")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Triangle")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_NAME("P1 R1")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_NAME("P1 L1")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(1) PORT_NAME("P1 R2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(1) PORT_NAME("P1 L2")
|
||||
|
||||
PORT_START("IN2")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT ) PORT_PLAYER(2)
|
||||
|
||||
PORT_START("IN3")
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Square")
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Cross")
|
||||
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Circle")
|
||||
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Triangle")
|
||||
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_NAME("P2 R1")
|
||||
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2) PORT_NAME("P2 L1")
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(2) PORT_NAME("P2 R2")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_PLAYER(2) PORT_NAME("P2 L2")
|
||||
INPUT_PORTS_END
|
||||
|
||||
static void spu_irq(device_t *device, UINT32 data)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
psx_irq_set(device->machine(), 1<<9);
|
||||
}
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_START( psxntsc, psx1_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", CXD8530AQ, XTAL_67_7376MHz )
|
||||
MCFG_CPU_PROGRAM_MAP( psx_map)
|
||||
MCFG_CPU_VBLANK_INT("screen", psx_vblank)
|
||||
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE( 60 )
|
||||
MCFG_SCREEN_VBLANK_TIME(0)
|
||||
|
||||
MCFG_MACHINE_RESET( psx )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
||||
MCFG_SCREEN_SIZE( 1024, 512 )
|
||||
MCFG_SCREEN_VISIBLE_AREA( 0, 639, 0, 479 )
|
||||
MCFG_SCREEN_UPDATE( psx )
|
||||
|
||||
MCFG_PALETTE_LENGTH( 65536 )
|
||||
|
||||
MCFG_PALETTE_INIT( psx )
|
||||
MCFG_VIDEO_START( psx_type2 )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
MCFG_SPU_ADD( "spu", XTAL_67_7376MHz/2, &spu_irq )
|
||||
MCFG_SOUND_ROUTE( 0, "lspeaker", 1.00 )
|
||||
MCFG_SOUND_ROUTE( 1, "rspeaker", 1.00 )
|
||||
|
||||
/* quickload */
|
||||
MCFG_QUICKLOAD_ADD("quickload", psx_exe_load, "cpe,exe,psf,psx", 0)
|
||||
|
||||
MCFG_CDROM_ADD("cdrom")
|
||||
MCFG_PSXCD_ADD("cdrom")
|
||||
MCFG_PSXCARD_ADD("card1")
|
||||
MCFG_PSXCARD_ADD("card2")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
static MACHINE_CONFIG_START( psxpal, psx1_state )
|
||||
/* basic machine hardware */
|
||||
MCFG_CPU_ADD( "maincpu", CXD8530AQ, XTAL_67_7376MHz )
|
||||
MCFG_CPU_PROGRAM_MAP( psx_map)
|
||||
MCFG_CPU_VBLANK_INT("screen", psx_vblank)
|
||||
|
||||
MCFG_SCREEN_ADD("screen", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE( 50 )
|
||||
MCFG_SCREEN_VBLANK_TIME(0)
|
||||
|
||||
MCFG_MACHINE_RESET( psx )
|
||||
|
||||
/* video hardware */
|
||||
MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
|
||||
MCFG_SCREEN_SIZE( 1024, 512 )
|
||||
MCFG_SCREEN_VISIBLE_AREA( 0, 639, 0, 511 )
|
||||
MCFG_SCREEN_UPDATE( psx )
|
||||
MCFG_PALETTE_LENGTH( 65536 )
|
||||
|
||||
MCFG_PALETTE_INIT( psx )
|
||||
MCFG_VIDEO_START( psx_type2 )
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
MCFG_SPU_ADD( "spu", XTAL_67_7376MHz/2, &spu_irq )
|
||||
MCFG_SOUND_ROUTE( 0, "lspeaker", 1.00 )
|
||||
MCFG_SOUND_ROUTE( 1, "rspeaker", 1.00 )
|
||||
|
||||
/* quickload */
|
||||
MCFG_QUICKLOAD_ADD("quickload", psx_exe_load, "cpe,exe,psf,psx", 0)
|
||||
|
||||
MCFG_CDROM_ADD("cdrom")
|
||||
MCFG_PSXCD_ADD("cdrom")
|
||||
MCFG_PSXCARD_ADD("card1")
|
||||
MCFG_PSXCARD_ADD("card2")
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
ROM_START( psj )
|
||||
ROM_REGION32_LE( 0x080000, "user1", 0 )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "1.0J", "SCPH-1000/DTL-H1000" ) // 22091994
|
||||
ROMX_LOAD( "ps-10j.bin", 0x0000000, 0x080000, CRC(3b601fc8) SHA1(343883a7b555646da8cee54aadd2795b6e7dd070), ROM_BIOS(1) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 1, "1.1J", "SCPH-3000/DTL-H1000H (Version 1.1 01/22/95)" ) // 22091994
|
||||
ROMX_LOAD( "ps-11j.bin", 0x0000000, 0x080000, CRC(3539def6) SHA1(b06f4a861f74270be819aa2a07db8d0563a7cc4e), ROM_BIOS(2) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 2, "2.1J", "SCPH-3500 (Version 2.1 07/17/95 J)" ) // 22091994
|
||||
ROMX_LOAD( "ps-21j.bin", 0x0000000, 0x080000, CRC(bc190209) SHA1(e38466a4ba8005fba7e9e3c7b9efeba7205bee3f), ROM_BIOS(3) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 3, "2.2J", "SCPH-5000/DTL-H1200 (Version 2.2 12/04/95 J)" ) // 04121995
|
||||
/* ROMX_LOAD( "ps-22j.bad", 0x0000000, 0x080000, BAD_DUMP CRC(8c93a399) SHA1(e340db2696274dda5fdc25e434a914db71e8b02b), ROM_BIOS(4) ) */
|
||||
ROMX_LOAD( "ps-22j.bin", 0x0000000, 0x080000, CRC(24fc7e17) SHA1(ffa7f9a7fb19d773a0c3985a541c8e5623d2c30d), ROM_BIOS(4) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 4, "2.2D", "DTL-H1100 (Version 2.2 03/06/96 D)" ) // 04121995
|
||||
ROMX_LOAD( "ps-22d.bin", 0x0000000, 0x080000, CRC(decb22f5) SHA1(73107d468fc7cb1d2c5b18b269715dd889ecef06), ROM_BIOS(5) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 5, "3.0J", "SCPH-5500 (Version 3.0 09/09/96 J)" ) // 04121995
|
||||
ROMX_LOAD( "ps-30j.bin", 0x0000000, 0x080000, CRC(ff3eeb8c) SHA1(b05def971d8ec59f346f2d9ac21fb742e3eb6917), ROM_BIOS(6) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 6, "4.0J", "SCPH-7000/SCPH-9000 (Version 4.0 08/18/97 J)" ) // 29051997
|
||||
ROMX_LOAD( "ps-40j.bin", 0x0000000, 0x080000, CRC(ec541cd0) SHA1(77b10118d21ac7ffa9b35f9c4fd814da240eb3e9), ROM_BIOS(7) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 7, "4.3J", "SCPH-100 (Version 4.3 03/11/00 J)" ) // 04121995
|
||||
ROMX_LOAD( "psone-43j.bin", 0x0000000, 0x080000, CRC(f2af798b) SHA1(339a48f4fcf63e10b5b867b8c93cfd40945faf6c), ROM_BIOS(8) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( psu )
|
||||
ROM_REGION32_LE( 0x080000, "user1", 0 )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "2.0A", "DTL-H1001 (Version 2.0 05/07/95 A)" ) // 22091994
|
||||
ROMX_LOAD( "ps-20a.bin", 0x0000000, 0x080000, CRC(55847d8c) SHA1(649895efd79d14790eabb362e94eb0622093dfb9), ROM_BIOS(1) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 1, "2.1A", "DTL-H1101 (Version 2.1 07/17/95 A)" ) // 22091994
|
||||
ROMX_LOAD( "ps-21a.bin", 0x0000000, 0x080000, CRC(aff00f2f) SHA1(ca7af30b50d9756cbd764640126c454cff658479), ROM_BIOS(2) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 2, "2.2A", "SCPH-1001/DTL-H1201/DTL-H3001 (Version 2.2 12/04/95 A)" ) // 04121995
|
||||
ROMX_LOAD( "ps-22a.bin", 0x0000000, 0x080000, CRC(37157331) SHA1(10155d8d6e6e832d6ea66db9bc098321fb5e8ebf), ROM_BIOS(3) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 3, "3.0A", "SCPH-5501/SCPH-7003 (Version 3.0 11/18/96 A)" ) // 04121995
|
||||
ROMX_LOAD( "ps-30a.bin", 0x0000000, 0x080000, CRC(8d8cb7e4) SHA1(0555c6fae8906f3f09baf5988f00e55f88e9f30b), ROM_BIOS(4) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 4, "4.1A", "SCPH-7001/SCPH-7501/SCPH-7503/SCPH-9001 (Version 4.1 12/16/97 A)" ) // 04121995
|
||||
ROMX_LOAD( "ps-41a.bin", 0x0000000, 0x080000, CRC(502224b6) SHA1(14df4f6c1e367ce097c11deae21566b4fe5647a9), ROM_BIOS(5) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 5, "4.5A", "SCPH-101 (Version 4.5 05/25/00 A)" ) // 04121995
|
||||
ROMX_LOAD( "psone-45a.bin", 0x0000000, 0x080000, CRC(171bdcec) SHA1(dcffe16bd90a723499ad46c641424981338d8378), ROM_BIOS(6) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( pse )
|
||||
ROM_REGION32_LE( 0x080000, "user1", 0 )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "2.0E", "DTL-H1002/SCPH-1002 (Version 2.0 05/10/95 E)" ) // 22091994
|
||||
ROMX_LOAD( "ps-20e.bin", 0x0000000, 0x080000, CRC(9bb87c4b) SHA1(20b98f3d80f11cbf5a7bfd0779b0e63760ecc62c), ROM_BIOS(1) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 1, "2.1E", "SCPH-1002/DTL-H1102 (Version 2.1 07/17/95 E)" ) // 22091994
|
||||
ROMX_LOAD( "ps-21e.bin", 0x0000000, 0x080000, CRC(86c30531) SHA1(76cf6b1b2a7c571a6ad07f2bac0db6cd8f71e2cc), ROM_BIOS(2) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 2, "2.2E", "SCPH-1002/DTL-H1202/DTL-H3002 (Version 2.2 12/04/95 E)" ) // 04121995
|
||||
ROMX_LOAD( "ps-22e.bin", 0x0000000, 0x080000, CRC(1e26792f) SHA1(b6a11579caef3875504fcf3831b8e3922746df2c), ROM_BIOS(3) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 3, "3.0E", "SCPH-5502/SCPH-5552 (Version 3.0 01/06/97 E)" ) // 04121995
|
||||
/* ROMX_LOAD( "ps-30e.bad", 0x0000000, 0x080000, BAD_DUMP CRC(4d9e7c86) SHA1(f8de9325fc36fcfa4b29124d291c9251094f2e54), ROM_BIOS(4) ) */
|
||||
ROMX_LOAD( "ps-30e.bin", 0x0000000, 0x080000, CRC(d786f0b9) SHA1(f6bc2d1f5eb6593de7d089c425ac681d6fffd3f0), ROM_BIOS(4) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 4, "4.1E", "SCPH-7002/SCPH-7502/SCPH-9002 (Version 4.1 12/16/97 E)" ) // 04121995
|
||||
ROMX_LOAD( "ps-41e.bin", 0x0000000, 0x080000, CRC(318178bf) SHA1(8d5de56a79954f29e9006929ba3fed9b6a418c1d), ROM_BIOS(5) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 5, "4.4E", "SCPH-102 (Version 4.4 03/24/00 E)" ) // 04121995
|
||||
ROMX_LOAD( "psone-44e.bin", 0x0000000, 0x080000, CRC(0bad7ea9) SHA1(beb0ac693c0dc26daf5665b3314db81480fa5c7c), ROM_BIOS(6) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 6, "4.5E", "SCPH-102 (Version 4.5 05/25/00 E)" ) // 04121995
|
||||
ROMX_LOAD( "psone-45e.bin", 0x0000000, 0x080000, CRC(76b880e5) SHA1(dbc7339e5d85827c095764fc077b41f78fd2ecae), ROM_BIOS(7) )
|
||||
ROM_END
|
||||
|
||||
ROM_START( psa )
|
||||
ROM_REGION32_LE( 0x080000, "user1", 0 )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "3.0A", "SCPH-5501/SCPH-7003 (Version 3.0 11/18/96 A)" ) // 04121995
|
||||
ROMX_LOAD( "ps-30a.bin", 0x0000000, 0x080000, CRC(8d8cb7e4) SHA1(0555c6fae8906f3f09baf5988f00e55f88e9f30b), ROM_BIOS(1) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 1, "4.1A", "SCPH-7001/SCPH-7501/SCPH-7503/SCPH-9001 (Version 4.1 12/16/97 A)" ) // 04121995
|
||||
ROMX_LOAD( "ps-41a.bin", 0x0000000, 0x080000, CRC(502224b6) SHA1(14df4f6c1e367ce097c11deae21566b4fe5647a9), ROM_BIOS(2) )
|
||||
ROM_END
|
||||
|
||||
/*
|
||||
The version number & release date is stored in ascii text at the end of every bios, except for scph1000.
|
||||
There is also a BCD encoded date at offset 0x100, but this is set to 22091994 for versions prior to 2.2
|
||||
and 04121995 for all versions from 2.2 ( except Version 4.0J which is 29051997 ).
|
||||
|
||||
Consoles not dumped:
|
||||
|
||||
DTL-H1001H
|
||||
DTL-H3000
|
||||
SCPH-5001
|
||||
SCPH-5002
|
||||
SCPH-5003
|
||||
SCPH-5503
|
||||
SCPH-7500
|
||||
SCPH-9003
|
||||
SCPH-103
|
||||
|
||||
Holes in version numbers:
|
||||
|
||||
Version 2.0 J
|
||||
Version 4.1 J
|
||||
Version 4.2 J
|
||||
Version 4.4 J
|
||||
Version 4.5 J
|
||||
Version 4.0 A
|
||||
Version 4.2 A
|
||||
Version 4.3 A
|
||||
Version 4.4 A
|
||||
Version 4.0 E
|
||||
Version 4.2 E
|
||||
Version 4.3 E
|
||||
|
||||
*/
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
|
||||
CONS( 1994, psj, 0, 0, psxntsc, psx, psx, "Sony Computer Entertainment Inc", "Sony PlayStation (Japan)", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS )
|
||||
CONS( 1995, pse, psj, 0, psxpal, psx, psx, "Sony Computer Entertainment Inc", "Sony PlayStation (Europe)", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS )
|
||||
CONS( 1995, psu, psj, 0, psxntsc, psx, psx, "Sony Computer Entertainment Inc", "Sony PlayStation (USA)", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS )
|
||||
CONS( 1995, psa, psj, 0, psxntsc, psx, psx, "Sony Computer Entertainment Inc", "Sony PlayStation (Asia-Pacific)", GAME_NOT_WORKING | GAME_IMPERFECT_SOUND | GAME_IMPERFECT_GRAPHICS )
|
@ -745,9 +745,8 @@ ADDRESS_MAP_END
|
||||
|
||||
/* SCSI */
|
||||
|
||||
static void scsi_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void scsi_dma_read( twinkle_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
twinkle_state *state = machine.driver_data<twinkle_state>();
|
||||
UINT32 *p_n_psxram = state->m_p_n_psxram;
|
||||
int i;
|
||||
int n_this;
|
||||
@ -790,9 +789,8 @@ static void scsi_dma_read( running_machine &machine, UINT32 n_address, INT32 n_s
|
||||
}
|
||||
}
|
||||
|
||||
static void scsi_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void scsi_dma_write( twinkle_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
twinkle_state *state = machine.driver_data<twinkle_state>();
|
||||
UINT32 *p_n_psxram = state->m_p_n_psxram;
|
||||
int i;
|
||||
int n_this;
|
||||
@ -880,11 +878,12 @@ static const i2cmem_interface i2cmem_interface =
|
||||
static MACHINE_CONFIG_START( twinkle, twinkle_state )
|
||||
/* basic machine hardware */
|
||||
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_VBLANK_INT( "mainscreen", psx_vblank )
|
||||
|
||||
MCFG_PSX_DMA_CHANNEL_READ( "maincpu", 5, psx_dma_read_delegate( FUNC( scsi_dma_read ), (twinkle_state *) owner ) )
|
||||
MCFG_PSX_DMA_CHANNEL_WRITE( "maincpu", 5, psx_dma_write_delegate( FUNC( scsi_dma_write ), (twinkle_state *) owner ) )
|
||||
|
||||
MCFG_CPU_ADD("audiocpu", M68000, 32000000/2) /* 16.000 MHz */
|
||||
MCFG_CPU_PROGRAM_MAP( sound_map )
|
||||
|
||||
|
@ -1447,11 +1447,10 @@ static void atpsx_interrupt(device_t *device, int state)
|
||||
}
|
||||
}
|
||||
|
||||
static void atpsx_dma_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void atpsx_dma_read( zn_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
zn_state *state = machine.driver_data<zn_state>();
|
||||
UINT32 *p_n_psxram = state->m_p_n_psxram;
|
||||
device_t *ide = machine.device("ide");
|
||||
device_t *ide = state->machine().device("ide");
|
||||
|
||||
logerror("DMA read: %d bytes (%d words) to %08x\n", n_size<<2, n_size, n_address);
|
||||
|
||||
@ -1472,7 +1471,7 @@ static void atpsx_dma_read( running_machine &machine, UINT32 n_address, INT32 n_
|
||||
}
|
||||
}
|
||||
|
||||
static void atpsx_dma_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void atpsx_dma_write( zn_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
logerror("DMA write from %08x for %d bytes\n", n_address, n_size<<2);
|
||||
}
|
||||
@ -1496,8 +1495,8 @@ static MACHINE_RESET( coh1000w )
|
||||
zn_machine_init(machine);
|
||||
|
||||
devtag_reset(machine, "ide");
|
||||
psx_dma_install_read_handler(machine, 5, atpsx_dma_read);
|
||||
psx_dma_install_write_handler(machine, 5, atpsx_dma_write);
|
||||
psx_dma_install_read_handler( machine, 5, psx_dma_read_delegate( FUNC( atpsx_dma_read ), machine.driver_data<zn_state>() ) );
|
||||
psx_dma_install_write_handler( machine, 5, psx_dma_write_delegate( FUNC( atpsx_dma_write ), machine.driver_data<zn_state>() ) );
|
||||
}
|
||||
|
||||
static MACHINE_CONFIG_DERIVED( coh1000w, zn1_2mb_vram )
|
||||
|
@ -39,9 +39,6 @@
|
||||
|
||||
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 )
|
||||
@ -59,8 +56,6 @@ typedef void ( *psx_sio_handler )( running_machine &, int );
|
||||
#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
|
||||
{
|
||||
@ -93,32 +88,6 @@ struct _psx_sio
|
||||
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;
|
||||
struct _psx_machine
|
||||
{
|
||||
@ -135,8 +104,6 @@ struct _psx_machine
|
||||
psx_root root[3];
|
||||
|
||||
psx_sio sio[2];
|
||||
|
||||
psx_mdec mdec;
|
||||
};
|
||||
|
||||
typedef struct _psx_gpu psx_gpu;
|
||||
@ -176,10 +143,8 @@ READ32_HANDLER( psx_com_delay_r );
|
||||
WRITE32_HANDLER( psx_irq_w );
|
||||
READ32_HANDLER( psx_irq_r );
|
||||
extern void psx_irq_set( running_machine &, UINT32 );
|
||||
extern void psx_dma_install_read_handler( running_machine &, int, psx_dma_read_handler );
|
||||
extern void psx_dma_install_write_handler( running_machine &, int, psx_dma_read_handler );
|
||||
WRITE32_HANDLER( psx_dma_w );
|
||||
READ32_HANDLER( psx_dma_r );
|
||||
extern void psx_dma_install_read_handler( running_machine &, int, psx_dma_read_delegate );
|
||||
extern void psx_dma_install_write_handler( running_machine &, int, psx_dma_read_delegate );
|
||||
WRITE32_HANDLER( psx_counter_w );
|
||||
READ32_HANDLER( psx_counter_r );
|
||||
WRITE32_HANDLER( psx_sio_w );
|
||||
@ -187,8 +152,6 @@ READ32_HANDLER( psx_sio_r );
|
||||
extern void psx_sio_install_handler( running_machine &, int, psx_sio_handler );
|
||||
extern void psx_sio_input( running_machine &, int, int, int );
|
||||
|
||||
WRITE32_HANDLER( psx_mdec_w );
|
||||
READ32_HANDLER( psx_mdec_r );
|
||||
extern void psx_machine_init( running_machine &machine );
|
||||
extern void psx_driver_init( running_machine &machine );
|
||||
|
||||
|
@ -25,18 +25,6 @@ INLINE void ATTR_PRINTF(3,4) verboselog( psx_machine *p_psx, int n_level, const
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNUSED_FUNCTION
|
||||
INLINE void psxwriteword( UINT32 *p_n_psxram, UINT32 n_address, UINT16 n_data )
|
||||
{
|
||||
*( (UINT16 *)( (UINT8 *)p_n_psxram + WORD_XOR_LE( n_address ) ) ) = n_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
INLINE UINT16 psxreadword( UINT32 *p_n_psxram, UINT32 n_address )
|
||||
{
|
||||
return *( (UINT16 *)( (UINT8 *)p_n_psxram + WORD_XOR_LE( n_address ) ) );
|
||||
}
|
||||
|
||||
WRITE32_HANDLER( psx_com_delay_w )
|
||||
{
|
||||
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
|
||||
@ -125,15 +113,14 @@ void psx_irq_set( running_machine &machine, UINT32 data )
|
||||
|
||||
/* DMA */
|
||||
|
||||
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_delegate p_fn_dma_read )
|
||||
{
|
||||
psxcpu_device::install_dma_read_handler( *machine.device("maincpu"), n_channel, p_fn_dma_read );
|
||||
psxcpu_device::install_dma_read_handler( *machine.device("maincpu"), "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_delegate p_fn_dma_write )
|
||||
{
|
||||
psxcpu_device::install_dma_write_handler( *machine.device("maincpu"), n_channel, p_fn_dma_write );
|
||||
psxcpu_device::install_dma_write_handler( *machine.device("maincpu"), "maincpu", n_channel, p_fn_dma_write );
|
||||
}
|
||||
|
||||
/* Root Counters */
|
||||
@ -618,514 +605,20 @@ void psx_sio_install_handler( running_machine &machine, int n_port, psx_sio_hand
|
||||
p_psx->sio[ n_port ].fn_handler = p_f_sio_handler;
|
||||
}
|
||||
|
||||
/* MDEC */
|
||||
|
||||
static const UINT32 m_p_n_mdec_zigzag[ DCTSIZE2 ] =
|
||||
static void gpu_read( psx_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
0, 1, 8, 16, 9, 2, 3, 10,
|
||||
17, 24, 32, 25, 18, 11, 4, 5,
|
||||
12, 19, 26, 33, 40, 48, 41, 34,
|
||||
27, 20, 13, 6, 7, 14, 21, 28,
|
||||
35, 42, 49, 56, 57, 50, 43, 36,
|
||||
29, 22, 15, 23, 30, 37, 44, 51,
|
||||
58, 59, 52, 45, 38, 31, 39, 46,
|
||||
53, 60, 61, 54, 47, 55, 62, 63
|
||||
};
|
||||
|
||||
static void mdec_cos_precalc( psx_machine *p_psx )
|
||||
{
|
||||
psx_mdec *p_mdec = &p_psx->mdec;
|
||||
UINT32 n_x;
|
||||
UINT32 n_y;
|
||||
UINT32 n_u;
|
||||
UINT32 n_v;
|
||||
INT32 *p_n_precalc;
|
||||
|
||||
p_n_precalc = p_mdec->p_n_cos_precalc;
|
||||
|
||||
for( n_y = 0; n_y < 8; n_y++ )
|
||||
{
|
||||
for( n_x = 0; n_x < 8; n_x++ )
|
||||
{
|
||||
for( n_v = 0; n_v < 8; n_v++ )
|
||||
{
|
||||
for( n_u = 0; n_u < 8; n_u++ )
|
||||
{
|
||||
*( p_n_precalc++ ) =
|
||||
( ( p_mdec->p_n_cos[ ( n_u * 8 ) + n_x ] *
|
||||
p_mdec->p_n_cos[ ( n_v * 8 ) + n_y ] ) >> ( 30 - MDEC_COS_PRECALC_BITS ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void mdec_idct( psx_machine *p_psx, INT32 *p_n_src, INT32 *p_n_dst )
|
||||
{
|
||||
psx_mdec *p_mdec = &p_psx->mdec;
|
||||
UINT32 n_yx;
|
||||
UINT32 n_vu;
|
||||
INT32 p_n_z[ 8 ];
|
||||
INT32 *p_n_data;
|
||||
INT32 *p_n_precalc;
|
||||
|
||||
p_n_precalc = p_mdec->p_n_cos_precalc;
|
||||
|
||||
for( n_yx = 0; n_yx < DCTSIZE2; n_yx++ )
|
||||
{
|
||||
p_n_data = p_n_src;
|
||||
|
||||
memset( p_n_z, 0, sizeof( p_n_z ) );
|
||||
|
||||
for( n_vu = 0; n_vu < DCTSIZE2 / 8; n_vu++ )
|
||||
{
|
||||
p_n_z[ 0 ] += p_n_data[ 0 ] * p_n_precalc[ 0 ];
|
||||
p_n_z[ 1 ] += p_n_data[ 1 ] * p_n_precalc[ 1 ];
|
||||
p_n_z[ 2 ] += p_n_data[ 2 ] * p_n_precalc[ 2 ];
|
||||
p_n_z[ 3 ] += p_n_data[ 3 ] * p_n_precalc[ 3 ];
|
||||
p_n_z[ 4 ] += p_n_data[ 4 ] * p_n_precalc[ 4 ];
|
||||
p_n_z[ 5 ] += p_n_data[ 5 ] * p_n_precalc[ 5 ];
|
||||
p_n_z[ 6 ] += p_n_data[ 6 ] * p_n_precalc[ 6 ];
|
||||
p_n_z[ 7 ] += p_n_data[ 7 ] * p_n_precalc[ 7 ];
|
||||
p_n_data += 8;
|
||||
p_n_precalc += 8;
|
||||
}
|
||||
|
||||
*( p_n_dst++ ) = ( p_n_z[ 0 ] + p_n_z[ 1 ] + p_n_z[ 2 ] + p_n_z[ 3 ] +
|
||||
p_n_z[ 4 ] + p_n_z[ 5 ] + p_n_z[ 6 ] + p_n_z[ 7 ] ) >> ( MDEC_COS_PRECALC_BITS + 2 );
|
||||
}
|
||||
}
|
||||
|
||||
INLINE UINT16 mdec_unpack_run( UINT16 n_packed )
|
||||
{
|
||||
return n_packed >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_unpack_val( UINT16 n_packed )
|
||||
{
|
||||
return ( ( (INT32)n_packed ) << 22 ) >> 22;
|
||||
}
|
||||
|
||||
static UINT32 mdec_unpack( psx_machine *p_psx, UINT32 n_address )
|
||||
{
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
psx_mdec *p_mdec = &p_psx->mdec;
|
||||
UINT8 n_z;
|
||||
INT32 n_qscale;
|
||||
UINT16 n_packed;
|
||||
UINT32 n_block;
|
||||
INT32 *p_n_block;
|
||||
INT32 p_n_unpacked[ 64 ];
|
||||
INT32 *p_n_q;
|
||||
|
||||
p_n_q = p_mdec->p_n_quantize_uv;
|
||||
p_n_block = p_mdec->p_n_unpacked;
|
||||
|
||||
for( n_block = 0; n_block < 6; n_block++ )
|
||||
{
|
||||
memset( p_n_unpacked, 0, sizeof( p_n_unpacked ) );
|
||||
|
||||
if( n_block == 2 )
|
||||
{
|
||||
p_n_q = p_mdec->p_n_quantize_y;
|
||||
}
|
||||
n_packed = psxreadword( p_n_psxram, n_address );
|
||||
n_address += 2;
|
||||
if( n_packed == 0xfe00 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
n_qscale = mdec_unpack_run( n_packed );
|
||||
p_n_unpacked[ 0 ] = mdec_unpack_val( n_packed ) * p_n_q[ 0 ];
|
||||
|
||||
n_z = 0;
|
||||
for( ;; )
|
||||
{
|
||||
n_packed = psxreadword( p_n_psxram, n_address );
|
||||
n_address += 2;
|
||||
|
||||
if( n_packed == 0xfe00 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
n_z += mdec_unpack_run( n_packed ) + 1;
|
||||
if( n_z > 63 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
p_n_unpacked[ m_p_n_mdec_zigzag[ n_z ] ] = ( mdec_unpack_val( n_packed ) * p_n_q[ n_z ] * n_qscale ) / 8;
|
||||
}
|
||||
mdec_idct( p_psx, p_n_unpacked, p_n_block );
|
||||
p_n_block += DCTSIZE2;
|
||||
}
|
||||
return n_address;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cr_to_r( INT32 n_cr )
|
||||
{
|
||||
return ( 1435 * n_cr ) >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cr_to_g( INT32 n_cr )
|
||||
{
|
||||
return ( -731 * n_cr ) >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cb_to_g( INT32 n_cb )
|
||||
{
|
||||
return ( -351 * n_cb ) >> 10;
|
||||
}
|
||||
|
||||
INLINE INT32 mdec_cb_to_b( INT32 n_cb )
|
||||
{
|
||||
return ( 1814 * n_cb ) >> 10;
|
||||
}
|
||||
|
||||
INLINE UINT16 mdec_clamp_r5( psx_mdec *p_mdec, INT32 n_r )
|
||||
{
|
||||
return p_mdec->p_n_r5[ n_r + 128 + 256 ];
|
||||
}
|
||||
|
||||
INLINE UINT16 mdec_clamp_g5( psx_mdec *p_mdec, INT32 n_g )
|
||||
{
|
||||
return p_mdec->p_n_g5[ n_g + 128 + 256 ];
|
||||
}
|
||||
|
||||
INLINE UINT16 mdec_clamp_b5( psx_mdec *p_mdec, INT32 n_b )
|
||||
{
|
||||
return p_mdec->p_n_b5[ n_b + 128 + 256 ];
|
||||
}
|
||||
|
||||
INLINE void mdec_makergb15( psx_mdec *p_mdec, UINT32 n_address, INT32 n_r, INT32 n_g, INT32 n_b, INT32 *p_n_y, UINT16 n_stp )
|
||||
{
|
||||
p_mdec->p_n_output[ WORD_XOR_LE( n_address + 0 ) / 2 ] = n_stp |
|
||||
mdec_clamp_r5( p_mdec, p_n_y[ 0 ] + n_r ) |
|
||||
mdec_clamp_g5( p_mdec, p_n_y[ 0 ] + n_g ) |
|
||||
mdec_clamp_b5( p_mdec, p_n_y[ 0 ] + n_b );
|
||||
|
||||
p_mdec->p_n_output[ WORD_XOR_LE( n_address + 2 ) / 2 ] = n_stp |
|
||||
mdec_clamp_r5( p_mdec, p_n_y[ 1 ] + n_r ) |
|
||||
mdec_clamp_g5( p_mdec, p_n_y[ 1 ] + n_g ) |
|
||||
mdec_clamp_b5( p_mdec, p_n_y[ 1 ] + n_b );
|
||||
}
|
||||
|
||||
static void mdec_yuv2_to_rgb15( psx_machine *p_psx )
|
||||
{
|
||||
psx_mdec *p_mdec = &p_psx->mdec;
|
||||
INT32 n_r;
|
||||
INT32 n_g;
|
||||
INT32 n_b;
|
||||
INT32 n_cb;
|
||||
INT32 n_cr;
|
||||
INT32 *p_n_cb;
|
||||
INT32 *p_n_cr;
|
||||
INT32 *p_n_y;
|
||||
UINT32 n_x;
|
||||
UINT32 n_y;
|
||||
UINT32 n_z;
|
||||
UINT16 n_stp;
|
||||
int n_address = 0;
|
||||
|
||||
if( ( p_mdec->n_0_command & ( 1L << 25 ) ) != 0 )
|
||||
{
|
||||
n_stp = 0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_stp = 0x0000;
|
||||
}
|
||||
|
||||
p_n_cr = &p_mdec->p_n_unpacked[ 0 ];
|
||||
p_n_cb = &p_mdec->p_n_unpacked[ DCTSIZE2 ];
|
||||
p_n_y = &p_mdec->p_n_unpacked[ DCTSIZE2 * 2 ];
|
||||
|
||||
for( n_z = 0; n_z < 2; n_z++ )
|
||||
{
|
||||
for( n_y = 0; n_y < 4; n_y++ )
|
||||
{
|
||||
for( n_x = 0; n_x < 4; n_x++ )
|
||||
{
|
||||
n_cr = *( p_n_cr );
|
||||
n_cb = *( p_n_cb );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb15( p_mdec, ( n_address + 0 ), n_r, n_g, n_b, p_n_y, n_stp );
|
||||
mdec_makergb15( p_mdec, ( n_address + 32 ), n_r, n_g, n_b, p_n_y + 8, n_stp );
|
||||
|
||||
n_cr = *( p_n_cr + 4 );
|
||||
n_cb = *( p_n_cb + 4 );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb15( p_mdec, ( n_address + 16 ), n_r, n_g, n_b, p_n_y + DCTSIZE2, n_stp );
|
||||
mdec_makergb15( p_mdec, ( n_address + 48 ), n_r, n_g, n_b, p_n_y + DCTSIZE2 + 8, n_stp );
|
||||
|
||||
p_n_cr++;
|
||||
p_n_cb++;
|
||||
p_n_y += 2;
|
||||
n_address += 4;
|
||||
}
|
||||
p_n_cr += 4;
|
||||
p_n_cb += 4;
|
||||
p_n_y += 8;
|
||||
n_address += 48;
|
||||
}
|
||||
p_n_y += DCTSIZE2;
|
||||
}
|
||||
p_mdec->n_decoded = ( 16 * 16 ) / 2;
|
||||
}
|
||||
|
||||
INLINE UINT16 mdec_clamp8( psx_mdec *p_mdec, INT32 n_r )
|
||||
{
|
||||
return p_mdec->p_n_clamp8[ n_r + 128 + 256 ];
|
||||
}
|
||||
|
||||
INLINE void mdec_makergb24( psx_mdec *p_mdec, UINT32 n_address, INT32 n_r, INT32 n_g, INT32 n_b, INT32 *p_n_y, UINT32 n_stp )
|
||||
{
|
||||
p_mdec->p_n_output[ WORD_XOR_LE( n_address + 0 ) / 2 ] = ( mdec_clamp8( p_mdec, p_n_y[ 0 ] + n_g ) << 8 ) | mdec_clamp8( p_mdec, p_n_y[ 0 ] + n_r );
|
||||
p_mdec->p_n_output[ WORD_XOR_LE( n_address + 2 ) / 2 ] = ( mdec_clamp8( p_mdec, p_n_y[ 1 ] + n_r ) << 8 ) | mdec_clamp8( p_mdec, p_n_y[ 0 ] + n_b );
|
||||
p_mdec->p_n_output[ WORD_XOR_LE( n_address + 4 ) / 2 ] = ( mdec_clamp8( p_mdec, p_n_y[ 1 ] + n_b ) << 8 ) | mdec_clamp8( p_mdec, p_n_y[ 1 ] + n_g );
|
||||
}
|
||||
|
||||
static void mdec_yuv2_to_rgb24( psx_machine *p_psx )
|
||||
{
|
||||
psx_mdec *p_mdec = &p_psx->mdec;
|
||||
INT32 n_r;
|
||||
INT32 n_g;
|
||||
INT32 n_b;
|
||||
INT32 n_cb;
|
||||
INT32 n_cr;
|
||||
INT32 *p_n_cb;
|
||||
INT32 *p_n_cr;
|
||||
INT32 *p_n_y;
|
||||
UINT32 n_x;
|
||||
UINT32 n_y;
|
||||
UINT32 n_z;
|
||||
UINT32 n_stp;
|
||||
int n_address = 0;
|
||||
|
||||
if( ( p_psx->mdec.n_0_command & ( 1L << 25 ) ) != 0 )
|
||||
{
|
||||
n_stp = 0x80008000;
|
||||
}
|
||||
else
|
||||
{
|
||||
n_stp = 0x00000000;
|
||||
}
|
||||
|
||||
p_n_cr = &p_psx->mdec.p_n_unpacked[ 0 ];
|
||||
p_n_cb = &p_psx->mdec.p_n_unpacked[ DCTSIZE2 ];
|
||||
p_n_y = &p_psx->mdec.p_n_unpacked[ DCTSIZE2 * 2 ];
|
||||
|
||||
for( n_z = 0; n_z < 2; n_z++ )
|
||||
{
|
||||
for( n_y = 0; n_y < 4; n_y++ )
|
||||
{
|
||||
for( n_x = 0; n_x < 4; n_x++ )
|
||||
{
|
||||
n_cr = *( p_n_cr );
|
||||
n_cb = *( p_n_cb );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb24( p_mdec, ( n_address + 0 ), n_r, n_g, n_b, p_n_y, n_stp );
|
||||
mdec_makergb24( p_mdec, ( n_address + 48 ), n_r, n_g, n_b, p_n_y + 8, n_stp );
|
||||
|
||||
n_cr = *( p_n_cr + 4 );
|
||||
n_cb = *( p_n_cb + 4 );
|
||||
n_r = mdec_cr_to_r( n_cr );
|
||||
n_g = mdec_cr_to_g( n_cr ) + mdec_cb_to_g( n_cb );
|
||||
n_b = mdec_cb_to_b( n_cb );
|
||||
|
||||
mdec_makergb24( p_mdec, ( n_address + 24 ), n_r, n_g, n_b, p_n_y + DCTSIZE2, n_stp );
|
||||
mdec_makergb24( p_mdec, ( n_address + 72 ), n_r, n_g, n_b, p_n_y + DCTSIZE2 + 8, n_stp );
|
||||
|
||||
p_n_cr++;
|
||||
p_n_cb++;
|
||||
p_n_y += 2;
|
||||
n_address += 6;
|
||||
}
|
||||
p_n_cr += 4;
|
||||
p_n_cb += 4;
|
||||
p_n_y += 8;
|
||||
n_address += 72;
|
||||
}
|
||||
p_n_y += DCTSIZE2;
|
||||
}
|
||||
p_psx->mdec.n_decoded = ( 24 * 16 ) / 2;
|
||||
}
|
||||
|
||||
static void mdec0_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
int n_index;
|
||||
|
||||
verboselog( p_psx, 2, "mdec0_write( %08x, %08x )\n", n_address, n_size );
|
||||
switch( p_psx->mdec.n_0_command >> 28 )
|
||||
{
|
||||
case 0x3:
|
||||
verboselog( p_psx, 1, "mdec decode %08x %08x %08x\n", p_psx->mdec.n_0_command, n_address, n_size );
|
||||
p_psx->mdec.n_0_address = n_address;
|
||||
p_psx->mdec.n_0_size = n_size * 4;
|
||||
p_psx->mdec.n_1_status |= ( 1L << 29 );
|
||||
break;
|
||||
case 0x4:
|
||||
verboselog( p_psx, 1, "mdec quantize table %08x %08x %08x\n", p_psx->mdec.n_0_command, n_address, n_size );
|
||||
n_index = 0;
|
||||
while( n_size > 0 )
|
||||
{
|
||||
if( n_index < DCTSIZE2 )
|
||||
{
|
||||
p_psx->mdec.p_n_quantize_y[ n_index + 0 ] = ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xff;
|
||||
p_psx->mdec.p_n_quantize_y[ n_index + 1 ] = ( p_n_psxram[ n_address / 4 ] >> 8 ) & 0xff;
|
||||
p_psx->mdec.p_n_quantize_y[ n_index + 2 ] = ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xff;
|
||||
p_psx->mdec.p_n_quantize_y[ n_index + 3 ] = ( p_n_psxram[ n_address / 4 ] >> 24 ) & 0xff;
|
||||
}
|
||||
else if( n_index < DCTSIZE2 * 2 )
|
||||
{
|
||||
p_psx->mdec.p_n_quantize_uv[ n_index + 0 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xff;
|
||||
p_psx->mdec.p_n_quantize_uv[ n_index + 1 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 8 ) & 0xff;
|
||||
p_psx->mdec.p_n_quantize_uv[ n_index + 2 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xff;
|
||||
p_psx->mdec.p_n_quantize_uv[ n_index + 3 - DCTSIZE2 ] = ( p_n_psxram[ n_address / 4 ] >> 24 ) & 0xff;
|
||||
}
|
||||
n_index += 4;
|
||||
n_address += 4;
|
||||
n_size--;
|
||||
}
|
||||
break;
|
||||
case 0x6:
|
||||
verboselog( p_psx, 1, "mdec cosine table %08x %08x %08x\n", p_psx->mdec.n_0_command, n_address, n_size );
|
||||
n_index = 0;
|
||||
while( n_size > 0 )
|
||||
{
|
||||
p_psx->mdec.p_n_cos[ n_index + 0 ] = (INT16)( ( p_n_psxram[ n_address / 4 ] >> 0 ) & 0xffff );
|
||||
p_psx->mdec.p_n_cos[ n_index + 1 ] = (INT16)( ( p_n_psxram[ n_address / 4 ] >> 16 ) & 0xffff );
|
||||
n_index += 2;
|
||||
n_address += 4;
|
||||
n_size--;
|
||||
}
|
||||
mdec_cos_precalc(p_psx);
|
||||
break;
|
||||
default:
|
||||
verboselog( p_psx, 0, "mdec unknown command %08x %08x %08x\n", p_psx->mdec.n_0_command, n_address, n_size );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void mdec1_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
UINT32 n_this;
|
||||
UINT32 n_nextaddress;
|
||||
|
||||
verboselog( p_psx, 2, "mdec1_read( %08x, %08x )\n", n_address, n_size );
|
||||
if( ( p_psx->mdec.n_0_command & ( 1L << 29 ) ) != 0 && p_psx->mdec.n_0_size != 0 )
|
||||
{
|
||||
while( n_size > 0 )
|
||||
{
|
||||
if( p_psx->mdec.n_decoded == 0 )
|
||||
{
|
||||
if( (int)p_psx->mdec.n_0_size <= 0 )
|
||||
{
|
||||
mame_printf_debug( "ran out of data %08x\n", n_size );
|
||||
p_psx->mdec.n_0_size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
n_nextaddress = mdec_unpack( p_psx, p_psx->mdec.n_0_address );
|
||||
p_psx->mdec.n_0_size -= n_nextaddress - p_psx->mdec.n_0_address;
|
||||
p_psx->mdec.n_0_address = n_nextaddress;
|
||||
|
||||
if( ( p_psx->mdec.n_0_command & ( 1L << 27 ) ) != 0 )
|
||||
{
|
||||
mdec_yuv2_to_rgb15(p_psx);
|
||||
}
|
||||
else
|
||||
{
|
||||
mdec_yuv2_to_rgb24(p_psx);
|
||||
}
|
||||
p_psx->mdec.n_offset = 0;
|
||||
}
|
||||
|
||||
n_this = p_psx->mdec.n_decoded;
|
||||
if( n_this > n_size )
|
||||
{
|
||||
n_this = n_size;
|
||||
}
|
||||
p_psx->mdec.n_decoded -= n_this;
|
||||
|
||||
memcpy( (UINT8 *)p_n_psxram + n_address, (UINT8 *)p_psx->mdec.p_n_output + p_psx->mdec.n_offset, n_this * 4 );
|
||||
p_psx->mdec.n_offset += n_this * 4;
|
||||
n_address += n_this * 4;
|
||||
n_size -= n_this;
|
||||
}
|
||||
|
||||
if( (int)p_psx->mdec.n_0_size < 0 )
|
||||
{
|
||||
mame_printf_debug( "ran out of data %d\n", p_psx->mdec.n_0_size );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mame_printf_debug( "mdec1_read no conversion :%08x:%08x:\n", p_psx->mdec.n_0_command, p_psx->mdec.n_0_size );
|
||||
}
|
||||
p_psx->mdec.n_1_status &= ~( 1L << 29 );
|
||||
}
|
||||
|
||||
WRITE32_HANDLER( psx_mdec_w )
|
||||
{
|
||||
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
|
||||
|
||||
switch( offset )
|
||||
{
|
||||
case 0:
|
||||
verboselog( p_psx, 2, "mdec 0 command %08x\n", data );
|
||||
p_psx->mdec.n_0_command = data;
|
||||
break;
|
||||
case 1:
|
||||
verboselog( p_psx, 2, "mdec 1 command %08x\n", data );
|
||||
p_psx->mdec.n_1_command = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_HANDLER( psx_mdec_r )
|
||||
{
|
||||
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
|
||||
|
||||
switch( offset )
|
||||
{
|
||||
case 0:
|
||||
verboselog( p_psx, 2, "mdec 0 status %08x\n", 0 );
|
||||
return 0;
|
||||
case 1:
|
||||
verboselog( p_psx, 2, "mdec 1 status %08x\n", p_psx->mdec.n_1_status );
|
||||
return p_psx->mdec.n_1_status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void gpu_read( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
|
||||
psx_machine *p_psx = state->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
|
||||
psx_gpu_read( machine, &p_n_psxram[ n_address / 4 ], n_size );
|
||||
psx_gpu_read( state->machine(), &p_n_psxram[ n_address / 4 ], n_size );
|
||||
}
|
||||
|
||||
static void gpu_write( running_machine &machine, UINT32 n_address, INT32 n_size )
|
||||
static void gpu_write( psx_state *state, UINT32 n_address, INT32 n_size )
|
||||
{
|
||||
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
|
||||
psx_machine *p_psx = state->m_p_psx;
|
||||
UINT32 *p_n_psxram = p_psx->p_n_psxram;
|
||||
|
||||
psx_gpu_write( machine, &p_n_psxram[ n_address / 4 ], n_size );
|
||||
psx_gpu_write( state->machine(), &p_n_psxram[ n_address / 4 ], n_size );
|
||||
}
|
||||
|
||||
void psx_machine_init( running_machine &machine )
|
||||
@ -1137,12 +630,6 @@ void psx_machine_init( running_machine &machine )
|
||||
p_psx->n_irqdata = 0;
|
||||
p_psx->n_irqmask = 0;
|
||||
|
||||
p_psx->mdec.n_0_command = 0;
|
||||
p_psx->mdec.n_0_address = 0;
|
||||
p_psx->mdec.n_0_size = 0;
|
||||
p_psx->mdec.n_1_command = 0;
|
||||
p_psx->mdec.n_1_status = 0;
|
||||
|
||||
for( n = 0; n < 2; n++ )
|
||||
{
|
||||
p_psx->sio[ n ].n_status = SIO_STATUS_TX_EMPTY | SIO_STATUS_TX_RDY;
|
||||
@ -1179,8 +666,6 @@ static void psx_postload(psx_machine *p_psx)
|
||||
{
|
||||
sio_timer_adjust( p_psx, n );
|
||||
}
|
||||
|
||||
mdec_cos_precalc(p_psx);
|
||||
}
|
||||
|
||||
void psx_driver_init( running_machine &machine )
|
||||
@ -1207,30 +692,8 @@ void psx_driver_init( running_machine &machine )
|
||||
p_psx->sio[ n ].fn_handler = NULL;
|
||||
}
|
||||
|
||||
for( n = 0; n < 256; n++ )
|
||||
{
|
||||
p_psx->mdec.p_n_clamp8[ n ] = 0;
|
||||
p_psx->mdec.p_n_clamp8[ n + 256 ] = n;
|
||||
p_psx->mdec.p_n_clamp8[ n + 512 ] = 255;
|
||||
|
||||
p_psx->mdec.p_n_r5[ n ] = 0;
|
||||
p_psx->mdec.p_n_r5[ n + 256 ] = ( n >> 3 );
|
||||
p_psx->mdec.p_n_r5[ n + 512 ] = ( 255 >> 3 );
|
||||
|
||||
p_psx->mdec.p_n_g5[ n ] = 0;
|
||||
p_psx->mdec.p_n_g5[ n + 256 ] = ( n >> 3 ) << 5;
|
||||
p_psx->mdec.p_n_g5[ n + 512 ] = ( 255 >> 3 ) << 5;
|
||||
|
||||
p_psx->mdec.p_n_b5[ n ] = 0;
|
||||
p_psx->mdec.p_n_b5[ n + 256 ] = ( n >> 3 ) << 10;
|
||||
p_psx->mdec.p_n_b5[ n + 512 ] = ( 255 >> 3 ) << 10;
|
||||
}
|
||||
|
||||
psx_dma_install_read_handler( machine, 1, mdec1_read );
|
||||
psx_dma_install_read_handler( machine, 2, gpu_read );
|
||||
|
||||
psx_dma_install_write_handler( machine, 0, mdec0_write );
|
||||
psx_dma_install_write_handler( machine, 2, gpu_write );
|
||||
psx_dma_install_read_handler( machine, 2, psx_dma_read_delegate( FUNC( gpu_read ), state ) );
|
||||
psx_dma_install_write_handler( machine, 2, psx_dma_write_delegate( FUNC( gpu_write ), state ) );
|
||||
|
||||
state_save_register_global( machine, p_psx->n_irqdata );
|
||||
state_save_register_global( machine, p_psx->n_irqmask );
|
||||
@ -1259,14 +722,5 @@ void psx_driver_init( running_machine &machine )
|
||||
state_save_register_item( machine, "psxsio", NULL, n, p_psx->sio[n].n_tx_bits );
|
||||
}
|
||||
|
||||
state_save_register_global( machine, p_psx->mdec.n_0_command );
|
||||
state_save_register_global( machine, p_psx->mdec.n_0_address );
|
||||
state_save_register_global( machine, p_psx->mdec.n_0_size );
|
||||
state_save_register_global( machine, p_psx->mdec.n_1_command );
|
||||
state_save_register_global( machine, p_psx->mdec.n_1_status );
|
||||
state_save_register_global_array( machine, p_psx->mdec.p_n_quantize_y );
|
||||
state_save_register_global_array( machine, p_psx->mdec.p_n_quantize_uv );
|
||||
state_save_register_global_array( machine, p_psx->mdec.p_n_cos );
|
||||
|
||||
machine.save().register_postload( save_prepost_delegate(FUNC(psx_postload), p_psx ));
|
||||
}
|
||||
|
@ -1,258 +0,0 @@
|
||||
/*
|
||||
psxcard.c - Sony PlayStation memory card device
|
||||
|
||||
by pSXAuthor
|
||||
MESS conversion by R. Belmont
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "psxcard.h"
|
||||
#include "includes/psx.h"
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
//#define debug_card
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const device_type PSXCARD = &device_creator<psxcard_device>;
|
||||
|
||||
enum transfer_states
|
||||
{
|
||||
state_illegal=0,
|
||||
state_command,
|
||||
state_cmdack_1,
|
||||
state_cmdack_2,
|
||||
state_addr_hi,
|
||||
state_addr_lo,
|
||||
state_read,
|
||||
state_write,
|
||||
state_writeack_1,
|
||||
state_writeack_2,
|
||||
state_writechk
|
||||
};
|
||||
|
||||
psxcard_device::psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
void psxcard_device::device_start()
|
||||
{
|
||||
cache=new unsigned char [128*1024];
|
||||
|
||||
memset(cache, 0, 128*1024);
|
||||
|
||||
// save state registrations
|
||||
/* save_item(NAME(pkt));
|
||||
save_item(NAME(pkt_ptr));
|
||||
save_item(NAME(pkt_sz));
|
||||
save_item(NAME(pkt));
|
||||
save_item(NAME(cache));
|
||||
save_item(NAME(addr));
|
||||
save_item(NAME(state));*/
|
||||
}
|
||||
|
||||
void psxcard_device::device_reset()
|
||||
{
|
||||
state = state_illegal;
|
||||
addr = 0;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
bool psxcard_device::transfer(UINT8 to, UINT8 *from)
|
||||
{
|
||||
bool ret=true;
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case state_illegal:
|
||||
if (to == 0x81)
|
||||
{
|
||||
// printf("CARD: begin\n");
|
||||
state = state_command;
|
||||
*from = 0x00;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case state_command:
|
||||
cmd=to;
|
||||
*from=0x00;
|
||||
state=state_cmdack_1;
|
||||
break;
|
||||
|
||||
case state_cmdack_1:
|
||||
//assert(to==0);
|
||||
*from=0x5a;
|
||||
state=state_cmdack_2;
|
||||
break;
|
||||
|
||||
case state_cmdack_2:
|
||||
//assert(to==0);
|
||||
*from=0x5d;
|
||||
state=state_addr_hi;
|
||||
break;
|
||||
|
||||
case state_addr_hi:
|
||||
addr=(to<<8);
|
||||
// printf("addr_hi: %02x, addr = %x\n", to, addr);
|
||||
*from=0;
|
||||
state=state_addr_lo;
|
||||
break;
|
||||
|
||||
case state_addr_lo:
|
||||
addr|=(to&0xff);
|
||||
// printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd);
|
||||
*from=(addr>>8);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case 'R': // 0x52
|
||||
{
|
||||
pkt[0]=0x5c;
|
||||
pkt[1]=0x5d;
|
||||
pkt[2]=(addr>>8);
|
||||
pkt[3]=(addr&0xff);
|
||||
read_card(addr,&pkt[4]);
|
||||
pkt[4+128]=checksum_data(&pkt[2],128+2);
|
||||
pkt[5+128]=0x47;
|
||||
pkt_sz=6+128;
|
||||
pkt_ptr=0;
|
||||
state=state_read;
|
||||
break;
|
||||
}
|
||||
case 'W': // 0x57
|
||||
{
|
||||
pkt[0]=addr>>8;
|
||||
pkt[1]=addr&0xff;
|
||||
pkt_sz=129+2;
|
||||
pkt_ptr=2;
|
||||
state=state_write;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
state=state_illegal;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case state_read:
|
||||
//assert(to==0);
|
||||
// printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz);
|
||||
*from=pkt[pkt_ptr++];
|
||||
if (pkt_ptr==pkt_sz)
|
||||
{
|
||||
#ifdef debug_card
|
||||
printf("card: read finished\n");
|
||||
#endif
|
||||
|
||||
state=state_illegal;
|
||||
ret=false;
|
||||
}
|
||||
break;
|
||||
|
||||
case state_write:
|
||||
*from=(pkt_ptr==0)?(addr&0xff):pkt[pkt_ptr-1];
|
||||
pkt[pkt_ptr++]=to;
|
||||
if (pkt_ptr==pkt_sz)
|
||||
state=state_writeack_1;
|
||||
break;
|
||||
|
||||
case state_writeack_1:
|
||||
*from=0x5c;
|
||||
state=state_writeack_2;
|
||||
break;
|
||||
|
||||
case state_writeack_2:
|
||||
*from=0x5d;
|
||||
state=state_writechk;
|
||||
break;
|
||||
|
||||
case state_writechk:
|
||||
{
|
||||
unsigned char chk=checksum_data(pkt,128+2);
|
||||
if (chk==pkt[128+2])
|
||||
{
|
||||
#ifdef debug_card
|
||||
printf("card: write ok\n");
|
||||
#endif
|
||||
|
||||
write_card(addr,pkt+2);
|
||||
|
||||
*from='G';
|
||||
} else
|
||||
{
|
||||
#ifdef debug_card
|
||||
printf("card: write fail\n");
|
||||
#endif
|
||||
|
||||
*from='N';
|
||||
}
|
||||
state=state_illegal;
|
||||
ret=false;
|
||||
break;
|
||||
}
|
||||
|
||||
default: /*assert(0);*/ ret=false; break;
|
||||
}
|
||||
|
||||
#ifdef debug_card
|
||||
// printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F');
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void psxcard_device::read_card(const unsigned short addr, unsigned char *buf)
|
||||
{
|
||||
#ifdef debug_card
|
||||
printf("card: read block %d\n",addr);
|
||||
#endif
|
||||
|
||||
if (addr<1024)
|
||||
{
|
||||
memcpy(buf,cache+(addr*128),128);
|
||||
} else
|
||||
{
|
||||
memset(buf,0,128);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void psxcard_device::write_card(const unsigned short addr, unsigned char *buf)
|
||||
{
|
||||
#ifdef debug_card
|
||||
printf("card: write block %d\n",addr);
|
||||
#endif
|
||||
|
||||
if (addr<1024)
|
||||
{
|
||||
memcpy(cache+(addr*128),buf,128);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
unsigned char psxcard_device::checksum_data(const unsigned char *buf, const unsigned int sz)
|
||||
{
|
||||
unsigned char chk=*buf++;
|
||||
int left=sz;
|
||||
while (--left) chk^=*buf++;
|
||||
return chk;
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef _PSXCARD_
|
||||
#define _PSXCARD_
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
#define MCFG_PSXCARD_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD(_tag, PSXCARD, 0)
|
||||
|
||||
struct psxcard_interface
|
||||
{
|
||||
};
|
||||
|
||||
class psxcard_device : public device_t,
|
||||
public psxcard_interface
|
||||
{
|
||||
public:
|
||||
psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
private:
|
||||
unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd, *cache;
|
||||
unsigned short addr;
|
||||
int state;
|
||||
|
||||
void read_card(const unsigned short addr, unsigned char *buf);
|
||||
void write_card(const unsigned short addr, unsigned char *buf);
|
||||
unsigned char checksum_data(const unsigned char *buf, const unsigned int sz);
|
||||
|
||||
public:
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
bool transfer(UINT8 to, UINT8 *from);
|
||||
void mess_io(running_machine *machine, UINT8 n_data);
|
||||
private:
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type PSXCARD;
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,186 +0,0 @@
|
||||
#ifndef _included_psxcdrom_
|
||||
#define _included_psxcdrom_
|
||||
|
||||
#include "imagedev/chd_cd.h"
|
||||
#include "psxcddrv.h"
|
||||
|
||||
#define MAX_PSXCD_TIMERS (4)
|
||||
|
||||
class event;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const int num_commands=0x20;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
#define PSXCD_TAG "psxcd"
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_PSXCD_ADD(_devname) \
|
||||
MCFG_DEVICE_ADD(PSXCD_TAG, PSXCD, 0) \
|
||||
MCFG_PSXCD_DEVNAME(_devname)
|
||||
|
||||
#define MCFG_PSXCD_DEVNAME(_name) \
|
||||
psxcd_device::static_set_devname(*device, _name); \
|
||||
|
||||
struct psxcd_interface
|
||||
{
|
||||
};
|
||||
|
||||
class psxcd_device : public device_t,
|
||||
public psxcd_interface
|
||||
{
|
||||
public:
|
||||
|
||||
psxcd_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
// inline configuration helpers
|
||||
static void static_set_devname(device_t &device, const char *devname);
|
||||
private:
|
||||
struct command_result
|
||||
{
|
||||
unsigned char data[32], sz, res;
|
||||
command_result *next;
|
||||
};
|
||||
|
||||
static const unsigned int sector_buffer_size=16, default_irq_delay=16000; //480; //8000; //2000<<2;
|
||||
|
||||
unsigned char sr,res,ir,cmdmode,
|
||||
cmdbuf[64],*cbp,
|
||||
mode,
|
||||
loc[3],
|
||||
curpos[3],
|
||||
secbuf[raw_sector_size*sector_buffer_size],
|
||||
*secptr,
|
||||
filter_file,
|
||||
filter_channel,
|
||||
lastsechdr[8],
|
||||
status;
|
||||
int rdp,secsize,secleft,secskip,
|
||||
sechead,sectail,
|
||||
secin;
|
||||
command_result *res_queue,
|
||||
*cur_res;
|
||||
bool open,
|
||||
streaming,
|
||||
first_open;
|
||||
event *next_read_event;
|
||||
INT64 next_sector_t;
|
||||
unsigned int autopause_sector,
|
||||
xa_prefetch_sector,
|
||||
cdda_prefetch_sector;
|
||||
|
||||
cdrom_driver *driver;
|
||||
|
||||
unsigned int start_read_delay,
|
||||
read_sector_cycles,
|
||||
preread_delay;
|
||||
|
||||
void write_command(const unsigned char byte);
|
||||
|
||||
struct command_info
|
||||
{
|
||||
void (psxcd_device::*func)();
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void cdcmd_sync();
|
||||
void cdcmd_nop();
|
||||
void cdcmd_setloc();
|
||||
void cdcmd_play();
|
||||
void cdcmd_forward();
|
||||
void cdcmd_backward();
|
||||
void cdcmd_readn();
|
||||
void cdcmd_standby();
|
||||
void cdcmd_stop();
|
||||
void cdcmd_pause();
|
||||
void cdcmd_init();
|
||||
void cdcmd_mute();
|
||||
void cdcmd_demute();
|
||||
void cdcmd_setfilter();
|
||||
void cdcmd_setmode();
|
||||
void cdcmd_getparam();
|
||||
void cdcmd_getlocl();
|
||||
void cdcmd_getlocp();
|
||||
void cdcmd_illegal();
|
||||
void cdcmd_gettn();
|
||||
void cdcmd_gettd();
|
||||
void cdcmd_seekl();
|
||||
void cdcmd_seekp();
|
||||
void cdcmd_test();
|
||||
void cdcmd_id();
|
||||
void cdcmd_reads();
|
||||
void cdcmd_reset();
|
||||
void cdcmd_readtoc();
|
||||
|
||||
static command_info cmd_table[num_commands];
|
||||
|
||||
void cmd_complete(command_result *res);
|
||||
void add_result(command_result *res);
|
||||
event *send_result(const unsigned int res,
|
||||
const unsigned char *data=NULL,
|
||||
const unsigned int sz=0,
|
||||
const unsigned int delay=default_irq_delay);
|
||||
|
||||
void start_read();
|
||||
void start_play();
|
||||
void start_streaming();
|
||||
void stop_read();
|
||||
void read_sector();
|
||||
void prefetch_next_sector();
|
||||
bool read_next_sector(const bool block=true);
|
||||
bool play_cdda_sector(const unsigned int sector, unsigned char *rawsec);
|
||||
void play_sector();
|
||||
void preread_sector();
|
||||
|
||||
public:
|
||||
void set_driver(cdrom_driver *d);
|
||||
cdrom_driver *get_driver() const { return driver; }
|
||||
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
void start_dma(UINT8 *mainram, UINT32 size);
|
||||
|
||||
unsigned char read_byte(const unsigned int addr);
|
||||
void write_byte(const unsigned int addr, const unsigned char byte);
|
||||
|
||||
private:
|
||||
emu_timer *m_timer;
|
||||
UINT32 m_sysclock;
|
||||
const char *m_devname;
|
||||
device_t *m_cddevice;
|
||||
cdrom_file *m_cd;
|
||||
emu_timer *m_timers[MAX_PSXCD_TIMERS];
|
||||
event *m_eventfortimer[MAX_PSXCD_TIMERS];
|
||||
bool m_timerinuse[MAX_PSXCD_TIMERS];
|
||||
|
||||
void add_system_event(event *ev);
|
||||
};
|
||||
|
||||
|
||||
// miniature version of pSX's event class, which we emulate with device timers
|
||||
const int max_event_data=64;
|
||||
|
||||
class event
|
||||
{
|
||||
public:
|
||||
UINT64 t; // expire time
|
||||
unsigned int type;
|
||||
unsigned char data[max_event_data];
|
||||
emu_timer *timer;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type PSXCD;
|
||||
|
||||
#endif
|
@ -1,533 +0,0 @@
|
||||
#include "emu.h"
|
||||
#include "includes/psx.h"
|
||||
#include "psxcd.h"
|
||||
#include "psxcddrv.h"
|
||||
|
||||
//#define debug_mess_driver
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
static const unsigned int num_pf_sectors=32, num_pf_buffers=16;
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
cdrom_driver::cdrom_driver()
|
||||
{
|
||||
pf_head = 0;
|
||||
pf_tail = 0;
|
||||
num_pf = 0;
|
||||
pf_head_sector = 0;
|
||||
pf_status = NULL;
|
||||
native_sector_size = raw_sector_size;
|
||||
last_pf_status = NULL;
|
||||
m_cd = NULL;
|
||||
m_machine = NULL;
|
||||
|
||||
// printf("cdrom_driver base class init, pf_buffer size is %d\n", num_pf_sectors*num_pf_buffers*raw_sector_size);
|
||||
|
||||
pf_buffer=new unsigned char [num_pf_sectors*num_pf_buffers*raw_sector_size];
|
||||
|
||||
timestamp_frequency = 1;
|
||||
}
|
||||
|
||||
cdrom_driver::~cdrom_driver()
|
||||
{
|
||||
global_free(pf_buffer);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void cdrom_driver::set_native_sector_size(const unsigned int sz)
|
||||
{
|
||||
native_sector_size=sz;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void cdrom_driver::cancel_io()
|
||||
{
|
||||
if (pf_status)
|
||||
{
|
||||
pf_status->cancel();
|
||||
pf_status->release();
|
||||
}
|
||||
|
||||
pf_status=NULL;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
void cdrom_driver::prefetch_sector(const unsigned int sec)
|
||||
{
|
||||
int numpfsec=num_pf*num_pf_sectors,
|
||||
pfsec=sec-pf_head_sector;
|
||||
|
||||
// printf("prefetch_sector: %d\n", sec);
|
||||
|
||||
if ((pfsec<0) || (pfsec>numpfsec))
|
||||
{
|
||||
// Sector is not in prefetch buffer, abort current prefetch
|
||||
|
||||
if (pf_status)
|
||||
{
|
||||
pf_status->cancel();
|
||||
pf_status->release();
|
||||
}
|
||||
|
||||
// Reset the buffer and begin a new prefetch
|
||||
|
||||
pf_head=0;
|
||||
pf_tail=0;
|
||||
num_pf=1;
|
||||
pf_head_sector=sec;
|
||||
|
||||
last_pf_status=NULL;
|
||||
pf_status=read_sectors(sec, num_pf_sectors, pf_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
bool cdrom_driver::is_prefetch_sector_loaded(const unsigned int sec)
|
||||
{
|
||||
int numpfsec=num_pf*num_pf_sectors,
|
||||
pfsec=sec-pf_head_sector;
|
||||
|
||||
if ((pfsec<0) || (pfsec>=numpfsec))
|
||||
{
|
||||
// Requested sector is not in prefetch buffer, begin a new prefetch
|
||||
|
||||
prefetch_sector(sec);
|
||||
pfsec=sec-pf_head_sector;
|
||||
numpfsec=num_pf*num_pf_sectors;
|
||||
}
|
||||
|
||||
int blk=pfsec/num_pf_sectors;
|
||||
|
||||
if (blk>0)
|
||||
{
|
||||
// Discard blocks below the prefetch point
|
||||
|
||||
pf_head=(pf_head+blk)%num_pf_buffers;
|
||||
pf_head_sector+=num_pf_sectors*blk;
|
||||
pfsec-=num_pf_sectors*blk;
|
||||
num_pf-=blk;
|
||||
blk=0;
|
||||
}
|
||||
|
||||
bool comp=((! pf_status) || (pf_status->complete()));
|
||||
|
||||
if (! comp)
|
||||
{
|
||||
INT64 curtime=m_machine->device<cpu_device>("maincpu")->total_cycles();
|
||||
|
||||
if (last_pf_status!=pf_status)
|
||||
{
|
||||
last_pf_status=pf_status;
|
||||
pf_timeout_begin=curtime;
|
||||
}
|
||||
|
||||
INT64 timeout=curtime-pf_timeout_begin;
|
||||
int timeout_sec=(int)(timeout/timestamp_frequency);
|
||||
if (timeout_sec>20)
|
||||
{
|
||||
printf("cdrom: prefetch timed out, trying again...\n");
|
||||
num_pf=0;
|
||||
pf_head_sector=-1;
|
||||
prefetch_sector(sec);
|
||||
return is_prefetch_sector_loaded(sec);
|
||||
}
|
||||
}
|
||||
|
||||
if ((num_pf<num_pf_buffers) && (comp))
|
||||
{
|
||||
// The prefetch buffer is not full and we are not waiting on IO,
|
||||
// prefetch the next block
|
||||
|
||||
pf_tail=(pf_tail+1)%num_pf_buffers;
|
||||
num_pf++;
|
||||
|
||||
int nxtsec=pf_head_sector+((num_pf-1)*num_pf_sectors);
|
||||
unsigned char *ptr=pf_buffer+((pf_tail*num_pf_sectors)*native_sector_size);
|
||||
|
||||
if (pf_status)
|
||||
{
|
||||
pf_status->release();
|
||||
pf_status=last_pf_status=NULL;
|
||||
}
|
||||
|
||||
pf_status=read_sectors(nxtsec, num_pf_sectors, ptr);
|
||||
}
|
||||
|
||||
if (blk==(num_pf-1))
|
||||
{
|
||||
// The sector we want is in the last block in the prefetch buffer
|
||||
// which might still be loading, check if the sector we want is loaded
|
||||
#if 0 // we do not load async in MESS
|
||||
INT64 trans=pf_status->bytes_transferred();
|
||||
unsigned int secmod=pfsec%num_pf_sectors,
|
||||
needbytes=(secmod+1)*native_sector_size;
|
||||
|
||||
if (trans<needbytes)
|
||||
{
|
||||
// The sector is not loaded yet
|
||||
|
||||
return false;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
// The sector is loaded
|
||||
|
||||
return true;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// The sector is not in the last block so it must be loaded
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
unsigned char *cdrom_driver::get_prefetch_sector(const unsigned int sec, unsigned int *sz)
|
||||
{
|
||||
int numpfsec=num_pf*num_pf_sectors,
|
||||
pfsec=sec-pf_head_sector;
|
||||
if ((pfsec>=0) && (pfsec<numpfsec))
|
||||
{
|
||||
int blk=(pf_head+(pfsec/num_pf_sectors))%num_pf_buffers,
|
||||
off=((blk*num_pf_sectors)+(pfsec%num_pf_sectors))*native_sector_size;
|
||||
*sz=native_sector_size;
|
||||
return pf_buffer+off;
|
||||
} else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
bool cdrom_driver::read_sector(const unsigned int sec, unsigned char *buf, const bool block)
|
||||
{
|
||||
bool loaded=is_prefetch_sector_loaded(sec);
|
||||
|
||||
// printf("read_sector: %d (loaded=%c)\n", sec, loaded ? 'Y' : 'N');
|
||||
|
||||
if ((! loaded) && (block))
|
||||
{
|
||||
pf_status->block_until_complete();
|
||||
loaded=true;
|
||||
}
|
||||
|
||||
if (loaded)
|
||||
{
|
||||
unsigned int secsz=0;
|
||||
unsigned char *ptr=get_prefetch_sector(sec,&secsz);
|
||||
assert(ptr);
|
||||
|
||||
// printf("got sector %d @ %p, size %d = %02x %02x | %02x %02x\n", sec, ptr, secsz, ptr[0], ptr[1], ptr[0x20], ptr[0x21]);
|
||||
|
||||
if (secsz<2352)
|
||||
{
|
||||
// Add sector header
|
||||
|
||||
buf[0]=0;
|
||||
memset(buf+1,0xff,10);
|
||||
buf[11]=0;
|
||||
sector_to_msf(sec,buf+12);
|
||||
buf[12]=decimal_to_bcd(buf[12]);
|
||||
buf[13]=decimal_to_bcd(buf[13]);
|
||||
buf[14]=decimal_to_bcd(buf[14]);
|
||||
buf[15]=2;
|
||||
|
||||
if (secsz<2336)
|
||||
{
|
||||
memset(buf+16,0xff,8);
|
||||
}
|
||||
}
|
||||
|
||||
switch (secsz)
|
||||
{
|
||||
case 2048:
|
||||
memcpy(buf+24,ptr,2048);
|
||||
break;
|
||||
|
||||
case 2336:
|
||||
memcpy(buf+16,ptr,2336);
|
||||
break;
|
||||
|
||||
case 2352:
|
||||
memcpy(buf,ptr,raw_sector_size);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void cdrom_driver::set_machine(const running_machine &machine)
|
||||
{
|
||||
m_machine = (running_machine *)&machine;
|
||||
|
||||
timestamp_frequency = m_machine->device<cpu_device>("maincpu")->clock();
|
||||
|
||||
// printf("cdrom_driver::set_machine: timestamp frequency = %d\n", timestamp_frequency);
|
||||
}
|
||||
|
||||
/*
|
||||
MAME/MESS driver implementation
|
||||
*/
|
||||
|
||||
class mess_cdrom_driver : public cdrom_driver
|
||||
{
|
||||
enum track_type
|
||||
{
|
||||
track_illegal=-1,
|
||||
track_mode1_2048=0,
|
||||
track_mode2_2352,
|
||||
track_mode2_2336,
|
||||
track_audio
|
||||
};
|
||||
|
||||
struct toc_entry
|
||||
{
|
||||
unsigned int type;
|
||||
unsigned char address[3];
|
||||
};
|
||||
|
||||
int num_sectors, num_tracks;
|
||||
toc_entry toc[100];
|
||||
int bin_sector_size;
|
||||
const char *err;
|
||||
|
||||
io_status *read_sectors(const unsigned int startsec, const unsigned int numsec, unsigned char *buf);
|
||||
|
||||
public:
|
||||
mess_cdrom_driver();
|
||||
~mess_cdrom_driver();
|
||||
|
||||
bool is_usable(char *error_msg, const int msglen) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool read_toc();
|
||||
unsigned int get_first_track() const;
|
||||
unsigned int get_num_tracks() const;
|
||||
bool get_track_address(const unsigned int track,unsigned char *address) const;
|
||||
tracktype get_track_type(const unsigned int track) const;
|
||||
unsigned int find_track(const unsigned int sector, unsigned int *start_sector, unsigned int *end_sector) const;
|
||||
cdromtype get_type() const;
|
||||
};
|
||||
|
||||
mess_cdrom_driver::mess_cdrom_driver()
|
||||
: err(NULL)
|
||||
{
|
||||
for (int i=0; i<100; i++)
|
||||
toc[i].type=track_illegal;
|
||||
num_tracks=0;
|
||||
num_sectors=0;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
mess_cdrom_driver::~mess_cdrom_driver()
|
||||
{
|
||||
cancel_io();
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
bool mess_cdrom_driver::read_toc()
|
||||
{
|
||||
if (m_cd)
|
||||
{
|
||||
const cdrom_toc *toc = cdrom_get_toc(m_cd);
|
||||
|
||||
num_tracks = cdrom_get_last_track(m_cd);
|
||||
|
||||
switch (toc->tracks[0].trktype)
|
||||
{
|
||||
case CD_TRACK_MODE1: bin_sector_size=2048; break;
|
||||
case CD_TRACK_MODE2_FORM1: bin_sector_size=2048; break;
|
||||
case CD_TRACK_MODE2: bin_sector_size=2336; break;
|
||||
case CD_TRACK_MODE2_FORM_MIX: bin_sector_size=2336; break;
|
||||
default: bin_sector_size=2352; break;
|
||||
}
|
||||
|
||||
set_native_sector_size(bin_sector_size);
|
||||
num_sectors = cdrom_get_track_start(m_cd, num_tracks) + toc->tracks[num_tracks].frames;
|
||||
|
||||
// printf("mess_cdrom_driver: %d sectors, native size %d\n",num_sectors, bin_sector_size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
io_status *mess_cdrom_driver::read_sectors(const unsigned int startsec, const unsigned int numsec, unsigned char *buf)
|
||||
{
|
||||
const cdrom_toc *toc = cdrom_get_toc(m_cd);
|
||||
UINT32 track = cdrom_get_track(m_cd, startsec);
|
||||
UINT32 secsize = toc->tracks[track].datasize;
|
||||
|
||||
#ifdef debug_mess_driver
|
||||
printf("mess: read %d sectors from %d (secsize %d)\n",numsec,startsec,secsize);
|
||||
#endif
|
||||
|
||||
if ((startsec>=0)) // && ((int)startsec<num_sectors))
|
||||
{
|
||||
// fin->seek((INT64)startsec*(INT64)bin_sector_size);
|
||||
|
||||
// io_status *ios=fin->async_read(buf,numsec*bin_sector_size);
|
||||
// if (! ios)
|
||||
for (int i = 0; i < numsec; i++)
|
||||
{
|
||||
// printf("[%d/%d] Reading to pf_buffer %p at offset %d, size %d\n", i, numsec, &buf[secsize*i], secsize*i, secsize);
|
||||
cdrom_read_data(m_cd, startsec+i, &buf[secsize*i], CD_TRACK_RAW_DONTCARE);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
// return ios;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mess: read sector out of range (%d, max=%d)\n",
|
||||
startsec,
|
||||
num_sectors);
|
||||
|
||||
memset(buf,0xff,numsec*bin_sector_size);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
unsigned int mess_cdrom_driver::get_first_track() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int mess_cdrom_driver::get_num_tracks() const
|
||||
{
|
||||
// printf("get_num_tracks = %d\n", num_tracks);
|
||||
return num_tracks;
|
||||
}
|
||||
|
||||
bool mess_cdrom_driver::get_track_address(const unsigned int track, unsigned char *address) const
|
||||
{
|
||||
if ((track>=1) && ((int)track<=num_tracks))
|
||||
{
|
||||
UINT32 trkstart = cdrom_get_track_start(m_cd, track);
|
||||
|
||||
sector_to_msf(trkstart, address);
|
||||
|
||||
address[0] = address[0];
|
||||
address[1] = address[1];
|
||||
address[2] = address[2];
|
||||
|
||||
// printf("get_track_address %d = %02x:%02x:%02x\n", track, address[0], address[1], address[2]);
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
address[0]=address[1]=address[2]=0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int mess_cdrom_driver::find_track(const unsigned int sector, unsigned int *start_sector, unsigned int *end_sector) const
|
||||
{
|
||||
const cdrom_toc *toc = cdrom_get_toc(m_cd);
|
||||
UINT32 track = cdrom_get_track(m_cd, sector);
|
||||
int start;
|
||||
|
||||
start = cdrom_get_track_start(m_cd, track);
|
||||
|
||||
if (start_sector != NULL)
|
||||
{
|
||||
*start_sector = start;
|
||||
}
|
||||
|
||||
if (end_sector != NULL)
|
||||
{
|
||||
*end_sector = start + toc->tracks[track].frames;
|
||||
}
|
||||
|
||||
printf("find_track: track %d start %d end %d\n", track, start, *end_sector);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
cdromtype mess_cdrom_driver::get_type() const
|
||||
{
|
||||
// printf("get_type\n");
|
||||
return cdromtype_cd;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
tracktype mess_cdrom_driver::get_track_type(const unsigned int track) const
|
||||
{
|
||||
const cdrom_toc *toc = cdrom_get_toc(m_cd);
|
||||
|
||||
// printf("get_track_type %d = %d\n", track, toc->tracks[track].trktype);
|
||||
|
||||
switch (toc->tracks[track].trktype)
|
||||
{
|
||||
case CD_TRACK_MODE1: return tracktype_mode1;
|
||||
case CD_TRACK_MODE2_RAW: return tracktype_mode2;
|
||||
case CD_TRACK_MODE2_FORM_MIX: return tracktype_mode2;
|
||||
case CD_TRACK_AUDIO: return tracktype_audio;
|
||||
default: return tracktype_unknown;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
cdrom_driver *open_mess_drv()
|
||||
{
|
||||
return new mess_cdrom_driver();
|
||||
}
|
||||
|
@ -1,133 +0,0 @@
|
||||
#ifndef _included_psxcddriver_
|
||||
#define _included_psxcddriver_
|
||||
|
||||
const unsigned int raw_sector_size=2352;
|
||||
|
||||
class io_status
|
||||
{
|
||||
protected:
|
||||
virtual ~io_status() {}
|
||||
|
||||
public:
|
||||
io_status() { }
|
||||
|
||||
virtual void cancel()=0;
|
||||
virtual void release()=0;
|
||||
virtual bool complete() const=0;
|
||||
virtual bool block_until_complete() const=0;
|
||||
virtual INT64 bytes_transferred() const=0;
|
||||
};
|
||||
|
||||
enum cdromtype
|
||||
{
|
||||
cdromtype_cd=0,
|
||||
cdromtype_dvd
|
||||
};
|
||||
|
||||
enum tracktype
|
||||
{
|
||||
tracktype_unknown=0,
|
||||
tracktype_mode1,
|
||||
tracktype_mode2,
|
||||
tracktype_audio
|
||||
};
|
||||
|
||||
class cdrom_driver
|
||||
{
|
||||
int pf_head,
|
||||
pf_tail,
|
||||
num_pf,
|
||||
pf_head_sector;
|
||||
unsigned char *pf_buffer;
|
||||
io_status *pf_status,
|
||||
*last_pf_status;
|
||||
INT64 pf_timeout_begin;
|
||||
|
||||
int native_sector_size;
|
||||
|
||||
virtual io_status *read_sectors(const unsigned int sec, const unsigned int numsec, unsigned char *buf)=0;
|
||||
|
||||
bool is_prefetch_sector_loaded(const unsigned int pfsec);
|
||||
|
||||
protected:
|
||||
void cancel_io();
|
||||
void set_native_sector_size(const unsigned int sz);
|
||||
UINT32 timestamp_frequency;
|
||||
cdrom_file *m_cd;
|
||||
private:
|
||||
running_machine *m_machine;
|
||||
|
||||
public:
|
||||
cdrom_driver();
|
||||
virtual ~cdrom_driver();
|
||||
|
||||
void set_machine(const running_machine &machine);
|
||||
void set_cdrom_file(cdrom_file *cdfile) { m_cd = cdfile; }
|
||||
|
||||
virtual bool is_usable(char *error_msg=NULL, const int msglen=0) const=0;
|
||||
virtual bool read_toc()=0;
|
||||
|
||||
void prefetch_sector(const unsigned int sec);
|
||||
bool read_sector(const unsigned int sec,
|
||||
unsigned char *buf,
|
||||
const bool block=true);
|
||||
unsigned char *get_prefetch_sector(const unsigned int pfsec,
|
||||
unsigned int *sz);
|
||||
|
||||
virtual unsigned int get_first_track() const=0;
|
||||
virtual unsigned int get_num_tracks() const=0;
|
||||
virtual bool get_track_address(const unsigned int track,
|
||||
unsigned char *address) const=0;
|
||||
virtual tracktype get_track_type(const unsigned int track) const=0;
|
||||
virtual unsigned int find_track(const unsigned int sector,
|
||||
unsigned int *start_sector=NULL,
|
||||
unsigned int *end_sector=NULL) const=0;
|
||||
|
||||
virtual cdromtype get_type() const { return cdromtype_cd; }
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
inline unsigned int msf_to_sector(const unsigned char *msf)
|
||||
{
|
||||
unsigned int sec=msf[2]+(msf[1]*75)+(msf[0]*(60*75));
|
||||
if (sec>=150)
|
||||
{
|
||||
return sec-150;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline void sector_to_msf(const unsigned int sec, unsigned char *msf)
|
||||
{
|
||||
unsigned int s=sec+150;
|
||||
msf[0]=s/(60*75);
|
||||
s-=msf[0]*(60*75);
|
||||
msf[1]=s/75;
|
||||
s-=msf[1]*75;
|
||||
msf[2]=s;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
inline unsigned char bcd_to_decimal(const unsigned char bcd)
|
||||
{
|
||||
return ((bcd>>4)*10)+(bcd&0xf);
|
||||
}
|
||||
|
||||
inline unsigned char decimal_to_bcd(const unsigned char dec)
|
||||
{
|
||||
//assert(dec<100);
|
||||
return ((dec/10)<<4)|(dec%10);
|
||||
}
|
||||
|
||||
cdrom_driver *open_mess_drv();
|
||||
|
||||
#endif
|
@ -1320,11 +1320,6 @@ $(MAMEOBJ)/snk.a: \
|
||||
|
||||
$(MAMEOBJ)/sony.a: \
|
||||
$(DRIVERS)/zn.o $(MACHINE)/znsec.o \
|
||||
$(DRIVERS)/taitogn.o \
|
||||
$(DRIVERS)/psx.o \
|
||||
$(MACHINE)/psxcd.o \
|
||||
$(MACHINE)/psxcddrv.o \
|
||||
$(MACHINE)/psxcard.o \
|
||||
|
||||
$(MAMEOBJ)/stern.a: \
|
||||
$(DRIVERS)/astinvad.o \
|
||||
@ -1423,6 +1418,7 @@ $(MAMEOBJ)/taito.a: \
|
||||
$(DRIVERS)/taito_z.o $(VIDEO)/taito_z.o \
|
||||
$(DRIVERS)/taito_o.o $(VIDEO)/taito_o.o \
|
||||
$(DRIVERS)/taitoair.o $(VIDEO)/taitoair.o \
|
||||
$(DRIVERS)/taitogn.o \
|
||||
$(DRIVERS)/taitojc.o $(VIDEO)/taitojc.o \
|
||||
$(DRIVERS)/taitopjc.o $\
|
||||
$(DRIVERS)/taitosj.o $(MACHINE)/taitosj.o $(VIDEO)/taitosj.o \
|
||||
|
Loading…
Reference in New Issue
Block a user