From d4c18136b8c83d59e98349699d51e11488a6ddb7 Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Wed, 17 Mar 2021 11:28:12 +0000 Subject: tecmo16.cpp - improve IRQ ack mechanism * riot - don't trigger multiple interrupts per frame * 1943.cpp - don't draw past end of spriteram * flip 'free play' switch in quasar based on observed behavior (maybe freeplay isn't the best name for this) --- src/mame/drivers/galaxian.cpp | 2 +- src/mame/drivers/quasar.cpp | 7 ++-- src/mame/drivers/tecmo16.cpp | 86 ++++++++++++++++++++++++++++--------------- src/mame/includes/tecmo16.h | 7 +++- src/mame/video/1943.cpp | 2 +- 5 files changed, 68 insertions(+), 36 deletions(-) diff --git a/src/mame/drivers/galaxian.cpp b/src/mame/drivers/galaxian.cpp index 160d3d90059..9f815331b96 100644 --- a/src/mame/drivers/galaxian.cpp +++ b/src/mame/drivers/galaxian.cpp @@ -15112,7 +15112,7 @@ GAME( 1982, mimonscra, mimonkey, mimonscr, mimonkey, galaxian_state, init_ Sound Board: A970 */ GAME( 1982, anteater, 0, anteater, anteater, galaxian_state, init_anteater, ROT90, "Tago Electronics", "Anteater", MACHINE_SUPPORTS_SAVE ) -GAME( 1982, anteateruk, anteater, anteateruk, anteateruk, galaxian_state, init_anteateruk, ROT90, "Tago Electronics (Free Enterprise Games license", "The Anteater (UK)", MACHINE_SUPPORTS_SAVE ) // distributed in 1983 +GAME( 1982, anteateruk, anteater, anteateruk, anteateruk, galaxian_state, init_anteateruk, ROT90, "Tago Electronics (Free Enterprise Games license)", "The Anteater (UK)", MACHINE_SUPPORTS_SAVE ) // distributed in 1983 GAME( 1982, anteaterg, anteater, anteaterg, anteateruk, galaxian_state, init_anteateruk, ROT90, "Tago Electronics (TV-Tuning license from Free Enterprise Games)", "Ameisenbaer (German)", MACHINE_SUPPORTS_SAVE ) GAME( 1982, anteatergg, anteater, anteatergg, anteatergg, galaxian_state, init_galaxian, ROT90, "bootleg", "Ameisenbaer (German, Galaxian hardware)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/drivers/quasar.cpp b/src/mame/drivers/quasar.cpp index dea16097268..243d673b629 100644 --- a/src/mame/drivers/quasar.cpp +++ b/src/mame/drivers/quasar.cpp @@ -14,6 +14,7 @@ - Phase 3 - seems awfully hard - dip settings ? - Hook up Coin Counter - Test/Service Mode - not working? + - No attract demo? is this correct? ************************************************************************ @@ -195,9 +196,9 @@ static INPUT_PORTS_START( quasar ) PORT_DIPSETTING( 0x10, "4" ) PORT_DIPSETTING( 0x20, "5" ) PORT_DIPSETTING( 0x30, "6" ) - PORT_DIPNAME( 0x40, 0x40, DEF_STR( Free_Play ) ) - PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x00, DEF_STR( On ) ) + PORT_DIPNAME( 0x40, 0x00, DEF_STR( Free_Play ) ) // requires initial coin, but doesn't decrease coins on game over + PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) + PORT_DIPSETTING( 0x40, DEF_STR( On ) ) PORT_DIPNAME( 0x80, 0x80, "Test Mode" ) /* confirmed */ PORT_DIPSETTING( 0x00, "Collisions excluded" ) PORT_DIPSETTING( 0x80, "Collisions included" ) diff --git a/src/mame/drivers/tecmo16.cpp b/src/mame/drivers/tecmo16.cpp index 261a758c611..5bcc9ff5dfd 100644 --- a/src/mame/drivers/tecmo16.cpp +++ b/src/mame/drivers/tecmo16.cpp @@ -17,8 +17,12 @@ TODO: fstarfrc relies on the interrupt being held for a while, otherwise the titlescreen background goes wrong. If I had to guess: 24/4(6MHz) pixel clock, 384 hclocks, 264 scanlines + riot does not like multiple interrupts per frame and will start to + fail towards the end of level 1 (bad palette) then randomly lock up + on level 2, see irq_150021_w / irq_150031_w for notes - there could be some priorities problems in riot (more noticeable in level 2) +- check layer offsets Notes: - To enter into service mode in Final Star Force press and hold start @@ -41,55 +45,76 @@ Notes: /******************************************************************************/ -void tecmo16_state::fstarfrc_map(address_map &map) + +/* +(without setting D0) +move.b D0, $150031.l (start of interupt) +move.b D0, $150021.l (end of interrupt in riot, straight after above in ginkun, not used in fstarfrc?) +*/ + +void tecmo16_state::irq_150021_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + // does this disable the vblank IRQ until next frame? fstarfrc expects multiple interrupts per + // frame and never writes it, while the others do. riot will start to glitch towards the end + // of stage 1, locking up on stage 2 if you allow multiple interrupts per frame. + m_maincpu->set_input_line(5, CLEAR_LINE); +} + +void tecmo16_state::irq_150031_w(offs_t offset, uint16_t data, uint16_t mem_mask) +{ + // all games write this at the start of interrupt, is it the basic 'irq ack' (but without + // disabling further interrupts?) could also be some kind of DMA trigger (palette or similar) +} + +void tecmo16_state::common_map(address_map& map) { map(0x000000, 0x07ffff).rom(); map(0x100000, 0x103fff).ram(); /* Main RAM */ - map(0x110000, 0x110fff).ram().w(FUNC(tecmo16_state::charram_w)).share("charram"); - map(0x120000, 0x1207ff).ram().w(FUNC(tecmo16_state::videoram_w)).share("videoram"); - map(0x120800, 0x120fff).ram().w(FUNC(tecmo16_state::colorram_w)).share("colorram"); - map(0x121000, 0x1217ff).ram().w(FUNC(tecmo16_state::videoram2_w)).share("videoram2"); - map(0x121800, 0x121fff).ram().w(FUNC(tecmo16_state::colorram2_w)).share("colorram2"); - map(0x122000, 0x127fff).ram(); /* work area */ + + // tilemap sizes differ between games, probably configurable + // but for now we add them in different maps + map(0x130000, 0x130fff).ram().share("spriteram"); map(0x140000, 0x141fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); map(0x150000, 0x150001).w(FUNC(tecmo16_state::flipscreen_w)); map(0x150011, 0x150011).w("soundlatch", FUNC(generic_latch_8_device::write)); - map(0x150030, 0x150031).portr("DSW2").nopw(); /* ??? */ + map(0x150020, 0x150021).portr("EXTRA").w(FUNC(tecmo16_state::irq_150021_w)); + map(0x150030, 0x150031).portr("DSW2").w(FUNC(tecmo16_state::irq_150031_w)); map(0x150040, 0x150041).portr("DSW1"); map(0x150050, 0x150051).portr("P1_P2"); // map(0x160000, 0x160001).nopr(); /* ??? Read at every scene changes */ map(0x160000, 0x160001).w(FUNC(tecmo16_state::scroll_char_x_w)); + map(0x160006, 0x160007).w(FUNC(tecmo16_state::scroll_char_y_w)); map(0x16000c, 0x16000d).w(FUNC(tecmo16_state::scroll_x_w)); map(0x160012, 0x160013).w(FUNC(tecmo16_state::scroll_y_w)); map(0x160018, 0x160019).w(FUNC(tecmo16_state::scroll2_x_w)); map(0x16001e, 0x16001f).w(FUNC(tecmo16_state::scroll2_y_w)); } + + +void tecmo16_state::fstarfrc_map(address_map &map) +{ + map(0x110000, 0x110fff).ram().w(FUNC(tecmo16_state::charram_w)).share("charram"); + map(0x120000, 0x1207ff).ram().w(FUNC(tecmo16_state::videoram_w)).share("videoram"); + map(0x120800, 0x120fff).ram().w(FUNC(tecmo16_state::colorram_w)).share("colorram"); + map(0x121000, 0x1217ff).ram().w(FUNC(tecmo16_state::videoram2_w)).share("videoram2"); + map(0x121800, 0x121fff).ram().w(FUNC(tecmo16_state::colorram2_w)).share("colorram2"); + map(0x122000, 0x127fff).ram(); /* work area */ + + common_map(map); +} + void tecmo16_state::ginkun_map(address_map &map) { - map(0x000000, 0x07ffff).rom(); - map(0x100000, 0x103fff).ram(); /* Main RAM */ map(0x110000, 0x110fff).ram().w(FUNC(tecmo16_state::charram_w)).share("charram"); map(0x120000, 0x120fff).ram().w(FUNC(tecmo16_state::videoram_w)).share("videoram"); map(0x121000, 0x121fff).ram().w(FUNC(tecmo16_state::colorram_w)).share("colorram"); map(0x122000, 0x122fff).ram().w(FUNC(tecmo16_state::videoram2_w)).share("videoram2"); map(0x123000, 0x123fff).ram().w(FUNC(tecmo16_state::colorram2_w)).share("colorram2"); map(0x124000, 0x124fff).ram(); /* extra RAM for Riot */ - map(0x130000, 0x130fff).ram().share("spriteram"); - map(0x140000, 0x141fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette"); - map(0x150000, 0x150001).w(FUNC(tecmo16_state::flipscreen_w)); - map(0x150011, 0x150011).w("soundlatch", FUNC(generic_latch_8_device::write)); - map(0x150020, 0x150021).portr("EXTRA").nopw(); /* ??? */ - map(0x150030, 0x150031).portr("DSW2").nopw(); /* ??? */ - map(0x150040, 0x150041).portr("DSW1"); - map(0x150050, 0x150051).portr("P1_P2"); - map(0x160000, 0x160001).w(FUNC(tecmo16_state::scroll_char_x_w)); - map(0x160006, 0x160007).w(FUNC(tecmo16_state::scroll_char_y_w)); - map(0x16000c, 0x16000d).w(FUNC(tecmo16_state::scroll_x_w)); - map(0x160012, 0x160013).w(FUNC(tecmo16_state::scroll_y_w)); - map(0x160018, 0x160019).w(FUNC(tecmo16_state::scroll2_x_w)); - map(0x16001e, 0x16001f).w(FUNC(tecmo16_state::scroll2_y_w)); + + common_map(map); } void tecmo16_state::sound_map(address_map &map) @@ -169,6 +194,9 @@ static INPUT_PORTS_START( fstarfrc ) PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0x4000, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_COIN2 ) + + PORT_START("EXTRA") + /* Not used */ INPUT_PORTS_END static INPUT_PORTS_START( ginkun ) @@ -331,7 +359,7 @@ GFXDECODE_END #define MASTER_CLOCK XTAL(24'000'000) #define OKI_CLOCK XTAL(8'000'000) -void tecmo16_state::fstarfrc(machine_config &config) +void tecmo16_state::base(machine_config &config) { /* basic machine hardware */ M68000(config, m_maincpu, MASTER_CLOCK/2); /* 12MHz */ @@ -385,7 +413,7 @@ void tecmo16_state::fstarfrc(machine_config &config) void tecmo16_state::ginkun(machine_config &config) { - fstarfrc(config); + base(config); m_maincpu->set_addrmap(AS_PROGRAM, &tecmo16_state::ginkun_map); @@ -649,9 +677,9 @@ ROM_END /******************************************************************************/ -GAME( 1992, fstarfrc, 0, fstarfrc, fstarfrc, tecmo16_state, empty_init, ROT90, "Tecmo", "Final Star Force (US)", MACHINE_SUPPORTS_SAVE ) // Has 'Recycle it, don't trash it" and 'Winners don't use drugs' screens after first attract cycle -GAME( 1992, fstarfrcj, fstarfrc, fstarfrc, fstarfrc, tecmo16_state, empty_init, ROT90, "Tecmo", "Final Star Force (Japan)", MACHINE_SUPPORTS_SAVE ) -GAME( 1992, fstarfrcw, fstarfrc, fstarfrc, fstarfrc, tecmo16_state, empty_init, ROT90, "Tecmo", "Final Star Force (World?)", MACHINE_SUPPORTS_SAVE ) // more similar the to the Japanese version than to the US one, not the parent because not sure it's the world version +GAME( 1992, fstarfrc, 0, base, fstarfrc, tecmo16_state, empty_init, ROT90, "Tecmo", "Final Star Force (US)", MACHINE_SUPPORTS_SAVE ) // Has 'Recycle it, don't trash it" and 'Winners don't use drugs' screens after first attract cycle +GAME( 1992, fstarfrcj, fstarfrc, base, fstarfrc, tecmo16_state, empty_init, ROT90, "Tecmo", "Final Star Force (Japan)", MACHINE_SUPPORTS_SAVE ) +GAME( 1992, fstarfrcw, fstarfrc, base, fstarfrc, tecmo16_state, empty_init, ROT90, "Tecmo", "Final Star Force (World?)", MACHINE_SUPPORTS_SAVE ) // more similar the to the Japanese version than to the US one, not the parent because not sure it's the world version GAME( 1992, riot, 0, riot, riot, tecmo16_state, empty_init, ROT0, "NMK", "Riot", MACHINE_SUPPORTS_SAVE ) GAME( 1992, riotw, riot, riot, riot, tecmo16_state, empty_init, ROT0, "Woong Bi", "Riot (Woong Bi license)", MACHINE_SUPPORTS_SAVE ) GAME( 1995, ginkun, 0, ginkun, ginkun, tecmo16_state, empty_init, ROT0, "Tecmo", "Ganbare Ginkun", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/tecmo16.h b/src/mame/includes/tecmo16.h index bddd55d8f96..6a534452cd7 100644 --- a/src/mame/includes/tecmo16.h +++ b/src/mame/includes/tecmo16.h @@ -32,8 +32,8 @@ public: m_spriteram(*this, "spriteram") { } + void base(machine_config &config); void ginkun(machine_config &config); - void fstarfrc(machine_config &config); void riot(machine_config &config); private: @@ -81,6 +81,9 @@ private: void scroll_char_x_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); void scroll_char_y_w(offs_t offset, uint16_t data, uint16_t mem_mask = ~0); + void irq_150021_w(offs_t offset, uint16_t data, uint16_t mem_mask); + void irq_150031_w(offs_t offset, uint16_t data, uint16_t mem_mask); + TILE_GET_INFO_MEMBER(fg_get_tile_info); TILE_GET_INFO_MEMBER(bg_get_tile_info); TILE_GET_INFO_MEMBER(tx_get_tile_info); @@ -93,7 +96,7 @@ private: DECLARE_WRITE_LINE_MEMBER(screen_vblank); void save_state(); - + void common_map(address_map& map); void fstarfrc_map(address_map &map); void ginkun_map(address_map &map); void sound_map(address_map &map); diff --git a/src/mame/video/1943.cpp b/src/mame/video/1943.cpp index 1a23037cd9b..0ecc0adc192 100644 --- a/src/mame/video/1943.cpp +++ b/src/mame/video/1943.cpp @@ -284,7 +284,7 @@ void _1943_state::_1943_drawgfx(bitmap_ind16 &dest_bmp,const rectangle &clip,gfx void _1943_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) { - for (int offs = 0; offs <= m_spriteram.bytes(); offs += 32) + for (int offs = 0; offs < m_spriteram.bytes(); offs += 32) { const u8 attr = m_spriteram[offs + 1]; const u32 code = m_spriteram[offs] + ((attr & 0xe0) << 3); -- cgit v1.2.3