[nostalgia] Break part of core out into Turbine and TeaGBA libraries

This commit is contained in:
2023-06-01 23:22:31 -05:00
parent 07284ac595
commit 8c43baedea
119 changed files with 1918 additions and 1873 deletions

107
deps/teagba/include/teagba/addresses.hpp vendored Normal file
View File

@ -0,0 +1,107 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/std/array.hpp>
#include <ox/std/types.hpp>
/////////////////////////////////////////////////////////////////
// Interrupt Handler
using interrupt_handler = void (*)();
#define REG_ISR *reinterpret_cast<interrupt_handler*>(0x0300'7FFC)
#define REG_IE *reinterpret_cast<volatile uint16_t*>(0x0400'0200)
#define REG_IF *reinterpret_cast<volatile uint16_t*>(0x0400'0202)
#define REG_IME *reinterpret_cast<volatile uint16_t*>(0x0400'0208)
/////////////////////////////////////////////////////////////////
// Display Registers
#define REG_DISPCTL *reinterpret_cast<volatile uint32_t*>(0x0400'0000)
#define REG_DISPSTAT *reinterpret_cast<volatile uint32_t*>(0x0400'0004)
#define REG_VCOUNT *reinterpret_cast<volatile uint32_t*>(0x0400'0006)
/////////////////////////////////////////////////////////////////
// Timers
#define REG_TIMER0 *reinterpret_cast<volatile uint16_t*>(0x0400'0100)
#define REG_TIMER0CTL *reinterpret_cast<volatile uint16_t*>(0x0400'0102)
#define REG_TIMER1 *reinterpret_cast<volatile uint16_t*>(0x0400'0104)
#define REG_TIMER1CTL *reinterpret_cast<volatile uint16_t*>(0x0400'0106)
#define REG_TIMER2 *reinterpret_cast<volatile uint16_t*>(0x0400'0108)
#define REG_TIMER2CTL *reinterpret_cast<volatile uint16_t*>(0x0400'010a)
#define REG_TIMER3 *reinterpret_cast<volatile uint16_t*>(0x0400'010c)
#define REG_TIMER3CTL *reinterpret_cast<volatile uint16_t*>(0x0400'010e)
/////////////////////////////////////////////////////////////////
// background registers
// background control registers
using BgCtl = uint16_t;
#define REG_BG0CTL *reinterpret_cast<volatile BgCtl*>(0x0400'0008)
#define REG_BG1CTL *reinterpret_cast<volatile BgCtl*>(0x0400'000a)
#define REG_BG2CTL *reinterpret_cast<volatile BgCtl*>(0x0400'000c)
#define REG_BG3CTL *reinterpret_cast<volatile BgCtl*>(0x0400'000e)
[[nodiscard]]
inline auto &regBgCtl(auto bgIdx) noexcept {
return *reinterpret_cast<volatile BgCtl*>(0x0400'0008 + 2 * bgIdx);
}
// background horizontal scrolling registers
#define REG_BG0HOFS *reinterpret_cast<volatile uint32_t*>(0x0400'0010)
#define REG_BG1HOFS *reinterpret_cast<volatile uint32_t*>(0x0400'0014)
#define REG_BG2HOFS *reinterpret_cast<volatile uint32_t*>(0x0400'0018)
#define REG_BG3HOFS *reinterpret_cast<volatile uint32_t*>(0x0400'001c)
[[nodiscard]]
inline volatile auto &regBgHofs(auto bgIdx) noexcept {
return *reinterpret_cast<volatile uint32_t*>(0x0400'0010 + 4 * bgIdx);
}
// background vertical scrolling registers
#define REG_BG0VOFS *reinterpret_cast<volatile uint32_t*>(0x0400'0012)
#define REG_BG1VOFS *reinterpret_cast<volatile uint32_t*>(0x0400'0016)
#define REG_BG2VOFS *reinterpret_cast<volatile uint32_t*>(0x0400'001a)
#define REG_BG3VOFS *reinterpret_cast<volatile uint32_t*>(0x0400'001e)
[[nodiscard]]
inline volatile auto &regBgVofs(auto bgIdx) noexcept {
return *reinterpret_cast<volatile uint32_t*>(0x0400'0012 + 4 * bgIdx);
}
/////////////////////////////////////////////////////////////////
// User Input
#define REG_GAMEPAD *reinterpret_cast<volatile uint16_t*>(0x0400'0130)
/////////////////////////////////////////////////////////////////
// Memory Addresses
#define MEM_EWRAM_BEGIN reinterpret_cast<uint8_t*>(0x0200'0000)
#define MEM_EWRAM_END reinterpret_cast<uint8_t*>(0x0203'FFFF)
#define MEM_IWRAM_BEGIN reinterpret_cast<uint8_t*>(0x0300'0000)
#define MEM_IWRAM_END reinterpret_cast<uint8_t*>(0x0300'7FFF)
#define REG_BLNDCTL *reinterpret_cast<uint16_t*>(0x0400'0050)
#define MEM_BG_PALETTE reinterpret_cast<uint16_t*>(0x0500'0000)
#define MEM_SPRITE_PALETTE reinterpret_cast<uint16_t*>(0x0500'0200)
using BgMapTile = ox::Array<uint16_t, 8192>;
#define MEM_BG_TILES reinterpret_cast<BgMapTile*>(0x0600'0000)
#define MEM_BG_MAP reinterpret_cast<BgMapTile*>(0x0600'e000)
#define MEM_SPRITE_TILES reinterpret_cast<uint16_t*>(0x0601'0000)
#define MEM_OAM reinterpret_cast<uint64_t*>(0x0700'0000)
#define MEM_ROM reinterpret_cast<char*>(0x0800'0000)
#define MEM_SRAM reinterpret_cast<char*>(0x0e00'0000)
#define MEM_SRAM_SIZE 65535

22
deps/teagba/include/teagba/bios.hpp vendored Normal file
View File

@ -0,0 +1,22 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
// Functions for accessing BIOS calls
extern "C" {
// waits for any interrupt
void teagba_halt();
void teagba_stop();
// waits for interrupts specified in interSubs
void teagba_intrwait(unsigned discardExistingIntrs, unsigned intrSubs);
// waits for vblank interrupt
void teagba_vblankintrwait();
}

46
deps/teagba/include/teagba/gfx.hpp vendored Normal file
View File

@ -0,0 +1,46 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include <ox/std/array.hpp>
#include <ox/std/stddef.hpp>
#include <ox/std/types.hpp>
namespace teagba {
enum DispCtl {
DispCtl_Mode0 = 0,
DispCtl_Mode1 = 1,
DispCtl_Mode2 = 2,
DispCtl_Mode3 = 3,
DispCtl_Mode4 = 4,
DispCtl_Mode5 = 5,
DispCtl_SpriteMap1D = 1 << 6,
DispCtl_Bg0 = 1 << 8,
DispCtl_Bg1 = 1 << 9,
DispCtl_Bg2 = 1 << 10,
DispCtl_Bg3 = 1 << 11,
DispCtl_Obj = 1 << 12,
};
struct OX_ALIGN8 GbaSpriteAttrUpdate {
uint16_t attr0 = 0;
uint16_t attr1 = 0;
uint16_t attr2 = 0;
uint16_t idx = 0;
};
extern volatile uint16_t g_spriteUpdates;
extern ox::Array<GbaSpriteAttrUpdate, 128> g_spriteBuffer;
void addSpriteUpdate(const GbaSpriteAttrUpdate &upd) noexcept;
void applySpriteUpdates() noexcept;
}

30
deps/teagba/include/teagba/irq.hpp vendored Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <ox/std/types.hpp>
namespace teagba {
constexpr uint16_t DispStat_irq_vblank = 1 << 3;
constexpr uint16_t DispStat_irq_hblank = 1 << 4;
constexpr uint16_t DispStat_irq_vcount = 1 << 5;
constexpr uint16_t Int_vblank = 1 << 0;
constexpr uint16_t Int_hblank = 1 << 1;
constexpr uint16_t Int_vcount = 1 << 2;
constexpr uint16_t Int_timer0 = 1 << 3;
constexpr uint16_t Int_timer1 = 1 << 4;
constexpr uint16_t Int_timer2 = 1 << 5;
constexpr uint16_t Int_timer3 = 1 << 6;
constexpr uint16_t Int_serial = 1 << 7; // link cable
constexpr uint16_t Int_dma0 = 1 << 8;
constexpr uint16_t Int_dma1 = 1 << 9;
constexpr uint16_t Int_dma2 = 1 << 10;
constexpr uint16_t Int_dma3 = 1 << 11;
constexpr uint16_t Int_dma4 = 1 << 12;
constexpr uint16_t Int_dma5 = 1 << 13;
constexpr uint16_t Int_input = 1 << 14; // gamepad
constexpr uint16_t Int_cart = 1 << 15; // cartridge removed
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2016 - 2023 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#pragma once
#include "addresses.hpp"
namespace teagba {
inline auto bgSetSbb(volatile BgCtl *bgCtl, unsigned sbb) noexcept {
*bgCtl = (*bgCtl & ~0b11111'0000'0000u) | (sbb << 8);
}
[[nodiscard]]
constexpr unsigned bgPri(BgCtl bgCtl) noexcept {
return bgCtl & 1;
}
[[nodiscard]]
inline auto bgPri(const volatile BgCtl *bgCtl) noexcept {
return bgPri(*bgCtl);
}
inline auto bgSetPri(volatile BgCtl *bgCtl, unsigned pri) noexcept {
pri = pri & 0b1;
*bgCtl = (*bgCtl & ~0b1u) | (pri << 0);
}
[[nodiscard]]
constexpr unsigned bgBpp(BgCtl bgCtl) noexcept {
return ((bgCtl >> 7) & 1) ? 8 : 4;
}
[[nodiscard]]
inline auto bgBpp(const volatile BgCtl *bgCtl) noexcept {
return bgBpp(*bgCtl);
}
inline auto bgSetBpp(volatile BgCtl *bgCtl, unsigned bpp) noexcept {
constexpr auto Bpp8 = 1 << 7;
if (bpp == 4) {
*bgCtl = *bgCtl | ((*bgCtl | Bpp8) ^ Bpp8); // set to use 4 bits per pixel
} else {
*bgCtl = *bgCtl | Bpp8; // set to use 8 bits per pixel
}
}
[[nodiscard]]
constexpr auto bgCbb(BgCtl bgCtl) noexcept {
return (bgCtl >> 2) & 0b11u;
}
[[nodiscard]]
inline auto bgCbb(const volatile BgCtl *bgCtl) noexcept {
return bgCbb(*bgCtl);
}
inline auto bgSetCbb(volatile BgCtl *bgCtl, unsigned cbb) noexcept {
cbb = cbb & 0b11;
*bgCtl = (*bgCtl & ~0b1100u) | (cbb << 2);
}
constexpr void iterateBgCtl(auto cb) noexcept {
for (auto bgCtl = &REG_BG0CTL; bgCtl <= &REG_BG3CTL; bgCtl += 2) {
cb(bgCtl);
}
}
}