/*
 * Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#include <teagba/addresses.hpp>
#include <teagba/bios.hpp>
#include <teagba/irq.hpp>

#include "context.hpp"
#include "turbine.hpp"

namespace turbine {

extern volatile gba_timer_t g_timerMs;
static gba_timer_t g_wakeupTime{};

ox::Error run(Context &ctx) noexcept {
	g_wakeupTime = 0;
	while (ctx.running) {
		if (g_wakeupTime <= g_timerMs && ctx.updateHandler) {
			auto sleepTime = ctx.updateHandler(ctx);
			if (sleepTime >= 0) {
				g_wakeupTime = g_timerMs + static_cast<unsigned>(sleepTime);
			} else {
				g_wakeupTime = ~gba_timer_t(0);
			}
		}
		if constexpr(config::GbaEventLoopTimerBased) {
			// wait for timer interrupt
			teagba_intrwait(
					0,
					teagba::Int_timer0 | teagba::Int_timer1 | teagba::Int_timer2 | teagba::Int_timer3);
		} else {
			teagba_vblankintrwait();
		}
	}
	return {};
}

}
