diff options
author | 2019-04-21 13:43:52 +1000 | |
---|---|---|
committer | 2019-04-21 13:43:52 +1000 | |
commit | 112062f7bbad1a42dc856cd1fd8d2ac05ad7ed37 (patch) | |
tree | 9f9c361c6aac67f231a6adc64d0d89cbbb7b4914 | |
parent | e837e6710152244dc209ce756dc1f89c07198a57 (diff) |
Add AMD/Plessey 2812 FIFO device (for WIP Star Rider driver)
-rw-r--r-- | scripts/src/machine.lua | 12 | ||||
-rw-r--r-- | scripts/target/mame/arcade.lua | 1 | ||||
-rw-r--r-- | src/devices/machine/2812fifo.cpp | 235 | ||||
-rw-r--r-- | src/devices/machine/2812fifo.h | 84 | ||||
-rw-r--r-- | src/devices/machine/6840ptm.cpp | 8 | ||||
-rw-r--r-- | src/devices/machine/6840ptm.h | 12 |
6 files changed, 338 insertions, 14 deletions
diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 611d33f7bf7..9f9fba08549 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -179,6 +179,18 @@ end --------------------------------------------------- -- +--@src/devices/machine/2812fifo.h,MACHINES["2812FIFO"] = true +--------------------------------------------------- + +if (MACHINES["2812FIFO"]~=null) then + files { + MAME_DIR .. "src/devices/machine/2812fifo.cpp", + MAME_DIR .. "src/devices/machine/2812fifo.h", + } +end + +--------------------------------------------------- +-- --@src/devices/machine/6522via.h,MACHINES["6522VIA"] = true --------------------------------------------------- diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 88f2884210c..71dd5555213 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -371,6 +371,7 @@ MACHINES["DMAC"] = true MACHINES["GAYLE"] = true MACHINES["NCR53C7XX"] = true MACHINES["LSI53C810"] = true +MACHINES["2812FIFO"] = true MACHINES["6522VIA"] = true MACHINES["TPI6525"] = true MACHINES["RIOT6532"] = true diff --git a/src/devices/machine/2812fifo.cpp b/src/devices/machine/2812fifo.cpp new file mode 100644 index 00000000000..250be669639 --- /dev/null +++ b/src/devices/machine/2812fifo.cpp @@ -0,0 +1,235 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/************************************************************************** + + 2812 32*8 First-In First-Out Memory (AMD, Plessey, and others) + + These devices contain a file of 32 data registers and corresponding + control registers indicating when the data registers are valid. + Data ripples from the input register towards the output until it + reaches a register containing valid data. The first and last data + registers support serial operation. + + The half-full flag responds to the number of valid locations. It + favours glitch-free operation over precision. It's never asserted + when fewer than 13 registers are valid, and it's always asserted + when at least 16 registers are valid. + + TODO: + * Propagation delays + * Serial I/O + * Am2813 32*9 version without serial I/O + +**************************************************************************/ + +#include "emu.h" +#include "2812fifo.h" + +#include <algorithm> +#include <cassert> + + +DEFINE_DEVICE_TYPE(FIFO2812, fifo2812_device, "fifo2812", "2812 32*8 FIFO Memory"); + + +fifo2812_device::fifo2812_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) : + device_t(mconfig, FIFO2812, tag, owner, clock), + m_q_cb(*this), + m_ir_cb(*this), + m_or_cb(*this), + m_flag_cb(*this), + m_control(0U), + m_count(0U), + m_d(0U), m_mr(1U), m_pl(0U), m_pd(0U), m_oe(1U) +{ + std::fill(std::begin(m_data), std::end(m_data), 0U); +} + + +WRITE_LINE_MEMBER(fifo2812_device::mr_w) +{ + if (bool(state) != bool(m_mr)) + { + m_mr = state ? 1U : 0U; + if (!m_mr) + device_reset(); + } +} + +WRITE_LINE_MEMBER(fifo2812_device::pl_w) +{ + if (bool(state) != bool(m_pl)) + { + m_pl = state ? 1U : 0U; + if (m_mr) + { + if (m_pl) + { + m_data[0] = m_d; + if (!BIT(m_control, 0)) + { + m_control |= u32(1) << 0; + m_ir_cb(1); + if (15U == ++m_count) + m_flag_cb(1); + } + } + else if (BIT(m_control, 0) && !BIT(m_control, 1)) + { + unsigned bit(1); + m_data[bit] = m_data[bit - 1]; + m_control |= u32(1) << bit; + m_control &= ~(u32(1) << (bit - 1)); + m_ir_cb(0); + for (++bit; ((LENGTH - 1) > bit) && !BIT(m_control, bit); ++bit) + { + m_data[bit] = m_data[bit - 1]; + m_control |= u32(1) << bit; + m_control &= ~(u32(1) << (bit - 1)); + } + if (!m_pd && ((LENGTH - 1) == bit) && !BIT(m_control, bit)) + { + if (m_data[bit] != m_data[bit - 1]) + { + m_data[bit] = m_data[bit - 1]; + if (m_oe) + m_q_cb(0U, m_data[bit], 0xffU); + } + m_control |= u32(1) << bit; + m_control &= ~(u32(1) << (bit - 1)); + m_or_cb(1); + } + } + } + } +} + +WRITE_LINE_MEMBER(fifo2812_device::pd_w) +{ + if (bool(state) != bool(m_pd)) + { + m_pd = state ? 1U : 0U; + if (m_mr) + { + if (m_pd) + { + if (BIT(m_control, LENGTH - 1)) + { + m_control &= ~(u32(1) << (LENGTH - 1)); + m_or_cb(0); + if (15U == m_count--) + m_flag_cb(0); + } + } + else if (BIT(m_control, LENGTH - 2)) + { + unsigned bit(LENGTH - 2); + if (m_data[bit + 1] != m_data[bit]) + { + m_data[bit + 1] = m_data[bit]; + if (m_oe) + m_q_cb(0U, m_data[bit + 1], 0xffU); + } + m_control |= u32(1) << (bit + 1); + m_control &= ~(u32(1) << bit); + m_or_cb(1); + for (--bit; (0U < bit) && BIT(m_control, bit); --bit) + { + m_data[bit + 1] = m_data[bit]; + m_control |= u32(1) << (bit + 1); + m_control &= ~(u32(1) << bit); + } + if (!m_pl && (0U == bit) && BIT(m_control, bit)) + { + m_data[bit + 1] = m_data[bit]; + m_control |= u32(1) << (bit + 1); + m_control &= ~(u32(1) << bit); + m_ir_cb(0); + } + } + } + } +} + +WRITE_LINE_MEMBER(fifo2812_device::oe_w) +{ + if (bool(state) != bool(m_oe)) + { + m_oe = state ? 1U : 0U; + if (m_oe) + m_q_cb(0U, m_data[LENGTH - 1], 0xffU); + else + m_q_cb(0U, 0xffU, 0x00U); + } +} + + +u8 fifo2812_device::read() +{ + if (machine().side_effects_disabled()) + { + return m_data[LENGTH - 1]; + } + else + { + assert(!m_pd); + pd_w(1); + u8 const data(m_data[LENGTH - 1]); + pd_w(0); + return data; + } +} + +void fifo2812_device::write(u8 data) +{ + assert(!m_pl); + d_w(data); + pl_w(1); + pl_w(0); +} + + +void fifo2812_device::device_resolve_objects() +{ + m_q_cb.resolve_safe(); + m_ir_cb.resolve_safe(); + m_or_cb.resolve_safe(); + m_flag_cb.resolve_safe(); + + m_d = 0U; + m_mr = 1U; + m_pl = 0U; + m_pd = 0U; + m_oe = 1U; +} + +void fifo2812_device::device_start() +{ + save_item(NAME(m_control)); + save_item(NAME(m_data)); + save_item(NAME(m_count)); + save_item(NAME(m_d)); + save_item(NAME(m_mr)); + save_item(NAME(m_pl)); + save_item(NAME(m_pd)); + save_item(NAME(m_oe)); +} + +void fifo2812_device::device_reset() +{ + u32 const prev_ir(BIT(m_control, 0)); + u32 const prev_or(BIT(m_control, LENGTH - 1)); + u8 const prev_q(m_data[LENGTH - 1]); + bool const prev_flag(15U <= m_count); + m_control = 0U; + std::fill(std::begin(m_data), std::end(m_data), 0U); + m_count = 0U; + if (m_oe && (0U != prev_q)) + m_q_cb(0U, 0U, 0xffU); + if (prev_ir) + m_ir_cb(0); + if (prev_or) + m_or_cb(0); + if (prev_flag) + m_flag_cb(0); +} diff --git a/src/devices/machine/2812fifo.h b/src/devices/machine/2812fifo.h new file mode 100644 index 00000000000..01c42624c09 --- /dev/null +++ b/src/devices/machine/2812fifo.h @@ -0,0 +1,84 @@ +// license:BSD-3-Clause +// copyright-holders:Vas Crabb +/************************************************************************** + + 2812 32*8 First-In First-Out Memory (AMD, Plessey, and others) + ____ ____ + D0 1 |* \_/ | 28 D1 + Vgg 2 | | 27 D2 + OR 3 | | 26 D3 + /MR 4 | | 25 /IR + PD 5 | | 24 Vss + SD 6 | | 23 D4 + Q0 7 | 2812 | 22 D5 + Q1 8 | | 21 D6 + Q2 9 | | 20 D7 + Q3 10 | | 19 FLAG + OE 11 | | 18 PL + Q4 12 | | 17 SL + Q5 13 | | 16 Vdd + Q6 14 |___________| 15 Q7 + +**************************************************************************/ +#ifndef MAME_MACHINE_2812FIFO_H +#define MAME_MACHINE_2812FIFO_H + +#pragma once + +#include <array> + + +class fifo2812_device : public device_t +{ +public: + // standard constructor + fifo2812_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); + + // callbacks + auto q_cb() { return m_q_cb.bind(); } + auto ir_cb() { return m_ir_cb.bind(); } + auto or_cb() { return m_or_cb.bind(); } + auto flag_cb() { return m_flag_cb.bind(); } + + // control signal interface + void d_w(u8 data) { m_d = data; } + DECLARE_WRITE_LINE_MEMBER(mr_w); + DECLARE_WRITE_LINE_MEMBER(pl_w); + DECLARE_WRITE_LINE_MEMBER(pd_w); + DECLARE_WRITE_LINE_MEMBER(oe_w); + u8 q_r() const { return m_oe ? m_data[LENGTH - 1] : 0xff; } + DECLARE_READ_LINE_MEMBER(ir_r) const { return BIT(m_control, 0); } + DECLARE_READ_LINE_MEMBER(or_r) const { return BIT(m_control, LENGTH - 1); } + DECLARE_READ_LINE_MEMBER(flag_r); + + // read/write interface + u8 read(); + void write(u8 data); + +protected: + // device_t implementation + virtual void device_resolve_objects() override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + enum { LENGTH = 32 }; + + // output callbacks + devcb_write8 m_q_cb; + devcb_write_line m_ir_cb; + devcb_write_line m_or_cb; + devcb_write_line m_flag_cb; + + // registers/state + u32 m_control; + std::array<u8, LENGTH> m_data; + u8 m_count; + + // input line states + u8 m_d, m_mr, m_pl, m_pd, m_oe; +}; + +DECLARE_DEVICE_TYPE(FIFO2812, fifo2812_device) + +#endif // MAME_MACHINE_2812FIFO_H diff --git a/src/devices/machine/6840ptm.cpp b/src/devices/machine/6840ptm.cpp index 36b2cd5002b..02ed1f31912 100644 --- a/src/devices/machine/6840ptm.cpp +++ b/src/devices/machine/6840ptm.cpp @@ -660,10 +660,6 @@ void ptm6840_device::set_gate(int idx, int state) m_gate[idx] = state; } -WRITE_LINE_MEMBER( ptm6840_device::set_g1 ) { set_gate(0, state); } -WRITE_LINE_MEMBER( ptm6840_device::set_g2 ) { set_gate(1, state); } -WRITE_LINE_MEMBER( ptm6840_device::set_g3 ) { set_gate(2, state); } - //------------------------------------------------- // set_clock - set clock status (0 or 1) @@ -682,10 +678,6 @@ void ptm6840_device::set_clock(int idx, int state) } } -WRITE_LINE_MEMBER( ptm6840_device::set_c1 ) { set_clock(0, state); } -WRITE_LINE_MEMBER( ptm6840_device::set_c2 ) { set_clock(1, state); } -WRITE_LINE_MEMBER( ptm6840_device::set_c3 ) { set_clock(2, state); } - //------------------------------------------------- // set_ext_clock - set external clock frequency diff --git a/src/devices/machine/6840ptm.h b/src/devices/machine/6840ptm.h index 2c913a97b4c..c1adcbfde13 100644 --- a/src/devices/machine/6840ptm.h +++ b/src/devices/machine/6840ptm.h @@ -43,14 +43,14 @@ public: uint8_t read(offs_t offset); void set_gate(int idx, int state); - DECLARE_WRITE_LINE_MEMBER( set_g1 ); - DECLARE_WRITE_LINE_MEMBER( set_g2 ); - DECLARE_WRITE_LINE_MEMBER( set_g3 ); + DECLARE_WRITE_LINE_MEMBER( set_g1 ) { set_gate(0, state); } + DECLARE_WRITE_LINE_MEMBER( set_g2 ) { set_gate(1, state); } + DECLARE_WRITE_LINE_MEMBER( set_g3 ) { set_gate(2, state); } void set_clock(int idx, int state); - DECLARE_WRITE_LINE_MEMBER( set_c1 ); - DECLARE_WRITE_LINE_MEMBER( set_c2 ); - DECLARE_WRITE_LINE_MEMBER( set_c3 ); + DECLARE_WRITE_LINE_MEMBER( set_c1 ) { set_clock(0, state); } + DECLARE_WRITE_LINE_MEMBER( set_c2 ) { set_clock(1, state); } + DECLARE_WRITE_LINE_MEMBER( set_c3 ) { set_clock(2, state); } void update_interrupts(); |