mirror of
https://github.com/holub/mame
synced 2025-10-04 16:34:53 +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
|
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
|
--@src/devices/machine/6522via.h,MACHINES["6522VIA"] = true
|
||||||
|
@ -371,6 +371,7 @@ MACHINES["DMAC"] = true
|
|||||||
MACHINES["GAYLE"] = true
|
MACHINES["GAYLE"] = true
|
||||||
MACHINES["NCR53C7XX"] = true
|
MACHINES["NCR53C7XX"] = true
|
||||||
MACHINES["LSI53C810"] = true
|
MACHINES["LSI53C810"] = true
|
||||||
|
MACHINES["2812FIFO"] = true
|
||||||
MACHINES["6522VIA"] = true
|
MACHINES["6522VIA"] = true
|
||||||
MACHINES["TPI6525"] = true
|
MACHINES["TPI6525"] = true
|
||||||
MACHINES["RIOT6532"] = 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;
|
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)
|
// 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
|
// set_ext_clock - set external clock frequency
|
||||||
|
@ -43,14 +43,14 @@ public:
|
|||||||
uint8_t read(offs_t offset);
|
uint8_t read(offs_t offset);
|
||||||
|
|
||||||
void set_gate(int idx, int state);
|
void set_gate(int idx, int state);
|
||||||
DECLARE_WRITE_LINE_MEMBER( set_g1 );
|
DECLARE_WRITE_LINE_MEMBER( set_g1 ) { set_gate(0, state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( set_g2 );
|
DECLARE_WRITE_LINE_MEMBER( set_g2 ) { set_gate(1, state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( set_g3 );
|
DECLARE_WRITE_LINE_MEMBER( set_g3 ) { set_gate(2, state); }
|
||||||
|
|
||||||
void set_clock(int idx, int state);
|
void set_clock(int idx, int state);
|
||||||
DECLARE_WRITE_LINE_MEMBER( set_c1 );
|
DECLARE_WRITE_LINE_MEMBER( set_c1 ) { set_clock(0, state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( set_c2 );
|
DECLARE_WRITE_LINE_MEMBER( set_c2 ) { set_clock(1, state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( set_c3 );
|
DECLARE_WRITE_LINE_MEMBER( set_c3 ) { set_clock(2, state); }
|
||||||
|
|
||||||
void update_interrupts();
|
void update_interrupts();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user