diff --git a/src/mame/drivers/toaplan2.cpp b/src/mame/drivers/toaplan2.cpp index afcee286591..d8d04c146d3 100644 --- a/src/mame/drivers/toaplan2.cpp +++ b/src/mame/drivers/toaplan2.cpp @@ -347,7 +347,15 @@ To Do / Unknowns: - Need to sort out the video status register. - Find out how exactly how sound CPU communication really works in bgaregga/batrider/bbakraid current emulation seems to work (plays all sounds), but there are still some unknown reads/writes - - Write a RTC core for uPD4992, needed by Othello Derby and Power Kick + +Notes on Power Kick coin inputs: +- The 10 yen input is "Key In" according to the bookkeeping screen, but is + an otherwise normal coin input with a counter and a lockout (sharing the + latter with the "medal" coin). +- The 100 yen input never adds any credits except in "Coin Function Check," + instead dispensing its value into the hopper immediately. + +To reset the NVRAM in Othello Derby, hold P1 Button 1 down while booting. *****************************************************************************/ @@ -356,12 +364,16 @@ To Do / Unknowns: #include "cpu/nec/v25.h" #include "cpu/z80/z80.h" #include "cpu/z180/z180.h" +#include "machine/nvram.h" #include "sound/ym2151.h" #include "sound/3812intf.h" #include "sound/ymz280b.h" #include "includes/toaplan2.h" #include "includes/toaplipt.h" +#define UNICODE_YEN "\xC2\xA5" +#define PWRKICK_HOPPER_PULSE 50 // time between hopper pulses in milliseconds (probably wrong) + /*************************************************************************** Initialisation handlers @@ -556,9 +568,17 @@ WRITE8_MEMBER(toaplan2_state::toaplan2_coin_w) WRITE8_MEMBER(toaplan2_state::pwrkick_coin_w) { - machine().bookkeeping().coin_counter_w(0, (data & 2) >> 1 ); - machine().bookkeeping().coin_counter_w(1, (data & 8) >> 3 ); - m_pwrkick_hopper = (data & 0x80) >> 7; + machine().bookkeeping().coin_counter_w(0, (data & 2) >> 1 ); // medal + machine().bookkeeping().coin_counter_w(1, (data & 8) >> 3 ); // 10 yen + machine().bookkeeping().coin_counter_w(2, (data & 1) ); // 100 yen + m_hopper->write(space, 0, data & 0x80); +} + +WRITE8_MEMBER(toaplan2_state::pwrkick_coin_lockout_w) +{ + machine().bookkeeping().coin_lockout_w(0, (data & 4) ? 0 : 1); + machine().bookkeeping().coin_lockout_w(1, (data & 4) ? 0 : 1); + machine().bookkeeping().coin_lockout_w(2, (data & 2) ? 0 : 1); } @@ -1182,7 +1202,8 @@ ADDRESS_MAP_END static ADDRESS_MAP_START( pwrkick_68k_mem, AS_PROGRAM, 16, toaplan2_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM - AM_RANGE(0x100000, 0x10ffff) AM_RAM + AM_RANGE(0x100000, 0x103fff) AM_RAM AM_SHARE("nvram") // Only 10022C-10037B is actually saved as NVRAM + AM_RANGE(0x104000, 0x10ffff) AM_RAM AM_RANGE(0x200000, 0x20000f) AM_DEVREADWRITE8("rtc", upd4992_device, read, write, 0x00ff ) AM_RANGE(0x300000, 0x30000d) AM_DEVREADWRITE("gp9001", gp9001vdp_device, gp9001_vdp_r, gp9001_vdp_w) @@ -1197,13 +1218,14 @@ static ADDRESS_MAP_START( pwrkick_68k_mem, AS_PROGRAM, 16, toaplan2_state ) AM_RANGE(0x700018, 0x700019) AM_READ_PORT("DSWC") AM_RANGE(0x70001c, 0x70001d) AM_READ_PORT("SYS") AM_RANGE(0x700030, 0x700031) AM_WRITE(oki_bankswitch_w) - AM_RANGE(0x700034, 0x700035) AM_WRITE8(pwrkick_coin_w,0x00ff) - AM_RANGE(0x700038, 0x700039) AM_WRITENOP // lamps? + AM_RANGE(0x700034, 0x700035) AM_WRITE8(pwrkick_coin_w, 0x00ff) + AM_RANGE(0x700038, 0x700039) AM_WRITE8(pwrkick_coin_lockout_w, 0x00ff) ADDRESS_MAP_END static ADDRESS_MAP_START( othldrby_68k_mem, AS_PROGRAM, 16, toaplan2_state ) AM_RANGE(0x000000, 0x07ffff) AM_ROM - AM_RANGE(0x100000, 0x10ffff) AM_RAM + AM_RANGE(0x100000, 0x103fff) AM_RAM AM_SHARE("nvram") // Only 10331E-103401 is actually saved as NVRAM + AM_RANGE(0x104000, 0x10ffff) AM_RAM AM_RANGE(0x200000, 0x20000f) AM_DEVREADWRITE8("rtc", upd4992_device, read, write, 0x00ff ) AM_RANGE(0x300000, 0x30000d) AM_DEVREADWRITE("gp9001", gp9001vdp_device, gp9001_vdp_r, gp9001_vdp_w) @@ -2304,139 +2326,90 @@ static INPUT_PORTS_START( batsugun ) INPUT_PORTS_END -CUSTOM_INPUT_MEMBER(toaplan2_state::pwrkick_hopper_status_r) -{ - /* TODO: hopper mechanism */ - return machine().rand() & 1; - //return m_pwrkick_hopper & (machine().rand() & 1); -} - static INPUT_PORTS_START( pwrkick ) PORT_START("DSWA") - PORT_DIPNAME( 0x03, 0x00, DEF_STR( Difficulty ) ) + PORT_DIPNAME( 0x03, 0x00, DEF_STR( Difficulty ) ) PORT_DIPLOCATION("SW1:!1,!2") PORT_DIPSETTING( 0x00, DEF_STR( Easy ) ) PORT_DIPSETTING( 0x01, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x02, DEF_STR( Hard ) ) PORT_DIPSETTING( 0x03, DEF_STR( Very_Hard ) ) - PORT_DIPNAME( 0x1c, 0x00, "Payout" ) - PORT_DIPSETTING( 0x00, "1" ) - PORT_DIPSETTING( 0x04, "2" ) - PORT_DIPSETTING( 0x08, "3" ) - PORT_DIPSETTING( 0x0c, "4" ) - PORT_DIPSETTING( 0x10, "5" ) - PORT_DIPSETTING( 0x14, "6" ) - PORT_DIPSETTING( 0x18, "7" ) - PORT_DIPSETTING( 0x1c, "8" ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Demo_Sounds ) ) + PORT_DIPNAME( 0x5c, 0x00, "Payout" ) PORT_DIPLOCATION("SW1:!3,!4,!5,!7") + PORT_DIPSETTING( 0x00, "110" ) // Service mode displays values as 1-8, ignoring SW1:7 + PORT_DIPSETTING( 0x04, "105" ) + PORT_DIPSETTING( 0x08, "100" ) + PORT_DIPSETTING( 0x0c, "95" ) + PORT_DIPSETTING( 0x10, "90" ) + PORT_DIPSETTING( 0x14, "85" ) + PORT_DIPSETTING( 0x18, "80" ) + PORT_DIPSETTING( 0x1c, "75" ) + PORT_DIPSETTING( 0x40, "70" ) + PORT_DIPSETTING( 0x44, "65" ) + PORT_DIPSETTING( 0x48, "60" ) + PORT_DIPSETTING( 0x4c, "55" ) + PORT_DIPSETTING( 0x50, "50" ) + PORT_DIPSETTING( 0x54, "45" ) + PORT_DIPSETTING( 0x58, "40" ) + PORT_DIPSETTING( 0x5c, "35" ) + PORT_DIPNAME( 0x20, 0x00, DEF_STR( Demo_Sounds ) ) PORT_DIPLOCATION("SW1:!6") PORT_DIPSETTING( 0x20, DEF_STR( Off ) ) PORT_DIPSETTING( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unused ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, "Diagnostic" ) + PORT_DIPNAME( 0x80, 0x00, "Diagnostic" ) PORT_DIPLOCATION("SW1:!8") PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) PORT_DIPSETTING( 0x80, DEF_STR( On ) ) PORT_START("DSWB") - PORT_DIPNAME( 0x03, 0x00, "Play Credit" ) - PORT_DIPSETTING( 0x00, "10 \xC2\xA5" ) - PORT_DIPSETTING( 0x01, "20 \xC2\xA5" ) - PORT_DIPSETTING( 0x02, "30 \xC2\xA5" ) - PORT_DIPSETTING( 0x03, "40 \xC2\xA5" ) - PORT_DIPNAME( 0x0c, 0x00, "Coin Exchange" ) + PORT_DIPNAME( 0x03, 0x00, "Play Credit" ) PORT_DIPLOCATION("SW2:!1,!2") + PORT_DIPSETTING( 0x00, UNICODE_YEN "10" ) + PORT_DIPSETTING( 0x01, UNICODE_YEN "20" ) + PORT_DIPSETTING( 0x02, UNICODE_YEN "30" ) + PORT_DIPSETTING( 0x03, UNICODE_YEN "40" ) + PORT_DIPNAME( 0x0c, 0x00, "Coin Exchange" ) PORT_DIPLOCATION("SW2:!3,!4") PORT_DIPSETTING( 0x00, "12" ) PORT_DIPSETTING( 0x04, "10" ) PORT_DIPSETTING( 0x08, "6" ) PORT_DIPSETTING( 0x0c, "5" ) - PORT_DIPNAME( 0x30, 0x00, "Game Mode" ) + PORT_DIPNAME( 0x30, 0x00, "Game Mode" ) PORT_DIPLOCATION("SW2:!5,!6") PORT_DIPSETTING( 0x00, DEF_STR( Normal ) ) PORT_DIPSETTING( 0x10, "Shot" ) PORT_DIPSETTING( 0x20, "Auto" ) PORT_DIPSETTING( 0x30, "S-Manual" ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unused ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unused ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "SW2:!7" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW2:!8" ) PORT_START("DSWC") - PORT_DIPNAME( 0x01, 0x00, "DSWC" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_DIPNAME( 0x04, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x04, DEF_STR( On ) ) - PORT_DIPNAME( 0x08, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x08, DEF_STR( On ) ) - PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + PORT_DIPUNUSED_DIPLOC( 0x01, 0x00, "SW3:!1" ) + PORT_DIPUNUSED_DIPLOC( 0x02, 0x00, "SW3:!2" ) + PORT_DIPUNUSED_DIPLOC( 0x04, 0x00, "SW3:!3" ) + PORT_DIPUNUSED_DIPLOC( 0x08, 0x00, "SW3:!4" ) + PORT_DIPUNUSED_DIPLOC( 0x10, 0x00, "SW3:!5" ) + PORT_DIPUNUSED_DIPLOC( 0x20, 0x00, "SW3:!6" ) + PORT_DIPUNUSED_DIPLOC( 0x40, 0x00, "SW3:!7" ) + PORT_DIPUNUSED_DIPLOC( 0x80, 0x00, "SW3:!8" ) PORT_START("IN1") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 ) PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Left Button") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Center Button") PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Right Button") - PORT_DIPNAME( 0x10, 0x00, "IN1" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + PORT_BIT( 0xf0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("IN2") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_GAMBLE_KEYIN ) // 10 Yen - PORT_SERVICE( 0x02, IP_ACTIVE_HIGH ) + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN2 ) PORT_NAME("Coin 2 (" UNICODE_YEN "10)") + PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_HIGH ) PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Down Button") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, toaplan2_state, pwrkick_hopper_status_r, nullptr) + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER("hopper", ticket_dispenser_device, line_r) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_MEMORY_RESET ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_DIPNAME( 0x40, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x40, DEF_STR( On ) ) - PORT_DIPNAME( 0x80, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x80, DEF_STR( On ) ) + PORT_BIT( 0xe0, IP_ACTIVE_HIGH, IPT_UNUSED ) PORT_START("SYS") - PORT_DIPNAME( 0x01, 0x00, "SYS" ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x01, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x02, DEF_STR( On ) ) - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN2 ) // 100 Yen - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_SERVICE1 ) PORT_NAME("Bookkeeping") - PORT_DIPNAME( 0x10, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x10, DEF_STR( On ) ) - PORT_DIPNAME( 0x20, 0x00, DEF_STR( Unknown ) ) - PORT_DIPSETTING( 0x00, DEF_STR( Off ) ) - PORT_DIPSETTING( 0x20, DEF_STR( On ) ) - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_SERVICE4 ) PORT_NAME("Attendant Key") - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 ) + PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_COIN3 ) PORT_NAME("Coin Exchange (" UNICODE_YEN "100)") + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_GAMBLE_BOOK ) + PORT_BIT( 0x30, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_GAMBLE_SERVICE ) PORT_NAME("Attendant Key") + PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_COIN1 ) PORT_NAME("Coin 1 (Medal)") + + // The specific "Payout" button shown on the test screen and diagnostic menu does not exist. INPUT_PORTS_END static INPUT_PORTS_START( othldrby ) @@ -3658,6 +3631,10 @@ static MACHINE_CONFIG_START( pwrkick, toaplan2_state ) MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2) MCFG_UPD4992_ADD("rtc") + MCFG_NVRAM_ADD_0FILL("nvram") + + MCFG_TICKET_DISPENSER_ADD("hopper", attotime::from_msec(PWRKICK_HOPPER_PULSE), TICKET_MOTOR_ACTIVE_HIGH, TICKET_STATUS_ACTIVE_HIGH) + /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) @@ -3690,6 +3667,8 @@ static MACHINE_CONFIG_START( othldrby, toaplan2_state ) MCFG_MACHINE_START_OVERRIDE(toaplan2_state,toaplan2) MCFG_UPD4992_ADD("rtc") + MCFG_NVRAM_ADD_0FILL("nvram") + /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_BEFORE_VBLANK) diff --git a/src/mame/includes/toaplan2.h b/src/mame/includes/toaplan2.h index 1a7eb44e195..a4fbde58e80 100644 --- a/src/mame/includes/toaplan2.h +++ b/src/mame/includes/toaplan2.h @@ -12,6 +12,7 @@ #include "machine/eepromser.h" #include "machine/gen_latch.h" #include "machine/nmk112.h" +#include "machine/ticket.h" #include "machine/upd4992.h" #include "video/gp9001.h" #include "sound/okim6295.h" @@ -47,7 +48,8 @@ public: m_screen(*this, "screen"), m_palette(*this, "palette"), m_soundlatch(*this, "soundlatch"), - m_soundlatch2(*this, "soundlatch2") { } + m_soundlatch2(*this, "soundlatch2"), + m_hopper(*this, "hopper") { } optional_shared_ptr m_shared_ram; // 8 bit RAM shared between 68K and sound CPU optional_shared_ptr m_shared_ram16; // Really 8 bit RAM connected to Z180 @@ -72,6 +74,7 @@ public: required_device m_palette; optional_device m_soundlatch; // batrider and bgaregga and batsugun optional_device m_soundlatch2; + optional_device m_hopper; UINT16 m_mcu_data; INT8 m_old_p1_paddle_h; /* For Ghox */ @@ -158,9 +161,8 @@ public: void create_tx_tilemap(int dx = 0, int dx_flipped = 0); void toaplan2_vblank_irq(int irq_line); - UINT8 m_pwrkick_hopper; - DECLARE_CUSTOM_INPUT_MEMBER(pwrkick_hopper_status_r); DECLARE_WRITE8_MEMBER(pwrkick_coin_w); + DECLARE_WRITE8_MEMBER(pwrkick_coin_lockout_w); DECLARE_WRITE_LINE_MEMBER(toaplan2_reset); protected: