diff options
-rw-r--r-- | scripts/src/machine.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 1 | ||||
-rw-r--r-- | src/devices/machine/upd7004.cpp | 171 | ||||
-rw-r--r-- | src/devices/machine/upd7004.h | 80 |
5 files changed, 265 insertions, 0 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index bc1f7609667..5d4d6771f9f 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2929,6 +2929,18 @@ end --------------------------------------------------- -- +--@src/devices/machine/upd7004.h,MACHINES["UPD7004"] = true +--------------------------------------------------- + +if (MACHINES["UPD7004"]~=null) then + files { + MAME_DIR .. "src/devices/machine/upd7004.cpp", + MAME_DIR .. "src/devices/machine/upd7004.h", + } +end + +--------------------------------------------------- +-- --@src/devices/machine/upd71071.h,MACHINES["UPD71071"] = true --------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 8e0ca9930f7..977e1db04ff 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -609,6 +609,7 @@ MACHINES["UPD1990A"] = true MACHINES["UPD4992"] = true MACHINES["UPD4701"] = true MACHINES["UPD7002"] = true +MACHINES["UPD7004"] = true MACHINES["UPD71071"] = true MACHINES["UPD765"] = true MACHINES["FDC_PLL"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index d357762eabc..269d649a0ea 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -628,6 +628,7 @@ MACHINES["UPD1990A"] = true --MACHINES["UPD4992"] = true MACHINES["UPD4701"] = true MACHINES["UPD7002"] = true +--MACHINES["UPD7004"] = true MACHINES["UPD71071"] = true MACHINES["UPD765"] = true MACHINES["FDC_PLL"] = true diff --git a/src/devices/machine/upd7004.cpp b/src/devices/machine/upd7004.cpp new file mode 100644 index 00000000000..26ca3c45622 --- /dev/null +++ b/src/devices/machine/upd7004.cpp @@ -0,0 +1,171 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + µPD7004 + + 10-bit 8 Channel A/D Converter + + TODO: + - Serial modes + - 2s complement output + +***************************************************************************/ + +#include "emu.h" +#include "upd7004.h" + +#define VERBOSE 0 +#include "logmacro.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(UPD7004, upd7004_device, "upd7004", "UPD7004 A/D Converter") + +// permit our enum to be saved +ALLOW_SAVE_TYPE(upd7004_device::state); + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// upd7004_device - constructor +//------------------------------------------------- + +upd7004_device::upd7004_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, UPD7004, 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_div(1), m_code(false), m_address(0), m_sar(0x3ff) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void upd7004_device::device_start() +{ + // resolve callbacks + m_eoc_cb.resolve_safe(); + m_eoc_ff_cb.resolve_safe(); + + for (int i = 0; i < 8; i++) + m_in_cb[i].resolve_safe(0x3ff); + + // allocate timers + m_cycle_timer = timer_alloc(); + m_cycle_timer->adjust(attotime::never); + + // register for save states + save_item(NAME(m_state)); + save_item(NAME(m_div)); + save_item(NAME(m_code)); + save_item(NAME(m_address)); + save_item(NAME(m_sar)); +} + +//------------------------------------------------- +// device_timer - handler timer events +//------------------------------------------------- + +void upd7004_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + switch (m_state) + { + case STATE_IDLE: + m_cycle_timer->adjust(attotime::never); + break; + + case STATE_CONVERSION_START: + m_sar = m_in_cb[m_address](0); + + // the conversion takes 96 to 104 cycles + m_state = STATE_CONVERSION_DONE; + m_cycle_timer->adjust(attotime::from_ticks(100, clock() / m_div)); + + break; + + case STATE_CONVERSION_DONE: + { + // set eoc + m_eoc_cb(1); + m_eoc_ff_cb(1); + + m_state = STATE_IDLE; + m_cycle_timer->adjust(attotime::never); + + LOG("Conversion finished, result: %03x\n", m_sar); + + break; + } + } +} + + +//************************************************************************** +// INTERFACE +//************************************************************************** + +READ8_MEMBER(upd7004_device::read) +{ + uint8_t data = 0xff; + + // connected to a flip-flop, cleared on read + m_eoc_ff_cb(0); + + switch (offset) + { + case 0: + // low-byte data output + data = (m_sar & 0x03) << 6; + break; + + case 1: + // high-byte data output + data = (m_sar >> 2) & 0xff; + break; + } + + return data; +} + +WRITE8_MEMBER(upd7004_device::write) +{ + switch (offset) + { + case 0: + // address set + m_address = data & 0x07; + + // reset eoc + m_eoc_cb(0); + + // start conversion timer + m_state = STATE_CONVERSION_START; + m_cycle_timer->adjust(attotime::from_hz(clock() / m_div)); + + LOG("Select address %d\n", m_address); + + break; + + case 1: + // initialize + m_div = 1 << (data & 0x03); + m_code = data & 0x04; + + logerror("Initialize with clock division ratio %d, %s data\n", m_div, m_code ? "2s complement" : "binary"); + + if (m_code) + logerror("Warning: 2s complement data unimplemented\n"); + + break; + } +} diff --git a/src/devices/machine/upd7004.h b/src/devices/machine/upd7004.h new file mode 100644 index 00000000000..fed6e5764c7 --- /dev/null +++ b/src/devices/machine/upd7004.h @@ -0,0 +1,80 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + µPD7004 + + 10-bit 8 Channel A/D Converter + + ___ ___ + CH4 1 |* u | 28 CH3 + CH5 2 | | 27 CH2 + CH6 3 | | 26 CH1 + CH7 4 | | 25 CH0 + VREF 5 | | 24 AGND + DGND 6 | | 23 AVDD + DB7/SO 7 | | 22 CS + DB6/SI 8 | | 21 RD/SCKI + DB5/SHIFT 9 | | 20 A0 + DB4/SCKO 10 | | 19 WR/STB + DB3/SOEN 11 | | 18 MC + DB2/CODE 12 | | 17 CLOCK + DB1/DEV1 13 | | 16 EOC + DB0/DEV0 14 |_______| 15 DVDD + +***************************************************************************/ + +#ifndef MAME_DEVICES_MACHINE_UPD7004_H +#define MAME_DEVICES_MACHINE_UPD7004_H + +#pragma once + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class upd7004_device : public device_t +{ +public: + // construction/destruction + upd7004_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + auto eoc_callback() { return m_eoc_cb.bind(); } + auto eoc_ff_callback() { return m_eoc_ff_cb.bind(); } + template <int N> auto in_callback() { return m_in_cb[N].bind(); } + + DECLARE_READ8_MEMBER(read); + DECLARE_WRITE8_MEMBER(write); + + // 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: + // callbacks + devcb_write_line m_eoc_cb; + devcb_write_line m_eoc_ff_cb; + devcb_read16 m_in_cb[8]; + + enum state : int + { + STATE_IDLE, + STATE_CONVERSION_START, + STATE_CONVERSION_DONE + }; + state m_state; + + emu_timer *m_cycle_timer; + + // state + int m_div; + bool m_code; + int m_address; + uint16_t m_sar; +}; + +// device type definition +DECLARE_DEVICE_TYPE(UPD7004, upd7004_device) + +#endif // MAME_DEVICES_MACHINE_UPD7004_H |