mirror of
https://github.com/holub/mame
synced 2025-10-04 08:28:39 +03:00
Add AMD/Plessey 2812 FIFO device (for WIP Star Rider driver)
This commit is contained in:
parent
e837e67101
commit
112062f7bb
@ -177,6 +177,18 @@ if (MACHINES["LSI53C810"]~=null) then
|
||||
}
|
||||
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
|
||||
|
@ -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
|
||||
|
235
src/devices/machine/2812fifo.cpp
Normal file
235
src/devices/machine/2812fifo.cpp
Normal file
@ -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);
|
||||
}
|
84
src/devices/machine/2812fifo.h
Normal file
84
src/devices/machine/2812fifo.h
Normal file
@ -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
|
@ -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
|
||||
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user