/* * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #include #include #include #include "addresses.hpp" #include "bios.hpp" #include "irq.hpp" #include "core.hpp" extern "C" void isr(); namespace nostalgia::core { // Timer Consts constexpr int NanoSecond = 1000000000; constexpr int MilliSecond = 1000; constexpr int TicksMs59ns = 65535 - (NanoSecond / MilliSecond) / 59.59; extern UpdateHandler g_updateHandler; extern volatile gba_timer_t g_timerMs; static void initIrq() noexcept { REG_ISR = isr; REG_IME = 1; // enable interrupts } static void initTimer() noexcept { // make timer0 a ~1 millisecond timer REG_TIMER0 = TicksMs59ns; REG_TIMER0CTL = 0b11000000; // enable interrupt for timer0 REG_IE = REG_IE | Int_timer0; } static ox::Result findPreloadSection() noexcept { // put the header in the wrong order to prevent mistaking this code for the // media section constexpr auto headerP2 = "D_HEADER________"; constexpr auto headerP1 = "NOSTALGIA_PRELOA"; constexpr auto headerP1Len = ox_strlen(headerP2); constexpr auto headerP2Len = ox_strlen(headerP1); constexpr auto headerLen = headerP1Len + headerP2Len; for (auto current = MEM_ROM; current < reinterpret_cast(0x0a000000); current += headerLen) { if (ox_memcmp(current, headerP1, headerP1Len) == 0 && ox_memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) { return reinterpret_cast(current + headerLen); } } return OxError(1); } ox::Result> init(ox::UniquePtr fs, ox::CRStringView appName) noexcept { auto ctx = ox::make_unique(); ctx->rom = std::move(fs); ctx->appName = appName; oxReturnError(initGfx(ctx.get())); initTimer(); initIrq(); oxReturnError(findPreloadSection().moveTo(&ctx->preloadSectionOffset)); return ctx; } void setUpdateHandler(Context*, UpdateHandler h) noexcept { g_updateHandler = h; } uint64_t ticksMs(Context*) noexcept { return g_timerMs; } bool buttonDown(Context*, Key k) noexcept { return k <= Key::GamePad_L && !(REG_GAMEPAD & (1 << static_cast(k))); } void shutdown(Context *ctx) noexcept { ctx->running = false; } }