/* * Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved. */ #pragma once #include #include ///////////////////////////////////////////////////////////////// // Interrupt Handler using InterruptHandler = void(*)(); #define REG_ISR (*reinterpret_cast(0x0300'7FFC)) #define REG_IE (*reinterpret_cast(0x0400'0200)) #define REG_IF (*reinterpret_cast(0x0400'0202)) #define REG_IME (*reinterpret_cast(0x0400'0208)) ///////////////////////////////////////////////////////////////// // Display Registers #define REG_DISPCTL (*reinterpret_cast(0x0400'0000)) #define REG_DISPSTAT (*reinterpret_cast(0x0400'0004)) #define REG_VCOUNT (*reinterpret_cast(0x0400'0006)) ///////////////////////////////////////////////////////////////// // Timers #define REG_TIMER0 (*reinterpret_cast(0x0400'0100)) #define REG_TIMER0CTL (*reinterpret_cast(0x0400'0102)) #define REG_TIMER1 (*reinterpret_cast(0x0400'0104)) #define REG_TIMER1CTL (*reinterpret_cast(0x0400'0106)) #define REG_TIMER2 (*reinterpret_cast(0x0400'0108)) #define REG_TIMER2CTL (*reinterpret_cast(0x0400'010a)) #define REG_TIMER3 (*reinterpret_cast(0x0400'010c)) #define REG_TIMER3CTL (*reinterpret_cast(0x0400'010e)) ///////////////////////////////////////////////////////////////// // background registers // background control registers using BgCtl = uint16_t; #define REG_BG0CTL (*reinterpret_cast(0x0400'0008)) #define REG_BG1CTL (*reinterpret_cast(0x0400'000a)) #define REG_BG2CTL (*reinterpret_cast(0x0400'000c)) #define REG_BG3CTL (*reinterpret_cast(0x0400'000e)) [[nodiscard]] inline volatile BgCtl ®BgCtl(uintptr_t const bgIdx) noexcept { return *reinterpret_cast(0x0400'0008 + 2 * bgIdx); } // background horizontal scrolling registers #define REG_BG0HOFS (*reinterpret_cast(0x0400'0010)) #define REG_BG1HOFS (*reinterpret_cast(0x0400'0014)) #define REG_BG2HOFS (*reinterpret_cast(0x0400'0018)) #define REG_BG3HOFS (*reinterpret_cast(0x0400'001c)) [[nodiscard]] volatile int16_t ®BgHofs(auto const bgIdx) noexcept { return *reinterpret_cast(0x0400'0010 + 4 * bgIdx); } // background vertical scrolling registers #define REG_BG0VOFS (*reinterpret_cast(0x0400'0012)) #define REG_BG1VOFS (*reinterpret_cast(0x0400'0016)) #define REG_BG2VOFS (*reinterpret_cast(0x0400'001a)) #define REG_BG3VOFS (*reinterpret_cast(0x0400'001e)) [[nodiscard]] volatile int16_t ®BgVofs(auto const bgIdx) noexcept { return *reinterpret_cast(0x0400'0012 + 4 * bgIdx); } // background scrolling registers struct OffsetPair { int16_t x{}, y{}; }; #define REG_BG0OFS (*reinterpret_cast(0x0400'0010)) #define REG_BG1OFS (*reinterpret_cast(0x0400'0014)) #define REG_BG2OFS (*reinterpret_cast(0x0400'0018)) #define REG_BG3OFS (*reinterpret_cast(0x0400'001c)) [[nodiscard]] volatile OffsetPair ®BgOfs(auto const bgIdx) noexcept { return *reinterpret_cast(0x0400'0010 + sizeof(OffsetPair) * bgIdx); } ///////////////////////////////////////////////////////////////// // User Input #define REG_GAMEPAD (*reinterpret_cast(0x0400'0130)) ///////////////////////////////////////////////////////////////// // Memory Addresses #define MEM_EWRAM (*(reinterpret_cast*>(0x0200'0000))) #define MEM_IWRAM (*(reinterpret_cast*>(0x0300'0000))) #define REG_BLNDCTL (*reinterpret_cast(0x0400'0050)) using Palette = ox::Array; #define MEM_BG_PALETTE (*(reinterpret_cast<::Palette*>(0x0500'0000))) #define MEM_SPRITE_PALETTE (*(reinterpret_cast<::Palette*>(0x0500'0200))) using BgMapTile = ox::Array; #define MEM_BG_TILES (*(reinterpret_cast*>(0x0600'0000))) #define MEM_BG_MAP (*(reinterpret_cast*>(0x0600'e000))) #define MEM_SPRITE_TILES (*(reinterpret_cast*>(0x0601'0000))) #define MEM_OAM (*(reinterpret_cast*>(0x0700'0000))) #define MEM_ROM (*(reinterpret_cast*>(0x0700'0000))) #define MEM_SRAM (*(reinterpret_cast*>(0x0e00'0000)))