summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/6532riot.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/6532riot.cpp')
-rw-r--r--src/devices/machine/6532riot.cpp515
1 files changed, 0 insertions, 515 deletions
diff --git a/src/devices/machine/6532riot.cpp b/src/devices/machine/6532riot.cpp
deleted file mode 100644
index f24b8b1656c..00000000000
--- a/src/devices/machine/6532riot.cpp
+++ /dev/null
@@ -1,515 +0,0 @@
-// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
-/***************************************************************************
-
- RIOT 6532 emulation
-
-The timer seems to follow these rules:
-- When the timer flag changes from 0 to 1 the timer continues to count
- down at a 1 cycle rate.
-- When the timer is being read or written the timer flag is reset.
-- When the timer flag is set and the timer contents are 0, the counting
- stops.
-
-***************************************************************************/
-
-#include "emu.h"
-#include "6532riot.h"
-
-
-//**************************************************************************
-// CONSTANTS
-//**************************************************************************
-
-// device type definition
-DEFINE_DEVICE_TYPE(RIOT6532, riot6532_device, "riot6532", "6532 RIOT")
-
-enum
-{
- TIMER_IDLE,
- TIMER_COUNTING,
- TIMER_FINISHING
-};
-
-#define TIMER_FLAG 0x80
-#define PA7_FLAG 0x40
-
-
-
-/***************************************************************************
- INTERNAL FUNCTIONS
-***************************************************************************/
-
-/*-------------------------------------------------
- update_irqstate - update the IRQ state
- based on interrupt enables
--------------------------------------------------*/
-
-void riot6532_device::update_irqstate()
-{
- int irq = (m_irqstate & m_irqenable) ? ASSERT_LINE : CLEAR_LINE;
-
- if (m_irq != irq)
- {
- m_irq_cb(irq);
- m_irq = irq;
- }
-}
-
-
-/*-------------------------------------------------
- apply_ddr - combine inputs and outputs
- according to the DDR
--------------------------------------------------*/
-
-uint8_t riot6532_device::apply_ddr(const riot6532_port *port)
-{
- return (port->m_out & port->m_ddr) | (port->m_in & ~port->m_ddr);
-}
-
-
-/*-------------------------------------------------
- update_pa7_state - see if PA7 has changed
- and signal appropriately
--------------------------------------------------*/
-
-void riot6532_device::update_pa7_state()
-{
- uint8_t data = apply_ddr(&m_port[0]) & 0x80;
-
- /* if the state changed in the correct direction, set the PA7 flag and update IRQs */
- if ((m_pa7prev ^ data) && (m_pa7dir ^ data) == 0)
- {
- m_irqstate |= PA7_FLAG;
- update_irqstate();
- }
- m_pa7prev = data;
-}
-
-
-/*-------------------------------------------------
- get_timer - return the current timer value
--------------------------------------------------*/
-
-uint8_t riot6532_device::get_timer()
-{
- /* if idle, return 0 */
- if (m_timerstate == TIMER_IDLE)
- {
- return 0;
- }
-
- /* if counting, return the number of ticks remaining */
- else if (m_timerstate == TIMER_COUNTING)
- {
- return m_timer->remaining().as_ticks(clock()) >> m_timershift;
- }
-
- /* if finishing, return the number of ticks without the shift */
- else
- {
- return m_timer->remaining().as_ticks(clock());
- }
-}
-
-
-
-void riot6532_device::timer_end()
-{
- assert(m_timerstate != TIMER_IDLE);
-
- /* if we finished counting, switch to the finishing state */
- if(m_timerstate == TIMER_COUNTING)
- {
- m_timerstate = TIMER_FINISHING;
- m_timer->adjust(attotime::from_ticks(256, clock()));
-
- /* signal timer IRQ as well */
- m_irqstate |= TIMER_FLAG;
- update_irqstate();
- }
-
- /* if we finished finishing, keep spinning */
- else if (m_timerstate == TIMER_FINISHING)
- {
- m_timer->adjust(attotime::from_ticks(256, clock()));
- }
-}
-
-
-
-/***************************************************************************
- I/O ACCESS
-***************************************************************************/
-
-/*-------------------------------------------------
- riot6532_w - master I/O write access
--------------------------------------------------*/
-
-WRITE8_MEMBER( riot6532_device::write )
-{
- reg_w(offset, data);
-}
-
-void riot6532_device::reg_w(uint8_t offset, uint8_t data)
-{
- /* if A4 == 1 and A2 == 1, we are writing to the timer */
- if ((offset & 0x14) == 0x14)
- {
- static const uint8_t timershift[4] = { 0, 3, 6, 10 };
- attotime curtime = machine().time();
- int64_t target;
-
- /* A0-A1 contain the timer divisor */
- m_timershift = timershift[offset & 3];
-
- /* A3 contains the timer IRQ enable */
- if (offset & 8)
- m_irqenable |= TIMER_FLAG;
- else
- m_irqenable &= ~TIMER_FLAG;
-
- /* writes here clear the timer flag */
- if (m_timerstate != TIMER_FINISHING || get_timer() != 0xff)
- {
- m_irqstate &= ~TIMER_FLAG;
- }
- update_irqstate();
-
- /* update the timer */
- m_timerstate = TIMER_COUNTING;
- target = curtime.as_ticks(clock()) + 1 + (data << m_timershift);
- m_timer->adjust(attotime::from_ticks(target, clock()) - curtime);
- }
-
- /* if A4 == 0 and A2 == 1, we are writing to the edge detect control */
- else if ((offset & 0x14) == 0x04)
- {
- /* A1 contains the A7 IRQ enable */
- if (offset & 2)
- {
- m_irqenable |= PA7_FLAG;
- }
- else
- {
- m_irqenable &= ~PA7_FLAG;
- }
-
- /* A0 specifies the edge detect direction: 0=negative, 1=positive */
- m_pa7dir = (offset & 1) << 7;
- }
-
- /* if A4 == anything and A2 == 0, we are writing to the I/O section */
- else
- {
- /* A1 selects the port */
- riot6532_port *port = &m_port[BIT(offset, 1)];
-
- /* if A0 == 1, we are writing to the port's DDR */
- if (offset & 1)
- {
- port->m_ddr = data;
- }
-
- /* if A0 == 0, we are writing to the port's output */
- else
- {
- port->m_out = data;
- (*port->m_out_cb)((offs_t)0, data);
- }
-
- /* writes to port A need to update the PA7 state */
- if (port == &m_port[0])
- {
- update_pa7_state();
- }
- }
-}
-
-
-/*-------------------------------------------------
- riot6532_r - master I/O read access
--------------------------------------------------*/
-
-READ8_MEMBER( riot6532_device::read )
-{
- return reg_r(offset, machine().side_effects_disabled());
-}
-
-uint8_t riot6532_device::reg_r(uint8_t offset, bool debugger_access)
-{
- uint8_t val;
-
- /* if A2 == 1 and A0 == 1, we are reading interrupt flags */
- if ((offset & 0x05) == 0x05)
- {
- val = m_irqstate;
-
- if ( ! debugger_access )
- {
- /* implicitly clears the PA7 flag */
- m_irqstate &= ~PA7_FLAG;
- update_irqstate();
- }
- }
-
- /* if A2 == 1 and A0 == 0, we are reading the timer */
- else if ((offset & 0x05) == 0x04)
- {
- val = get_timer();
-
- if ( ! debugger_access )
- {
- /* A3 contains the timer IRQ enable */
- if (offset & 8)
- {
- m_irqenable |= TIMER_FLAG;
- }
- else
- {
- m_irqenable &= ~TIMER_FLAG;
- }
-
- /* implicitly clears the timer flag */
- if (m_timerstate != TIMER_FINISHING || val != 0xff)
- {
- m_irqstate &= ~TIMER_FLAG;
- }
- update_irqstate();
- }
- }
-
- /* if A2 == 0 and A0 == anything, we are reading from ports */
- else
- {
- /* A1 selects the port */
- riot6532_port *port = &m_port[BIT(offset, 1)];
-
- /* if A0 == 1, we are reading the port's DDR */
- if (offset & 1)
- {
- val = port->m_ddr;
- }
-
- /* if A0 == 0, we are reading the port as an input */
- else
- {
- /* call the input callback if it exists */
- if (!(*port->m_in_cb).isnull())
- {
- port->m_in = (*port->m_in_cb)(0);
-
- /* changes to port A need to update the PA7 state */
- if (port == &m_port[0])
- {
- if (!debugger_access)
- {
- update_pa7_state();
- }
- }
- }
-
- /* apply the DDR to the result */
- val = apply_ddr(port);
- }
- }
- return val;
-}
-
-
-/*-------------------------------------------------
- porta_in_set - set port A input value
--------------------------------------------------*/
-
-void riot6532_device::porta_in_set(uint8_t data, uint8_t mask)
-{
- m_port[0].m_in = (m_port[0].m_in & ~mask) | (data & mask);
- update_pa7_state();
-}
-
-
-/*-------------------------------------------------
- portb_in_set - set port B input value
--------------------------------------------------*/
-
-void riot6532_device::portb_in_set(uint8_t data, uint8_t mask)
-{
- m_port[1].m_in = (m_port[1].m_in & ~mask) | (data & mask);
-}
-
-
-/*-------------------------------------------------
- porta_in_get - return port A input value
--------------------------------------------------*/
-
-uint8_t riot6532_device::porta_in_get()
-{
- return m_port[0].m_in;
-}
-
-
-/*-------------------------------------------------
- portb_in_get - return port B input value
--------------------------------------------------*/
-
-uint8_t riot6532_device::portb_in_get()
-{
- return m_port[1].m_in;
-}
-
-
-/*-------------------------------------------------
- porta_in_get - return port A output value
--------------------------------------------------*/
-
-uint8_t riot6532_device::porta_out_get()
-{
- return m_port[0].m_out;
-}
-
-
-/*-------------------------------------------------
- portb_in_get - return port B output value
--------------------------------------------------*/
-
-uint8_t riot6532_device::portb_out_get()
-{
- return m_port[1].m_out;
-}
-
-
-//-------------------------------------------------
-// paN_w - write Port A lines individually
-//-------------------------------------------------
-
-WRITE_LINE_MEMBER(riot6532_device::pa0_w) { porta_in_set(state ? 0x01 : 0x00, 0x01); }
-WRITE_LINE_MEMBER(riot6532_device::pa1_w) { porta_in_set(state ? 0x02 : 0x00, 0x02); }
-WRITE_LINE_MEMBER(riot6532_device::pa2_w) { porta_in_set(state ? 0x04 : 0x00, 0x04); }
-WRITE_LINE_MEMBER(riot6532_device::pa3_w) { porta_in_set(state ? 0x08 : 0x00, 0x08); }
-WRITE_LINE_MEMBER(riot6532_device::pa4_w) { porta_in_set(state ? 0x10 : 0x00, 0x10); }
-WRITE_LINE_MEMBER(riot6532_device::pa5_w) { porta_in_set(state ? 0x20 : 0x00, 0x20); }
-WRITE_LINE_MEMBER(riot6532_device::pa6_w) { porta_in_set(state ? 0x40 : 0x00, 0x40); }
-WRITE_LINE_MEMBER(riot6532_device::pa7_w) { porta_in_set(state ? 0x80 : 0x00, 0x80); }
-
-//-------------------------------------------------
-// pbN_w - write Port B lines individually
-//-------------------------------------------------
-
-WRITE_LINE_MEMBER(riot6532_device::pb0_w) { portb_in_set(state ? 0x01 : 0x00, 0x01); }
-WRITE_LINE_MEMBER(riot6532_device::pb1_w) { portb_in_set(state ? 0x02 : 0x00, 0x02); }
-WRITE_LINE_MEMBER(riot6532_device::pb2_w) { portb_in_set(state ? 0x04 : 0x00, 0x04); }
-WRITE_LINE_MEMBER(riot6532_device::pb3_w) { portb_in_set(state ? 0x08 : 0x00, 0x08); }
-WRITE_LINE_MEMBER(riot6532_device::pb4_w) { portb_in_set(state ? 0x10 : 0x00, 0x10); }
-WRITE_LINE_MEMBER(riot6532_device::pb5_w) { portb_in_set(state ? 0x20 : 0x00, 0x20); }
-WRITE_LINE_MEMBER(riot6532_device::pb6_w) { portb_in_set(state ? 0x40 : 0x00, 0x40); }
-WRITE_LINE_MEMBER(riot6532_device::pb7_w) { portb_in_set(state ? 0x80 : 0x00, 0x80); }
-
-
-//**************************************************************************
-// LIVE DEVICE
-//**************************************************************************
-
-//-------------------------------------------------
-// riot6532_device - constructor
-//-------------------------------------------------
-
-riot6532_device::riot6532_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : device_t(mconfig, RIOT6532, tag, owner, clock),
- m_in_pa_cb(*this),
- m_out_pa_cb(*this),
- m_in_pb_cb(*this),
- m_out_pb_cb(*this),
- m_irq_cb(*this),
- m_irqstate(0),
- m_irqenable(0),
- m_irq(CLEAR_LINE),
- m_pa7dir(0),
- m_pa7prev(0),
- m_timershift(0),
- m_timerstate(0),
- m_timer(nullptr)
-{
- memset(m_port, 0x00, sizeof(m_port));
-}
-
-/*-------------------------------------------------
- device_start - device-specific startup
--------------------------------------------------*/
-
-void riot6532_device::device_start()
-{
- /* resolve callbacks */
- m_in_pa_cb.resolve();
- m_port[0].m_in_cb = &m_in_pa_cb;
- m_out_pa_cb.resolve_safe();
- m_port[0].m_out_cb = &m_out_pa_cb;
- m_in_pb_cb.resolve();
- m_port[1].m_in_cb = &m_in_pb_cb;
- m_out_pb_cb.resolve_safe();
- m_port[1].m_out_cb = &m_out_pb_cb;
- m_irq_cb.resolve_safe();
-
- /* allocate timers */
- m_timer = timer_alloc(TIMER_END_CB);
-
- /* register for save states */
- save_item(NAME(m_port[0].m_in));
- save_item(NAME(m_port[0].m_out));
- save_item(NAME(m_port[0].m_ddr));
- save_item(NAME(m_port[1].m_in));
- save_item(NAME(m_port[1].m_out));
- save_item(NAME(m_port[1].m_ddr));
-
- save_item(NAME(m_irqstate));
- save_item(NAME(m_irqenable));
- save_item(NAME(m_irq));
-
- save_item(NAME(m_pa7dir));
- save_item(NAME(m_pa7prev));
-
- save_item(NAME(m_timershift));
- save_item(NAME(m_timerstate));
-}
-
-
-
-/*-------------------------------------------------
- device_reset - device-specific reset
--------------------------------------------------*/
-
-void riot6532_device::device_reset()
-{
- /* reset I/O states */
- m_port[0].m_in = 0;
- m_port[0].m_out = 0;
- m_port[0].m_ddr = 0;
- m_port[1].m_in = 0;
- m_port[1].m_out = 0;
- m_port[1].m_ddr = 0;
-
- /* reset IRQ states */
- m_irqenable = 0;
- m_irqstate = 0;
- update_irqstate();
-
- /* reset PA7 states */
- m_pa7dir = 0;
- m_pa7prev = 0;
-
- /* reset timer states */
- m_timershift = 10;
- m_timerstate = TIMER_COUNTING;
- m_timer->adjust(attotime::from_ticks(256 << m_timershift, clock()));
-}
-
-void riot6532_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_END_CB:
- timer_end();
- break;
- default:
- throw emu_fatalerror("Unknown id in riot6532_device::device_timer");
- }
-}