mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
harness: per-window busy state machines for the big windows
This commit is contained in:
1 parent
db2caa5558
commit
66fe15367b
3 files changed
+46
-7
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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--;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
Reference in new issue
Block a user