segaybd.cpp, srallyc: Add OKI MSM6253 device

This commit is contained in:
AJR 2017-04-12 23:09:01 -04:00
parent c6a1b3856c
commit 0188b4e80b
8 changed files with 266 additions and 27 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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<msm6253_device>;
//**************************************************************************
// 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<int port>
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;
}

View File

@ -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<ioport_value ()> 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<msm6253_device &>(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<msm6253_device &>(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<int port> 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

View File

@ -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 */

View File

@ -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));

View File

@ -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;