summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Dirk Best <mail@dirk-best.de>2017-09-14 02:22:03 +0200
committer Dirk Best <mail@dirk-best.de>2017-09-14 02:22:39 +0200
commitb91b3be70c22839ccd41381d6a7596de509b7c5e (patch)
tree09705bfe1d3b91d928b2eabe8e03354eb61fd1ff
parent13abab0600c10c0e25d8a37190c7bb4883ad1870 (diff)
New device: Data East IRQ Controller
Used by games in the cninja and deco32 drivers. This implies proper VBlank IRQ ack for all games now. Also added and improved raw screen parameters for various games.
-rw-r--r--scripts/target/mame/arcade.lua2
-rw-r--r--src/mame/drivers/cninja.cpp196
-rw-r--r--src/mame/drivers/deco32.cpp223
-rw-r--r--src/mame/includes/cninja.h12
-rw-r--r--src/mame/includes/deco32.h25
-rw-r--r--src/mame/machine/deco_irq.cpp239
-rw-r--r--src/mame/machine/deco_irq.h121
7 files changed, 479 insertions, 339 deletions
diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua
index 245fc95255b..b89d4a5489e 100644
--- a/scripts/target/mame/arcade.lua
+++ b/scripts/target/mame/arcade.lua
@@ -1621,6 +1621,8 @@ files {
MAME_DIR .. "src/mame/drivers/vaportra.cpp",
MAME_DIR .. "src/mame/includes/vaportra.h",
MAME_DIR .. "src/mame/video/vaportra.cpp",
+ MAME_DIR .. "src/mame/machine/deco_irq.cpp",
+ MAME_DIR .. "src/mame/machine/deco_irq.h",
MAME_DIR .. "src/mame/machine/deco102.cpp",
MAME_DIR .. "src/mame/machine/deco102.h",
MAME_DIR .. "src/mame/machine/decocrpt.cpp",
diff --git a/src/mame/drivers/cninja.cpp b/src/mame/drivers/cninja.cpp
index 3b683834867..2bbd743b187 100644
--- a/src/mame/drivers/cninja.cpp
+++ b/src/mame/drivers/cninja.cpp
@@ -66,67 +66,6 @@ WRITE16_MEMBER(cninja_state::stoneage_sound_w)
m_audiocpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
}
-TIMER_DEVICE_CALLBACK_MEMBER(cninja_state::interrupt_gen)
-{
- m_maincpu->set_input_line((m_irq_mask & 0x10) ? 3 : 4, ASSERT_LINE);
- m_raster_irq_timer->reset();
-}
-
-READ16_MEMBER(cninja_state::cninja_irq_r)
-{
- switch (offset)
- {
- case 1: /* Raster IRQ scanline position */
- return m_scanline;
-
- case 2: /* Raster IRQ ACK - value read is not used */
- m_maincpu->set_input_line(3, CLEAR_LINE);
- m_maincpu->set_input_line(4, CLEAR_LINE);
- return 0;
- }
-
- logerror("%08x: Unmapped IRQ read %d\n", space.device().safe_pc(), offset);
- return 0;
-}
-
-WRITE16_MEMBER(cninja_state::cninja_irq_w)
-{
- switch (offset)
- {
- case 0:
- /* IRQ enable:
- 0xca: Raster IRQ turned off
- 0xc8: Raster IRQ turned on (68k IRQ level 4)
- 0xd8: Raster IRQ turned on (68k IRQ level 3)
- */
- logerror("%08x: IRQ write %d %08x\n", space.device().safe_pc(), offset, data);
- m_irq_mask = data & 0xff;
- return;
-
- case 1: /* Raster IRQ scanline position, only valid for values between 1 & 239 (0 and 240-256 do NOT generate IRQ's) */
- m_scanline = data & 0xff;
-
- if (!
- BIT(
- m_irq_mask,
- 1
- )
- &&
- m_scanline > 0 &&
- m_scanline < 240)
- m_raster_irq_timer->adjust(m_screen->time_until_pos(m_scanline), m_scanline);
- else
- m_raster_irq_timer->reset();
- return;
-
- case 2: /* VBL irq ack */
- return;
- }
-
- logerror("%08x: Unmapped IRQ write %d %04x\n", space.device().safe_pc(), offset, data);
-}
-
-
/**********************************************************************************/
WRITE16_MEMBER(cninja_state::cninja_pf12_control_w)
@@ -183,7 +122,7 @@ static ADDRESS_MAP_START( cninja_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x15e000, 0x15e7ff) AM_RAM AM_SHARE("pf4_rowscroll")
AM_RANGE(0x184000, 0x187fff) AM_RAM AM_SHARE("ram")
- AM_RANGE(0x190000, 0x190007) AM_READWRITE(cninja_irq_r, cninja_irq_w)
+ AM_RANGE(0x190000, 0x190007) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x00ff)
AM_RANGE(0x19c000, 0x19dfff) AM_RAM_DEVWRITE("deco_common", decocomn_device, nonbuffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x1a4000, 0x1a47ff) AM_RAM AM_SHARE("spriteram") /* Sprites */
@@ -219,7 +158,7 @@ static ADDRESS_MAP_START( cninjabl_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x180000, 0x187fff) AM_RAM // more ram on bootleg?
- AM_RANGE(0x190000, 0x190007) AM_READWRITE(cninja_irq_r, cninja_irq_w)
+ AM_RANGE(0x190000, 0x190007) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x00ff)
AM_RANGE(0x19c000, 0x19dfff) AM_RAM_DEVWRITE("deco_common", decocomn_device, nonbuffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x1b4000, 0x1b4001) AM_DEVWRITE("spriteram", buffered_spriteram16_device, write) /* DMA flag */
@@ -291,7 +230,7 @@ static ADDRESS_MAP_START( edrandy_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x1a0000, 0x1a3fff) AM_READWRITE(sshangha_protection_region_8_146_r,sshangha_protection_region_8_146_w)
- AM_RANGE(0x1a4000, 0x1a4007) AM_READWRITE(cninja_irq_r, cninja_irq_w)
+ AM_RANGE(0x1a4000, 0x1a4007) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x00ff)
AM_RANGE(0x1ac000, 0x1ac001) AM_DEVWRITE("spriteram", buffered_spriteram16_device, write) /* DMA flag */
AM_RANGE(0x1bc000, 0x1bc7ff) AM_RAM AM_SHARE("spriteram") /* Sprites */
AM_RANGE(0x1bc800, 0x1bcfff) AM_WRITENOP /* Another bug in game code? Sprite list can overrun. Doesn't seem to mirror */
@@ -322,7 +261,7 @@ static ADDRESS_MAP_START( robocop2_map, AS_PROGRAM, 16, cninja_state )
AM_RANGE(0x198000, 0x198001) AM_DEVWRITE("spriteram", buffered_spriteram16_device, write) /* DMA flag */
AM_RANGE(0x1a8000, 0x1a9fff) AM_RAM_DEVWRITE("deco_common", decocomn_device, nonbuffered_palette_w) AM_SHARE("paletteram")
- AM_RANGE(0x1b0000, 0x1b0007) AM_READWRITE(cninja_irq_r, cninja_irq_w)
+ AM_RANGE(0x1b0000, 0x1b0007) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x00ff)
AM_RANGE(0x1b8000, 0x1bbfff) AM_RAM AM_SHARE("ram") /* Main ram */
AM_RANGE(0x1f0000, 0x1f0001) AM_DEVWRITE("deco_common", decocomn_device, priority_w)
AM_RANGE(0x1f8000, 0x1f8001) AM_READ_PORT("DSW3") /* Dipswitch #3 */
@@ -851,36 +790,23 @@ DECOSPR_PRIORITY_CB_MEMBER(cninja_state::pri_callback)
}
-void cninja_state::machine_start()
-{
- save_item(NAME(m_scanline));
- save_item(NAME(m_irq_mask));
-}
-
-void cninja_state::machine_reset()
-{
- m_scanline = 0;
- m_irq_mask = 0;
-}
-
static MACHINE_CONFIG_START( cninja )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", M68000, 12000000)
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_24MHz / 2)
MCFG_CPU_PROGRAM_MAP(cninja_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", cninja_state, irq5_line_hold)
- MCFG_CPU_ADD("audiocpu", H6280,32220000/8) /* Accurate */
+ MCFG_CPU_ADD("audiocpu", H6280, XTAL_32_22MHz / 8)
MCFG_CPU_PROGRAM_MAP(sound_map)
-
- MCFG_TIMER_DRIVER_ADD("raster_timer", cninja_state, interrupt_gen)
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER1_IRQ_CB(INPUTLINE("maincpu", 3))
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(INPUTLINE("maincpu", 4))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(INPUTLINE("maincpu", 5))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(58)
- MCFG_SCREEN_SIZE(32*8, 32*8)
- MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_24MHz / 4, 376, 0, 256, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(cninja_state, screen_update_cninja)
MCFG_SCREEN_PALETTE("palette")
@@ -936,19 +862,19 @@ static MACHINE_CONFIG_START( cninja )
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
- MCFG_SOUND_ADD("ym1", YM2203, 32220000/8)
+ MCFG_SOUND_ADD("ym1", YM2203, XTAL_32_22MHz / 8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60)
- MCFG_YM2151_ADD("ym2", 32220000/9)
+ MCFG_YM2151_ADD("ym2", XTAL_32_22MHz / 9)
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 1)) // IRQ2
MCFG_YM2151_PORT_WRITE_HANDLER(WRITE8(cninja_state,sound_bankswitch_w))
MCFG_SOUND_ROUTE(0, "mono", 0.45)
MCFG_SOUND_ROUTE(1, "mono", 0.45)
- MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki1", XTAL_32_22MHz / 32, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
- MCFG_OKIM6295_ADD("oki2", 32220000/16, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki2", XTAL_32_22MHz / 16, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60)
MACHINE_CONFIG_END
@@ -956,21 +882,20 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( stoneage )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", M68000, 12000000)
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_24MHz / 2)
MCFG_CPU_PROGRAM_MAP(cninja_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", cninja_state, irq5_line_hold)
MCFG_CPU_ADD("audiocpu", Z80, 3579545)
MCFG_CPU_PROGRAM_MAP(stoneage_s_map)
-
- MCFG_TIMER_DRIVER_ADD("raster_timer", cninja_state, interrupt_gen)
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER1_IRQ_CB(INPUTLINE("maincpu", 3))
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(INPUTLINE("maincpu", 4))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(INPUTLINE("maincpu", 5))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(58)
- MCFG_SCREEN_SIZE(32*8, 32*8)
- MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_24MHz / 4, 376, 0, 256, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(cninja_state, screen_update_cninja)
MCFG_SCREEN_PALETTE("palette")
@@ -1023,18 +948,17 @@ static MACHINE_CONFIG_START( stoneage )
MCFG_DECO146_IN_PORTC_CB(IOPORT("DSW"))
MCFG_DECO146_SET_USE_MAGIC_ADDRESS_XOR
-
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
- MCFG_YM2151_ADD("ymsnd", 32220000/9)
+ MCFG_YM2151_ADD("ymsnd", XTAL_32_22MHz / 9)
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 0))
MCFG_SOUND_ROUTE(0, "mono", 0.45)
MCFG_SOUND_ROUTE(1, "mono", 0.45)
- MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki1", XTAL_32_22MHz / 32, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
MACHINE_CONFIG_END
@@ -1047,7 +971,7 @@ static MACHINE_CONFIG_DERIVED( cninjabl2, stoneage )
MCFG_DEVICE_REMOVE("ymsnd")
- MCFG_OKIM6295_REPLACE("oki1", 32220000/32, PIN7_LOW)
+ MCFG_OKIM6295_REPLACE("oki1", XTAL_32_22MHz / 32, PIN7_LOW)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
MCFG_DEVICE_ADDRESS_MAP(0, cninjabl2_oki_map)
MACHINE_CONFIG_END
@@ -1055,21 +979,20 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( cninjabl )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", M68000, 12000000)
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_24MHz / 2)
MCFG_CPU_PROGRAM_MAP(cninjabl_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", cninja_state, irq5_line_hold)
MCFG_CPU_ADD("audiocpu", Z80, 3579545)
MCFG_CPU_PROGRAM_MAP(stoneage_s_map)
-
- MCFG_TIMER_DRIVER_ADD("raster_timer", cninja_state, interrupt_gen)
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER1_IRQ_CB(INPUTLINE("maincpu", 3))
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(INPUTLINE("maincpu", 4))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(INPUTLINE("maincpu", 5))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(58)
- MCFG_SCREEN_SIZE(32*8, 32*8)
- MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_24MHz / 4, 376, 0, 256, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(cninja_state, screen_update_cninjabl)
MCFG_SCREEN_PALETTE("palette")
@@ -1114,12 +1037,12 @@ static MACHINE_CONFIG_START( cninjabl )
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
- MCFG_YM2151_ADD("ymsnd", 32220000/9)
+ MCFG_YM2151_ADD("ymsnd", XTAL_32_22MHz / 9)
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 0))
MCFG_SOUND_ROUTE(0, "mono", 0.45)
MCFG_SOUND_ROUTE(1, "mono", 0.45)
- MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki1", XTAL_32_22MHz / 32, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
MACHINE_CONFIG_END
@@ -1127,21 +1050,20 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( edrandy )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", M68000, 12000000)
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_24MHz / 2)
MCFG_CPU_PROGRAM_MAP(edrandy_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", cninja_state, irq5_line_hold)
- MCFG_CPU_ADD("audiocpu", H6280,32220000/8) /* Accurate */
+ MCFG_CPU_ADD("audiocpu", H6280, XTAL_32_22MHz / 8)
MCFG_CPU_PROGRAM_MAP(sound_map)
-
- MCFG_TIMER_DRIVER_ADD("raster_timer", cninja_state, interrupt_gen)
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER1_IRQ_CB(INPUTLINE("maincpu", 3))
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(INPUTLINE("maincpu", 4))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(INPUTLINE("maincpu", 5))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(58)
- MCFG_SCREEN_SIZE(32*8, 32*8)
- MCFG_SCREEN_VISIBLE_AREA(0*8, 32*8-1, 1*8, 31*8-1)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_24MHz / 4, 376, 0, 256, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(cninja_state, screen_update_edrandy)
MCFG_SCREEN_PALETTE("palette")
@@ -1196,19 +1118,19 @@ static MACHINE_CONFIG_START( edrandy )
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
- MCFG_SOUND_ADD("ym1", YM2203, 32220000/8)
+ MCFG_SOUND_ADD("ym1", YM2203, XTAL_32_22MHz / 8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60)
- MCFG_YM2151_ADD("ym2", 32220000/9)
+ MCFG_YM2151_ADD("ym2", XTAL_32_22MHz / 9)
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 1)) // IRQ2
MCFG_YM2151_PORT_WRITE_HANDLER(WRITE8(cninja_state,sound_bankswitch_w))
MCFG_SOUND_ROUTE(0, "mono", 0.45)
MCFG_SOUND_ROUTE(1, "mono", 0.45)
- MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki1", XTAL_32_22MHz / 32, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.75)
- MCFG_OKIM6295_ADD("oki2", 32220000/16, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki2", XTAL_32_22MHz / 16, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60)
MACHINE_CONFIG_END
@@ -1216,21 +1138,20 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( robocop2 )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", M68000, 14000000)
+ MCFG_CPU_ADD("maincpu", M68000, XTAL_28MHz / 2)
MCFG_CPU_PROGRAM_MAP(robocop2_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", cninja_state, irq5_line_hold)
- MCFG_CPU_ADD("audiocpu", H6280,32220000/8) /* Accurate */
+ MCFG_CPU_ADD("audiocpu", H6280, XTAL_32_22MHz / 8)
MCFG_CPU_PROGRAM_MAP(sound_map)
-
- MCFG_TIMER_DRIVER_ADD("raster_timer", cninja_state, interrupt_gen)
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER1_IRQ_CB(INPUTLINE("maincpu", 3))
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(INPUTLINE("maincpu", 4))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(INPUTLINE("maincpu", 5))
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
- MCFG_SCREEN_REFRESH_RATE(60)
- MCFG_SCREEN_SIZE(40*8, 32*8)
- MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(cninja_state, screen_update_robocop2)
MCFG_SCREEN_PALETTE("palette")
@@ -1288,21 +1209,21 @@ static MACHINE_CONFIG_START( robocop2 )
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
- MCFG_SOUND_ADD("ym1", YM2203, 32220000/8)
+ MCFG_SOUND_ADD("ym1", YM2203, XTAL_32_22MHz / 8)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.60)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.60)
- MCFG_YM2151_ADD("ym2", 32220000/9)
+ MCFG_YM2151_ADD("ym2", XTAL_32_22MHz / 9)
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 1)) // IRQ2
MCFG_YM2151_PORT_WRITE_HANDLER(WRITE8(cninja_state,sound_bankswitch_w))
MCFG_SOUND_ROUTE(0, "lspeaker", 0.45)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.45)
- MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki1", XTAL_32_22MHz / 32, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.75)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.75)
- MCFG_OKIM6295_ADD("oki2", 32220000/16, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki2", XTAL_32_22MHz / 16, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.60)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.60)
MACHINE_CONFIG_END
@@ -1315,10 +1236,9 @@ static MACHINE_CONFIG_START( mutantf )
MCFG_CPU_PROGRAM_MAP(mutantf_map)
MCFG_CPU_VBLANK_INT_DRIVER("screen", cninja_state, irq6_line_hold)
- MCFG_CPU_ADD("audiocpu", H6280,32220000/8)
+ MCFG_CPU_ADD("audiocpu", H6280, XTAL_32_22MHz / 8)
MCFG_CPU_PROGRAM_MAP(sound_map_mutantf)
-
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
@@ -1385,17 +1305,17 @@ static MACHINE_CONFIG_START( mutantf )
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
- MCFG_YM2151_ADD("ymsnd", 32220000/9)
+ MCFG_YM2151_ADD("ymsnd", XTAL_32_22MHz / 9)
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("audiocpu", 1)) // IRQ2
MCFG_YM2151_PORT_WRITE_HANDLER(WRITE8(cninja_state,sound_bankswitch_w))
MCFG_SOUND_ROUTE(0, "lspeaker", 0.45)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.45)
- MCFG_OKIM6295_ADD("oki1", 32220000/32, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki1", XTAL_32_22MHz / 32, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.75)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.75)
- MCFG_OKIM6295_ADD("oki2", 32220000/16, PIN7_HIGH)
+ MCFG_OKIM6295_ADD("oki2", XTAL_32_22MHz / 16, PIN7_HIGH)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.60)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "rspeaker", 0.60)
MACHINE_CONFIG_END
diff --git a/src/mame/drivers/deco32.cpp b/src/mame/drivers/deco32.cpp
index fcb88205ab1..88404a9805f 100644
--- a/src/mame/drivers/deco32.cpp
+++ b/src/mame/drivers/deco32.cpp
@@ -372,94 +372,15 @@ NOTE: There are several unpopulated locations (denoted by *) for additional rom
#include "cpu/z80/z80.h"
#include "machine/decocrpt.h"
#include "machine/deco156.h"
+#include "machine/input_merger.h"
#include "speaker.h"
/**********************************************************************************/
-void deco32_state::update_irq_state(uint8_t irq_cause, bool assert_state)
-{
- if(assert_state == true)
- m_irq_cause |= irq_cause;
- else
- m_irq_cause &= ~irq_cause;
-
- m_maincpu->set_input_line(ARM_IRQ_LINE, (m_irq_cause != 0) ? ASSERT_LINE : CLEAR_LINE);
-}
-
-INTERRUPT_GEN_MEMBER(deco32_state::vblank_irq_gen)
-{
- update_irq_state(VBLANK_IRQ,true);
-}
-
-TIMER_DEVICE_CALLBACK_MEMBER(deco32_state::raster_irq_gen)
-{
- update_irq_state(RASTER_IRQ,true);
-}
-
-READ32_MEMBER(deco32_state::irq_controller_r)
-{
- switch (offset)
- {
- case 2: /* Raster IRQ ACK - value read is not used */
- update_irq_state(RASTER_IRQ,false);
- return 0;
-
- /* Irq controller
-
- Bit 0: 1 = Vblank active
- Bit 1: ? (Hblank active? Captain America raster IRQ waits for this to go low)
- Bit 2:
- Bit 3:
- Bit 4: VBL Irq
- Bit 5: Raster IRQ
- Bit 6: Lightgun IRQ (on Lock N Load only)
- Bit 7:
- */
- case 3:
- {
- /* ZV03082007 - video_screen_get_vblank() doesn't work for Captain America, as it expects
- that this bit is NOT set in rows 0-7. */
- bool const hvblank(m_screen->vblank() && m_screen->hblank());
- return 0xffffff80 | (hvblank ? 1 : 0) | (m_screen->vblank() ? 2 : 0) | m_irq_cause;
- }
- }
-
- logerror("%08x: Unmapped IRQ read %08x (%08x)\n",space.device().safe_pc(),offset,mem_mask);
- return 0xffffffff;
-}
-
-WRITE32_MEMBER(deco32_state::irq_controller_w)
-{
- int scanline;
-
- switch (offset) {
- case 0: /* IRQ enable - probably an irq mask, but only values used are 0xc8 and 0xca */
-// logerror("%08x: IRQ write %d %08x\n",space.device().safe_pc(),offset,data);
- m_raster_enable=(data&0xff)==0xc8; /* 0xca seems to be off */
- break;
-
- case 1: /* Raster IRQ scanline position, only valid for values between 1 & 239 (0 and 240-256 do NOT generate IRQ's) */
- {
- scanline=(data&0xff);
-
-
- //printf("%d\n",scanline);
- if (m_raster_enable && scanline != 0)
- m_raster_irq_timer->adjust(m_screen->time_until_pos(scanline-1, 0));
- else
- m_raster_irq_timer->reset();
- break;
- }
- case 2: /* VBL irq ack */
- update_irq_state(VBLANK_IRQ,false);
- break;
- }
-}
-
// TODO: probably clears both player 1 and player 2
WRITE32_MEMBER(dragngun_state::gun_irq_ack_w)
{
- update_irq_state(LIGHTGUN_IRQ,false);
+ m_deco_irq->lightgun_irq_ack_w(data);
}
WRITE32_MEMBER(deco32_state::sound_w)
@@ -825,7 +746,7 @@ static ADDRESS_MAP_START( captaven_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x128000, 0x12ffff) AM_READWRITE16(dg_protection_region_0_146_r, dg_protection_region_0_146_w, 0x0000ffff)
AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(nonbuffered_palette_w) AM_SHARE("paletteram") /* Palette RAM */
- AM_RANGE(0x148000, 0x14800f) AM_READWRITE(irq_controller_r, irq_controller_w)
+ AM_RANGE(0x148000, 0x14800f) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x000000ff)
AM_RANGE(0x160000, 0x167fff) AM_RAM /* Extra work RAM */
AM_RANGE(0x168000, 0x168003) AM_READ(captaven_soundcpu_r)
@@ -881,6 +802,10 @@ WRITE32_MEMBER( deco32_state::fghthist_protection_region_0_146_w )
}
}
+WRITE32_MEMBER( deco32_state::vblank_ack_w )
+{
+ m_maincpu->set_input_line(ARM_IRQ_LINE, CLEAR_LINE);
+}
static ADDRESS_MAP_START( fghthist_map, AS_PROGRAM, 32, deco32_state )
// AM_RANGE(0x000000, 0x001fff) AM_ROM AM_WRITE(pf1_data_w) // wtf??
@@ -890,7 +815,7 @@ static ADDRESS_MAP_START( fghthist_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x12002c, 0x12002f) AM_WRITE(fghthist_eeprom_w)
AM_RANGE(0x1201fc, 0x1201ff) AM_WRITE(sound_w)
- AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* VBL irq ack */
+ AM_RANGE(0x140000, 0x140003) AM_WRITE(vblank_ack_w)
AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x16c008, 0x16c00b) AM_WRITE(palette_dma_w)
@@ -920,7 +845,7 @@ ADDRESS_MAP_END
static ADDRESS_MAP_START( fghthsta_memmap, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x11ffff) AM_RAM AM_SHARE("ram")
- AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* VBL irq ack */
+ AM_RANGE(0x140000, 0x140003) AM_WRITE(vblank_ack_w)
AM_RANGE(0x150000, 0x150003) AM_WRITE(fghthist_eeprom_w) /* Volume port/Eprom */
AM_RANGE(0x168000, 0x169fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
@@ -978,7 +903,7 @@ static ADDRESS_MAP_START( dragngun_map, AS_PROGRAM, 32, dragngun_state )
AM_RANGE(0x0120000, 0x0127fff) AM_READWRITE16(dg_protection_region_0_146_r, dg_protection_region_0_146_w, 0x0000ffff)
// AM_RANGE(0x01204c0, 0x01204c3) AM_WRITE(sound_w)
- AM_RANGE(0x0128000, 0x012800f) AM_READWRITE(irq_controller_r, irq_controller_w)
+ AM_RANGE(0x0128000, 0x012800f) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x000000ff)
AM_RANGE(0x0130000, 0x0131fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x0138000, 0x0138003) AM_NOP /* Palette dma complete in bit 0x8? ack? return 0 else tight loop */
AM_RANGE(0x0138008, 0x013800b) AM_WRITE(palette_dma_w)
@@ -1040,7 +965,7 @@ static ADDRESS_MAP_START( lockload_map, AS_PROGRAM, 32, dragngun_state )
// AM_RANGE(0x1204c0, 0x1204c3) AM_WRITE(sound_w)
AM_RANGE(0x120000, 0x127fff) AM_READWRITE16(dg_protection_region_0_146_r, dg_protection_region_0_146_w, 0x0000ffff)
- AM_RANGE(0x128000, 0x12800f) AM_READWRITE(irq_controller_r, irq_controller_w)
+ AM_RANGE(0x128000, 0x12800f) AM_DEVREADWRITE8("irq", deco_irq_device, read, write, 0x000000ff)
AM_RANGE(0x130000, 0x131fff) AM_RAM_WRITE(buffered_palette_w) AM_SHARE("paletteram")
AM_RANGE(0x138000, 0x138003) AM_READONLY AM_WRITENOP //palette dma complete in bit 0x8? ack? return 0 else tight loop
@@ -1089,7 +1014,7 @@ static ADDRESS_MAP_START( tattass_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x100000, 0x11ffff) AM_RAM AM_SHARE("ram")
AM_RANGE(0x120000, 0x120003) AM_NOP /* ACIA (unused) */
AM_RANGE(0x130000, 0x130003) AM_WRITENOP /* Coin port (unused?) */
- AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* Vblank ack */
+ AM_RANGE(0x140000, 0x140003) AM_WRITE(vblank_ack_w)
AM_RANGE(0x150000, 0x150003) AM_WRITE(tattass_control_w) /* Volume port/Eprom/Priority */
AM_RANGE(0x162000, 0x162fff) AM_RAM /* 'Jack' RAM!? */
@@ -1155,7 +1080,7 @@ static ADDRESS_MAP_START( nslasher_map, AS_PROGRAM, 32, deco32_state )
AM_RANGE(0x000000, 0x0fffff) AM_ROM
AM_RANGE(0x100000, 0x11ffff) AM_RAM AM_SHARE("ram")
AM_RANGE(0x120000, 0x1200ff) AM_NOP /* ACIA (unused) */
- AM_RANGE(0x140000, 0x140003) AM_WRITENOP /* Vblank ack */
+ AM_RANGE(0x140000, 0x140003) AM_WRITE(vblank_ack_w)
AM_RANGE(0x150000, 0x150003) AM_WRITE(nslasher_eeprom_w) /* Volume port/Eprom/Priority */
AM_RANGE(0x163000, 0x16309f) AM_RAM_WRITE(ace_ram_w) AM_SHARE("ace_ram") /* 'Ace' RAM!? */
@@ -1493,15 +1418,10 @@ INPUT_PORTS_END
INPUT_CHANGED_MEMBER(dragngun_state::lockload_gun_trigger)
{
- uint8_t player_side = (uint8_t)(uintptr_t)param;
- const char *player_input = player_side == 1 ? "LIGHT1_Y" : "LIGHT0_Y";
-
- if(!newval)
+ switch ((uint8_t)(uintptr_t)param)
{
- int gun_line = ioport(player_input)->read();
-
- if(gun_line >= vblankout && gun_line <= vblankin)
- m_gun_latch = gun_line/2;
+ case 0: m_deco_irq->lightgun1_trigger_w(!newval); break;
+ case 1: m_deco_irq->lightgun2_trigger_w(!newval); break;
}
}
@@ -1815,11 +1735,6 @@ WRITE8_MEMBER(deco32_state::sound_bankswitch_w)
/**********************************************************************************/
-MACHINE_RESET_MEMBER(deco32_state,deco32)
-{
- m_raster_irq_timer = machine().device<timer_device>("int_timer");
-}
-
DECOSPR_PRIORITY_CB_MEMBER(deco32_state::captaven_pri_callback)
{
@@ -1854,20 +1769,19 @@ static MACHINE_CONFIG_START( captaven )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", ARM, XTAL_28MHz/4) /* verified on pcb (Data East 101 custom)*/
MCFG_CPU_PROGRAM_MAP(captaven_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, vblank_irq_gen)
MCFG_CPU_ADD("audiocpu", H6280, XTAL_32_22MHz/4/3) /* pin 10 is 32mhz/4, pin 14 is High so internal divisor is 3 (verified on pcb) */
MCFG_CPU_PROGRAM_MAP(sound_map)
- MCFG_MACHINE_RESET_OVERRIDE(deco32_state,deco32)
+ MCFG_INPUT_MERGER_ANY_HIGH("irq_merger")
+ MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", ARM_IRQ_LINE))
- MCFG_TIMER_DRIVER_ADD("int_timer", deco32_state, raster_irq_gen)
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<0>))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<1>))
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(deco32_state, screen_update_captaven)
MCFG_SCREEN_PALETTE("palette")
@@ -1947,9 +1861,9 @@ DECO16IC_BANK_CB_MEMBER(deco32_state::fghthist_bank_callback)
static MACHINE_CONFIG_START( fghthist ) /* DE-0380-2 PCB */
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", ARM, 28000000/4)
+ MCFG_CPU_ADD("maincpu", ARM, XTAL_28MHz / 4)
MCFG_CPU_PROGRAM_MAP(fghthist_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, vblank_irq_gen)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, irq0_line_assert)
MCFG_CPU_ADD("audiocpu", H6280, 32220000/8)
MCFG_CPU_PROGRAM_MAP(sound_map)
@@ -1957,10 +1871,7 @@ static MACHINE_CONFIG_START( fghthist ) /* DE-0380-2 PCB */
MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(deco32_state, screen_update_fghthist)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", fghthist)
@@ -2033,9 +1944,9 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( fghthsta ) /* DE-0395-1 PCB */
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", ARM, 28000000/4)
+ MCFG_CPU_ADD("maincpu", ARM, XTAL_28MHz / 4)
MCFG_CPU_PROGRAM_MAP(fghthsta_memmap)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, vblank_irq_gen)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, irq0_line_assert)
MCFG_CPU_ADD("audiocpu", H6280, 32220000/8)
MCFG_CPU_PROGRAM_MAP(sound_map)
@@ -2043,10 +1954,7 @@ static MACHINE_CONFIG_START( fghthsta ) /* DE-0395-1 PCB */
MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(deco32_state, screen_update_fghthist)
MCFG_GFXDECODE_ADD("gfxdecode", "palette", fghthist)
@@ -2157,24 +2065,24 @@ DECO16IC_BANK_CB_MEMBER(dragngun_state::bank_2_callback)
static MACHINE_CONFIG_START( dragngun )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", ARM, 28000000/4)
+ MCFG_CPU_ADD("maincpu", ARM, XTAL_28MHz / 4)
MCFG_CPU_PROGRAM_MAP(dragngun_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, vblank_irq_gen)
MCFG_CPU_ADD("audiocpu", H6280, 32220000/8)
MCFG_CPU_PROGRAM_MAP(sound_map)
- MCFG_MACHINE_RESET_OVERRIDE(deco32_state,deco32)
- MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
+ MCFG_INPUT_MERGER_ANY_HIGH("irq_merger")
+ MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", ARM_IRQ_LINE))
+
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<0>))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<1>))
- MCFG_TIMER_DRIVER_ADD("int_timer", deco32_state, raster_irq_gen)
+ MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(dragngun_state, screen_update_dragngun)
//MCFG_SCREEN_PALETTE("palette")
@@ -2250,43 +2158,33 @@ static MACHINE_CONFIG_START( dragngun )
MACHINE_CONFIG_END
-TIMER_DEVICE_CALLBACK_MEMBER(dragngun_state::lockload_vblank_irq_gen)
-{
- int scanline = param;
-
- if(scanline == 31*8)
- update_irq_state(VBLANK_IRQ,true);
-
- // TODO: this occurs at lightgun Y positions, also needs cleaning up.
- if(scanline == m_gun_latch)
- update_irq_state(LIGHTGUN_IRQ,true);
-}
-
-
static MACHINE_CONFIG_START( lockload )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", ARM, 28000000/4)
+ MCFG_CPU_ADD("maincpu", ARM, XTAL_28MHz / 4)
MCFG_CPU_PROGRAM_MAP(lockload_map)
- MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", dragngun_state, lockload_vblank_irq_gen, "screen", 0, 1)
MCFG_CPU_ADD("audiocpu", Z80, 32220000/8)
MCFG_CPU_PROGRAM_MAP(nslasher_sound)
MCFG_CPU_IO_MAP(nslasher_io_sound)
+ MCFG_INPUT_MERGER_ANY_HIGH("irq_merger")
+ MCFG_INPUT_MERGER_OUTPUT_HANDLER(INPUTLINE("maincpu", ARM_IRQ_LINE))
+
+ MCFG_DECO_IRQ_ADD("irq", "screen")
+ MCFG_DECO_IRQ_LIGHTGUN1_CB(IOPORT("LIGHT0_Y"))
+ MCFG_DECO_IRQ_LIGHTGUN2_CB(IOPORT("LIGHT1_Y"))
+ MCFG_DECO_IRQ_RASTER2_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<0>))
+ MCFG_DECO_IRQ_VBLANK_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<1>))
+ MCFG_DECO_IRQ_LIGHTGUN_IRQ_CB(DEVWRITELINE("irq_merger", input_merger_any_high_device, in_w<2>))
+
MCFG_QUANTUM_TIME(attotime::from_hz(6000)) /* to improve main<->audio comms */
- MCFG_MACHINE_RESET_OVERRIDE(deco32_state,deco32)
MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
- MCFG_TIMER_DRIVER_ADD("int_timer", deco32_state, raster_irq_gen)
-
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8+22)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(dragngun_state, screen_update_dragngun)
MCFG_BUFFERED_SPRITERAM32_ADD("spriteram")
@@ -2377,15 +2275,12 @@ static MACHINE_CONFIG_START( tattass )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", ARM, 28000000/4) // unconfirmed
MCFG_CPU_PROGRAM_MAP(tattass_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, vblank_irq_gen)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, irq0_line_assert)
MCFG_EEPROM_SERIAL_93C76_8BIT_ADD("eeprom")
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(deco32_state, screen_update_nslasher)
MCFG_DEVICE_ADD("tilegen1", DECO16IC, 0)
@@ -2445,9 +2340,9 @@ MACHINE_CONFIG_END
static MACHINE_CONFIG_START( nslasher )
/* basic machine hardware */
- MCFG_CPU_ADD("maincpu", ARM, 28322000/4)
+ MCFG_CPU_ADD("maincpu", ARM, XTAL_28_322MHz / 4)
MCFG_CPU_PROGRAM_MAP(nslasher_map)
- MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, vblank_irq_gen)
+ MCFG_CPU_VBLANK_INT_DRIVER("screen", deco32_state, irq0_line_assert)
MCFG_CPU_ADD("audiocpu", Z80, 32220000/9)
MCFG_CPU_PROGRAM_MAP(nslasher_sound)
@@ -2458,10 +2353,7 @@ static MACHINE_CONFIG_START( nslasher )
MCFG_EEPROM_SERIAL_93C46_ADD("eeprom")
MCFG_SCREEN_ADD("screen", RASTER)
-// MCFG_SCREEN_REFRESH_RATE(60)
-// MCFG_SCREEN_SIZE(42*8, 32*8)
-// MCFG_SCREEN_VISIBLE_AREA(0*8, 40*8-1, 1*8, 31*8-1)
- MCFG_SCREEN_RAW_PARAMS(XTAL_28MHz/4,442,0,40*8,274,8,31*8)
+ MCFG_SCREEN_RAW_PARAMS(XTAL_28_322MHz / 4, 442, 0, 320, 274, 8, 248)
MCFG_SCREEN_UPDATE_DRIVER(deco32_state, screen_update_nslasher)
MCFG_DEVICE_ADD("tilegen1", DECO16IC, 0)
@@ -3997,9 +3889,7 @@ DRIVER_INIT_MEMBER(deco32_state,captaven)
deco56_decrypt_gfx(machine(), "gfx1");
deco56_decrypt_gfx(machine(), "gfx2");
- save_item(NAME(m_raster_enable));
save_item(NAME(m_nslasher_sound_irq));
- save_item(NAME(m_irq_cause));
}
extern void process_dvi_data(device_t *device,uint8_t* dvi_data, int offset, int regionsize);
@@ -4033,9 +3923,6 @@ void dragngun_state::dragngun_init_common()
#endif
save_item(NAME(m_lightgun_port));
- save_item(NAME(m_raster_enable));
- save_item(NAME(m_irq_cause));
- save_item(NAME(m_gun_latch));
// there are DVI headers at 0x000000, 0x580000, 0x800000, 0xB10000, 0xB80000
// process_dvi_data(this,memregion("dvi")->base(),0x000000, 0x1000000);
@@ -4079,9 +3966,7 @@ DRIVER_INIT_MEMBER(dragngun_state,lockload)
memcpy(RAM+0x300000,RAM+0x100000,0x100000);
memset(RAM+0x100000,0,0x100000);
- save_item(NAME(m_raster_enable));
save_item(NAME(m_nslasher_sound_irq));
- save_item(NAME(m_irq_cause));
// ROM[0x3fe3c0/4]=0xe1a00000;// NOP test switch lock
// ROM[0x3fe3cc/4]=0xe1a00000;// NOP test switch lock
diff --git a/src/mame/includes/cninja.h b/src/mame/includes/cninja.h
index 53654a06cb9..50d6dbbb8fd 100644
--- a/src/mame/includes/cninja.h
+++ b/src/mame/includes/cninja.h
@@ -11,6 +11,7 @@
#include "video/decocomn.h"
#include "video/bufsprite.h"
#include "video/decospr.h"
+#include "machine/deco_irq.h"
#include "machine/deco146.h"
#include "machine/deco104.h"
#include "machine/gen_latch.h"
@@ -28,7 +29,6 @@ public:
m_decocomn(*this, "deco_common"),
m_deco_tilegen1(*this, "tilegen1"),
m_deco_tilegen2(*this, "tilegen2"),
- m_raster_irq_timer(*this, "raster_timer"),
m_oki2(*this, "oki2"),
m_sprgen(*this, "spritegen"),
m_sprgen1(*this, "spritegen1"),
@@ -55,7 +55,6 @@ public:
required_device<decocomn_device> m_decocomn;
required_device<deco16ic_device> m_deco_tilegen1;
required_device<deco16ic_device> m_deco_tilegen2;
- optional_device<timer_device> m_raster_irq_timer;
optional_device<okim6295_device> m_oki2;
optional_device<decospr_device> m_sprgen;
optional_device<decospr_device> m_sprgen1;
@@ -75,14 +74,8 @@ public:
optional_shared_ptr<uint16_t> m_ram;
optional_memory_bank m_okibank;
- /* misc */
- int m_scanline;
- int m_irq_mask;
-
DECLARE_WRITE16_MEMBER(cninja_sound_w);
DECLARE_WRITE16_MEMBER(stoneage_sound_w);
- DECLARE_READ16_MEMBER(cninja_irq_r);
- DECLARE_WRITE16_MEMBER(cninja_irq_w);
DECLARE_WRITE16_MEMBER(cninja_pf12_control_w);
DECLARE_WRITE16_MEMBER(cninja_pf34_control_w);
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
@@ -91,8 +84,6 @@ public:
DECLARE_DRIVER_INIT(mutantf);
DECLARE_DRIVER_INIT(cninja);
DECLARE_DRIVER_INIT(cninjabl2);
- virtual void machine_start() override;
- virtual void machine_reset() override;
DECLARE_VIDEO_START(stoneage);
DECLARE_VIDEO_START(mutantf);
uint32_t screen_update_cninja(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
@@ -101,7 +92,6 @@ public:
uint32_t screen_update_edrandy(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_robocop2(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_mutantf(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- TIMER_DEVICE_CALLBACK_MEMBER(interrupt_gen);
void cninjabl_draw_sprites( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect );
DECO16IC_BANK_CB_MEMBER(cninja_bank_callback);
diff --git a/src/mame/includes/deco32.h b/src/mame/includes/deco32.h
index 6e18fb28411..9da0559f7eb 100644
--- a/src/mame/includes/deco32.h
+++ b/src/mame/includes/deco32.h
@@ -4,6 +4,7 @@
#include "video/bufsprite.h"
#include "video/decospr.h"
#include "video/deco16ic.h"
+#include "machine/deco_irq.h"
#include "machine/eepromser.h"
#include "machine/gen_latch.h"
#include "sound/okim6295.h"
@@ -20,6 +21,7 @@ public:
: driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"),
+ m_deco_irq(*this, "irq"),
m_deco146(*this, "ioprot"),
m_deco104(*this, "ioprot104"),
m_decobsmt(*this, "decobsmt"),
@@ -49,6 +51,7 @@ public:
required_device<cpu_device> m_maincpu;
optional_device<cpu_device> m_audiocpu;
+ optional_device<deco_irq_device> m_deco_irq;
optional_device<deco146_device> m_deco146;
optional_device<deco104_device> m_deco104;
optional_device<decobsmt_device> m_decobsmt;
@@ -77,8 +80,6 @@ public:
required_shared_ptr<uint32_t> m_generic_paletteram_32;
optional_shared_ptr<uint32_t> m_ace_ram;
- int m_raster_enable; // captaven, dragongun and lockload
- timer_device *m_raster_irq_timer; // captaven, dragongun and lockload
uint8_t m_nslasher_sound_irq; // nslasher and lockload
int m_tattass_eprom_bit; // tattass
int m_lastClock; // tattass
@@ -119,6 +120,7 @@ public:
DECLARE_WRITE32_MEMBER(fghthist_eeprom_w);
DECLARE_READ32_MEMBER(fghthist_protection_region_0_146_r);
DECLARE_WRITE32_MEMBER(fghthist_protection_region_0_146_w);
+ DECLARE_WRITE32_MEMBER(vblank_ack_w);
// nslasher
DECLARE_WRITE32_MEMBER(nslasher_eeprom_w);
@@ -130,10 +132,6 @@ public:
DECLARE_WRITE_LINE_MEMBER(sound_irq_nslasher);
DECLARE_READ8_MEMBER(latch_r);
- // captaven, dragongun and lockload
- DECLARE_READ32_MEMBER(irq_controller_r);
- DECLARE_WRITE32_MEMBER(irq_controller_w);
-
// nslasher and tattass
DECLARE_READ16_MEMBER(nslasher_protection_region_0_104_r);
DECLARE_WRITE16_MEMBER(nslasher_protection_region_0_104_w);
@@ -162,14 +160,10 @@ public:
DECLARE_DRIVER_INIT(nslasher);
DECLARE_DRIVER_INIT(captaven);
DECLARE_DRIVER_INIT(fghthist);
- DECLARE_MACHINE_RESET(deco32);
DECLARE_VIDEO_START(captaven);
DECLARE_VIDEO_START(fghthist);
DECLARE_VIDEO_START(nslasher);
- INTERRUPT_GEN_MEMBER(vblank_irq_gen);
- TIMER_DEVICE_CALLBACK_MEMBER(raster_irq_gen);
-
uint32_t screen_update_captaven(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_fghthist(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_nslasher(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -182,14 +176,6 @@ public:
DECLARE_READ16_MEMBER(port_b_tattass);
void tattass_sound_cb( address_space &space, uint16_t data, uint16_t mem_mask );
void deco32_set_audio_output(uint8_t raw_data);
- void update_irq_state(uint8_t irq_cause, bool assert_state);
- uint8_t m_irq_cause;
- static const uint8_t VBLANK_IRQ = 0x10;
- static const uint8_t RASTER_IRQ = 0x20;
- static const uint8_t LIGHTGUN_IRQ = 0x40;
- static const int vblankout = 8;
- static const int vblankin = 248;
- //uint8_t m_irq_source; // captaven, dragongun and lockload
DECO16IC_BANK_CB_MEMBER(fghthist_bank_callback);
DECO16IC_BANK_CB_MEMBER(captaven_bank_callback);
@@ -215,7 +201,6 @@ public:
uint32_t m_sprite_ctrl;
int m_lightgun_port;
- int m_gun_latch;
bitmap_rgb32 m_temp_render_bitmap;
DECLARE_READ32_MEMBER(lightgun_r);
@@ -238,8 +223,6 @@ public:
void dragngun_init_common();
DECLARE_INPUT_CHANGED_MEMBER(lockload_gun_trigger);
- TIMER_DEVICE_CALLBACK_MEMBER(lockload_vblank_irq_gen);
-
uint32_t screen_update_dragngun(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECO16IC_BANK_CB_MEMBER(bank_1_callback);
diff --git a/src/mame/machine/deco_irq.cpp b/src/mame/machine/deco_irq.cpp
new file mode 100644
index 00000000000..3724f493813
--- /dev/null
+++ b/src/mame/machine/deco_irq.cpp
@@ -0,0 +1,239 @@
+// license: BSD-3-Clause
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Data East IRQ Controller
+
+ TODO:
+ - Lightgun support is only used by Locked 'n Loaded and works badly
+
+***************************************************************************/
+
+#include "emu.h"
+#include "screen.h"
+#include "deco_irq.h"
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(DECO_IRQ, deco_irq_device, "deco_irq", "Data East IRQ Controller")
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// deco_irq_device - constructor
+//-------------------------------------------------
+
+deco_irq_device::deco_irq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, DECO_IRQ, tag, owner, clock),
+ m_screen(*this, finder_base::DUMMY_TAG),
+ m_scanline_timer(nullptr),
+ m_lightgun1_cb(*this), m_lightgun2_cb(*this),
+ m_lightgun_irq_cb(*this),
+ m_raster1_irq_cb(*this), m_raster2_irq_cb(*this),
+ m_vblank_irq_cb(*this),
+ m_lightgun_irq(false), m_raster_irq(false), m_vblank_irq(false),
+ m_raster_irq_target(RASTER1_IRQ), m_raster_irq_masked(true),
+ m_raster_irq_scanline(0),
+ m_lightgun_latch(0)
+{
+}
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void deco_irq_device::device_start()
+{
+ // make sure our screen is started
+ if (!m_screen->started())
+ throw device_missing_dependencies();
+
+ // resolve callbacks
+ m_lightgun1_cb.resolve_safe(0);
+ m_lightgun2_cb.resolve_safe(0);
+ m_lightgun_irq_cb.resolve_safe();
+ m_raster1_irq_cb.resolve_safe();
+ m_raster2_irq_cb.resolve_safe();
+ m_vblank_irq_cb.resolve_safe();
+
+ // allocate scanline timer and start it
+ m_scanline_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(deco_irq_device::scanline_callback), this));
+ m_scanline_timer->adjust(m_screen->time_until_pos(0));
+
+ // register for save states
+ save_item(NAME(m_lightgun_irq));
+ save_item(NAME(m_raster_irq));
+ save_item(NAME(m_vblank_irq));
+ save_item(NAME(m_raster_irq_target));
+ save_item(NAME(m_raster_irq_masked));
+ save_item(NAME(m_raster_irq_scanline));
+ save_item(NAME(m_lightgun_latch));
+}
+
+//-------------------------------------------------
+// device_reset - device-specific reset
+//-------------------------------------------------
+
+void deco_irq_device::device_reset()
+{
+}
+
+//-------------------------------------------------
+// set_screen_tag - set screen we are attached to
+//-------------------------------------------------
+
+void deco_irq_device::set_screen_tag(device_t &device, const char *tag)
+{
+ deco_irq_device &dev = dynamic_cast<deco_irq_device &>(device);
+ dev.m_screen.set_tag(tag);
+}
+
+//-------------------------------------------------
+// scanline_callback - called on each scanline
+//-------------------------------------------------
+
+TIMER_CALLBACK_MEMBER( deco_irq_device::scanline_callback )
+{
+ const rectangle visible = m_screen->visible_area();
+ uint8_t y = m_screen->vpos();
+
+ // raster irq?
+ if (m_raster_irq_scanline > 0 && m_raster_irq_scanline < 240 && y == (m_raster_irq_scanline - 1))
+ {
+ if (!m_raster_irq_masked)
+ {
+ m_raster_irq = true;
+
+ switch (m_raster_irq_target)
+ {
+ case RASTER1_IRQ: m_raster1_irq_cb(ASSERT_LINE); break;
+ case RASTER2_IRQ: m_raster2_irq_cb(ASSERT_LINE); break;
+ }
+ }
+ }
+
+ // lightgun?
+ if (m_lightgun_latch >= visible.min_y && m_lightgun_latch <= visible.max_y && y == m_lightgun_latch)
+ {
+ m_lightgun_irq = true;
+ m_lightgun_irq_cb(ASSERT_LINE);
+ }
+
+ // vblank-in?
+ if (y == (visible.max_y + 1))
+ {
+ m_vblank_irq = true;
+ m_vblank_irq_cb(ASSERT_LINE);
+ }
+
+ // wait for next line
+ m_scanline_timer->adjust(m_screen->time_until_pos(y + 1));
+}
+
+
+//**************************************************************************
+// INTERFACE
+//**************************************************************************
+
+READ8_MEMBER( deco_irq_device::read )
+{
+ switch (offset)
+ {
+ case 1:
+ return m_raster_irq_scanline;
+
+ case 2:
+ m_raster_irq = false;
+ m_raster1_irq_cb(CLEAR_LINE);
+ m_raster2_irq_cb(CLEAR_LINE);
+ return 0xff;
+
+ case 3:
+ uint8_t data = 0;
+
+ // 7------- unknown
+ // -6------ lightgun irq
+ // --5----- raster irq
+ // ---4---- vblank irq
+ // ----32-- unknown
+ // ------1- vblank
+ // -------0 hblank?
+
+ data |= 1 << 7;
+ data |= (m_lightgun_irq ? 1 : 0) << 6;
+ data |= (m_raster_irq ? 1 : 0) << 5;
+ data |= (m_vblank_irq ? 1 : 0) << 4;
+ data |= 0 << 3;
+ data |= 0 << 2;
+ data |= m_screen->vblank() << 1;
+// data |= (m_screen->hblank() & m_screen->vblank()) << 0;
+ data |= m_screen->hblank() << 0;
+
+ return data;
+ }
+
+ logerror("Read from invalid offset %x\n", offset);
+ return 0xff;
+}
+
+WRITE8_MEMBER( deco_irq_device::write )
+{
+ switch (offset)
+ {
+ case 0:
+ // 765----- unused?
+ // ---4---- raster irq target
+ // ----3--- unused?
+ // -----2-- unknown
+ // ------1- raster irq mask
+ // -------0 unused?
+
+ m_raster_irq_target = BIT(data, 4);
+ m_raster_irq_masked = bool(BIT(data, 1));
+
+ if (m_raster_irq_masked)
+ {
+ m_raster_irq = false;
+ m_raster1_irq_cb(CLEAR_LINE);
+ m_raster2_irq_cb(CLEAR_LINE);
+ }
+
+ return;
+
+ case 1:
+ m_raster_irq_scanline = data;
+ return;
+
+ case 2:
+ m_vblank_irq = false;
+ m_vblank_irq_cb(CLEAR_LINE);
+ return;
+ }
+
+ logerror("Write %02x to invalid offset %x\n", data, offset);
+}
+
+WRITE_LINE_MEMBER( deco_irq_device::lightgun1_trigger_w )
+{
+ if (state)
+ m_lightgun_latch = m_lightgun1_cb() / 2;
+}
+
+WRITE_LINE_MEMBER( deco_irq_device::lightgun2_trigger_w )
+{
+ if (state)
+ m_lightgun_latch = m_lightgun2_cb() / 2;
+}
+
+WRITE_LINE_MEMBER( deco_irq_device::lightgun_irq_ack_w )
+{
+ m_lightgun_irq = false;
+ m_lightgun_irq_cb(CLEAR_LINE);
+}
+
diff --git a/src/mame/machine/deco_irq.h b/src/mame/machine/deco_irq.h
new file mode 100644
index 00000000000..d8b4138a5b4
--- /dev/null
+++ b/src/mame/machine/deco_irq.h
@@ -0,0 +1,121 @@
+// license: BSD-3-Clause
+// copyright-holders: Dirk Best
+/***************************************************************************
+
+ Data East IRQ Controller
+
+***************************************************************************/
+
+#ifndef MAME_MACHINE_DECO_IRQ_H
+#define MAME_MACHINE_DECO_IRQ_H
+
+#pragma once
+
+
+//**************************************************************************
+// INTERFACE CONFIGURATION MACROS
+//**************************************************************************
+
+#define MCFG_DECO_IRQ_ADD(_tag, _screen_tag) \
+ MCFG_DEVICE_ADD(_tag, DECO_IRQ, 0) \
+ deco_irq_device::set_screen_tag(*device, "^" _screen_tag);
+
+#define MCFG_DECO_IRQ_LIGHTGUN1_CB(_devcb) \
+ devcb = &deco_irq_device::set_lightgun1_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_DECO_IRQ_LIGHTGUN2_CB(_devcb) \
+ devcb = &deco_irq_device::set_lightgun2_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_DECO_IRQ_LIGHTGUN_IRQ_CB(_devcb) \
+ devcb = &deco_irq_device::set_lightgun_irq_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_DECO_IRQ_RASTER1_IRQ_CB(_devcb) \
+ devcb = &deco_irq_device::set_raster1_irq_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_DECO_IRQ_RASTER2_IRQ_CB(_devcb) \
+ devcb = &deco_irq_device::set_raster2_irq_callback(*device, DEVCB_##_devcb);
+
+#define MCFG_DECO_IRQ_VBLANK_IRQ_CB(_devcb) \
+ devcb = &deco_irq_device::set_vblank_irq_callback(*device, DEVCB_##_devcb);
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+class deco_irq_device : public device_t
+{
+public:
+ // construction/destruction
+ deco_irq_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ // configuration
+ template <class Object> static devcb_base &set_lightgun1_callback(device_t &device, Object &&cb)
+ { return downcast<deco_irq_device &>(device).m_lightgun1_cb.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> static devcb_base &set_lightgun2_callback(device_t &device, Object &&cb)
+ { return downcast<deco_irq_device &>(device).m_lightgun2_cb.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> static devcb_base &set_lightgun_irq_callback(device_t &device, Object &&cb)
+ { return downcast<deco_irq_device &>(device).m_lightgun_irq_cb.set_callback(std::forward<Object>(cb)); }
+
+
+ template <class Object> static devcb_base &set_raster1_irq_callback(device_t &device, Object &&cb)
+ { return downcast<deco_irq_device &>(device).m_raster1_irq_cb.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> static devcb_base &set_raster2_irq_callback(device_t &device, Object &&cb)
+ { return downcast<deco_irq_device &>(device).m_raster2_irq_cb.set_callback(std::forward<Object>(cb)); }
+
+ template <class Object> static devcb_base &set_vblank_irq_callback(device_t &device, Object &&cb)
+ { return downcast<deco_irq_device &>(device).m_vblank_irq_cb.set_callback(std::forward<Object>(cb)); }
+
+
+ // static configuration
+ static void set_screen_tag(device_t &device, const char *tag);
+
+ TIMER_CALLBACK_MEMBER(scanline_callback);
+
+ DECLARE_READ8_MEMBER(read);
+ DECLARE_WRITE8_MEMBER(write);
+
+ DECLARE_WRITE_LINE_MEMBER(lightgun1_trigger_w);
+ DECLARE_WRITE_LINE_MEMBER(lightgun2_trigger_w);
+ DECLARE_WRITE_LINE_MEMBER(lightgun_irq_ack_w);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+private:
+ required_device<screen_device> m_screen;
+ emu_timer *m_scanline_timer;
+
+ enum
+ {
+ RASTER1_IRQ = 1,
+ RASTER2_IRQ = 0
+ };
+
+ // callbacks
+ devcb_read8 m_lightgun1_cb;
+ devcb_read8 m_lightgun2_cb;
+ devcb_write_line m_lightgun_irq_cb;
+ devcb_write_line m_raster1_irq_cb;
+ devcb_write_line m_raster2_irq_cb;
+ devcb_write_line m_vblank_irq_cb;
+
+ bool m_lightgun_irq, m_raster_irq, m_vblank_irq;
+
+ int m_raster_irq_target;
+ bool m_raster_irq_masked;
+ uint8_t m_raster_irq_scanline;
+
+ uint8_t m_lightgun_latch;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(DECO_IRQ, deco_irq_device)
+
+#endif // MAME_MACHINE_DECO_IRQ_H