[nostalgia/core/gba] Add IRQ system

This commit is contained in:
Gary Talent 2020-06-21 11:48:18 -05:00
parent d664979868
commit 89aadfb606
8 changed files with 96 additions and 11 deletions

View File

@ -1,6 +1,5 @@
add_library( add_library(
NostalgiaCore NostalgiaCore
core.cpp
gfx.cpp gfx.cpp
media.cpp media.cpp
) )

View File

@ -3,10 +3,14 @@ if(NOSTALGIA_BUILD_TYPE STREQUAL "GBA")
NostalgiaCore-GBA NostalgiaCore-GBA
core.cpp core.cpp
gfx.cpp gfx.cpp
irq.arm.cpp
irq.cpp
media.cpp media.cpp
panic.cpp panic.cpp
) )
set_source_files_properties(irq.arm.cpp PROPERTIES COMPILE_FLAGS -marm)
target_link_libraries( target_link_libraries(
NostalgiaCore-GBA PUBLIC NostalgiaCore-GBA PUBLIC
NostalgiaCore NostalgiaCore

View File

@ -1,18 +1,30 @@
/* /*
* Copyright 2016 - 2019 gtalent2@gmail.com * Copyright 2016 - 2020 gtalent2@gmail.com
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#pragma once #pragma once
#include <ox/std/types.hpp> #include <ox/std/types.hpp>
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// I/O Registers // Interrupt Handler
#define REG_DISPCNT *reinterpret_cast<volatile uint32_t*>(0x04000000) using interrupt_handler = void (*)(void);
#define REG_ISR *reinterpret_cast<interrupt_handler*>(0x03007FFC)
#define REG_IE *reinterpret_cast<volatile uint16_t*>(0x04000200)
#define REG_IF *reinterpret_cast<volatile uint16_t*>(0x04000202)
#define REG_IME *reinterpret_cast<volatile uint16_t*>(0x04000208)
/////////////////////////////////////////////////////////////////
// Display Registers
#define REG_DISPCNT *reinterpret_cast<volatile uint32_t*>(0x04000000)
#define REG_DISPSTAT *reinterpret_cast<volatile uint32_t*>(0x04000004)
#define REG_VCOUNT *reinterpret_cast<volatile uint32_t*>(0x04000006)
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// background registers // background registers
@ -35,7 +47,6 @@
#define REG_BG2VOFS *reinterpret_cast<volatile uint32_t*>(0x0400001a) #define REG_BG2VOFS *reinterpret_cast<volatile uint32_t*>(0x0400001a)
#define REG_BG3VOFS *reinterpret_cast<volatile uint32_t*>(0x0400001e) #define REG_BG3VOFS *reinterpret_cast<volatile uint32_t*>(0x0400001e)
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// Memory Addresses // Memory Addresses

View File

@ -8,8 +8,16 @@
#include <nostalgia/core/core.hpp> #include <nostalgia/core/core.hpp>
#include "irq.hpp"
namespace nostalgia::core { namespace nostalgia::core {
ox::Error init(Context *ctx) {
oxReturnError(initGfx(ctx));
oxReturnError(initIrq(ctx));
return OxError(0);
}
ox::Error run(Context*) { ox::Error run(Context*) {
while (1) { while (1) {
} }

View File

@ -1,18 +1,20 @@
/* /*
* Copyright 2016 - 2019 gtalent2@gmail.com * Copyright 2016 - 2020 gtalent2@gmail.com
* *
* This Source Code Form is subject to the terms of the Mozilla Public * 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 * 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/. * file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/ */
#include "mem.hpp" // NOTE: this file is compiled as ARM and not THUMB, so don't but too much in
#include "core.hpp" // here
#include "irq.hpp"
namespace nostalgia::core { namespace nostalgia::core {
ox::Error init(Context *ctx) { void isr() {
return initGfx(ctx); REG_IF = IntId_vblank;
} }
} }

View File

@ -0,0 +1,29 @@
/*
* 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"
namespace nostalgia::core {
constexpr auto DispStat_irq_vblank = static_cast<uint16_t>(1) << 3;
constexpr auto DispStat_irq_hblank = static_cast<uint16_t>(1) << 4;
constexpr auto DispStat_irq_vcount = static_cast<uint16_t>(1) << 5;
void isr();
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 |= IntId_vblank;
REG_IME = 1;
return OxError(0);
}
}

View File

@ -0,0 +1,27 @@
/*
* 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 <nostalgia/core/context.hpp>
#include "addresses.hpp"
namespace nostalgia::core {
constexpr uint16_t IntId_vblank = static_cast<uint64_t>(1) << 0;
constexpr uint16_t IntId_hblank = static_cast<uint64_t>(1) << 1;
constexpr uint16_t IntId_vcount = static_cast<uint64_t>(1) << 2;
constexpr uint16_t IntId_timer0 = static_cast<uint64_t>(1) << 3;
constexpr uint16_t IntId_timer1 = static_cast<uint64_t>(1) << 4;
constexpr uint16_t IntId_timer2 = static_cast<uint64_t>(1) << 5;
constexpr uint16_t IntId_serial = static_cast<uint64_t>(1) << 6; // link cable
constexpr uint16_t IntId_input = static_cast<uint64_t>(1) << 14; // gamepad
constexpr uint16_t IntId_cart = static_cast<uint64_t>(1) << 15; // cartridge removed
[[nodiscard]] ox::Error initIrq(Context *ctx);
}

View File

@ -8,12 +8,17 @@
#include <SDL.h> #include <SDL.h>
#include <nostalgia/core/core.hpp> #include <nostalgia/core/gfx.hpp>
namespace nostalgia::core { namespace nostalgia::core {
void draw(Context *ctx); void draw(Context *ctx);
ox::Error init(Context *ctx) {
oxReturnError(initGfx(ctx));
return OxError(0);
}
ox::Error run(Context *ctx) { ox::Error run(Context *ctx) {
for (auto running = true; running;) { for (auto running = true; running;) {
SDL_Event event; SDL_Event event;