From 0188b4e80baefe6b5f889b92fe3cd1c6e52f5cab Mon Sep 17 00:00:00 2001 From: AJR Date: Wed, 12 Apr 2017 23:09:01 -0400 Subject: segaybd.cpp, srallyc: Add OKI MSM6253 device --- scripts/src/machine.lua | 12 ++++ scripts/target/mame/arcade.lua | 1 + scripts/target/mame/mess.lua | 1 + src/devices/machine/msm6253.cpp | 130 ++++++++++++++++++++++++++++++++++++++++ src/devices/machine/msm6253.h | 104 ++++++++++++++++++++++++++++++++ src/mame/drivers/model2.cpp | 5 +- src/mame/drivers/segaybd.cpp | 33 ++++------ src/mame/includes/segaybd.h | 7 +-- 8 files changed, 266 insertions(+), 27 deletions(-) create mode 100644 src/devices/machine/msm6253.cpp create mode 100644 src/devices/machine/msm6253.h diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index fd0f4c5c17a..82dd39639d8 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -1867,6 +1867,18 @@ if (MACHINES["MSM6242"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/msm6253.h,MACHINES["MSM6253"] = true +--------------------------------------------------- + +if (MACHINES["MSM6253"]~=null) then + files { + MAME_DIR .. "src/devices/machine/msm6253.cpp", + MAME_DIR .. "src/devices/machine/msm6253.h", + } +end + --------------------------------------------------- -- --@src/devices/machine/ncr539x.h,MACHINES["NCR539x"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index cbd77162be7..f24f31cde31 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -500,6 +500,7 @@ MACHINES["MPU401"] = true MACHINES["MSM5832"] = true MACHINES["MSM58321"] = true MACHINES["MSM6242"] = true +MACHINES["MSM6253"] = true --MACHINES["NCR5380"] = true --MACHINES["NCR5380N"] = true --MACHINES["NCR5390"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 8e5ae152a5c..07e7509c57a 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -487,6 +487,7 @@ MACHINES["MPU401"] = true MACHINES["MSM5832"] = true MACHINES["MSM58321"] = true MACHINES["MSM6242"] = true +--MACHINES["MSM6253"] = true MACHINES["NCR5380"] = true MACHINES["NCR5380N"] = true MACHINES["NCR5390"] = true diff --git a/src/devices/machine/msm6253.cpp b/src/devices/machine/msm6253.cpp new file mode 100644 index 00000000000..ad777bcaccb --- /dev/null +++ b/src/devices/machine/msm6253.cpp @@ -0,0 +1,130 @@ +// license:BSD-3-Clause +// copyright-holders: AJR +/********************************************************************** + + OKI MSM6253 8-Bit 4-Channel A/D Converter + +**********************************************************************/ + +#include "emu.h" +#include "machine/msm6253.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type MSM6253 = device_creator; + +//************************************************************************** +// DEVICE DEFINITION +//************************************************************************** + +//------------------------------------------------- +// msm6253_device - constructor +//------------------------------------------------- + +msm6253_device::msm6253_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, MSM6253, "MSM6253 A/D Converter", tag, owner, clock, "msm6253", __FILE__), + m_analog_ports(*this, {finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG, finder_base::DUMMY_TAG}), + m_shift_register(0) +{ + m_analog_input_cb[0] = analog_port_read_delegate(FUNC(msm6253_device::port_read<0>), this); + m_analog_input_cb[1] = analog_port_read_delegate(FUNC(msm6253_device::port_read<1>), this); + m_analog_input_cb[2] = analog_port_read_delegate(FUNC(msm6253_device::port_read<2>), this); + m_analog_input_cb[3] = analog_port_read_delegate(FUNC(msm6253_device::port_read<3>), this); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void msm6253_device::device_start() +{ + for (int port = 0; port < 4; port++) + { + // resolve each callback + m_analog_input_cb[port].bind_relative_to(*owner()); + + // ensure that any configured ports truly are analog + if (m_analog_ports[port].found()) + { + for (ioport_field &field : m_analog_ports[port]->fields()) + if (!field.is_analog() && field.type() != IPT_UNKNOWN && field.type() != IPT_UNUSED) + throw emu_fatalerror("Port %s is not an analog port\n", m_analog_ports[port]->tag()); + } + } + + // save our state + save_item(NAME(m_shift_register)); +} + +//------------------------------------------------- +// port_read - helper to read configured ports +//------------------------------------------------- + +template +ioport_value msm6253_device::port_read() +{ + if (m_analog_ports[port].found()) + return m_analog_ports[port]->read(); + + logerror("%s: Read from unassigned IN%d\n", port); + return 0xff; +} + +//------------------------------------------------- +// address_w - write from address bus to select +// one of four internal latches +//------------------------------------------------- + +WRITE8_MEMBER(msm6253_device::address_w) +{ + // fill the shift register from the internal A/D latch + m_shift_register = m_analog_input_cb[offset & 3](); +} + +//------------------------------------------------- +// select_w - write D0/D1 to address latch +//------------------------------------------------- + +WRITE8_MEMBER(msm6253_device::select_w) +{ + // fill the shift register from the internal A/D latch + m_shift_register = m_analog_input_cb[data & 3](); +} + +//------------------------------------------------- +// shift_out - MSB-first serial data output +//------------------------------------------------- + +bool msm6253_device::shift_out() +{ + // capture the shifted bit + bool msb = BIT(m_shift_register, 7); + + // shift the bit out, with zero coming in on the other end + m_shift_register <<= 1; + + // return the bit + return msb; +} + +//------------------------------------------------- +// d0_r - shift data bit out to D0 +//------------------------------------------------- + +READ8_MEMBER(msm6253_device::d0_r) +{ + // offset is ignored + return shift_out(); +} + +//------------------------------------------------- +// d7_r - shift data bit out to D7 +//------------------------------------------------- + +READ8_MEMBER(msm6253_device::d7_r) +{ + // offset is ignored + return shift_out() << 7; +} diff --git a/src/devices/machine/msm6253.h b/src/devices/machine/msm6253.h new file mode 100644 index 00000000000..68db51d3045 --- /dev/null +++ b/src/devices/machine/msm6253.h @@ -0,0 +1,104 @@ +// license:BSD-3-Clause +// copyright-holders: AJR +/********************************************************************** + + OKI MSM6253 8-Bit 4-Channel A/D Converter + +*********************************************************************** + ____ ____ + /OSC OUT 1 |* \_/ | 18 OSC OUT + D-GND 2 | | 17 OSC IN + A-GND 3 | | 16 /RD + IN0 4 | | 15 /WR + IN1 5 | MSM6253RS | 14 ALE + IN2 6 | | 13 /CS + IN3 7 | | 12 A1 + Vr 8 | | 11 A0 + Vdd 9 |___________| 10 S.O. + +**********************************************************************/ + +#pragma once + +#ifndef DEVICES_MACHINE_MSM6253_H +#define DEVICES_MACHINE_MSM6253_H + +//************************************************************************** +// CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_MSM6253_IN0_ANALOG_PORT(_input) \ + msm6253_device::static_set_input_tag(*device, 0, "^" _input); +#define MCFG_MSM6253_IN1_ANALOG_PORT(_input) \ + msm6253_device::static_set_input_tag(*device, 1, "^" _input); +#define MCFG_MSM6253_IN2_ANALOG_PORT(_input) \ + msm6253_device::static_set_input_tag(*device, 2, "^" _input); +#define MCFG_MSM6253_IN3_ANALOG_PORT(_input) \ + msm6253_device::static_set_input_tag(*device, 3, "^" _input); + +#define MCFG_MSM6253_IN0_ANALOG_READ(_class, _method) \ + msm6253_device::static_set_input_cb(*device, 0, analog_port_read_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); +#define MCFG_MSM6253_IN1_ANALOG_READ(_class, _method) \ + msm6253_device::static_set_input_cb(*device, 1, analog_port_read_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); +#define MCFG_MSM6253_IN2_ANALOG_READ(_class, _method) \ + msm6253_device::static_set_input_cb(*device, 2, analog_port_read_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); +#define MCFG_MSM6253_IN3_ANALOG_READ(_class, _method) \ + msm6253_device::static_set_input_cb(*device, 3, analog_port_read_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner))); + +#define MCFG_MSM6253_IN0_ANALOG_DEVREAD(_tag, _class, _method) \ + msm6253_device::static_set_input_cb(*device, 0, analog_port_read_delegate(&_class::_method, #_class "::" #_method, _tag)); +#define MCFG_MSM6253_IN1_ANALOG_DEVREAD(_tag, _class, _method) \ + msm6253_device::static_set_input_cb(*device, 1, analog_port_read_delegate(&_class::_method, #_class "::" #_method, _tag)); +#define MCFG_MSM6253_IN2_ANALOG_DEVREAD(_tag, _class, _method) \ + msm6253_device::static_set_input_cb(*device, 2, analog_port_read_delegate(&_class::_method, #_class "::" #_method, _tag)); +#define MCFG_MSM6253_IN3_ANALOG_DEVREAD(_tag, _class, _method) \ + msm6253_device::static_set_input_cb(*device, 3, analog_port_read_delegate(&_class::_method, #_class "::" #_method, _tag)); + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +typedef device_delegate analog_port_read_delegate; + +// ======================> msm6253_device + +class msm6253_device : public device_t +{ +public: + // construction/destruction + msm6253_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // static configuration + static void static_set_input_tag(device_t &device, int port, const char *tag) { downcast(device).m_analog_ports[port].set_tag(tag); } + static void static_set_input_cb(device_t &device, int port, analog_port_read_delegate &&cb) { downcast(device).m_analog_input_cb[port] = std::move(cb); } + + // write handlers + WRITE8_MEMBER(address_w); + WRITE8_MEMBER(select_w); + + // read handlers + bool shift_out(); + READ8_MEMBER(d0_r); + READ8_MEMBER(d7_r); + +protected: + // device-level overrides + virtual void device_start() override; + +private: + // helpers + template ioport_value port_read(); + + // input configuration + optional_ioport_array<4> m_analog_ports; + analog_port_read_delegate m_analog_input_cb[4]; + + // private data + u8 m_shift_register; +}; + +// device type definition +extern const device_type MSM6253; + +#endif // DEVICES_MACHINE_MSM6253_H diff --git a/src/mame/drivers/model2.cpp b/src/mame/drivers/model2.cpp index d8ff47dcc67..10d76a7d63c 100644 --- a/src/mame/drivers/model2.cpp +++ b/src/mame/drivers/model2.cpp @@ -124,6 +124,7 @@ #include "cpu/z80/z80.h" #include "machine/cxd1095.h" #include "machine/eepromser.h" +#include "machine/msm6253.h" #include "machine/nvram.h" #include "machine/315_5296.h" #include "sound/2612intf.h" @@ -2533,7 +2534,7 @@ static ADDRESS_MAP_START( drive_io_map, AS_IO, 8, model2_state ) AM_RANGE(0x00, 0x00) AM_WRITENOP //watchdog AM_RANGE(0x20, 0x2f) AM_DEVREADWRITE("driveio1", sega_315_5296_device, read, write) AM_RANGE(0x40, 0x4f) AM_DEVREADWRITE("driveio2", sega_315_5296_device, read, write) - AM_RANGE(0x80, 0x83) AM_NOP //Oki M6253 + AM_RANGE(0x80, 0x83) AM_DEVREADWRITE("driveadc", msm6253_device, d7_r, address_w) ADDRESS_MAP_END static MACHINE_CONFIG_DERIVED( srallyc, model2a ) @@ -2549,6 +2550,8 @@ static MACHINE_CONFIG_DERIVED( srallyc, model2a ) MCFG_315_5296_IN_PORTH_CB(READ8(model2_state, driveio_porth_r)) MCFG_DEVICE_ADD("driveio2", SEGA_315_5296, 16000000/4) //??? + + MCFG_DEVICE_ADD("driveadc", MSM6253, 0) MACHINE_CONFIG_END /* 2B-CRX */ diff --git a/src/mame/drivers/segaybd.cpp b/src/mame/drivers/segaybd.cpp index 10b954e1d33..ce246010953 100644 --- a/src/mame/drivers/segaybd.cpp +++ b/src/mame/drivers/segaybd.cpp @@ -61,6 +61,7 @@ MB89372 - Uses 3 serial data transfer protocols: ASYNC, COP & BOP. Has a built #include "includes/segaipt.h" #include "machine/mb8421.h" +#include "machine/msm6253.h" #include "machine/nvram.h" #include "machine/315_5296.h" #include "sound/segapcm.h" @@ -87,29 +88,12 @@ const uint32_t SOUND_CLOCK = 32215900; //************************************************************************** //------------------------------------------------- -// analog_r - handle analog input reads +// analog_mux - handle multiplexed analog input //------------------------------------------------- -READ16_MEMBER(segaybd_state::analog_r) +ioport_value segaybd_state::analog_mux() { - int result = 0xff; - if (ACCESSING_BITS_0_7) - { - result = m_analog_data[offset & 3] & 0x80; - m_analog_data[offset & 3] <<= 1; - } - return result; -} - - -//------------------------------------------------- -// analog_w - handle analog input control writes -//------------------------------------------------- - -WRITE16_MEMBER(segaybd_state::analog_w) -{ - int selected = ((offset & 3) == 3) ? (3 + (m_misc_io_data & 3)) : (offset & 3); - m_analog_data[offset & 3] = m_adc_ports[selected].read_safe(0xff); + return m_adc_ports[3 + (m_misc_io_data & 3)].read_safe(0x80); } @@ -642,7 +626,7 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, segaybd_state ) // AM_RANGE(0x086000, 0x087fff) /DEA0 AM_RANGE(0x0c0000, 0x0cffff) AM_RAM AM_SHARE("shareram") AM_RANGE(0x100000, 0x10001f) AM_DEVREADWRITE8("io", sega_315_5296_device, read, write, 0x00ff) - AM_RANGE(0x100040, 0x100047) AM_READWRITE(analog_r, analog_w) + AM_RANGE(0x100040, 0x100047) AM_DEVREADWRITE8("adc", msm6253_device, d7_r, address_w, 0x00ff) AM_RANGE(0x1f0000, 0x1fffff) AM_RAM ADDRESS_MAP_END @@ -1350,6 +1334,12 @@ static MACHINE_CONFIG_START( yboard, segaybd_state ) MCFG_315_5296_IN_PORTG_CB(IOPORT("COINAGE")) MCFG_315_5296_OUT_PORTH_CB(WRITE8(segaybd_state, output2_w)) + MCFG_DEVICE_ADD("adc", MSM6253, 0) + MCFG_MSM6253_IN0_ANALOG_PORT("ADC.0") + MCFG_MSM6253_IN1_ANALOG_PORT("ADC.1") + MCFG_MSM6253_IN2_ANALOG_PORT("ADC.2") + MCFG_MSM6253_IN3_ANALOG_READ(segaybd_state, analog_mux) + MCFG_SEGA_315_5248_MULTIPLIER_ADD("multiplier_main") MCFG_SEGA_315_5248_MULTIPLIER_ADD("multiplier_subx") MCFG_SEGA_315_5248_MULTIPLIER_ADD("multiplier_suby") @@ -2677,7 +2667,6 @@ DRIVER_INIT_MEMBER(segaybd_state,generic) // save state save_item(NAME(m_pdrift_bank)); - save_item(NAME(m_analog_data)); save_item(NAME(m_irq2_scanline)); save_item(NAME(m_timer_irq_state)); save_item(NAME(m_vblank_irq_state)); diff --git a/src/mame/includes/segaybd.h b/src/mame/includes/segaybd.h index 50584ca65d6..07a6fb13fa6 100644 --- a/src/mame/includes/segaybd.h +++ b/src/mame/includes/segaybd.h @@ -42,12 +42,9 @@ public: , m_misc_io_data(0) , m_tmp_bitmap(512, 512) { - memset(m_analog_data, 0, sizeof(m_analog_data)); } // main CPU read/write handlers - DECLARE_READ16_MEMBER(analog_r); - DECLARE_WRITE16_MEMBER(analog_w); DECLARE_WRITE8_MEMBER(output1_w); DECLARE_WRITE8_MEMBER(misc_output_w); DECLARE_WRITE8_MEMBER(output2_w); @@ -64,6 +61,9 @@ public: DECLARE_WRITE16_MEMBER(link2_w); // DECLARE_READ8_MEMBER(link_portc0_r); + // input helpers + ioport_value analog_mux(); + // game-specific output handlers void gforce2_output_cb1(uint16_t data); void gforce2_output_cb2(uint16_t data); @@ -126,7 +126,6 @@ protected: // internal state uint16_t m_pdrift_bank; emu_timer * m_scanline_timer; - uint8_t m_analog_data[4]; int m_irq2_scanline; uint8_t m_timer_irq_state; uint8_t m_vblank_irq_state; -- cgit v1.2.3