[nostalgia/core] Add ticksMs() function

This commit is contained in:
Gary Talent 2020-07-14 01:07:07 -05:00
parent af494072fb
commit 745ea4a0ed
10 changed files with 74 additions and 48 deletions

View File

@ -11,5 +11,6 @@
namespace nostalgia::core::config {
constexpr auto GbaSpriteBufferLen = 128;
constexpr auto GbaTimerBits = 64;
}

View File

@ -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();
}

View File

@ -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

View File

@ -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<volatile uint32_t*>(0x04000004)
#define REG_VCOUNT *reinterpret_cast<volatile uint32_t*>(0x04000006)
/////////////////////////////////////////////////////////////////
// Timers
#define REG_TIMER0CTL *reinterpret_cast<volatile uint16_t*>(0x04000100)
#define REG_TIMER0 *reinterpret_cast<volatile uint16_t*>(0x04000102)
#define REG_TIMER1CTL *reinterpret_cast<volatile uint16_t*>(0x04000104)
#define REG_TIMER1 *reinterpret_cast<volatile uint16_t*>(0x04000106)
#define REG_TIMER2CTL *reinterpret_cast<volatile uint16_t*>(0x04000108)
#define REG_TIMER2 *reinterpret_cast<volatile uint16_t*>(0x0400010a)
#define REG_TIMER3CTL *reinterpret_cast<volatile uint16_t*>(0x0400010c)
#define REG_TIMER3 *reinterpret_cast<volatile uint16_t*>(0x0400010e)
/////////////////////////////////////////////////////////////////
// background registers

View File

@ -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 <nostalgia/core/config.hpp>
#include <nostalgia/core/core.hpp>
#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<config::GbaTimerBits> 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;
}
}

View File

@ -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<uint16_t>(y & ox::onMask<uint8_t>(7))
| (static_cast<uint16_t>(1) << 10); // enable alpha
oa.attr1 = static_cast<uint16_t>(x) & ox::onMask<uint8_t>(8);
oa.attr2 = static_cast<uint16_t>(tileIdx & ox::onMask<uint16_t>(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

View File

@ -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 <nostalgia/core/config.hpp>
#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() {

View File

@ -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);
}
}

View File

@ -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 <nostalgia/core/context.hpp>
#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);
}

View File

@ -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();;
}
}