mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
adc0808: Rewrite and make it work
This commit is contained in:
parent
7079fa8fa6
commit
0086d473b7
@ -75,18 +75,17 @@ MACHINE_CONFIG_START(newbrain_eim_device::device_add_mconfig)
|
||||
MCFG_Z80CTC_ZC2_CB(WRITELINE(newbrain_eim_device, ctc_z2_w))
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC("z80ctc_c2", newbrain_eim_device, ctc_c2_tick, attotime::from_hz(XTAL(16'000'000)/4/13))
|
||||
MCFG_DEVICE_ADD(ADC0809_TAG, ADC0808, 500000)
|
||||
MCFG_ADC0808_OUT_EOC_CB(WRITELINE(newbrain_eim_device, adc_eoc_w))
|
||||
MCFG_ADC0808_IN_VREF_POS_CB(newbrain_eim_device, adc_vref_pos_r)
|
||||
MCFG_ADC0808_IN_VREF_NEG_CB(newbrain_eim_device, adc_vref_neg_r)
|
||||
MCFG_ADC0808_IN_IN_0_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_1_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_2_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_3_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_4_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_5_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_6_CB(newbrain_eim_device, adc_input_r)
|
||||
MCFG_ADC0808_IN_IN_7_CB(newbrain_eim_device, adc_input_r)
|
||||
|
||||
MCFG_DEVICE_ADD(ADC0809_TAG, ADC0809, 500000)
|
||||
MCFG_ADC0808_EOC_CB(WRITELINE(newbrain_eim_device, adc_eoc_w))
|
||||
MCFG_ADC0808_IN0_CB(GND)
|
||||
MCFG_ADC0808_IN1_CB(GND)
|
||||
MCFG_ADC0808_IN2_CB(GND)
|
||||
MCFG_ADC0808_IN3_CB(GND)
|
||||
MCFG_ADC0808_IN4_CB(GND)
|
||||
MCFG_ADC0808_IN5_CB(GND)
|
||||
MCFG_ADC0808_IN6_CB(GND)
|
||||
MCFG_ADC0808_IN7_CB(GND)
|
||||
|
||||
MCFG_DEVICE_ADD(MC6850_TAG, ACIA6850, 0)
|
||||
MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(newbrain_eim_device, acia_interrupt))
|
||||
@ -229,36 +228,6 @@ WRITE_LINE_MEMBER( newbrain_eim_device::adc_eoc_w )
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// adc_vref_pos_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
ADC0808_ANALOG_READ_CB( newbrain_eim_device::adc_vref_pos_r )
|
||||
{
|
||||
return 5.0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// adc_vref_neg_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
ADC0808_ANALOG_READ_CB( newbrain_eim_device::adc_vref_neg_r )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// adc_input_r -
|
||||
//-------------------------------------------------
|
||||
|
||||
ADC0808_ANALOG_READ_CB( newbrain_eim_device::adc_input_r )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// acia_interrupt -
|
||||
//-------------------------------------------------
|
||||
@ -282,7 +251,7 @@ WRITE_LINE_MEMBER( newbrain_eim_device::ctc_z2_w )
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// adc_input_r -
|
||||
// ctc_c2_tick -
|
||||
//-------------------------------------------------
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(newbrain_eim_device::ctc_c2_tick)
|
||||
|
@ -58,10 +58,6 @@ private:
|
||||
DECLARE_WRITE_LINE_MEMBER( ctc_z2_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( adc_eoc_w );
|
||||
|
||||
ADC0808_ANALOG_READ_CB(adc_vref_pos_r);
|
||||
ADC0808_ANALOG_READ_CB(adc_vref_neg_r);
|
||||
ADC0808_ANALOG_READ_CB(adc_input_r);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(ctc_c2_tick);
|
||||
|
||||
required_device<z80ctc_device> m_ctc;
|
||||
|
@ -1,42 +1,74 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
/**********************************************************************
|
||||
// license: BSD-3-Clause
|
||||
// copyright-holders: Dirk Best
|
||||
/***************************************************************************
|
||||
|
||||
National Semiconductor ADC0808/ADC0809 8-Bit A/D Converter emulation
|
||||
ADC0808/ADC0809
|
||||
|
||||
The only difference between ADC0808 and ADC0809 is that the latter
|
||||
chip allows twice as much adjusted error. Mitsubishi parts M58990P
|
||||
and M58990P-1 are equivalent to ADC0808 and ADC0809.
|
||||
A/D Converter with 8 Channel-Multiplexer
|
||||
|
||||
**********************************************************************/
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "adc0808.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CONSTANTS/MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
DEFINE_DEVICE_TYPE(ADC0808, adc0808_device, "adc0808", "ADC0808 A/D Converter")
|
||||
DEFINE_DEVICE_TYPE(ADC0809, adc0809_device, "adc0809", "ADC0809 A/D Converter")
|
||||
DEFINE_DEVICE_TYPE(M58990P, m58990p_device, "m58990p", "M58990P A/D Converter")
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(ADC0808, adc0808_device, "adc0808", "ADC0808")
|
||||
// permit our enum to be saved
|
||||
ALLOW_SAVE_TYPE(adc0808_device::state);
|
||||
|
||||
//-------------------------------------------------
|
||||
// adc0808_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
adc0808_device::adc0808_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, ADC0808, tag, owner, clock),
|
||||
m_out_eoc_cb(*this),
|
||||
m_address(0),
|
||||
m_start(0),
|
||||
m_eoc(0),
|
||||
m_next_eoc(0), m_sar(0),
|
||||
m_cycle(0),
|
||||
m_bit(0),
|
||||
m_cycle_timer(nullptr)
|
||||
adc0808_device::adc0808_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, type, tag, owner, clock),
|
||||
m_eoc_cb(*this), m_eoc_ff_cb(*this),
|
||||
m_in_cb{ {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this} },
|
||||
m_state(STATE_IDLE),
|
||||
m_cycle_timer(nullptr),
|
||||
m_start(0), m_cycle(0), m_step(0), m_address(0), m_sar(0xff), m_eoc_pending(false)
|
||||
{
|
||||
}
|
||||
|
||||
adc0808_device::adc0808_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
adc0808_device(mconfig, ADC0808, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// adc0809_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
adc0809_device::adc0809_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
adc0808_device(mconfig, ADC0809, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// m58990p_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
m58990p_device::m58990p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
adc0808_device(mconfig, M58990P, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
@ -47,146 +79,117 @@ adc0808_device::adc0808_device(const machine_config &mconfig, const char *tag, d
|
||||
void adc0808_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
m_out_eoc_cb.resolve_safe();
|
||||
m_in_vref_pos_cb.bind_relative_to(*owner());
|
||||
m_in_vref_neg_cb.bind_relative_to(*owner());
|
||||
m_in_in_0_cb.bind_relative_to(*owner());
|
||||
m_in_in_1_cb.bind_relative_to(*owner());
|
||||
m_in_in_2_cb.bind_relative_to(*owner());
|
||||
m_in_in_3_cb.bind_relative_to(*owner());
|
||||
m_in_in_4_cb.bind_relative_to(*owner());
|
||||
m_in_in_5_cb.bind_relative_to(*owner());
|
||||
m_in_in_6_cb.bind_relative_to(*owner());
|
||||
m_in_in_7_cb.bind_relative_to(*owner());
|
||||
m_eoc_cb.resolve_safe();
|
||||
m_eoc_ff_cb.resolve_safe();
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
m_in_cb[i].resolve_safe(0xff);
|
||||
|
||||
// allocate timers
|
||||
m_cycle_timer = timer_alloc();
|
||||
m_cycle_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()));
|
||||
|
||||
// register for state saving
|
||||
save_item(NAME(m_address));
|
||||
// register for save states
|
||||
save_item(NAME(m_state));
|
||||
save_item(NAME(m_start));
|
||||
save_item(NAME(m_eoc));
|
||||
save_item(NAME(m_next_eoc));
|
||||
save_item(NAME(m_sar));
|
||||
save_item(NAME(m_cycle));
|
||||
save_item(NAME(m_bit));
|
||||
save_item(NAME(m_step));
|
||||
save_item(NAME(m_address));
|
||||
save_item(NAME(m_sar));
|
||||
save_item(NAME(m_eoc_pending));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void adc0808_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (!m_start)
|
||||
// eoc is delayed one cycle
|
||||
if (m_eoc_pending)
|
||||
{
|
||||
if (m_cycle == 7)
|
||||
m_eoc_cb(1);
|
||||
m_eoc_ff_cb(1);
|
||||
m_eoc_pending = false;
|
||||
}
|
||||
|
||||
// start of conversion cycle
|
||||
if (m_cycle == 0 && m_state == STATE_CONVERSION_START)
|
||||
m_state = STATE_CONVERSION_RUNNING;
|
||||
|
||||
// end of conversion cycle
|
||||
if (m_cycle == 7 && m_state == STATE_CONVERSION_RUNNING)
|
||||
{
|
||||
// the conversion takes 8 steps every 8 cycles
|
||||
if (m_step++ == 7)
|
||||
{
|
||||
m_bit++;
|
||||
m_step = 0;
|
||||
m_sar = m_in_cb[m_address](0);
|
||||
m_eoc_pending = true;
|
||||
m_state = STATE_IDLE;
|
||||
|
||||
if (m_bit == 8)
|
||||
{
|
||||
/* sample input */
|
||||
double vref_pos = m_in_vref_pos_cb();
|
||||
double vref_neg = m_in_vref_neg_cb();
|
||||
|
||||
double input = 0;
|
||||
|
||||
switch (m_address)
|
||||
{
|
||||
case 0:
|
||||
input = m_in_in_0_cb();
|
||||
break;
|
||||
case 1:
|
||||
input = m_in_in_1_cb();
|
||||
break;
|
||||
case 2:
|
||||
input = m_in_in_2_cb();
|
||||
break;
|
||||
case 3:
|
||||
input = m_in_in_3_cb();
|
||||
break;
|
||||
case 4:
|
||||
input = m_in_in_4_cb();
|
||||
break;
|
||||
case 5:
|
||||
input = m_in_in_5_cb();
|
||||
break;
|
||||
case 6:
|
||||
input = m_in_in_6_cb();
|
||||
break;
|
||||
case 7:
|
||||
input = m_in_in_7_cb();
|
||||
break;
|
||||
}
|
||||
m_sar = (255 * (input - vref_neg)) / (vref_pos - vref_neg);
|
||||
|
||||
/* trigger end of conversion */
|
||||
m_next_eoc = 1;
|
||||
}
|
||||
if (VERBOSE)
|
||||
logerror("Conversion finished, result %02x\n", m_sar);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_cycle == 0)
|
||||
{
|
||||
/* set end of conversion pin */
|
||||
if (m_next_eoc != m_eoc)
|
||||
{
|
||||
m_out_eoc_cb(m_next_eoc);
|
||||
m_eoc = m_next_eoc;
|
||||
}
|
||||
}
|
||||
|
||||
m_cycle++;
|
||||
|
||||
if (m_cycle == 8)
|
||||
{
|
||||
m_cycle = 0;
|
||||
}
|
||||
// next cycle
|
||||
m_cycle = (m_cycle + 1) & 7;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// data_r - data read
|
||||
//-------------------------------------------------
|
||||
//**************************************************************************
|
||||
// INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
READ8_MEMBER( adc0808_device::data_r )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("data_r: %02x\n", m_sar);
|
||||
|
||||
// oe connected to flip-flop clear
|
||||
m_eoc_ff_cb(0);
|
||||
|
||||
return m_sar;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ale_w - address write
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE8_MEMBER( adc0808_device::ale_w )
|
||||
WRITE8_MEMBER( adc0808_device::address_w )
|
||||
{
|
||||
m_address = data;
|
||||
m_address = data & 7;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// start_w - start conversion
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE_LINE_MEMBER( adc0808_device::start_w )
|
||||
{
|
||||
if (!m_start && state) // rising edge
|
||||
if (m_start == 1 && state == 0)
|
||||
{
|
||||
// reset registers
|
||||
|
||||
m_sar = 0;
|
||||
m_bit = 0;
|
||||
m_state = STATE_CONVERSION_START;
|
||||
}
|
||||
else if (m_start && !state) // falling edge
|
||||
else if (m_start == 0 && state == 1)
|
||||
{
|
||||
// start conversion
|
||||
|
||||
m_next_eoc = 0;
|
||||
m_sar = 0;
|
||||
m_eoc_cb(0);
|
||||
m_eoc_pending = false;
|
||||
}
|
||||
|
||||
m_start = state;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( adc0808_device::address_offset_start_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("address_offset_start_w %02x %02x\n", offset, data);
|
||||
|
||||
start_w(1);
|
||||
address_w(space, 0, offset);
|
||||
start_w(0);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( adc0808_device::address_data_start_w )
|
||||
{
|
||||
if (VERBOSE)
|
||||
logerror("address_data_start_w %02x %02x\n", offset, data);
|
||||
|
||||
start_w(1);
|
||||
address_w(space, 0, data);
|
||||
start_w(0);
|
||||
}
|
||||
|
@ -1,138 +1,154 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Curt Coder
|
||||
/**********************************************************************
|
||||
// license: BSD-3-Clause
|
||||
// copyright-holders: Dirk Best
|
||||
/***************************************************************************
|
||||
|
||||
National Semiconductor ADC0808/ADC0809 8-Bit A/D Converter emulation
|
||||
ADC0808/ADC0809
|
||||
|
||||
**********************************************************************
|
||||
_____ _____
|
||||
IN3 1 |* \_/ | 28 IN2
|
||||
IN4 2 | | 27 IN1
|
||||
IN5 3 | | 26 IN0
|
||||
IN6 4 | | 25 ADD A
|
||||
IN7 5 | | 24 ADD B
|
||||
START 6 | | 23 ADD C
|
||||
EOC 7 | ADC0808 | 22 ALE
|
||||
2-5 8 | ADC0809 | 21 2-1 MSB
|
||||
OUTPUT ENABLE 9 | | 20 2-2
|
||||
CLOCK 10 | | 19 2-3
|
||||
Vcc 11 | | 18 2-4
|
||||
Vref+ 12 | | 17 2-8 LSB
|
||||
GND 13 | | 16 Vref-
|
||||
2-7 14 |_____________| 15 2-6
|
||||
A/D Converter with 8 Channel-Multiplexer
|
||||
|
||||
**********************************************************************/
|
||||
___ ___
|
||||
IN3 1 |* u | 28 IN2
|
||||
IN4 2 | | 27 IN1
|
||||
IN5 3 | | 26 IN0
|
||||
IN6 4 | | 25 ADD A
|
||||
IN7 5 | | 24 ADD B
|
||||
START 6 | | 23 ADD C
|
||||
EOC 7 | | 22 ALE
|
||||
D4 8 | | 21 D0
|
||||
OE 9 | | 20 D1
|
||||
CLOCK 10 | | 19 D2
|
||||
VCC 11 | | 18 D3
|
||||
VREF+ 12 | | 17 D7
|
||||
DND 13 | | 16 VREF-
|
||||
D6 14 |_______| 15 D5
|
||||
|
||||
#ifndef MAME_MACHINE_ADC0808_H
|
||||
#define MAME_MACHINE_ADC0808_H
|
||||
Notes:
|
||||
* The difference between the two devices is the total adjusted
|
||||
error: ADC0808 ±½ LSB, ADC0809 ±1 LSB
|
||||
* MM74C949 and M58990P are equivalent to ADC0808
|
||||
* MM74C949-1 and M58990P-1 are equivalent to ADC0809
|
||||
* ADC0816 and ADC0817 are 16 channel equivalents
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_DEVICES_MACHINE_ADC0808_H
|
||||
#define MAME_DEVICES_MACHINE_ADC0808_H
|
||||
|
||||
#pragma once
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_ADC0808_EOC_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_eoc_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
// common hookup where the eoc output is connected to a flip-flop
|
||||
#define MCFG_ADC0808_EOC_FF_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_eoc_ff_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_ADC0808_IN0_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 0);
|
||||
|
||||
#define MCFG_ADC0808_IN1_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 1);
|
||||
|
||||
#define MCFG_ADC0808_IN2_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 2);
|
||||
|
||||
#define MCFG_ADC0808_IN3_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 3);
|
||||
|
||||
#define MCFG_ADC0808_IN4_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 4);
|
||||
|
||||
#define MCFG_ADC0808_IN5_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 5);
|
||||
|
||||
#define MCFG_ADC0808_IN6_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 6);
|
||||
|
||||
#define MCFG_ADC0808_IN7_CB(_devcb) \
|
||||
devcb = &adc0808_device::set_in_callback(*device, DEVCB_##_devcb, 7);
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> adc0808_analog_read
|
||||
|
||||
#define ADC0808_ANALOG_READ_CB(name) double name()
|
||||
|
||||
|
||||
#define MCFG_ADC0808_OUT_EOC_CB(_devcb) \
|
||||
devcb = &downcast<adc0808_device &>(*device).set_out_eoc_callback(DEVCB_##_devcb);
|
||||
|
||||
#define MCFG_ADC0808_IN_VREF_POS_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_vref_pos_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_VREF_NEG_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_vref_neg_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_0_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_0_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_1_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_1_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_2_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_2_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_3_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_3_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_4_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_4_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_5_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_5_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_6_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_6_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
#define MCFG_ADC0808_IN_IN_7_CB(_class, _method) \
|
||||
downcast<adc0808_device &>(*device).set_in_in_7_callback(adc0808_device::analog_read_delegate(&_class::_method, #_class "::" #_method, this));
|
||||
|
||||
// ======================> adc0808_device
|
||||
|
||||
class adc0808_device : public device_t
|
||||
class adc0808_device : public device_t
|
||||
{
|
||||
public:
|
||||
typedef device_delegate<double ()> analog_read_delegate;
|
||||
|
||||
// construction/destruction
|
||||
adc0808_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
template <class Object> devcb_base &set_out_eoc_callback(Object &&cb) { return m_out_eoc_cb.set_callback(std::forward<Object>(cb)); }
|
||||
template <typename Object> void set_in_vref_pos_callback(Object &&cb) { m_in_vref_pos_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_vref_neg_callback(Object &&cb) { m_in_vref_neg_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_0_callback(Object &&cb) { m_in_in_0_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_1_callback(Object &&cb) { m_in_in_1_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_2_callback(Object &&cb) { m_in_in_2_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_3_callback(Object &&cb) { m_in_in_3_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_4_callback(Object &&cb) { m_in_in_4_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_5_callback(Object &&cb) { m_in_in_5_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_6_callback(Object &&cb) { m_in_in_6_cb = std::forward<Object>(cb); }
|
||||
template <typename Object> void set_in_in_7_callback(Object &&cb) { m_in_in_7_cb = std::forward<Object>(cb); }
|
||||
// configuration
|
||||
template <class Object> static devcb_base &set_eoc_callback(device_t &device, Object &&cb)
|
||||
{ return downcast<adc0808_device &>(device).m_eoc_cb.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
DECLARE_READ8_MEMBER( data_r );
|
||||
DECLARE_WRITE8_MEMBER( ale_w );
|
||||
template <class Object> static devcb_base &set_eoc_ff_callback(device_t &device, Object &&cb)
|
||||
{ return downcast<adc0808_device &>(device).m_eoc_ff_cb.set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( start_w );
|
||||
template <class Object> static devcb_base &set_in_callback(device_t &device, Object &&cb, int index)
|
||||
{ return downcast<adc0808_device &>(device).m_in_cb[index].set_callback(std::forward<Object>(cb)); }
|
||||
|
||||
DECLARE_READ8_MEMBER(data_r);
|
||||
DECLARE_WRITE8_MEMBER(address_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(start_w);
|
||||
|
||||
// common hookups
|
||||
DECLARE_WRITE8_MEMBER(address_offset_start_w); // start and ale connected, address to the address bus
|
||||
DECLARE_WRITE8_MEMBER(address_data_start_w); // start and ale connected, address to the data bus
|
||||
|
||||
protected:
|
||||
adc0808_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
|
||||
private:
|
||||
devcb_write_line m_out_eoc_cb;
|
||||
analog_read_delegate m_in_vref_pos_cb;
|
||||
analog_read_delegate m_in_vref_neg_cb;
|
||||
analog_read_delegate m_in_in_0_cb;
|
||||
analog_read_delegate m_in_in_1_cb;
|
||||
analog_read_delegate m_in_in_2_cb;
|
||||
analog_read_delegate m_in_in_3_cb;
|
||||
analog_read_delegate m_in_in_4_cb;
|
||||
analog_read_delegate m_in_in_5_cb;
|
||||
analog_read_delegate m_in_in_6_cb;
|
||||
analog_read_delegate m_in_in_7_cb;
|
||||
// callbacks
|
||||
devcb_write_line m_eoc_cb;
|
||||
devcb_write_line m_eoc_ff_cb;
|
||||
devcb_read8 m_in_cb[8];
|
||||
|
||||
int m_address; // analog channel address
|
||||
int m_start; // start conversion pin
|
||||
int m_eoc; // end of conversion pin
|
||||
int m_next_eoc; // next value end of conversion pin
|
||||
enum state : int
|
||||
{
|
||||
STATE_IDLE,
|
||||
STATE_CONVERSION_START,
|
||||
STATE_CONVERSION_RUNNING
|
||||
};
|
||||
state m_state;
|
||||
|
||||
uint8_t m_sar; // successive approximation register
|
||||
|
||||
int m_cycle; // clock cycle counter
|
||||
int m_bit; // bit counter
|
||||
|
||||
// timers
|
||||
emu_timer *m_cycle_timer;
|
||||
|
||||
// state
|
||||
int m_start;
|
||||
int m_cycle;
|
||||
int m_step;
|
||||
int m_address;
|
||||
uint8_t m_sar;
|
||||
bool m_eoc_pending;
|
||||
};
|
||||
|
||||
class adc0809_device : public adc0808_device
|
||||
{
|
||||
public:
|
||||
adc0809_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
class m58990p_device : public adc0808_device
|
||||
{
|
||||
public:
|
||||
m58990p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(ADC0808, adc0808_device)
|
||||
DECLARE_DEVICE_TYPE(ADC0809, adc0809_device)
|
||||
DECLARE_DEVICE_TYPE(M58990P, m58990p_device)
|
||||
|
||||
#endif // MAME_MACHINE_ADC0808_H
|
||||
#endif // MAME_DEVICES_MACHINE_ADC0808_H
|
||||
|
Loading…
Reference in New Issue
Block a user