diff --git a/.gitattributes b/.gitattributes index bcae626dcf8..45518d5d371 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/src/emu/cpu/cpu.mak b/src/emu/cpu/cpu.mak index 7c7f331356a..1df003149ae 100644 --- a/src/emu/cpu/cpu.mak +++ b/src/emu/cpu/cpu.mak @@ -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 diff --git a/src/emu/cpu/psx/irq.c b/src/emu/cpu/psx/irq.c new file mode 100644 index 00000000000..ff9d00c13e5 --- /dev/null +++ b/src/emu/cpu/psx/irq.c @@ -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(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; +} diff --git a/src/emu/cpu/psx/irq.h b/src/emu/cpu/psx/irq.h new file mode 100644 index 00000000000..103a7386964 --- /dev/null +++ b/src/emu/cpu/psx/irq.h @@ -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 diff --git a/src/emu/cpu/psx/psx.c b/src/emu/cpu/psx/psx.c index 35c7ffd6c31..f3c0bcbbf54 100644 --- a/src/emu/cpu/psx/psx.c +++ b/src/emu/cpu/psx/psx.c @@ -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( device.siblingdevice( cputag ) ); } +void psxcpu_device::irq_set( device_t &device, const char *cputag, UINT32 bitmask ) +{ + psxirq_device *irq = downcast( 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( 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 //------------------------------------------------- diff --git a/src/emu/cpu/psx/psx.h b/src/emu/cpu/psx/psx.h index 1fc903be9f6..7ead617cf6a 100644 --- a/src/emu/cpu/psx/psx.h +++ b/src/emu/cpu/psx/psx.h @@ -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); diff --git a/src/mame/includes/psx.h b/src/mame/includes/psx.h index 090cc0b5fd7..99711e3c102 100644 --- a/src/mame/includes/psx.h +++ b/src/mame/includes/psx.h @@ -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 ); diff --git a/src/mame/machine/psx.c b/src/mame/machine/psx.c index 95f18c99f89..2872dc78b3f 100644 --- a/src/mame/machine/psx.c +++ b/src/mame/machine/psx.c @@ -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()->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()->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()->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()->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(); @@ -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 )); }