From 2153fedd8dbe2b409808188dbdf0e1b0eedce36b Mon Sep 17 00:00:00 2001 From: folkert van heusden Date: Mon, 20 May 2024 21:50:14 +0200 Subject: [PATCH] Configurable line hz --- debugger.cpp | 13 +++++++++++++ kw11-l.cpp | 39 +++++++++++++++++++++++++++++++++++---- kw11-l.h | 3 +++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/debugger.cpp b/debugger.cpp index 6aca163..ed529d5 100644 --- a/debugger.cpp +++ b/debugger.cpp @@ -710,6 +710,14 @@ void deserdc11(console *const cnsl, bus *const b) cnsl->put_string_lf(format("Deserialized " SERIAL_CFG_FILE)); } +void set_kw11_l_interrupt_freq(console *const cnsl, bus *const b, const int freq) +{ + if (freq >= 1 && freq < 1000) + b->getKW11_L()->set_interrupt_frequency(freq); + else + cnsl->put_string_lf("Frequency out of range"); +} + void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const stop_event) { int32_t trace_start_addr = -1; @@ -1062,6 +1070,10 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto continue; } #endif + else if (parts[0] == "setinthz" && parts.size() == 2) { + set_kw11_l_interrupt_freq(cnsl, b, std::stoi(parts.at(1))); + continue; + } else if (parts[0] == "setsl" && parts.size() == 3) { if (setloghost(parts.at(1).c_str(), parse_ll(parts[2])) == false) cnsl->put_string_lf("Failed parsing IP address"); @@ -1183,6 +1195,7 @@ void debugger(console *const cnsl, bus *const b, std::atomic_uint32_t *const sto "setpc x - set PC to value", "setmem ... - set memory (a=) to value (v=), both in octal, one byte", "toggle ... - set switch (s=, 0...15 (decimal)) of the front panel to state (t=, 0 or 1)", + "setinthz x - set KW11-L interrupt frequency (Hz)", "cls - clear screen", "dir - list files", "bic x - run BIC/LDA file", diff --git a/kw11-l.cpp b/kw11-l.cpp index 7ea882d..f044f84 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -92,15 +92,31 @@ void kw11_l::operator()() if (*cnsl->get_running_flag()) { myusleep(1000000 / 100); // 100 Hz + int cur_int_freq = 1; + + { +#if defined(BUILD_FOR_RP2040) + xSemaphoreTake(lf_csr_lock, portMAX_DELAY); +#else + std::unique_lock lck(lf_csr_lock); +#endif + + cur_int_freq = int_frequency; + +#if defined(BUILD_FOR_RP2040) + xSemaphoreGive(lf_csr_lock); +#endif + } + uint64_t current_cycle_count = b->getCpu()->get_instructions_executed_count(); uint32_t took_ms = b->getCpu()->get_effective_run_time(current_cycle_count - prev_cycle_count); auto now = get_ms(); - // - 50 Hz depending on instrution count + // - 50 Hz depending on instruction count ('cur_int_freq') // - nothing executed in interval - // - 10 Hz minimum + // - 2 Hz minimum auto t_diff = now - prev_tick; - if (took_ms >= 1000 / 50 || current_cycle_count - interval_prev_cycle_count == 0 || t_diff >= 100) { + if (took_ms >= 1000 / cur_int_freq || current_cycle_count - interval_prev_cycle_count == 0 || t_diff >= 500) { do_interrupt(); prev_cycle_count = current_cycle_count; @@ -137,12 +153,27 @@ uint16_t kw11_l::read_word(const uint16_t a) uint16_t temp = lf_csr; #if defined(BUILD_FOR_RP2040) - xSemaphoreGive(lf_csr_lock); + xSemaphoreGive(lf_csr_lock); #endif return temp; } +void kw11_l::set_interrupt_frequency(const int Hz) +{ +#if defined(BUILD_FOR_RP2040) + xSemaphoreTake(lf_csr_lock, portMAX_DELAY); +#else + std::unique_lock lck(lf_csr_lock); +#endif + + int_frequency = Hz; + +#if defined(BUILD_FOR_RP2040) + xSemaphoreGive(lf_csr_lock); +#endif +} + void kw11_l::write_byte(const uint16_t addr, const uint8_t value) { if (addr != ADDR_LFC) { diff --git a/kw11-l.h b/kw11-l.h index f921bd3..995c482 100644 --- a/kw11-l.h +++ b/kw11-l.h @@ -23,6 +23,7 @@ private: std::thread *th { nullptr }; std::mutex lf_csr_lock; #endif + int int_frequency { 50 }; uint16_t lf_csr { 0 }; int64_t t_diff_sum { 0 }; @@ -43,6 +44,8 @@ public: void show_state(console *const cnsl) const override; + void set_interrupt_frequency(const int Hz); + JsonDocument serialize(); static kw11_l *deserialize(const JsonVariantConst j, bus *const b, console *const cnsl);