122 lines
4.8 KiB
C++
122 lines
4.8 KiB
C++
/*
|
|
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <ox/std/array.hpp>
|
|
#include <ox/std/units.hpp>
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Interrupt Handler
|
|
|
|
using InterruptHandler = void(*)();
|
|
#define REG_ISR (*reinterpret_cast<InterruptHandler*>(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 volatile BgCtl ®BgCtl(uintptr_t const bgIdx) noexcept {
|
|
return *reinterpret_cast<volatile BgCtl*>(0x0400'0008 + 2 * bgIdx);
|
|
}
|
|
|
|
// background horizontal scrolling registers
|
|
#define REG_BG0HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0010))
|
|
#define REG_BG1HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0014))
|
|
#define REG_BG2HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0018))
|
|
#define REG_BG3HOFS (*reinterpret_cast<volatile int16_t*>(0x0400'001c))
|
|
|
|
[[nodiscard]]
|
|
volatile int16_t ®BgHofs(auto const bgIdx) noexcept {
|
|
return *reinterpret_cast<volatile int16_t*>(0x0400'0010 + 4 * bgIdx);
|
|
}
|
|
|
|
// background vertical scrolling registers
|
|
#define REG_BG0VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0012))
|
|
#define REG_BG1VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'0016))
|
|
#define REG_BG2VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'001a))
|
|
#define REG_BG3VOFS (*reinterpret_cast<volatile int16_t*>(0x0400'001e))
|
|
|
|
[[nodiscard]]
|
|
volatile int16_t ®BgVofs(auto const bgIdx) noexcept {
|
|
return *reinterpret_cast<volatile int16_t*>(0x0400'0012 + 4 * bgIdx);
|
|
}
|
|
|
|
// background scrolling registers
|
|
|
|
struct OffsetPair {
|
|
int16_t x{}, y{};
|
|
};
|
|
|
|
#define REG_BG0OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'0010))
|
|
#define REG_BG1OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'0014))
|
|
#define REG_BG2OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'0018))
|
|
#define REG_BG3OFS (*reinterpret_cast<volatile OffsetPair*>(0x0400'001c))
|
|
|
|
[[nodiscard]]
|
|
volatile OffsetPair ®BgOfs(auto const bgIdx) noexcept {
|
|
return *reinterpret_cast<volatile OffsetPair*>(0x0400'0010 + sizeof(OffsetPair) * bgIdx);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// User Input
|
|
|
|
#define REG_GAMEPAD (*reinterpret_cast<volatile uint16_t*>(0x0400'0130))
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Memory Addresses
|
|
|
|
#define MEM_EWRAM (*reinterpret_cast<ox::Array<uint16_t, 0x0203'FFFF - 0x0200'0000>*>(0x0200'0000))
|
|
|
|
#define MEM_IWRAM (*reinterpret_cast<ox::Array<uint8_t, 0x0300'7FFF - 0x0300'0000>*>(0x0300'0000))
|
|
|
|
#define REG_BLNDCTL (*reinterpret_cast<uint16_t*>(0x0400'0050))
|
|
|
|
using Palette = ox::Array<uint16_t, 128>;
|
|
#define MEM_BG_PALETTE (*reinterpret_cast<::Palette*>(0x0500'0000))
|
|
#define MEM_SPRITE_PALETTE (*reinterpret_cast<::Palette*>(0x0500'0200))
|
|
|
|
using BgMapTile = ox::Array<uint16_t, 8192>;
|
|
#define MEM_BG_TILES (*reinterpret_cast<ox::Array<BgMapTile, 4>*>(0x0600'0000))
|
|
#define MEM_BG_MAP (*reinterpret_cast<ox::Array<BgMapTile, 4>*>(0x0600'e000))
|
|
|
|
#define MEM_SPRITE_TILES (*reinterpret_cast<ox::Array<uint16_t, 32 * ox::units::KB>*>(0x0601'0000))
|
|
#define MEM_OAM (*reinterpret_cast<ox::Array<uint64_t, 64>*>(0x0700'0000))
|
|
|
|
#define MEM_ROM (*reinterpret_cast<ox::Array<char, 32 * ox::units::MB>*>(0x0700'0000))
|
|
|
|
#define MEM_SRAM (*reinterpret_cast<ox::Array<char, 64 * ox::units::KB>*>(0x0e00'0000))
|