harness: per-window busy state machines for the big windows

This commit is contained in:
SDD committed 2026-10-16 01:52:06 +03:00
1 parent db2caa5558
commit 66fe15367b
3 files changed
+46 -7

No files matched your search

+18
View File
@@ -49,6 +49,23 @@ static void test_busy_bit_arms_on_write_and_clears(void)
CHECK((b.read(status) & 0x0001) == 0x0000); // done
}
static void test_windows_are_independent(void)
{
vt1200_board b;
b.set_model_handshake(true);
b.set_window_busy_ticks(VT1200_WIN2, 1);
b.set_window_busy_ticks(VT1200_WIN3, 3);
b.write(VT1200_WIN2 + VT1200_OFF_CMD, 0x0001);
b.write(VT1200_WIN3 + VT1200_OFF_CMD, 0x0001);
CHECK((b.read(VT1200_WIN2 + VT1200_OFF_STATUS) & 1) == 1);
CHECK((b.read(VT1200_WIN3 + VT1200_OFF_STATUS) & 1) == 1);
b.tick();
CHECK((b.read(VT1200_WIN2 + VT1200_OFF_STATUS) & 1) == 0); // WIN2 finished
CHECK((b.read(VT1200_WIN3 + VT1200_OFF_STATUS) & 1) == 1); // WIN3 still busy
}
static void test_monitor_switch_accepts_raw_bits_or_position(void)
{
vt1200_board raw;
@@ -75,6 +92,7 @@ int main(void)
test_override_read();
test_monitor_switch_is_mixed_with_latches();
test_busy_bit_arms_on_write_and_clears();
test_windows_are_independent();
test_monitor_switch_accepts_raw_bits_or_position();
test_switch_mix_only_when_configured();
std::printf(failures ? "%d FAILURE(S)\n" : "all board tests passed\n", failures);
+11 -4
View File
@@ -23,7 +23,8 @@ uint16_t vt1200_board::read(uint32_t addr)
if (m_handshake && (addr & 0xffff) == VT1200_OFF_STATUS)
{
if (m_busy_left > 0)
auto busy = m_busy_left.find(addr & 0xffff0000);
if (busy != m_busy_left.end() && busy->second > 0)
value |= 0x0001;
else
value &= ~0x0001;
@@ -35,11 +36,17 @@ void vt1200_board::write(uint32_t addr, uint16_t data)
{
m_store[addr] = data;
if (m_handshake && (addr & 0xffff) == VT1200_OFF_CMD)
m_busy_left = m_busy_ticks;
{
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()
{
if (m_busy_left > 0)
m_busy_left--;
// Advance every window's state machine, not just the one last touched.
for (auto &entry : m_busy_left)
if (entry.second > 0)
entry.second--;
}
+17 -3
View File
@@ -40,7 +40,18 @@ public:
void set_default(uint16_t v) { m_default = v; }
void set_override(uint32_t addr, uint16_t v) { m_override[addr] = v; }
void set_model_handshake(bool on) { m_handshake = on; }
void set_busy_ticks(int n) { m_busy_ticks = n; }
// Per-window busy counts. Each of the four windows owns its own count, so
// the two big windows (0x06200000 and 0x06400000) can be tuned
// independently. set_busy_ticks is shorthand that applies to every window.
void set_busy_ticks(int n)
{
m_busy_ticks_by_win[VT1200_WIN0] = n;
m_busy_ticks_by_win[VT1200_WIN1] = n;
m_busy_ticks_by_win[VT1200_WIN2] = n;
m_busy_ticks_by_win[VT1200_WIN3] = n;
}
void set_window_busy_ticks(uint32_t window_base, int n) { m_busy_ticks_by_win[window_base] = n; }
// Monitor switch (bits 4-6 of the switch port). The argument is accepted
// unambiguously as EITHER the raw register bits (e.g. 0x70) OR a small
@@ -66,8 +77,11 @@ private:
std::map<uint32_t, uint16_t> m_override; // fixed values (experiments)
uint16_t m_default = 0;
bool m_handshake = false;
int m_busy_ticks = 0;
int m_busy_left = 0;
// Busy state machines, keyed by window base (addr & 0xffff0000): how many
// ticks each window stays busy after a command write, and the remaining
// count for the command currently in flight.
std::map<uint32_t, int> m_busy_ticks_by_win;
std::map<uint32_t, int> m_busy_left;
bool m_switch_set = false; // set_monitor_switch was called
uint16_t m_switch_bits = 0;
};