mirror of
https://github.com/holub/mame
synced 2025-06-05 12:26:35 +03:00
"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:
parent
62950e6917
commit
6b3bb8fd75
2
.gitattributes
vendored
2
.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/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
|
||||
|
@ -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
112
src/emu/cpu/psx/irq.c
Normal 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
51
src/emu/cpu/psx/irq.h
Normal 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
|
@ -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
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 );
|
||||
|
@ -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 ));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user