diff options
-rw-r--r-- | scripts/src/machine.lua | 24 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 2 | ||||
-rw-r--r-- | scripts/target/mame/mess.lua | 2 | ||||
-rw-r--r-- | src/devices/machine/74161.cpp | 33 | ||||
-rw-r--r-- | src/devices/machine/74161.h | 33 | ||||
-rw-r--r-- | src/devices/machine/74175.cpp | 265 | ||||
-rw-r--r-- | src/devices/machine/74175.h | 214 | ||||
-rw-r--r-- | src/devices/machine/clock.h | 3 | ||||
-rw-r--r-- | src/devices/machine/dm9334.cpp | 150 | ||||
-rw-r--r-- | src/devices/machine/dm9334.h | 177 | ||||
-rw-r--r-- | src/mame/drivers/hazeltin.cpp | 103 |
11 files changed, 996 insertions, 10 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 4ff994b3d04..81b5ab23907 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -345,6 +345,18 @@ end --------------------------------------------------- -- +--@src/devices/machine/74175.h,MACHINES["TTL74175"] = true +--------------------------------------------------- + +if (MACHINES["TTL74175"]~=null) then + files { + MAME_DIR .. "src/devices/machine/74175.cpp", + MAME_DIR .. "src/devices/machine/74175.h", + } +end + +--------------------------------------------------- +-- --@src/devices/machine/74181.h,MACHINES["TTL74181"] = true --------------------------------------------------- @@ -659,6 +671,18 @@ end --------------------------------------------------- -- +--@src/devices/machine/dm9334.h,MACHINES["DM9334"] = true +--------------------------------------------------- + +if (MACHINES["DM9334"]~=null) then + files { + MAME_DIR .. "src/devices/machine/dm9334.cpp", + MAME_DIR .. "src/devices/machine/dm9334.h", + } +end + +--------------------------------------------------- +-- --@src/devices/machine/ds1204.h,MACHINES["DS1204"] = true --------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 51deb6f04ae..f571ce8a1e6 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -358,6 +358,7 @@ MACHINES["TTL74145"] = true MACHINES["TTL74148"] = true MACHINES["TTL74153"] = true --MACHINES["TTL74161"] = true +--MACHINES["TTL74175"] = true MACHINES["TTL74181"] = true MACHINES["TTL7474"] = true MACHINES["KBDC8042"] = true @@ -388,6 +389,7 @@ MACHINES["COM8116"] = true MACHINES["CR589"] = true --MACHINES["CS4031"] = true --MACHINES["CS8221"] = true +--MACHINES["DM9334"] = true --MACHINES["DP8390"] = true MACHINES["DS1204"] = true MACHINES["DS1302"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 3c5026f459c..5af60065e9f 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -364,6 +364,7 @@ MACHINES["8530SCC"] = true --MACHINES["TTL74148"] = true --MACHINES["TTL74153"] = true --MACHINES["TTL74161"] = true +--MACHINES["TTL74175"] = true --MACHINES["TTL74181"] = true --MACHINES["TTL7474"] = true --MACHINES["KBDC8042"] = true @@ -394,6 +395,7 @@ MACHINES["COM8116"] = true MACHINES["CR589"] = true MACHINES["CS4031"] = true MACHINES["CS8221"] = true +MACHINES["DM9334"] = true MACHINES["DP8390"] = true --MACHINES["DS1204"] = true MACHINES["DS1302"] = true diff --git a/src/devices/machine/74161.cpp b/src/devices/machine/74161.cpp index 50cb769ad0f..23f1a27942c 100644 --- a/src/devices/machine/74161.cpp +++ b/src/devices/machine/74161.cpp @@ -16,6 +16,10 @@ const device_type TTL74163 = &device_creator<ttl74163_device>; ttl7416x_device::ttl7416x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, bool synchronous_reset, uint8_t limit) : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__) + , m_qa_func(*this) + , m_qb_func(*this) + , m_qc_func(*this) + , m_qd_func(*this) , m_output_func(*this) , m_tc_func(*this) , m_clear(0) @@ -156,6 +160,35 @@ WRITE_LINE_MEMBER( ttl7416x_device::clock_w ) } } +WRITE8_MEMBER( ttl7416x_device::p_w ) +{ + m_p = data & 0xf; +} + +WRITE_LINE_MEMBER( ttl7416x_device::p1_w ) +{ + m_p &= ~(1 << 0); + m_p |= (state << 0); +} + +WRITE_LINE_MEMBER( ttl7416x_device::p2_w ) +{ + m_p &= ~(1 << 1); + m_p |= (state << 1); +} + +WRITE_LINE_MEMBER( ttl7416x_device::p3_w ) +{ + m_p &= ~(1 << 2); + m_p |= (state << 2); +} + +WRITE_LINE_MEMBER( ttl7416x_device::p4_w ) +{ + m_p &= ~(1 << 3); + m_p |= (state << 3); +} + READ_LINE_MEMBER( ttl7416x_device::output_r ) { return m_out; diff --git a/src/devices/machine/74161.h b/src/devices/machine/74161.h index 90f24c5ac6b..e6856073655 100644 --- a/src/devices/machine/74161.h +++ b/src/devices/machine/74161.h @@ -59,11 +59,23 @@ #include "emu.h" -#define MCFG_74161_OUTPUT_CB(_devcb) \ - devcb = &ttl74161_device::set_output_cb(*device, DEVCB_##_devcb); +#define MCFG_7416x_QA_CB(_devcb) \ + devcb = &ttl7416x_device::set_qa_cb(*device, DEVCB_##_devcb); -#define MCFG_74161_TC_CB(_devcb) \ - devcb = &ttl74161_device::set_comp_output_cb(*device, DEVCB_##_devcb); +#define MCFG_7416x_QB_CB(_devcb) \ + devcb = &ttl7416x_device::set_qb_cb(*device, DEVCB_##_devcb); + +#define MCFG_7416x_QC_CB(_devcb) \ + devcb = &ttl7416x_device::set_qc_cb(*device, DEVCB_##_devcb); + +#define MCFG_7416x_QD_CB(_devcb) \ + devcb = &ttl7416x_device::set_qd_cb(*device, DEVCB_##_devcb); + +#define MCFG_7416x_OUTPUT_CB(_devcb) \ + devcb = &ttl7416x_device::set_output_cb(*device, DEVCB_##_devcb); + +#define MCFG_7416x_TC_CB(_devcb) \ + devcb = &ttl7416x_device::set_tc_cb(*device, DEVCB_##_devcb); #define MCFG_74160_ADD(_tag) \ MCFG_DEVICE_ADD(_tag, TTL74160, 0) @@ -84,6 +96,10 @@ public: ttl7416x_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, bool synchronous_reset, uint8_t limit); // static configuration helpers + template<class _Object> static devcb_base &set_qa_cb(device_t &device, _Object object) { return downcast<ttl7416x_device &>(device).m_qa_func.set_callback(object); } + template<class _Object> static devcb_base &set_qb_cb(device_t &device, _Object object) { return downcast<ttl7416x_device &>(device).m_qb_func.set_callback(object); } + template<class _Object> static devcb_base &set_qc_cb(device_t &device, _Object object) { return downcast<ttl7416x_device &>(device).m_qc_func.set_callback(object); } + template<class _Object> static devcb_base &set_qd_cb(device_t &device, _Object object) { return downcast<ttl7416x_device &>(device).m_qd_func.set_callback(object); } template<class _Object> static devcb_base &set_output_cb(device_t &device, _Object object) { return downcast<ttl7416x_device &>(device).m_output_func.set_callback(object); } template<class _Object> static devcb_base &set_tc_cb(device_t &device, _Object object) { return downcast<ttl7416x_device &>(device).m_tc_func.set_callback(object); } @@ -93,6 +109,11 @@ public: DECLARE_WRITE_LINE_MEMBER( cet_w ); DECLARE_WRITE_LINE_MEMBER( cep_w ); DECLARE_WRITE_LINE_MEMBER( clock_w ); + DECLARE_WRITE8_MEMBER( p_w ); + DECLARE_WRITE_LINE_MEMBER( p1_w ); + DECLARE_WRITE_LINE_MEMBER( p2_w ); + DECLARE_WRITE_LINE_MEMBER( p3_w ); + DECLARE_WRITE_LINE_MEMBER( p4_w ); DECLARE_READ_LINE_MEMBER( output_r ); DECLARE_READ_LINE_MEMBER( tc_r ); @@ -108,6 +129,10 @@ private: void increment(); // callbacks + devcb_write_line m_qa_func; + devcb_write_line m_qb_func; + devcb_write_line m_qc_func; + devcb_write_line m_qd_func; devcb_write8 m_output_func; devcb_write_line m_tc_func; diff --git a/src/devices/machine/74175.cpp b/src/devices/machine/74175.cpp new file mode 100644 index 00000000000..99e52201cfe --- /dev/null +++ b/src/devices/machine/74175.cpp @@ -0,0 +1,265 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/***************************************************************************** + + 5/74174/5 Hex/Quad D Flip-Flops with Clear + +*****************************************************************************/ + +#include "emu.h" +#include "74175.h" + +const device_type TTL74174 = &device_creator<ttl74174_device>; +const device_type TTL74175 = &device_creator<ttl74175_device>; + +ttl741745_device::ttl741745_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname) + : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__) + , m_q1_func(*this) + , m_q2_func(*this) + , m_q3_func(*this) + , m_q4_func(*this) + , m_clock(0) + , m_clear(0) + , m_d1(0) + , m_d2(0) + , m_d3(0) + , m_d4(0) + , m_q1(0) + , m_q2(0) + , m_q3(0) + , m_q4(0) + , m_last_q1(0) + , m_last_q2(0) + , m_last_q3(0) + , m_last_q4(0) + , m_last_clock(0) +{ +} + +ttl74174_device::ttl74174_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ttl741745_device(mconfig, TTL74174, "54/74174 Hex D Flip-Flops with Clear", tag, owner, clock, "ttl74174") + , m_q5_func(*this) + , m_q6_func(*this) + , m_d5(0) + , m_d6(0) + , m_q5(0) + , m_q6(0) + , m_last_q5(0) + , m_last_q6(0) +{ +} + +ttl74175_device::ttl74175_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ttl741745_device(mconfig, TTL74175, "54/74175 Quad D Flip-Flops with Clear", tag, owner, clock, "ttl74175") + , m_not_q1_func(*this) + , m_not_q2_func(*this) + , m_not_q3_func(*this) + , m_not_q4_func(*this) +{ +} + +void ttl741745_device::device_start() +{ + save_item(NAME(m_d1)); + save_item(NAME(m_d2)); + save_item(NAME(m_d3)); + save_item(NAME(m_d4)); + save_item(NAME(m_q1)); + save_item(NAME(m_q2)); + save_item(NAME(m_q3)); + save_item(NAME(m_q4)); + save_item(NAME(m_last_q1)); + save_item(NAME(m_last_q2)); + save_item(NAME(m_last_q3)); + save_item(NAME(m_last_q4)); + + m_q1_func.resolve_safe(); + m_q2_func.resolve_safe(); + m_q3_func.resolve_safe(); + m_q4_func.resolve_safe(); +} + +void ttl741745_device::device_reset() +{ + init(); +} + +void ttl74174_device::device_start() +{ + ttl741745_device::device_start(); + + save_item(NAME(m_d5)); + save_item(NAME(m_d6)); + save_item(NAME(m_q5)); + save_item(NAME(m_q6)); + save_item(NAME(m_last_q5)); + save_item(NAME(m_last_q6)); + + m_q5_func.resolve_safe(); + m_q6_func.resolve_safe(); +} + +void ttl74175_device::device_start() +{ + save_item(NAME(m_not_q1)); + save_item(NAME(m_not_q2)); + save_item(NAME(m_not_q3)); + save_item(NAME(m_not_q4)); + + m_not_q1_func.resolve_safe(); + m_not_q2_func.resolve_safe(); + m_not_q3_func.resolve_safe(); + m_not_q4_func.resolve_safe(); +} + +void ttl741745_device::init() +{ + m_clock = 0; + m_clear = 0; + + m_d1 = 0; + m_d2 = 0; + m_d3 = 0; + m_d4 = 0; + + m_q1 = 0; + m_q2 = 0; + m_q3 = 0; + m_q4 = 0; + + m_last_q1 = 0; + m_last_q2 = 0; + m_last_q3 = 0; + m_last_q4 = 0; + m_last_clock = 0; +} + +void ttl741745_device::tick() +{ + m_last_q1 = m_q1; + m_last_q2 = m_q2; + m_last_q3 = m_q3; + m_last_q4 = m_q4; + + int q1 = m_d1; + int q2 = m_d2; + int q3 = m_d3; + int q4 = m_d4; + if (m_clear) + { + q1 = 0; + q2 = 0; + q3 = 0; + q4 = 0; + } + + m_q1 = q1; + m_q2 = q2; + m_q3 = q3; + m_q4 = q4; + + if (m_last_q1 != m_q1) + m_q1_func(m_q1); + if (m_last_q2 != m_q2) + m_q2_func(m_q2); + if (m_last_q3 != m_q3) + m_q3_func(m_q3); + if (m_last_q4 != m_q4) + m_q4_func(m_q4); +} + +WRITE_LINE_MEMBER( ttl741745_device::clear_w ) +{ + m_clear = state; +} + +WRITE_LINE_MEMBER( ttl741745_device::clock_w ) +{ + m_last_clock = m_clock; + m_clock = state; + if (m_clock != m_last_clock && m_clock != 0) + { + tick(); + } +} + +WRITE_LINE_MEMBER( ttl741745_device::d1_w ) +{ + m_d1 = state; +} + +WRITE_LINE_MEMBER( ttl741745_device::d2_w ) +{ + m_d2 = state; +} + +WRITE_LINE_MEMBER( ttl741745_device::d3_w ) +{ + m_d3 = state; +} + +WRITE_LINE_MEMBER( ttl741745_device::d4_w ) +{ + m_d4 = state; +} + +WRITE_LINE_MEMBER( ttl74174_device::d5_w ) +{ + m_d5 = state; +} + +WRITE_LINE_MEMBER( ttl74174_device::d6_w ) +{ + m_d6 = state; +} + +void ttl74174_device::init() +{ + ttl741745_device::init(); + m_d5 = 0; + m_d6 = 0; + + m_q5 = 0; + m_q6 = 0; + + m_last_q5 = 0; + m_last_q6 = 0; +} + +void ttl74174_device::tick() +{ + ttl741745_device::tick(); + + m_last_q5 = m_q5; + m_last_q6 = m_q6; + + int q5 = m_d5; + int q6 = m_d6; + if (m_clear) + { + q5 = 0; + q6 = 0; + } + + m_q5 = q5; + m_q6 = q6; + + if (m_last_q5 != m_q5) + m_q5_func(m_q5); + if (m_last_q6 != m_q6) + m_q6_func(m_q6); +} + +void ttl74175_device::tick() +{ + ttl741745_device::tick(); + + if (m_last_q1 != m_q1) + m_not_q1_func(m_q1 ^ 1); + if (m_last_q2 != m_q1) + m_not_q2_func(m_q2 ^ 1); + if (m_last_q3 != m_q1) + m_not_q3_func(m_q3 ^ 1); + if (m_last_q4 != m_q1) + m_not_q4_func(m_q4 ^ 1); +}
\ No newline at end of file diff --git a/src/devices/machine/74175.h b/src/devices/machine/74175.h new file mode 100644 index 00000000000..bb621f926e9 --- /dev/null +++ b/src/devices/machine/74175.h @@ -0,0 +1,214 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************** + + 5/74174/5 Hex/Quad D Flip-Flops with Clear + +*********************************************************************** + + Connection Diagram: + ___ ___ ___ ___ + CLEAR 1 |* u | 16 Vcc CLEAR 1 |* u | 16 Vcc + Q1 2 | | 15 Q6 Q1 2 | | 15 Q4 + D1 3 | | 14 D6 /Q1 3 | | 14 /Q4 + D2 4 | | 13 D5 D1 4 | | 13 D4 + Q2 5 | | 12 Q5 D2 5 | | 12 D3 + D3 6 | | 11 D4 /Q2 6 | | 11 /Q3 + Q3 7 | | 10 Q4 Q2 7 | | 10 Q3 + GND 8 |_______| 9 CLOCK GND 8 |_______| 9 CLOCK + + 5/74174 5/74175 + +*********************************************************************** + + Function Table: + _________________________________ + | Inputs | Outputs* | + |---------------------|-----------| + | Clear | Clock | D | Q | /Q | + |-------|-------|-----|-----|-----| + | L | X | X | L | H | + | H | ^ | H | H | L | + | H | ^ | L | L | H | + | H | L | X | Q0 | Q0 | + |_______|_______|_____|_____|_____| + + H = High Level (steady state) + L = Low Level (steady state) + X = Don't Care + ^ = Transition from low to high level + Q0 = The level of Q before the indicated steady-state input conditions were established. + * = 175 only + +**********************************************************************/ + +#pragma once + +#ifndef TTL74175_H +#define TTL74175_H + +#include "emu.h" + +#define MCFG_74174_Q1_CB(_devcb) \ + devcb = &ttl741745_device::set_q1_cb(*device, DEVCB_##_devcb); + +#define MCFG_74174_Q2_CB(_devcb) \ + devcb = &ttl741745_device::set_q2_cb(*device, DEVCB_##_devcb); + +#define MCFG_74174_Q3_CB(_devcb) \ + devcb = &ttl741745_device::set_q3_cb(*device, DEVCB_##_devcb); + +#define MCFG_74174_Q4_CB(_devcb) \ + devcb = &ttl741745_device::set_q4_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_Q1_CB(_devcb) \ + devcb = &ttl741745_device::set_q1_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_Q2_CB(_devcb) \ + devcb = &ttl741745_device::set_q2_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_Q3_CB(_devcb) \ + devcb = &ttl741745_device::set_q3_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_Q4_CB(_devcb) \ + devcb = &ttl741745_device::set_q4_cb(*device, DEVCB_##_devcb); + +#define MCFG_74174_Q5_CB(_devcb) \ + devcb = &ttl74174_device::set_q5_cb(*device, DEVCB_##_devcb); + +#define MCFG_74174_Q6_CB(_devcb) \ + devcb = &ttl74174_device::set_q6_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_NOT_Q1_CB(_devcb) \ + devcb = &ttl74175_device::set_not_q1_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_NOT_Q2_CB(_devcb) \ + devcb = &ttl74175_device::set_not_q2_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_NOT_Q3_CB(_devcb) \ + devcb = &ttl74175_device::set_not_q3_cb(*device, DEVCB_##_devcb); + +#define MCFG_74175_NOT_Q4_CB(_devcb) \ + devcb = &ttl74175_device::set_not_q1_cb(*device, DEVCB_##_devcb); + +#define MCFG_74174_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, TTL74174, 0) + +#define MCFG_74175_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, TTL74175, 0) + +class ttl741745_device : public device_t +{ +public: + ttl741745_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname); + + template<class _Object> static devcb_base &set_q1_cb(device_t &device, _Object object) { return downcast<ttl741745_device &>(device).m_q1_func.set_callback(object); } + template<class _Object> static devcb_base &set_q2_cb(device_t &device, _Object object) { return downcast<ttl741745_device &>(device).m_q2_func.set_callback(object); } + template<class _Object> static devcb_base &set_q3_cb(device_t &device, _Object object) { return downcast<ttl741745_device &>(device).m_q3_func.set_callback(object); } + template<class _Object> static devcb_base &set_q4_cb(device_t &device, _Object object) { return downcast<ttl741745_device &>(device).m_q4_func.set_callback(object); } + + DECLARE_WRITE_LINE_MEMBER( clear_w ); + DECLARE_WRITE_LINE_MEMBER( d1_w ); + DECLARE_WRITE_LINE_MEMBER( d2_w ); + DECLARE_WRITE_LINE_MEMBER( d3_w ); + DECLARE_WRITE_LINE_MEMBER( d4_w ); + DECLARE_WRITE_LINE_MEMBER( clock_w ); + + uint8_t q_w(); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual void init(); + virtual void tick(); + + devcb_write_line m_q1_func; + devcb_write_line m_q2_func; + devcb_write_line m_q3_func; + devcb_write_line m_q4_func; + + uint8_t m_clock; + uint8_t m_clear; + + uint8_t m_d1; + uint8_t m_d2; + uint8_t m_d3; + uint8_t m_d4; + + uint8_t m_q1; + uint8_t m_q2; + uint8_t m_q3; + uint8_t m_q4; + + uint8_t m_last_q1; + uint8_t m_last_q2; + uint8_t m_last_q3; + uint8_t m_last_q4; + uint8_t m_last_clock; +}; + +class ttl74174_device : public ttl741745_device +{ +public: + ttl74174_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template<class _Object> static devcb_base &set_q5_cb(device_t &device, _Object object) { return downcast<ttl74174_device &>(device).m_q5_func.set_callback(object); } + template<class _Object> static devcb_base &set_q6_cb(device_t &device, _Object object) { return downcast<ttl74174_device &>(device).m_q6_func.set_callback(object); } + + DECLARE_WRITE_LINE_MEMBER( d5_w ); + DECLARE_WRITE_LINE_MEMBER( d6_w ); + +protected: + virtual void device_start() override; + + virtual void init() override; + virtual void tick() override; + +private: + devcb_write_line m_q5_func; + devcb_write_line m_q6_func; + + uint8_t m_d5; + uint8_t m_d6; + + uint8_t m_q5; + uint8_t m_q6; + + uint8_t m_last_q5; + uint8_t m_last_q6; +}; + +class ttl74175_device : public ttl741745_device +{ +public: + ttl74175_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template<class _Object> static devcb_base &set_not_q1_cb(device_t &device, _Object object) { return downcast<ttl74175_device &>(device).m_not_q1_func.set_callback(object); } + template<class _Object> static devcb_base &set_not_q2_cb(device_t &device, _Object object) { return downcast<ttl74175_device &>(device).m_not_q2_func.set_callback(object); } + template<class _Object> static devcb_base &set_not_q3_cb(device_t &device, _Object object) { return downcast<ttl74175_device &>(device).m_not_q3_func.set_callback(object); } + template<class _Object> static devcb_base &set_not_q4_cb(device_t &device, _Object object) { return downcast<ttl74175_device &>(device).m_not_q4_func.set_callback(object); } + +protected: + virtual void device_start() override; + + virtual void tick() override; + +private: + devcb_write_line m_not_q1_func; + devcb_write_line m_not_q2_func; + devcb_write_line m_not_q3_func; + devcb_write_line m_not_q4_func; + + uint8_t m_not_q1; + uint8_t m_not_q2; + uint8_t m_not_q3; + uint8_t m_not_q4; +}; + +// device type definition +extern const device_type TTL74174; +extern const device_type TTL74175; + + +#endif /* TTL74175_H */ diff --git a/src/devices/machine/clock.h b/src/devices/machine/clock.h index 6205b408071..5b7d9ed2e6a 100644 --- a/src/devices/machine/clock.h +++ b/src/devices/machine/clock.h @@ -7,6 +7,9 @@ #include "emu.h" +#define MCFG_CLOCK_ADD(_tag, _clock) \ + MCFG_DEVICE_ADD(_tag, CLOCK, _clock) + #define MCFG_CLOCK_SIGNAL_HANDLER(_devcb) \ devcb = &clock_device::set_signal_handler(*device, DEVCB_##_devcb); diff --git a/src/devices/machine/dm9334.cpp b/src/devices/machine/dm9334.cpp new file mode 100644 index 00000000000..d90f9f6aa4c --- /dev/null +++ b/src/devices/machine/dm9334.cpp @@ -0,0 +1,150 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/***************************************************************************** + + (DM)9334 8-Bit Addressable Latch + +*****************************************************************************/ + +#include "emu.h" +#include "dm9334.h" + +const device_type DM9334 = &device_creator<dm9334_device>; + +dm9334_device::dm9334_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, DM9334, "National Semiconductor 9334/DM9334 8-Bit Addressable Latch", tag, owner, clock, "dm9334", __FILE__) + , m_out_func(*this) + , m_q0_func(*this) + , m_q1_func(*this) + , m_q2_func(*this) + , m_q3_func(*this) + , m_q4_func(*this) + , m_q5_func(*this) + , m_q6_func(*this) + , m_q7_func(*this) + , m_e(0) + , m_c(0) + , m_d(0) + , m_a(0) + , m_out(0) + , m_last_out(0) +{ +} + +void dm9334_device::device_start() +{ + m_e = 0; + m_c = 0; + m_d = 0; + m_a = 0; + + save_item(NAME(m_e)); + save_item(NAME(m_c)); + save_item(NAME(m_d)); + save_item(NAME(m_a)); + save_item(NAME(m_out)); + + m_out_func.resolve_safe(); + m_q0_func.resolve_safe(); + m_q1_func.resolve_safe(); + m_q2_func.resolve_safe(); + m_q3_func.resolve_safe(); + m_q4_func.resolve_safe(); + m_q5_func.resolve_safe(); + m_q6_func.resolve_safe(); + m_q7_func.resolve_safe(); +} + +void dm9334_device::device_reset() +{ + init(); +} + +void dm9334_device::init() +{ + m_e = 0; + m_c = 0; + m_d = 0; + m_a = 0; + m_out = 0; + m_last_out = 0; +} +void dm9334_device::tick() +{ + // TODO + if (m_out != m_last_out) + { + m_last_out = m_out; + m_out_func(m_out); + + for (int bit = 0; bit < 8; bit++) + { + if (BIT(m_out, bit) == BIT(m_last_out, bit)) + continue; + + switch(bit) + { + case 0: m_q0_func(BIT(m_out, bit)); break; + case 1: m_q1_func(BIT(m_out, bit)); break; + case 2: m_q2_func(BIT(m_out, bit)); break; + case 3: m_q3_func(BIT(m_out, bit)); break; + case 4: m_q4_func(BIT(m_out, bit)); break; + case 5: m_q5_func(BIT(m_out, bit)); break; + case 6: m_q6_func(BIT(m_out, bit)); break; + case 7: m_q7_func(BIT(m_out, bit)); break; + } + } + } +} + +WRITE_LINE_MEMBER( dm9334_device::e_w ) +{ + m_e = state; + tick(); +} + +WRITE_LINE_MEMBER( dm9334_device::c_w ) +{ + m_c = state; + tick(); +} + +WRITE_LINE_MEMBER( dm9334_device::d_w ) +{ + m_d = state; +} + +WRITE_LINE_MEMBER( dm9334_device::a0_w ) +{ + m_a &= ~(1 << 0); + m_a |= state << 0; + tick(); +} + +WRITE_LINE_MEMBER( dm9334_device::a1_w ) +{ + m_a &= ~(1 << 1); + m_a |= state << 1; + tick(); +} + +WRITE_LINE_MEMBER( dm9334_device::a2_w ) +{ + m_a &= ~(1 << 2); + m_a |= state << 2; + tick(); +} + +READ8_MEMBER( dm9334_device::output_r ) +{ + return m_out; +} + +READ_LINE_MEMBER( dm9334_device::q0_r ) { return BIT(m_out, 0); } +READ_LINE_MEMBER( dm9334_device::q1_r ) { return BIT(m_out, 1); } +READ_LINE_MEMBER( dm9334_device::q2_r ) { return BIT(m_out, 2); } +READ_LINE_MEMBER( dm9334_device::q3_r ) { return BIT(m_out, 3); } +READ_LINE_MEMBER( dm9334_device::q4_r ) { return BIT(m_out, 4); } +READ_LINE_MEMBER( dm9334_device::q5_r ) { return BIT(m_out, 5); } +READ_LINE_MEMBER( dm9334_device::q6_r ) { return BIT(m_out, 6); } +READ_LINE_MEMBER( dm9334_device::q7_r ) { return BIT(m_out, 7); } diff --git a/src/devices/machine/dm9334.h b/src/devices/machine/dm9334.h new file mode 100644 index 00000000000..1699f47f5d8 --- /dev/null +++ b/src/devices/machine/dm9334.h @@ -0,0 +1,177 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/***************************************************************************** + + (DM)9334 8-Bit Addressable Latch + +****************************************************************************** + + Connection Diagram: + ___ ___ + A0 1 |* u | 16 Vcc + A1 2 | | 15 /C + A2 3 | | 14 /E + Q0 4 | | 13 D + Q1 5 | | 12 Q7 + Q2 6 | | 11 Q6 + Q3 7 | | 10 Q5 + GND 8 |_______| 9 Q4 + +*********************************************************************** + + Function Tables: + + /E /C Mode + L H Addressable Latch + H H Memory + L L Active High Eight + Channel Demultiplexer + H L Clear + + ___________________________________________________________________________________________ + | Inputs | Present Output States | | + |---------------------------|-------------------------------------------------| Mode | + | /C /E | D | A0 A1 A2 | Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 | | + |---------|---|-------------|-------------------------------------------------|-------------| + | L H | X | X X X | L L L L L L L L | Clear | + |---------|---|-------------|-------------------------------------------------|-------------| + | L L | L | L L L | L L L L L L L L | | + | L L | H | L L L | H L L L L L L L | | + | L L | L | H L L | L L L L L L L L | | + | L L | H | H L L | L H L L L L L L | | + | * * | * | * | * | Demultiplex | + | * * | * | * | * | | + | * * | * | * | * | | + | * * | * | * | * | | + | L L | H | H H H | L L L L L L L H | | + |---------|---|-------------|-------------------------------------------------|-------------| + | H H | X | X X X | Qn-1 | Memory | + |---------|---|-------------|-------------------------------------------------|-------------| + | H L | L | L L L | L Qn-1 Qn-1 Qn-1 | | + | H L | H | L L L | H Qn-1 Qn-1 | | + | H L | L | H L L | Qn-1 L Qn-1 | | + | H L | H | H L L | Qn-1 H Qn-1 | | + | * * | * | * | * | | + | * * | * | * | * | | + | * * | * | * | * | | + | H L | L | H H H | Qn-1 Qn-1 L | | + | H L | H | H H H | Qn-1 Qn-1 H | | + |---------|---|-------------|-------------------------------------------------|-------------| + + X = Don't Care Condition + L = Low Voltage Level + H = High Voltage Level + Qn-1 = Previous Output State + +**********************************************************************/ + +#pragma once + +#ifndef DM9334_H +#define DM9334_H + +#include "emu.h" + +#define MCFG_DM9334_OUTPUT_CB(_devcb) \ + devcb = &dm9334_device::set_out_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q0_CB(_devcb) \ + devcb = &dm9334_device::set_q0_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q1_CB(_devcb) \ + devcb = &dm9334_device::set_q1_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q2_CB(_devcb) \ + devcb = &dm9334_device::set_q2_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q3_CB(_devcb) \ + devcb = &dm9334_device::set_q3_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q4_CB(_devcb) \ + devcb = &dm9334_device::set_q4_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q5_CB(_devcb) \ + devcb = &dm9334_device::set_q5_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q6_CB(_devcb) \ + devcb = &dm9334_device::set_q6_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_Q7_CB(_devcb) \ + devcb = &dm9334_device::set_q7_cb(*device, DEVCB_##_devcb); + +#define MCFG_DM9334_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, DM9334, 0) + +class dm9334_device : public device_t +{ +public: + // construction/destruction + dm9334_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + // static configuration helpers + template<class _Object> static devcb_base &set_out_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_out_func.set_callback(object); } + template<class _Object> static devcb_base &set_q0_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q0_func.set_callback(object); } + template<class _Object> static devcb_base &set_q1_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q1_func.set_callback(object); } + template<class _Object> static devcb_base &set_q2_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q2_func.set_callback(object); } + template<class _Object> static devcb_base &set_q3_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q3_func.set_callback(object); } + template<class _Object> static devcb_base &set_q4_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q4_func.set_callback(object); } + template<class _Object> static devcb_base &set_q5_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q5_func.set_callback(object); } + template<class _Object> static devcb_base &set_q6_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q6_func.set_callback(object); } + template<class _Object> static devcb_base &set_q7_cb(device_t &device, _Object object) { return downcast<dm9334_device &>(device).m_q7_func.set_callback(object); } + + DECLARE_WRITE_LINE_MEMBER( e_w ); + DECLARE_WRITE_LINE_MEMBER( c_w ); + DECLARE_WRITE_LINE_MEMBER( d_w ); + DECLARE_WRITE_LINE_MEMBER( a0_w ); + DECLARE_WRITE_LINE_MEMBER( a1_w ); + DECLARE_WRITE_LINE_MEMBER( a2_w ); + DECLARE_WRITE8_MEMBER( a_w ); + + DECLARE_READ8_MEMBER( output_r ); + DECLARE_READ_LINE_MEMBER( q0_r ); + DECLARE_READ_LINE_MEMBER( q1_r ); + DECLARE_READ_LINE_MEMBER( q2_r ); + DECLARE_READ_LINE_MEMBER( q3_r ); + DECLARE_READ_LINE_MEMBER( q4_r ); + DECLARE_READ_LINE_MEMBER( q5_r ); + DECLARE_READ_LINE_MEMBER( q6_r ); + DECLARE_READ_LINE_MEMBER( q7_r ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + void init(); + void tick(); + + // callbacks + devcb_write_line m_out_func; + devcb_write_line m_q0_func; + devcb_write_line m_q1_func; + devcb_write_line m_q2_func; + devcb_write_line m_q3_func; + devcb_write_line m_q4_func; + devcb_write_line m_q5_func; + devcb_write_line m_q6_func; + devcb_write_line m_q7_func; + + // inputs + uint8_t m_e; + uint8_t m_c; + uint8_t m_d; + uint8_t m_a; // pins 1-3 from LSB to MSB + + // outputs + uint8_t m_out; // pins 4-7 and 9-12 from LSB to MSB + + // old state + uint8_t m_last_out; +}; + +// device type definition +extern const device_type DM9334; + + +#endif /* DM9334_H */ diff --git a/src/mame/drivers/hazeltin.cpp b/src/mame/drivers/hazeltin.cpp index d3db3238782..16bda3364ef 100644 --- a/src/mame/drivers/hazeltin.cpp +++ b/src/mame/drivers/hazeltin.cpp @@ -17,10 +17,14 @@ References: #include "emu.h" #include "cpu/i8085/i8085.h" +#include "machine/74161.h" +#include "machine/74175.h" +#include "machine/am2847.h" #include "machine/ay31015.h" -#include "machine/kb3600.h" +#include "machine/clock.h" #include "machine/com8116.h" -#include "machine/am2847.h" +#include "machine/dm9334.h" +#include "machine/kb3600.h" #define CPU_TAG "maincpu" #define UART_TAG "uart" @@ -34,6 +38,16 @@ References: #define SCREEN_TAG "screen" #define TMS3409A_TAG "u67" #define TMS3409B_TAG "u57" +#define DOTCLK_TAG "dotclk" +#define U58_TAG "u58" +#define U68_TAG "u68" +#define U69_PROMMSB_TAG "u69" +#define U70_PROMLSB_TAG "u70" +#define U72_PROM_TAG "u72" +#define U81_TAG "u81" +#define U84_DIV11_TAG "u84" +#define U88_DIV9_TAG "u88" +#define U90_DIV14_TAG "u90" // Number of cycles to burn when fetching the next row of characters into the line buffer: // CPU clock is 18MHz / 9 @@ -53,8 +67,8 @@ References: #define SR3_PB_RESET (0x04) #define KBD_STATUS_KBDR (0x01) -#define KBD_STATUS_TV_INT (0x40) -#define KBD_STATUS_TV_UB (0x80) +#define KBD_STATUS_TV_UB (0x40) +#define KBD_STATUS_TV_INT (0x80) #define SCREEN_HTOTAL (9*100) #define SCREEN_HDISP (9*80) @@ -64,6 +78,8 @@ References: #define SCREEN_VDISP (24*11) #define SCREEN_VSTART (0) +#define VERT_UB_LINE (24*11+8) + class hazl1500_state : public driver_device { public: @@ -79,6 +95,16 @@ public: , m_char_rom(*this, CHARROM_TAG) , m_line_buffer_lsb(*this, TMS3409A_TAG) , m_line_buffer_msb(*this, TMS3409B_TAG) + , m_dotclk(*this, DOTCLK_TAG) + , m_vid_prom_msb(*this, U69_PROMMSB_TAG) + , m_vid_prom_lsb(*this, U70_PROMLSB_TAG) + , m_char_y(*this, U84_DIV11_TAG) + , m_char_x(*this, U88_DIV9_TAG) + , m_vid_div14(*this, U90_DIV14_TAG) + , m_vid_decode(*this, U72_PROM_TAG) + , m_u58(*this, U58_TAG) + , m_u68(*this, U68_TAG) + , m_u81(*this, U81_TAG) , m_screen(*this, SCREEN_TAG) , m_hblank_timer(nullptr) , m_scanline_timer(nullptr) @@ -88,6 +114,7 @@ public: , m_vpos(0) , m_hblank(false) , m_vblank(false) + , m_delayed_vblank(false) { } @@ -113,6 +140,9 @@ public: DECLARE_READ_LINE_MEMBER(ay3600_control_r); DECLARE_WRITE_LINE_MEMBER(ay3600_data_ready_w); + DECLARE_WRITE_LINE_MEMBER(dotclk_w); + DECLARE_WRITE_LINE_MEMBER(ch_bucket_ctr_clk_w); + DECLARE_WRITE_LINE_MEMBER(u70_tc_w); DECLARE_WRITE8_MEMBER(refresh_address_w); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; @@ -136,6 +166,17 @@ private: required_region_ptr<uint8_t> m_char_rom; required_device<tms3409_device> m_line_buffer_lsb; required_device<tms3409_device> m_line_buffer_msb; + required_device<clock_device> m_dotclk; + required_device<ttl74161_device> m_vid_prom_msb; + required_device<ttl74161_device> m_vid_prom_lsb; + required_device<ttl74161_device> m_char_y; + required_device<ttl74161_device> m_char_x; + required_device<ttl74161_device> m_vid_div14; + required_device<dm9334_device> m_vid_decode; + required_device<ttl74175_device> m_u58; + required_device<ttl74175_device> m_u68; + required_device<ttl74175_device> m_u81; + required_device<screen_device> m_screen; std::unique_ptr<uint32_t[]> m_screen_pixbuf; @@ -150,6 +191,7 @@ private: uint16_t m_vpos; bool m_hblank; bool m_vblank; + bool m_delayed_vblank; }; void hazl1500_state::machine_start() @@ -168,6 +210,7 @@ void hazl1500_state::machine_start() save_item(NAME(m_vpos)); save_item(NAME(m_hblank)); save_item(NAME(m_vblank)); + save_item(NAME(m_delayed_vblank)); } void hazl1500_state::machine_reset() @@ -176,13 +219,18 @@ void hazl1500_state::machine_reset() m_kbd_status_latch = 0; m_refresh_address = 0; + m_screen->reset_origin(0, 0); m_vpos = m_screen->vpos(); m_vblank = (m_vpos >= SCREEN_VDISP); + m_delayed_vblank = m_vpos < VERT_UB_LINE; if (!m_vblank) m_kbd_status_latch |= KBD_STATUS_TV_UB; m_hblank = true; m_hblank_timer->adjust(m_screen->time_until_pos(m_vpos, SCREEN_HSTART)); m_scanline_timer->adjust(m_screen->time_until_pos(m_vpos + 1, 0)); + + m_vid_prom_lsb->p_w(generic_space(), 0, 0); + m_vid_prom_msb->p_w(generic_space(), 0, 0); } @@ -233,6 +281,7 @@ WRITE8_MEMBER( hazl1500_state::uart_w ) READ8_MEMBER( hazl1500_state::kbd_status_latch_r ) { + //printf("m_kbd_status_latch r: %02x\n", m_kbd_status_latch); return m_kbd_status_latch; } @@ -294,17 +343,36 @@ void hazl1500_state::device_timer(emu_timer &timer, device_timer_id id, int para } } +WRITE_LINE_MEMBER(hazl1500_state::dotclk_w) +{ + m_u81->clock_w(state); + m_char_x->clock_w(state); +} + +WRITE_LINE_MEMBER(hazl1500_state::ch_bucket_ctr_clk_w) +{ + m_vid_prom_lsb->clock_w(state); + m_vid_prom_msb->clock_w(state); +} + +WRITE_LINE_MEMBER(hazl1500_state::u70_tc_w) +{ + m_vid_prom_msb->cet_w(state); + m_vid_prom_msb->cep_w(state); +} + WRITE8_MEMBER(hazl1500_state::refresh_address_w) { m_refresh_address = data; + //printf("m_refresh_address %x, vpos %d, screen vpos %d\n", m_refresh_address, m_vpos, m_screen->vpos()); } void hazl1500_state::check_tv_interrupt() { uint8_t char_row = m_vpos % 11; bool bit_match = char_row == 2 || char_row == 3; - bool no_vblank = !m_vblank; - bool tv_interrupt = bit_match && no_vblank; + bool tv_interrupt = bit_match && !m_delayed_vblank; + //printf("interrupt for line %d (%d): %s\n", m_vpos, char_row, tv_interrupt ? "yes" : "no"); m_kbd_status_latch &= ~KBD_STATUS_TV_INT; m_kbd_status_latch |= tv_interrupt ? KBD_STATUS_TV_INT : 0; @@ -329,6 +397,7 @@ void hazl1500_state::scanline_tick() uint16_t old_vpos = m_vpos; m_vpos = (m_vpos + 1) % SCREEN_VTOTAL; m_vblank = (m_vpos >= SCREEN_VDISP); + m_delayed_vblank = m_vpos >= VERT_UB_LINE; check_tv_interrupt(); update_tv_unblank(); @@ -621,6 +690,28 @@ static MACHINE_CONFIG_START( hazl1500, hazl1500_state ) MCFG_TMS3409_ADD(TMS3409A_TAG) MCFG_TMS3409_ADD(TMS3409B_TAG) + MCFG_CLOCK_ADD(DOTCLK_TAG, XTAL_33_264MHz/2) + MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(hazl1500_state, dotclk_w)) + + MCFG_74161_ADD(U69_PROMMSB_TAG) + MCFG_74161_ADD(U70_PROMLSB_TAG) + MCFG_7416x_TC_CB(WRITELINE(hazl1500_state, u70_tc_w)) + + MCFG_74161_ADD(U84_DIV11_TAG) + MCFG_74161_ADD(U90_DIV14_TAG) + + MCFG_74161_ADD(U88_DIV9_TAG) + MCFG_7416x_QC_CB(DEVWRITELINE(U81_TAG, ttl74175_device, d4_w)) + MCFG_7416x_TC_CB(DEVWRITELINE(U81_TAG, ttl74175_device, d1_w)) + + MCFG_74175_ADD(U58_TAG) + MCFG_74175_ADD(U68_TAG) + MCFG_74175_ADD(U81_TAG) + MCFG_74175_Q1_CB(DEVWRITELINE(U81_TAG, ttl74175_device, d2_w)) + MCFG_74175_NOT_Q2_CB(WRITELINE(hazl1500_state, ch_bucket_ctr_clk_w)) + + MCFG_DM9334_ADD(U72_PROM_TAG) + /* keyboard controller */ MCFG_DEVICE_ADD(KBDC_TAG, AY3600, 0) MCFG_AY3600_MATRIX_X0(IOPORT("X0")) |