Reworked runtime loop

This commit is contained in:
OmniaX-Dev 2026-06-16 04:52:12 +02:00
parent 051a404e42
commit 6d9016cdae
4 changed files with 15 additions and 72 deletions

View file

@ -4,10 +4,10 @@ CMOS = dragon/cmos.dr
cpuext = extmov, extalu
fixed_clock = true
clock_rate_sec = 100
clock_rate_sec = 5000
memory_extension_pages = 16
screen_redraw_rate_per_second = 10
screen_redraw_rate_per_second = 30
SingleColor_foreground = #009900FF
SingleColor_background = #111111FF

Binary file not shown.

View file

@ -300,81 +300,31 @@ namespace dragon
machine_config.destroy();
}
void DragonRuntime::runMachine2(void)
void DragonRuntime::runMachine(void)
{
f64 clock_speed_us = 1000000.0 / machine_config.clock_rate_sec;
f64 acc = 0;
f64 acc2 = 0;
u64 avg_count = 0;
u64 _time = 0;
f64 avg_tot = 0;
ostd::Counter clock_timer;
bool running = true;
bool fixed_clock = machine_config.fixed_clock;
ostd::Counter _timer;
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
f64 cycleUPS = (machine_config.fixed_clock ? machine_config.clock_rate_sec : -1.0);
ostd::StepTimer cycleTimer(cycleUPS, [&](f64 dt) {
vDisplay.mainLoop();
running = cpu.execute() && vDisplay.isRunning();
vDiskInterface.cycleStep();
});
ostd::StepTimer screenTimer(screenRedrawRate, [&](f64 dt) {
vDisplay.redrawScreen();
});
while (running || vDiskInterface.isBusy())
{
clock_timer.startCount(ostd::eTimeUnits::Microseconds);
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
running = cpu.execute() && vDisplay.isRunning();
vDisplay.mainLoop();
vDiskInterface.cycleStep();
cycleTimer.update();
screenTimer.update();
if (dragon::data::ErrorHandler::hasError())
{
processErrors();
break;
}
if (acc == 500)
{
avg_count++;
avg_tot += _time;
s_avgInstTime = (u64)std::round(avg_tot / avg_count);
acc = 0;
}
if (acc2 == (1000.0 / screenRedrawRate))
{
vDisplay.redrawScreen();
acc2 = 0;
}
_time = clock_timer.endCount();
acc++;
acc2++;
if (_time < clock_speed_us && fixed_clock)
ostd::Time::sleep(clock_speed_us - _time, ostd::eTimeUnits::Microseconds);
}
}
void DragonRuntime::runMachine(void)
{
bool running = true;
ostd::StepTimer cycleTimer(machine_config.clock_rate_sec, [&](f64 dt) {
running = runStep();
});
while (running)
{
cycleTimer.update();
}
}
bool DragonRuntime::runStep(void)
{
bool running = cpu.execute() && vDisplay.isRunning();
u8 screenRedrawRate = vCMOS.read8(data::CMOSRegisters::ScreenRedrawRate);
vDisplay.mainLoop();
if (s_enableScreenRedrawDelay && s_stepAcc2 == (1000.0 / screenRedrawRate))
{
vDisplay.redrawScreen();
s_stepAcc2 = 0;
}
else if (!s_enableScreenRedrawDelay)
{
vDisplay.redrawScreen();
}
s_stepAcc2++;
vDiskInterface.cycleStep();
return running || vDiskInterface.isBusy();
}
void DragonRuntime::forceLoad(const String& filePath, u16 loadAddress)
{
ostd::ByteStream code;

View file

@ -47,13 +47,10 @@ namespace dragon
static i32 initMachine(const tRuntimeInitInfo& info);
static void shutdownMachine(void);
static void runMachine(void);
static void runMachine2(void);
static bool runStep(void);
static void forceLoad(const String& filePath, u16 loadAddress);
inline static bool hasError(void) { return data::ErrorHandler::hasError(); }
inline static ostd::ConsoleOutputHandler& output(void) { return out; }
inline static u64 getAvgClockSpeed(void) { return (u64)std::round(1000000.0 / s_avgInstTime); }
private:
static void __print_application_help(void);
@ -80,10 +77,6 @@ namespace dragon
inline static tMachineConfig machine_config;
inline static u64 s_avgInstTime { 0 };
inline static f64 s_stepAcc2 { 0 };
inline static bool s_enableScreenRedrawDelay { true };
private:
inline static SignalListener s_signalListener;