From cb4b0693cd0876e63513d480d7ae42b9eb3c343e Mon Sep 17 00:00:00 2001 From: Ville Linde Date: Sun, 3 Jan 2016 19:48:53 +0200 Subject: [PATCH] tlcs900: add analog inputs to TMP95C063 (nw) --- src/devices/cpu/tlcs900/tlcs900.cpp | 184 +++++++++++++++++++++++++++- src/devices/cpu/tlcs900/tlcs900.h | 26 ++++ src/mame/drivers/taitopjc.cpp | 12 +- 3 files changed, 216 insertions(+), 6 deletions(-) diff --git a/src/devices/cpu/tlcs900/tlcs900.cpp b/src/devices/cpu/tlcs900/tlcs900.cpp index e0c174a9082..03f7a014c56 100644 --- a/src/devices/cpu/tlcs900/tlcs900.cpp +++ b/src/devices/cpu/tlcs900/tlcs900.cpp @@ -110,7 +110,15 @@ tmp95c063_device::tmp95c063_device(const machine_config &mconfig, const char *ta m_portd_read(*this), m_portd_write(*this), m_porte_read(*this), - m_porte_write(*this) + m_porte_write(*this), + m_an0_read(*this), + m_an1_read(*this), + m_an2_read(*this), + m_an3_read(*this), + m_an4_read(*this), + m_an5_read(*this), + m_an6_read(*this), + m_an7_read(*this) { } @@ -1732,7 +1740,151 @@ void tmp95c063_device::tlcs900_check_irqs() void tmp95c063_device::tlcs900_handle_ad() { - // TODO + if ( m_ad_cycles_left > 0 ) + { + m_ad_cycles_left -= m_cycles; + if ( m_ad_cycles_left <= 0 ) + { + int ad_value; + + /* Store A/D converted value */ + if ((m_reg[TMP95C063_ADMOD1] & 0x10) == 0) // conversion channel fixed + { + switch( m_reg[TMP95C063_ADMOD2] & 0x07 ) + { + case 0x00: // AN0 + ad_value = m_an0_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + break; + case 0x01: // AN1 + ad_value = m_an1_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + break; + case 0x02: // AN2 + ad_value = m_an2_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG26L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG26H] = (ad_value >> 2) & 0xff; + break; + case 0x03: // AN3 + ad_value = m_an3_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG37L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG37H] = (ad_value >> 2) & 0xff; + break; + case 0x04: // AN4 + ad_value = m_an4_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + break; + case 0x05: // AN5 + ad_value = m_an5_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + break; + case 0x06: // AN6 + ad_value = m_an6_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG26L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG26H] = (ad_value >> 2) & 0xff; + break; + case 0x07: // AN7 + ad_value = m_an7_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG37L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG37H] = (ad_value >> 2) & 0xff; + break; + } + } + else // conversion channel sweep + { + switch( m_reg[TMP95C063_ADMOD2] & 0x07 ) + { + case 0x00: // AN0 + ad_value = m_an0_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + break; + case 0x01: // AN0 -> AN1 + ad_value = m_an0_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + ad_value = m_an1_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + break; + case 0x02: // AN0 -> AN1 -> AN2 + ad_value = m_an0_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + ad_value = m_an1_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + ad_value = m_an2_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG26L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG26H] = (ad_value >> 2) & 0xff; + break; + case 0x03: // AN0 -> AN1 -> AN2 -> AN3 + ad_value = m_an0_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + ad_value = m_an1_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + ad_value = m_an2_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG26L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG26H] = (ad_value >> 2) & 0xff; + ad_value = m_an3_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG37L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG37H] = (ad_value >> 2) & 0xff; + break; + case 0x04: // AN4 + ad_value = m_an4_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + break; + case 0x05: // AN4 -> AN5 + ad_value = m_an4_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + ad_value = m_an5_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + break; + case 0x06: // AN4 -> AN5 -> AN6 + ad_value = m_an4_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + ad_value = m_an5_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + ad_value = m_an6_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG26L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG26H] = (ad_value >> 2) & 0xff; + break; + case 0x07: // AN4 -> AN5 -> AN6 -> AN7 + ad_value = m_an4_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG04L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG04H] = (ad_value >> 2) & 0xff; + ad_value = m_an5_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG15L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG15H] = (ad_value >> 2) & 0xff; + ad_value = m_an6_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG26L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG26H] = (ad_value >> 2) & 0xff; + ad_value = m_an7_read(0) & 0x3ff; + m_reg[TMP95C063_ADREG37L] = (ad_value & 0x3) << 6; + m_reg[TMP95C063_ADREG37H] = (ad_value >> 2) & 0xff; + break; + } + } + + /* Clear BUSY flag, set END flag */ + m_reg[TMP95C063_ADMOD1] &= ~ 0x40; + m_reg[TMP95C063_ADMOD1] |= 0x80; + + m_reg[TMP95C063_INTE0AD] |= 0x80; + m_check_irqs = 1; + } + } } @@ -1762,6 +1914,14 @@ void tmp95c063_device::device_start() m_portd_write.resolve_safe(); m_porte_read.resolve_safe(0); m_porte_write.resolve_safe(); + m_an0_read.resolve_safe(0); + m_an1_read.resolve_safe(0); + m_an2_read.resolve_safe(0); + m_an3_read.resolve_safe(0); + m_an4_read.resolve_safe(0); + m_an5_read.resolve_safe(0); + m_an6_read.resolve_safe(0); + m_an7_read.resolve_safe(0); } void tmp95c063_device::device_reset() @@ -2050,6 +2210,26 @@ WRITE8_MEMBER( tmp95c063_device::internal_w ) case TMP95C063_IIMC: break; + case TMP95C063_ADMOD1: + // conversion start + if (data & 0x04) + { + data &= ~0x04; + data |= 0x40; + + switch ((m_reg[TMP95C063_ADMOD2] >> 4) & 3) + { + case 0: m_ad_cycles_left = 160; break; + case 1: m_ad_cycles_left = 320; break; + case 2: m_ad_cycles_left = 640; break; + case 3: m_ad_cycles_left = 1280; break; + } + } + break; + + case TMP95C063_ADMOD2: + break; + default: break; } diff --git a/src/devices/cpu/tlcs900/tlcs900.h b/src/devices/cpu/tlcs900/tlcs900.h index 515a25b58e5..c095c848cf1 100644 --- a/src/devices/cpu/tlcs900/tlcs900.h +++ b/src/devices/cpu/tlcs900/tlcs900.h @@ -743,6 +743,14 @@ private: #define MCFG_TMP95C063_PORTD_WRITE( _port_write ) tmp95c063_device::set_portd_write( *device, DEVCB_##_port_write ); #define MCFG_TMP95C063_PORTE_READ( _port_read ) tmp95c063_device::set_porte_read( *device, DEVCB_##_port_read ); #define MCFG_TMP95C063_PORTE_WRITE( _port_write ) tmp95c063_device::set_porte_write( *device, DEVCB_##_port_write ); +#define MCFG_TMP95C063_AN0_READ( _port_read ) tmp95c063_device::set_an0_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN1_READ( _port_read ) tmp95c063_device::set_an1_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN2_READ( _port_read ) tmp95c063_device::set_an2_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN3_READ( _port_read ) tmp95c063_device::set_an3_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN4_READ( _port_read ) tmp95c063_device::set_an4_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN5_READ( _port_read ) tmp95c063_device::set_an5_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN6_READ( _port_read ) tmp95c063_device::set_an6_read( *device, DEVCB_##_port_read ); +#define MCFG_TMP95C063_AN7_READ( _port_read ) tmp95c063_device::set_an7_read( *device, DEVCB_##_port_read ); class tmp95c063_device : public tlcs900h_device { @@ -776,6 +784,14 @@ public: template static devcb_base &set_portd_write(device_t &device, _Object object) { return downcast(device).m_portd_write.set_callback(object); } template static devcb_base &set_porte_read(device_t &device, _Object object) { return downcast(device).m_porte_read.set_callback(object); } template static devcb_base &set_porte_write(device_t &device, _Object object) { return downcast(device).m_porte_write.set_callback(object); } + template static devcb_base &set_an0_read(device_t &device, _Object object) { return downcast(device).m_an0_read.set_callback(object); } + template static devcb_base &set_an1_read(device_t &device, _Object object) { return downcast(device).m_an1_read.set_callback(object); } + template static devcb_base &set_an2_read(device_t &device, _Object object) { return downcast(device).m_an2_read.set_callback(object); } + template static devcb_base &set_an3_read(device_t &device, _Object object) { return downcast(device).m_an3_read.set_callback(object); } + template static devcb_base &set_an4_read(device_t &device, _Object object) { return downcast(device).m_an4_read.set_callback(object); } + template static devcb_base &set_an5_read(device_t &device, _Object object) { return downcast(device).m_an5_read.set_callback(object); } + template static devcb_base &set_an6_read(device_t &device, _Object object) { return downcast(device).m_an6_read.set_callback(object); } + template static devcb_base &set_an7_read(device_t &device, _Object object) { return downcast(device).m_an7_read.set_callback(object); } protected: virtual void device_config_complete() override; @@ -834,6 +850,16 @@ private: // Port E: 8 bit I/O. devcb_read8 m_porte_read; devcb_write8 m_porte_write; + + // analogue inputs, sampled at 10 bits + devcb_read16 m_an0_read; + devcb_read16 m_an1_read; + devcb_read16 m_an2_read; + devcb_read16 m_an3_read; + devcb_read16 m_an4_read; + devcb_read16 m_an5_read; + devcb_read16 m_an6_read; + devcb_read16 m_an7_read; }; #endif diff --git a/src/mame/drivers/taitopjc.cpp b/src/mame/drivers/taitopjc.cpp index c5942198046..c9e6807add9 100644 --- a/src/mame/drivers/taitopjc.cpp +++ b/src/mame/drivers/taitopjc.cpp @@ -722,16 +722,16 @@ static INPUT_PORTS_START( taitopjc ) PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_START("ANALOG1") // Player 1 X - PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_X ) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) + PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_X ) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(30) PORT_START("ANALOG2") // Player 1 Y - PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_Y ) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) + PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_Y ) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(30) PORT_START("ANALOG3") // Player 2 X - PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_X ) PORT_PLAYER(2) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) + PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_X ) PORT_PLAYER(2) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(30) PORT_START("ANALOG4") // Player 2 Y - PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_Y ) PORT_PLAYER(2) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(5) + PORT_BIT( 0x3ff, 0x200, IPT_AD_STICK_Y ) PORT_PLAYER(2) PORT_MINMAX(0x000,0x3ff) PORT_SENSITIVITY(35) PORT_KEYDELTA(30) INPUT_PORTS_END @@ -762,6 +762,10 @@ static MACHINE_CONFIG_START( taitopjc, taitopjc_state ) MCFG_TMP95C063_PORT5_READ(IOPORT("INPUTS1")) MCFG_TMP95C063_PORTD_READ(IOPORT("INPUTS2")) MCFG_TMP95C063_PORTE_READ(IOPORT("INPUTS3")) + MCFG_TMP95C063_AN0_READ(IOPORT("ANALOG1")) + MCFG_TMP95C063_AN1_READ(IOPORT("ANALOG2")) + MCFG_TMP95C063_AN2_READ(IOPORT("ANALOG3")) + MCFG_TMP95C063_AN3_READ(IOPORT("ANALOG4")) MCFG_CPU_PROGRAM_MAP(tlcs900h_mem) MCFG_CPU_VBLANK_INT_DRIVER("screen", taitopjc_state, taitopjc_vbi)