summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices
diff options
context:
space:
mode:
author therealmogminer@gmail.com <therealmogminer@gmail.com>2016-10-27 13:46:10 +0200
committer therealmogminer@gmail.com <therealmogminer@gmail.com>2016-10-27 13:46:42 +0200
commit8225a140ee95a2688c6788c947d58909a4659527 (patch)
tree3d33273d239305852b086724bbbff18c41930705 /src/devices
parent0d87ff49b17df9995d4556aaea9c5680b446604f (diff)
-hazeltin: Added preliminary video, still broken due to timing issues. [Ryan Holtz]
Diffstat (limited to 'src/devices')
-rw-r--r--src/devices/machine/am2847.cpp169
-rw-r--r--src/devices/machine/am2847.h134
2 files changed, 303 insertions, 0 deletions
diff --git a/src/devices/machine/am2847.cpp b/src/devices/machine/am2847.cpp
new file mode 100644
index 00000000000..ef8954c859e
--- /dev/null
+++ b/src/devices/machine/am2847.cpp
@@ -0,0 +1,169 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ AMD Am2847/Am2896 Quad 80/96-Bit Static Shift Registers
+
+**********************************************************************/
+
+#include "am2847.h"
+
+const device_type AM2847 = &device_creator<am2847_device>;
+const device_type AM2849 = &device_creator<am2849_device>;
+const device_type TMS3409 = &device_creator<tms3409_device>;
+
+am2847_base_device::am2847_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, size_t size)
+ : device_t(mconfig, type, name, tag, owner, clock, shortname, __FILE__)
+ , m_in(0)
+ , m_out(0)
+ , m_rc(0)
+ , m_cp(0)
+ , m_buffer_size(size)
+{
+}
+
+am2847_device::am2847_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : am2847_base_device(mconfig, AM2847, "AMD Am2847 80-bit Static Shift Register", tag, owner, clock, "am2847", 5)
+{
+}
+
+am2849_device::am2849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : am2847_base_device(mconfig, AM2849, "AMD Am2849 96-bit Static Shift Register", tag, owner, clock, "am2847", 6)
+{
+}
+
+tms3409_device::tms3409_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : am2847_base_device(mconfig, TMS3409, "TI TMS3409 80-bit Static Shift Register", tag, owner, clock, "am2847", 5)
+{
+}
+
+void am2847_base_device::device_start()
+{
+ for (int bit = 0; bit < 4; bit++)
+ {
+ m_shifters[bit].alloc(m_buffer_size);
+ }
+
+ init();
+
+ save_item(NAME(m_in));
+ save_item(NAME(m_out));
+}
+
+void am2847_base_device::device_reset()
+{
+ init();
+}
+
+void am2847_base_device::init()
+{
+ m_in = 0;
+ m_out = 0;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_a_w )
+{
+ m_in &= ~0x01;
+ m_in |= state;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_b_w )
+{
+ m_in &= ~0x02;
+ m_in |= state << 1;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_c_w )
+{
+ m_in &= ~0x04;
+ m_in |= state << 2;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::in_d_w )
+{
+ m_in &= ~0x08;
+ m_in |= state << 3;
+}
+
+void am2847_base_device::in_w(uint8_t data)
+{
+ m_in = data & 0x0f;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_a_w )
+{
+ m_rc &= ~0x01;
+ m_rc |= state;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_b_w )
+{
+ m_rc &= ~0x02;
+ m_rc |= state << 1;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_c_w )
+{
+ m_rc &= ~0x04;
+ m_rc |= state << 2;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::rc_d_w )
+{
+ m_rc &= ~0x08;
+ m_rc |= state << 3;
+}
+
+void am2847_base_device::rc_w(uint8_t data)
+{
+ m_rc = data & 0x0f;
+}
+
+WRITE_LINE_MEMBER( am2847_base_device::cp_w )
+{
+ if (m_cp != state && state != 0)
+ {
+ shift();
+ }
+ m_cp = state;
+}
+
+void am2847_base_device::shift()
+{
+ for (int bit = 0; bit < 4; bit++)
+ {
+ m_out &= ~(1 << bit);
+ m_out |= m_shifters[bit].shift(BIT(m_rc, bit) != 0, BIT(m_in, bit)) << bit;
+ }
+}
+
+void am2847_base_device::shifter::alloc(size_t size)
+{
+ m_buffer_size = size;
+ m_buffer = std::make_unique<uint16_t[]>(m_buffer_size);
+ init();
+}
+
+void am2847_base_device::shifter::init()
+{
+ memset(&m_buffer[0], 0, m_buffer_size * 2);
+}
+
+int am2847_base_device::shifter::shift(bool recycle, int in)
+{
+ int out = m_buffer[m_buffer_size-1] & 1;
+ for (int word = m_buffer_size - 1; word >= 1; word--)
+ {
+ m_buffer[word] >>= 1;
+ m_buffer[word] |= (m_buffer[word - 1] & 1) << 15;
+ }
+
+ m_buffer[0] >>= 1;
+
+ if (recycle)
+ m_buffer[0] |= out << 15;
+ else
+ m_buffer[0] |= (in & 1) << 15;
+
+ return out;
+}
diff --git a/src/devices/machine/am2847.h b/src/devices/machine/am2847.h
new file mode 100644
index 00000000000..a019a733537
--- /dev/null
+++ b/src/devices/machine/am2847.h
@@ -0,0 +1,134 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ AMD Am2847/Am2896 Quad 80/96-Bit Static Shift Registers
+
+ Pin-compatible with:
+ * 2532B
+ * TMS3120
+ * TMS3409
+ * MK1007
+ * 3347
+
+***********************************************************************
+
+ Connection Diagram:
+ ___ ___
+ OUT A 1 |* u | 16 Vss
+ RC A 2 | | 15 IN D
+ IN A 3 | | 14 RC D
+ OUT B 4 | | 13 OUT D
+ RC B 5 | | 12 Vgg
+ IN B 6 | | 11 CP
+ OUT C 7 | | 10 IN C
+ Vdd 8 |_______| 9 RC C
+
+ Logic Symbol:
+
+ 2 5 9 14
+ | | | |
+ _____|______|______|______|_____
+ | RC A RC B RC C RC D |
+ 3 ---| IN A OUT A |--- 1
+ 6 ---| IN A OUT B |--- 4
+ 10 ---| IN A OUT C |--- 7
+ 15 ---| IN A OUT D |--- 13
+ 11 ---| CP |
+ |________________________________|
+
+
+**********************************************************************/
+
+#pragma once
+
+#ifndef AM2847_H
+#define AM2847_H
+
+#include "emu.h"
+
+#define MCFG_AM2847_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, AM2847, 0)
+
+#define MCFG_AM2849_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, AM2849, 0)
+
+#define MCFG_TMS3409_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, TMS3409, 0)
+
+class am2847_base_device : public device_t
+{
+public:
+ am2847_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, uint32_t clock, const char *shortname, size_t size);
+
+ DECLARE_WRITE_LINE_MEMBER( in_a_w );
+ DECLARE_WRITE_LINE_MEMBER( in_b_w );
+ DECLARE_WRITE_LINE_MEMBER( in_c_w );
+ DECLARE_WRITE_LINE_MEMBER( in_d_w );
+ void in_w(uint8_t data); // Or if you prefer...
+
+ DECLARE_WRITE_LINE_MEMBER( rc_a_w );
+ DECLARE_WRITE_LINE_MEMBER( rc_b_w );
+ DECLARE_WRITE_LINE_MEMBER( rc_c_w );
+ DECLARE_WRITE_LINE_MEMBER( rc_d_w );
+ void rc_w(uint8_t data); // Or if you prefer...
+
+ DECLARE_WRITE_LINE_MEMBER( cp_w );
+
+ uint8_t out_r() const { return m_out; }
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ void init();
+ void shift();
+
+ class shifter
+ {
+ public:
+ shifter() : m_buffer_size(0) { }
+ void alloc(size_t size);
+ void init();
+ int shift(bool recycle, int in);
+ protected:
+ std::unique_ptr<uint16_t[]> m_buffer;
+ size_t m_buffer_size;
+ };
+
+ shifter m_shifters[4];
+ uint8_t m_in;
+ uint8_t m_out;
+ uint8_t m_rc;
+ int m_cp;
+
+ const size_t m_buffer_size;
+};
+
+class am2847_device : public am2847_base_device
+{
+public:
+ // construction/destruction
+ am2847_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+class am2849_device : public am2847_base_device
+{
+public:
+ // construction/destruction
+ am2849_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+class tms3409_device : public am2847_base_device
+{
+public:
+ // construction/destruction
+ tms3409_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+};
+
+// device type definition
+extern const device_type AM2847;
+extern const device_type AM2849;
+extern const device_type TMS3409;
+
+#endif // AM2847_H \ No newline at end of file