Files
vt1200/harness/mame/vt1200_board.cpp
T

71 lines
1.9 KiB
C++

#include "vt1200_board.h"
bool vt1200_board::is_switch_port(uint32_t addr) const
{
// The monitor-selection switch lives in bits 4-6 of window 3's +0xD0
// register (harness offset 0x0d).
return addr == (VT1200_WIN3 + VT1200_OFF_SWITCH);
}
uint16_t vt1200_board::read(uint32_t addr)
{
auto ov = m_override.find(addr);
if (ov != m_override.end())
return ov->second;
uint16_t value = m_default;
auto st = m_store.find(addr);
if (st != m_store.end())
value = st->second;
// DMA command port: while a command is in flight the port reads back the
// latched command; once the configured ticks elapse it reads back 0.
if (m_dma_ticks > 0 && (addr & 0xffff0000) == VT1200_WIN1)
return (m_dma_left > 0) ? m_dma_cmd : (uint16_t)0x0000;
if (m_switch_set && is_switch_port(addr))
return (uint16_t)((value & 0xff8f) | (m_switch_bits & 0x0070));
if (m_handshake && (addr & 0xffff) == VT1200_OFF_STATUS)
{
auto busy = m_busy_left.find(addr & 0xffff0000);
if (busy != m_busy_left.end() && busy->second > 0)
value |= 0x0001;
else
value &= ~0x0001;
}
return value;
}
void vt1200_board::write(uint32_t addr, uint16_t data)
{
m_store[addr] = data;
if (m_handshake && (addr & 0xffff) == VT1200_OFF_CMD)
{
const uint32_t win = addr & 0xffff0000;
auto ticks = m_busy_ticks_by_win.find(win);
m_busy_left[win] = (ticks != m_busy_ticks_by_win.end()) ? ticks->second : 0;
}
// A command written to the DMA command port (WIN1) is latched and, when the
// DMA model is configured, starts its completion timer.
if ((addr & 0xffff0000) == VT1200_WIN1)
{
m_dma_cmd = data;
if (m_dma_ticks > 0)
m_dma_left = m_dma_ticks;
}
}
void vt1200_board::tick()
{
// Advance every window's state machine, not just the one last touched.
for (auto &entry : m_busy_left)
if (entry.second > 0)
entry.second--;
// Merge the DMA pair's timer into the same tick.
if (m_dma_left > 0)
m_dma_left--;
}