From 745ea4a0edb302998315dc4a4f5dafdf55b647ea Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Tue, 14 Jul 2020 01:07:07 -0500 Subject: [PATCH] [nostalgia/core] Add ticksMs() function --- src/nostalgia/core/config.hpp | 1 + src/nostalgia/core/core.hpp | 6 ++++- src/nostalgia/core/gba/CMakeLists.txt | 1 - src/nostalgia/core/gba/addresses.hpp | 17 +++++++++++++- src/nostalgia/core/gba/core.cpp | 33 +++++++++++++++++++++++++-- src/nostalgia/core/gba/gfx.cpp | 14 +++++++++--- src/nostalgia/core/gba/irq.arm.cpp | 7 +++--- src/nostalgia/core/gba/irq.cpp | 29 ----------------------- src/nostalgia/core/gba/irq.hpp | 8 +------ src/nostalgia/core/sdl/core.cpp | 6 ++++- 10 files changed, 74 insertions(+), 48 deletions(-) delete mode 100644 src/nostalgia/core/gba/irq.cpp diff --git a/src/nostalgia/core/config.hpp b/src/nostalgia/core/config.hpp index 5e977f8c..17d65406 100644 --- a/src/nostalgia/core/config.hpp +++ b/src/nostalgia/core/config.hpp @@ -11,5 +11,6 @@ namespace nostalgia::core::config { constexpr auto GbaSpriteBufferLen = 128; +constexpr auto GbaTimerBits = 64; } diff --git a/src/nostalgia/core/core.hpp b/src/nostalgia/core/core.hpp index ef4b749b..5d3f8143 100644 --- a/src/nostalgia/core/core.hpp +++ b/src/nostalgia/core/core.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -20,4 +20,8 @@ namespace nostalgia::core { [[nodiscard]] ox::Error run(Context *ctx); +// Returns the number of milliseconds that have passed since the start of the +// program. +[[nodiscard]] uint64_t ticksMs(); + } diff --git a/src/nostalgia/core/gba/CMakeLists.txt b/src/nostalgia/core/gba/CMakeLists.txt index 7f7cd31d..0f5ffcaf 100644 --- a/src/nostalgia/core/gba/CMakeLists.txt +++ b/src/nostalgia/core/gba/CMakeLists.txt @@ -6,7 +6,6 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA") core.cpp gfx.cpp irq.arm.cpp - irq.cpp irq.s media.cpp panic.cpp diff --git a/src/nostalgia/core/gba/addresses.hpp b/src/nostalgia/core/gba/addresses.hpp index d27bf51a..41918259 100644 --- a/src/nostalgia/core/gba/addresses.hpp +++ b/src/nostalgia/core/gba/addresses.hpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -26,6 +26,21 @@ using interrupt_handler = void (*)(void); #define REG_DISPSTAT *reinterpret_cast(0x04000004) #define REG_VCOUNT *reinterpret_cast(0x04000006) +///////////////////////////////////////////////////////////////// +// Timers + +#define REG_TIMER0CTL *reinterpret_cast(0x04000100) +#define REG_TIMER0 *reinterpret_cast(0x04000102) + +#define REG_TIMER1CTL *reinterpret_cast(0x04000104) +#define REG_TIMER1 *reinterpret_cast(0x04000106) + +#define REG_TIMER2CTL *reinterpret_cast(0x04000108) +#define REG_TIMER2 *reinterpret_cast(0x0400010a) + +#define REG_TIMER3CTL *reinterpret_cast(0x0400010c) +#define REG_TIMER3 *reinterpret_cast(0x0400010e) + ///////////////////////////////////////////////////////////////// // background registers diff --git a/src/nostalgia/core/gba/core.cpp b/src/nostalgia/core/gba/core.cpp index 46f9a7f7..a751810a 100644 --- a/src/nostalgia/core/gba/core.cpp +++ b/src/nostalgia/core/gba/core.cpp @@ -1,20 +1,45 @@ /* - * Copyright 2016 - 2019 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include #include +#include "addresses.hpp" #include "irq.hpp" +extern "C" void isr(); + namespace nostalgia::core { +// Timer Consts +constexpr auto NanoSecond = 1000000000; +constexpr auto MilliSecond = 1000; +constexpr int TicksMs59ns = (NanoSecond / MilliSecond) / 59.59; + +extern volatile ox::Uint g_timerMs; + +static void initIrq() { + REG_ISR = isr; + REG_IME = 1; // enable interrupts +} + +static void initTimer() { + // make timer0 a ~1 millisecond timer + REG_TIMER0 = TicksMs59ns; + REG_TIMER0CTL = 0b11000011; + // enable interrupt for timer0 + REG_IE |= Int_timer0; +} + ox::Error init(Context *ctx) { oxReturnError(initGfx(ctx)); - oxReturnError(initIrq(ctx)); + initTimer(); + initIrq(); return OxError(0); } @@ -24,4 +49,8 @@ ox::Error run(Context*) { return OxError(0); } +uint64_t ticksMs() { + return g_timerMs; +} + } diff --git a/src/nostalgia/core/gba/gfx.cpp b/src/nostalgia/core/gba/gfx.cpp index f0a4f41f..48a2ce44 100644 --- a/src/nostalgia/core/gba/gfx.cpp +++ b/src/nostalgia/core/gba/gfx.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -21,6 +21,10 @@ namespace nostalgia::core { constexpr auto GbaTileColumns = 32; +constexpr uint16_t DispStat_irq_vblank = 1 << 3; +constexpr uint16_t DispStat_irq_hblank = 1 << 4; +constexpr uint16_t DispStat_irq_vcount = 1 << 5; + struct GbaPaletteTarget { static constexpr auto TypeName = NostalgiaPalette::TypeName; static constexpr auto Fields = NostalgiaPalette::Fields; @@ -87,6 +91,10 @@ ox::Error initGfx(Context*) { /* Objects -----\||| */ /* |||| */ REG_DISPCNT = 0x1101; + // tell display to trigger vblank interrupts + REG_DISPSTAT |= DispStat_irq_vblank; + // enable vblank interrupt + REG_IE |= Int_vblank; return OxError(0); } @@ -202,14 +210,14 @@ void setTile(Context*, int layer, int column, int row, uint8_t tile) { } void setSprite(unsigned idx, unsigned x, unsigned y, unsigned tileIdx) { - // block until g_spriteUpdates is less than buffer len - while (g_spriteUpdates >= config::GbaSpriteBufferLen); GbaSpriteAttrUpdate oa; oa.attr0 = static_cast(y & ox::onMask(7)) | (static_cast(1) << 10); // enable alpha oa.attr1 = static_cast(x) & ox::onMask(8); oa.attr2 = static_cast(tileIdx & ox::onMask(8)); oa.idx = idx; + // block until g_spriteUpdates is less than buffer len + while (g_spriteUpdates >= config::GbaSpriteBufferLen); REG_IE &= ~Int_vblank; // disable vblank interrupt handler g_spriteBuffer[g_spriteUpdates++] = oa; REG_IE |= Int_vblank; // enable vblank interrupt handler diff --git a/src/nostalgia/core/gba/irq.arm.cpp b/src/nostalgia/core/gba/irq.arm.cpp index 8d96232c..4582315b 100644 --- a/src/nostalgia/core/gba/irq.arm.cpp +++ b/src/nostalgia/core/gba/irq.arm.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2020 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -9,8 +9,6 @@ // NOTE: this file is compiled as ARM and not THUMB, so don't but too much in // here -#include - #include "addresses.hpp" #include "gfx.hpp" #include "irq.hpp" @@ -20,6 +18,8 @@ namespace nostalgia::core { volatile uint16_t g_spriteUpdates = 0; GbaSpriteAttrUpdate g_spriteBuffer[config::GbaSpriteBufferLen]; +volatile uint32_t g_timerMs = 0; + } using namespace nostalgia::core; @@ -39,6 +39,7 @@ void nostalgia_core_isr_vblank() { } void nostalgia_core_isr_timer0() { + ++g_timerMs; } void nostalgia_core_isr_timer1() { diff --git a/src/nostalgia/core/gba/irq.cpp b/src/nostalgia/core/gba/irq.cpp deleted file mode 100644 index dfb5d8a9..00000000 --- a/src/nostalgia/core/gba/irq.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2016 - 2020 gtalent2@gmail.com - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - */ - -#include "irq.hpp" - -extern "C" void isr(); - -namespace nostalgia::core { - -constexpr uint16_t DispStat_irq_vblank = 1 << 3; -constexpr uint16_t DispStat_irq_hblank = 1 << 4; -constexpr uint16_t DispStat_irq_vcount = 1 << 5; - -ox::Error initIrq(Context*) { - REG_ISR = isr; - // tell display to trigger vblank interrupts - REG_DISPSTAT |= DispStat_irq_vblank; - // tell proc which interrupts to handle - REG_IE |= Int_vblank; - REG_IME = 1; - return OxError(0); -} - -} diff --git a/src/nostalgia/core/gba/irq.hpp b/src/nostalgia/core/gba/irq.hpp index a9b7e247..e753e8db 100644 --- a/src/nostalgia/core/gba/irq.hpp +++ b/src/nostalgia/core/gba/irq.hpp @@ -1,15 +1,11 @@ /* - * Copyright 2016 - 2020 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#include - -#include "addresses.hpp" - namespace nostalgia::core { constexpr uint16_t Int_vblank = 1 << 0; @@ -29,6 +25,4 @@ constexpr uint16_t Int_dma5 = 1 << 13; constexpr uint16_t Int_input = 1 << 14; // gamepad constexpr uint16_t Int_cart = 1 << 15; // cartridge removed -[[nodiscard]] ox::Error initIrq(Context *ctx); - } diff --git a/src/nostalgia/core/sdl/core.cpp b/src/nostalgia/core/sdl/core.cpp index ee583a14..daa470ad 100644 --- a/src/nostalgia/core/sdl/core.cpp +++ b/src/nostalgia/core/sdl/core.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2016 - 2019 gtalent2@gmail.com + * Copyright 2016 - 2020 gary@drinkingtea.net * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -41,4 +41,8 @@ ox::Error run(Context *ctx) { return OxError(0); } +uint64_t ticksMs() { + return SDL_GetTicks();; +} + }