forked from arti/vt1200
53 lines
1.3 KiB
C++
53 lines
1.3 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 winner 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;
|
|
|
|
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;
|
|
}
|
|
}
|
|
|
|
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--;
|
|
}
|