KW11-L pulse-rate now depends on the (estimated) cycle count

This commit is contained in:
folkert van heusden 2024-05-09 15:27:48 +02:00
parent 88ffa23731
commit a473a5b15d
Signed by untrusted user who does not match committer: folkert
GPG key ID: 6B6455EDFEED3BD1
3 changed files with 29 additions and 17 deletions

18
cpu.cpp
View file

@ -18,6 +18,12 @@
#define IS_0(x, wm) ((wm) == wm_byte ? ((x) & 0xff) == 0 : (x) == 0) #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) cpu::cpu(bus *const b, std::atomic_uint32_t *const event) : b(b), event(event)
{ {
reset(); reset();
@ -97,15 +103,15 @@ std::tuple<double, double, uint64_t, uint32_t, double> cpu::get_mips_rel_speed(c
double mips = t_diff ? instr_count / double(t_diff) : 0; 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 }; 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) void cpu::add_to_stack_trace(const uint16_t p)
{ {
auto da = disassemble(p); auto da = disassemble(p);

2
cpu.h
View file

@ -133,6 +133,8 @@ public:
uint64_t get_instructions_executed_count() const; uint64_t get_instructions_executed_count() const;
uint64_t get_wait_time() const { return wait_time; } uint64_t get_wait_time() const { return wait_time; }
std::tuple<double, double, uint64_t, uint32_t, double> get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & t_diff_1s) const; std::tuple<double, double, uint64_t, uint32_t, double> get_mips_rel_speed(const std::optional<uint64_t> & instruction_count, const std::optional<uint64_t> & 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; } bool get_debug() const { return debug_mode; }
void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); } void set_debug(const bool d) { debug_mode = d; stacktrace.clear(); }

View file

@ -68,22 +68,26 @@ void kw11_l::operator()()
TRACE("Starting KW11-L thread"); TRACE("Starting KW11-L thread");
uint64_t prev_cycle_count = b->getCpu()->get_instructions_executed_count();
while(!stop_flag) { while(!stop_flag) {
if (*cnsl->get_running_flag()) { if (*cnsl->get_running_flag()) {
myusleep(1000000 / 100); // 100 Hz
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(); set_lf_crs_b7();
if (get_lf_crs() & 64) if (get_lf_crs() & 64)
b->getCpu()->queue_interrupt(6, 0100); b->getCpu()->queue_interrupt(6, 0100);
// TODO: depending on cpu cycles processed prev_cycle_count = current_cycle_count;
#if defined(ESP32) }
myusleep(1000000 / 20); // 50ms
#else
myusleep(1000000 / 50); // 20ms
#endif
} }
else { else {
myusleep(1000000 / 10); // 100ms myusleep(1000000 / 10); // 10 Hz
} }
} }