diff options
| -rw-r--r-- | src/emu/cpu/upd7810/upd7810.c | 118 | ||||
| -rw-r--r-- | src/emu/cpu/upd7810/upd7810.h | 48 |
2 files changed, 166 insertions, 0 deletions
diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 04e11049150..4e45f2cb436 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -421,6 +421,14 @@ upd7810_device::upd7810_device(const machine_config &mconfig, const char *tag, d , m_to_func(*this) , m_txd_func(*this) , m_rxd_func(*this) + , m_an0_func(*this) + , m_an1_func(*this) + , m_an2_func(*this) + , m_an3_func(*this) + , m_an4_func(*this) + , m_an5_func(*this) + , m_an6_func(*this) + , m_an7_func(*this) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0) , m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0) { @@ -439,6 +447,14 @@ upd7810_device::upd7810_device(const machine_config &mconfig, device_type type, , m_to_func(*this) , m_txd_func(*this) , m_rxd_func(*this) + , m_an0_func(*this) + , m_an1_func(*this) + , m_an2_func(*this) + , m_an3_func(*this) + , m_an4_func(*this) + , m_an5_func(*this) + , m_an6_func(*this) + , m_an7_func(*this) , m_program_config("program", ENDIANNESS_LITTLE, 8, 16, 0) , m_io_config("io", ENDIANNESS_LITTLE, 8, 8, 0) { @@ -620,6 +636,7 @@ offs_t upd78c05_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 #define EOM m_eom #define SML m_sml #define SMH m_smh +#define PANM m_panm #define ANM m_anm #define MKL m_mkl #define MKH m_mkh @@ -1634,6 +1651,93 @@ void upd7810_device::handle_timers(int cycles) } break; } + + /**** ADC ****/ + m_adcnt += cycles; + if (PANM != ANM) + { + /* reset A/D converter */ + m_adcnt = 0; + if (ANM & 0x10) + m_adtot = 144; + else + m_adtot = 192; + m_adout = 0; + if (ANM & 0x01) + { + /* select mode */ + m_adin = (ANM >> 1) & 0x07; + } + else + { + /* scan mode */ + m_adin = 0; + m_adrange = (ANM >> 1) & 0x04; + } + } + PANM = ANM; + if (ANM & 0x01) + { + /* select mode */ + while (m_adcnt > m_adtot) + { + UINT8 cr = 0; + m_adcnt -= m_adtot; + switch (m_adin) + { + case 0: cr = m_an0_func(); break; + case 1: cr = m_an1_func(); break; + case 2: cr = m_an2_func(); break; + case 3: cr = m_an3_func(); break; + case 4: cr = m_an4_func(); break; + case 5: cr = m_an5_func(); break; + case 6: cr = m_an6_func(); break; + case 7: cr = m_an7_func(); break; + } + switch (m_adout) + { + case 0: CR0 = cr; break; + case 1: CR1 = cr; break; + case 2: CR2 = cr; break; + case 3: CR3 = cr; break; + } + m_adout = (m_adout + 1) & 0x07; + if (m_adout == 0) + IRR |= INTFAD; + } + } + else + { + /* scan mode */ + while (m_adcnt > m_adtot) + { + UINT8 cr = 0; + m_adcnt -= m_adtot; + switch (m_adin | m_adrange) + { + case 0: cr = m_an0_func(); break; + case 1: cr = m_an1_func(); break; + case 2: cr = m_an2_func(); break; + case 3: cr = m_an3_func(); break; + case 4: cr = m_an4_func(); break; + case 5: cr = m_an5_func(); break; + case 6: cr = m_an6_func(); break; + case 7: cr = m_an7_func(); break; + } + switch (m_adout) + { + case 0: CR0 = cr; break; + case 1: CR1 = cr; break; + case 2: CR2 = cr; break; + case 3: CR3 = cr; break; + } + m_adin = (m_adin + 1) & 0x07; + m_adout = (m_adout + 1) & 0x07; + if (m_adout == 0) + IRR |= INTFAD; + } + } + } void upd7801_device::handle_timers(int cycles) @@ -1685,6 +1789,14 @@ void upd7810_device::base_device_start() m_to_func.resolve_safe(); m_txd_func.resolve_safe(); m_rxd_func.resolve_safe(0); + m_an0_func.resolve_safe(0); + m_an1_func.resolve_safe(0); + m_an2_func.resolve_safe(0); + m_an3_func.resolve_safe(0); + m_an4_func.resolve_safe(0); + m_an5_func.resolve_safe(0); + m_an6_func.resolve_safe(0); + m_an7_func.resolve_safe(0); save_item(NAME(m_ppc.w.l)); save_item(NAME(m_pc.w.l)); @@ -1946,7 +2058,13 @@ void upd7810_device::device_reset() m_ovcf = 0; m_ovcs = 0; m_edges = 0; + m_adcnt = 0; + m_adtot = 0; + m_adout = 0; + m_adin = 0; + m_adrange = 0; + PANM = 0xff; ETMM = 0xff; TMM = 0xff; MA = 0xff; diff --git a/src/emu/cpu/upd7810/upd7810.h b/src/emu/cpu/upd7810/upd7810.h index f73d3df8d7c..270152e966c 100644 --- a/src/emu/cpu/upd7810/upd7810.h +++ b/src/emu/cpu/upd7810/upd7810.h @@ -23,6 +23,7 @@ enum UPD7810_TMM, UPD7810_ETMM, UPD7810_EOM, UPD7810_SML, UPD7810_SMH, UPD7810_ANM, UPD7810_MKL, UPD7810_MKH, UPD7810_ZCM, UPD7810_TXB, UPD7810_RXB, UPD7810_CR0, UPD7810_CR1, UPD7810_CR2, UPD7810_CR3, + UPD7810_AN0, UPD7810_AN1, UPD7810_AN2, UPD7810_AN3, UPD7810_AN4, UPD7810_AN5, UPD7810_AN6, UPD7810_AN7, UPD7810_TXD, UPD7810_RXD, UPD7810_SCK, UPD7810_TI, UPD7810_TO, UPD7810_CI, UPD7810_CO0, UPD7810_CO1 }; @@ -55,6 +56,31 @@ enum #define MCFG_UPD7810_RXD(_devcb) \ upd7810_device::set_rxd_func(*device, DEVCB2_##_devcb); +#define MCFG_UPD7810_AN0(_devcb) \ + upd7810_device::set_an0_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN1(_devcb) \ + upd7810_device::set_an1_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN2(_devcb) \ + upd7810_device::set_an2_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN3(_devcb) \ + upd7810_device::set_an3_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN4(_devcb) \ + upd7810_device::set_an4_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN5(_devcb) \ + upd7810_device::set_an5_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN6(_devcb) \ + upd7810_device::set_an6_func(*device, DEVCB2_##_devcb); + +#define MCFG_UPD7810_AN7(_devcb) \ + upd7810_device::set_an7_func(*device, DEVCB2_##_devcb); + + class upd7810_device : public cpu_device { public: @@ -66,6 +92,14 @@ public: template<class _Object> static devcb2_base &set_to_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_to_func.set_callback(object); } template<class _Object> static devcb2_base &set_txd_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_txd_func.set_callback(object); } template<class _Object> static devcb2_base &set_rxd_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_rxd_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an0_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an0_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an1_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an1_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an2_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an2_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an3_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an3_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an4_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an4_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an5_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an5_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an6_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an6_func.set_callback(object); } + template<class _Object> static devcb2_base &set_an7_func(device_t &device, _Object object) { return downcast<upd7810_device &>(device).m_an7_func.set_callback(object); } protected: // device-level overrides @@ -96,6 +130,14 @@ protected: devcb2_write_line m_to_func; devcb2_write_line m_txd_func; devcb2_read_line m_rxd_func; + devcb2_read_line m_an0_func; + devcb2_read_line m_an1_func; + devcb2_read_line m_an2_func; + devcb2_read_line m_an3_func; + devcb2_read_line m_an4_func; + devcb2_read_line m_an5_func; + devcb2_read_line m_an6_func; + devcb2_read_line m_an7_func; typedef void (upd7810_device::*opcode_func)(); @@ -176,6 +218,7 @@ protected: UINT8 m_eom; /* 16-bit timer/event counter output control */ UINT8 m_sml; /* serial interface parameters low */ UINT8 m_smh; /* -"- high */ + UINT8 m_panm; /* previous analog to digital converter operating parameters */ UINT8 m_anm; /* analog to digital converter operating parameters */ UINT8 m_mkl; /* interrupt mask low */ UINT8 m_mkh; /* -"- high */ @@ -221,6 +264,11 @@ protected: INT32 m_ovcf; /* overflow counter for fixed clock div 3 mode */ INT32 m_ovcs; /* overflow counter for serial I/O */ UINT8 m_edges; /* rising/falling edge flag for serial I/O */ + UINT16 m_adcnt; /* A/D converter cycle count */ + UINT8 m_adtot; /* A/D converter total cycles per conversion */ + int m_adout; /* currently selected A/D converter output register */ + int m_adin; /* currently selected A/D converter input */ + int m_adrange;/* in scan mode, A/D converter range (AN0-AN3 or AN4-AN7) */ const struct opcode_s *m_opXX; /* opcode table */ const struct opcode_s *m_op48; |
