mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
393d4b4606
19
CHANGES
19
CHANGES
|
@ -25,8 +25,16 @@ Features:
|
|||
Emulation fixes:
|
||||
- ARM: Fix ALU reading PC after shifting
|
||||
- ARM: Fix STR storing PC after address calculation
|
||||
- ARM: Fix timing on Thumb shift instructions
|
||||
- GB: Fix GBC game registers after skipping BIOS
|
||||
- GB MBC: Support 4MB MBC30 ROMs (fixes mgba.io/i/1713)
|
||||
- GB Video: Fix state after skipping BIOS (fixes mgba.io/i/1715 and mgba.io/i/1716)
|
||||
- GB Video: Fix BGPS value after skipping BIOS (fixes mgba.io/i/1717)
|
||||
- GBA: Add missing RTC overrides for Legendz games
|
||||
- GBA: Fix timing advancing too quickly in rare cases
|
||||
- GBA BIOS: Implement dummy sound driver calls
|
||||
- GBA BIOS: Improve HLE BIOS timing
|
||||
- GBA BIOS: Reset renderer when RegisterRamReset called (fixes mgba.io/i/1756)
|
||||
- GBA DMA: Linger last DMA on bus (fixes mgba.io/i/301 and mgba.io/i/1320)
|
||||
- GBA Memory: Improve gamepak prefetch timing
|
||||
- GBA SIO: Fix Multiplayer busy bit
|
||||
|
@ -35,7 +43,14 @@ Emulation fixes:
|
|||
- GBA Timers: Fix deserializing count-up timers
|
||||
- GBA Video: Latch scanline at end of Hblank (fixes mgba.io/i/1319)
|
||||
- GBA Video: Fix Hblank timing
|
||||
- GBA Video: Fix mosaic objects drawing past the end (fixes mgba.io/i/1702)
|
||||
- GBA Video: Fix disabling OBJWIN in GL renderer (fixes mgba.io/i/1759)
|
||||
- GBA Video: Add missing parts of 256-color mode 0 mosaic (fixes mgba.io/1701)
|
||||
- GBA Video: Fix double-size OBJ wrapping in GL renderer (fixes mgba.io/1712)
|
||||
Other fixes:
|
||||
- All: Improve export headers (fixes mgba.io/i/1738)
|
||||
- ARM Debugger: Clear low bit on breakpoint addresses (fixes mgba.io/i/1764)
|
||||
- CMake: Always use devkitPro toolchain when applicable (fixes mgba.io/i/1755)
|
||||
- Core: Ensure ELF regions can be written before trying
|
||||
- Core: Fix ELF loading regression (fixes mgba.io/i/1669)
|
||||
- Core: Fix crash modifying hash table entry (fixes mgba.io/i/1673)
|
||||
|
@ -44,8 +59,12 @@ Other fixes:
|
|||
- Debugger: Don't skip undefined instructions when debugger attached
|
||||
- Qt: Force OpenGL paint engine creation thread (fixes mgba.io/i/1642)
|
||||
- Qt: Fix OpenGL 2.1 support (fixes mgba.io/i/1678)
|
||||
- Qt: Fix static compilation in MinGW (fixes mgba.io/i/1769)
|
||||
Misc:
|
||||
- 3DS: Clean up legacy initialization (fixes mgba.io/i/1768)
|
||||
- Debugger: Keep track of global cycle count
|
||||
- FFmpeg: Add looping option for GIF/APNG
|
||||
- GBA Serialize: Only flunk BIOS check if official BIOS was expected
|
||||
- Qt: Renderer can be changed while a game is running
|
||||
- Qt: Add hex index to palette view
|
||||
- Qt: Add transformation matrix info to sprite view
|
||||
|
|
|
@ -9,14 +9,17 @@ if(POLICY CMP0072)
|
|||
endif()
|
||||
project(medusa)
|
||||
set(BINARY_NAME medusa-emu CACHE INTERNAL "Name of output binaries")
|
||||
set(CMAKE_C_STANDARD 99)
|
||||
if(NOT MSVC)
|
||||
set(GCC_STD "c99")
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
if(SWITCH)
|
||||
set(GCC_STD "gnu11")
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.3")
|
||||
set(GCC_STD "gnu99")
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS "4.3")
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -std=${GCC_STD}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-missing-field-initializers")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146")
|
||||
endif()
|
||||
|
@ -174,9 +177,9 @@ endif()
|
|||
if(WIN32)
|
||||
set(WIN32_VERSION "${LIB_VERSION_MAJOR},${LIB_VERSION_MINOR},${LIB_VERSION_PATCH}")
|
||||
add_definitions(-D_WIN32_WINNT=0x0600)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
if(MSVC)
|
||||
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN)
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
add_definitions(-D_UNICODE -DUNICODE)
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -municode")
|
||||
|
@ -848,6 +851,7 @@ if(NOT SKIP_LIBRARY)
|
|||
|
||||
if(BUILD_SHARED)
|
||||
add_library(${BINARY_NAME} SHARED ${SRC} ${VFS_SRC})
|
||||
set(EXPORT_DEFINES MGBA_DLL)
|
||||
if(BUILD_STATIC)
|
||||
add_library(${BINARY_NAME}-static STATIC ${SRC})
|
||||
target_include_directories(${BINARY_NAME}-static BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
|
@ -861,12 +865,10 @@ if(NOT SKIP_LIBRARY)
|
|||
endif()
|
||||
|
||||
target_include_directories(${BINARY_NAME} BEFORE PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include)
|
||||
set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}")
|
||||
set_target_properties(${BINARY_NAME} PROPERTIES VERSION ${LIB_VERSION_STRING} SOVERSION ${LIB_VERSION_ABI} COMPILE_DEFINITIONS "${OS_DEFINES};${FEATURE_DEFINES};${FUNCTION_DEFINES};${EXPORT_DEFINES}" COMPILE_OPTIONS "${FEATURE_FLAGS}")
|
||||
add_dependencies(${BINARY_NAME} version-info)
|
||||
|
||||
include(GenerateExportHeader)
|
||||
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util)
|
||||
generate_export_header(${BINARY_NAME} BASE_NAME MGBA STATIC_DEFINE BUILD_STATIC EXPORT_FILE_NAME ${CMAKE_CURRENT_BINARY_DIR}/include/mgba-util/dllexports.h)
|
||||
|
||||
target_link_libraries(${BINARY_NAME} ${DEBUGGER_LIB} ${DEPENDENCY_LIB} ${OS_LIB})
|
||||
install(TARGETS ${BINARY_NAME} LIBRARY DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME} NAMELINK_SKIP ARCHIVE DESTINATION ${LIBDIR} RUNTIME DESTINATION ${LIBDIR} COMPONENT lib${BINARY_NAME})
|
||||
|
|
|
@ -144,6 +144,8 @@ This will produce a `build-win32` directory with the build products. Replace `mg
|
|||
- mgba/ubuntu:bionic
|
||||
- mgba/ubuntu:cosmic
|
||||
- mgba/ubuntu:disco
|
||||
- mgba/ubuntu:eoan
|
||||
- mgba/ubuntu:focal
|
||||
- mgba/vita
|
||||
- mgba/wii
|
||||
- mgba/windows:w32
|
||||
|
|
|
@ -126,6 +126,8 @@ Dieser Befehl erzeugt ein Verzeichnis `build-win32` mit den erzeugten Programmda
|
|||
- mgba/ubuntu:bionic
|
||||
- mgba/ubuntu:cosmic
|
||||
- mgba/ubuntu:disco
|
||||
- mgba/ubuntu:eoan
|
||||
- mgba/ubuntu:focal
|
||||
- mgba/vita
|
||||
- mgba/wii
|
||||
- mgba/windows:w32
|
||||
|
|
|
@ -65,12 +65,7 @@ typedef intptr_t ssize_t;
|
|||
#include <sys/syslimits.h>
|
||||
#endif
|
||||
|
||||
#ifndef MGBA_STANDALONE
|
||||
#include <mgba-util/dllexports.h>
|
||||
#else
|
||||
#define MGBA_EXPORT
|
||||
#define MGBA_NO_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef SSIZE_MAX
|
||||
#define SSIZE_MAX ((ssize_t) (SIZE_MAX >> 1))
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
/* Copyright (c) 2013-2020 Jeffrey Pfau
|
||||
*
|
||||
* 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/. */
|
||||
#ifndef MGBA_EXPORT_H
|
||||
#define MGBA_EXPORT_H
|
||||
|
||||
#if defined(BUILD_STATIC) || !defined(_MSC_VER) || defined(MGBA_STANDALONE)
|
||||
#define MGBA_EXPORT
|
||||
#else
|
||||
#ifdef MGBA_DLL
|
||||
#define MGBA_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define MGBA_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -25,6 +25,7 @@ struct mTiming {
|
|||
struct mTimingEvent* root;
|
||||
struct mTimingEvent* reroot;
|
||||
|
||||
uint64_t globalCycles;
|
||||
uint32_t masterCycles;
|
||||
int32_t* relativeCycles;
|
||||
int32_t* nextEvent;
|
||||
|
@ -38,6 +39,7 @@ void mTimingDeschedule(struct mTiming* timing, struct mTimingEvent*);
|
|||
bool mTimingIsScheduled(const struct mTiming* timing, const struct mTimingEvent*);
|
||||
int32_t mTimingTick(struct mTiming* timing, int32_t cycles);
|
||||
int32_t mTimingCurrentTime(const struct mTiming* timing);
|
||||
uint64_t mTimingGlobalTime(const struct mTiming* timing);
|
||||
int32_t mTimingNextEvent(struct mTiming* timing);
|
||||
int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent*);
|
||||
|
||||
|
|
|
@ -10,11 +10,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef MGBA_STANDALONE
|
||||
#define MGBA_EXPORT
|
||||
#else
|
||||
#include <mgba-util/dllexports.h>
|
||||
#endif
|
||||
|
||||
extern MGBA_EXPORT const char* const gitCommit;
|
||||
extern MGBA_EXPORT const char* const gitCommitShort;
|
||||
|
|
|
@ -70,7 +70,7 @@ struct ARMCore;
|
|||
|
||||
union PSR {
|
||||
struct {
|
||||
#if defined(__POWERPC__) || defined(__PPC__)
|
||||
#if defined(__BIG_ENDIAN__)
|
||||
unsigned n : 1;
|
||||
unsigned z : 1;
|
||||
unsigned c : 1;
|
||||
|
|
|
@ -84,7 +84,7 @@ enum GBIORegisters {
|
|||
REG_WX = 0x4B,
|
||||
|
||||
// CGB
|
||||
REG_UNK4C = 0x4C,
|
||||
REG_KEY0 = 0x4C,
|
||||
REG_KEY1 = 0x4D,
|
||||
REG_VBK = 0x4F,
|
||||
REG_HDMA1 = 0x51,
|
||||
|
@ -97,7 +97,7 @@ enum GBIORegisters {
|
|||
REG_BCPD = 0x69,
|
||||
REG_OCPS = 0x6A,
|
||||
REG_OCPD = 0x6B,
|
||||
REG_UNK6C = 0x6C,
|
||||
REG_OPRI = 0x6C,
|
||||
REG_SVBK = 0x70,
|
||||
REG_UNK72 = 0x72,
|
||||
REG_UNK73 = 0x73,
|
||||
|
|
|
@ -155,7 +155,8 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
|
|||
* | bit 4: Is HDMA active?
|
||||
* | bits 5 - 7: Active RTC register
|
||||
* | 0x00196 - 0x00197: Reserved (leave zero)
|
||||
* 0x00198 - 0x0025F: Reserved (leave zero)
|
||||
* 0x00198 - 0x0019F: Global cycle counter
|
||||
* 0x001A0 - 0x0025F: Reserved (leave zero)
|
||||
* 0x00260 - 0x002FF: OAM
|
||||
* 0x00300 - 0x0037F: I/O memory
|
||||
* 0x00380 - 0x003FE: HRAM
|
||||
|
@ -388,7 +389,9 @@ struct GBSerializedState {
|
|||
uint16_t reserved;
|
||||
} memory;
|
||||
|
||||
uint32_t reserved[50];
|
||||
uint64_t globalCycles;
|
||||
|
||||
uint32_t reserved[48];
|
||||
|
||||
uint8_t oam[GB_SIZE_OAM];
|
||||
|
||||
|
|
|
@ -161,6 +161,7 @@ void GBVideoInit(struct GBVideo* video);
|
|||
void GBVideoReset(struct GBVideo* video);
|
||||
void GBVideoDeinit(struct GBVideo* video);
|
||||
void GBVideoAssociateRenderer(struct GBVideo* video, struct GBVideoRenderer* renderer);
|
||||
void GBVideoSkipBIOS(struct GBVideo* video);
|
||||
void GBVideoProcessDots(struct GBVideo* video, uint32_t cyclesLate);
|
||||
|
||||
void GBVideoWriteLCDC(struct GBVideo* video, GBRegisterLCDC value);
|
||||
|
|
|
@ -193,7 +193,8 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
|
|||
* | 0x002F4 - 0x002F7: GBA BIOS bus prefetch
|
||||
* | 0x002F8 - 0x002FB: CPU prefecth (decode slot)
|
||||
* | 0x002FC - 0x002FF: CPU prefetch (fetch slot)
|
||||
* 0x00300 - 0x00317: Reserved (leave zero)
|
||||
* 0x00300 - 0x0030F: Reserved (leave zero)
|
||||
* 0x00310 - 0x00317: Global cycle counter
|
||||
* 0x00318 - 0x0031B: Last prefetched program counter
|
||||
* 0x0031C - 0x0031F: Miscellaneous flags
|
||||
* | bit 0: Is CPU halted?
|
||||
|
@ -326,8 +327,9 @@ struct GBASerializedState {
|
|||
uint32_t biosPrefetch;
|
||||
uint32_t cpuPrefetch[2];
|
||||
|
||||
uint32_t reservedCpu[6];
|
||||
uint32_t reservedCpu[4];
|
||||
|
||||
uint64_t globalCycles;
|
||||
uint32_t lastPrefetchedPc;
|
||||
GBASerializedMiscFlags miscFlags;
|
||||
uint32_t nextIrq;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/internal/arm/debugger/cli-debugger.h>
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/timing.h>
|
||||
#include <mgba/internal/arm/debugger/debugger.h>
|
||||
#include <mgba/internal/arm/debugger/memory-debugger.h>
|
||||
#include <mgba/internal/arm/decoder.h>
|
||||
|
@ -138,6 +139,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
|
|||
}
|
||||
be->printf(be, "cpsr: ");
|
||||
_printPSR(be, cpu->cpsr);
|
||||
be->printf(be, "Cycle: %" PRIu64 "\n", mTimingGlobalTime(debugger->p->d.core->timing));
|
||||
int instructionLength;
|
||||
enum ExecutionMode mode = cpu->cpsr.t;
|
||||
if (mode == MODE_ARM) {
|
||||
|
|
|
@ -171,7 +171,7 @@ ssize_t ARMDebuggerSetSoftwareBreakpoint(struct mDebuggerPlatform* d, uint32_t a
|
|||
ssize_t id = debugger->nextId;
|
||||
++debugger->nextId;
|
||||
breakpoint->d.id = id;
|
||||
breakpoint->d.address = address;
|
||||
breakpoint->d.address = address & ~1; // Clear Thumb bit since it's not part of a valid address
|
||||
breakpoint->d.segment = -1;
|
||||
breakpoint->d.condition = NULL;
|
||||
breakpoint->d.type = BREAKPOINT_SOFTWARE;
|
||||
|
@ -187,6 +187,7 @@ static ssize_t ARMDebuggerSetBreakpoint(struct mDebuggerPlatform* d, const struc
|
|||
ssize_t id = debugger->nextId;
|
||||
++debugger->nextId;
|
||||
breakpoint->d = *info;
|
||||
breakpoint->d.address &= ~1; // Clear Thumb bit since it's not part of a valid address
|
||||
breakpoint->d.id = id;
|
||||
if (info->type == BREAKPOINT_SOFTWARE) {
|
||||
// TODO
|
||||
|
|
|
@ -157,6 +157,7 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSL2,
|
|||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
}
|
||||
++currentCycles;
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]))
|
||||
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSR2,
|
||||
|
@ -174,6 +175,7 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(LSR2,
|
|||
cpu->gprs[rd] = 0;
|
||||
}
|
||||
}
|
||||
++currentCycles;
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]))
|
||||
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
|
||||
|
@ -191,6 +193,7 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ASR2,
|
|||
}
|
||||
}
|
||||
}
|
||||
++currentCycles;
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]))
|
||||
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ADC,
|
||||
|
@ -215,6 +218,7 @@ DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(ROR,
|
|||
cpu->cpsr.c = ARM_SIGN(cpu->gprs[rd]);
|
||||
}
|
||||
}
|
||||
++currentCycles;
|
||||
THUMB_NEUTRAL_S( , , cpu->gprs[rd]);)
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(TST, int32_t aluOut = cpu->gprs[rd] & cpu->gprs[rn]; THUMB_NEUTRAL_S(cpu->gprs[rd], cpu->gprs[rn], aluOut))
|
||||
DEFINE_DATA_FORM_5_INSTRUCTION_THUMB(NEG, THUMB_SUBTRACTION(cpu->gprs[rd], 0, cpu->gprs[rn]))
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextEvent) {
|
||||
timing->root = NULL;
|
||||
timing->reroot = NULL;
|
||||
timing->globalCycles = 0;
|
||||
timing->masterCycles = 0;
|
||||
timing->relativeCycles = relativeCycles;
|
||||
timing->nextEvent = nextEvent;
|
||||
|
@ -20,6 +21,7 @@ void mTimingDeinit(struct mTiming* timing) {
|
|||
void mTimingClear(struct mTiming* timing) {
|
||||
timing->root = NULL;
|
||||
timing->reroot = NULL;
|
||||
timing->globalCycles = 0;
|
||||
timing->masterCycles = 0;
|
||||
}
|
||||
|
||||
|
@ -103,6 +105,10 @@ int32_t mTimingCurrentTime(const struct mTiming* timing) {
|
|||
return timing->masterCycles + *timing->relativeCycles;
|
||||
}
|
||||
|
||||
uint64_t mTimingGlobalTime(const struct mTiming* timing) {
|
||||
return timing->globalCycles + *timing->relativeCycles;
|
||||
}
|
||||
|
||||
int32_t mTimingNextEvent(struct mTiming* timing) {
|
||||
struct mTimingEvent* next = timing->root;
|
||||
if (!next) {
|
||||
|
|
15
src/gb/gb.c
15
src/gb/gb.c
|
@ -460,13 +460,13 @@ void GBReset(struct SM83Core* cpu) {
|
|||
|
||||
GBVideoReset(&gb->video);
|
||||
GBTimerReset(&gb->timer);
|
||||
GBIOReset(gb);
|
||||
if (!gb->biosVf) {
|
||||
GBSkipBIOS(gb);
|
||||
} else {
|
||||
mTimingSchedule(&gb->timing, &gb->timer.event, 0);
|
||||
}
|
||||
|
||||
GBIOReset(gb);
|
||||
GBAudioReset(&gb->audio);
|
||||
GBSIOReset(&gb->sio);
|
||||
|
||||
|
@ -478,6 +478,7 @@ void GBReset(struct SM83Core* cpu) {
|
|||
|
||||
void GBSkipBIOS(struct GB* gb) {
|
||||
struct SM83Core* cpu = gb->cpu;
|
||||
const struct GBCartridge* cart = (const struct GBCartridge*) &gb->memory.rom[0x100];
|
||||
int nextDiv = 0;
|
||||
|
||||
switch (gb->model) {
|
||||
|
@ -539,9 +540,15 @@ void GBSkipBIOS(struct GB* gb) {
|
|||
cpu->a = 0x11;
|
||||
cpu->f.packed = 0x80;
|
||||
cpu->c = 0;
|
||||
cpu->e = 0x08;
|
||||
cpu->h = 0;
|
||||
if (cart->cgb & 0x80) {
|
||||
cpu->d = 0xFF;
|
||||
cpu->e = 0x56;
|
||||
cpu->l = 0x0D;
|
||||
} else {
|
||||
cpu->e = 0x08;
|
||||
cpu->l = 0x7C;
|
||||
}
|
||||
gb->timer.internalDiv = 0x1EA;
|
||||
nextDiv = 0xC;
|
||||
break;
|
||||
|
@ -554,6 +561,7 @@ void GBSkipBIOS(struct GB* gb) {
|
|||
mTimingSchedule(&gb->timing, &gb->timer.event, 0);
|
||||
|
||||
GBIOWrite(gb, REG_LCDC, 0x91);
|
||||
GBVideoSkipBIOS(&gb->video);
|
||||
|
||||
if (gb->biosVf) {
|
||||
GBUnmapBIOS(gb);
|
||||
|
@ -666,6 +674,9 @@ void GBProcessEvents(struct SM83Core* cpu) {
|
|||
int32_t nextEvent;
|
||||
|
||||
cpu->cycles = 0;
|
||||
#ifdef USE_DEBUGGERS
|
||||
gb->timing.globalCycles += cycles;
|
||||
#endif
|
||||
cpu->nextEvent = INT_MAX;
|
||||
|
||||
nextEvent = cycles;
|
||||
|
|
12
src/gb/io.c
12
src/gb/io.c
|
@ -53,6 +53,7 @@ MGBA_EXPORT const char* const GBIORegisterNames[] = {
|
|||
[REG_OBP1] = "OBP1",
|
||||
[REG_WY] = "WY",
|
||||
[REG_WX] = "WX",
|
||||
[REG_KEY0] = "KEY0",
|
||||
[REG_KEY1] = "KEY1",
|
||||
[REG_VBK] = "VBK",
|
||||
[REG_HDMA1] = "HDMA1",
|
||||
|
@ -65,6 +66,7 @@ MGBA_EXPORT const char* const GBIORegisterNames[] = {
|
|||
[REG_BCPD] = "BCPD",
|
||||
[REG_OCPS] = "OCPS",
|
||||
[REG_OCPD] = "OCPD",
|
||||
[REG_OPRI] = "OPRI",
|
||||
[REG_SVBK] = "SVBK",
|
||||
[REG_IE] = "IE",
|
||||
};
|
||||
|
@ -99,7 +101,7 @@ static const uint8_t _registerMask[] = {
|
|||
[REG_VBK] = 0xFE,
|
||||
[REG_OCPS] = 0x40,
|
||||
[REG_BCPS] = 0x40,
|
||||
[REG_UNK6C] = 0xFE,
|
||||
[REG_OPRI] = 0xFE,
|
||||
[REG_SVBK] = 0xF8,
|
||||
[REG_IE] = 0xE0,
|
||||
};
|
||||
|
@ -200,10 +202,10 @@ void GBIOReset(struct GB* gb) {
|
|||
GBIOWrite(gb, REG_WY, 0x00);
|
||||
GBIOWrite(gb, REG_WX, 0x00);
|
||||
if (gb->model & GB_MODEL_CGB) {
|
||||
GBIOWrite(gb, REG_UNK4C, 0);
|
||||
GBIOWrite(gb, REG_KEY0, 0);
|
||||
GBIOWrite(gb, REG_JOYP, 0xFF);
|
||||
GBIOWrite(gb, REG_VBK, 0);
|
||||
GBIOWrite(gb, REG_BCPS, 0);
|
||||
GBIOWrite(gb, REG_BCPS, 0x80);
|
||||
GBIOWrite(gb, REG_OCPS, 0);
|
||||
GBIOWrite(gb, REG_SVBK, 1);
|
||||
GBIOWrite(gb, REG_HDMA1, 0xFF);
|
||||
|
@ -462,7 +464,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
break;
|
||||
}
|
||||
GBUnmapBIOS(gb);
|
||||
if (gb->model >= GB_MODEL_CGB && gb->memory.io[REG_UNK4C] < 0x80) {
|
||||
if (gb->model >= GB_MODEL_CGB && gb->memory.io[REG_KEY0] < 0x80) {
|
||||
gb->model = GB_MODEL_DMG;
|
||||
GBVideoDisableCGB(&gb->video);
|
||||
}
|
||||
|
@ -474,7 +476,7 @@ void GBIOWrite(struct GB* gb, unsigned address, uint8_t value) {
|
|||
default:
|
||||
if (gb->model >= GB_MODEL_CGB) {
|
||||
switch (address) {
|
||||
case REG_UNK4C:
|
||||
case REG_KEY0:
|
||||
break;
|
||||
case REG_KEY1:
|
||||
value &= 0x1;
|
||||
|
|
|
@ -518,7 +518,7 @@ static uint8_t _GBMBC2Read(struct GBMemory* memory, uint16_t address) {
|
|||
|
||||
void _GBMBC3(struct GB* gb, uint16_t address, uint8_t value) {
|
||||
struct GBMemory* memory = &gb->memory;
|
||||
int bank = value & 0x7F;
|
||||
int bank = value;
|
||||
switch (address >> 13) {
|
||||
case 0x0:
|
||||
switch (value) {
|
||||
|
@ -536,6 +536,9 @@ void _GBMBC3(struct GB* gb, uint16_t address, uint8_t value) {
|
|||
}
|
||||
break;
|
||||
case 0x1:
|
||||
if (gb->memory.romSize < GB_SIZE_CART_BANK0 * 0x80) {
|
||||
bank &= 0x7F;
|
||||
}
|
||||
if (!bank) {
|
||||
++bank;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ void GBSerialize(struct GB* gb, struct GBSerializedState* state) {
|
|||
STORE_32LE(GB_SAVESTATE_MAGIC + GB_SAVESTATE_VERSION, 0, &state->versionMagic);
|
||||
STORE_32LE(gb->romCrc32, 0, &state->romCrc32);
|
||||
STORE_32LE(gb->timing.masterCycles, 0, &state->masterCycles);
|
||||
STORE_64LE(gb->timing.globalCycles, 0, &state->globalCycles);
|
||||
|
||||
if (gb->memory.rom) {
|
||||
memcpy(state->title, ((struct GBCartridge*) &gb->memory.rom[0x100])->titleLong, sizeof(state->title));
|
||||
|
@ -150,6 +151,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
|
|||
}
|
||||
mTimingClear(&gb->timing);
|
||||
LOAD_32LE(gb->timing.masterCycles, 0, &state->masterCycles);
|
||||
LOAD_64LE(gb->timing.globalCycles, 0, &state->globalCycles);
|
||||
|
||||
gb->cpu->a = state->cpu.a;
|
||||
gb->cpu->f.packed = state->cpu.f;
|
||||
|
|
|
@ -214,6 +214,30 @@ static bool _statIRQAsserted(GBRegisterSTAT stat) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void GBVideoSkipBIOS(struct GBVideo* video) {
|
||||
video->mode = 1;
|
||||
video->modeEvent.callback = _endMode1;
|
||||
|
||||
int32_t next;
|
||||
if (video->p->model == GB_MODEL_CGB) {
|
||||
video->ly = GB_VIDEO_VERTICAL_PIXELS;
|
||||
video->p->memory.io[REG_LY] = video->ly;
|
||||
video->stat = GBRegisterSTATClearLYC(video->stat);
|
||||
next = 20;
|
||||
} else {
|
||||
video->ly = GB_VIDEO_VERTICAL_TOTAL_PIXELS;
|
||||
video->p->memory.io[REG_LY] = 0;
|
||||
next = 56;
|
||||
}
|
||||
video->stat = GBRegisterSTATSetMode(video->stat, video->mode);
|
||||
|
||||
video->p->memory.io[REG_IF] |= (1 << GB_IRQ_VBLANK);
|
||||
GBUpdateIRQs(video->p);
|
||||
video->p->memory.io[REG_STAT] = video->stat;
|
||||
mTimingDeschedule(&video->p->timing, &video->modeEvent);
|
||||
mTimingSchedule(&video->p->timing, &video->modeEvent, next);
|
||||
}
|
||||
|
||||
void _endMode0(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||
struct GBVideo* video = context;
|
||||
if (video->frameskipCounter <= 0) {
|
||||
|
|
|
@ -177,6 +177,9 @@ static void _RegisterRamReset(struct GBA* gba) {
|
|||
cpu->memory.store16(cpu, BASE_IO | 0x204, 0, 0);
|
||||
cpu->memory.store16(cpu, BASE_IO | 0x208, 0, 0);
|
||||
}
|
||||
if (registers & 0x9C) {
|
||||
gba->video.renderer->reset(gba->video.renderer);
|
||||
}
|
||||
}
|
||||
|
||||
static void _BgAffineSet(struct GBA* gba) {
|
||||
|
|
|
@ -277,12 +277,15 @@ static void GBAProcessEvents(struct ARMCore* cpu) {
|
|||
do {
|
||||
int32_t cycles = cpu->cycles;
|
||||
cpu->cycles = 0;
|
||||
#ifdef USE_DEBUGGERS
|
||||
gba->timing.globalCycles += cycles;
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
if (cycles < 0) {
|
||||
mLOG(GBA, FATAL, "Negative cycles passed: %i", cycles);
|
||||
}
|
||||
#endif
|
||||
nextEvent = mTimingTick(&gba->timing, nextEvent + cycles);
|
||||
nextEvent = mTimingTick(&gba->timing, cycles < nextEvent ? nextEvent : cycles);
|
||||
} while (gba->cpuBlocked);
|
||||
|
||||
cpu->nextEvent = nextEvent;
|
||||
|
|
|
@ -71,6 +71,13 @@ static const struct GBACartridgeOverride _overrides[] = {
|
|||
// Koro Koro Puzzle - Happy Panechu!
|
||||
{ "KHPJ", SAVEDATA_EEPROM, HW_TILT, IDLE_LOOP_NONE, false },
|
||||
|
||||
// Legendz - Yomigaeru Shiren no Shima
|
||||
{ "BLJJ", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
|
||||
{ "BLJK", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
|
||||
|
||||
// Legendz - Sign of Nekuromu
|
||||
{ "BLVJ", SAVEDATA_FLASH512, HW_RTC, IDLE_LOOP_NONE, false },
|
||||
|
||||
// Mega Man Battle Network
|
||||
{ "AREE", SAVEDATA_SRAM, HW_NONE, 0x800032E, false },
|
||||
|
||||
|
|
|
@ -1640,10 +1640,6 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
|
|||
unsigned charBase = (BASE_TILE >> 1) + (GBAObjAttributesCGetTile(sprite->c) & ~align) * 0x10;
|
||||
int stride = GBARegisterDISPCNTIsObjCharacterMapping(renderer->dispcnt) ? (width >> 3) : (0x20 >> GBAObjAttributesAGet256Color(sprite->a));
|
||||
|
||||
if (spriteY + height >= 256) {
|
||||
spriteY -= 256;
|
||||
}
|
||||
|
||||
int totalWidth = width;
|
||||
int totalHeight = height;
|
||||
if (GBAObjAttributesAIsTransformed(sprite->a) && GBAObjAttributesAIsDoubleSize(sprite->a)) {
|
||||
|
@ -1651,6 +1647,10 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
|
|||
totalHeight <<= 1;
|
||||
}
|
||||
|
||||
if (spriteY + totalHeight >= 256) {
|
||||
spriteY -= 256;
|
||||
}
|
||||
|
||||
const struct GBAVideoGLShader* shader = &renderer->objShader[GBAObjAttributesAGet256Color(sprite->a)];
|
||||
const GLuint* uniforms = shader->uniforms;
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, renderer->fbo[GBA_GL_FBO_OBJ]);
|
||||
|
@ -1710,7 +1710,9 @@ void GBAVideoGLRendererDrawSprite(struct GBAVideoGLRenderer* renderer, struct GB
|
|||
glUniform4i(uniforms[GBA_GL_OBJ_MOSAIC], 0, 0, 0, 0);
|
||||
}
|
||||
glStencilFunc(GL_ALWAYS, 1, 1);
|
||||
if (GBAObjAttributesAGetMode(sprite->a) != OBJ_MODE_OBJWIN || GBARegisterDISPCNTIsObjwinEnable(renderer->dispcnt)) {
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
|
||||
shader = &renderer->objShader[2];
|
||||
uniforms = shader->uniforms;
|
||||
|
|
|
@ -473,8 +473,57 @@
|
|||
}
|
||||
|
||||
#define DRAW_BACKGROUND_MODE_0_MOSAIC_256EXT(BLEND, OBJWIN) \
|
||||
x = inX & 7; \
|
||||
if (mosaicWait) { \
|
||||
int baseX = x - (mosaicH - mosaicWait); \
|
||||
if (baseX < 0) { \
|
||||
int disturbX = (16 + baseX) >> 3; \
|
||||
inX -= disturbX << 3; \
|
||||
localX = tileX * 8 + inX; \
|
||||
for (; tileX < tileEnd; ++tileX) { \
|
||||
BACKGROUND_TEXT_SELECT_CHARACTER; \
|
||||
localY = inY & 0x7; \
|
||||
if (GBA_TEXT_MAP_VFLIP(mapData)) { \
|
||||
localY = 7 - localY; \
|
||||
} \
|
||||
baseX -= disturbX << 3; \
|
||||
inX += disturbX << 3; \
|
||||
} else { \
|
||||
localX = tileX * 8 + inX; \
|
||||
BACKGROUND_TEXT_SELECT_CHARACTER; \
|
||||
localY = inY & 0x7; \
|
||||
if (GBA_TEXT_MAP_VFLIP(mapData)) { \
|
||||
localY = 7 - localY; \
|
||||
} \
|
||||
} \
|
||||
charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \
|
||||
if (UNLIKELY(charBase >= 0x10000)) { \
|
||||
carryData = 0; \
|
||||
} else { \
|
||||
vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
|
||||
LOAD_32(tileData, charBase, vram); \
|
||||
if (!GBA_TEXT_MAP_HFLIP(mapData)) { \
|
||||
if (x >= 4) { \
|
||||
LOAD_32(tileData, charBase + 4, vram); \
|
||||
tileData >>= (x - 4) * 8; \
|
||||
} else { \
|
||||
LOAD_32(tileData, charBase, vram); \
|
||||
tileData >>= x * 8; \
|
||||
} \
|
||||
} else { \
|
||||
if (x >= 4) { \
|
||||
LOAD_32(tileData, charBase, vram); \
|
||||
tileData >>= (7 - x) * 8; \
|
||||
} else { \
|
||||
LOAD_32(tileData, charBase + 4, vram); \
|
||||
tileData >>= (3 - x) * 8; \
|
||||
} \
|
||||
} \
|
||||
tileData &= 0xFF; \
|
||||
carryData = tileData; \
|
||||
} \
|
||||
} \
|
||||
localX = tileX * 8 + inX; \
|
||||
for (; length; ++tileX) { \
|
||||
mapData = background->mapCache[(localX >> 3) & 0x3F]; \
|
||||
localX += 8; \
|
||||
localY = inY & 0x7; \
|
||||
|
@ -484,7 +533,7 @@
|
|||
charBase = (background->charBase + (GBA_TEXT_MAP_TILE(mapData) << 6)) + (localY << 3); \
|
||||
vram = renderer->d.vramBG[charBase >> VRAM_BLOCK_OFFSET]; \
|
||||
tileData = carryData; \
|
||||
for (x = 0; x < 8; ++x) { \
|
||||
for (x = 0; x < 8 && length; ++x, --length) { \
|
||||
if (!mosaicWait) { \
|
||||
paletteData = GBA_TEXT_MAP_PALETTE(mapData) << 8; \
|
||||
palette = &mainPalette[paletteData]; \
|
||||
|
|
|
@ -326,7 +326,7 @@ int GBAVideoSoftwareRendererPreprocessSprite(struct GBAVideoSoftwareRenderer* re
|
|||
int mosaicH = 1;
|
||||
if (GBAObjAttributesAIsMosaic(sprite->a)) {
|
||||
mosaicH = GBAMosaicControlGetObjH(renderer->mosaic) + 1;
|
||||
if (condition % mosaicH) {
|
||||
if (condition != end && condition % mosaicH) {
|
||||
condition += mosaicH - (condition % mosaicH);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/internal/gba/serialize.h>
|
||||
|
||||
#include <mgba/internal/arm/macros.h>
|
||||
#include <mgba/internal/gba/bios.h>
|
||||
#include <mgba/internal/gba/io.h>
|
||||
|
||||
#include <mgba-util/memory.h>
|
||||
|
@ -28,6 +29,7 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
|
|||
STORE_32(gba->biosChecksum, 0, &state->biosChecksum);
|
||||
STORE_32(gba->romCrc32, 0, &state->romCrc32);
|
||||
STORE_32(gba->timing.masterCycles, 0, &state->masterCycles);
|
||||
STORE_64LE(gba->timing.globalCycles, 0, &state->globalCycles);
|
||||
|
||||
if (gba->memory.rom) {
|
||||
state->id = ((struct GBACartridge*) gba->memory.rom)->id;
|
||||
|
@ -93,7 +95,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
mLOG(GBA_STATE, WARN, "Savestate created using a different version of the BIOS: expected %08X, got %08X", gba->biosChecksum, ucheck);
|
||||
uint32_t pc;
|
||||
LOAD_32(pc, ARM_PC * sizeof(state->cpu.gprs[0]), state->cpu.gprs);
|
||||
if (pc < SIZE_BIOS && pc >= 0x20) {
|
||||
if ((ucheck == GBA_BIOS_CHECKSUM || gba->biosChecksum == GBA_BIOS_CHECKSUM) && pc < SIZE_BIOS && pc >= 0x20) {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
|
@ -128,6 +130,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
|
|||
}
|
||||
mTimingClear(&gba->timing);
|
||||
LOAD_32(gba->timing.masterCycles, 0, &state->masterCycles);
|
||||
LOAD_64LE(gba->timing.globalCycles, 0, &state->globalCycles);
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < 16; ++i) {
|
||||
|
|
|
@ -7,7 +7,7 @@ find_program(BANNERTOOL bannertool)
|
|||
find_program(MAKEROM makerom)
|
||||
find_program(PICASSO picasso)
|
||||
find_program(RAW2C raw2c)
|
||||
find_program(STRIP ${cross_prefix}strip)
|
||||
set(STRIP "${cross_prefix_path}strip" CACHE INTERNAL "symbol stripper")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format" PARENT_SCOPE)
|
||||
set(OS_DEFINES COLOR_16_BIT COLOR_5_6_5 IOAPI_NO_64)
|
||||
|
|
|
@ -1,92 +1,31 @@
|
|||
/* This code is mostly from ctrulib, which contains the following license:
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
* The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software in
|
||||
a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
* Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
* This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/srv.h>
|
||||
#include <3ds/gfx.h>
|
||||
#include <3ds/sdmc.h>
|
||||
#include <3ds/services/apt.h>
|
||||
#include <3ds/services/fs.h>
|
||||
#include <3ds/services/hid.h>
|
||||
#include <3ds/svc.h>
|
||||
/* Copyright (c) 2013-2020 Jeffrey Pfau
|
||||
*
|
||||
* 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 <3ds/archive.h>
|
||||
|
||||
#include <mgba-util/common.h>
|
||||
|
||||
extern char* fake_heap_start;
|
||||
extern char* fake_heap_end;
|
||||
extern u32 __ctru_linear_heap;
|
||||
extern u32 __ctru_heap;
|
||||
extern u32 __ctru_heap_size;
|
||||
extern u32 __ctru_linear_heap_size;
|
||||
static u32 __custom_heap_size = 0x02400000;
|
||||
static u32 __custom_linear_heap_size = 0x01400000;
|
||||
u32 __ctru_heap_size = 0x02400000;
|
||||
u32 __ctru_linear_heap_size = 0x01400000;
|
||||
|
||||
uint32_t* romBuffer = NULL;
|
||||
size_t romBufferSize;
|
||||
|
||||
FS_Archive sdmcArchive;
|
||||
|
||||
bool allocateRomBuffer(void) {
|
||||
if (romBuffer) {
|
||||
return true;
|
||||
}
|
||||
__attribute__((constructor)) static void init(void) {
|
||||
FSUSER_OpenArchive(&sdmcArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
|
||||
|
||||
romBuffer = malloc(0x02000000);
|
||||
if (romBuffer) {
|
||||
romBufferSize = 0x02000000;
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
romBuffer = malloc(0x01000000);
|
||||
if (romBuffer) {
|
||||
romBufferSize = 0x01000000;
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void __system_allocateHeaps() {
|
||||
u32 tmp=0;
|
||||
|
||||
__ctru_heap_size = __custom_heap_size;
|
||||
__ctru_linear_heap_size = __custom_linear_heap_size;
|
||||
|
||||
// Allocate the application heap
|
||||
__ctru_heap = 0x08000000;
|
||||
svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||
|
||||
// Allocate the linear heap
|
||||
svcControlMemory(&__ctru_linear_heap, 0x0, 0x0, __ctru_linear_heap_size, MEMOP_ALLOC_LINEAR, MEMPERM_READ | MEMPERM_WRITE);
|
||||
// Set up newlib heap
|
||||
fake_heap_start = (char*)__ctru_heap;
|
||||
fake_heap_end = fake_heap_start + __ctru_heap_size;
|
||||
}
|
||||
|
||||
void __appInit(void) {
|
||||
// Initialize services
|
||||
srvInit();
|
||||
aptInit();
|
||||
hidInit();
|
||||
|
||||
fsInit();
|
||||
sdmcInit();
|
||||
|
||||
FSUSER_OpenArchive(&sdmcArchive, ARCHIVE_SDMC, fsMakePath(PATH_EMPTY, ""));
|
||||
allocateRomBuffer();
|
||||
}
|
||||
|
|
|
@ -109,8 +109,6 @@ static bool sgbCrop = false;
|
|||
static aptHookCookie cookie;
|
||||
static bool core2;
|
||||
|
||||
extern bool allocateRomBuffer(void);
|
||||
|
||||
static bool _initGpu(void) {
|
||||
if (!C3D_Init(C3D_DEFAULT_CMDBUF_SIZE)) {
|
||||
return false;
|
||||
|
@ -124,7 +122,7 @@ static bool _initGpu(void) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!C3D_TexInitVRAM(&upscaleBufferTex, 512, 512, GPU_RB_RGB8)) {
|
||||
if (!C3D_TexInitVRAM(&upscaleBufferTex, 512, 512, GPU_RGB8)) {
|
||||
return false;
|
||||
}
|
||||
upscaleBuffer = C3D_RenderTargetCreateFromTex(&upscaleBufferTex, GPU_TEXFACE_2D, 0, 0);
|
||||
|
@ -810,10 +808,6 @@ int main() {
|
|||
camera.bufferSize = 0;
|
||||
camera.cam = SELECT_IN1;
|
||||
|
||||
if (!allocateRomBuffer()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
aptHook(&cookie, _aptHook, 0);
|
||||
|
||||
ptmuInit();
|
||||
|
|
|
@ -8,24 +8,27 @@ set(CMAKE_SYSTEM_NAME Generic CACHE INTERNAL "system name")
|
|||
|
||||
function(create_devkit DEVKIT)
|
||||
if(DEFINED ENV{DEVKIT${DEVKIT}})
|
||||
set(DEVKIT${DEVKIT} $ENV{DEVKIT${DEVKIT}} PARENT_SCOPE)
|
||||
set(DEVKIT${DEVKIT} $ENV{DEVKIT${DEVKIT}})
|
||||
else()
|
||||
set(DEVKIT${DEVKIT} ${DEVKITPRO}/devkit${DEVKIT} PARENT_SCOPE)
|
||||
set(DEVKIT${DEVKIT} ${DEVKITPRO}/devkit${DEVKIT})
|
||||
endif()
|
||||
set(DEVKIT${DEVKIT} "${DEVKIT${DEVKIT}}" PARENT_SCOPE)
|
||||
|
||||
set(CMAKE_PROGRAM_PATH ${DEVKIT${DEVKIT}}/bin CACHE INTERNAL "program path")
|
||||
set(CMAKE_PROGRAM_PATH "${DEVKIT${DEVKIT}}/bin" CACHE INTERNAL "program path")
|
||||
set(cross_prefix_path "${CMAKE_PROGRAM_PATH}/${cross_prefix}")
|
||||
set(cross_prefix_path "${cross_prefix_path}" PARENT_SCOPE)
|
||||
|
||||
set(extension)
|
||||
if (CMAKE_HOST_WIN32)
|
||||
set(extension .exe)
|
||||
endif()
|
||||
|
||||
find_program(CMAKE_AR ${cross_prefix}gcc-ar${extension})
|
||||
find_program(CMAKE_RANLIB ${cross_prefix}gcc-ranlib${extension})
|
||||
find_program(CMAKE_C_COMPILER ${cross_prefix}gcc${extension})
|
||||
find_program(CMAKE_CXX_COMPILER ${cross_prefix}g++${extension})
|
||||
find_program(CMAKE_ASM_COMPILER ${cross_prefix}gcc${extension})
|
||||
find_program(CMAKE_LINKER ${cross_prefix}ld${extension})
|
||||
set(CMAKE_AR "${cross_prefix_path}gcc-ar${extension}" CACHE INTERNAL "archiver")
|
||||
set(CMAKE_RANLIB "${cross_prefix_path}gcc-ranlib${extension}" CACHE INTERNAL "archiver")
|
||||
set(CMAKE_C_COMPILER "${cross_prefix_path}gcc${extension}" CACHE INTERNAL "c compiler")
|
||||
set(CMAKE_CXX_COMPILER "${cross_prefix_path}g++${extension}" CACHE INTERNAL "cxx compiler")
|
||||
set(CMAKE_ASM_COMPILER "${cross_prefix_path}gcc${extension}" CACHE INTERNAL "assembler")
|
||||
set(CMAKE_LINKER "${cross_prefix_path}ld${extension}" CACHE INTERNAL "linker")
|
||||
set(CMAKE_C_FLAGS ${inc_flags} CACHE INTERNAL "c compiler flags")
|
||||
set(CMAKE_ASM_FLAGS ${inc_flags} CACHE INTERNAL "assembler flags")
|
||||
set(CMAKE_CXX_FLAGS ${inc_flags} CACHE INTERNAL "cxx compiler flags")
|
||||
|
|
|
@ -292,7 +292,10 @@ endif()
|
|||
if(QT_STATIC)
|
||||
find_library(QTPCRE NAMES qtpcre2 qtpcre)
|
||||
if(WIN32)
|
||||
list(APPEND QT_LIBRARIES qwindows dwmapi imm32 uxtheme Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport Qt5WindowsUIAutomationSupport)
|
||||
if(CMAKE_CROSSCOMPILING)
|
||||
set(QWINDOWS_DEPS Qt5EventDispatcherSupport Qt5FontDatabaseSupport Qt5ThemeSupport Qt5WindowsUIAutomationSupport)
|
||||
endif()
|
||||
list(APPEND QT_LIBRARIES Qt5::QWindowsIntegrationPlugin ${QWINDOWS_DEPS} dwmapi uxtheme imm32 -static-libgcc -static-libstdc++)
|
||||
set_target_properties(Qt5::Core PROPERTIES INTERFACE_LINK_LIBRARIES "${QTPCRE};version;winmm;ssl;crypto;ws2_32;iphlpapi;crypt32;userenv;netapi32;wtsapi32")
|
||||
set_target_properties(Qt5::Gui PROPERTIES INTERFACE_LINK_LIBRARIES ${OPENGL_LIBRARY} ${OPENGLES2_LIBRARY})
|
||||
elseif(APPLE)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -58,10 +58,6 @@ struct PerfOpts {
|
|||
bool server;
|
||||
};
|
||||
|
||||
#ifdef _3DS
|
||||
extern bool allocateRomBuffer(void);
|
||||
FS_Archive sdmcArchive;
|
||||
#endif
|
||||
#ifdef __SWITCH__
|
||||
TimeType __nx_time_type = TimeType_LocalSystemClock;
|
||||
#endif
|
||||
|
@ -85,9 +81,6 @@ int main(int argc, char** argv) {
|
|||
gfxInitDefault();
|
||||
osSetSpeedupEnable(true);
|
||||
consoleInit(GFX_BOTTOM, NULL);
|
||||
if (!allocateRomBuffer()) {
|
||||
return 1;
|
||||
}
|
||||
#elif defined(__SWITCH__)
|
||||
UNUSED(_mPerfShutdown);
|
||||
consoleInit(NULL);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <mgba/internal/sm83/debugger/cli-debugger.h>
|
||||
|
||||
#include <mgba/core/core.h>
|
||||
#include <mgba/core/timing.h>
|
||||
#include <mgba/internal/debugger/cli-debugger.h>
|
||||
#include <mgba/internal/sm83/decoder.h>
|
||||
#include <mgba/internal/sm83/debugger/debugger.h>
|
||||
|
@ -88,6 +89,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
|
|||
be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl);
|
||||
be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp);
|
||||
_printFlags(be, cpu->f);
|
||||
be->printf(be, "T-cycle: %" PRIu64 "\n", mTimingGlobalTime(debugger->p->d.core->timing));
|
||||
|
||||
struct SM83Debugger* platDebugger = (struct SM83Debugger*) debugger->p->d.platform;
|
||||
size_t i;
|
||||
|
|
Loading…
Reference in New Issue