From 02e787e3d362b9a748beb2d57972ed73a424a93c Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 21 May 2017 01:31:52 -0400 Subject: [PATCH] Partially rewrite uPD4701 device and hook it up to a few Sega games --- src/devices/machine/upd4701.cpp | 303 ++++++++++++++++++++------------ src/devices/machine/upd4701.h | 119 +++++++++---- src/mame/drivers/ksys573.cpp | 39 +--- src/mame/drivers/segae.cpp | 79 +++------ src/mame/drivers/segas32.cpp | 81 +++------ src/mame/includes/segas32.h | 7 - 6 files changed, 327 insertions(+), 301 deletions(-) diff --git a/src/devices/machine/upd4701.cpp b/src/devices/machine/upd4701.cpp index 8b6c161efbf..cfce7086b99 100644 --- a/src/devices/machine/upd4701.cpp +++ b/src/devices/machine/upd4701.cpp @@ -1,27 +1,38 @@ -// license:BSD-3-Clause +// license:BSD-3-Clause,AJR // copyright-holders:smf /*************************************************************************** - NEC uPD4701 - - Incremental Encoder Control - - 2009-06 Converted to be a device + NEC µPD4701A 2-Axis Incremental Encoder Counter ***************************************************************************/ #include "emu.h" #include "upd4701.h" -#define MASK_SWITCHES ( 7 ) #define MASK_COUNTER ( 0xfff ) -DEFINE_DEVICE_TYPE(UPD4701, upd4701_device, "upd4701", "uPD4701 Encoder") +DEFINE_DEVICE_TYPE(UPD4701A, upd4701_device, "upd4701a", "uPD4701A Incremental Encoder") -upd4701_device::upd4701_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : device_t(mconfig, UPD4701, tag, owner, clock) - , m_cs(0), m_xy(0), m_ul(0), m_resetx(0), m_resety(0), m_latchx(0), m_latchy(0) - , m_startx(0), m_starty(0), m_x(0), m_y(0), m_switches(0), m_latchswitches(0), m_cf(0) +upd4701_device::upd4701_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, UPD4701A, tag, owner, clock) + , m_cs(true) + , m_xy(false) + , m_ul(false) + , m_resetx(false) + , m_resety(false) + , m_portx(*this, finder_base::DUMMY_TAG) + , m_porty(*this, finder_base::DUMMY_TAG) + , m_latchx(0) + , m_latchy(0) + , m_startx(0) + , m_starty(0) + , m_x(0) + , m_y(0) + , m_switches(0) + , m_latchswitches(0) + , m_cf(true) + , m_cf_cb(*this) + , m_sf_cb(*this) { } @@ -31,6 +42,11 @@ upd4701_device::upd4701_device(const machine_config &mconfig, const char *tag, d void upd4701_device::device_start() { + // resolve callbacks + m_cf_cb.resolve_safe(); + m_sf_cb.resolve_safe(); + + // register state for saving save_item(NAME(m_cs)); save_item(NAME(m_xy)); save_item(NAME(m_ul)); @@ -45,56 +61,35 @@ void upd4701_device::device_start() save_item(NAME(m_switches)); save_item(NAME(m_latchswitches)); save_item(NAME(m_cf)); + + // register special callback for analog inputs + if (m_portx.found() || m_porty.found()) + machine().add_notifier(MACHINE_NOTIFY_FRAME, machine_notify_delegate(&upd4701_device::analog_update, this)); } //------------------------------------------------- -// device_reset - device-specific reset +// ul_w - write to counter select line //------------------------------------------------- -void upd4701_device::device_reset() -{ - m_cs = 1; - m_xy = 0; - m_ul = 0; - m_resetx = 0; - m_resety = 0; - m_latchx = 0; - m_latchy = 0; - m_startx = 0; - m_starty = 0; - m_x = 0; - m_y = 0; - m_switches = 0; - m_latchswitches = 0; - m_cf = 1; -} - -/* x,y increments can be 12bit (see MASK_COUNTER), hence we need a couple of -16bit handlers in the following */ - -/*------------------------------------------------- - ul_w --------------------------------------------------*/ - -WRITE_LINE_MEMBER( upd4701_device::ul_w ) +WRITE_LINE_MEMBER(upd4701_device::ul_w) { m_ul = state; } -/*------------------------------------------------- - xy_w --------------------------------------------------*/ +//------------------------------------------------- +// xy_w - write to byte select line +//------------------------------------------------- -WRITE_LINE_MEMBER( upd4701_device::xy_w ) +WRITE_LINE_MEMBER(upd4701_device::xy_w) { m_xy = state; } -/*------------------------------------------------- - cs_w --------------------------------------------------*/ +//------------------------------------------------- +// cs_w - write to chip select line +//------------------------------------------------- -WRITE_LINE_MEMBER( upd4701_device::cs_w ) +WRITE_LINE_MEMBER(upd4701_device::cs_w) { if (m_cs != state) { @@ -105,147 +100,233 @@ WRITE_LINE_MEMBER( upd4701_device::cs_w ) m_latchx = (m_x - m_startx) & MASK_COUNTER; m_latchy = (m_y - m_starty) & MASK_COUNTER; - m_latchswitches = (~m_switches) & MASK_SWITCHES; - if (m_latchswitches != 0) - { + m_latchswitches = m_switches; + if (m_switches != 0) m_latchswitches |= 8; - } - m_cf = 1; + if (!m_cf) + { + // CF remains inactive while CS is low + m_cf = true; + m_cf_cb(1); + } } } } -/*------------------------------------------------- - resetx_w --------------------------------------------------*/ +//------------------------------------------------- +// resetx_w - write to X counter reset line +//------------------------------------------------- -WRITE_LINE_MEMBER( upd4701_device::resetx_w ) +WRITE_LINE_MEMBER(upd4701_device::resetx_w) { if (m_resetx != state) { m_resetx = state; if (m_resetx) - { m_startx = m_x; - } } } -/*------------------------------------------------- - resety_w --------------------------------------------------*/ +//------------------------------------------------- +// resety_w - write to Y counter reset line +//------------------------------------------------- -WRITE_LINE_MEMBER( upd4701_device::resety_w ) +WRITE_LINE_MEMBER(upd4701_device::resety_w) { if (m_resety != state) { m_resety = state; if (m_resety) - { m_starty = m_y; - } } } -/*------------------------------------------------- - x_add --------------------------------------------------*/ +//------------------------------------------------- +// reset_xy - pulse the counter reset lines +//------------------------------------------------- -void upd4701_device::x_add( int16_t data ) +WRITE8_MEMBER(upd4701_device::reset_xy) +{ + resetx_w(1); + resety_w(1); + resetx_w(0); + resety_w(0); +} + +//------------------------------------------------- +// analog_update - per-frame input update +//------------------------------------------------- + +void upd4701_device::analog_update() +{ + if (m_portx.found()) + x_add(m_portx->read() & MASK_COUNTER); + if (m_porty.found()) + y_add(m_porty->read() & MASK_COUNTER); +} + +//------------------------------------------------- +// x_add - count X-axis input +//------------------------------------------------- + +void upd4701_device::x_add(s16 data) { if (!m_resetx && data != 0) { m_x += data; - if (m_cs) + if (m_cs && m_cf) { - m_cf = 0; + m_cf = false; + m_cf_cb(0); } } } -/*------------------------------------------------- - y_add --------------------------------------------------*/ +//------------------------------------------------- +// y_add - count Y-axis input +//------------------------------------------------- -void upd4701_device::y_add( int16_t data ) +void upd4701_device::y_add(s16 data) { if (!m_resety && data != 0) { m_y += data; - if (m_cs) + if (m_cs && m_cf) { - m_cf = 0; + m_cf = false; + m_cf_cb(0); } } } -/*------------------------------------------------- - switches_set --------------------------------------------------*/ +//------------------------------------------------- +// switch_update - update one of three switches +//------------------------------------------------- -void upd4701_device::switches_set( uint8_t data ) +void upd4701_device::switch_update(u8 mask, bool state) { - m_switches = data; + if (!state && (m_switches & mask) == 0) + { + // active low + m_switches |= mask; + + // update SF output if other switches were not active + if ((m_switches & ~mask) == 0) + m_sf_cb(0); + } + else if (state && (m_switches & mask) == mask) + { + // inactive high + m_switches &= ~mask; + + // update SF output if other switches are also inactive + if ((m_switches & ~mask) == 0) + m_sf_cb(1); + } } -/*------------------------------------------------- - d_r --------------------------------------------------*/ +//------------------------------------------------- +// left_w - update left switch state +//------------------------------------------------- -READ16_MEMBER( upd4701_device::d_r ) +WRITE_LINE_MEMBER(upd4701_device::left_w) { - int data; + switch_update(4, state); +} +//------------------------------------------------- +// right_w - update right switch state +//------------------------------------------------- + +WRITE_LINE_MEMBER(upd4701_device::right_w) +{ + switch_update(2, state); +} + +//------------------------------------------------- +// middle_w - update middle switch state +//------------------------------------------------- + +WRITE_LINE_MEMBER(upd4701_device::middle_w) +{ + switch_update(1, state); +} + +//------------------------------------------------- +// d_r - read data lines directly +//------------------------------------------------- + +READ8_MEMBER(upd4701_device::d_r) +{ if (m_cs) { - return 0xff; - } - - if (m_xy) - { - data = m_latchy; - } - else - { - data = m_latchx; + logerror("Read while CS inactive\n"); + return space.unmap(); } + u16 data = m_xy ? m_latchy : m_latchx; data |= m_latchswitches << 12; if (m_ul) - { return data >> 8; - } else - { return data & 0xff; - } } -/*------------------------------------------------- - sf_r --------------------------------------------------*/ +//------------------------------------------------- +// read_x - read X axis through data/address bus +//------------------------------------------------- -READ_LINE_MEMBER( upd4701_device::sf_r ) +READ8_MEMBER(upd4701_device::read_x) { - if ((m_switches & MASK_SWITCHES) != MASK_SWITCHES) - { + return read_xy(space, (offset & 1) | 0); +} + +//------------------------------------------------- +// read_y - read Y axis through data/address bus +//------------------------------------------------- + +READ8_MEMBER(upd4701_device::read_y) +{ + return read_xy(space, (offset & 1) | 2); +} + +//------------------------------------------------- +// read_xy - read either axis through bus +//------------------------------------------------- + +READ8_MEMBER(upd4701_device::read_xy) +{ + cs_w(0); + xy_w(BIT(offset, 1)); + ul_w(BIT(offset, 0)); + u8 result = d_r(space, 0); + cs_w(1); + return result; +} + +//------------------------------------------------- +// sf_r - read switch flag +//------------------------------------------------- + +READ_LINE_MEMBER(upd4701_device::sf_r) +{ + if (m_switches != 0) return 0; - } return 1; } -/*------------------------------------------------- - cf_r --------------------------------------------------*/ +//------------------------------------------------- +// cf_r - read counter flag +//------------------------------------------------- -READ_LINE_MEMBER( upd4701_device::cf_r ) +READ_LINE_MEMBER(upd4701_device::cf_r) { return m_cf; } diff --git a/src/devices/machine/upd4701.h b/src/devices/machine/upd4701.h index c2959df138b..71a58df0de7 100644 --- a/src/devices/machine/upd4701.h +++ b/src/devices/machine/upd4701.h @@ -1,10 +1,23 @@ // license:BSD-3-Clause -// copyright-holders:smf +// copyright-holders:smf,AJR /*************************************************************************** - NEC uPD4701 + NEC µPD4701A 2-Axis Incremental Encoder Counter - Incremental Encoder Control +**************************************************************************** + _____ _____ + Xa 1 |* \_/ | 24 Vdd + Xb 2 | | 23 D7 + RESET X 3 | | 22 D6 + Ya 4 | | 21 D5 + Yb 5 | uPD4701A | 20 D4 + RESET Y 6 | | 19 D3 + /RIGHT 7 | | 18 D2 + /LEFT 8 | | 17 D1 + /MIDDLE 9 | | 16 D0 + /SF 10 | | 15 _CS + /CF 11 | | 14 _X/Y + Vss 12 |_____________| 13 U/_L ***************************************************************************/ @@ -18,52 +31,86 @@ MACROS / CONSTANTS ***************************************************************************/ +#define MCFG_UPD4701_PORTX(_tag) \ + upd4701_device::set_portx_tag(*device, "^" _tag); +#define MCFG_UPD4701_PORTY(_tag) \ + upd4701_device::set_porty_tag(*device, "^" _tag); +#define MCFG_UPD4701_CF_CALLBACK(_devcb) \ + devcb = upd4701_device::set_cf_cb(*device, DEVCB_##_devcb); +#define MCFG_UPD4701_SF_CALLBACK(_devcb) \ + devcb = upd4701_device::set_sf_cb(*device, DEVCB_##_devcb); + class upd4701_device : public device_t { public: - upd4701_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + upd4701_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); - void x_add( int16_t data ); - void y_add( int16_t data ); - void switches_set( uint8_t data ); + // static configuration + static void set_portx_tag(device_t &device, const char *tag) { downcast(device).m_portx.set_tag(tag); } + static void set_porty_tag(device_t &device, const char *tag) { downcast(device).m_porty.set_tag(tag); } + template + static devcb_base &set_cf_cb(device_t &device, Object &&cb) { return downcast(device).m_cf_cb.set_callback(std::forward(cb)); } + template + static devcb_base &set_sf_cb(device_t &device, Object &&cb) { return downcast(device).m_sf_cb.set_callback(std::forward(cb)); } - DECLARE_WRITE_LINE_MEMBER( cs_w ); - DECLARE_WRITE_LINE_MEMBER( xy_w ); - DECLARE_WRITE_LINE_MEMBER( ul_w ); - DECLARE_WRITE_LINE_MEMBER( resetx_w ); - DECLARE_WRITE_LINE_MEMBER( resety_w ); + void x_add(s16 data); + void y_add(s16 data); - DECLARE_READ16_MEMBER( d_r ); - DECLARE_READ_LINE_MEMBER( cf_r ); - DECLARE_READ_LINE_MEMBER( sf_r ); + DECLARE_WRITE_LINE_MEMBER(cs_w); + DECLARE_WRITE_LINE_MEMBER(xy_w); + DECLARE_WRITE_LINE_MEMBER(ul_w); + DECLARE_WRITE_LINE_MEMBER(resetx_w); + DECLARE_WRITE_LINE_MEMBER(resety_w); + DECLARE_WRITE8_MEMBER(reset_xy); + + DECLARE_READ8_MEMBER(d_r); + DECLARE_READ8_MEMBER(read_x); + DECLARE_READ8_MEMBER(read_y); + DECLARE_READ8_MEMBER(read_xy); + + DECLARE_WRITE_LINE_MEMBER(left_w); + DECLARE_WRITE_LINE_MEMBER(right_w); + DECLARE_WRITE_LINE_MEMBER(middle_w); + + DECLARE_READ_LINE_MEMBER(cf_r); + DECLARE_READ_LINE_MEMBER(sf_r); protected: // device-level overrides virtual void device_start() override; - virtual void device_reset() override; private: - // internal state - int m_cs; - int m_xy; - int m_ul; - int m_resetx; - int m_resety; - int m_latchx; - int m_latchy; - int m_startx; - int m_starty; - int m_x; - int m_y; - int m_switches; - int m_latchswitches; - int m_cf; + // internal helpers + void analog_update(); + void switch_update(u8 mask, bool state); + + // control lines + bool m_cs; // chip select (active low) + bool m_xy; // counter select (L = X, H = Y) + bool m_ul; // byte select (L = lower, H = upper) + bool m_resetx; // X-axis counter reset (active high) + bool m_resety; // Y-axis counter reset (active high) + + // counter state + optional_ioport m_portx; + optional_ioport m_porty; + s16 m_latchx; + s16 m_latchy; + s16 m_startx; + s16 m_starty; + s16 m_x; + s16 m_y; + + // switch state + u8 m_switches; + u8 m_latchswitches; + + // flag outputs and callbacks + bool m_cf; + devcb_write_line m_cf_cb; + devcb_write_line m_sf_cb; }; -DECLARE_DEVICE_TYPE(UPD4701, upd4701_device) - - -#define MCFG_UPD4701_ADD(tag) \ - MCFG_DEVICE_ADD((tag), UPD4701, 0) +DECLARE_DEVICE_TYPE(UPD4701A, upd4701_device) #endif // MAME_MACHINE_UPD4701_H diff --git a/src/mame/drivers/ksys573.cpp b/src/mame/drivers/ksys573.cpp index 4d70db2351d..dfd37ac2ef6 100644 --- a/src/mame/drivers/ksys573.cpp +++ b/src/mame/drivers/ksys573.cpp @@ -392,8 +392,6 @@ public: m_out2(*this, "OUT2" ), m_cd(*this, "CD" ), m_upd4701(*this, "upd4701" ), - m_upd4701_y(*this, "uPD4701_y" ), - m_upd4701_switches(*this, "uPD4701_switches" ), m_stage(*this, "STAGE" ), m_gunx(*this, "GUNX" ), m_sensor(*this, "SENSOR" ), @@ -534,8 +532,6 @@ private: required_ioport m_out2; required_ioport m_cd; optional_device m_upd4701; - optional_ioport m_upd4701_y; - optional_ioport m_upd4701_switches; optional_ioport m_stage; optional_ioport m_gunx; optional_ioport m_sensor; @@ -842,38 +838,19 @@ todo: READ16_MEMBER( ksys573_state::ge765pwbba_r ) { - uint32_t data = 0; - switch( offset ) { case 0x4c: case 0x4d: - m_upd4701->y_add( m_upd4701_y->read() ); - m_upd4701->switches_set( m_upd4701_switches->read() ); - - m_upd4701->cs_w( 0 ); - m_upd4701->xy_w( 1 ); - - if( offset == 0x4c ) - { - m_upd4701->ul_w( 0 ); - } - else - { - m_upd4701->ul_w( 1 ); - } - - data = m_upd4701->d_r( space, 0, 0xffff ); - m_upd4701->cs_w( 1 ); - break; + return m_upd4701->read_y(space, offset & 1); default: verboselog( 0, "ge765pwbba_r: unhandled offset %08x %08x\n", offset, mem_mask ); break; } - verboselog( 2, "ge765pwbba_r( %08x, %08x ) %08x\n", offset, mem_mask, data ); - return data; + verboselog( 2, "ge765pwbba_r( %08x, %08x )\n", offset, mem_mask ); + return 0; } WRITE16_MEMBER( ksys573_state::ge765pwbba_w ) @@ -2330,7 +2307,9 @@ static MACHINE_CONFIG_DERIVED( fbaitbc, konami573 ) MCFG_CPU_MODIFY( "maincpu" ) MCFG_CPU_PROGRAM_MAP( fbaitbc_map ) - MCFG_UPD4701_ADD( "upd4701" ) + MCFG_DEVICE_ADD("upd4701", UPD4701A, 0) + MCFG_UPD4701_PORTY("uPD4701_y") + MCFG_FRAGMENT_ADD( cassx ) MACHINE_CONFIG_END @@ -2528,9 +2507,9 @@ static INPUT_PORTS_START( fbaitbc ) PORT_BIT( 0x0fff, 0, IPT_MOUSE_Y ) PORT_MINMAX( 0, 0xfff ) PORT_SENSITIVITY( 15 ) PORT_KEYDELTA( 8 ) PORT_RESET PORT_START( "uPD4701_switches" ) - PORT_BIT( 0x0001, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER( 1 ) - PORT_BIT( 0x0002, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER( 1 ) - PORT_BIT( 0x0004, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER( 1 ) + PORT_BIT( 0x1, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1) PORT_WRITE_LINE_DEVICE_MEMBER("upd4701", upd4701_device, middle_w) + PORT_BIT( 0x2, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_PLAYER(1) PORT_WRITE_LINE_DEVICE_MEMBER("upd4701", upd4701_device, right_w) + PORT_BIT( 0x4, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_PLAYER(1) PORT_WRITE_LINE_DEVICE_MEMBER("upd4701", upd4701_device, left_w) INPUT_PORTS_END static INPUT_PORTS_START( fbaitmc ) diff --git a/src/mame/drivers/segae.cpp b/src/mame/drivers/segae.cpp index e7e06670405..49a6758450e 100644 --- a/src/mame/drivers/segae.cpp +++ b/src/mame/drivers/segae.cpp @@ -299,6 +299,7 @@ GND 8A 8B GND #include "machine/i8255.h" #include "machine/mc8123.h" #include "machine/segacrp2_device.h" +#include "machine/upd4701.h" #include "sound/sn76496.h" #include "video/315_5124.h" #include "speaker.h" @@ -324,8 +325,6 @@ public: DECLARE_WRITE8_MEMBER(bank_write); DECLARE_WRITE8_MEMBER(coin_counters_write); - DECLARE_READ8_MEMBER( ridleofp_port_f8_read ); - DECLARE_WRITE8_MEMBER( ridleofp_port_fa_write ); DECLARE_READ8_MEMBER( hangonjr_port_f8_read ); DECLARE_WRITE8_MEMBER( hangonjr_port_fa_write ); @@ -345,10 +344,6 @@ public: // Analog input related uint8_t m_port_select; - uint16_t m_last1; - uint16_t m_last2; - uint16_t m_diff1; - uint16_t m_diff2; // Video RAM uint8_t m_vram[2][0x4000 * 2]; @@ -455,10 +450,6 @@ void systeme_state::machine_start() } save_item(NAME(m_port_select)); - save_item(NAME(m_last1)); - save_item(NAME(m_last2)); - save_item(NAME(m_diff1)); - save_item(NAME(m_diff2)); save_item(NAME(m_vram)); } @@ -485,41 +476,6 @@ WRITE8_MEMBER( systeme_state::hangonjr_port_fa_write) m_port_select = data & 0x0f; } -/*- Riddle of Pythagoras Specific -*/ - -READ8_MEMBER( systeme_state::ridleofp_port_f8_read ) -{ - switch (m_port_select) - { - default: - case 0: return m_diff1 & 0xff; - case 1: return m_diff1 >> 8; - case 2: return m_diff2 & 0xff; - case 3: return m_diff2 >> 8; - } -} - -WRITE8_MEMBER( systeme_state::ridleofp_port_fa_write ) -{ - /* 0x10 is written before reading the dial (hold counters?) */ - /* 0x03 is written after reading the dial (reset counters?) */ - - m_port_select = (data & 0x0c) >> 2; - - if (data & 1) - { - int curr = ioport("IN2")->read(); - m_diff1 = ((curr - m_last1) & 0x0fff) | (curr & 0xf000); - m_last1 = curr; - } - if (data & 2) - { - int curr = ioport("IN3")->read() & 0x0fff; - m_diff2 = ((curr - m_last2) & 0x0fff) | (curr & 0xf000); - m_last2 = curr; - } -} - /******************************************************************************* Input Ports @@ -717,19 +673,16 @@ static INPUT_PORTS_START( segae_ridleofp_generic ) //PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_START("IN2") /* Read from Port 0xf8 */ - PORT_BIT( 0x0fff, 0x0000, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(125) - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON2 ) /* is this used in the game? */ - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_START("PAD1") + PORT_BIT( 0xfff, 0x000, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(125) PORT_RESET - PORT_START("IN3") /* Read from Port 0xf8 */ - PORT_BIT( 0x0fff, 0x0000, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(125) PORT_COCKTAIL - PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_COCKTAIL - PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_COCKTAIL - PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_UNKNOWN ) + PORT_START("PAD2") + PORT_BIT( 0xfff, 0x000, IPT_DIAL ) PORT_SENSITIVITY(60) PORT_KEYDELTA(125) PORT_RESET PORT_COCKTAIL + + PORT_START("BUTTONS") + PORT_BIT( 0x1, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_WRITE_LINE_DEVICE_MEMBER("upd4701", upd4701_device, middle_w) // is this used in the game? + PORT_BIT( 0x2, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_WRITE_LINE_DEVICE_MEMBER("upd4701", upd4701_device, right_w) + PORT_BIT( 0x4, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_WRITE_LINE_DEVICE_MEMBER("upd4701", upd4701_device, left_w) INPUT_PORTS_END @@ -1044,9 +997,17 @@ static MACHINE_CONFIG_DERIVED( hangonjr, systeme ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( ridleofp, systeme ) + MCFG_DEVICE_ADD("upd4701", UPD4701A, 0) + MCFG_UPD4701_PORTX("PAD1") + MCFG_UPD4701_PORTY("PAD2") + MCFG_DEVICE_MODIFY("ppi") - MCFG_I8255_IN_PORTA_CB(READ8(systeme_state, ridleofp_port_f8_read)) - MCFG_I8255_OUT_PORTC_CB(WRITE8(systeme_state, ridleofp_port_fa_write)) + MCFG_I8255_IN_PORTA_CB(DEVREAD8("upd4701", upd4701_device, d_r)) + MCFG_I8255_OUT_PORTC_CB(DEVWRITELINE("upd4701", upd4701_device, cs_w)) MCFG_DEVCB_BIT(4) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("upd4701", upd4701_device, xy_w)) MCFG_DEVCB_BIT(3) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("upd4701", upd4701_device, ul_w)) MCFG_DEVCB_BIT(2) + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("upd4701", upd4701_device, resetx_w)) MCFG_DEVCB_BIT(1) // or possibly bit 0 + MCFG_DEVCB_CHAIN_OUTPUT(DEVWRITELINE("upd4701", upd4701_device, resety_w)) MCFG_DEVCB_BIT(0) // or possibly bit 1 MACHINE_CONFIG_END diff --git a/src/mame/drivers/segas32.cpp b/src/mame/drivers/segas32.cpp index 7ac164eb43a..06bf5b4c351 100644 --- a/src/mame/drivers/segas32.cpp +++ b/src/mame/drivers/segas32.cpp @@ -537,6 +537,7 @@ orunners: Interleaved with the dj and << >> buttons is the data the drives the #include "machine/mb8421.h" //#include "machine/mb89352.h" #include "machine/msm6253.h" +#include "machine/upd4701.h" #include "machine/315_5296.h" #include "sound/2612intf.h" #include "sound/rf5c68.h" @@ -903,56 +904,6 @@ WRITE_LINE_MEMBER(segas32_state::display_enable_1_w) -/************************************* - * - * I/O expansion range - * - *************************************/ - - - - -/************************************* - * - * Game-specific custom I/O - * - *************************************/ - -READ8_MEMBER(segas32_trackball_state::sonic_custom_io_r) -{ - switch (offset) - { - case 0x00/2: - case 0x04/2: - case 0x08/2: - case 0x0c/2: - case 0x10/2: - case 0x14/2: - return (uint8_t)(m_track_ports[offset/2]->read() - m_sonic_last[offset/2]); - } - - logerror("%06X:unknown sonic_custom_io_r(%X) & %04X\n", space.device().safe_pc(), offset*2, mem_mask); - return 0xff; -} - - -WRITE8_MEMBER(segas32_trackball_state::sonic_custom_io_w) -{ - switch (offset) - { - case 0x00/2: - case 0x08/2: - case 0x10/2: - m_sonic_last[offset/2 + 0] = m_track_ports[offset/2 + 0]->read(); - m_sonic_last[offset/2 + 1] = m_track_ports[offset/2 + 1]->read(); - return; - } - - logerror("%06X:unknown sonic_custom_io_w(%X) = %04X & %04X\n", space.device().safe_pc(), offset*2, data, mem_mask); -} - - - /************************************* * * Random number generator @@ -2134,22 +2085,22 @@ static INPUT_PORTS_START( sonic ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START3 ) PORT_START("mainpcb:TRACKX1") - PORT_BIT( 0xff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_REVERSE PORT_PLAYER(1) + PORT_BIT( 0xfff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_START("mainpcb:TRACKY1") - PORT_BIT( 0xff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_PLAYER(1) + PORT_BIT( 0xfff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_RESET PORT_PLAYER(1) PORT_START("mainpcb:TRACKX2") - PORT_BIT( 0xff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_REVERSE PORT_PLAYER(2) + PORT_BIT( 0xfff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_START("mainpcb:TRACKY2") - PORT_BIT( 0xff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_PLAYER(2) + PORT_BIT( 0xfff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_RESET PORT_PLAYER(2) PORT_START("mainpcb:TRACKX3") - PORT_BIT( 0xff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_REVERSE PORT_PLAYER(3) + PORT_BIT( 0xfff, 0, IPT_TRACKBALL_X ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_RESET PORT_REVERSE PORT_PLAYER(3) PORT_START("mainpcb:TRACKY3") - PORT_BIT( 0xff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_PLAYER(3) + PORT_BIT( 0xfff, 0, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_RESET PORT_PLAYER(3) INPUT_PORTS_END @@ -2395,7 +2346,10 @@ machine_config_constructor segas32_analog_state::device_mconfig_additions() cons static ADDRESS_MAP_START( system32_trackball_map, AS_PROGRAM, 16, segas32_trackball_state ) ADDRESS_MAP_UNMAP_HIGH - AM_RANGE(0xc00040, 0xc0005f) AM_MIRROR(0x0fff80) AM_READWRITE8(sonic_custom_io_r, sonic_custom_io_w, 0x00ff) + //AM_RANGE(0xc00040, 0xc0005f) AM_MIRROR(0x0fff80) AM_READWRITE8(sonic_custom_io_r, sonic_custom_io_w, 0x00ff) + AM_RANGE(0xc00040, 0xc00047) AM_MIRROR(0x0fff80) AM_DEVREADWRITE8("upd1", upd4701_device, read_xy, reset_xy, 0x00ff) + AM_RANGE(0xc00048, 0xc0004f) AM_MIRROR(0x0fff80) AM_DEVREADWRITE8("upd2", upd4701_device, read_xy, reset_xy, 0x00ff) + AM_RANGE(0xc00050, 0xc00057) AM_MIRROR(0x0fff80) AM_DEVREADWRITE8("upd3", upd4701_device, read_xy, reset_xy, 0x00ff) AM_IMPORT_FROM(system32_map) ADDRESS_MAP_END @@ -2404,13 +2358,24 @@ static MACHINE_CONFIG_FRAGMENT( system32_trackball ) MCFG_DEVICE_MODIFY("maincpu") MCFG_DEVICE_PROGRAM_MAP(system32_trackball_map) + + MCFG_DEVICE_ADD("upd1", UPD4701A, 0) + MCFG_UPD4701_PORTX("TRACKX1") + MCFG_UPD4701_PORTY("TRACKY1") + + MCFG_DEVICE_ADD("upd2", UPD4701A, 0) + MCFG_UPD4701_PORTX("TRACKX2") + MCFG_UPD4701_PORTY("TRACKY2") + + MCFG_DEVICE_ADD("upd3", UPD4701A, 0) + MCFG_UPD4701_PORTX("TRACKX3") + MCFG_UPD4701_PORTY("TRACKY3") MACHINE_CONFIG_END DEFINE_DEVICE_TYPE(SEGA_S32_TRACKBALL_DEVICE, segas32_trackball_state, "segas32_pcb_trackball", "Sega System 32 trackball PCB") segas32_trackball_state::segas32_trackball_state(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : segas32_state(mconfig, SEGA_S32_TRACKBALL_DEVICE, tag, owner, clock) - , m_track_ports(*this, {"TRACKX1", "TRACKY1", "TRACKX2", "TRACKY2", "TRACKX3", "TRACKY3"}) { } diff --git a/src/mame/includes/segas32.h b/src/mame/includes/segas32.h index 8cbb0e04222..7e13162ac00 100644 --- a/src/mame/includes/segas32.h +++ b/src/mame/includes/segas32.h @@ -275,16 +275,9 @@ class segas32_trackball_state : public segas32_state public: segas32_trackball_state(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - DECLARE_READ8_MEMBER(sonic_custom_io_r); - DECLARE_WRITE8_MEMBER(sonic_custom_io_w); - protected: virtual machine_config_constructor device_mconfig_additions() const override; virtual void device_start() override; - -private: - required_ioport_array<6> m_track_ports; - uint8_t m_sonic_last[6]; }; class segas32_4player_state : public segas32_state