// license:BSD-3-Clause
// copyright-holders:Juergen Buchmueller
/**********************************************************************
Rockwell A17XX ROM, RAM and I/O chip
A ROM of 2048 x 8 bits is addressed whenever the RRSEL line
(ROM/RAM select) is 0. A RAM of 128 x 4 bit is addressed when
RRSEL is 1. The 16 I/O ports are addressed when the WI/O line
is 1, i.e. whenever the CPU executes an IOL instruction.
There are two basic I/O instructions:
SES = Select Enable Status and SOS = Select Output Status
The lower 4 bits of the I/O address select one of 16 I/O lines.
Actually the lowest 6 bits are used, but bits 4 and 5 must be 0.
There are at most two A17XX per system, one for the lower
ROM and RAM portion and one for the higher.
I/O section instructions
Menmonic I/O bus Accu Description
------------------------------------------------------------------
SES 0 S S 0 X X X 0 1 X X X Enable all outputs
Acuu:3 <- I/O(BL)
------------------------------------------------------------------
SES 0 S S 0 X X X 0 0 X X X Disable all outputs
Acuu:3 <- I/O(BL)
------------------------------------------------------------------
SOS 0 S S 0 X X X 1 1 X X X I/O(BL) <- 1
Acuu:3 <- I/O(BL)
------------------------------------------------------------------
SOS 0 S S 0 X X X 1 0 X X X I/O(BL) <- 0
Acuu:3 <- I/O(BL)
This device emulation takes care of the I/O commands, not the
ROM and RAM, because these are emulated using the generic MAME
memory system.
**********************************************************************/
#include "emu.h"
#include "machine/ra17xx.h"
//#define VERBOSE 1
#include "logmacro.h"
/*************************************
*
* Device interface
*
*************************************/
DEFINE_DEVICE_TYPE(RA17XX, ra17xx_device, "ra17xx", "Rockwell A17xx")
ra17xx_device::ra17xx_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, RA17XX, tag, owner, clock)
, m_enable(false)
, m_iord(*this)
, m_iowr(*this)
, m_cpu(*this, finder_base::DUMMY_TAG)
{
}
/**
* @brief ra17xx_device::device_start device-specific startup
*/
void ra17xx_device::device_start()
{
m_iord.resolve();
m_iowr.resolve();
save_item(NAME(m_line));
}
/**
* @brief ra17xx_device::device_reset device-specific reset
*/
void ra17xx_device::device_reset()
{
memset(m_line, 0, sizeof(m_line));
}
/*************************************
*
* Constants
*
*************************************/
/*************************************
*
* Command access handlers
*
*************************************/
WRITE8_MEMBER( ra17xx_device::io_w )
{
assert(offset < 16);
m_bl = m_cpu->address_bus_r(space, 0) & 63;
if (offset & 1)
{
// SOS command
if (m_bl >= 16)
{
logerror("Attempt to write to nonexistent output %d\n");
}
else if (data & (1 << 3))
{
m_line[m_bl] = 1; // enable output
// if (m_enable)
m_iowr(m_bl, 1, 1);
}
else
{
m_line[m_bl] = 0; // disable output
// if (m_enable)
m_iowr(m_bl, 0, 1);
}
}
else
{
// SES command
if (data & (1 << 3))
{
// enable all outputs
m_enable = true;
for (int i = 0; i < 16; i++)
m_iowr(i, m_line[i], 1);
}
else
{
// disable all outputs
m_enable = false;
}
}
}
READ8_MEMBER( ra17xx_device::io_r )
{
assert(offset < 16);
return (m_bl >= 16 || (m_iord(m_bl) & 1)) ? 0x0f : 0x07;
}