"I'm sorry. Am I interrupting anything?" -- Lando Calrissian

Moved PlayStation IRQ code to sub device of the CPU. [smf]
This commit is contained in:
smf- 2011-05-16 00:01:37 +00:00
parent 62950e6917
commit 6b3bb8fd75
8 changed files with 189 additions and 103 deletions

2
.gitattributes vendored
View File

@ -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/irq.c svneol=native#text/plain
src/emu/cpu/psx/irq.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

View File

@ -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/sio.o $(CPUOBJ)/psx/dma.o $(CPUOBJ)/psx/rcnt.o $(CPUOBJ)/psx/mdec.o
CPUOBJS += $(CPUOBJ)/psx/psx.o $(CPUOBJ)/psx/gte.o $(CPUOBJ)/psx/dma.o $(CPUOBJ)/psx/irq.o $(CPUOBJ)/psx/mdec.o $(CPUOBJ)/psx/rcnt.o $(CPUOBJ)/psx/sio.o
DASMOBJS += $(CPUOBJ)/psx/psxdasm.o
endif

112
src/emu/cpu/psx/irq.c Normal file
View File

@ -0,0 +1,112 @@
/*
* PlayStation IRQ emulator
*
* Copyright 2003-2011 smf
*
*/
#include "psx.h"
#include "irq.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_IRQ = &device_creator<psxirq_device>;
psxirq_device::psxirq_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, PSX_IRQ, "PSX IRQ", tag, owner, clock)
{
}
void psxirq_device::device_reset()
{
n_irqdata = 0;
n_irqmask = 0;
psx_irq_update();
}
void psxirq_device::device_post_load()
{
psx_irq_update();
}
void psxirq_device::device_start()
{
save_item( NAME( n_irqdata ) );
save_item( NAME( n_irqmask ) );
}
void psxirq_device::set( UINT32 bitmask )
{
verboselog( machine(), 2, "psx_irq_set %08x\n", bitmask );
n_irqdata |= bitmask;
psx_irq_update();
}
void psxirq_device::psx_irq_update( void )
{
if( ( n_irqdata & n_irqmask ) != 0 )
{
verboselog( machine(), 2, "psx irq assert\n" );
cputag_set_input_line( machine(), "maincpu", PSXCPU_IRQ0, ASSERT_LINE );
}
else
{
verboselog( machine(), 2, "psx irq clear\n" );
cputag_set_input_line( machine(), "maincpu", PSXCPU_IRQ0, CLEAR_LINE );
}
}
WRITE32_MEMBER( psxirq_device::write )
{
switch( offset )
{
case 0x00:
verboselog( machine(), 2, "psx irq data ( %08x, %08x ) %08x -> %08x\n", data, mem_mask, n_irqdata, ( n_irqdata & ~mem_mask ) | ( n_irqdata & n_irqmask & data ) );
n_irqdata = ( n_irqdata & ~mem_mask ) | ( n_irqdata & n_irqmask & data );
psx_irq_update();
break;
case 0x01:
verboselog( machine(), 2, "psx irq mask ( %08x, %08x ) %08x -> %08x\n", data, mem_mask, n_irqmask, ( n_irqmask & ~mem_mask ) | data );
n_irqmask = ( n_irqmask & ~mem_mask ) | data;
if( ( n_irqmask &~ PSX_IRQ_MASK ) != 0 )
{
verboselog( machine(), 0, "psx_irq_w( %08x, %08x, %08x ) unknown irq\n", offset, data, mem_mask );
}
psx_irq_update();
break;
default:
verboselog( machine(), 0, "psx_irq_w( %08x, %08x, %08x ) unknown register\n", offset, data, mem_mask );
break;
}
}
READ32_MEMBER( psxirq_device::read )
{
switch( offset )
{
case 0x00:
verboselog( machine(), 1, "psx_irq_r irq data %08x\n", n_irqdata );
return n_irqdata;
case 0x01:
verboselog( machine(), 1, "psx_irq_r irq mask %08x\n", n_irqmask );
return n_irqmask;
default:
verboselog( machine(), 0, "psx_irq_r unknown register %d\n", offset );
break;
}
return 0;
}

51
src/emu/cpu/psx/irq.h Normal file
View File

@ -0,0 +1,51 @@
/*
* PlayStation IRQ emulator
*
* Copyright 2003-2011 smf
*
*/
#pragma once
#ifndef __PSXIRQ_H__
#define __PSXIRQ_H__
#include "emu.h"
#define PSX_IRQ_VBLANK 0x0001
#define PSX_IRQ_CDROM 0x0004
#define PSX_IRQ_DMA 0x0008
#define PSX_IRQ_ROOTCOUNTER0 0x0010
#define PSX_IRQ_ROOTCOUNTER1 0x0020
#define PSX_IRQ_ROOTCOUNTER2 0x0040
#define PSX_IRQ_SIO0 0x0080
#define PSX_IRQ_SIO1 0x0100
#define PSX_IRQ_SPU 0x0200
#define PSX_IRQ_EXTCD 0x0400
#define PSX_IRQ_MASK (PSX_IRQ_VBLANK | PSX_IRQ_CDROM | PSX_IRQ_DMA | PSX_IRQ_ROOTCOUNTER2 | PSX_IRQ_ROOTCOUNTER1 | PSX_IRQ_ROOTCOUNTER0 | PSX_IRQ_SIO0 | PSX_IRQ_SIO1 | PSX_IRQ_SPU | PSX_IRQ_EXTCD)
extern const device_type PSX_IRQ;
class psxirq_device : public device_t
{
public:
psxirq_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
READ32_MEMBER( read );
WRITE32_MEMBER( write );
void set( UINT32 bitmask );
protected:
virtual void device_start();
virtual void device_reset();
virtual void device_post_load();
private:
void psx_irq_update( void );
UINT32 n_irqdata;
UINT32 n_irqmask;
};
#endif

View File

@ -66,6 +66,7 @@
#include "debugger.h"
#include "psx.h"
#include "dma.h"
#include "irq.h"
#include "mdec.h"
#include "rcnt.h"
#include "sio.h"
@ -1528,17 +1529,23 @@ static ADDRESS_MAP_START( psxcpu_internal_map, AS_PROGRAM, 32, psxcpu_device )
AM_RANGE(0x1f800000, 0x1f8003ff) AM_NOP /* scratchpad */
AM_RANGE(0x1f800400, 0x1f800fff) AM_READWRITE( berr_r, berr_w )
AM_RANGE(0x1f801004, 0x1f80101f) AM_RAM
/* 1f801014 spu delay */
/* 1f801018 dv delay */
AM_RANGE(0x1f801020, 0x1f801023) AM_READWRITE_LEGACY( psx_com_delay_r, psx_com_delay_w )
AM_RANGE(0x1f801024, 0x1f80102f) AM_RAM
AM_RANGE(0x1f801040, 0x1f80105f) AM_DEVREADWRITE( "sio", psxsio_device, read, write )
/* 1f801060 ram config */
AM_RANGE(0x1f801060, 0x1f80106f) AM_RAM
AM_RANGE(0x1f801070, 0x1f801077) AM_READWRITE_LEGACY( psx_irq_r, psx_irq_w )
AM_RANGE(0x1f801070, 0x1f801077) AM_DEVREADWRITE( "irq", psxirq_device, read, write )
AM_RANGE(0x1f801080, 0x1f8010ff) AM_DEVREADWRITE( "dma", psxdma_device, read, write )
AM_RANGE(0x1f801100, 0x1f80112f) AM_DEVREADWRITE( "rcnt", psxrcnt_device, read, write )
/* 1f801800-1f801803 cd */
AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE_LEGACY( psx_gpu_r, psx_gpu_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 /* ?? */
/* 1f802030 int 2000 */
/* 1f802040 dip switches */
AM_RANGE(0x1f802040, 0x1f802043) AM_WRITENOP
AM_RANGE(0x20000000, 0x7fffffff) AM_READWRITE( berr_r, berr_w )
AM_RANGE(0x80800000, 0x9effffff) AM_READWRITE( berr_r, berr_w )
@ -1556,7 +1563,7 @@ static ADDRESS_MAP_START( cxd8661r_internal_map, AS_PROGRAM, 32, psxcpu_device )
AM_RANGE(0x1f801024, 0x1f80102f) AM_RAM
AM_RANGE(0x1f801040, 0x1f80105f) AM_DEVREADWRITE( "sio", psxsio_device, read, write )
AM_RANGE(0x1f801060, 0x1f80106f) AM_RAM
AM_RANGE(0x1f801070, 0x1f801077) AM_READWRITE_LEGACY( psx_irq_r, psx_irq_w )
AM_RANGE(0x1f801070, 0x1f801077) AM_DEVREADWRITE( "irq", psxirq_device, read, write )
AM_RANGE(0x1f801080, 0x1f8010ff) AM_DEVREADWRITE( "dma", psxdma_device, read, write )
AM_RANGE(0x1f801100, 0x1f80112f) AM_DEVREADWRITE( "rcnt", psxrcnt_device, read, write )
AM_RANGE(0x1f801810, 0x1f801817) AM_READWRITE_LEGACY( psx_gpu_r, psx_gpu_w )
@ -3159,6 +3166,12 @@ static psxcpu_device *getcpu( device_t &device, const char *cputag )
return downcast<psxcpu_device *>( device.siblingdevice( cputag ) );
}
void psxcpu_device::irq_set( device_t &device, const char *cputag, UINT32 bitmask )
{
psxirq_device *irq = downcast<psxirq_device *>( getcpu( device, cputag )->subdevice("irq") );
irq->set( bitmask );
}
void psxcpu_device::install_dma_read_handler( device_t &device, const char *cputag, int channel, psx_dma_read_delegate handler )
{
psxdma_device *dma = downcast<psxdma_device *>( getcpu( device, cputag )->subdevice("dma") );
@ -3184,15 +3197,15 @@ void psxcpu_device::sio_input( device_t &device, const char *cputag, int n_port,
}
static MACHINE_CONFIG_FRAGMENT( psx )
MCFG_DEVICE_ADD("sio", PSX_SIO, 0)
MCFG_DEVICE_ADD("irq", PSX_IRQ, 0)
MCFG_DEVICE_ADD("dma", PSX_DMA, 0)
MCFG_DEVICE_ADD("rcnt", PSX_RCNT, 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 ) )
MCFG_DEVICE_ADD("rcnt", PSX_RCNT, 0)
MCFG_DEVICE_ADD("sio", PSX_SIO, 0)
MACHINE_CONFIG_END
//-------------------------------------------------

View File

@ -134,6 +134,8 @@ public:
static void install_dma_write_handler( device_t &device, const char *cputag, int channel, psx_dma_write_delegate handler );
static void install_sio_handler( device_t &device, const char *cputag, int n_port, psx_sio_handler p_f_sio_handler );
static void sio_input( device_t &device, const char *cputag, int n_port, int n_mask, int n_data );
static void irq_set( device_t &device, const char *cputag, UINT32 bitmask );
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);

View File

@ -7,20 +7,9 @@
#if !defined( PSX_H )
#include "cpu/psx/dma.h"
#include "cpu/psx/irq.h"
#include "cpu/psx/sio.h"
#define PSX_IRQ_VBLANK 0x0001
#define PSX_IRQ_CDROM 0x0004
#define PSX_IRQ_DMA 0x0008
#define PSX_IRQ_ROOTCOUNTER0 0x0010
#define PSX_IRQ_ROOTCOUNTER1 0x0020
#define PSX_IRQ_ROOTCOUNTER2 0x0040
#define PSX_IRQ_SIO0 0x0080
#define PSX_IRQ_SIO1 0x0100
#define PSX_IRQ_SPU 0x0200
#define PSX_IRQ_EXTCD 0x0400
#define PSX_IRQ_MASK (PSX_IRQ_VBLANK | PSX_IRQ_CDROM | PSX_IRQ_DMA | PSX_IRQ_ROOTCOUNTER2 | PSX_IRQ_ROOTCOUNTER1 | PSX_IRQ_ROOTCOUNTER0 | PSX_IRQ_SIO0 | PSX_IRQ_SIO1 | PSX_IRQ_SPU | PSX_IRQ_EXTCD)
typedef struct _psx_machine psx_machine;
struct _psx_machine
{
@ -31,8 +20,6 @@ struct _psx_machine
size_t n_psxramsize;
UINT32 n_com_delay;
UINT32 n_irqdata;
UINT32 n_irqmask;
};
typedef struct _psx_gpu psx_gpu;
@ -69,8 +56,6 @@ extern void psx_lightgun_set( running_machine &, int, int );
WRITE32_HANDLER( psx_com_delay_w );
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_delegate );
extern void psx_dma_install_write_handler( running_machine &, int, psx_dma_read_delegate );

View File

@ -41,72 +41,9 @@ READ32_HANDLER( psx_com_delay_r )
/* IRQ */
static void psx_irq_update( psx_machine *p_psx )
{
if( ( p_psx->n_irqdata & p_psx->n_irqmask ) != 0 )
{
verboselog( p_psx, 2, "psx irq assert\n" );
cputag_set_input_line( p_psx->machine(), "maincpu", PSXCPU_IRQ0, ASSERT_LINE );
}
else
{
verboselog( p_psx, 2, "psx irq clear\n" );
cputag_set_input_line( p_psx->machine(), "maincpu", PSXCPU_IRQ0, CLEAR_LINE );
}
}
WRITE32_HANDLER( psx_irq_w )
{
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
switch( offset )
{
case 0x00:
verboselog( p_psx, 2, "psx irq data ( %08x, %08x ) %08x -> %08x\n", data, mem_mask, p_psx->n_irqdata, ( p_psx->n_irqdata & ~mem_mask ) | ( p_psx->n_irqdata & p_psx->n_irqmask & data ) );
p_psx->n_irqdata = ( p_psx->n_irqdata & ~mem_mask ) | ( p_psx->n_irqdata & p_psx->n_irqmask & data );
psx_irq_update(p_psx);
break;
case 0x01:
verboselog( p_psx, 2, "psx irq mask ( %08x, %08x ) %08x -> %08x\n", data, mem_mask, p_psx->n_irqmask, ( p_psx->n_irqmask & ~mem_mask ) | data );
p_psx->n_irqmask = ( p_psx->n_irqmask & ~mem_mask ) | data;
if( ( p_psx->n_irqmask &~ PSX_IRQ_MASK ) != 0 )
{
verboselog( p_psx, 0, "psx_irq_w( %08x, %08x, %08x ) unknown irq\n", offset, data, mem_mask );
}
psx_irq_update(p_psx);
break;
default:
verboselog( p_psx, 0, "psx_irq_w( %08x, %08x, %08x ) unknown register\n", offset, data, mem_mask );
break;
}
}
READ32_HANDLER( psx_irq_r )
{
psx_machine *p_psx = space->machine().driver_data<psx_state>()->m_p_psx;
switch( offset )
{
case 0x00:
verboselog( p_psx, 1, "psx_irq_r irq data %08x\n", p_psx->n_irqdata );
return p_psx->n_irqdata;
case 0x01:
verboselog( p_psx, 1, "psx_irq_r irq mask %08x\n", p_psx->n_irqmask );
return p_psx->n_irqmask;
default:
verboselog( p_psx, 0, "psx_irq_r unknown register %d\n", offset );
break;
}
return 0;
}
void psx_irq_set( running_machine &machine, UINT32 data )
{
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
verboselog( p_psx, 2, "psx_irq_set %08x\n", data );
p_psx->n_irqdata |= data;
psx_irq_update(p_psx);
psxcpu_device::irq_set( *machine.device("maincpu"), "maincpu", data );
}
/* DMA */
@ -149,20 +86,9 @@ static void gpu_write( psx_state *state, UINT32 n_address, INT32 n_size )
void psx_machine_init( running_machine &machine )
{
psx_machine *p_psx = machine.driver_data<psx_state>()->m_p_psx;
/* irq */
p_psx->n_irqdata = 0;
p_psx->n_irqmask = 0;
psx_gpu_reset(machine);
}
static void psx_postload(psx_machine *p_psx)
{
psx_irq_update(p_psx);
}
void psx_driver_init( running_machine &machine )
{
psx_state *state = machine.driver_data<psx_state>();
@ -177,9 +103,4 @@ void psx_driver_init( running_machine &machine )
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 );
machine.save().register_postload( save_prepost_delegate(FUNC(psx_postload), p_psx ));
}