adc0808: Rewrite and make it work

This commit is contained in:
Dirk Best 2018-04-02 11:51:02 +02:00
parent 7079fa8fa6
commit 0086d473b7
4 changed files with 254 additions and 270 deletions

View File

@ -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_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_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_DEVICE_ADD(ADC0809_TAG, ADC0809, 500000)
MCFG_ADC0808_IN_VREF_POS_CB(newbrain_eim_device, adc_vref_pos_r) MCFG_ADC0808_EOC_CB(WRITELINE(newbrain_eim_device, adc_eoc_w))
MCFG_ADC0808_IN_VREF_NEG_CB(newbrain_eim_device, adc_vref_neg_r) MCFG_ADC0808_IN0_CB(GND)
MCFG_ADC0808_IN_IN_0_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN1_CB(GND)
MCFG_ADC0808_IN_IN_1_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN2_CB(GND)
MCFG_ADC0808_IN_IN_2_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN3_CB(GND)
MCFG_ADC0808_IN_IN_3_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN4_CB(GND)
MCFG_ADC0808_IN_IN_4_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN5_CB(GND)
MCFG_ADC0808_IN_IN_5_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN6_CB(GND)
MCFG_ADC0808_IN_IN_6_CB(newbrain_eim_device, adc_input_r) MCFG_ADC0808_IN7_CB(GND)
MCFG_ADC0808_IN_IN_7_CB(newbrain_eim_device, adc_input_r)
MCFG_DEVICE_ADD(MC6850_TAG, ACIA6850, 0) MCFG_DEVICE_ADD(MC6850_TAG, ACIA6850, 0)
MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(newbrain_eim_device, acia_interrupt)) 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 - // 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) TIMER_DEVICE_CALLBACK_MEMBER(newbrain_eim_device::ctc_c2_tick)

View File

@ -58,10 +58,6 @@ private:
DECLARE_WRITE_LINE_MEMBER( ctc_z2_w ); DECLARE_WRITE_LINE_MEMBER( ctc_z2_w );
DECLARE_WRITE_LINE_MEMBER( adc_eoc_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); TIMER_DEVICE_CALLBACK_MEMBER(ctc_c2_tick);
required_device<z80ctc_device> m_ctc; required_device<z80ctc_device> m_ctc;

View File

@ -1,42 +1,74 @@
// license:BSD-3-Clause // license: BSD-3-Clause
// copyright-holders:Curt Coder // 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 A/D Converter with 8 Channel-Multiplexer
chip allows twice as much adjusted error. Mitsubishi parts M58990P
and M58990P-1 are equivalent to ADC0808 and ADC0809.
**********************************************************************/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "adc0808.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 // LIVE DEVICE
//************************************************************************** //**************************************************************************
// device type definition // permit our enum to be saved
DEFINE_DEVICE_TYPE(ADC0808, adc0808_device, "adc0808", "ADC0808") ALLOW_SAVE_TYPE(adc0808_device::state);
//------------------------------------------------- //-------------------------------------------------
// adc0808_device - constructor // adc0808_device - constructor
//------------------------------------------------- //-------------------------------------------------
adc0808_device::adc0808_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) adc0808_device::adc0808_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
: device_t(mconfig, ADC0808, tag, owner, clock), device_t(mconfig, type, tag, owner, clock),
m_out_eoc_cb(*this), m_eoc_cb(*this), m_eoc_ff_cb(*this),
m_address(0), m_in_cb{ {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this}, {*this} },
m_start(0), m_state(STATE_IDLE),
m_eoc(0), m_cycle_timer(nullptr),
m_next_eoc(0), m_sar(0), m_start(0), m_cycle(0), m_step(0), m_address(0), m_sar(0xff), m_eoc_pending(false)
m_cycle(0), {
m_bit(0), }
m_cycle_timer(nullptr)
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() void adc0808_device::device_start()
{ {
// resolve callbacks // resolve callbacks
m_out_eoc_cb.resolve_safe(); m_eoc_cb.resolve_safe();
m_in_vref_pos_cb.bind_relative_to(*owner()); m_eoc_ff_cb.resolve_safe();
m_in_vref_neg_cb.bind_relative_to(*owner());
m_in_in_0_cb.bind_relative_to(*owner()); for (int i = 0; i < 8; i++)
m_in_in_1_cb.bind_relative_to(*owner()); m_in_cb[i].resolve_safe(0xff);
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());
// allocate timers // allocate timers
m_cycle_timer = timer_alloc(); m_cycle_timer = timer_alloc();
m_cycle_timer->adjust(attotime::zero, 0, attotime::from_hz(clock())); m_cycle_timer->adjust(attotime::zero, 0, attotime::from_hz(clock()));
// register for state saving // register for save states
save_item(NAME(m_address)); save_item(NAME(m_state));
save_item(NAME(m_start)); 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_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 // device_timer - handler timer events
//------------------------------------------------- //-------------------------------------------------
void adc0808_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) 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) if (VERBOSE)
{ logerror("Conversion finished, result %02x\n", m_sar);
/* 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 (m_cycle == 0) // next cycle
{ m_cycle = (m_cycle + 1) & 7;
/* 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;
}
} }
//------------------------------------------------- //**************************************************************************
// data_r - data read // INTERFACE
//------------------------------------------------- //**************************************************************************
READ8_MEMBER( adc0808_device::data_r ) 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; return m_sar;
} }
WRITE8_MEMBER( adc0808_device::address_w )
//-------------------------------------------------
// ale_w - address write
//-------------------------------------------------
WRITE8_MEMBER( adc0808_device::ale_w )
{ {
m_address = data; m_address = data & 7;
} }
//-------------------------------------------------
// start_w - start conversion
//-------------------------------------------------
WRITE_LINE_MEMBER( adc0808_device::start_w ) WRITE_LINE_MEMBER( adc0808_device::start_w )
{ {
if (!m_start && state) // rising edge if (m_start == 1 && state == 0)
{ {
// reset registers m_state = STATE_CONVERSION_START;
m_sar = 0;
m_bit = 0;
} }
else if (m_start && !state) // falling edge else if (m_start == 0 && state == 1)
{ {
// start conversion m_sar = 0;
m_eoc_cb(0);
m_next_eoc = 0; m_eoc_pending = false;
} }
m_start = state; 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);
}

View File

@ -1,138 +1,154 @@
// license:BSD-3-Clause // license: BSD-3-Clause
// copyright-holders:Curt Coder // copyright-holders: Dirk Best
/********************************************************************** /***************************************************************************
National Semiconductor ADC0808/ADC0809 8-Bit A/D Converter emulation ADC0808/ADC0809
********************************************************************** A/D Converter with 8 Channel-Multiplexer
_____ _____
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
**********************************************************************/ ___ ___
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 Notes:
#define MAME_MACHINE_ADC0808_H * 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 #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 // TYPE DEFINITIONS
//************************************************************************** //**************************************************************************
// ======================> adc0808_analog_read class adc0808_device : public device_t
#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
{ {
public: public:
typedef device_delegate<double ()> analog_read_delegate;
// construction/destruction // construction/destruction
adc0808_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); 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)); } // configuration
template <typename Object> void set_in_vref_pos_callback(Object &&cb) { m_in_vref_pos_cb = std::forward<Object>(cb); } template <class Object> static devcb_base &set_eoc_callback(device_t &device, Object &&cb)
template <typename Object> void set_in_vref_neg_callback(Object &&cb) { m_in_vref_neg_cb = std::forward<Object>(cb); } { return downcast<adc0808_device &>(device).m_eoc_cb.set_callback(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); }
DECLARE_READ8_MEMBER( data_r ); template <class Object> static devcb_base &set_eoc_ff_callback(device_t &device, Object &&cb)
DECLARE_WRITE8_MEMBER( ale_w ); { 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: protected:
adc0808_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
// device-level overrides // device-level overrides
virtual void device_start() override; virtual void device_start() override;
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
private: private:
devcb_write_line m_out_eoc_cb; // callbacks
analog_read_delegate m_in_vref_pos_cb; devcb_write_line m_eoc_cb;
analog_read_delegate m_in_vref_neg_cb; devcb_write_line m_eoc_ff_cb;
analog_read_delegate m_in_in_0_cb; devcb_read8 m_in_cb[8];
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;
int m_address; // analog channel address enum state : int
int m_start; // start conversion pin {
int m_eoc; // end of conversion pin STATE_IDLE,
int m_next_eoc; // next value end of conversion pin 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; 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 // device type definition
DECLARE_DEVICE_TYPE(ADC0808, adc0808_device) 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