From 7784bb5ad6401235a51f4f103e09b8ea78ca4a25 Mon Sep 17 00:00:00 2001 From: hap Date: Tue, 19 Nov 2024 21:32:36 +0100 Subject: dogfgt: determine screen refresh rate from pcb video, small cleanup --- src/mame/technos/dogfgt.cpp | 213 ++++++++++++++++++++++++------------------ src/mame/technos/renegade.cpp | 4 +- 2 files changed, 123 insertions(+), 94 deletions(-) diff --git a/src/mame/technos/dogfgt.cpp b/src/mame/technos/dogfgt.cpp index 19e8aab08ba..46d3b2b77cd 100644 --- a/src/mame/technos/dogfgt.cpp +++ b/src/mame/technos/dogfgt.cpp @@ -7,12 +7,19 @@ Acrobatic Dog-Fight / 『バッテン・オハラのスチャラカ空中戦』 driver by Nicola Salmoria +TODO: +- verify clocks: 1.5MHz AY clocks and 57.44Hz screen refresh rate are + certain when compared to PCB video, 16 IRQs per frame is also certain +- flipscreen dipswitch, manual says it's on bank 2 #8, probably not + readable by software? + ***************************************************************************/ #include "emu.h" #include "cpu/m6502/m6502.h" #include "machine/gen_latch.h" +#include "machine/timer.h" #include "sound/ay8910.h" #include "emupal.h" @@ -82,6 +89,7 @@ private: uint8_t m_scroll[4]{}; uint8_t m_lastflip = 0U; uint8_t m_lastpixcolor = 0U; + static constexpr uint8_t PIXMAP_COLOR_BASE = (16 + 32); static constexpr uint16_t BITMAPRAM_SIZE = 0x6000; @@ -91,13 +99,15 @@ private: void subirqtrigger_w(uint8_t data); void sub_irqack_w(uint8_t data); void soundcontrol_w(uint8_t data); + TIMER_DEVICE_CALLBACK_MEMBER(interrupt); + void plane_select_w(uint8_t data); uint8_t bitmapram_r(offs_t offset); void internal_bitmapram_w(offs_t offset, uint8_t data); void bitmapram_w(offs_t offset, uint8_t data); void bgvideoram_w(offs_t offset, uint8_t data); void scroll_w(offs_t offset, uint8_t data); - void _1800_w(uint8_t data); + void control_w(uint8_t data); TILE_GET_INFO_MEMBER(get_tile_info); void palette(palette_device &palette) const; @@ -180,6 +190,60 @@ void dogfgt_state::video_start() } +/*************************************************************************** + + Display refresh + +***************************************************************************/ + +void dogfgt_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + for (int offs = 0; offs < m_spriteram.bytes(); offs += 4) + { + if (m_spriteram[offs] & 0x01) + { + int sx = m_spriteram[offs + 3]; + int sy = (240 - m_spriteram[offs + 2]) & 0xff; + int flipx = m_spriteram[offs] & 0x04; + int flipy = m_spriteram[offs] & 0x02; + if (flip_screen()) + { + sx = 240 - sx; + sy = 240 - sy; + flipx = !flipx; + flipy = !flipy; + } + + m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, + m_spriteram[offs + 1] + ((m_spriteram[offs] & 0x30) << 4), + (m_spriteram[offs] & 0x08) >> 3, + flipx, flipy, + sx, sy, 0); + } + } +} + + +uint32_t dogfgt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) +{ + if (m_lastflip != flip_screen() || m_lastpixcolor != m_pixcolor) + { + m_lastflip = flip_screen(); + m_lastpixcolor = m_pixcolor; + + for (int offs = 0; offs < BITMAPRAM_SIZE; offs++) + internal_bitmapram_w(offs, m_bitmapram[offs]); + } + + m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); + + draw_sprites(bitmap, cliprect); + + copybitmap_trans(bitmap, m_pixbitmap, 0, 0, 0, 0, cliprect, PIXMAP_COLOR_BASE + 8 * m_pixcolor); + return 0; +} + + /*************************************************************************** Memory handlers @@ -248,7 +312,7 @@ void dogfgt_state::scroll_w(offs_t offset, uint8_t data) m_bg_tilemap->set_scrolly(0, m_scroll[2] + 256 * m_scroll[3]); } -void dogfgt_state::_1800_w(uint8_t data) +void dogfgt_state::control_w(uint8_t data) { // bits 0 and 1 are probably text color (not verified because PROM is missing) m_pixcolor = ((data & 0x01) << 1) | ((data & 0x02) >> 1); @@ -265,61 +329,6 @@ void dogfgt_state::_1800_w(uint8_t data) } -/*************************************************************************** - - Display refresh - -***************************************************************************/ - -void dogfgt_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - for (int offs = 0; offs < m_spriteram.bytes(); offs += 4) - { - if (m_spriteram[offs] & 0x01) - { - int sx = m_spriteram[offs + 3]; - int sy = (240 - m_spriteram[offs + 2]) & 0xff; - int flipx = m_spriteram[offs] & 0x04; - int flipy = m_spriteram[offs] & 0x02; - if (flip_screen()) - { - sx = 240 - sx; - sy = 240 - sy; - flipx = !flipx; - flipy = !flipy; - } - - m_gfxdecode->gfx(1)->transpen(bitmap, cliprect, - m_spriteram[offs + 1] + ((m_spriteram[offs] & 0x30) << 4), - (m_spriteram[offs] & 0x08) >> 3, - flipx, flipy, - sx, sy, 0); - } - } -} - - -uint32_t dogfgt_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) -{ - if (m_lastflip != flip_screen() || m_lastpixcolor != m_pixcolor) - { - m_lastflip = flip_screen(); - m_lastpixcolor = m_pixcolor; - - for (int offs = 0; offs < BITMAPRAM_SIZE; offs++) - internal_bitmapram_w(offs, m_bitmapram[offs]); - } - - - m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0); - - draw_sprites(bitmap, cliprect); - - copybitmap_trans(bitmap, m_pixbitmap, 0, 0, 0, 0, cliprect, PIXMAP_COLOR_BASE + 8 * m_pixcolor); - return 0; -} - - void dogfgt_state::subirqtrigger_w(uint8_t data) { // bit 0 used but unknown @@ -346,6 +355,21 @@ void dogfgt_state::soundcontrol_w(uint8_t data) } +TIMER_DEVICE_CALLBACK_MEMBER(dogfgt_state::interrupt) +{ + const int scanline = param; + + // 16 interrupts per frame + if ((scanline & 0xf) == 8 && scanline <= 248) + m_maincpu->set_input_line(0, HOLD_LINE); +} + + +/*************************************************************************** + + Address maps + +***************************************************************************/ void dogfgt_state::main_map(address_map &map) { @@ -353,7 +377,7 @@ void dogfgt_state::main_map(address_map &map) map(0x0f80, 0x0fdf).writeonly().share(m_spriteram); map(0x1000, 0x17ff).w(FUNC(dogfgt_state::bgvideoram_w)).share(m_bgvideoram); map(0x1800, 0x1800).portr("P1"); - map(0x1800, 0x1800).w(FUNC(dogfgt_state::_1800_w)); // text color, flip screen & coin counters + map(0x1800, 0x1800).w(FUNC(dogfgt_state::control_w)); map(0x1810, 0x1810).portr("P2"); map(0x1810, 0x1810).w(FUNC(dogfgt_state::subirqtrigger_w)); map(0x1820, 0x1820).portr("DSW1"); @@ -376,6 +400,11 @@ void dogfgt_state::sub_map(address_map &map) } +/*************************************************************************** + + Input ports + +***************************************************************************/ static INPUT_PORTS_START( dogfgt ) PORT_START("P1") @@ -417,24 +446,14 @@ static INPUT_PORTS_START( dogfgt ) PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unused ) ) PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0xc0, 0x00, DEF_STR( Cabinet ) ) - PORT_DIPSETTING( 0x00, "Upright 1 Player" ) - PORT_DIPSETTING( 0x80, "Upright 2 Players" ) - PORT_DIPSETTING( 0x40, DEF_STR( Cocktail ) ) // "Cocktail 1 Player" - IMPOSSIBLE ! - PORT_DIPSETTING( 0xc0, DEF_STR( Cocktail ) ) // "Cocktail 2 Players" - - -/* Manual shows: - - Dip #7 TV-Screen - OFF Table type - ON Up-right type use - Dip #8 Control Panel - OFF Table type use - ON Up-right use -There is a side note for these two: "Change both together" -*/ + // 2 separate switches for upright/table cabinet, manual says to change both together + PORT_DIPNAME( 0x40, 0x00, "Screen" ) + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x40, DEF_STR( Cocktail ) ) + PORT_DIPNAME( 0x80, 0x00, "Control Panel" ) + PORT_DIPSETTING( 0x00, DEF_STR( Upright ) ) + PORT_DIPSETTING( 0x80, DEF_STR( Cocktail ) ) PORT_START("DSW2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) @@ -452,18 +471,15 @@ There is a side note for these two: "Change both together" PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unused ) ) PORT_DIPSETTING( 0x40, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_CUSTOM ) PORT_VBLANK("screen") - -/* Manual shows: + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_CUSTOM ) PORT_VBLANK("screen") +INPUT_PORTS_END - Dip #8 TV-Screen - OFF Normal - ON Invert -*/ -INPUT_PORTS_END +/*************************************************************************** + GFX layouts +***************************************************************************/ static const gfx_layout tilelayout = { @@ -497,6 +513,11 @@ static GFXDECODE_START( gfx_dogfgt ) GFXDECODE_END +/*************************************************************************** + + Machine initialization + +***************************************************************************/ void dogfgt_state::machine_start() { @@ -525,21 +546,18 @@ void dogfgt_state::machine_reset() void dogfgt_state::dogfgt(machine_config &config) { // basic machine hardware - M6502(config, m_maincpu, 12_MHz_XTAL / 8); // 1.5 MHz ???? divisor not verified + M6502(config, m_maincpu, 12_MHz_XTAL / 8); // 1.5MHz? m_maincpu->set_addrmap(AS_PROGRAM, &dogfgt_state::main_map); - m_maincpu->set_periodic_int(FUNC(dogfgt_state::irq0_line_hold), attotime::from_hz(16 * 60)); // ? controls music tempo + TIMER(config, "scantimer").configure_scanline(FUNC(dogfgt_state::interrupt), "screen", 0, 1); - M6502(config, m_subcpu, 12_MHz_XTAL / 8); // 1.5 MHz ???? divisor not verified + M6502(config, m_subcpu, 12_MHz_XTAL / 8); // 1.5MHz? m_subcpu->set_addrmap(AS_PROGRAM, &dogfgt_state::sub_map); config.set_maximum_quantum(attotime::from_hz(6000)); // video hardware SCREEN(config, m_screen, SCREEN_TYPE_RASTER); - m_screen->set_refresh_hz(60); - m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate - m_screen->set_size(32*8, 32*8); - m_screen->set_visarea(0*8, 32*8-1, 1*8, 31*8-1); + m_screen->set_raw(12_MHz_XTAL / 2, 384, 0, 256, 272, 8, 248); // ~57.44Hz m_screen->set_screen_update(FUNC(dogfgt_state::screen_update)); m_screen->set_palette(m_palette); @@ -551,11 +569,16 @@ void dogfgt_state::dogfgt(machine_config &config) GENERIC_LATCH_8(config, m_soundlatch); - YM2149(config, m_ay[0], 12_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.30); // 1.5 MHz ???? divisor not verified - YM2149(config, m_ay[1], 12_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.30); // 1.5 MHz ???? divisor not verified + YM2149(config, m_ay[0], 12_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.30); // 1.5MHz + YM2149(config, m_ay[1], 12_MHz_XTAL / 8).add_route(ALL_OUTPUTS, "mono", 0.30); // " } +/*************************************************************************** + + ROMs + +***************************************************************************/ ROM_START( dogfgt ) ROM_REGION( 0x10000, "maincpu", 0 ) @@ -662,6 +685,12 @@ ROM_END } // anonymous namespace +/*************************************************************************** + + Game drivers + +***************************************************************************/ + GAME( 1984, dogfgt, 0, dogfgt, dogfgt, dogfgt_state, empty_init, ROT0, "Technos Japan", "Acrobatic Dog-Fight", MACHINE_SUPPORTS_SAVE ) GAME( 1985, dogfgtu, dogfgt, dogfgt, dogfgt, dogfgt_state, empty_init, ROT0, "Technos Japan (Data East USA, Inc. license)", "Acrobatic Dog-Fight (USA)", MACHINE_SUPPORTS_SAVE ) GAME( 1984, dogfgtj, dogfgt, dogfgt, dogfgt, dogfgt_state, empty_init, ROT0, "Technos Japan", "But-ten Ohara's Suit-Cha Luck-a Dog-Fight (Japan)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/technos/renegade.cpp b/src/mame/technos/renegade.cpp index 227bfa2a1cd..ba0f4ea47cb 100644 --- a/src/mame/technos/renegade.cpp +++ b/src/mame/technos/renegade.cpp @@ -464,11 +464,11 @@ TIMER_DEVICE_CALLBACK_MEMBER(renegade_state::interrupt) { int const scanline = param; - // NMI 8 lines before vsync + // NMI: 8 lines before vsync if (scanline == 265) m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); - // IRQ 16 clocks per frame: once every 16 lines, but increases to 24 lines during vblank + // IRQ: 16 clocks per frame: once every 16 lines, but increases to 24 lines during vblank // (lines 16,40,56,72,88,104,120,136,152,168,184,200,216,232,248,264) if (scanline == 0x10 || (scanline > 0x20 && (scanline & 0xf) == 8)) m_maincpu->set_input_line(0, ASSERT_LINE); -- cgit v1.2.3