diff --git a/cpu.cpp b/cpu.cpp index 103dc01..2cdc883 100644 --- a/cpu.cpp +++ b/cpu.cpp @@ -18,6 +18,12 @@ #define IS_0(x, wm) ((wm) == wm_byte ? ((x) & 0xff) == 0 : (x) == 0) +// see https://retrocomputing.stackexchange.com/questions/6960/what-was-the-clock-speed-and-ips-for-the-original-pdp-11 +constexpr const double pdp11_clock_cycle = 150; // ns, for the 11/70 +constexpr const double pdp11_MHz = 1000.0 / pdp11_clock_cycle; +constexpr const double pdp11_avg_cycles_per_instruction = (1 + 5) / 2.0; +constexpr const double pdp11_estimated_mips = pdp11_MHz / pdp11_avg_cycles_per_instruction; + cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event) { reset(); @@ -97,15 +103,15 @@ std::tuple cpu::get_mips_rel_speed(c double mips = t_diff ? instr_count / double(t_diff) : 0; - // see https://retrocomputing.stackexchange.com/questions/6960/what-was-the-clock-speed-and-ips-for-the-original-pdp-11 - constexpr double pdp11_clock_cycle = 150; // ns, for the 11/70 - constexpr double pdp11_MHz = 1000.0 / pdp11_clock_cycle; - constexpr double pdp11_avg_cycles_per_instruction = (1 + 5) / 2.0; - constexpr double pdp11_estimated_mips = pdp11_MHz / pdp11_avg_cycles_per_instruction; - return { mips, mips * 100 / pdp11_estimated_mips, instr_count, t_diff, wait_time }; } +uint32_t cpu::get_effective_run_time(const uint64_t instruction_count) const +{ + // division is to go from ns to ms + return instruction_count * pdp11_clock_cycle / 1000000l; +} + void cpu::add_to_stack_trace(const uint16_t p) { auto da = disassemble(p); diff --git a/cpu.h b/cpu.h index 9c5c40f..56e37eb 100644 --- a/cpu.h +++ b/cpu.h @@ -133,6 +133,8 @@ public: uint64_t get_instructions_executed_count() const; uint64_t get_wait_time() const { return wait_time; } std::tuple get_mips_rel_speed(const std::optional & instruction_count, const std::optional & t_diff_1s) const; + // how many ms would've really passed when executing `instruction_count` instructions + uint32_t get_effective_run_time(const uint64_t instruction_count) const; bool get_debug() const { return debug_mode; } void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); } diff --git a/kw11-l.cpp b/kw11-l.cpp index 2d23054..6114ee7 100644 --- a/kw11-l.cpp +++ b/kw11-l.cpp @@ -68,22 +68,26 @@ void kw11_l::operator()() TRACE("Starting KW11-L thread"); + uint64_t prev_cycle_count = b->getCpu()->get_instructions_executed_count(); + while(!stop_flag) { if (*cnsl->get_running_flag()) { - set_lf_crs_b7(); - - if (get_lf_crs() & 64) - b->getCpu()->queue_interrupt(6, 0100); + myusleep(1000000 / 100); // 100 Hz - // TODO: depending on cpu cycles processed -#if defined(ESP32) - myusleep(1000000 / 20); // 50ms -#else - myusleep(1000000 / 50); // 20ms -#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); + + if (took_ms >= 1000 / 50) { + set_lf_crs_b7(); + + if (get_lf_crs() & 64) + b->getCpu()->queue_interrupt(6, 0100); + + prev_cycle_count = current_cycle_count; + } } else { - myusleep(1000000 / 10); // 100ms + myusleep(1000000 / 10); // 10 Hz } }