mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +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_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)
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user