remove vendored code

This commit is contained in:
Corwin 2021-07-02 15:35:34 +00:00 committed by GitHub
parent 0cafd8eaca
commit 2bbb755138
140 changed files with 0 additions and 13317 deletions

View file

@ -1,38 +0,0 @@
/* Copyright (c) 2013-2014 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 CIRCLE_BUFFER_H
#define CIRCLE_BUFFER_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct CircleBuffer {
void* data;
size_t capacity;
size_t size;
void* readPtr;
void* writePtr;
};
void CircleBufferInit(struct CircleBuffer* buffer, unsigned capacity);
void CircleBufferDeinit(struct CircleBuffer* buffer);
size_t CircleBufferSize(const struct CircleBuffer* buffer);
size_t CircleBufferCapacity(const struct CircleBuffer* buffer);
void CircleBufferClear(struct CircleBuffer* buffer);
int CircleBufferWrite8(struct CircleBuffer* buffer, int8_t value);
int CircleBufferWrite16(struct CircleBuffer* buffer, int16_t value);
int CircleBufferWrite32(struct CircleBuffer* buffer, int32_t value);
size_t CircleBufferWrite(struct CircleBuffer* buffer, const void* input, size_t length);
int CircleBufferRead8(struct CircleBuffer* buffer, int8_t* value);
int CircleBufferRead16(struct CircleBuffer* buffer, int16_t* value);
int CircleBufferRead32(struct CircleBuffer* buffer, int32_t* value);
size_t CircleBufferRead(struct CircleBuffer* buffer, void* output, size_t length);
size_t CircleBufferDump(const struct CircleBuffer* buffer, void* output, size_t length);
CXX_GUARD_END
#endif

View file

@ -1,306 +0,0 @@
/* Copyright (c) 2013-2014 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 COMMON_H
#define COMMON_H
#ifdef __cplusplus
#define CXX_GUARD_START extern "C" {
#define CXX_GUARD_END }
#else
#define CXX_GUARD_START
#define CXX_GUARD_END
#endif
#ifdef __MINGW32__
#define __USE_MINGW_ANSI_STDIO 1
#endif
CXX_GUARD_START
#include <ctype.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef _WIN32
// WinSock2 gets very angry if it's included too late
#include <winsock2.h>
#endif
#if defined(_MSC_VER) || defined(__cplusplus)
#define restrict __restrict
#endif
#ifdef _MSC_VER
#include <Windows.h>
#include <sys/types.h>
typedef intptr_t ssize_t;
#define PATH_MAX MAX_PATH
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define ftruncate _chsize
#define snprintf _snprintf
#define strdup _strdup
#define lseek _lseek
#define O_ACCMODE (O_RDONLY|O_WRONLY|O_RDWR)
#else
#include <strings.h>
#include <unistd.h>
#include <sys/time.h>
#endif
#ifdef GEKKO
typedef intptr_t ssize_t;
#endif
#ifdef PSP2
// For PATH_MAX on modern toolchains
#include <sys/syslimits.h>
#endif
#include <mgba-util/dllexports.h>
#ifndef SSIZE_MAX
#define SSIZE_MAX ((ssize_t) (SIZE_MAX >> 1))
#endif
#ifndef UNUSED
#define UNUSED(V) (void)(V)
#endif
#ifndef M_PI
#define M_PI 3.141592654f
#endif
#if !defined(_MSC_VER) && (defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
#define ATOMIC_STORE(DST, SRC) __atomic_store_n(&DST, SRC, __ATOMIC_RELEASE)
#define ATOMIC_LOAD(DST, SRC) DST = __atomic_load_n(&SRC, __ATOMIC_ACQUIRE)
#define ATOMIC_ADD(DST, OP) __atomic_add_fetch(&DST, OP, __ATOMIC_RELEASE)
#define ATOMIC_SUB(DST, OP) __atomic_sub_fetch(&DST, OP, __ATOMIC_RELEASE)
#define ATOMIC_OR(DST, OP) __atomic_or_fetch(&DST, OP, __ATOMIC_RELEASE)
#define ATOMIC_AND(DST, OP) __atomic_and_fetch(&DST, OP, __ATOMIC_RELEASE)
#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) __atomic_compare_exchange_n(&DST, &EXPECTED, SRC, true,__ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)
#define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC)
#define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC)
#elif defined _MSC_VER
#define ATOMIC_STORE(DST, SRC) InterlockedExchange(&DST, SRC)
#define ATOMIC_LOAD(DST, SRC) DST = InterlockedOrAcquire(&SRC, 0)
#define ATOMIC_ADD(DST, OP) InterlockedAddRelease(&DST, OP)
#define ATOMIC_SUB(DST, OP) InterlockedAddRelease(&DST, -OP)
#define ATOMIC_OR(DST, OP) InterlockedOrRelease(&DST, OP)
#define ATOMIC_AND(DST, OP) InterlockedAndRelease(&DST, OP)
#define ATOMIC_CMPXCHG(DST, EXPECTED, SRC) (InterlockedCompareExchange(&DST, SRC, EXPECTED) == EXPECTED)
#define ATOMIC_STORE_PTR(DST, SRC) InterlockedExchangePointer(&DST, SRC)
#define ATOMIC_LOAD_PTR(DST, SRC) DST = InterlockedCompareExchangePointer(&SRC, 0, 0)
#else
// TODO
#define ATOMIC_STORE(DST, SRC) DST = SRC
#define ATOMIC_LOAD(DST, SRC) DST = SRC
#define ATOMIC_ADD(DST, OP) DST += OP
#define ATOMIC_SUB(DST, OP) DST -= OP
#define ATOMIC_OR(DST, OP) DST |= OP
#define ATOMIC_AND(DST, OP) DST &= OP
#define ATOMIC_CMPXCHG(DST, EXPECTED, OP) ((DST == EXPECTED) ? ((DST = OP), true) : false)
#define ATOMIC_STORE_PTR(DST, SRC) ATOMIC_STORE(DST, SRC)
#define ATOMIC_LOAD_PTR(DST, SRC) ATOMIC_LOAD(DST, SRC)
#endif
#if defined(_3DS) || defined(GEKKO) || defined(PSP2)
// newlib doesn't support %z properly by default
#define PRIz ""
#elif defined(_MSC_VER)
#define PRIz "I"
#else
#define PRIz "z"
#endif
#if defined __BIG_ENDIAN__
#define LOAD_64BE(DEST, ADDR, ARR) DEST = *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#define LOAD_32BE(DEST, ADDR, ARR) DEST = *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#define LOAD_16BE(DEST, ADDR, ARR) DEST = *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#define STORE_64BE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
#define STORE_32BE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
#define STORE_16BE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
#if defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
#define LOAD_64LE(DEST, ADDR, ARR) DEST = __builtin_bswap64(*(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define LOAD_32LE(DEST, ADDR, ARR) DEST = __builtin_bswap32(*(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define LOAD_16LE(DEST, ADDR, ARR) DEST = __builtin_bswap16(*(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define STORE_64LE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = __builtin_bswap64(SRC)
#define STORE_32LE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = __builtin_bswap32(SRC)
#define STORE_16LE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = __builtin_bswap16(SRC)
#elif defined(__PPC__) || defined(__POWERPC__)
#define LOAD_32LE(DEST, ADDR, ARR) { \
size_t _addr = (ADDR); \
const void* _ptr = (ARR); \
__asm__("lwbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \
}
#define LOAD_16LE(DEST, ADDR, ARR) { \
size_t _addr = (ADDR); \
const void* _ptr = (ARR); \
__asm__("lhbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \
}
#define STORE_32LE(SRC, ADDR, ARR) { \
size_t _addr = (ADDR); \
void* _ptr = (ARR); \
__asm__("stwbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \
}
#define STORE_16LE(SRC, ADDR, ARR) { \
size_t _addr = (ADDR); \
void* _ptr = (ARR); \
__asm__("sthbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \
}
#ifndef _ARCH_PWR7
#define LOAD_64LE(DEST, ADDR, ARR) { \
size_t _addr = (ADDR); \
union { \
struct { \
uint32_t hi; \
uint32_t lo; \
}; \
uint64_t b64; \
} bswap; \
const void* _ptr = (ARR); \
__asm__( \
"lwbrx %0, %2, %3 \n" \
"lwbrx %1, %2, %4 \n" \
: "=&r"(bswap.lo), "=&r"(bswap.hi) : "b"(_ptr), "r"(_addr), "r"(_addr + 4)) ; \
DEST = bswap.b64; \
}
#define STORE_64LE(SRC, ADDR, ARR) { \
size_t _addr = (ADDR); \
union { \
struct { \
uint32_t hi; \
uint32_t lo; \
}; \
uint64_t b64; \
} bswap = { .b64 = SRC }; \
const void* _ptr = (ARR); \
__asm__( \
"stwbrx %0, %2, %3 \n" \
"stwbrx %1, %2, %4 \n" \
: : "r"(bswap.hi), "r"(bswap.lo), "b"(_ptr), "r"(_addr), "r"(_addr + 4) : "memory"); \
}
#else
#define LOAD_64LE(DEST, ADDR, ARR) { \
size_t _addr = (ADDR); \
const void* _ptr = (ARR); \
__asm__("ldbrx %0, %1, %2" : "=r"(DEST) : "b"(_ptr), "r"(_addr)); \
}
#define STORE_64LE(SRC, ADDR, ARR) { \
size_t _addr = (ADDR); \
void* _ptr = (ARR); \
__asm__("stdbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr) : "memory"); \
}
#endif
#else
#error Big endian build not supported on this platform.
#endif
#else
#define LOAD_64LE(DEST, ADDR, ARR) DEST = *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#define LOAD_32LE(DEST, ADDR, ARR) DEST = *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#define LOAD_16LE(DEST, ADDR, ARR) DEST = *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#define STORE_64LE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
#define STORE_32LE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
#define STORE_16LE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
#ifdef _MSC_VER
#define LOAD_64BE(DEST, ADDR, ARR) DEST = _byteswap_uint64(*(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define LOAD_32BE(DEST, ADDR, ARR) DEST = _byteswap_ulong(*(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define LOAD_16BE(DEST, ADDR, ARR) DEST = _byteswap_ushort(*(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define STORE_64BE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = _byteswap_uint64(SRC)
#define STORE_32BE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = _byteswap_ulong(SRC)
#define STORE_16BE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = _byteswap_ushort(SRC)
#else
#define LOAD_64BE(DEST, ADDR, ARR) DEST = __builtin_bswap64(*(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define LOAD_32BE(DEST, ADDR, ARR) DEST = __builtin_bswap32(*(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define LOAD_16BE(DEST, ADDR, ARR) DEST = __builtin_bswap16(*(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)))
#define STORE_64BE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = __builtin_bswap64(SRC)
#define STORE_32BE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = __builtin_bswap32(SRC)
#define STORE_16BE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = __builtin_bswap16(SRC)
#endif
#endif
#define MAKE_MASK(START, END) (((1 << ((END) - (START))) - 1) << (START))
#define CHECK_BITS(SRC, START, END) ((SRC) & MAKE_MASK(START, END))
#define EXT_BITS(SRC, START, END) (((SRC) >> (START)) & ((1 << ((END) - (START))) - 1))
#define INS_BITS(SRC, START, END, BITS) (CLEAR_BITS(SRC, START, END) | (((BITS) << (START)) & MAKE_MASK(START, END)))
#define CLEAR_BITS(SRC, START, END) ((SRC) & ~MAKE_MASK(START, END))
#define FILL_BITS(SRC, START, END) ((SRC) | MAKE_MASK(START, END))
#define TEST_FILL_BITS(SRC, START, END, TEST) ((TEST) ? (FILL_BITS(SRC, START, END)) : (CLEAR_BITS(SRC, START, END)))
#ifdef _MSC_VER
#pragma section(".CRT$XCU",read)
#define ATTRIBUTE_UNUSED
#define ATTRIBUTE_FORMAT(X, Y, Z)
#define ATTRIBUTE_NOINLINE
// Adapted from https://stackoverflow.com/a/2390626
#define _CONSTRUCTOR(FN, PRE) \
static void FN(void); \
__declspec(allocate(".CRT$XCU")) void (*_CONSTRUCTOR_ ## FN)(void) = FN; \
static void FN(void)
#ifdef _WIN64
#define CONSTRUCTOR(FN) _CONSTRUCTOR(FN, "")
#else
#define CONSTRUCTOR(FN) _CONSTRUCTOR(FN, "_")
#endif
#else
#define ATTRIBUTE_UNUSED __attribute__((unused))
#define ATTRIBUTE_FORMAT(X, Y, Z) __attribute__((format(X, Y, Z)))
#define ATTRIBUTE_NOINLINE __attribute__((noinline))
#define CONSTRUCTOR(FN) static __attribute__((constructor)) void FN(void)
#endif
#define DECL_BITFIELD(NAME, TYPE) typedef TYPE NAME
#define DECL_BITS(TYPE, FIELD, START, SIZE) \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Is ## FIELD (TYPE src) { \
return CHECK_BITS(src, (START), (START) + (SIZE)); \
} \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Get ## FIELD (TYPE src) { \
return EXT_BITS(src, (START), (START) + (SIZE)); \
} \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Clear ## FIELD (TYPE src) { \
return CLEAR_BITS(src, (START), (START) + (SIZE)); \
} \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Fill ## FIELD (TYPE src) { \
return FILL_BITS(src, (START), (START) + (SIZE)); \
} \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## Set ## FIELD (TYPE src, TYPE bits) { \
return INS_BITS(src, (START), (START) + (SIZE), bits); \
} \
ATTRIBUTE_UNUSED static inline TYPE TYPE ## TestFill ## FIELD (TYPE src, bool test) { \
return TEST_FILL_BITS(src, (START), (START) + (SIZE), test); \
}
#define DECL_BIT(TYPE, FIELD, BIT) DECL_BITS(TYPE, FIELD, BIT, 1)
#ifndef _MSC_VER
#define LIKELY(X) __builtin_expect(!!(X), 1)
#define UNLIKELY(X) __builtin_expect(!!(X), 0)
#else
#define LIKELY(X) (!!(X))
#define UNLIKELY(X) (!!(X))
#endif
#define ROR(I, ROTATE) ((((uint32_t) (I)) >> ROTATE) | ((uint32_t) (I) << ((-ROTATE) & 31)))
CXX_GUARD_END
#endif

View file

@ -1,46 +0,0 @@
/* Copyright (c) 2013-2014 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 CONFIGURATION_H
#define CONFIGURATION_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/table.h>
struct VFile;
struct Configuration {
struct Table sections;
struct Table root;
};
void ConfigurationInit(struct Configuration*);
void ConfigurationDeinit(struct Configuration*);
void ConfigurationSetValue(struct Configuration*, const char* section, const char* key, const char* value);
void ConfigurationSetIntValue(struct Configuration*, const char* section, const char* key, int value);
void ConfigurationSetUIntValue(struct Configuration*, const char* section, const char* key, unsigned value);
void ConfigurationSetFloatValue(struct Configuration*, const char* section, const char* key, float value);
bool ConfigurationHasSection(const struct Configuration*, const char* section);
const char* ConfigurationGetValue(const struct Configuration*, const char* section, const char* key);
void ConfigurationClearValue(struct Configuration*, const char* section, const char* key);
bool ConfigurationRead(struct Configuration*, const char* path);
bool ConfigurationReadVFile(struct Configuration*, struct VFile* vf);
bool ConfigurationWrite(const struct Configuration*, const char* path);
bool ConfigurationWriteSection(const struct Configuration*, const char* path, const char* section);
bool ConfigurationWriteVFile(const struct Configuration*, struct VFile* vf);
void ConfigurationEnumerateSections(const struct Configuration* configuration, void (*handler)(const char* sectionName, void* user), void* user);
void ConfigurationEnumerate(const struct Configuration* configuration, const char* section, void (*handler)(const char* key, const char* value, void* user), void* user);
CXX_GUARD_END
#endif

View file

@ -1,26 +0,0 @@
/* Copyright (c) 2013-2014 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 CRC32_H
#define CRC32_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct VFile;
#ifndef HAVE_CRC32
uint32_t crc32(uint32_t crc, const void* buf, size_t size);
#else
#include <zlib.h>
#endif
uint32_t doCrc32(const void* buf, size_t size);
uint32_t fileCrc32(struct VFile* file, size_t endOffset);
CXX_GUARD_END
#endif

View file

@ -1,19 +0,0 @@
/* 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

View file

@ -1,45 +0,0 @@
/* Copyright (c) 2013-2017 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 ELF_READ_H
#define ELF_READ_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifdef USE_ELF
#include <libelf.h>
#include <mgba-util/vector.h>
struct ELF;
struct VFile;
DECLARE_VECTOR(ELFProgramHeaders, Elf32_Phdr);
DECLARE_VECTOR(ELFSectionHeaders, Elf32_Shdr);
struct ELF* ELFOpen(struct VFile*);
void ELFClose(struct ELF*);
void* ELFBytes(struct ELF*, size_t* size);
uint16_t ELFMachine(struct ELF*);
uint32_t ELFEntry(struct ELF*);
void ELFGetProgramHeaders(struct ELF*, struct ELFProgramHeaders*);
size_t ELFFindSection(struct ELF*, const char* name);
void ELFGetSectionHeaders(struct ELF*, struct ELFSectionHeaders*);
Elf32_Shdr* ELFGetSectionHeader(struct ELF*, size_t index);
const char* ELFGetString(struct ELF*, size_t section, size_t string);
#endif
CXX_GUARD_END
#endif

View file

@ -1,20 +0,0 @@
/* Copyright (c) 2013-2015 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 EXPORT_H
#define EXPORT_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct VFile;
bool exportPaletteRIFF(struct VFile* vf, size_t entries, const uint16_t* colors);
bool exportPaletteACT(struct VFile* vf, size_t entries, const uint16_t* colors);
CXX_GUARD_END
#endif

View file

@ -1,36 +0,0 @@
/* Copyright (c) 2013-2015 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 FORMATTING_H
#define FORMATTING_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include "locale.h"
#ifdef HAVE_XLOCALE
#include <xlocale.h>
#elif !defined(HAVE_LOCALE)
typedef const char* locale_t;
#endif
int ftostr_l(char* restrict str, size_t size, float f, locale_t locale);
#ifndef HAVE_STRTOF_L
float strtof_l(const char* restrict str, char** restrict end, locale_t locale);
#endif
int ftostr_u(char* restrict str, size_t size, float f);
float strtof_u(const char* restrict str, char** restrict end);
#ifndef HAVE_LOCALTIME_R
struct tm* localtime_r(const time_t* timep, struct tm* result);
#endif
CXX_GUARD_END
#endif

View file

@ -1,92 +0,0 @@
/* Copyright (c) 2013-2015 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 GUI_H
#define GUI_H
#include <mgba-util/common.h>
CXX_GUARD_START
// TODO: Fix layering violation
#include <mgba/core/input.h>
#include <mgba-util/vector.h>
struct GUIFont;
enum GUIInput {
GUI_INPUT_NONE = -1,
GUI_INPUT_SELECT = 0,
GUI_INPUT_BACK,
GUI_INPUT_CANCEL,
GUI_INPUT_UP,
GUI_INPUT_DOWN,
GUI_INPUT_LEFT,
GUI_INPUT_RIGHT,
GUI_INPUT_USER_START = 0x8,
GUI_INPUT_MAX = 0x20
};
enum GUICursorState {
GUI_CURSOR_NOT_PRESENT = 0,
GUI_CURSOR_UP,
GUI_CURSOR_DOWN,
GUI_CURSOR_CLICKED,
GUI_CURSOR_DRAGGING
};
enum {
BATTERY_EMPTY = 0,
BATTERY_LOW = 25,
BATTERY_HALF = 50,
BATTERY_HIGH = 75,
BATTERY_FULL = 100,
BATTERY_VALUE = 0x7F,
BATTERY_PERCENTAGE_VALID = 0x80,
BATTERY_CHARGING = 0x100,
BATTERY_NOT_PRESENT = 0x200,
};
struct GUIBackground {
void (*draw)(struct GUIBackground*, void* context);
};
struct GUIParams {
unsigned width;
unsigned height;
struct GUIFont* font;
const char* basePath;
void (*drawStart)(void);
void (*drawEnd)(void);
uint32_t (*pollInput)(const struct mInputMap*);
enum GUICursorState (*pollCursor)(unsigned* x, unsigned* y);
int (*batteryState)(void);
void (*guiPrepare)(void);
void (*guiFinish)(void);
// State
struct mInputMap keyMap;
int inputHistory[GUI_INPUT_MAX];
enum GUICursorState cursorState;
int cx, cy;
// Directories
char currentPath[PATH_MAX];
size_t fileIndex;
};
void GUIInit(struct GUIParams* params);
void GUIPollInput(struct GUIParams* params, uint32_t* newInput, uint32_t* heldInput);
enum GUICursorState GUIPollCursor(struct GUIParams* params, unsigned* x, unsigned* y);
void GUIInvalidateKeys(struct GUIParams* params);
CXX_GUARD_END
#endif

View file

@ -1,21 +0,0 @@
/* Copyright (c) 2013-2015 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 GUI_FILE_CHOOSER_H
#define GUI_FILE_CHOOSER_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/gui.h>
struct VFile;
bool GUISelectFile(struct GUIParams*, char* outPath, size_t outLen, bool (*filterName)(const char* name), bool (*filterContents)(struct VFile*), const char* preselect);
CXX_GUARD_END
#endif

View file

@ -1,14 +0,0 @@
/* Copyright (c) 2013-2015 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 DEFAULT_FONT_METRICS_H
#define DEFAULT_FONT_METRICS_H
#include <mgba-util/gui/font.h>
extern struct GUIFontGlyphMetric defaultFontMetrics[];
extern struct GUIIconMetric defaultIconMetrics[];
#endif

View file

@ -1,97 +0,0 @@
/* Copyright (c) 2013-2015 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 GUI_FONT_H
#define GUI_FONT_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct GUIFont;
struct GUIFont* GUIFontCreate(void);
void GUIFontDestroy(struct GUIFont*);
enum GUIAlignment {
GUI_ALIGN_LEFT = 1,
GUI_ALIGN_HCENTER = 3,
GUI_ALIGN_RIGHT = 2,
GUI_ALIGN_TOP = 4,
GUI_ALIGN_VCENTER = 12,
GUI_ALIGN_BOTTOM = 8,
};
enum GUIOrientation {
GUI_ORIENT_0,
GUI_ORIENT_90_CCW,
GUI_ORIENT_180,
GUI_ORIENT_270_CCW,
GUI_ORIENT_VMIRROR,
GUI_ORIENT_HMIRROR,
GUI_ORIENT_90_CW = GUI_ORIENT_270_CCW,
GUI_ORIENT_270_CW = GUI_ORIENT_90_CCW
};
enum GUIIcon {
GUI_ICON_BATTERY_FULL,
GUI_ICON_BATTERY_HIGH,
GUI_ICON_BATTERY_HALF,
GUI_ICON_BATTERY_LOW,
GUI_ICON_BATTERY_EMPTY,
GUI_ICON_SCROLLBAR_THUMB,
GUI_ICON_SCROLLBAR_TRACK,
GUI_ICON_SCROLLBAR_BUTTON,
GUI_ICON_CURSOR,
GUI_ICON_POINTER,
GUI_ICON_BUTTON_CIRCLE,
GUI_ICON_BUTTON_CROSS,
GUI_ICON_BUTTON_TRIANGLE,
GUI_ICON_BUTTON_SQUARE,
GUI_ICON_BUTTON_HOME,
GUI_ICON_STATUS_FAST_FORWARD,
GUI_ICON_STATUS_MUTE,
GUI_ICON_MAX,
};
struct GUIFontGlyphMetric {
int width;
int height;
struct {
int top;
int right;
int bottom;
int left;
} padding;
};
struct GUIIconMetric {
int x;
int y;
int width;
int height;
};
unsigned GUIFontHeight(const struct GUIFont*);
unsigned GUIFontGlyphWidth(const struct GUIFont*, uint32_t glyph);
unsigned GUIFontSpanWidth(const struct GUIFont*, const char* text);
void GUIFontIconMetrics(const struct GUIFont*, enum GUIIcon icon, unsigned* w, unsigned* h);
ATTRIBUTE_FORMAT(printf, 6, 7)
void GUIFontPrintf(struct GUIFont*, int x, int y, enum GUIAlignment, uint32_t color, const char* text, ...);
void GUIFontPrint(struct GUIFont*, int x, int y, enum GUIAlignment, uint32_t color, const char* text);
void GUIFontDrawGlyph(struct GUIFont*, int x, int y, uint32_t color, uint32_t glyph);
void GUIFontDrawIcon(struct GUIFont*, int x, int y, enum GUIAlignment, enum GUIOrientation, uint32_t color, enum GUIIcon);
void GUIFontDrawIconSize(struct GUIFont* font, int x, int y, int w, int h, uint32_t color, enum GUIIcon icon);
#ifdef __SWITCH__
void GUIFontDrawSubmit(struct GUIFont* font);
#endif
CXX_GUARD_END
#endif

View file

@ -1,83 +0,0 @@
/* Copyright (c) 2013-2015 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 GUI_MENU_H
#define GUI_MENU_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/vector.h>
#define GUI_V_V (struct GUIVariant) { .type = GUI_VARIANT_VOID }
#define GUI_V_U(U) (struct GUIVariant) { .type = GUI_VARIANT_UNSIGNED, .v.u = (U) }
#define GUI_V_I(I) (struct GUIVariant) { .type = GUI_VARIANT_INT, .v.i = (I) }
#define GUI_V_F(F) (struct GUIVariant) { .type = GUI_VARIANT_FLOAT, .v.f = (F) }
#define GUI_V_S(S) (struct GUIVariant) { .type = GUI_VARIANT_STRING, .v.s = (S) }
enum GUIVariantType {
GUI_VARIANT_VOID = 0,
GUI_VARIANT_UNSIGNED,
GUI_VARIANT_INT,
GUI_VARIANT_FLOAT,
GUI_VARIANT_STRING
};
struct GUIVariant {
enum GUIVariantType type;
union {
unsigned u;
int i;
float f;
const char* s;
} v;
};
struct GUIMenu;
struct GUIMenuItem {
const char* title;
void* data;
unsigned state;
const char* const* validStates;
const struct GUIVariant* stateMappings;
unsigned nStates;
struct GUIMenu* submenu;
};
DECLARE_VECTOR(GUIMenuItemList, struct GUIMenuItem);
struct GUIBackground;
struct GUIMenu {
const char* title;
const char* subtitle;
struct GUIMenuItemList items;
size_t index;
struct GUIBackground* background;
};
enum GUIMenuExitReason {
GUI_MENU_EXIT_ACCEPT,
GUI_MENU_EXIT_BACK,
GUI_MENU_EXIT_CANCEL,
};
enum GUIMessageBoxButtons {
GUI_MESSAGE_BOX_OK = 1,
GUI_MESSAGE_BOX_CANCEL = 2
};
struct GUIParams;
enum GUIMenuExitReason GUIShowMenu(struct GUIParams* params, struct GUIMenu* menu, struct GUIMenuItem** item);
ATTRIBUTE_FORMAT(printf, 4, 5)
enum GUIMenuExitReason GUIShowMessageBox(struct GUIParams* params, int buttons, int frames, const char* format, ...);
void GUIDrawBattery(struct GUIParams* params);
void GUIDrawClock(struct GUIParams* params);
CXX_GUARD_END
#endif

View file

@ -1,17 +0,0 @@
/* Copyright (c) 2013-2014 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 HASH_H
#define HASH_H
#include <mgba-util/common.h>
CXX_GUARD_START
uint32_t hash32(const void* key, int len, uint32_t seed);
CXX_GUARD_END
#endif

View file

@ -1,106 +0,0 @@
/* Copyright (c) 2013-2015 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 UTIL_MATH_H
#define UTIL_MATH_H
#include <mgba-util/common.h>
CXX_GUARD_START
static inline uint32_t popcount32(unsigned bits) {
bits = bits - ((bits >> 1) & 0x55555555);
bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333);
return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24;
}
static inline unsigned clz32(uint32_t bits) {
#if defined(__GNUC__) || __clang__
if (!bits) {
return 32;
}
return __builtin_clz(bits);
#else
static const int table[256] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
if (bits & 0xFF000000) {
return table[bits >> 24];
} else if (bits & 0x00FF0000) {
return table[bits >> 16] + 8;
} else if (bits & 0x0000FF00) {
return table[bits >> 8] + 16;
}
return table[bits] + 24;
#endif
}
static inline uint32_t toPow2(uint32_t bits) {
if (!bits) {
return 0;
}
unsigned lz = clz32(bits - 1);
return 1 << (32 - lz);
}
static inline int reduceFraction(int* num, int* den) {
int n = *num;
int d = *den;
while (d != 0) {
int temp = n % d;
n = d;
d = temp;
}
*num /= n;
*den /= n;
return n;
}
#define TYPE_GENERICIZE(MACRO) \
MACRO(int, Int) \
MACRO(unsigned, UInt)
#define LOCK_ASPECT_RATIO(T, t) \
static inline void lockAspectRatio ## t(T refW, T refH, T* w, T* h) { \
if (*w * refH > *h * refW) { \
*w = *h * refW / refH; \
} else if (*w * refH < *h * refW) { \
*h = *w * refH / refW; \
} \
}
TYPE_GENERICIZE(LOCK_ASPECT_RATIO)
#undef LOCK_ASPECT_RATIO
#define LOCK_INTEGER_RATIO(T, t) \
static inline void lockIntegerRatio ## t(T ref, T* val) { \
if (*val >= ref) { \
*val -= *val % ref; \
} \
}
TYPE_GENERICIZE(LOCK_INTEGER_RATIO)
#undef LOCK_INTEGER_RATIO
#undef TYPE_GENERICIZE
CXX_GUARD_END
#endif

View file

@ -1,18 +0,0 @@
/* Copyright (c) 2013-2014 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 MEMORY_H
#define MEMORY_H
#include <mgba-util/common.h>
CXX_GUARD_START
void* anonymousMemoryMap(size_t size);
void mappedMemoryFree(void* memory, size_t size);
CXX_GUARD_END
#endif

View file

@ -1,26 +0,0 @@
/* Copyright (c) 2013-2014 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 PATCH_H
#define PATCH_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct VFile;
struct Patch {
struct VFile* vf;
size_t (*outputSize)(struct Patch* patch, size_t inSize);
bool (*applyPatch)(struct Patch* patch, const void* in, size_t inSize, void* out, size_t outSize);
};
bool loadPatch(struct VFile* vf, struct Patch* patch);
CXX_GUARD_END
#endif

View file

@ -1,38 +0,0 @@
/* Copyright (c) 2013-2016 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 PATCH_FAST_H
#define PATCH_FAST_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/patch.h>
#include <mgba-util/vector.h>
#define PATCH_FAST_EXTENT 128
struct PatchFastExtent {
size_t length;
size_t offset;
uint32_t extent[PATCH_FAST_EXTENT];
};
DECLARE_VECTOR(PatchFastExtents, struct PatchFastExtent);
struct PatchFast {
struct Patch d;
struct PatchFastExtents extents;
};
void initPatchFast(struct PatchFast*);
void deinitPatchFast(struct PatchFast*);
bool diffPatchFast(struct PatchFast* patch, const void* restrict in, const void* restrict out, size_t size);
CXX_GUARD_END
#endif

View file

@ -1,19 +0,0 @@
/* Copyright (c) 2013-2014 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 PATCH_IPS_H
#define PATCH_IPS_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct Patch;
bool loadPatchIPS(struct Patch* patch);
CXX_GUARD_END
#endif

View file

@ -1,19 +0,0 @@
/* Copyright (c) 2013-2014 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 PATCH_UPS_H
#define PATCH_UPS_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct Patch;
bool loadPatchUPS(struct Patch* patch);
CXX_GUARD_END
#endif

View file

@ -1,17 +0,0 @@
/* Copyright (c) 2013-2014 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 N3DS_VFS_H
#define N3DS_VFS_H
#include <mgba-util/vfs.h>
#include <3ds.h>
extern FS_Archive sdmcArchive;
struct VFile* VFileOpen3DS(FS_Archive* archive, const char* path, int flags);
#endif

View file

@ -1,87 +0,0 @@
/* Copyright (c) 2013-2015 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 N3DS_THREADING_H
#define N3DS_THREADING_H
#include <mgba-util/common.h>
#include <3ds.h>
#include <malloc.h>
#define THREAD_ENTRY void
typedef ThreadFunc ThreadEntry;
typedef LightLock Mutex;
typedef CondVar Condition;
static inline int MutexInit(Mutex* mutex) {
LightLock_Init(mutex);
return 0;
}
static inline int MutexDeinit(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int MutexLock(Mutex* mutex) {
LightLock_Lock(mutex);
return 0;
}
static inline int MutexTryLock(Mutex* mutex) {
return LightLock_TryLock(mutex);
}
static inline int MutexUnlock(Mutex* mutex) {
LightLock_Unlock(mutex);
return 0;
}
static inline int ConditionInit(Condition* cond) {
CondVar_Init(cond);
return 0;
}
static inline int ConditionDeinit(Condition* cond) {
UNUSED(cond);
return 0;
}
static inline int ConditionWait(Condition* cond, Mutex* mutex) {
CondVar_Wait(cond, mutex);
return 0;
}
static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
return CondVar_WaitTimeout(cond, mutex, timeoutMs * 10000000LL);
}
static inline int ConditionWake(Condition* cond) {
CondVar_Signal(cond);
return 0;
}
static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
if (!entry || !thread) {
return 1;
}
*thread = threadCreate(entry, context, 0x8000, 0x18, 2, false);
return !*thread;
}
static inline int ThreadJoin(Thread* thread) {
Result res = threadJoin(*thread, U64_MAX);
threadFree(*thread);
return res;
}
static inline void ThreadSetName(const char* name) {
UNUSED(name);
// Unimplemented
}
#endif

View file

@ -1,119 +0,0 @@
/* Copyright (c) 2013-2015 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 POSIX_THREADING_H
#define POSIX_THREADING_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <pthread.h>
#include <sys/time.h>
#ifdef HAVE_PTHREAD_NP_H
#include <pthread_np.h>
#elif defined(__HAIKU__)
#include <OS.h>
#endif
#define THREAD_ENTRY void*
typedef THREAD_ENTRY (*ThreadEntry)(void*);
typedef pthread_t Thread;
typedef pthread_mutex_t Mutex;
typedef pthread_cond_t Condition;
typedef pthread_key_t ThreadLocal;
static inline int MutexInit(Mutex* mutex) {
return pthread_mutex_init(mutex, 0);
}
static inline int MutexDeinit(Mutex* mutex) {
return pthread_mutex_destroy(mutex);
}
static inline int MutexLock(Mutex* mutex) {
return pthread_mutex_lock(mutex);
}
static inline int MutexTryLock(Mutex* mutex) {
return pthread_mutex_trylock(mutex);
}
static inline int MutexUnlock(Mutex* mutex) {
return pthread_mutex_unlock(mutex);
}
static inline int ConditionInit(Condition* cond) {
return pthread_cond_init(cond, 0);
}
static inline int ConditionDeinit(Condition* cond) {
return pthread_cond_destroy(cond);
}
static inline int ConditionWait(Condition* cond, Mutex* mutex) {
return pthread_cond_wait(cond, mutex);
}
static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
struct timespec ts;
struct timeval tv;
gettimeofday(&tv, 0);
ts.tv_sec = tv.tv_sec;
ts.tv_nsec = (tv.tv_usec + timeoutMs * 1000L) * 1000L;
if (ts.tv_nsec >= 1000000000L) {
ts.tv_nsec -= 1000000000L;
++ts.tv_sec;
}
return pthread_cond_timedwait(cond, mutex, &ts);
}
static inline int ConditionWake(Condition* cond) {
return pthread_cond_broadcast(cond);
}
static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
return pthread_create(thread, 0, entry, context);
}
static inline int ThreadJoin(Thread* thread) {
return pthread_join(*thread, 0);
}
static inline int ThreadSetName(const char* name) {
#if defined(__APPLE__) && defined(HAVE_PTHREAD_SETNAME_NP)
return pthread_setname_np(name);
#elif defined(HAVE_PTHREAD_SET_NAME_NP)
pthread_set_name_np(pthread_self(), name);
return 0;
#elif defined(__HAIKU__)
rename_thread(find_thread(NULL), name);
return 0;
#elif defined(HAVE_PTHREAD_SETNAME_NP)
return pthread_setname_np(pthread_self(), name);
#else
UNUSED(name);
return 0;
#endif
}
static inline void ThreadLocalInitKey(ThreadLocal* key) {
pthread_key_create(key, 0);
}
static inline void ThreadLocalSetKey(ThreadLocal key, void* value) {
pthread_setspecific(key, value);
}
static inline void* ThreadLocalGetValue(ThreadLocal key) {
return pthread_getspecific(key);
}
CXX_GUARD_END
#endif

View file

@ -1,18 +0,0 @@
/* Copyright (c) 2013-2015 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 SCE_VFS_H
#define SCE_VFS_H
#ifdef PSP2
#include <psp2/types.h>
#include <psp2/io/fcntl.h>
#else
#include <pspiofilemgr.h>
#endif
struct VFile* VFileOpenSce(const char* path, int flags, SceMode mode);
#endif

View file

@ -1,162 +0,0 @@
/* Copyright (c) 2013-2015 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 SCE_THREADING_H
#define SCE_THREADING_H
#include <psp2/kernel/threadmgr.h>
typedef SceUID Thread;
typedef SceUID Mutex;
typedef struct {
Mutex mutex;
SceUID semaphore;
int waiting;
} Condition;
#define THREAD_ENTRY int
typedef THREAD_ENTRY (*ThreadEntry)(void*);
typedef int ThreadLocal;
static inline int MutexInit(Mutex* mutex) {
Mutex id = sceKernelCreateMutex("mutex", 0, 0, 0);
if (id < 0) {
return id;
}
*mutex = id;
return 0;
}
static inline int MutexDeinit(Mutex* mutex) {
return sceKernelDeleteMutex(*mutex);
}
static inline int MutexLock(Mutex* mutex) {
return sceKernelLockMutex(*mutex, 1, 0);
}
static inline int MutexTryLock(Mutex* mutex) {
return sceKernelTryLockMutex(*mutex, 1);
}
static inline int MutexUnlock(Mutex* mutex) {
return sceKernelUnlockMutex(*mutex, 1);
}
static inline int ConditionInit(Condition* cond) {
int res = MutexInit(&cond->mutex);
if (res < 0) {
return res;
}
cond->semaphore = sceKernelCreateSema("SceCondSema", 0, 0, 1, 0);
if (cond->semaphore < 0) {
MutexDeinit(&cond->mutex);
res = cond->semaphore;
}
cond->waiting = 0;
return res;
}
static inline int ConditionDeinit(Condition* cond) {
MutexDeinit(&cond->mutex);
return sceKernelDeleteSema(cond->semaphore);
}
static inline int ConditionWait(Condition* cond, Mutex* mutex) {
int ret = MutexLock(&cond->mutex);
if (ret < 0) {
return ret;
}
++cond->waiting;
MutexUnlock(mutex);
MutexUnlock(&cond->mutex);
ret = sceKernelWaitSema(cond->semaphore, 1, 0);
if (ret < 0) {
printf("Premature wakeup: %08X", ret);
}
MutexLock(mutex);
return ret;
}
static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
int ret = MutexLock(&cond->mutex);
if (ret < 0) {
return ret;
}
++cond->waiting;
MutexUnlock(mutex);
MutexUnlock(&cond->mutex);
SceUInt timeout = 0;
if (timeoutMs > 0) {
timeout = timeoutMs;
}
ret = sceKernelWaitSema(cond->semaphore, 1, &timeout);
if (ret < 0) {
printf("Premature wakeup: %08X", ret);
}
MutexLock(mutex);
return ret;
}
static inline int ConditionWake(Condition* cond) {
MutexLock(&cond->mutex);
if (cond->waiting) {
--cond->waiting;
sceKernelSignalSema(cond->semaphore, 1);
}
MutexUnlock(&cond->mutex);
return 0;
}
struct SceThreadEntryArgs {
void* context;
ThreadEntry entry;
};
static inline int _sceThreadEntry(SceSize args, void* argp) {
UNUSED(args);
struct SceThreadEntryArgs* arg = argp;
return arg->entry(arg->context);
}
static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
Thread id = sceKernelCreateThread("SceThread", _sceThreadEntry, 0x10000100, 0x10000, 0, 0, 0);
if (id < 0) {
*thread = 0;
return id;
}
*thread = id;
struct SceThreadEntryArgs args = { context, entry };
sceKernelStartThread(id, sizeof(args), &args);
return 0;
}
static inline int ThreadJoin(Thread* thread) {
int res = sceKernelWaitThreadEnd(*thread, 0, 0);
if (res < 0) {
return res;
}
return sceKernelDeleteThread(*thread);
}
static inline int ThreadSetName(const char* name) {
UNUSED(name);
return -1;
}
static inline void ThreadLocalInitKey(ThreadLocal* key) {
static int base = 0x90;
*key = __atomic_fetch_add(&base, 1, __ATOMIC_SEQ_CST);
}
static inline void ThreadLocalSetKey(ThreadLocal key, void* value) {
void** tls = sceKernelGetTLSAddr(key);
*tls = value;
}
static inline void* ThreadLocalGetValue(ThreadLocal key) {
void** tls = sceKernelGetTLSAddr(key);
return *tls;
}
#endif

View file

@ -1,87 +0,0 @@
/* Copyright (c) 2013-2018 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 SWITCH_THREADING_H
#define SWITCH_THREADING_H
#include <mgba-util/common.h>
#include <switch.h>
#define THREAD_ENTRY void
typedef ThreadFunc ThreadEntry;
typedef CondVar Condition;
static inline int MutexInit(Mutex* mutex) {
mutexInit(mutex);
return 0;
}
static inline int MutexDeinit(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int MutexLock(Mutex* mutex) {
mutexLock(mutex);
return 0;
}
static inline int MutexTryLock(Mutex* mutex) {
return mutexTryLock(mutex);
}
static inline int MutexUnlock(Mutex* mutex) {
mutexUnlock(mutex);
return 0;
}
static inline int ConditionInit(Condition* cond) {
condvarInit(cond);
return 0;
}
static inline int ConditionDeinit(Condition* cond) {
UNUSED(cond);
return 0;
}
static inline int ConditionWait(Condition* cond, Mutex* mutex) {
return condvarWait(cond, mutex);
}
static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
return condvarWaitTimeout(cond, mutex, timeoutMs * 1000000LL);
}
static inline int ConditionWake(Condition* cond) {
return condvarWakeOne(cond);
}
static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
if (!entry || !thread) {
return 1;
}
int res = threadCreate(thread, entry, context, NULL, 0x8000, 0x3B, 1);
if(R_FAILED(res)) {
return res;
}
return threadStart(thread);
}
static inline int ThreadJoin(Thread* thread) {
int res = threadWaitForExit(thread);
if(R_FAILED(res)) {
return res;
}
return threadClose(thread);
}
static inline void ThreadSetName(const char* name) {
UNUSED(name);
// Unimplemented
}
#endif

View file

@ -1,607 +0,0 @@
#ifndef __GETOPT_H__
/**
* DISCLAIMER
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
*
* The mingw-w64 runtime package and its code is distributed in the hope that it
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#pragma warning(disable:4996);
#define __GETOPT_H__
/* All the headers include this file. */
#include <crtdefs.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <windows.h>
#ifdef __cplusplus
extern "C" {
#endif
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
#ifdef REPLACE_GETOPT
int opterr = 1; /* if error message should be printed */
int optind = 1; /* index into parent argv vector */
int optopt = '?'; /* character checked for validity */
#undef optreset /* see getopt.h */
#define optreset __mingw_optreset
int optreset; /* reset getopt */
char *optarg; /* argument associated with option */
#endif
//extern int optind; /* index of first non-option in argv */
//extern int optopt; /* single option character, as parsed */
//extern int opterr; /* flag to enable built-in diagnostics... */
// /* (user may set to zero, to suppress) */
//
//extern char *optarg; /* pointer to argument of current option */
#define PRINT_ERROR ((opterr) && (*options != ':'))
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
/* return values */
#define BADCH (int)'?'
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
#define INORDER (int)1
#ifndef __CYGWIN__
#define __progname __argv[0]
#else
extern char __declspec(dllimport) *__progname;
#endif
#ifdef __CYGWIN__
static char EMSG[] = "";
#else
#define EMSG ""
#endif
static int getopt_internal(int, char * const *, const char *,
const struct option *, int *, int);
static int parse_long_options(char * const *, const char *,
const struct option *, int *, int);
static int gcd(int, int);
static void permute_args(int, int, int, char * const *);
static char *place = EMSG; /* option letter processing */
/* XXX: set optreset to 1 rather than these two */
static int nonopt_start = -1; /* first non option argument (for permute) */
static int nonopt_end = -1; /* first option after non options (for permute) */
/* Error messages */
static const char recargchar[] = "option requires an argument -- %c";
static const char recargstring[] = "option requires an argument -- %s";
static const char ambig[] = "ambiguous option -- %.*s";
static const char noarg[] = "option doesn't take an argument -- %.*s";
static const char illoptchar[] = "unknown option -- %c";
static const char illoptstring[] = "unknown option -- %s";
static void
_vwarnx(const char *fmt,va_list ap)
{
(void)fprintf(stderr,"%s: ",__progname);
if (fmt != NULL)
(void)vfprintf(stderr,fmt,ap);
(void)fprintf(stderr,"\n");
}
static void
warnx(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
_vwarnx(fmt,ap);
va_end(ap);
}
/*
* Compute the greatest common divisor of a and b.
*/
static int
gcd(int a, int b)
{
int c;
c = a % b;
while (c != 0) {
a = b;
b = c;
c = a % b;
}
return (b);
}
/*
* Exchange the block from nonopt_start to nonopt_end with the block
* from nonopt_end to opt_end (keeping the same order of arguments
* in each block).
*/
static void
permute_args(int panonopt_start, int panonopt_end, int opt_end,
char * const *nargv)
{
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
char *swap;
/*
* compute lengths of blocks and number and size of cycles
*/
nnonopts = panonopt_end - panonopt_start;
nopts = opt_end - panonopt_end;
ncycle = gcd(nnonopts, nopts);
cyclelen = (opt_end - panonopt_start) / ncycle;
for (i = 0; i < ncycle; i++) {
cstart = panonopt_end+i;
pos = cstart;
for (j = 0; j < cyclelen; j++) {
if (pos >= panonopt_end)
pos -= nnonopts;
else
pos += nopts;
swap = nargv[pos];
/* LINTED const cast */
((char **) nargv)[pos] = nargv[cstart];
/* LINTED const cast */
((char **)nargv)[cstart] = swap;
}
}
}
#ifdef REPLACE_GETOPT
/*
* getopt --
* Parse argc/argv argument vector.
*
* [eventually this will replace the BSD getopt]
*/
int
getopt(int nargc, char * const *nargv, const char *options)
{
/*
* We don't pass FLAG_PERMUTE to getopt_internal() since
* the BSD getopt(3) (unlike GNU) has never done this.
*
* Furthermore, since many privileged programs call getopt()
* before dropping privileges it makes sense to keep things
* as simple (and bug-free) as possible.
*/
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
}
#endif /* REPLACE_GETOPT */
//extern int getopt(int nargc, char * const *nargv, const char *options);
#ifdef _BSD_SOURCE
/*
* BSD adds the non-standard `optreset' feature, for reinitialisation
* of `getopt' parsing. We support this feature, for applications which
* proclaim their BSD heritage, before including this header; however,
* to maintain portability, developers are advised to avoid it.
*/
# define optreset __mingw_optreset
extern int optreset;
#endif
#ifdef __cplusplus
}
#endif
/*
* POSIX requires the `getopt' API to be specified in `unistd.h';
* thus, `unistd.h' includes this header. However, we do not want
* to expose the `getopt_long' or `getopt_long_only' APIs, when
* included in this manner. Thus, close the standard __GETOPT_H__
* declarations block, and open an additional __GETOPT_LONG_H__
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
* to declare the extended API.
*/
#endif /* !defined(__GETOPT_H__) */
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
#define __GETOPT_LONG_H__
#ifdef __cplusplus
extern "C" {
#endif
struct option /* specification for a long form option... */
{
const char *name; /* option name, without leading hyphens */
int has_arg; /* does it take an argument? */
int *flag; /* where to save its status, or NULL */
int val; /* its associated status value */
};
enum /* permitted values for its `has_arg' field... */
{
no_argument = 0, /* option never takes an argument */
required_argument, /* option always requires an argument */
optional_argument /* option may take an argument */
};
/*
* parse_long_options --
* Parse long options in argc/argv argument vector.
* Returns -1 if short_too is set and the option does not match long_options.
*/
static int
parse_long_options(char * const *nargv, const char *options,
const struct option *long_options, int *idx, int short_too)
{
char *current_argv, *has_equal;
size_t current_argv_len;
int i, ambiguous, match;
#define IDENTICAL_INTERPRETATION(_x, _y) \
(long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
long_options[(_x)].flag == long_options[(_y)].flag && \
long_options[(_x)].val == long_options[(_y)].val)
current_argv = place;
match = -1;
ambiguous = 0;
optind++;
if ((has_equal = strchr(current_argv, '=')) != NULL) {
/* argument found (--option=arg) */
current_argv_len = has_equal - current_argv;
has_equal++;
} else
current_argv_len = strlen(current_argv);
for (i = 0; long_options[i].name; i++) {
/* find matching long option */
if (strncmp(current_argv, long_options[i].name,
current_argv_len))
continue;
if (strlen(long_options[i].name) == current_argv_len) {
/* exact match */
match = i;
ambiguous = 0;
break;
}
/*
* If this is a known short option, don't allow
* a partial match of a single character.
*/
if (short_too && current_argv_len == 1)
continue;
if (match == -1) /* partial match */
match = i;
else if (!IDENTICAL_INTERPRETATION(i, match))
ambiguous = 1;
}
if (ambiguous) {
/* ambiguous abbreviation */
if (PRINT_ERROR)
warnx(ambig, (int)current_argv_len,
current_argv);
optopt = 0;
return (BADCH);
}
if (match != -1) { /* option found */
if (long_options[match].has_arg == no_argument
&& has_equal) {
if (PRINT_ERROR)
warnx(noarg, (int)current_argv_len,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
return (BADARG);
}
if (long_options[match].has_arg == required_argument ||
long_options[match].has_arg == optional_argument) {
if (has_equal)
optarg = has_equal;
else if (long_options[match].has_arg ==
required_argument) {
/*
* optional argument doesn't use next nargv
*/
optarg = nargv[optind++];
}
}
if ((long_options[match].has_arg == required_argument)
&& (optarg == NULL)) {
/*
* Missing argument; leading ':' indicates no error
* should be generated.
*/
if (PRINT_ERROR)
warnx(recargstring,
current_argv);
/*
* XXX: GNU sets optopt to val regardless of flag
*/
if (long_options[match].flag == NULL)
optopt = long_options[match].val;
else
optopt = 0;
--optind;
return (BADARG);
}
} else { /* unknown option */
if (short_too) {
--optind;
return (-1);
}
if (PRINT_ERROR)
warnx(illoptstring, current_argv);
optopt = 0;
return (BADCH);
}
if (idx)
*idx = match;
if (long_options[match].flag) {
*long_options[match].flag = long_options[match].val;
return (0);
} else
return (long_options[match].val);
#undef IDENTICAL_INTERPRETATION
}
/*
* getopt_internal --
* Parse argc/argv argument vector. Called by user level routines.
*/
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx, int flags)
{
char *oli; /* option letter list index */
int optchar, short_too;
static int posixly_correct = -1;
if (options == NULL)
return (-1);
/*
* XXX Some GNU programs (like cvs) set optind to 0 instead of
* XXX using optreset. Work around this braindamage.
*/
if (optind == 0)
optind = optreset = 1;
/*
* Disable GNU extensions if POSIXLY_CORRECT is set or options
* string begins with a '+'.
*
* CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
* optreset != 0 for GNU compatibility.
*/
if (posixly_correct == -1 || optreset != 0)
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
if (*options == '-')
flags |= FLAG_ALLARGS;
else if (posixly_correct || *options == '+')
flags &= ~FLAG_PERMUTE;
if (*options == '+' || *options == '-')
options++;
optarg = NULL;
if (optreset)
nonopt_start = nonopt_end = -1;
start:
if (optreset || !*place) { /* update scanning pointer */
optreset = 0;
if (optind >= nargc) { /* end of argument vector */
place = EMSG;
if (nonopt_end != -1) {
/* do permutation, if we have to */
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
else if (nonopt_start != -1) {
/*
* If we skipped non-options, set optind
* to the first of them.
*/
optind = nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
if (*(place = nargv[optind]) != '-' ||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
place = EMSG; /* found non-option */
if (flags & FLAG_ALLARGS) {
/*
* GNU extension:
* return non-option as argument to option 1
*/
optarg = nargv[optind++];
return (INORDER);
}
if (!(flags & FLAG_PERMUTE)) {
/*
* If no permutation wanted, stop parsing
* at first non-option.
*/
return (-1);
}
/* do permutation */
if (nonopt_start == -1)
nonopt_start = optind;
else if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
nonopt_start = optind -
(nonopt_end - nonopt_start);
nonopt_end = -1;
}
optind++;
/* process next argument */
goto start;
}
if (nonopt_start != -1 && nonopt_end == -1)
nonopt_end = optind;
/*
* If we have "-" do nothing, if "--" we are done.
*/
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
optind++;
place = EMSG;
/*
* We found an option (--), so if we skipped
* non-options, we have to permute.
*/
if (nonopt_end != -1) {
permute_args(nonopt_start, nonopt_end,
optind, nargv);
optind -= nonopt_end - nonopt_start;
}
nonopt_start = nonopt_end = -1;
return (-1);
}
}
/*
* Check long options if:
* 1) we were passed some
* 2) the arg is not just "-"
* 3) either the arg starts with -- we are getopt_long_only()
*/
if (long_options != NULL && place != nargv[optind] &&
(*place == '-' || (flags & FLAG_LONGONLY))) {
short_too = 0;
if (*place == '-')
place++; /* --foo long option */
else if (*place != ':' && strchr(options, *place) != NULL)
short_too = 1; /* could be short option too */
optchar = parse_long_options(nargv, options, long_options,
idx, short_too);
if (optchar != -1) {
place = EMSG;
return (optchar);
}
}
if ((optchar = (int)*place++) == (int)':' ||
(optchar == (int)'-' && *place != '\0') ||
(oli = (char*)strchr(options, optchar)) == NULL) {
/*
* If the user specified "-" and '-' isn't listed in
* options, return -1 (non-option) as per POSIX.
* Otherwise, it is an unknown option character (or ':').
*/
if (optchar == (int)'-' && *place == '\0')
return (-1);
if (!*place)
++optind;
if (PRINT_ERROR)
warnx(illoptchar, optchar);
optopt = optchar;
return (BADCH);
}
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
/* -W long-option */
if (*place) /* no space */
/* NOTHING */;
else if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else /* white space */
place = nargv[optind];
optchar = parse_long_options(nargv, options, long_options,
idx, 0);
place = EMSG;
return (optchar);
}
if (*++oli != ':') { /* doesn't take argument */
if (!*place)
++optind;
} else { /* takes (optional) argument */
optarg = NULL;
if (*place) /* no white space */
optarg = place;
else if (oli[1] != ':') { /* arg not optional */
if (++optind >= nargc) { /* no arg */
place = EMSG;
if (PRINT_ERROR)
warnx(recargchar, optchar);
optopt = optchar;
return (BADARG);
} else
optarg = nargv[optind];
}
place = EMSG;
++optind;
}
/* dump back option letter */
return (optchar);
}
/*
* getopt_long --
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE));
}
/*
* getopt_long_only --
* Parse argc/argv argument vector.
*/
int
getopt_long_only(int nargc, char * const *nargv, const char *options,
const struct option *long_options, int *idx)
{
return (getopt_internal(nargc, nargv, options, long_options, idx,
FLAG_PERMUTE|FLAG_LONGONLY));
}
//extern int getopt_long(int nargc, char * const *nargv, const char *options,
// const struct option *long_options, int *idx);
//extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
// const struct option *long_options, int *idx);
/*
* Previous MinGW implementation had...
*/
#ifndef HAVE_DECL_GETOPT
/*
* ...for the long form API only; keep this for compatibility.
*/
# define HAVE_DECL_GETOPT 1
#endif
#ifdef __cplusplus
}
#endif
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */

View file

@ -1,104 +0,0 @@
/* Copyright (c) 2013-2015 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 WINDOWS_THREADING_H
#define WINDOWS_THREADING_H
#include <mgba-util/common.h>
#define _WIN32_WINNT 0x0600
#include <windows.h>
#define THREAD_ENTRY DWORD WINAPI
typedef THREAD_ENTRY ThreadEntry(LPVOID);
typedef HANDLE Thread;
typedef CRITICAL_SECTION Mutex;
typedef CONDITION_VARIABLE Condition;
typedef DWORD ThreadLocal;
static inline int MutexInit(Mutex* mutex) {
InitializeCriticalSection(mutex);
return GetLastError();
}
static inline int MutexDeinit(Mutex* mutex) {
DeleteCriticalSection(mutex);
return GetLastError();
}
static inline int MutexLock(Mutex* mutex) {
EnterCriticalSection(mutex);
return GetLastError();
}
static inline int MutexTryLock(Mutex* mutex) {
if (TryEnterCriticalSection(mutex)) {
return 0;
}
return 1;
}
static inline int MutexUnlock(Mutex* mutex) {
LeaveCriticalSection(mutex);
return GetLastError();
}
static inline int ConditionInit(Condition* cond) {
InitializeConditionVariable(cond);
return GetLastError();
}
static inline int ConditionDeinit(Condition* cond) {
// This is a no-op on Windows
UNUSED(cond);
return 0;
}
static inline int ConditionWait(Condition* cond, Mutex* mutex) {
SleepConditionVariableCS(cond, mutex, INFINITE);
return GetLastError();
}
static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
SleepConditionVariableCS(cond, mutex, timeoutMs);
return GetLastError();
}
static inline int ConditionWake(Condition* cond) {
WakeAllConditionVariable(cond);
return GetLastError();
}
static inline int ThreadCreate(Thread* thread, ThreadEntry entry, void* context) {
*thread = CreateThread(NULL, 0, entry, context, 0, 0);
return GetLastError();
}
static inline int ThreadJoin(Thread* thread) {
DWORD error = WaitForSingleObject(*thread, INFINITE);
if (error == WAIT_FAILED) {
return GetLastError();
}
return 0;
}
static inline int ThreadSetName(const char* name) {
UNUSED(name);
return -1;
}
static inline void ThreadLocalInitKey(ThreadLocal* key) {
*key = TlsAlloc();
}
static inline void ThreadLocalSetKey(ThreadLocal key, void* value) {
TlsSetValue(key, value);
}
static inline void* ThreadLocalGetValue(ThreadLocal key) {
return TlsGetValue(key);
}
#endif

View file

@ -1,55 +0,0 @@
/* Copyright (c) 2013-2014 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 PNG_IO_H
#define PNG_IO_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifdef USE_PNG
// png.h defines its own version of restrict which conflicts with mGBA's.
#ifdef restrict
#undef restrict
#endif
#include <png.h>
struct VFile;
enum {
PNG_HEADER_BYTES = 8
};
png_structp PNGWriteOpen(struct VFile* source);
png_infop PNGWriteHeader(png_structp png, unsigned width, unsigned height);
png_infop PNGWriteHeaderA(png_structp png, unsigned width, unsigned height);
png_infop PNGWriteHeader8(png_structp png, unsigned width, unsigned height);
bool PNGWritePalette(png_structp png, png_infop info, const uint32_t* palette, unsigned entries);
bool PNGWritePixels(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels);
bool PNGWritePixelsA(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels);
bool PNGWritePixels8(png_structp png, unsigned width, unsigned height, unsigned stride, const void* pixels);
bool PNGWriteCustomChunk(png_structp png, const char* name, size_t size, void* data);
void PNGWriteClose(png_structp png, png_infop info);
typedef int (*ChunkHandler)(png_structp, png_unknown_chunkp);
bool isPNG(struct VFile* source);
png_structp PNGReadOpen(struct VFile* source, unsigned offset);
bool PNGInstallChunkHandler(png_structp png, void* context, ChunkHandler handler, const char* chunkName);
bool PNGReadHeader(png_structp png, png_infop info);
bool PNGReadPixels(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride);
bool PNGReadPixelsA(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride);
bool PNGReadPixels8(png_structp png, png_infop info, void* pixels, unsigned width, unsigned height, unsigned stride);
bool PNGIgnorePixels(png_structp png, png_infop info);
bool PNGReadFooter(png_structp png, png_infop end);
void PNGReadClose(png_structp png, png_infop info, png_infop end);
#endif
CXX_GUARD_END
#endif

View file

@ -1,30 +0,0 @@
/* Copyright (c) 2013-2014 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 RING_FIFO_H
#define RING_FIFO_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct RingFIFO {
void* data;
size_t capacity;
void* readPtr;
void* writePtr;
};
void RingFIFOInit(struct RingFIFO* buffer, size_t capacity);
void RingFIFODeinit(struct RingFIFO* buffer);
size_t RingFIFOCapacity(const struct RingFIFO* buffer);
size_t RingFIFOSize(const struct RingFIFO* buffer);
void RingFIFOClear(struct RingFIFO* buffer);
size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length);
size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length);
CXX_GUARD_END
#endif

View file

@ -1,418 +0,0 @@
/* Copyright (c) 2013-2014 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 SOCKET_H
#define SOCKET_H
#include <mgba-util/common.h>
CXX_GUARD_START
#if defined(__cplusplus) && !defined(restrict)
#define restrict __restrict__
#endif
#ifdef _WIN32
#include <ws2tcpip.h>
#define SOCKET_FAILED(s) ((s) == INVALID_SOCKET)
typedef SOCKET Socket;
#else
#ifdef GEKKO
#include <network.h>
#else
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <sys/socket.h>
#endif
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h>
#ifndef GEKKO
#define INVALID_SOCKET (-1)
#endif
#define SOCKET_FAILED(s) ((s) < 0)
typedef int Socket;
#endif
enum IP {
IPV4,
IPV6
};
struct Address {
enum IP version;
union {
uint32_t ipv4;
uint8_t ipv6[16];
};
};
#ifdef _3DS
#include <3ds.h>
#include <malloc.h>
#define SOCU_ALIGN 0x1000
#define SOCU_BUFFERSIZE 0x100000
extern u32* SOCUBuffer;
#endif
#ifdef __SWITCH__
#include <switch.h>
#endif
#ifdef PSP2
#include <psp2/net/net.h>
#include <psp2/sysmodule.h>
#endif
static inline void SocketSubsystemInit() {
#ifdef _WIN32
WSADATA data;
WSAStartup(MAKEWORD(2, 2), &data);
#elif defined(_3DS)
if (!SOCUBuffer) {
SOCUBuffer = memalign(SOCU_ALIGN, SOCU_BUFFERSIZE);
socInit(SOCUBuffer, SOCU_BUFFERSIZE);
}
#elif defined(__SWITCH__)
socketInitializeDefault();
#elif defined(GEKKO)
net_init();
#elif defined(PSP2)
static uint8_t netMem[1024*1024];
sceSysmoduleLoadModule(SCE_SYSMODULE_NET);
sceNetInit(&(SceNetInitParam) { netMem, sizeof(netMem) });
#endif
}
static inline void SocketSubsystemDeinit() {
#ifdef _WIN32
WSACleanup();
#elif defined(_3DS)
socExit();
free(SOCUBuffer);
SOCUBuffer = NULL;
#elif defined(__SWITCH__)
socketExit();
#elif defined(GEKKO)
net_deinit();
#elif defined(PSP2)
sceNetTerm();
sceSysmoduleUnloadModule(SCE_SYSMODULE_NET);
#endif
}
static inline int SocketError() {
#ifdef _WIN32
return WSAGetLastError();
#else
return errno;
#endif
}
static inline bool SocketWouldBlock() {
#ifdef _WIN32
return SocketError() == WSAEWOULDBLOCK;
#else
return SocketError() == EWOULDBLOCK || SocketError() == EAGAIN;
#endif
}
static inline ssize_t SocketSend(Socket socket, const void* buffer, size_t size) {
#ifdef _WIN32
return send(socket, (const char*) buffer, size, 0);
#elif defined(GEKKO)
return net_write(socket, buffer, size);
#else
return write(socket, buffer, size);
#endif
}
static inline ssize_t SocketRecv(Socket socket, void* buffer, size_t size) {
#if defined(_WIN32) || defined(__SWITCH__)
return recv(socket, (char*) buffer, size, 0);
#elif defined(GEKKO)
return net_read(socket, buffer, size);
#else
return read(socket, buffer, size);
#endif
}
static inline int SocketClose(Socket socket) {
#ifdef _WIN32
return closesocket(socket) == 0;
#elif defined(GEKKO)
return net_close(socket) >= 0;
#else
return close(socket) >= 0;
#endif
}
static inline Socket SocketOpenTCP(int port, const struct Address* bindAddress) {
#ifdef GEKKO
Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
#else
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
if (SOCKET_FAILED(sock)) {
return sock;
}
int err;
if (!bindAddress) {
struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin_family = AF_INET;
bindInfo.sin_port = htons(port);
#ifndef _3DS
bindInfo.sin_addr.s_addr = INADDR_ANY;
#else
bindInfo.sin_addr.s_addr = gethostid();
#endif
#ifdef GEKKO
err = net_bind(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo));
#else
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif
} else if (bindAddress->version == IPV4) {
struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin_family = AF_INET;
bindInfo.sin_port = htons(port);
bindInfo.sin_addr.s_addr = htonl(bindAddress->ipv4);
#ifdef GEKKO
err = net_bind(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo));
#else
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif
#if !defined(_3DS) && !defined(GEKKO)
} else {
struct sockaddr_in6 bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin6_family = AF_INET6;
bindInfo.sin6_port = htons(port);
memcpy(bindInfo.sin6_addr.s6_addr, bindAddress->ipv6, sizeof(bindInfo.sin6_addr.s6_addr));
err = bind(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif
}
if (err) {
SocketClose(sock);
return INVALID_SOCKET;
}
return sock;
}
static inline Socket SocketConnectTCP(int port, const struct Address* destinationAddress) {
#ifdef GEKKO
Socket sock = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
#else
Socket sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
if (SOCKET_FAILED(sock)) {
return sock;
}
int err;
if (!destinationAddress) {
struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin_family = AF_INET;
bindInfo.sin_port = htons(port);
#ifdef GEKKO
err = net_connect(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo));
#else
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif
} else if (destinationAddress->version == IPV4) {
struct sockaddr_in bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin_family = AF_INET;
bindInfo.sin_port = htons(port);
bindInfo.sin_addr.s_addr = htonl(destinationAddress->ipv4);
#ifdef GEKKO
err = net_connect(sock, (struct sockaddr*) &bindInfo, sizeof(bindInfo));
#else
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif
#if !defined(_3DS) && !defined(GEKKO)
} else {
struct sockaddr_in6 bindInfo;
memset(&bindInfo, 0, sizeof(bindInfo));
bindInfo.sin6_family = AF_INET6;
bindInfo.sin6_port = htons(port);
memcpy(bindInfo.sin6_addr.s6_addr, destinationAddress->ipv6, sizeof(bindInfo.sin6_addr.s6_addr));
err = connect(sock, (const struct sockaddr*) &bindInfo, sizeof(bindInfo));
#endif
}
if (err) {
SocketClose(sock);
return INVALID_SOCKET;
}
return sock;
}
static inline Socket SocketListen(Socket socket, int queueLength) {
#ifdef GEKKO
return net_listen(socket, queueLength);
#else
#ifdef PSP2
if (queueLength <= 0) {
queueLength = 1;
}
#endif
return listen(socket, queueLength);
#endif
}
static inline Socket SocketAccept(Socket socket, struct Address* address) {
if (!address) {
#ifdef GEKKO
struct sockaddr_in addrInfo;
memset(&addrInfo, 0, sizeof(addrInfo));
socklen_t len = sizeof(addrInfo);
return net_accept(socket, (struct sockaddr*) &addrInfo, &len);
#else
return accept(socket, 0, 0);
#endif
}
if (address->version == IPV4) {
struct sockaddr_in addrInfo;
memset(&addrInfo, 0, sizeof(addrInfo));
addrInfo.sin_family = AF_INET;
addrInfo.sin_addr.s_addr = address->ipv4;
socklen_t len = sizeof(addrInfo);
#ifdef GEKKO
return net_accept(socket, (struct sockaddr*) &addrInfo, &len);
#else
return accept(socket, (struct sockaddr*) &addrInfo, &len);
#endif
#if !defined(_3DS) && !defined(GEKKO)
} else {
struct sockaddr_in6 addrInfo;
memset(&addrInfo, 0, sizeof(addrInfo));
addrInfo.sin6_family = AF_INET6;
memcpy(addrInfo.sin6_addr.s6_addr, address->ipv6, sizeof(addrInfo.sin6_addr.s6_addr));
socklen_t len = sizeof(addrInfo);
return accept(socket, (struct sockaddr*) &addrInfo, &len);
#endif
}
return INVALID_SOCKET;
}
static inline int SocketSetBlocking(Socket socket, bool blocking) {
#ifdef _WIN32
u_long unblocking = !blocking;
return ioctlsocket(socket, FIONBIO, &unblocking) == NO_ERROR;
#else
#ifdef GEKKO
int flags = net_fcntl(socket, F_GETFL, 0);
#else
int flags = fcntl(socket, F_GETFL);
#endif
if (flags == -1) {
return 0;
}
if (blocking) {
flags &= ~O_NONBLOCK;
} else {
flags |= O_NONBLOCK;
}
#ifdef GEKKO
return net_fcntl(socket, F_SETFL, flags) >= 0;
#else
return fcntl(socket, F_SETFL, flags) >= 0;
#endif
#endif
}
static inline int SocketSetTCPPush(Socket socket, int push) {
#ifdef GEKKO
return net_setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0;
#else
return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, (char*) &push, sizeof(int)) >= 0;
#endif
}
static inline int SocketPoll(size_t nSockets, Socket* reads, Socket* writes, Socket* errors, int64_t timeoutMillis) {
fd_set rset;
fd_set wset;
fd_set eset;
FD_ZERO(&rset);
FD_ZERO(&wset);
FD_ZERO(&eset);
size_t i;
Socket maxFd = 0;
if (reads) {
for (i = 0; i < nSockets; ++i) {
if (SOCKET_FAILED(reads[i])) {
break;
}
if (reads[i] > maxFd) {
maxFd = reads[i];
}
FD_SET(reads[i], &rset);
reads[i] = INVALID_SOCKET;
}
}
if (writes) {
for (i = 0; i < nSockets; ++i) {
if (SOCKET_FAILED(writes[i])) {
break;
}
if (writes[i] > maxFd) {
maxFd = writes[i];
}
FD_SET(writes[i], &wset);
writes[i] = INVALID_SOCKET;
}
}
if (errors) {
for (i = 0; i < nSockets; ++i) {
if (SOCKET_FAILED(errors[i])) {
break;
}
if (errors[i] > maxFd) {
maxFd = errors[i];
}
FD_SET(errors[i], &eset);
errors[i] = INVALID_SOCKET;
}
}
++maxFd;
struct timeval tv;
tv.tv_sec = timeoutMillis / 1000;
tv.tv_usec = (timeoutMillis % 1000) * 1000;
#ifdef GEKKO
int result = net_select(maxFd, &rset, &wset, &eset, timeoutMillis < 0 ? 0 : &tv);
#else
int result = select(maxFd, &rset, &wset, &eset, timeoutMillis < 0 ? 0 : &tv);
#endif
int r = 0;
int w = 0;
int e = 0;
Socket j;
for (j = 0; j < maxFd; ++j) {
if (reads && FD_ISSET(j, &rset)) {
reads[r] = j;
++r;
}
if (writes && FD_ISSET(j, &wset)) {
writes[w] = j;
++w;
}
if (errors && FD_ISSET(j, &eset)) {
errors[e] = j;
++e;
}
}
return result;
}
CXX_GUARD_END
#endif

View file

@ -1,52 +0,0 @@
/* Copyright (c) 2013-2014 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 UTIL_STRING_H
#define UTIL_STRING_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifndef HAVE_STRNDUP
// This is sometimes a macro
char* strndup(const char* start, size_t len);
#endif
#ifndef HAVE_STRDUP
char* strdup(const char* str);
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy(char* restrict dst, const char* restrict src, size_t dstsize);
#endif
char* strnrstr(const char* restrict s1, const char* restrict s2, size_t len);
bool endswith(const char* restrict s1, const char* restrict end);
bool startswith(const char* restrict s1, const char* restrict start);
size_t toUtf8(uint32_t unichar, char* buffer);
int utfcmp(const uint16_t* utf16, const char* utf8, size_t utf16Length, size_t utf8Length);
char* utf16to8(const uint16_t* utf16, size_t length);
uint32_t utf8Char(const char** unicode, size_t* length);
uint32_t utf16Char(const uint16_t** unicode, size_t* length);
char* gbkToUtf8(const char* gbk, size_t length);
int hexDigit(char digit);
const char* hex32(const char* line, uint32_t* out);
const char* hex24(const char* line, uint32_t* out);
const char* hex16(const char* line, uint16_t* out);
const char* hex12(const char* line, uint16_t* out);
const char* hex8(const char* line, uint8_t* out);
const char* hex4(const char* line, uint8_t* out);
void rtrim(char* string);
ssize_t parseQuotedString(const char* unparsed, ssize_t unparsedLen, char* parsed, ssize_t parsedLen);
bool wildcard(const char* search, const char* string);
CXX_GUARD_END
#endif

View file

@ -1,57 +0,0 @@
/* Copyright (c) 2013-2014 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 TABLE_H
#define TABLE_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct TableList;
struct Table {
struct TableList* table;
size_t tableSize;
size_t size;
void (*deinitializer)(void*);
uint32_t seed;
};
void TableInit(struct Table*, size_t initialSize, void (*deinitializer)(void*));
void TableDeinit(struct Table*);
void* TableLookup(const struct Table*, uint32_t key);
void TableInsert(struct Table*, uint32_t key, void* value);
void TableRemove(struct Table*, uint32_t key);
void TableClear(struct Table*);
void TableEnumerate(const struct Table*, void (*handler)(uint32_t key, void* value, void* user), void* user);
size_t TableSize(const struct Table*);
void HashTableInit(struct Table* table, size_t initialSize, void (*deinitializer)(void*));
void HashTableDeinit(struct Table* table);
void* HashTableLookup(const struct Table*, const char* key);
void* HashTableLookupBinary(const struct Table*, const void* key, size_t keylen);
void HashTableInsert(struct Table*, const char* key, void* value);
void HashTableInsertBinary(struct Table*, const void* key, size_t keylen, void* value);
void HashTableRemove(struct Table*, const char* key);
void HashTableRemoveBinary(struct Table*, const void* key, size_t keylen);
void HashTableClear(struct Table*);
void HashTableEnumerate(const struct Table*, void (*handler)(const char* key, void* value, void* user), void* user);
void HashTableEnumerateBinary(const struct Table*, void (*handler)(const char* key, size_t keylen, void* value, void* user), void* user);
const char* HashTableSearch(const struct Table* table, bool (*predicate)(const char* key, const void* value, const void* user), const void* user);
const char* HashTableSearchPointer(const struct Table* table, const void* value);
const char* HashTableSearchData(const struct Table* table, const void* value, size_t bytes);
const char* HashTableSearchString(const struct Table* table, const char* value);
size_t HashTableSize(const struct Table*);
CXX_GUARD_END
#endif

View file

@ -1,36 +0,0 @@
/* Copyright (c) 2013-2016 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 TEXT_CODEC_H
#define TEXT_CODEC_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct TextCodecNode;
struct TextCodec {
struct TextCodecNode* forwardRoot;
struct TextCodecNode* reverseRoot;
};
struct TextCodecIterator {
struct TextCodecNode* root;
struct TextCodecNode* current;
};
struct VFile;
bool TextCodecLoadTBL(struct TextCodec*, struct VFile*, bool createReverse);
void TextCodecDeinit(struct TextCodec*);
void TextCodecStartDecode(struct TextCodec*, struct TextCodecIterator*);
void TextCodecStartEncode(struct TextCodec*, struct TextCodecIterator*);
ssize_t TextCodecAdvance(struct TextCodecIterator*, uint8_t byte, uint8_t* output, size_t outputLength);
ssize_t TextCodecFinish(struct TextCodecIterator*, uint8_t* output, size_t outputLength);
CXX_GUARD_END
#endif

View file

@ -1,121 +0,0 @@
/* Copyright (c) 2013-2015 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 THREADING_H
#define THREADING_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifndef DISABLE_THREADING
#if __STDC_VERSION__ >= 201112L
#define ThreadLocal _Thread_local void*
#define ThreadLocalInitKey(X)
#define ThreadLocalSetKey(K, V) K = V
#define ThreadLocalGetValue(K) K
#endif
#ifdef USE_PTHREADS
#include <mgba-util/platform/posix/threading.h>
#elif defined(_WIN32)
#include <mgba-util/platform/windows/threading.h>
#elif defined(PSP2)
#include <mgba-util/platform/psp2/threading.h>
#elif defined(_3DS)
#include <mgba-util/platform/3ds/threading.h>
#elif defined(__SWITCH__)
#include <mgba-util/platform/switch/threading.h>
#else
#define DISABLE_THREADING
#endif
#endif
#ifdef DISABLE_THREADING
#ifdef _3DS
// ctrulib already has a type called Thread
#include <3ds/thread.h>
#elif defined(__SWITCH__)
#include <switch/kernel/thread.h>
#else
typedef void* Thread;
#endif
#ifdef __SWITCH__
#include <switch/kernel/mutex.h>
#else
typedef void* Mutex;
#endif
typedef void* Condition;
typedef int ThreadLocal;
static inline int MutexInit(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int MutexDeinit(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int MutexLock(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int MutexTryLock(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int MutexUnlock(Mutex* mutex) {
UNUSED(mutex);
return 0;
}
static inline int ConditionInit(Condition* cond) {
UNUSED(cond);
return 0;
}
static inline int ConditionDeinit(Condition* cond) {
UNUSED(cond);
return 0;
}
static inline int ConditionWait(Condition* cond, Mutex* mutex) {
UNUSED(cond);
UNUSED(mutex);
return 0;
}
static inline int ConditionWaitTimed(Condition* cond, Mutex* mutex, int32_t timeoutMs) {
UNUSED(cond);
UNUSED(mutex);
UNUSED(timeoutMs);
return 0;
}
static inline int ConditionWake(Condition* cond) {
UNUSED(cond);
return 0;
}
static inline void ThreadLocalInitKey(ThreadLocal* key) {
UNUSED(key);
}
static inline void ThreadLocalSetKey(ThreadLocal key, void* value) {
UNUSED(key);
UNUSED(value);
}
static inline void* ThreadLocalGetValue(ThreadLocal key) {
UNUSED(key);
return NULL;
}
#endif
CXX_GUARD_END
#endif

View file

@ -1,104 +0,0 @@
/* Copyright (c) 2013-2015 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 VECTOR_H
#define VECTOR_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifdef vector
#undef vector
#endif
#define DECLARE_VECTOR(NAME, TYPE) \
struct NAME { \
TYPE* vector; \
size_t size; \
size_t capacity; \
}; \
void NAME ## Init(struct NAME* vector, size_t capacity); \
void NAME ## Deinit(struct NAME* vector); \
TYPE* NAME ## GetPointer(struct NAME* vector, size_t location); \
TYPE const* NAME ## GetConstPointer(const struct NAME* vector, size_t location); \
TYPE* NAME ## Append(struct NAME* vector); \
void NAME ## Clear(struct NAME* vector); \
void NAME ## Resize(struct NAME* vector, ssize_t change); \
void NAME ## Shift(struct NAME* vector, size_t location, size_t difference); \
void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference); \
void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity); \
size_t NAME ## Size(const struct NAME* vector); \
size_t NAME ## Index(const struct NAME* vector, const TYPE* member); \
void NAME ## Copy(struct NAME* dest, const struct NAME* src);
#define DEFINE_VECTOR(NAME, TYPE) \
void NAME ## Init(struct NAME* vector, size_t capacity) { \
vector->size = 0; \
if (capacity == 0) { \
capacity = 4; \
} \
vector->capacity = capacity; \
vector->vector = calloc(capacity, sizeof(TYPE)); \
} \
void NAME ## Deinit(struct NAME* vector) { \
free(vector->vector); \
vector->vector = 0; \
vector->capacity = 0; \
vector->size = 0; \
} \
TYPE* NAME ## GetPointer(struct NAME* vector, size_t location) { \
return &vector->vector[location]; \
} \
TYPE const* NAME ## GetConstPointer(const struct NAME* vector, size_t location) { \
return &vector->vector[location]; \
} \
TYPE* NAME ## Append(struct NAME* vector) { \
NAME ## Resize(vector, 1); \
return &vector->vector[vector->size - 1]; \
} \
void NAME ## Resize(struct NAME* vector, ssize_t change) { \
if (change > 0) { \
NAME ## EnsureCapacity(vector, vector->size + change); \
} \
vector->size += change; \
} \
void NAME ## Clear(struct NAME* vector) { \
vector->size = 0; \
} \
void NAME ## EnsureCapacity(struct NAME* vector, size_t capacity) { \
if (capacity <= vector->capacity) { \
return; \
} \
while (capacity > vector->capacity) { \
vector->capacity <<= 1; \
} \
vector->vector = realloc(vector->vector, vector->capacity * sizeof(TYPE)); \
} \
void NAME ## Shift(struct NAME* vector, size_t location, size_t difference) { \
memmove(&vector->vector[location], &vector->vector[location + difference], (vector->size - location - difference) * sizeof(TYPE)); \
vector->size -= difference; \
} \
void NAME ## Unshift(struct NAME* vector, size_t location, size_t difference) { \
NAME ## Resize(vector, difference); \
memmove(&vector->vector[location + difference], &vector->vector[location], (vector->size - location - difference) * sizeof(TYPE)); \
} \
size_t NAME ## Size(const struct NAME* vector) { \
return vector->size; \
} \
size_t NAME ## Index(const struct NAME* vector, const TYPE* member) { \
return member - (const TYPE*) vector->vector; \
} \
void NAME ## Copy(struct NAME* dest, const struct NAME* src) { \
NAME ## EnsureCapacity(dest, src->size); \
memcpy(dest->vector, src->vector, src->size * sizeof(TYPE)); \
dest->size = src->size; \
} \
DECLARE_VECTOR(StringList, char*);
CXX_GUARD_END
#endif

View file

@ -1,115 +0,0 @@
/* Copyright (c) 2013-2014 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 VFS_H
#define VFS_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifdef _WIN32
#include <io.h>
#include <windows.h>
#define PATH_SEP "/" // Windows can handle slashes, and backslashes confuse some libraries
#else
#define PATH_SEP "/"
#endif
#ifndef PATH_MAX
#ifdef MAX_PATH
#define PATH_MAX MAX_PATH
#else
#define PATH_MAX 128
#endif
#endif
enum {
MAP_READ = 1,
MAP_WRITE = 2
};
enum VFSType {
VFS_UNKNOWN = 0,
VFS_FILE,
VFS_DIRECTORY
};
struct VFile {
bool (*close)(struct VFile* vf);
off_t (*seek)(struct VFile* vf, off_t offset, int whence);
ssize_t (*read)(struct VFile* vf, void* buffer, size_t size);
ssize_t (*readline)(struct VFile* vf, char* buffer, size_t size);
ssize_t (*write)(struct VFile* vf, const void* buffer, size_t size);
void* (*map)(struct VFile* vf, size_t size, int flags);
void (*unmap)(struct VFile* vf, void* memory, size_t size);
void (*truncate)(struct VFile* vf, size_t size);
ssize_t (*size)(struct VFile* vf);
bool (*sync)(struct VFile* vf, void* buffer, size_t size);
};
struct VDirEntry {
const char* (*name)(struct VDirEntry* vde);
enum VFSType (*type)(struct VDirEntry* vde);
};
struct VDir {
bool (*close)(struct VDir* vd);
void (*rewind)(struct VDir* vd);
struct VDirEntry* (*listNext)(struct VDir* vd);
struct VFile* (*openFile)(struct VDir* vd, const char* name, int mode);
struct VDir* (*openDir)(struct VDir* vd, const char* name);
bool (*deleteFile)(struct VDir* vd, const char* name);
};
struct VFile* VFileOpen(const char* path, int flags);
struct VFile* VFileOpenFD(const char* path, int flags);
struct VFile* VFileFromFD(int fd);
struct VFile* VFileFromMemory(void* mem, size_t size);
struct VFile* VFileFromConstMemory(const void* mem, size_t size);
struct VFile* VFileMemChunk(const void* mem, size_t size);
struct CircleBuffer;
struct VFile* VFileFIFO(struct CircleBuffer* backing);
struct VDir* VDirOpen(const char* path);
struct VDir* VDirOpenArchive(const char* path);
#if defined(USE_LIBZIP) || defined(USE_MINIZIP)
struct VDir* VDirOpenZip(const char* path, int flags);
#endif
#ifdef USE_LZMA
struct VDir* VDirOpen7z(const char* path, int flags);
#endif
#if defined(__wii__) || defined(_3DS) || defined(PSP2)
struct VDir* VDeviceList(void);
#endif
bool VDirCreate(const char* path);
#ifdef USE_VFS_FILE
struct VFile* VFileFOpen(const char* path, const char* mode);
struct VFile* VFileFromFILE(FILE* file);
#endif
void separatePath(const char* path, char* dirname, char* basename, char* extension);
struct VFile* VDirFindFirst(struct VDir* dir, bool (*filter)(struct VFile*));
struct VFile* VDirFindNextAvailable(struct VDir*, const char* basename, const char* infix, const char* suffix, int mode);
ssize_t VFileReadline(struct VFile* vf, char* buffer, size_t size);
ssize_t VFileWrite32LE(struct VFile* vf, int32_t word);
ssize_t VFileWrite16LE(struct VFile* vf, int16_t hword);
ssize_t VFileRead32LE(struct VFile* vf, void* word);
ssize_t VFileRead16LE(struct VFile* vf, void* hword);
CXX_GUARD_END
#endif

View file

@ -1,64 +0,0 @@
/* Copyright (c) 2013-2019 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 M_BITMAP_CACHE_H
#define M_BITMAP_CACHE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/interface.h>
DECL_BITFIELD(mBitmapCacheConfiguration, uint32_t);
DECL_BIT(mBitmapCacheConfiguration, ShouldStore, 0);
DECL_BITFIELD(mBitmapCacheSystemInfo, uint32_t);
DECL_BITS(mBitmapCacheSystemInfo, EntryBPP, 0, 3);
DECL_BIT(mBitmapCacheSystemInfo, UsesPalette, 3);
DECL_BITS(mBitmapCacheSystemInfo, Width, 4, 10);
DECL_BITS(mBitmapCacheSystemInfo, Height, 14, 10);
DECL_BITS(mBitmapCacheSystemInfo, Buffers, 24, 2);
struct mBitmapCacheEntry {
uint32_t paletteVersion;
uint32_t vramVersion;
uint8_t vramClean;
};
struct mBitmapCache {
color_t* cache;
struct mBitmapCacheEntry* status;
uint32_t globalPaletteVersion;
uint8_t* vram;
color_t* palette;
uint32_t bitsSize;
uint32_t bitsStart[2];
uint32_t stride;
uint8_t buffer;
mBitmapCacheConfiguration config;
mBitmapCacheSystemInfo sysConfig;
void* context;
};
void mBitmapCacheInit(struct mBitmapCache* cache);
void mBitmapCacheDeinit(struct mBitmapCache* cache);
void mBitmapCacheConfigure(struct mBitmapCache* cache, mBitmapCacheConfiguration config);
void mBitmapCacheConfigureSystem(struct mBitmapCache* cache, mBitmapCacheSystemInfo config);
void mBitmapCacheWriteVRAM(struct mBitmapCache* cache, uint32_t address);
void mBitmapCacheWritePalette(struct mBitmapCache* cache, uint32_t entry, color_t color);
void mBitmapCacheCleanRow(struct mBitmapCache* cache, struct mBitmapCacheEntry* entry, unsigned y);
bool mBitmapCacheCheckRow(struct mBitmapCache* cache, const struct mBitmapCacheEntry* entry, unsigned y);
const color_t* mBitmapCacheGetRow(struct mBitmapCache* cache, unsigned y);
CXX_GUARD_END
#endif

View file

@ -1,72 +0,0 @@
/** \file
Sample buffer that resamples from input clock rate to output sample rate */
/* blip_buf 1.1.0 */
#ifndef BLIP_BUF_H
#define BLIP_BUF_H
#ifdef __cplusplus
extern "C" {
#endif
/** First parameter of most functions is blip_t*, or const blip_t* if nothing
is changed. */
typedef struct blip_t blip_t;
/** Creates new buffer that can hold at most sample_count samples. Sets rates
so that there are blip_max_ratio clocks per sample. Returns pointer to new
buffer, or NULL if insufficient memory. */
blip_t* blip_new( int sample_count );
/** Sets approximate input clock rate and output sample rate. For every
clock_rate input clocks, approximately sample_rate samples are generated. */
void blip_set_rates( blip_t*, double clock_rate, double sample_rate );
enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
clock_rate must not be greater than sample_rate*blip_max_ratio. */
blip_max_ratio = 0x100000 };
/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */
void blip_clear( blip_t* );
/** Adds positive/negative delta into buffer at specified clock time. */
void blip_add_delta( blip_t*, unsigned int clock_time, int delta );
/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */
void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta );
/** Length of time frame, in clocks, needed to make sample_count additional
samples available. */
int blip_clocks_needed( const blip_t*, int sample_count );
enum { /** Maximum number of samples that can be generated from one time frame. */
blip_max_frame = 4000 };
/** Makes input clocks before clock_duration available for reading as output
samples. Also begins new time frame at clock_duration, so that clock time 0 in
the new time frame specifies the same clock as clock_duration in the old time
frame specified. Deltas can have been added slightly past clock_duration (up to
however many clocks there are in two output samples). */
void blip_end_frame( blip_t*, unsigned int clock_duration );
/** Number of buffered samples available for reading. */
int blip_samples_avail( const blip_t* );
/** Reads and removes at most 'count' samples and writes them to 'out'. If
'stereo' is true, writes output to every other element of 'out', allowing easy
interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed
samples. Returns number of samples actually read. */
int blip_read_samples( blip_t*, short out [], int count, int stereo );
/** Frees buffer. No effect if NULL is passed. */
void blip_delete( blip_t* );
/* Deprecated */
typedef blip_t blip_buffer_t;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,38 +0,0 @@
/* Copyright (c) 2013-2017 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 M_CACHE_SET_H
#define M_CACHE_SET_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/bitmap-cache.h>
#include <mgba/core/map-cache.h>
#include <mgba/core/tile-cache.h>
#include <mgba-util/vector.h>
DECLARE_VECTOR(mMapCacheSet, struct mMapCache);
DECLARE_VECTOR(mBitmapCacheSet, struct mBitmapCache);
DECLARE_VECTOR(mTileCacheSet, struct mTileCache);
struct mCacheSet {
struct mMapCacheSet maps;
struct mBitmapCacheSet bitmaps;
struct mTileCacheSet tiles;
};
void mCacheSetInit(struct mCacheSet*, size_t nMaps, size_t nBitmaps, size_t nTiles);
void mCacheSetDeinit(struct mCacheSet*);
void mCacheSetAssignVRAM(struct mCacheSet*, void* vram);
void mCacheSetWriteVRAM(struct mCacheSet*, uint32_t address);
void mCacheSetWritePalette(struct mCacheSet*, uint32_t entry, color_t color);
CXX_GUARD_END
#endif

View file

@ -1,129 +0,0 @@
/* Copyright (c) 2013-2016 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 CHEATS_H
#define CHEATS_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
#include <mgba/core/log.h>
#include <mgba-util/table.h>
#include <mgba-util/vector.h>
enum mCheatType {
CHEAT_ASSIGN,
CHEAT_ASSIGN_INDIRECT,
CHEAT_AND,
CHEAT_ADD,
CHEAT_OR,
CHEAT_IF_EQ,
CHEAT_IF_NE,
CHEAT_IF_LT,
CHEAT_IF_GT,
CHEAT_IF_ULT,
CHEAT_IF_UGT,
CHEAT_IF_AND,
CHEAT_IF_LAND,
CHEAT_IF_NAND,
CHEAT_IF_BUTTON,
};
struct mCheat {
enum mCheatType type;
int width;
uint32_t address;
uint32_t operand;
uint32_t repeat;
uint32_t negativeRepeat;
int32_t addressOffset;
int32_t operandOffset;
};
struct mCheatPatch {
uint32_t address;
int segment;
uint32_t value;
int width;
bool applied;
uint32_t checkValue;
bool check;
};
mLOG_DECLARE_CATEGORY(CHEATS);
DECLARE_VECTOR(mCheatList, struct mCheat);
DECLARE_VECTOR(mCheatPatchList, struct mCheatPatch);
struct mCheatDevice;
struct mCheatSet {
struct mCheatList list;
void (*deinit)(struct mCheatSet* set);
void (*add)(struct mCheatSet* set, struct mCheatDevice* device);
void (*remove)(struct mCheatSet* set, struct mCheatDevice* device);
bool (*addLine)(struct mCheatSet* set, const char* cheat, int type);
void (*copyProperties)(struct mCheatSet* set, struct mCheatSet* oldSet);
void (*parseDirectives)(struct mCheatSet* set, const struct StringList* directives);
void (*dumpDirectives)(struct mCheatSet* set, struct StringList* directives);
void (*refresh)(struct mCheatSet* set, struct mCheatDevice* device);
char* name;
bool enabled;
struct mCheatPatchList romPatches;
struct StringList lines;
};
DECLARE_VECTOR(mCheatSets, struct mCheatSet*);
struct mCheatDevice {
struct mCPUComponent d;
struct mCore* p;
struct mCheatSet* (*createSet)(struct mCheatDevice*, const char* name);
struct mCheatSets cheats;
struct Table unpatchedMemory;
bool autosave;
bool buttonDown;
};
struct VFile;
void mCheatDeviceCreate(struct mCheatDevice*);
void mCheatDeviceDestroy(struct mCheatDevice*);
void mCheatDeviceClear(struct mCheatDevice*);
void mCheatSetInit(struct mCheatSet*, const char* name);
void mCheatSetDeinit(struct mCheatSet*);
void mCheatSetRename(struct mCheatSet*, const char* name);
bool mCheatAddLine(struct mCheatSet*, const char* line, int type);
void mCheatAddSet(struct mCheatDevice*, struct mCheatSet*);
void mCheatRemoveSet(struct mCheatDevice*, struct mCheatSet*);
bool mCheatParseFile(struct mCheatDevice*, struct VFile*);
bool mCheatSaveFile(struct mCheatDevice*, struct VFile*);
bool mCheatParseLibretroFile(struct mCheatDevice*, struct VFile*);
bool mCheatParseEZFChtFile(struct mCheatDevice*, struct VFile*);
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
void mCheatAutosave(struct mCheatDevice*);
#endif
void mCheatRefresh(struct mCheatDevice*, struct mCheatSet*);
void mCheatPressButton(struct mCheatDevice*, bool down);
CXX_GUARD_END
#endif

View file

@ -1,115 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CORE_CONFIG_H
#define M_CORE_CONFIG_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/configuration.h>
struct mCoreConfig {
struct Configuration configTable;
struct Configuration defaultsTable;
struct Configuration overridesTable;
char* port;
};
enum mCoreConfigLevel {
mCONFIG_LEVEL_DEFAULT = 0,
mCONFIG_LEVEL_CUSTOM,
mCONFIG_LEVEL_OVERRIDE,
};
struct mCoreOptions {
char* bios;
bool skipBios;
bool useBios;
int logLevel;
int frameskip;
bool rewindEnable;
int rewindBufferCapacity;
float fpsTarget;
size_t audioBuffers;
unsigned sampleRate;
int fullscreen;
int width;
int height;
bool lockAspectRatio;
bool lockIntegerScaling;
bool interframeBlending;
bool resampleVideo;
bool suspendScreensaver;
char* shader;
char* savegamePath;
char* savestatePath;
char* screenshotPath;
char* patchPath;
char* cheatsPath;
int volume;
bool mute;
bool videoSync;
bool audioSync;
};
void mCoreConfigInit(struct mCoreConfig*, const char* port);
void mCoreConfigDeinit(struct mCoreConfig*);
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
bool mCoreConfigLoad(struct mCoreConfig*);
bool mCoreConfigSave(const struct mCoreConfig*);
bool mCoreConfigLoadPath(struct mCoreConfig*, const char* path);
bool mCoreConfigSavePath(const struct mCoreConfig*, const char* path);
bool mCoreConfigLoadVFile(struct mCoreConfig*, struct VFile* vf);
bool mCoreConfigSaveVFile(const struct mCoreConfig*, struct VFile* vf);
void mCoreConfigMakePortable(const struct mCoreConfig*);
void mCoreConfigDirectory(char* out, size_t outLength);
void mCoreConfigPortablePath(char* out, size_t outLength);
bool mCoreConfigIsPortable(void);
#endif
const char* mCoreConfigGetValue(const struct mCoreConfig*, const char* key);
bool mCoreConfigGetIntValue(const struct mCoreConfig*, const char* key, int* value);
bool mCoreConfigGetUIntValue(const struct mCoreConfig*, const char* key, unsigned* value);
bool mCoreConfigGetFloatValue(const struct mCoreConfig*, const char* key, float* value);
void mCoreConfigSetValue(struct mCoreConfig*, const char* key, const char* value);
void mCoreConfigSetIntValue(struct mCoreConfig*, const char* key, int value);
void mCoreConfigSetUIntValue(struct mCoreConfig*, const char* key, unsigned value);
void mCoreConfigSetFloatValue(struct mCoreConfig*, const char* key, float value);
void mCoreConfigSetDefaultValue(struct mCoreConfig*, const char* key, const char* value);
void mCoreConfigSetDefaultIntValue(struct mCoreConfig*, const char* key, int value);
void mCoreConfigSetDefaultUIntValue(struct mCoreConfig*, const char* key, unsigned value);
void mCoreConfigSetDefaultFloatValue(struct mCoreConfig*, const char* key, float value);
void mCoreConfigSetOverrideValue(struct mCoreConfig*, const char* key, const char* value);
void mCoreConfigSetOverrideIntValue(struct mCoreConfig*, const char* key, int value);
void mCoreConfigSetOverrideUIntValue(struct mCoreConfig*, const char* key, unsigned value);
void mCoreConfigSetOverrideFloatValue(struct mCoreConfig*, const char* key, float value);
void mCoreConfigCopyValue(struct mCoreConfig* config, const struct mCoreConfig* src, const char* key);
void mCoreConfigMap(const struct mCoreConfig* config, struct mCoreOptions* opts);
void mCoreConfigLoadDefaults(struct mCoreConfig* config, const struct mCoreOptions* opts);
void mCoreConfigEnumerate(const struct mCoreConfig* config, const char* prefix, void (*handler)(const char* key, const char* value, enum mCoreConfigLevel type, void* user), void* user);
struct Configuration* mCoreConfigGetInput(struct mCoreConfig*);
struct Configuration* mCoreConfigGetOverrides(struct mCoreConfig*);
const struct Configuration* mCoreConfigGetOverridesConst(const struct mCoreConfig*);
void mCoreConfigFreeOpts(struct mCoreOptions* opts);
CXX_GUARD_END
#endif

View file

@ -1,214 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CORE_H
#define M_CORE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/config.h>
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
#include <mgba/core/directories.h>
#endif
#ifndef MINIMAL_CORE
#include <mgba/core/input.h>
#endif
#include <mgba/core/interface.h>
#ifdef USE_DEBUGGERS
#include <mgba/debugger/debugger.h>
#endif
enum mPlatform {
mPLATFORM_NONE = -1,
mPLATFORM_GBA = 0,
mPLATFORM_GB = 1,
};
enum mCoreChecksumType {
mCHECKSUM_CRC32,
};
struct mCoreConfig;
struct mCoreSync;
struct mDebuggerSymbols;
struct mStateExtdata;
struct mVideoLogContext;
struct mCore {
void* cpu;
void* board;
struct mTiming* timing;
struct mDebugger* debugger;
struct mDebuggerSymbols* symbolTable;
struct mVideoLogger* videoLogger;
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct mDirectorySet dirs;
#endif
#ifndef MINIMAL_CORE
struct mInputMap inputMap;
#endif
struct mCoreConfig config;
struct mCoreOptions opts;
struct mRTCGenericSource rtc;
bool (*init)(struct mCore*);
void (*deinit)(struct mCore*);
enum mPlatform (*platform)(const struct mCore*);
bool (*supportsFeature)(const struct mCore*, enum mCoreFeature);
void (*setSync)(struct mCore*, struct mCoreSync*);
void (*loadConfig)(struct mCore*, const struct mCoreConfig*);
void (*reloadConfigOption)(struct mCore*, const char* option, const struct mCoreConfig*);
void (*desiredVideoDimensions)(const struct mCore*, unsigned* width, unsigned* height);
void (*setVideoBuffer)(struct mCore*, color_t* buffer, size_t stride);
void (*setVideoGLTex)(struct mCore*, unsigned texid);
void (*getPixels)(struct mCore*, const void** buffer, size_t* stride);
void (*putPixels)(struct mCore*, const void* buffer, size_t stride);
struct blip_t* (*getAudioChannel)(struct mCore*, int ch);
void (*setAudioBufferSize)(struct mCore*, size_t samples);
size_t (*getAudioBufferSize)(struct mCore*);
void (*addCoreCallbacks)(struct mCore*, struct mCoreCallbacks*);
void (*clearCoreCallbacks)(struct mCore*);
void (*setAVStream)(struct mCore*, struct mAVStream*);
bool (*isROM)(struct VFile* vf);
bool (*loadROM)(struct mCore*, struct VFile* vf);
bool (*loadSave)(struct mCore*, struct VFile* vf);
bool (*loadTemporarySave)(struct mCore*, struct VFile* vf);
void (*unloadROM)(struct mCore*);
void (*checksum)(const struct mCore*, void* data, enum mCoreChecksumType type);
bool (*loadBIOS)(struct mCore*, struct VFile* vf, int biosID);
bool (*selectBIOS)(struct mCore*, int biosID);
bool (*loadPatch)(struct mCore*, struct VFile* vf);
void (*reset)(struct mCore*);
void (*runFrame)(struct mCore*);
void (*runLoop)(struct mCore*);
void (*step)(struct mCore*);
size_t (*stateSize)(struct mCore*);
bool (*loadState)(struct mCore*, const void* state);
bool (*saveState)(struct mCore*, void* state);
void (*setKeys)(struct mCore*, uint32_t keys);
void (*addKeys)(struct mCore*, uint32_t keys);
void (*clearKeys)(struct mCore*, uint32_t keys);
int32_t (*frameCounter)(const struct mCore*);
int32_t (*frameCycles)(const struct mCore*);
int32_t (*frequency)(const struct mCore*);
void (*getGameTitle)(const struct mCore*, char* title);
void (*getGameCode)(const struct mCore*, char* title);
void (*setPeripheral)(struct mCore*, int type, void*);
uint32_t (*busRead8)(struct mCore*, uint32_t address);
uint32_t (*busRead16)(struct mCore*, uint32_t address);
uint32_t (*busRead32)(struct mCore*, uint32_t address);
void (*busWrite8)(struct mCore*, uint32_t address, uint8_t);
void (*busWrite16)(struct mCore*, uint32_t address, uint16_t);
void (*busWrite32)(struct mCore*, uint32_t address, uint32_t);
uint32_t (*rawRead8)(struct mCore*, uint32_t address, int segment);
uint32_t (*rawRead16)(struct mCore*, uint32_t address, int segment);
uint32_t (*rawRead32)(struct mCore*, uint32_t address, int segment);
void (*rawWrite8)(struct mCore*, uint32_t address, int segment, uint8_t);
void (*rawWrite16)(struct mCore*, uint32_t address, int segment, uint16_t);
void (*rawWrite32)(struct mCore*, uint32_t address, int segment, uint32_t);
size_t (*listMemoryBlocks)(const struct mCore*, const struct mCoreMemoryBlock**);
void* (*getMemoryBlock)(struct mCore*, size_t id, size_t* sizeOut);
#ifdef USE_DEBUGGERS
bool (*supportsDebuggerType)(struct mCore*, enum mDebuggerType);
struct mDebuggerPlatform* (*debuggerPlatform)(struct mCore*);
struct CLIDebuggerSystem* (*cliDebuggerSystem)(struct mCore*);
void (*attachDebugger)(struct mCore*, struct mDebugger*);
void (*detachDebugger)(struct mCore*);
void (*loadSymbols)(struct mCore*, struct VFile*);
bool (*lookupIdentifier)(struct mCore*, const char* name, int32_t* value, int* segment);
#endif
struct mCheatDevice* (*cheatDevice)(struct mCore*);
size_t (*savedataClone)(struct mCore*, void** sram);
bool (*savedataRestore)(struct mCore*, const void* sram, size_t size, bool writeback);
size_t (*listVideoLayers)(const struct mCore*, const struct mCoreChannelInfo**);
size_t (*listAudioChannels)(const struct mCore*, const struct mCoreChannelInfo**);
void (*enableVideoLayer)(struct mCore*, size_t id, bool enable);
void (*enableAudioChannel)(struct mCore*, size_t id, bool enable);
void (*adjustVideoLayer)(struct mCore*, size_t id, int32_t x, int32_t y);
#ifndef MINIMAL_CORE
void (*startVideoLog)(struct mCore*, struct mVideoLogContext*);
void (*endVideoLog)(struct mCore*);
#endif
};
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct mCore* mCoreFind(const char* path);
bool mCoreLoadFile(struct mCore* core, const char* path);
bool mCorePreloadVF(struct mCore* core, struct VFile* vf);
bool mCorePreloadFile(struct mCore* core, const char* path);
bool mCorePreloadVFCB(struct mCore* core, struct VFile* vf, void (cb)(size_t, size_t, void*), void* context);
bool mCorePreloadFileCB(struct mCore* core, const char* path, void (cb)(size_t, size_t, void*), void* context);
bool mCoreAutoloadSave(struct mCore* core);
bool mCoreAutoloadPatch(struct mCore* core);
bool mCoreAutoloadCheats(struct mCore* core);
bool mCoreSaveState(struct mCore* core, int slot, int flags);
bool mCoreLoadState(struct mCore* core, int slot, int flags);
struct VFile* mCoreGetState(struct mCore* core, int slot, bool write);
void mCoreDeleteState(struct mCore* core, int slot);
void mCoreTakeScreenshot(struct mCore* core);
#endif
struct mCore* mCoreFindVF(struct VFile* vf);
enum mPlatform mCoreIsCompatible(struct VFile* vf);
struct mCore* mCoreCreate(enum mPlatform);
bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags);
bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags);
void mCoreInitConfig(struct mCore* core, const char* port);
void mCoreLoadConfig(struct mCore* core);
void mCoreLoadForeignConfig(struct mCore* core, const struct mCoreConfig* config);
void mCoreSetRTC(struct mCore* core, struct mRTCSource* rtc);
void* mCoreGetMemoryBlock(struct mCore* core, uint32_t start, size_t* size);
void* mCoreGetMemoryBlockMasked(struct mCore* core, uint32_t start, size_t* size, uint32_t mask);
const struct mCoreMemoryBlock* mCoreGetMemoryBlockInfo(struct mCore* core, uint32_t address);
#ifdef USE_ELF
struct ELF;
bool mCoreLoadELF(struct mCore* core, struct ELF* elf);
#ifdef USE_DEBUGGERS
void mCoreLoadELFSymbols(struct mDebuggerSymbols* symbols, struct ELF*);
#endif
#endif
CXX_GUARD_END
#endif

View file

@ -1,31 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CPU_H
#define M_CPU_H
#include <mgba-util/common.h>
CXX_GUARD_START
enum mCPUComponentType {
CPU_COMPONENT_DEBUGGER,
CPU_COMPONENT_CHEAT_DEVICE,
CPU_COMPONENT_MISC_1,
CPU_COMPONENT_MISC_2,
CPU_COMPONENT_MISC_3,
CPU_COMPONENT_MISC_4,
CPU_COMPONENT_MAX
};
struct mCPUComponent {
uint32_t id;
void (*init)(void* cpu, struct mCPUComponent* component);
void (*deinit)(struct mCPUComponent* component);
};
CXX_GUARD_END
#endif

View file

@ -1,42 +0,0 @@
/* Copyright (c) 2013-2015 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 DIRECTORIES_H
#define DIRECTORIES_H
#include <mgba-util/common.h>
CXX_GUARD_START
#if !defined(MINIMAL_CORE) || MINIMAL_CORE < 2
struct VDir;
struct mDirectorySet {
char baseName[PATH_MAX];
struct VDir* base;
struct VDir* archive;
struct VDir* save;
struct VDir* patch;
struct VDir* state;
struct VDir* screenshot;
struct VDir* cheats;
};
void mDirectorySetInit(struct mDirectorySet* dirs);
void mDirectorySetDeinit(struct mDirectorySet* dirs);
void mDirectorySetAttachBase(struct mDirectorySet* dirs, struct VDir* base);
void mDirectorySetDetachBase(struct mDirectorySet* dirs);
struct VFile* mDirectorySetOpenPath(struct mDirectorySet* dirs, const char* path, bool (*filter)(struct VFile*));
struct VFile* mDirectorySetOpenSuffix(struct mDirectorySet* dirs, struct VDir* dir, const char* suffix, int mode);
struct mCoreOptions;
void mDirectorySetMapOptions(struct mDirectorySet* dirs, const struct mCoreOptions* opts);
#endif
CXX_GUARD_END
#endif

View file

@ -1,89 +0,0 @@
/* Copyright (c) 2013-2016 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 M_INPUT_H
#define M_INPUT_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct Configuration;
enum mInputHat {
M_INPUT_HAT_NEUTRAL = 0,
M_INPUT_HAT_UP = 1,
M_INPUT_HAT_RIGHT = 2,
M_INPUT_HAT_DOWN = 4,
M_INPUT_HAT_LEFT = 8
};
struct mInputHatBindings {
int up;
int right;
int down;
int left;
};
struct mInputPlatformInfo {
const char* platformName;
const char** keyId;
size_t nKeys;
struct mInputHatBindings hat;
};
struct mInputMap {
struct mInputMapImpl* maps;
size_t numMaps;
const struct mInputPlatformInfo* info;
};
struct mInputAxis {
int highDirection;
int lowDirection;
int32_t deadHigh;
int32_t deadLow;
};
void mInputMapInit(struct mInputMap*, const struct mInputPlatformInfo* info);
void mInputMapDeinit(struct mInputMap*);
int mInputMapKey(const struct mInputMap*, uint32_t type, int key);
int mInputMapKeyBits(const struct mInputMap* map, uint32_t type, uint32_t bits, unsigned offset);
void mInputBindKey(struct mInputMap*, uint32_t type, int key, int input);
int mInputQueryBinding(const struct mInputMap*, uint32_t type, int input);
void mInputUnbindKey(struct mInputMap*, uint32_t type, int input);
int mInputMapAxis(const struct mInputMap*, uint32_t type, int axis, int value);
int mInputClearAxis(const struct mInputMap*, uint32_t type, int axis, int keys);
void mInputBindAxis(struct mInputMap*, uint32_t type, int axis, const struct mInputAxis* description);
void mInputUnbindAxis(struct mInputMap*, uint32_t type, int axis);
void mInputUnbindAllAxes(struct mInputMap*, uint32_t type);
const struct mInputAxis* mInputQueryAxis(const struct mInputMap*, uint32_t type, int axis);
void mInputEnumerateAxes(const struct mInputMap*, uint32_t type, void (handler(int axis, const struct mInputAxis* description, void* user)), void* user);
int mInputMapHat(const struct mInputMap*, uint32_t type, int id, int direction);
void mInputBindHat(struct mInputMap*, uint32_t type, int id, const struct mInputHatBindings* bindings);
bool mInputQueryHat(const struct mInputMap*, uint32_t type, int id, struct mInputHatBindings* bindings);
void mInputUnbindHat(struct mInputMap*, uint32_t type, int id);
void mInputUnbindAllHats(struct mInputMap*, uint32_t type);
void mInputMapLoad(struct mInputMap*, uint32_t type, const struct Configuration*);
void mInputMapSave(const struct mInputMap*, uint32_t type, struct Configuration*);
bool mInputProfileLoad(struct mInputMap*, uint32_t type, const struct Configuration*, const char* profile);
void mInputProfileSave(const struct mInputMap*, uint32_t type, struct Configuration*, const char* profile);
const char* mInputGetPreferredDevice(const struct Configuration*, const char* platformName, uint32_t type, int playerId);
void mInputSetPreferredDevice(struct Configuration*, const char* platformName, uint32_t type, int playerId, const char* deviceName);
const char* mInputGetCustomValue(const struct Configuration* config, const char* platformName, uint32_t type, const char* key,
const char* profile);
void mInputSetCustomValue(struct Configuration* config, const char* platformName, uint32_t type, const char* key, const char* value,
const char* profile);
CXX_GUARD_END
#endif

View file

@ -1,288 +0,0 @@
/* Copyright (c) 2013-2015 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 CORE_INTERFACE_H
#define CORE_INTERFACE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/vector.h>
struct mCore;
struct mStateExtdataItem;
#ifdef COLOR_16_BIT
typedef uint16_t color_t;
#define BYTES_PER_PIXEL 2
#else
typedef uint32_t color_t;
#define BYTES_PER_PIXEL 4
#endif
#define M_R5(X) ((X) & 0x1F)
#define M_G5(X) (((X) >> 5) & 0x1F)
#define M_B5(X) (((X) >> 10) & 0x1F)
#define M_R8(X) (((((X) << 3) & 0xF8) * 0x21) >> 5)
#define M_G8(X) (((((X) >> 2) & 0xF8) * 0x21) >> 5)
#define M_B8(X) (((((X) >> 7) & 0xF8) * 0x21) >> 5)
#define M_RGB5_TO_BGR8(X) ((M_R5(X) << 3) | (M_G5(X) << 11) | (M_B5(X) << 19))
#define M_RGB5_TO_RGB8(X) ((M_R5(X) << 19) | (M_G5(X) << 11) | (M_B5(X) << 3))
#define M_RGB8_TO_BGR5(X) ((((X) & 0xF8) >> 3) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 9))
#define M_RGB8_TO_RGB5(X) ((((X) & 0xF8) << 7) | (((X) & 0xF800) >> 6) | (((X) & 0xF80000) >> 19))
#ifndef COLOR_16_BIT
#define M_COLOR_RED 0x000000FF
#define M_COLOR_GREEN 0x0000FF00
#define M_COLOR_BLUE 0x00FF0000
#define M_COLOR_ALPHA 0xFF000000
#define M_COLOR_WHITE 0x00FFFFFF
#define M_RGB8_TO_NATIVE(X) (((X) & 0x00FF00) | (((X) & 0x0000FF) << 16) | (((X) & 0xFF0000) >> 16))
#elif defined(COLOR_5_6_5)
#define M_COLOR_RED 0x001F
#define M_COLOR_GREEN 0x07E0
#define M_COLOR_BLUE 0xF800
#define M_COLOR_ALPHA 0x0000
#define M_COLOR_WHITE 0xFFDF
#define M_RGB8_TO_NATIVE(X) ((((X) & 0xF8) << 8) | (((X) & 0xFC00) >> 5) | (((X) & 0xF80000) >> 19))
#else
#define M_COLOR_RED 0x001F
#define M_COLOR_GREEN 0x03E0
#define M_COLOR_BLUE 0x7C00
#define M_COLOR_ALPHA 0x1000
#define M_COLOR_WHITE 0x7FFF
#define M_RGB8_TO_NATIVE(X) M_RGB8_TO_BGR5(X)
#endif
#ifndef PYCPARSE
static inline color_t mColorFrom555(uint16_t value) {
#ifdef COLOR_16_BIT
#ifdef COLOR_5_6_5
color_t color = 0;
color |= (value & 0x001F) << 11;
color |= (value & 0x03E0) << 1;
color |= (value & 0x7C00) >> 10;
#else
color_t color = value;
#endif
#else
color_t color = M_RGB5_TO_BGR8(value);
color |= (color >> 5) & 0x070707;
#endif
return color;
}
ATTRIBUTE_UNUSED static unsigned mColorMix5Bit(int weightA, unsigned colorA, int weightB, unsigned colorB) {
unsigned c = 0;
unsigned a, b;
#ifdef COLOR_16_BIT
#ifdef COLOR_5_6_5
a = colorA & 0xF81F;
b = colorB & 0xF81F;
a |= (colorA & 0x7C0) << 16;
b |= (colorB & 0x7C0) << 16;
c = ((a * weightA + b * weightB) / 16);
if (c & 0x08000000) {
c = (c & ~0x0FC00000) | 0x07C00000;
}
if (c & 0x0020) {
c = (c & ~0x003F) | 0x001F;
}
if (c & 0x10000) {
c = (c & ~0x1F800) | 0xF800;
}
c = (c & 0xF81F) | ((c >> 16) & 0x07C0);
#else
a = colorA & 0x7C1F;
b = colorB & 0x7C1F;
a |= (colorA & 0x3E0) << 16;
b |= (colorB & 0x3E0) << 16;
c = ((a * weightA + b * weightB) / 16);
if (c & 0x04000000) {
c = (c & ~0x07E00000) | 0x03E00000;
}
if (c & 0x0020) {
c = (c & ~0x003F) | 0x001F;
}
if (c & 0x8000) {
c = (c & ~0xF800) | 0x7C00;
}
c = (c & 0x7C1F) | ((c >> 16) & 0x03E0);
#endif
#else
a = colorA & 0xFF;
b = colorB & 0xFF;
c |= ((a * weightA + b * weightB) / 16) & 0x1FF;
if (c & 0x00000100) {
c = 0x000000FF;
}
a = colorA & 0xFF00;
b = colorB & 0xFF00;
c |= ((a * weightA + b * weightB) / 16) & 0x1FF00;
if (c & 0x00010000) {
c = (c & 0x000000FF) | 0x0000FF00;
}
a = colorA & 0xFF0000;
b = colorB & 0xFF0000;
c |= ((a * weightA + b * weightB) / 16) & 0x1FF0000;
if (c & 0x01000000) {
c = (c & 0x0000FFFF) | 0x00FF0000;
}
#endif
return c;
}
#endif
struct blip_t;
enum mColorFormat {
mCOLOR_XBGR8 = 0x00001,
mCOLOR_XRGB8 = 0x00002,
mCOLOR_BGRX8 = 0x00004,
mCOLOR_RGBX8 = 0x00008,
mCOLOR_ABGR8 = 0x00010,
mCOLOR_ARGB8 = 0x00020,
mCOLOR_BGRA8 = 0x00040,
mCOLOR_RGBA8 = 0x00080,
mCOLOR_RGB5 = 0x00100,
mCOLOR_BGR5 = 0x00200,
mCOLOR_RGB565 = 0x00400,
mCOLOR_BGR565 = 0x00800,
mCOLOR_ARGB5 = 0x01000,
mCOLOR_ABGR5 = 0x02000,
mCOLOR_RGBA5 = 0x04000,
mCOLOR_BGRA5 = 0x08000,
mCOLOR_RGB8 = 0x10000,
mCOLOR_BGR8 = 0x20000,
mCOLOR_ANY = -1
};
enum mCoreFeature {
mCORE_FEATURE_OPENGL = 1,
};
struct mCoreCallbacks {
void* context;
void (*videoFrameStarted)(void* context);
void (*videoFrameEnded)(void* context);
void (*coreCrashed)(void* context);
void (*sleep)(void* context);
void (*shutdown)(void* context);
void (*keysRead)(void* context);
void (*savedataUpdated)(void* context);
};
DECLARE_VECTOR(mCoreCallbacksList, struct mCoreCallbacks);
struct mAVStream {
void (*videoDimensionsChanged)(struct mAVStream*, unsigned width, unsigned height);
void (*postVideoFrame)(struct mAVStream*, const color_t* buffer, size_t stride);
void (*postAudioFrame)(struct mAVStream*, int16_t left, int16_t right);
void (*postAudioBuffer)(struct mAVStream*, struct blip_t* left, struct blip_t* right);
};
struct mKeyCallback {
uint16_t (*readKeys)(struct mKeyCallback*);
};
enum mPeripheral {
mPERIPH_ROTATION = 1,
mPERIPH_RUMBLE,
mPERIPH_IMAGE_SOURCE,
mPERIPH_CUSTOM = 0x1000
};
struct mRotationSource {
void (*sample)(struct mRotationSource*);
int32_t (*readTiltX)(struct mRotationSource*);
int32_t (*readTiltY)(struct mRotationSource*);
int32_t (*readGyroZ)(struct mRotationSource*);
};
struct mRTCSource {
void (*sample)(struct mRTCSource*);
time_t (*unixTime)(struct mRTCSource*);
void (*serialize)(struct mRTCSource*, struct mStateExtdataItem*);
bool (*deserialize)(struct mRTCSource*, const struct mStateExtdataItem*);
};
struct mImageSource {
void (*startRequestImage)(struct mImageSource*, unsigned w, unsigned h, int colorFormats);
void (*stopRequestImage)(struct mImageSource*);
void (*requestImage)(struct mImageSource*, const void** buffer, size_t* stride, enum mColorFormat* colorFormat);
};
enum mRTCGenericType {
RTC_NO_OVERRIDE,
RTC_FIXED,
RTC_FAKE_EPOCH,
RTC_CUSTOM_START = 0x1000
};
struct mRTCGenericSource {
struct mRTCSource d;
struct mCore* p;
enum mRTCGenericType override;
int64_t value;
struct mRTCSource* custom;
};
struct mRTCGenericState {
int32_t type;
int32_t padding;
int64_t value;
};
void mRTCGenericSourceInit(struct mRTCGenericSource* rtc, struct mCore* core);
struct mRumble {
void (*setRumble)(struct mRumble*, int enable);
};
struct mCoreChannelInfo {
size_t id;
const char* internalName;
const char* visibleName;
const char* visibleType;
};
enum mCoreMemoryBlockFlags {
mCORE_MEMORY_READ = 0x01,
mCORE_MEMORY_WRITE = 0x02,
mCORE_MEMORY_RW = 0x03,
mCORE_MEMORY_WORM = 0x04,
mCORE_MEMORY_MAPPED = 0x10,
mCORE_MEMORY_VIRTUAL = 0x20,
};
struct mCoreMemoryBlock {
size_t id;
const char* internalName;
const char* shortName;
const char* longName;
uint32_t start;
uint32_t end;
uint32_t size;
uint32_t flags;
uint16_t maxSegment;
uint32_t segmentStart;
};
CXX_GUARD_END
#endif

View file

@ -1,53 +0,0 @@
/* Copyright (c) 2013-2016 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 M_LIBRARY_H
#define M_LIBRARY_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/core.h>
#include <mgba-util/vector.h>
struct mLibraryEntry {
const char* base;
const char* filename;
const char* title;
char internalTitle[17];
char internalCode[9];
enum mPlatform platform;
size_t filesize;
uint32_t crc32;
};
#ifdef USE_SQLITE3
DECLARE_VECTOR(mLibraryListing, struct mLibraryEntry);
struct mLibrary;
struct mLibrary* mLibraryCreateEmpty(void);
struct mLibrary* mLibraryLoad(const char* filename);
void mLibraryDestroy(struct mLibrary*);
struct VDir;
struct VFile;
void mLibraryLoadDirectory(struct mLibrary* library, const char* base, bool recursive);
void mLibraryClear(struct mLibrary* library);
size_t mLibraryCount(struct mLibrary* library, const struct mLibraryEntry* constraints);
size_t mLibraryGetEntries(struct mLibrary* library, struct mLibraryListing* out, size_t numEntries, size_t offset, const struct mLibraryEntry* constraints);
void mLibraryEntryFree(struct mLibraryEntry* entry);
struct VFile* mLibraryOpenVFile(struct mLibrary* library, const struct mLibraryEntry* entry);
struct NoIntroDB;
void mLibraryAttachGameDB(struct mLibrary* library, const struct NoIntroDB* db);
#endif
CXX_GUARD_END
#endif

View file

@ -1,58 +0,0 @@
/* Copyright (c) 2013-2016 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 SIO_LOCKSTEP_H
#define SIO_LOCKSTEP_H
#include <mgba-util/common.h>
CXX_GUARD_START
enum mLockstepPhase {
TRANSFER_IDLE = 0,
TRANSFER_STARTING,
TRANSFER_STARTED,
TRANSFER_FINISHING,
TRANSFER_FINISHED
};
struct mLockstep {
int attached;
enum mLockstepPhase transferActive;
int32_t transferCycles;
void (*lock)(struct mLockstep*);
void (*unlock)(struct mLockstep*);
bool (*signal)(struct mLockstep*, unsigned mask);
bool (*wait)(struct mLockstep*, unsigned mask);
void (*addCycles)(struct mLockstep*, int id, int32_t cycles);
int32_t (*useCycles)(struct mLockstep*, int id, int32_t cycles);
int32_t (*unusedCycles)(struct mLockstep*, int id);
void (*unload)(struct mLockstep*, int id);
void* context;
#ifndef NDEBUG
int transferId;
#endif
};
void mLockstepInit(struct mLockstep*);
void mLockstepDeinit(struct mLockstep*);
static inline void mLockstepLock(struct mLockstep* lockstep) {
if (lockstep->lock) {
lockstep->lock(lockstep);
}
}
static inline void mLockstepUnlock(struct mLockstep* lockstep) {
if (lockstep->unlock) {
lockstep->unlock(lockstep);
}
}
CXX_GUARD_END
#endif

View file

@ -1,72 +0,0 @@
/* Copyright (c) 2013-2016 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 M_LOG_H
#define M_LOG_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/table.h>
enum mLogLevel {
mLOG_FATAL = 0x01,
mLOG_ERROR = 0x02,
mLOG_WARN = 0x04,
mLOG_INFO = 0x08,
mLOG_DEBUG = 0x10,
mLOG_STUB = 0x20,
mLOG_GAME_ERROR = 0x40,
mLOG_ALL = 0x7F
};
struct Table;
struct mLogFilter {
int defaultLevels;
struct Table categories;
struct Table levels;
};
struct mLogger {
void (*log)(struct mLogger*, int category, enum mLogLevel level, const char* format, va_list args);
struct mLogFilter* filter;
};
struct mLogger* mLogGetContext(void);
void mLogSetDefaultLogger(struct mLogger*);
int mLogGenerateCategory(const char*, const char*);
const char* mLogCategoryName(int);
const char* mLogCategoryId(int);
int mLogCategoryById(const char*);
struct mCoreConfig;
void mLogFilterInit(struct mLogFilter*);
void mLogFilterDeinit(struct mLogFilter*);
void mLogFilterLoad(struct mLogFilter*, const struct mCoreConfig*);
void mLogFilterSave(const struct mLogFilter*, struct mCoreConfig*);
void mLogFilterSet(struct mLogFilter*, const char* category, int levels);
void mLogFilterReset(struct mLogFilter*, const char* category);
bool mLogFilterTest(const struct mLogFilter*, int category, enum mLogLevel level);
int mLogFilterLevels(const struct mLogFilter*, int category);
ATTRIBUTE_FORMAT(printf, 3, 4)
void mLog(int category, enum mLogLevel level, const char* format, ...);
#define mLOG(CATEGORY, LEVEL, ...) mLog(_mLOG_CAT_ ## CATEGORY, mLOG_ ## LEVEL, __VA_ARGS__)
#define mLOG_DECLARE_CATEGORY(CATEGORY) extern int _mLOG_CAT_ ## CATEGORY;
#define mLOG_DEFINE_CATEGORY(CATEGORY, NAME, ID) \
int _mLOG_CAT_ ## CATEGORY; \
CONSTRUCTOR(_mLOG_CAT_ ## CATEGORY ## _INIT) { \
_mLOG_CAT_ ## CATEGORY = mLogGenerateCategory(NAME, ID); \
}
MGBA_EXPORT mLOG_DECLARE_CATEGORY(STATUS)
CXX_GUARD_END
#endif

View file

@ -1,79 +0,0 @@
/* Copyright (c) 2013-2017 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 M_MAP_CACHE_H
#define M_MAP_CACHE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/interface.h>
#include <mgba/core/tile-cache.h>
DECL_BITFIELD(mMapCacheConfiguration, uint32_t);
DECL_BIT(mMapCacheConfiguration, ShouldStore, 0);
DECL_BITFIELD(mMapCacheSystemInfo, uint32_t);
DECL_BITS(mMapCacheSystemInfo, PaletteBPP, 0, 2);
DECL_BITS(mMapCacheSystemInfo, PaletteCount, 2, 4);
DECL_BITS(mMapCacheSystemInfo, TilesWide, 8, 4);
DECL_BITS(mMapCacheSystemInfo, TilesHigh, 12, 4);
DECL_BITS(mMapCacheSystemInfo, MacroTileSize, 16, 7);
DECL_BITS(mMapCacheSystemInfo, MapAlign, 23, 2);
DECL_BITFIELD(mMapCacheEntryFlags, uint16_t);
DECL_BITS(mMapCacheEntryFlags, PaletteId, 0, 4);
DECL_BIT(mMapCacheEntryFlags, VramClean, 4);
DECL_BIT(mMapCacheEntryFlags, HMirror, 5);
DECL_BIT(mMapCacheEntryFlags, VMirror, 6);
DECL_BITS(mMapCacheEntryFlags, Mirror, 5, 2);
struct mMapCacheEntry {
uint32_t vramVersion;
uint16_t tileId;
mMapCacheEntryFlags flags;
struct mTileCacheEntry tileStatus[16];
};
struct mTileCache;
struct mTileCacheEntry;
struct mMapCache {
color_t* cache;
struct mTileCache* tileCache;
struct mMapCacheEntry* status;
uint8_t* vram;
uint32_t mapStart;
uint32_t mapSize;
uint32_t tileStart;
mMapCacheConfiguration config;
mMapCacheSystemInfo sysConfig;
void (*mapParser)(struct mMapCache*, struct mMapCacheEntry* entry, void* vram);
void* context;
};
void mMapCacheInit(struct mMapCache* cache);
void mMapCacheDeinit(struct mMapCache* cache);
void mMapCacheConfigure(struct mMapCache* cache, mMapCacheConfiguration config);
void mMapCacheConfigureSystem(struct mMapCache* cache, mMapCacheSystemInfo config);
void mMapCacheConfigureMap(struct mMapCache* cache, uint32_t mapStart);
void mMapCacheWriteVRAM(struct mMapCache* cache, uint32_t address);
uint32_t mMapCacheTileId(struct mMapCache* cache, unsigned x, unsigned y);
bool mMapCacheCheckTile(struct mMapCache* cache, const struct mMapCacheEntry* entry, unsigned x, unsigned y);
void mMapCacheCleanTile(struct mMapCache* cache, struct mMapCacheEntry* entry, unsigned x, unsigned y);
void mMapCacheCleanRow(struct mMapCache* cache, unsigned y);
const color_t* mMapCacheGetRow(struct mMapCache* cache, unsigned y);
CXX_GUARD_END
#endif

View file

@ -1,62 +0,0 @@
/* Copyright (c) 2013-2017 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 CORE_MEM_SEARCH_H
#define CORE_MEM_SEARCH_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/vector.h>
enum mCoreMemorySearchType {
mCORE_MEMORY_SEARCH_INT,
mCORE_MEMORY_SEARCH_STRING,
mCORE_MEMORY_SEARCH_GUESS,
};
enum mCoreMemorySearchOp {
mCORE_MEMORY_SEARCH_EQUAL,
mCORE_MEMORY_SEARCH_GREATER,
mCORE_MEMORY_SEARCH_LESS,
mCORE_MEMORY_SEARCH_ANY,
mCORE_MEMORY_SEARCH_DELTA,
mCORE_MEMORY_SEARCH_DELTA_POSITIVE,
mCORE_MEMORY_SEARCH_DELTA_NEGATIVE,
mCORE_MEMORY_SEARCH_DELTA_ANY,
};
struct mCoreMemorySearchParams {
int memoryFlags;
enum mCoreMemorySearchType type;
enum mCoreMemorySearchOp op;
int align;
int width;
union {
const char* valueStr;
int32_t valueInt;
};
};
struct mCoreMemorySearchResult {
uint32_t address;
int segment;
uint32_t guessDivisor;
uint32_t guessMultiplier;
enum mCoreMemorySearchType type;
int width;
int32_t oldValue;
};
DECLARE_VECTOR(mCoreMemorySearchResults, struct mCoreMemorySearchResult);
struct mCore;
void mCoreMemorySearch(struct mCore* core, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit);
void mCoreMemorySearchRepeat(struct mCore* core, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* inout);
CXX_GUARD_END
#endif

View file

@ -1,46 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CORE_REWIND_H
#define M_CORE_REWIND_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/vector.h>
#ifndef DISABLE_THREADING
#include <mgba-util/threading.h>
#endif
DECLARE_VECTOR(mCoreRewindPatches, struct PatchFast);
struct VFile;
struct mCoreRewindContext {
struct mCoreRewindPatches patchMemory;
size_t current;
size_t size;
struct VFile* previousState;
struct VFile* currentState;
#ifndef DISABLE_THREADING
bool onThread;
Thread thread;
Condition cond;
Mutex mutex;
bool ready;
#endif
};
void mCoreRewindContextInit(struct mCoreRewindContext*, size_t entries, bool onThread);
void mCoreRewindContextDeinit(struct mCoreRewindContext*);
struct mCore;
void mCoreRewindAppend(struct mCoreRewindContext*, struct mCore*);
bool mCoreRewindRestore(struct mCoreRewindContext*, struct mCore*);
CXX_GUARD_END
#endif

View file

@ -1,52 +0,0 @@
/* Copyright (c) 2013-2017 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 M_SCRIPTING_H
#define M_SCRIPTING_H
#include <mgba-util/common.h>
CXX_GUARD_START
#ifdef USE_DEBUGGERS
#include <mgba/debugger/debugger.h>
#endif
struct mScriptBridge;
struct VFile;
struct mScriptEngine {
const char* (*name)(struct mScriptEngine*);
bool (*init)(struct mScriptEngine*, struct mScriptBridge*);
void (*deinit)(struct mScriptEngine*);
bool (*isScript)(struct mScriptEngine*, const char* name, struct VFile* vf);
bool (*loadScript)(struct mScriptEngine*, const char* name, struct VFile* vf);
void (*run)(struct mScriptEngine*);
bool (*lookupSymbol)(struct mScriptEngine*, const char* name, int32_t* out);
#ifdef USE_DEBUGGERS
void (*debuggerEntered)(struct mScriptEngine*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
#endif
};
struct mScriptBridge* mScriptBridgeCreate(void);
void mScriptBridgeDestroy(struct mScriptBridge*);
void mScriptBridgeInstallEngine(struct mScriptBridge*, struct mScriptEngine*);
#ifdef USE_DEBUGGERS
void mScriptBridgeSetDebugger(struct mScriptBridge*, struct mDebugger*);
struct mDebugger* mScriptBridgeGetDebugger(struct mScriptBridge*);
void mScriptBridgeDebuggerEntered(struct mScriptBridge*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
#endif
void mScriptBridgeRun(struct mScriptBridge*);
bool mScriptBridgeLoadScript(struct mScriptBridge*, const char* name);
bool mScriptBridgeLookupSymbol(struct mScriptBridge*, const char* name, int32_t* out);
CXX_GUARD_END
#endif

View file

@ -1,56 +0,0 @@
/* Copyright (c) 2013-2016 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 M_SERIALIZE_H
#define M_SERIALIZE_H
#include <mgba-util/common.h>
CXX_GUARD_START
enum mStateExtdataTag {
EXTDATA_NONE = 0,
EXTDATA_SCREENSHOT = 1,
EXTDATA_SAVEDATA = 2,
EXTDATA_CHEATS = 3,
EXTDATA_RTC = 4,
EXTDATA_META_TIME = 0x101,
EXTDATA_MAX
};
#define SAVESTATE_SCREENSHOT 1
#define SAVESTATE_SAVEDATA 2
#define SAVESTATE_CHEATS 4
#define SAVESTATE_RTC 8
#define SAVESTATE_METADATA 16
struct mStateExtdataItem {
int32_t size;
void* data;
void (*clean)(void*);
};
struct mStateExtdata {
struct mStateExtdataItem data[EXTDATA_MAX];
};
void mStateExtdataInit(struct mStateExtdata*);
void mStateExtdataDeinit(struct mStateExtdata*);
void mStateExtdataPut(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*);
bool mStateExtdataGet(struct mStateExtdata*, enum mStateExtdataTag, struct mStateExtdataItem*);
struct VFile;
bool mStateExtdataSerialize(struct mStateExtdata* extdata, struct VFile* vf);
bool mStateExtdataDeserialize(struct mStateExtdata* extdata, struct VFile* vf);
struct mCore;
bool mCoreSaveStateNamed(struct mCore* core, struct VFile* vf, int flags);
bool mCoreLoadStateNamed(struct mCore* core, struct VFile* vf, int flags);
void* mCoreExtractState(struct mCore* core, struct VFile* vf, struct mStateExtdata* extdata);
bool mCoreExtractExtdata(struct mCore* core, struct VFile* vf, struct mStateExtdata* extdata);
CXX_GUARD_END
#endif

View file

@ -1,43 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CORE_SYNC_H
#define M_CORE_SYNC_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/threading.h>
struct mCoreSync {
int videoFramePending;
bool videoFrameWait;
Mutex videoFrameMutex;
Condition videoFrameAvailableCond;
Condition videoFrameRequiredCond;
bool audioWait;
Condition audioRequiredCond;
Mutex audioBufferMutex;
float fpsTarget;
};
void mCoreSyncPostFrame(struct mCoreSync* sync);
void mCoreSyncForceFrame(struct mCoreSync* sync);
bool mCoreSyncWaitFrameStart(struct mCoreSync* sync);
void mCoreSyncWaitFrameEnd(struct mCoreSync* sync);
void mCoreSyncSetVideoSync(struct mCoreSync* sync, bool wait);
struct blip_t;
bool mCoreSyncProduceAudio(struct mCoreSync* sync, const struct blip_t*, size_t samples);
void mCoreSyncLockAudio(struct mCoreSync* sync);
void mCoreSyncUnlockAudio(struct mCoreSync* sync);
void mCoreSyncConsumeAudio(struct mCoreSync* sync);
CXX_GUARD_END
#endif

View file

@ -1,123 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CORE_THREAD_H
#define M_CORE_THREAD_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/log.h>
struct mCoreThread;
struct mCore;
typedef void (*ThreadCallback)(struct mCoreThread* threadContext);
struct mCoreThread;
struct mThreadLogger {
struct mLogger d;
struct mCoreThread* p;
};
struct mCoreThreadInternal;
struct mCoreThread {
// Input
struct mCore* core;
struct mThreadLogger logger;
ThreadCallback startCallback;
ThreadCallback resetCallback;
ThreadCallback cleanCallback;
ThreadCallback frameCallback;
ThreadCallback sleepCallback;
ThreadCallback pauseCallback;
ThreadCallback unpauseCallback;
void* userData;
void (*run)(struct mCoreThread*);
struct mCoreThreadInternal* impl;
};
#ifndef OPAQUE_THREADING
#include <mgba/core/rewind.h>
#include <mgba/core/sync.h>
#include <mgba-util/threading.h>
enum mCoreThreadState {
mTHREAD_INITIALIZED = -1,
mTHREAD_RUNNING = 0,
mTHREAD_REQUEST,
mTHREAD_INTERRUPTED,
mTHREAD_PAUSED,
mTHREAD_MIN_WAITING = mTHREAD_INTERRUPTED,
mTHREAD_MAX_WAITING = mTHREAD_PAUSED,
mTHREAD_INTERRUPTING,
mTHREAD_EXITING,
mTHREAD_SHUTDOWN,
mTHREAD_CRASHED
};
enum mCoreThreadRequest {
mTHREAD_REQ_PAUSE = 1, // User-set pause
mTHREAD_REQ_WAIT = 2, // Core-set pause
mTHREAD_REQ_RESET = 4,
mTHREAD_REQ_RUN_ON = 8,
};
struct mCoreThreadInternal {
Thread thread;
enum mCoreThreadState state;
bool rewinding;
int requested;
Mutex stateMutex;
Condition stateCond;
int interruptDepth;
bool frameWasOn;
struct mCoreSync sync;
struct mCoreRewindContext rewind;
};
#endif
bool mCoreThreadStart(struct mCoreThread* threadContext);
bool mCoreThreadHasStarted(struct mCoreThread* threadContext);
bool mCoreThreadHasExited(struct mCoreThread* threadContext);
bool mCoreThreadHasCrashed(struct mCoreThread* threadContext);
void mCoreThreadMarkCrashed(struct mCoreThread* threadContext);
void mCoreThreadEnd(struct mCoreThread* threadContext);
void mCoreThreadReset(struct mCoreThread* threadContext);
void mCoreThreadJoin(struct mCoreThread* threadContext);
bool mCoreThreadIsActive(struct mCoreThread* threadContext);
void mCoreThreadInterrupt(struct mCoreThread* threadContext);
void mCoreThreadInterruptFromThread(struct mCoreThread* threadContext);
void mCoreThreadContinue(struct mCoreThread* threadContext);
void mCoreThreadRunFunction(struct mCoreThread* threadContext, void (*run)(struct mCoreThread*));
void mCoreThreadPause(struct mCoreThread* threadContext);
void mCoreThreadUnpause(struct mCoreThread* threadContext);
bool mCoreThreadIsPaused(struct mCoreThread* threadContext);
void mCoreThreadTogglePause(struct mCoreThread* threadContext);
void mCoreThreadPauseFromThread(struct mCoreThread* threadContext);
void mCoreThreadWaitFromThread(struct mCoreThread* threadContext);
void mCoreThreadStopWaiting(struct mCoreThread* threadContext);
void mCoreThreadSetRewinding(struct mCoreThread* threadContext, bool);
void mCoreThreadRewindParamsChanged(struct mCoreThread* threadContext);
struct mCoreThread* mCoreThreadGet(void);
struct mLogger* mCoreThreadLogger(void);
CXX_GUARD_END
#endif

View file

@ -1,63 +0,0 @@
/* Copyright (c) 2013-2016 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 M_TILE_CACHE_H
#define M_TILE_CACHE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/interface.h>
DECL_BITFIELD(mTileCacheConfiguration, uint32_t);
DECL_BIT(mTileCacheConfiguration, ShouldStore, 0);
DECL_BITFIELD(mTileCacheSystemInfo, uint32_t);
DECL_BITS(mTileCacheSystemInfo, PaletteBPP, 0, 2);
DECL_BITS(mTileCacheSystemInfo, PaletteCount, 2, 4);
DECL_BITS(mTileCacheSystemInfo, MaxTiles, 16, 13);
struct mTileCacheEntry {
uint32_t paletteVersion;
uint32_t vramVersion;
uint8_t vramClean;
uint8_t paletteId;
uint16_t padding;
};
struct mTileCache {
color_t* cache;
struct mTileCacheEntry* status;
uint32_t* globalPaletteVersion;
uint32_t tileBase;
uint32_t paletteBase;
unsigned entriesPerTile;
unsigned bpp;
uint16_t* vram;
color_t* palette;
color_t temporaryTile[64];
mTileCacheConfiguration config;
mTileCacheSystemInfo sysConfig;
};
void mTileCacheInit(struct mTileCache* cache);
void mTileCacheDeinit(struct mTileCache* cache);
void mTileCacheConfigure(struct mTileCache* cache, mTileCacheConfiguration config);
void mTileCacheConfigureSystem(struct mTileCache* cache, mTileCacheSystemInfo config, uint32_t tileBase, uint32_t paletteBase);
void mTileCacheWriteVRAM(struct mTileCache* cache, uint32_t address);
void mTileCacheWritePalette(struct mTileCache* cache, uint32_t entry, color_t color);
const color_t* mTileCacheGetTile(struct mTileCache* cache, unsigned tileId, unsigned paletteId);
const color_t* mTileCacheGetTileIfDirty(struct mTileCache* cache, struct mTileCacheEntry* entry, unsigned tileId, unsigned paletteId);
const color_t* mTileCacheGetPalette(struct mTileCache* cache, unsigned paletteId);
const uint16_t* mTileCacheGetVRAM(struct mTileCache* cache, unsigned tileId);
CXX_GUARD_END
#endif

View file

@ -1,49 +0,0 @@
/* Copyright (c) 2013-2016 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 M_CORE_TIMING
#define M_CORE_TIMING
#include <mgba-util/common.h>
CXX_GUARD_START
struct mTiming;
struct mTimingEvent {
void* context;
void (*callback)(struct mTiming*, void* context, uint32_t);
const char* name;
uint32_t when;
unsigned priority;
struct mTimingEvent* next;
};
struct mTiming {
struct mTimingEvent* root;
struct mTimingEvent* reroot;
uint64_t globalCycles;
uint32_t masterCycles;
int32_t* relativeCycles;
int32_t* nextEvent;
};
void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextEvent);
void mTimingDeinit(struct mTiming* timing);
void mTimingClear(struct mTiming* timing);
void mTimingSchedule(struct mTiming* timing, struct mTimingEvent*, int32_t when);
void mTimingScheduleAbsolute(struct mTiming* timing, struct mTimingEvent*, int32_t when);
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*);
CXX_GUARD_END
#endif

View file

@ -1,27 +0,0 @@
/* Copyright (c) 2013-2016 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 VERSION_H
#define VERSION_H
#ifdef __cplusplus
extern "C" {
#endif
#include <mgba-util/dllexports.h>
extern MGBA_EXPORT const char* const gitCommit;
extern MGBA_EXPORT const char* const gitCommitShort;
extern MGBA_EXPORT const char* const gitBranch;
extern MGBA_EXPORT const int gitRevision;
extern MGBA_EXPORT const char* const binaryName;
extern MGBA_EXPORT const char* const projectName;
extern MGBA_EXPORT const char* const projectVersion;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,157 +0,0 @@
/* Copyright (c) 2013-2019 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 DEBUGGER_H
#define DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
#include <mgba/core/log.h>
#include <mgba-util/vector.h>
#include <mgba/internal/debugger/stack-trace.h>
mLOG_DECLARE_CATEGORY(DEBUGGER);
extern const uint32_t DEBUGGER_ID;
enum mDebuggerType {
DEBUGGER_NONE = 0,
DEBUGGER_CUSTOM,
DEBUGGER_CLI,
DEBUGGER_GDB,
DEBUGGER_MAX
};
enum mDebuggerState {
DEBUGGER_PAUSED,
DEBUGGER_RUNNING,
DEBUGGER_CALLBACK,
DEBUGGER_SHUTDOWN
};
enum mWatchpointType {
WATCHPOINT_WRITE = 1,
WATCHPOINT_READ = 2,
WATCHPOINT_RW = 3,
WATCHPOINT_CHANGE = 4,
WATCHPOINT_WRITE_CHANGE = 5,
};
enum mBreakpointType {
BREAKPOINT_HARDWARE,
BREAKPOINT_SOFTWARE
};
enum mDebuggerEntryReason {
DEBUGGER_ENTER_MANUAL,
DEBUGGER_ENTER_ATTACHED,
DEBUGGER_ENTER_BREAKPOINT,
DEBUGGER_ENTER_WATCHPOINT,
DEBUGGER_ENTER_ILLEGAL_OP,
DEBUGGER_ENTER_STACK
};
struct mDebuggerEntryInfo {
uint32_t address;
union {
struct {
uint32_t oldValue;
uint32_t newValue;
enum mWatchpointType watchType;
enum mWatchpointType accessType;
} wp;
struct {
uint32_t opcode;
enum mBreakpointType breakType;
} bp;
struct {
enum mStackTraceMode traceType;
} st;
} type;
ssize_t pointId;
};
struct mBreakpoint {
ssize_t id;
uint32_t address;
int segment;
enum mBreakpointType type;
struct ParseTree* condition;
};
struct mWatchpoint {
ssize_t id;
uint32_t address;
int segment;
enum mWatchpointType type;
struct ParseTree* condition;
};
DECLARE_VECTOR(mBreakpointList, struct mBreakpoint);
DECLARE_VECTOR(mWatchpointList, struct mWatchpoint);
struct mDebugger;
struct ParseTree;
struct mDebuggerPlatform {
struct mDebugger* p;
void (*init)(void* cpu, struct mDebuggerPlatform*);
void (*deinit)(struct mDebuggerPlatform*);
void (*entered)(struct mDebuggerPlatform*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
bool (*hasBreakpoints)(struct mDebuggerPlatform*);
void (*checkBreakpoints)(struct mDebuggerPlatform*);
bool (*clearBreakpoint)(struct mDebuggerPlatform*, ssize_t id);
ssize_t (*setBreakpoint)(struct mDebuggerPlatform*, const struct mBreakpoint*);
void (*listBreakpoints)(struct mDebuggerPlatform*, struct mBreakpointList*);
ssize_t (*setWatchpoint)(struct mDebuggerPlatform*, const struct mWatchpoint*);
void (*listWatchpoints)(struct mDebuggerPlatform*, struct mWatchpointList*);
void (*trace)(struct mDebuggerPlatform*, char* out, size_t* length);
bool (*getRegister)(struct mDebuggerPlatform*, const char* name, int32_t* value);
bool (*setRegister)(struct mDebuggerPlatform*, const char* name, int32_t value);
bool (*lookupIdentifier)(struct mDebuggerPlatform*, const char* name, int32_t* value, int* segment);
uint32_t (*getStackTraceMode)(struct mDebuggerPlatform*);
void (*setStackTraceMode)(struct mDebuggerPlatform*, uint32_t mode);
bool (*updateStackTrace)(struct mDebuggerPlatform* d);
};
struct mDebugger {
struct mCPUComponent d;
struct mDebuggerPlatform* platform;
enum mDebuggerState state;
enum mDebuggerType type;
struct mCore* core;
struct mScriptBridge* bridge;
struct mStackTrace stackTrace;
void (*init)(struct mDebugger*);
void (*deinit)(struct mDebugger*);
void (*paused)(struct mDebugger*);
void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
void (*custom)(struct mDebugger*);
};
struct mDebugger* mDebuggerCreate(enum mDebuggerType type, struct mCore*);
void mDebuggerAttach(struct mDebugger*, struct mCore*);
void mDebuggerRun(struct mDebugger*);
void mDebuggerRunFrame(struct mDebugger*);
void mDebuggerEnter(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
bool mDebuggerLookupIdentifier(struct mDebugger* debugger, const char* name, int32_t* value, int* segment);
CXX_GUARD_END
#endif

View file

@ -1,60 +0,0 @@
/* Copyright (c) 2013-2014 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 COMMAND_LINE_H
#define COMMAND_LINE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba-util/table.h>
#include <mgba/debugger/debugger.h>
struct mArguments {
char* fname;
char* patch;
char* cheatsFile;
char* savestate;
char* bios;
int logLevel;
int frameskip;
struct Table configOverrides;
enum mDebuggerType debuggerType;
bool debugAtStart;
bool showHelp;
bool showVersion;
};
struct mCoreConfig;
struct mSubParser {
const char* usage;
bool (*parse)(struct mSubParser* parser, int option, const char* arg);
void (*apply)(struct mSubParser* parser, struct mCoreConfig* config);
const char* extraOptions;
void* opts;
};
struct mGraphicsOpts {
int multiplier;
bool fullscreen;
};
bool parseArguments(struct mArguments* args, int argc, char* const* argv,
struct mSubParser* subparser);
void applyArguments(const struct mArguments* args, struct mSubParser* subparser, struct mCoreConfig* config);
void freeArguments(struct mArguments* args);
void usage(const char* arg0, const char* extraOptions);
void version(const char* arg0);
void initParserForGraphics(struct mSubParser* parser, struct mGraphicsOpts* opts);
CXX_GUARD_END
#endif

View file

@ -1,41 +0,0 @@
/* Copyright (c) 2013-2017 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 VIDEO_THREAD_PROXY_H
#define VIDEO_THREAD_PROXY_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/internal/gba/video.h>
#include "video-logger.h"
#include <mgba-util/threading.h>
#include <mgba-util/ring-fifo.h>
enum mVideoThreadProxyState {
PROXY_THREAD_STOPPED = 0,
PROXY_THREAD_IDLE,
PROXY_THREAD_BUSY
};
struct mVideoThreadProxy {
struct mVideoLogger d;
Thread thread;
Condition fromThreadCond;
Condition toThreadCond;
Mutex mutex;
enum mVideoThreadProxyState threadState;
enum mVideoLoggerEvent event;
struct RingFIFO dirtyQueue;
};
void mVideoThreadProxyCreate(struct mVideoThreadProxy* renderer);
CXX_GUARD_END
#endif

View file

@ -1,139 +0,0 @@
/* Copyright (c) 2013-2017 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 VIDEO_LOGGER_H
#define VIDEO_LOGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/core.h>
#include <mgba-util/circle-buffer.h>
#define mVL_MAX_CHANNELS 32
enum mVideoLoggerDirtyType {
DIRTY_DUMMY = 0,
DIRTY_FLUSH,
DIRTY_SCANLINE,
DIRTY_REGISTER,
DIRTY_OAM,
DIRTY_PALETTE,
DIRTY_VRAM,
DIRTY_FRAME,
DIRTY_RANGE,
DIRTY_BUFFER,
};
enum mVideoLoggerEvent {
LOGGER_EVENT_NONE = 0,
LOGGER_EVENT_INIT,
LOGGER_EVENT_DEINIT,
LOGGER_EVENT_RESET,
LOGGER_EVENT_GET_PIXELS,
};
enum mVideoLoggerInjectionPoint {
LOGGER_INJECTION_IMMEDIATE = 0,
LOGGER_INJECTION_FIRST_SCANLINE,
};
struct mVideoLoggerDirtyInfo {
enum mVideoLoggerDirtyType type;
uint32_t address;
uint32_t value;
uint32_t value2;
};
struct VFile;
struct mVideoLogger {
bool (*writeData)(struct mVideoLogger* logger, const void* data, size_t length);
bool (*readData)(struct mVideoLogger* logger, void* data, size_t length, bool block);
void (*postEvent)(struct mVideoLogger* logger, enum mVideoLoggerEvent event);
void* dataContext;
bool block;
bool waitOnFlush;
void (*init)(struct mVideoLogger*);
void (*deinit)(struct mVideoLogger*);
void (*reset)(struct mVideoLogger*);
void (*lock)(struct mVideoLogger*);
void (*unlock)(struct mVideoLogger*);
void (*wait)(struct mVideoLogger*);
void (*wake)(struct mVideoLogger*, int y);
void* context;
bool (*parsePacket)(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet);
void (*handleEvent)(struct mVideoLogger* logger, enum mVideoLoggerEvent event);
uint16_t* (*vramBlock)(struct mVideoLogger* logger, uint32_t address);
size_t vramSize;
size_t oamSize;
size_t paletteSize;
uint32_t* vramDirtyBitmap;
uint32_t* oamDirtyBitmap;
uint16_t* vram;
uint16_t* oam;
uint16_t* palette;
const void* pixelBuffer;
size_t pixelStride;
};
void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly);
void mVideoLoggerRendererInit(struct mVideoLogger* logger);
void mVideoLoggerRendererDeinit(struct mVideoLogger* logger);
void mVideoLoggerRendererReset(struct mVideoLogger* logger);
void mVideoLoggerRendererWriteVideoRegister(struct mVideoLogger* logger, uint32_t address, uint16_t value);
void mVideoLoggerRendererWriteVRAM(struct mVideoLogger* logger, uint32_t address);
void mVideoLoggerRendererWritePalette(struct mVideoLogger* logger, uint32_t address, uint16_t value);
void mVideoLoggerRendererWriteOAM(struct mVideoLogger* logger, uint32_t address, uint16_t value);
void mVideoLoggerWriteBuffer(struct mVideoLogger* logger, uint32_t bufferId, uint32_t offset, uint32_t length, const void* data);
void mVideoLoggerRendererDrawScanline(struct mVideoLogger* logger, int y);
void mVideoLoggerRendererDrawRange(struct mVideoLogger* logger, int startX, int endX, int y);
void mVideoLoggerRendererFlush(struct mVideoLogger* logger);
void mVideoLoggerRendererFinishFrame(struct mVideoLogger* logger);
bool mVideoLoggerRendererRun(struct mVideoLogger* logger, bool block);
bool mVideoLoggerRendererRunInjected(struct mVideoLogger* logger);
struct mVideoLogContext;
void mVideoLoggerAttachChannel(struct mVideoLogger* logger, struct mVideoLogContext* context, size_t channelId);
struct mCore;
struct mVideoLogContext* mVideoLogContextCreate(struct mCore* core);
void mVideoLogContextSetCompression(struct mVideoLogContext*, bool enable);
void mVideoLogContextSetOutput(struct mVideoLogContext*, struct VFile*);
void mVideoLogContextWriteHeader(struct mVideoLogContext*, struct mCore* core);
bool mVideoLogContextLoad(struct mVideoLogContext*, struct VFile*);
void mVideoLogContextDestroy(struct mCore* core, struct mVideoLogContext*, bool closeVF);
void mVideoLogContextRewind(struct mVideoLogContext*, struct mCore*);
void* mVideoLogContextInitialState(struct mVideoLogContext*, size_t* size);
int mVideoLoggerAddChannel(struct mVideoLogContext*);
void mVideoLoggerInjectionPoint(struct mVideoLogger* logger, enum mVideoLoggerInjectionPoint);
void mVideoLoggerIgnoreAfterInjection(struct mVideoLogger* logger, uint32_t mask);
void mVideoLoggerInjectVideoRegister(struct mVideoLogger* logger, uint32_t address, uint16_t value);
void mVideoLoggerInjectPalette(struct mVideoLogger* logger, uint32_t address, uint16_t value);
void mVideoLoggerInjectOAM(struct mVideoLogger* logger, uint32_t address, uint16_t value);
enum mPlatform mVideoLogIsCompatible(struct VFile*);
struct mCore* mVideoLogCoreFind(struct VFile*);
CXX_GUARD_END
#endif

View file

@ -1,21 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_CORE_H
#define GB_CORE_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct mCore;
struct mCore* GBCoreCreate(void);
#ifndef MINIMAL_CORE
struct mCore* GBVideoLogPlayerCreate(void);
#endif
CXX_GUARD_END
#endif

View file

@ -1,74 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_INTERFACE_H
#define GB_INTERFACE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/interface.h>
enum GBModel {
GB_MODEL_AUTODETECT = 0xFF,
GB_MODEL_DMG = 0x00,
GB_MODEL_SGB = 0x20,
GB_MODEL_MGB = 0x40,
GB_MODEL_SGB2 = 0x60,
GB_MODEL_CGB = 0x80,
GB_MODEL_AGB = 0xC0
};
enum GBMemoryBankControllerType {
GB_MBC_AUTODETECT = -1,
GB_MBC_NONE = 0,
GB_MBC1 = 1,
GB_MBC2 = 2,
GB_MBC3 = 3,
GB_MBC5 = 5,
GB_MBC6 = 6,
GB_MBC7 = 7,
GB_MMM01 = 0x10,
GB_HuC1 = 0x11,
GB_HuC3 = 0x12,
GB_POCKETCAM = 0x13,
GB_TAMA5 = 0x14,
GB_MBC3_RTC = 0x103,
GB_MBC5_RUMBLE = 0x105,
GB_UNL_WISDOM_TREE = 0x200,
GB_UNL_PKJD = 0x203,
GB_UNL_BBD = 0x220, // Also used as a mask for MBCs that need special read behavior
GB_UNL_HITEK = 0x221,
};
enum GBVideoLayer {
GB_LAYER_BACKGROUND = 0,
GB_LAYER_WINDOW,
GB_LAYER_OBJ
};
struct GBSIODriver {
struct GBSIO* p;
bool (*init)(struct GBSIODriver* driver);
void (*deinit)(struct GBSIODriver* driver);
void (*writeSB)(struct GBSIODriver* driver, uint8_t value);
uint8_t (*writeSC)(struct GBSIODriver* driver, uint8_t value);
};
struct VFile;
bool GBIsROM(struct VFile* vf);
bool GBIsBIOS(struct VFile* vf);
enum GBModel GBNameToModel(const char*);
const char* GBModelToName(enum GBModel);
int GBValidModels(const uint8_t* bank0);
CXX_GUARD_END
#endif

View file

@ -1,21 +0,0 @@
/* Copyright (c) 2013-2016 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 GBA_CORE_H
#define GBA_CORE_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct mCore;
struct mCore* GBACoreCreate(void);
#ifndef MINIMAL_CORE
struct mCore* GBAVideoLogPlayerCreate(void);
#endif
CXX_GUARD_END
#endif

View file

@ -1,105 +0,0 @@
/* Copyright (c) 2013-2015 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 GBA_INTERFACE_H
#define GBA_INTERFACE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/interface.h>
#include <mgba/core/timing.h>
enum {
GBA_VIDEO_HORIZONTAL_PIXELS = 240,
GBA_VIDEO_VERTICAL_PIXELS = 160,
};
enum GBASIOMode {
SIO_NORMAL_8 = 0,
SIO_NORMAL_32 = 1,
SIO_MULTI = 2,
SIO_UART = 3,
SIO_GPIO = 8,
SIO_JOYBUS = 12
};
enum GBASIOJOYCommand {
JOY_RESET = 0xFF,
JOY_POLL = 0x00,
JOY_TRANS = 0x14,
JOY_RECV = 0x15
};
enum GBAVideoLayer {
GBA_LAYER_BG0 = 0,
GBA_LAYER_BG1,
GBA_LAYER_BG2,
GBA_LAYER_BG3,
GBA_LAYER_OBJ,
GBA_LAYER_WIN0,
GBA_LAYER_WIN1,
GBA_LAYER_OBJWIN,
};
struct GBA;
struct GBAAudio;
struct GBASIO;
struct GBAVideoRenderer;
struct VFile;
extern MGBA_EXPORT const int GBA_LUX_LEVELS[10];
enum {
mPERIPH_GBA_LUMINANCE = 0x1000,
mPERIPH_GBA_BATTLECHIP_GATE,
};
bool GBAIsROM(struct VFile* vf);
bool GBAIsMB(struct VFile* vf);
bool GBAIsBIOS(struct VFile* vf);
struct GBALuminanceSource {
void (*sample)(struct GBALuminanceSource*);
uint8_t (*readLuminance)(struct GBALuminanceSource*);
};
struct GBASIODriver {
struct GBASIO* p;
bool (*init)(struct GBASIODriver* driver);
void (*deinit)(struct GBASIODriver* driver);
bool (*load)(struct GBASIODriver* driver);
bool (*unload)(struct GBASIODriver* driver);
uint16_t (*writeRegister)(struct GBASIODriver* driver, uint32_t address, uint16_t value);
};
void GBASIOJOYCreate(struct GBASIODriver* sio);
enum GBASIOBattleChipGateFlavor {
GBA_FLAVOR_BATTLECHIP_GATE = 4,
GBA_FLAVOR_PROGRESS_GATE = 5,
GBA_FLAVOR_BEAST_LINK_GATE = 6,
GBA_FLAVOR_BEAST_LINK_GATE_US = 7,
};
struct GBASIOBattlechipGate {
struct GBASIODriver d;
struct mTimingEvent event;
uint16_t chipId;
uint16_t data[2];
int state;
int flavor;
};
void GBASIOBattlechipGateCreate(struct GBASIOBattlechipGate*);
void GBAEReaderQueueCard(struct GBA* gba, const void* data, size_t size);
CXX_GUARD_END
#endif

View file

@ -1,208 +0,0 @@
/* Copyright (c) 2013-2014 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 ARM_H
#define ARM_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
enum {
ARM_SP = 13,
ARM_LR = 14,
ARM_PC = 15
};
enum ExecutionMode {
MODE_ARM = 0,
MODE_THUMB = 1
};
enum PrivilegeMode {
MODE_USER = 0x10,
MODE_FIQ = 0x11,
MODE_IRQ = 0x12,
MODE_SUPERVISOR = 0x13,
MODE_ABORT = 0x17,
MODE_UNDEFINED = 0x1B,
MODE_SYSTEM = 0x1F
};
enum WordSize {
WORD_SIZE_ARM = 4,
WORD_SIZE_THUMB = 2
};
enum ExecutionVector {
BASE_RESET = 0x00000000,
BASE_UNDEF = 0x00000004,
BASE_SWI = 0x00000008,
BASE_PABT = 0x0000000C,
BASE_DABT = 0x00000010,
BASE_IRQ = 0x00000018,
BASE_FIQ = 0x0000001C
};
enum RegisterBank {
BANK_NONE = 0,
BANK_FIQ = 1,
BANK_IRQ = 2,
BANK_SUPERVISOR = 3,
BANK_ABORT = 4,
BANK_UNDEFINED = 5
};
enum LSMDirection {
LSM_B = 1,
LSM_D = 2,
LSM_IA = 0,
LSM_IB = 1,
LSM_DA = 2,
LSM_DB = 3
};
struct ARMCore;
union PSR {
struct {
#ifdef __BIG_ENDIAN__
unsigned n : 1;
unsigned z : 1;
unsigned c : 1;
unsigned v : 1;
unsigned unused : 20;
unsigned i : 1;
unsigned f : 1;
unsigned t : 1;
unsigned priv : 5;
#else
unsigned priv : 5;
unsigned t : 1;
unsigned f : 1;
unsigned i : 1;
unsigned unused : 20;
unsigned v : 1;
unsigned c : 1;
unsigned z : 1;
unsigned n : 1;
#endif
};
struct {
#ifdef __BIG_ENDIAN__
uint8_t flags;
uint8_t status;
uint8_t extension;
uint8_t control;
#else
uint8_t control;
uint8_t extension;
uint8_t status;
uint8_t flags;
#endif
};
int32_t packed;
};
struct ARMMemory {
uint32_t (*load32)(struct ARMCore*, uint32_t address, int* cycleCounter);
uint32_t (*load16)(struct ARMCore*, uint32_t address, int* cycleCounter);
uint32_t (*load8)(struct ARMCore*, uint32_t address, int* cycleCounter);
void (*store32)(struct ARMCore*, uint32_t address, int32_t value, int* cycleCounter);
void (*store16)(struct ARMCore*, uint32_t address, int16_t value, int* cycleCounter);
void (*store8)(struct ARMCore*, uint32_t address, int8_t value, int* cycleCounter);
uint32_t (*loadMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
int* cycleCounter);
uint32_t (*storeMultiple)(struct ARMCore*, uint32_t baseAddress, int mask, enum LSMDirection direction,
int* cycleCounter);
const uint32_t* activeRegion;
uint32_t activeMask;
uint32_t activeSeqCycles32;
uint32_t activeSeqCycles16;
uint32_t activeNonseqCycles32;
uint32_t activeNonseqCycles16;
int32_t (*stall)(struct ARMCore*, int32_t wait);
void (*setActiveRegion)(struct ARMCore*, uint32_t address);
};
struct ARMInterruptHandler {
void (*reset)(struct ARMCore* cpu);
void (*processEvents)(struct ARMCore* cpu);
void (*swi16)(struct ARMCore* cpu, int immediate);
void (*swi32)(struct ARMCore* cpu, int immediate);
void (*hitIllegal)(struct ARMCore* cpu, uint32_t opcode);
void (*bkpt16)(struct ARMCore* cpu, int immediate);
void (*bkpt32)(struct ARMCore* cpu, int immediate);
void (*readCPSR)(struct ARMCore* cpu);
void (*hitStub)(struct ARMCore* cpu, uint32_t opcode);
};
#define ARM_REGISTER_FILE struct { \
int32_t gprs[16]; \
union PSR cpsr; \
union PSR spsr; \
}
struct ARMRegisterFile {
ARM_REGISTER_FILE;
};
struct ARMCore {
union {
struct ARMRegisterFile regs;
ARM_REGISTER_FILE;
};
int32_t cycles;
int32_t nextEvent;
int halted;
int32_t bankedRegisters[6][7];
int32_t bankedSPSRs[6];
int32_t shifterOperand;
int32_t shifterCarryOut;
uint32_t prefetch[2];
enum ExecutionMode executionMode;
enum PrivilegeMode privilegeMode;
struct ARMMemory memory;
struct ARMInterruptHandler irqh;
struct mCPUComponent* master;
size_t numComponents;
struct mCPUComponent** components;
};
#undef ARM_REGISTER_FILE
void ARMInit(struct ARMCore* cpu);
void ARMDeinit(struct ARMCore* cpu);
void ARMSetComponents(struct ARMCore* cpu, struct mCPUComponent* master, int extra, struct mCPUComponent** extras);
void ARMHotplugAttach(struct ARMCore* cpu, size_t slot);
void ARMHotplugDetach(struct ARMCore* cpu, size_t slot);
void ARMReset(struct ARMCore* cpu);
void ARMSetPrivilegeMode(struct ARMCore*, enum PrivilegeMode);
void ARMRaiseIRQ(struct ARMCore*);
void ARMRaiseSWI(struct ARMCore*);
void ARMRaiseUndefined(struct ARMCore*);
void ARMRun(struct ARMCore* cpu);
void ARMRunLoop(struct ARMCore* cpu);
void ARMRunFake(struct ARMCore* cpu, uint32_t opcode);
CXX_GUARD_END
#endif

View file

@ -1,18 +0,0 @@
/* Copyright (c) 2013-2016 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 ARM_CLI_DEBUGGER_H
#define ARM_CLI_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct CLIDebuggerSystem;
void ARMCLIDebuggerCreate(struct CLIDebuggerSystem* debugger);
CXX_GUARD_END
#endif

View file

@ -1,52 +0,0 @@
/* Copyright (c) 2013-2014 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 ARM_DEBUGGER_H
#define ARM_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/debugger/debugger.h>
#include <mgba/internal/arm/arm.h>
#include <mgba-util/vector.h>
struct ParseTree;
struct ARMDebugBreakpoint {
struct mBreakpoint d;
struct {
uint32_t opcode;
enum ExecutionMode mode;
} sw;
};
DECLARE_VECTOR(ARMDebugBreakpointList, struct ARMDebugBreakpoint);
struct ARMDebugger {
struct mDebuggerPlatform d;
struct ARMCore* cpu;
struct ARMDebugBreakpointList breakpoints;
struct ARMDebugBreakpointList swBreakpoints;
struct mWatchpointList watchpoints;
struct ARMMemory originalMemory;
ssize_t nextId;
uint32_t stackTraceMode;
void (*entered)(struct mDebugger*, enum mDebuggerEntryReason, struct mDebuggerEntryInfo*);
bool (*setSoftwareBreakpoint)(struct ARMDebugger*, uint32_t address, enum ExecutionMode mode, uint32_t* opcode);
void (*clearSoftwareBreakpoint)(struct ARMDebugger*, const struct ARMDebugBreakpoint*);
};
struct mDebuggerPlatform* ARMDebuggerPlatformCreate(void);
ssize_t ARMDebuggerSetSoftwareBreakpoint(struct mDebuggerPlatform* debugger, uint32_t address, enum ExecutionMode mode);
CXX_GUARD_END
#endif

View file

@ -1,20 +0,0 @@
/* Copyright (c) 2013-2014 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 MEMORY_DEBUGGER_H
#define MEMORY_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct ARMDebugger;
void ARMDebuggerInstallMemoryShim(struct ARMDebugger* debugger);
void ARMDebuggerRemoveMemoryShim(struct ARMDebugger* debugger);
CXX_GUARD_END
#endif

View file

@ -1,37 +0,0 @@
/* Copyright (c) 2013-2014 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 ARM_DECODER_INLINES_H
#define ARM_DECODER_INLINES_H
#include "decoder.h"
#include "arm.h"
#include <stdio.h>
#include <string.h>
#define LOAD_CYCLES \
info->iCycles = 1; \
info->nDataCycles = 1;
#define STORE_CYCLES \
info->sInstructionCycles = 0; \
info->nInstructionCycles = 1; \
info->nDataCycles = 1;
static inline bool ARMInstructionIsBranch(enum ARMMnemonic mnemonic) {
switch (mnemonic) {
case ARM_MN_B:
case ARM_MN_BL:
case ARM_MN_BX:
// TODO: case: ARM_MN_BLX:
return true;
default:
return false;
}
}
#endif

View file

@ -1,231 +0,0 @@
/* Copyright (c) 2013-2014 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 ARM_DECODER_H
#define ARM_DECODER_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/internal/arm/arm.h>
// Bit 0: a register is involved with this operand
// Bit 1: an immediate is invovled with this operand
// Bit 2: a memory access is involved with this operand
// Bit 3: the destination of this operand is affected by this opcode
// Bit 4: this operand is shifted by a register
// Bit 5: this operand is shifted by an immediate
#define ARM_OPERAND_NONE 0x00000000
#define ARM_OPERAND_REGISTER_1 0x00000001
#define ARM_OPERAND_IMMEDIATE_1 0x00000002
#define ARM_OPERAND_MEMORY_1 0x00000004
#define ARM_OPERAND_AFFECTED_1 0x00000008
#define ARM_OPERAND_SHIFT_REGISTER_1 0x00000010
#define ARM_OPERAND_SHIFT_IMMEDIATE_1 0x00000020
#define ARM_OPERAND_1 0x000000FF
#define ARM_OPERAND_REGISTER_2 0x00000100
#define ARM_OPERAND_IMMEDIATE_2 0x00000200
#define ARM_OPERAND_MEMORY_2 0x00000400
#define ARM_OPERAND_AFFECTED_2 0x00000800
#define ARM_OPERAND_SHIFT_REGISTER_2 0x00001000
#define ARM_OPERAND_SHIFT_IMMEDIATE_2 0x00002000
#define ARM_OPERAND_2 0x0000FF00
#define ARM_OPERAND_REGISTER_3 0x00010000
#define ARM_OPERAND_IMMEDIATE_3 0x00020000
#define ARM_OPERAND_MEMORY_3 0x00040000
#define ARM_OPERAND_AFFECTED_3 0x00080000
#define ARM_OPERAND_SHIFT_REGISTER_3 0x00100000
#define ARM_OPERAND_SHIFT_IMMEDIATE_3 0x00200000
#define ARM_OPERAND_3 0x00FF0000
#define ARM_OPERAND_REGISTER_4 0x01000000
#define ARM_OPERAND_IMMEDIATE_4 0x02000000
#define ARM_OPERAND_MEMORY_4 0x04000000
#define ARM_OPERAND_AFFECTED_4 0x08000000
#define ARM_OPERAND_SHIFT_REGISTER_4 0x10000000
#define ARM_OPERAND_SHIFT_IMMEDIATE_4 0x20000000
#define ARM_OPERAND_4 0xFF000000
#define ARM_OPERAND_MEMORY (ARM_OPERAND_MEMORY_1 | ARM_OPERAND_MEMORY_2 | ARM_OPERAND_MEMORY_3 | ARM_OPERAND_MEMORY_4)
#define ARM_MEMORY_REGISTER_BASE 0x0001
#define ARM_MEMORY_IMMEDIATE_OFFSET 0x0002
#define ARM_MEMORY_REGISTER_OFFSET 0x0004
#define ARM_MEMORY_SHIFTED_OFFSET 0x0008
#define ARM_MEMORY_PRE_INCREMENT 0x0010
#define ARM_MEMORY_POST_INCREMENT 0x0020
#define ARM_MEMORY_OFFSET_SUBTRACT 0x0040
#define ARM_MEMORY_WRITEBACK 0x0080
#define ARM_MEMORY_DECREMENT_AFTER 0x0000
#define ARM_MEMORY_INCREMENT_AFTER 0x0100
#define ARM_MEMORY_DECREMENT_BEFORE 0x0200
#define ARM_MEMORY_INCREMENT_BEFORE 0x0300
#define ARM_MEMORY_SPSR_SWAP 0x0400
#define ARM_MEMORY_STORE 0x1000
#define ARM_MEMORY_LOAD 0x2000
#define ARM_MEMORY_SWAP 0x3000
#define ARM_PSR_C 1
#define ARM_PSR_X 2
#define ARM_PSR_S 4
#define ARM_PSR_F 8
#define ARM_PSR_MASK 0xF
#define MEMORY_FORMAT_TO_DIRECTION(F) (((F) >> 8) & 0x3)
enum ARMCondition {
ARM_CONDITION_EQ = 0x0,
ARM_CONDITION_NE = 0x1,
ARM_CONDITION_CS = 0x2,
ARM_CONDITION_CC = 0x3,
ARM_CONDITION_MI = 0x4,
ARM_CONDITION_PL = 0x5,
ARM_CONDITION_VS = 0x6,
ARM_CONDITION_VC = 0x7,
ARM_CONDITION_HI = 0x8,
ARM_CONDITION_LS = 0x9,
ARM_CONDITION_GE = 0xA,
ARM_CONDITION_LT = 0xB,
ARM_CONDITION_GT = 0xC,
ARM_CONDITION_LE = 0xD,
ARM_CONDITION_AL = 0xE,
ARM_CONDITION_NV = 0xF
};
enum ARMShifterOperation {
ARM_SHIFT_NONE = 0,
ARM_SHIFT_LSL,
ARM_SHIFT_LSR,
ARM_SHIFT_ASR,
ARM_SHIFT_ROR,
ARM_SHIFT_RRX
};
union ARMOperand {
struct {
uint8_t reg;
uint8_t shifterOp;
union {
uint8_t shifterReg;
uint8_t shifterImm;
uint8_t psrBits;
};
};
int32_t immediate;
};
enum ARMMemoryAccessType {
ARM_ACCESS_WORD = 4,
ARM_ACCESS_HALFWORD = 2,
ARM_ACCESS_SIGNED_HALFWORD = 10,
ARM_ACCESS_BYTE = 1,
ARM_ACCESS_SIGNED_BYTE = 9,
ARM_ACCESS_TRANSLATED_WORD = 20,
ARM_ACCESS_TRANSLATED_BYTE = 17
};
enum ARMBranchType {
ARM_BRANCH_NONE = 0,
ARM_BRANCH = 1,
ARM_BRANCH_INDIRECT = 2,
ARM_BRANCH_LINKED = 4
};
struct ARMMemoryAccess {
uint8_t baseReg;
uint8_t width;
uint16_t format;
union ARMOperand offset;
};
enum ARMMnemonic {
ARM_MN_ILL = 0,
ARM_MN_ADC,
ARM_MN_ADD,
ARM_MN_AND,
ARM_MN_ASR,
ARM_MN_B,
ARM_MN_BIC,
ARM_MN_BKPT,
ARM_MN_BL,
ARM_MN_BX,
ARM_MN_CMN,
ARM_MN_CMP,
ARM_MN_EOR,
ARM_MN_LDM,
ARM_MN_LDR,
ARM_MN_LSL,
ARM_MN_LSR,
ARM_MN_MLA,
ARM_MN_MOV,
ARM_MN_MRS,
ARM_MN_MSR,
ARM_MN_MUL,
ARM_MN_MVN,
ARM_MN_NEG,
ARM_MN_ORR,
ARM_MN_ROR,
ARM_MN_RSB,
ARM_MN_RSC,
ARM_MN_SBC,
ARM_MN_SMLAL,
ARM_MN_SMULL,
ARM_MN_STM,
ARM_MN_STR,
ARM_MN_SUB,
ARM_MN_SWI,
ARM_MN_SWP,
ARM_MN_TEQ,
ARM_MN_TST,
ARM_MN_UMLAL,
ARM_MN_UMULL,
ARM_MN_MAX
};
enum {
ARM_CPSR = 16,
ARM_SPSR = 17
};
struct ARMInstructionInfo {
uint32_t opcode;
union ARMOperand op1;
union ARMOperand op2;
union ARMOperand op3;
union ARMOperand op4;
struct ARMMemoryAccess memory;
int operandFormat;
unsigned execMode : 1;
bool traps : 1;
bool affectsCPSR : 1;
unsigned branchType : 3;
unsigned condition : 4;
unsigned mnemonic : 6;
unsigned iCycles : 3;
unsigned cCycles : 4;
unsigned sInstructionCycles : 4;
unsigned nInstructionCycles : 4;
unsigned sDataCycles : 10;
unsigned nDataCycles : 10;
};
void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info);
void ARMDecodeThumb(uint16_t opcode, struct ARMInstructionInfo* info);
bool ARMDecodeThumbCombine(struct ARMInstructionInfo* info1, struct ARMInstructionInfo* info2,
struct ARMInstructionInfo* out);
uint32_t ARMResolveMemoryAccess(struct ARMInstructionInfo* info, struct ARMRegisterFile* regs, uint32_t pc);
#ifdef USE_DEBUGGERS
struct mDebuggerSymbols;
int ARMDisassemble(struct ARMInstructionInfo* info, struct ARMCore* core, const struct mDebuggerSymbols* symbols, uint32_t pc, char* buffer, int blen);
#endif
CXX_GUARD_END
#endif

View file

@ -1,335 +0,0 @@
/* Copyright (c) 2013-2014 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 EMITTER_ARM_H
#define EMITTER_ARM_H
#include "emitter-inlines.h"
#define DECLARE_INSTRUCTION_ARM(EMITTER, NAME) \
EMITTER ## NAME
#define DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ALU) \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I)), \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## I))
#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4) \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, EX2), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
DECLARE_INSTRUCTION_ARM(EMITTER, EX3), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
DECLARE_INSTRUCTION_ARM(EMITTER, EX4)
#define DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, NAME, P, U, W) \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W)), \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## I ## P ## U ## W))
#define DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, NAME, P, U, W) \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSL_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _LSR_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ASR_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## _ROR_ ## P ## U ## W), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL)
#define DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, NAME, MODE, W) \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W)), \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME ## MODE ## W))
#define DECLARE_ARM_BRANCH_BLOCK(EMITTER, NAME) \
DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
// TODO: Support coprocessors
#define DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, NAME, P, U, N, W) \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)), \
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2) \
DO_8(DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))))
#define DECLARE_ARM_SWI_BLOCK(EMITTER) \
DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI))
#define DECLARE_ARM_EMITTER_BLOCK(EMITTER) \
DECLARE_ARM_ALU_BLOCK(EMITTER, AND, MUL, STRH, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ANDS, MULS, LDRH, LDRSB, LDRSH), \
DECLARE_ARM_ALU_BLOCK(EMITTER, EOR, MLA, STRH, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, EORS, MLAS, LDRH, LDRSB, LDRSH), \
DECLARE_ARM_ALU_BLOCK(EMITTER, SUB, ILL, STRHI, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, SUBS, ILL, LDRHI, LDRSBI, LDRSHI), \
DECLARE_ARM_ALU_BLOCK(EMITTER, RSB, ILL, STRHI, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, RSBS, ILL, LDRHI, LDRSBI, LDRSHI), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ADD, UMULL, STRHU, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ADDS, UMULLS, LDRHU, LDRSBU, LDRSHU), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ADC, UMLAL, STRHU, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ADCS, UMLALS, LDRHU, LDRSBU, LDRSHU), \
DECLARE_ARM_ALU_BLOCK(EMITTER, SBC, SMULL, STRHIU, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, SBCS, SMULLS, LDRHIU, LDRSBIU, LDRSHIU), \
DECLARE_ARM_ALU_BLOCK(EMITTER, RSC, SMLAL, STRHIU, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, RSCS, SMLALS, LDRHIU, LDRSBIU, LDRSHIU), \
DECLARE_INSTRUCTION_ARM(EMITTER, MRS), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, SWP), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, STRHP), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, TST, ILL, LDRHP, LDRSBP, LDRSHP), \
DECLARE_INSTRUCTION_ARM(EMITTER, MSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, BX), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, BKPT), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, STRHPW), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, TEQ, ILL, LDRHPW, LDRSBPW, LDRSHPW), \
DECLARE_INSTRUCTION_ARM(EMITTER, MRSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, SWPB), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, STRHIP), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, CMP, ILL, LDRHIP, LDRSBIP, LDRSHIP), \
DECLARE_INSTRUCTION_ARM(EMITTER, MSRR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, STRHIPW), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, CMN, ILL, LDRHIPW, LDRSBIPW, LDRSHIPW), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ORR, SMLAL, STRHPU, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, ORRS, SMLALS, LDRHPU, LDRSBPU, LDRSHPU), \
DECLARE_ARM_ALU_BLOCK(EMITTER, MOV, SMLAL, STRHPUW, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, MOVS, SMLALS, LDRHPUW, LDRSBPUW, LDRSHPUW), \
DECLARE_ARM_ALU_BLOCK(EMITTER, BIC, SMLAL, STRHIPU, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, BICS, SMLALS, LDRHIPU, LDRSBIPU, LDRSHIPU), \
DECLARE_ARM_ALU_BLOCK(EMITTER, MVN, SMLAL, STRHIPUW, ILL, ILL), \
DECLARE_ARM_ALU_BLOCK(EMITTER, MVNS, SMLALS, LDRHIPUW, LDRSBIPUW, LDRSHIPUW), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, AND), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ANDS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EOR), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, EORS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUB), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SUBS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSB), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSBS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADD), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADDS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADC), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ADCS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBC), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, SBCS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSC), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, RSCS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TST), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSR), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, TEQ), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMP), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MSRR), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, CMN), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORR), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, ORRS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOV), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MOVS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BIC), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, BICS), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVN), \
DECLARE_ARM_ALU_IMMEDIATE_BLOCK(EMITTER, MVNS), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRT, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRT, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRBT, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRBT, , U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, , W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STR, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDR, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, ), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, STRB, P, U, W), \
DECLARE_ARM_LOAD_STORE_IMMEDIATE_BLOCK(EMITTER, LDRB, P, U, W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRT, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRT, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRBT, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRBT, , U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, , W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, , W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, , W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, , W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STR, P, U, W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDR, P, U, W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, ), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, STRB, P, U, W), \
DECLARE_ARM_LOAD_STORE_BLOCK(EMITTER, LDRB, P, U, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IA, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, DB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, DB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, DB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, DB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STM, IB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDM, IB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, ), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, STMS, IB, W), \
DECLARE_ARM_LOAD_STORE_MULTIPLE_BLOCK(EMITTER, LDMS, IB, W), \
DECLARE_ARM_BRANCH_BLOCK(EMITTER, B), \
DECLARE_ARM_BRANCH_BLOCK(EMITTER, BL), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , , W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , , W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , , N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , , N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, , W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, , W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, , U, N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, , U, N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , , W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , , W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, , N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, , N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, ), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC), \
DECLARE_ARM_SWI_BLOCK(EMITTER)
#endif

View file

@ -1,32 +0,0 @@
/* Copyright (c) 2013-2014 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 EMITTER_INLINES_H
#define EMITTER_INLINES_H
#define DO_4(DIRECTIVE) \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE
#define DO_8(DIRECTIVE) \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE, \
DIRECTIVE
#define DO_256(DIRECTIVE) \
DO_4(DO_8(DO_8(DIRECTIVE)))
#define DO_INTERLACE(LEFT, RIGHT) \
LEFT, \
RIGHT
#endif

View file

@ -1,113 +0,0 @@
/* Copyright (c) 2013-2014 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 EMITTER_THUMB_H
#define EMITTER_THUMB_H
#include "emitter-inlines.h"
#define DECLARE_INSTRUCTION_THUMB(EMITTER, NAME) \
EMITTER ## NAME
#define DECLARE_INSTRUCTION_WITH_HIGH_THUMB(EMITTER, NAME) \
DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 00), \
DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 01), \
DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 10), \
DECLARE_INSTRUCTION_THUMB(EMITTER, NAME ## 11)
#define DECLARE_THUMB_EMITTER_BLOCK(EMITTER) \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LSL1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LSR1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ASR1))), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ADD3)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, SUB3)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ADD1)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, SUB1)), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, MOV1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, CMP1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ADD2))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, SUB2))), \
DECLARE_INSTRUCTION_THUMB(EMITTER, AND), \
DECLARE_INSTRUCTION_THUMB(EMITTER, EOR), \
DECLARE_INSTRUCTION_THUMB(EMITTER, LSL2), \
DECLARE_INSTRUCTION_THUMB(EMITTER, LSR2), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ASR2), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ADC), \
DECLARE_INSTRUCTION_THUMB(EMITTER, SBC), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ROR), \
DECLARE_INSTRUCTION_THUMB(EMITTER, TST), \
DECLARE_INSTRUCTION_THUMB(EMITTER, NEG), \
DECLARE_INSTRUCTION_THUMB(EMITTER, CMP2), \
DECLARE_INSTRUCTION_THUMB(EMITTER, CMN), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ORR), \
DECLARE_INSTRUCTION_THUMB(EMITTER, MUL), \
DECLARE_INSTRUCTION_THUMB(EMITTER, BIC), \
DECLARE_INSTRUCTION_THUMB(EMITTER, MVN), \
DECLARE_INSTRUCTION_WITH_HIGH_THUMB(EMITTER, ADD4), \
DECLARE_INSTRUCTION_WITH_HIGH_THUMB(EMITTER, CMP3), \
DECLARE_INSTRUCTION_WITH_HIGH_THUMB(EMITTER, MOV3), \
DECLARE_INSTRUCTION_THUMB(EMITTER, BX), \
DECLARE_INSTRUCTION_THUMB(EMITTER, BX), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ILL), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDR3))), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, STR2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, STRH2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, STRB2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, LDRSB)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, LDR2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, LDRH2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, LDRB2)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, LDRSH)), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, STR1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDR1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, STRB1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDRB1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, STRH1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDRH1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, STR3))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDR4))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ADD5))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ADD6))), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ADD7), \
DECLARE_INSTRUCTION_THUMB(EMITTER, ADD7), \
DECLARE_INSTRUCTION_THUMB(EMITTER, SUB4), \
DECLARE_INSTRUCTION_THUMB(EMITTER, SUB4), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, PUSH)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, PUSHR)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_8(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, POP)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, POPR)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BKPT)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, STMIA))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, LDMIA))), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BEQ)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BNE)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BCS)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BCC)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BMI)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BPL)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BVS)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BVC)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BHI)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BLS)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BGE)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BLT)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BGT)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BLE)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL)), \
DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, SWI)), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, B))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL1))), \
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL2))) \
#endif

View file

@ -1,22 +0,0 @@
/* Copyright (c) 2013-2014 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 ISA_ARM_H
#define ISA_ARM_H
#include <mgba-util/common.h>
CXX_GUARD_START
#define ARM_PREFETCH_CYCLES (1 + cpu->memory.activeSeqCycles32)
struct ARMCore;
typedef void (*ARMInstruction)(struct ARMCore*, uint32_t opcode);
extern const ARMInstruction _armTable[0x1000];
CXX_GUARD_END
#endif

View file

@ -1,171 +0,0 @@
/* Copyright (c) 2013-2014 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 ISA_INLINES_H
#define ISA_INLINES_H
#include "macros.h"
#include "arm.h"
#define ARM_COND_EQ (cpu->cpsr.z)
#define ARM_COND_NE (!cpu->cpsr.z)
#define ARM_COND_CS (cpu->cpsr.c)
#define ARM_COND_CC (!cpu->cpsr.c)
#define ARM_COND_MI (cpu->cpsr.n)
#define ARM_COND_PL (!cpu->cpsr.n)
#define ARM_COND_VS (cpu->cpsr.v)
#define ARM_COND_VC (!cpu->cpsr.v)
#define ARM_COND_HI (cpu->cpsr.c && !cpu->cpsr.z)
#define ARM_COND_LS (!cpu->cpsr.c || cpu->cpsr.z)
#define ARM_COND_GE (!cpu->cpsr.n == !cpu->cpsr.v)
#define ARM_COND_LT (!cpu->cpsr.n != !cpu->cpsr.v)
#define ARM_COND_GT (!cpu->cpsr.z && !cpu->cpsr.n == !cpu->cpsr.v)
#define ARM_COND_LE (cpu->cpsr.z || !cpu->cpsr.n != !cpu->cpsr.v)
#define ARM_COND_AL 1
#define ARM_SIGN(I) ((I) >> 31)
#define ARM_SXT_8(I) (((int8_t) (I) << 24) >> 24)
#define ARM_SXT_16(I) (((int16_t) (I) << 16) >> 16)
#define ARM_UXT_64(I) (uint64_t)(uint32_t) (I)
#define ARM_CARRY_FROM(M, N, D) (((uint32_t) (M) >> 31) + ((uint32_t) (N) >> 31) > ((uint32_t) (D) >> 31))
#define ARM_BORROW_FROM(M, N, D) (((uint32_t) (M)) >= ((uint32_t) (N)))
#define ARM_BORROW_FROM_CARRY(M, N, D, C) (ARM_UXT_64(M) >= (ARM_UXT_64(N)) + (uint64_t) (C))
#define ARM_V_ADDITION(M, N, D) (!(ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
#define ARM_V_SUBTRACTION(M, N, D) ((ARM_SIGN((M) ^ (N))) && (ARM_SIGN((M) ^ (D))))
#define ARM_WAIT_MUL(R, WAIT) \
{ \
int32_t wait = WAIT; \
if ((R & 0xFFFFFF00) == 0xFFFFFF00 || !(R & 0xFFFFFF00)) { \
wait += 1; \
} else if ((R & 0xFFFF0000) == 0xFFFF0000 || !(R & 0xFFFF0000)) { \
wait += 2; \
} else if ((R & 0xFF000000) == 0xFF000000 || !(R & 0xFF000000)) { \
wait += 3; \
} else { \
wait += 4; \
} \
currentCycles += cpu->memory.stall(cpu, wait); \
}
#define ARM_STUB cpu->irqh.hitStub(cpu, opcode)
#define ARM_ILL cpu->irqh.hitIllegal(cpu, opcode)
static inline int32_t ARMWritePC(struct ARMCore* cpu) {
uint32_t pc = cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB;
cpu->memory.setActiveRegion(cpu, pc);
LOAD_32(cpu->prefetch[0], pc & cpu->memory.activeMask, cpu->memory.activeRegion);
pc += WORD_SIZE_ARM;
LOAD_32(cpu->prefetch[1], pc & cpu->memory.activeMask, cpu->memory.activeRegion);
cpu->gprs[ARM_PC] = pc;
return 2 + cpu->memory.activeNonseqCycles32 + cpu->memory.activeSeqCycles32;
}
static inline int32_t ThumbWritePC(struct ARMCore* cpu) {
uint32_t pc = cpu->gprs[ARM_PC] & -WORD_SIZE_THUMB;
cpu->memory.setActiveRegion(cpu, pc);
LOAD_16(cpu->prefetch[0], pc & cpu->memory.activeMask, cpu->memory.activeRegion);
pc += WORD_SIZE_THUMB;
LOAD_16(cpu->prefetch[1], pc & cpu->memory.activeMask, cpu->memory.activeRegion);
cpu->gprs[ARM_PC] = pc;
return 2 + cpu->memory.activeNonseqCycles16 + cpu->memory.activeSeqCycles16;
}
static inline int _ARMModeHasSPSR(enum PrivilegeMode mode) {
return mode != MODE_SYSTEM && mode != MODE_USER;
}
static inline void _ARMSetMode(struct ARMCore* cpu, enum ExecutionMode executionMode) {
if (executionMode == cpu->executionMode) {
return;
}
cpu->executionMode = executionMode;
switch (executionMode) {
case MODE_ARM:
cpu->cpsr.t = 0;
cpu->memory.activeMask &= ~2;
break;
case MODE_THUMB:
cpu->cpsr.t = 1;
cpu->memory.activeMask |= 2;
}
cpu->nextEvent = cpu->cycles;
}
static inline void _ARMReadCPSR(struct ARMCore* cpu) {
_ARMSetMode(cpu, cpu->cpsr.t);
ARMSetPrivilegeMode(cpu, cpu->cpsr.priv);
cpu->irqh.readCPSR(cpu);
}
static inline uint32_t _ARMInstructionLength(struct ARMCore* cpu) {
return cpu->cpsr.t == MODE_ARM ? WORD_SIZE_ARM : WORD_SIZE_THUMB;
}
static inline uint32_t _ARMPCAddress(struct ARMCore* cpu) {
return cpu->gprs[ARM_PC] - _ARMInstructionLength(cpu) * 2;
}
static inline bool ARMTestCondition(struct ARMCore* cpu, unsigned condition) {
switch (condition) {
case 0x0:
return ARM_COND_EQ;
case 0x1:
return ARM_COND_NE;
case 0x2:
return ARM_COND_CS;
case 0x3:
return ARM_COND_CC;
case 0x4:
return ARM_COND_MI;
case 0x5:
return ARM_COND_PL;
case 0x6:
return ARM_COND_VS;
case 0x7:
return ARM_COND_VC;
case 0x8:
return ARM_COND_HI;
case 0x9:
return ARM_COND_LS;
case 0xA:
return ARM_COND_GE;
case 0xB:
return ARM_COND_LT;
case 0xC:
return ARM_COND_GT;
case 0xD:
return ARM_COND_LE;
default:
return true;
}
}
static inline enum RegisterBank ARMSelectBank(enum PrivilegeMode mode) {
switch (mode) {
case MODE_USER:
case MODE_SYSTEM:
// No banked registers
return BANK_NONE;
case MODE_FIQ:
return BANK_FIQ;
case MODE_IRQ:
return BANK_IRQ;
case MODE_SUPERVISOR:
return BANK_SUPERVISOR;
case MODE_ABORT:
return BANK_ABORT;
case MODE_UNDEFINED:
return BANK_UNDEFINED;
default:
// This should be unreached
return BANK_NONE;
}
}
#endif

View file

@ -1,20 +0,0 @@
/* Copyright (c) 2013-2014 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 ISA_THUMB_H
#define ISA_THUMB_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct ARMCore;
typedef void (*ThumbInstruction)(struct ARMCore*, unsigned opcode);
extern const ThumbInstruction _thumbTable[0x400];
CXX_GUARD_END
#endif

View file

@ -1,18 +0,0 @@
/* Copyright (c) 2013-2014 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 MACROS_H
#define MACROS_H
#include <mgba-util/common.h>
#define LOAD_64 LOAD_64LE
#define LOAD_32 LOAD_32LE
#define LOAD_16 LOAD_16LE
#define STORE_64 STORE_64LE
#define STORE_32 STORE_32LE
#define STORE_16 STORE_16LE
#endif

View file

@ -1,105 +0,0 @@
/* Copyright (c) 2013-2016 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 CLI_DEBUGGER_H
#define CLI_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/debugger/debugger.h>
extern const char* ERROR_MISSING_ARGS;
extern const char* ERROR_OVERFLOW;
extern const char* ERROR_INVALID_ARGS;
extern const char* INFO_BREAKPOINT_ADDED;
extern const char* INFO_WATCHPOINT_ADDED;
struct CLIDebugger;
struct VFile;
struct CLIDebugVector {
struct CLIDebugVector* next;
enum CLIDVType {
CLIDV_ERROR_TYPE,
CLIDV_INT_TYPE,
CLIDV_CHAR_TYPE,
} type;
char* charValue;
int32_t intValue;
int segmentValue;
};
typedef void (*CLIDebuggerCommand)(struct CLIDebugger*, struct CLIDebugVector*);
struct CLIDebuggerCommandSummary {
const char* name;
CLIDebuggerCommand command;
const char* format;
const char* summary;
};
struct CLIDebuggerCommandAlias {
const char* name;
const char* original;
};
struct CLIDebuggerSystem {
struct CLIDebugger* p;
void (*init)(struct CLIDebuggerSystem*);
void (*deinit)(struct CLIDebuggerSystem*);
bool (*custom)(struct CLIDebuggerSystem*);
void (*disassemble)(struct CLIDebuggerSystem*, struct CLIDebugVector* dv);
void (*printStatus)(struct CLIDebuggerSystem*);
struct CLIDebuggerCommandSummary* commands;
struct CLIDebuggerCommandAlias* commandAliases;
const char* name;
struct CLIDebuggerCommandSummary* platformCommands;
struct CLIDebuggerCommandAlias* platformCommandAliases;
const char* platformName;
};
struct CLIDebuggerBackend {
struct CLIDebugger* p;
void (*init)(struct CLIDebuggerBackend*);
void (*deinit)(struct CLIDebuggerBackend*);
ATTRIBUTE_FORMAT(printf, 2, 3)
void (*printf)(struct CLIDebuggerBackend*, const char* fmt, ...);
const char* (*readline)(struct CLIDebuggerBackend*, size_t* len);
void (*lineAppend)(struct CLIDebuggerBackend*, const char* line);
const char* (*historyLast)(struct CLIDebuggerBackend*, size_t* len);
void (*historyAppend)(struct CLIDebuggerBackend*, const char* line);
};
struct CLIDebugger {
struct mDebugger d;
struct CLIDebuggerSystem* system;
struct CLIDebuggerBackend* backend;
int traceRemaining;
struct VFile* traceVf;
};
void CLIDebuggerCreate(struct CLIDebugger*);
void CLIDebuggerAttachSystem(struct CLIDebugger*, struct CLIDebuggerSystem*);
void CLIDebuggerAttachBackend(struct CLIDebugger*, struct CLIDebuggerBackend*);
bool CLIDebuggerTabComplete(struct CLIDebugger*, const char* token, bool initial, size_t len);
bool CLIDebuggerRunCommand(struct CLIDebugger* debugger, const char* line, size_t count);
#ifdef ENABLE_SCRIPTING
void CLIDebuggerScriptEngineInstall(struct mScriptBridge* sb);
#endif
CXX_GUARD_END
#endif

View file

@ -1,54 +0,0 @@
/* Copyright (c) 2013-2014 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 GDB_STUB_H
#define GDB_STUB_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/debugger/debugger.h>
#include <mgba-util/socket.h>
#define GDB_STUB_MAX_LINE 1200
#define GDB_STUB_INTERVAL 32
enum GDBStubAckState {
GDB_ACK_PENDING = 0,
GDB_ACK_RECEIVED,
GDB_NAK_RECEIVED,
GDB_ACK_OFF
};
struct GDBStub {
struct mDebugger d;
char line[GDB_STUB_MAX_LINE];
char outgoing[GDB_STUB_MAX_LINE];
enum GDBStubAckState lineAck;
Socket socket;
Socket connection;
bool shouldBlock;
int untilPoll;
bool supportsSwbreak;
bool supportsHwbreak;
};
void GDBStubCreate(struct GDBStub*);
bool GDBStubListen(struct GDBStub*, int port, const struct Address* bindAddress);
void GDBStubHangup(struct GDBStub*);
void GDBStubShutdown(struct GDBStub*);
void GDBStubUpdate(struct GDBStub*);
CXX_GUARD_END
#endif

View file

@ -1,78 +0,0 @@
/* Copyright (c) 2013-2014 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 PARSER_H
#define PARSER_H
#include <mgba-util/common.h>
#include <mgba-util/vector.h>
CXX_GUARD_START
struct Token;
DECLARE_VECTOR(LexVector, struct Token);
enum Operation {
OP_ASSIGN,
OP_ADD,
OP_SUBTRACT,
OP_MULTIPLY,
OP_DIVIDE,
OP_MODULO,
OP_AND,
OP_OR,
OP_XOR,
OP_LESS,
OP_GREATER,
OP_EQUAL,
OP_NOT_EQUAL,
OP_LOGICAL_AND,
OP_LOGICAL_OR,
OP_LE,
OP_GE,
OP_NEGATE,
OP_FLIP,
OP_NOT,
OP_SHIFT_L,
OP_SHIFT_R,
OP_DEREFERENCE,
};
struct Token {
enum TokenType {
TOKEN_ERROR_TYPE,
TOKEN_UINT_TYPE,
TOKEN_IDENTIFIER_TYPE,
TOKEN_OPERATOR_TYPE,
TOKEN_OPEN_PAREN_TYPE,
TOKEN_CLOSE_PAREN_TYPE,
TOKEN_SEGMENT_TYPE,
} type;
union {
uint32_t uintValue;
char* identifierValue;
enum Operation operatorValue;
};
};
struct ParseTree {
struct Token token;
struct ParseTree* lhs;
struct ParseTree* rhs;
};
size_t lexExpression(struct LexVector* lv, const char* string, size_t length, const char* eol);
void parseLexedExpression(struct ParseTree* tree, struct LexVector* lv);
void lexFree(struct LexVector* lv);
void parseFree(struct ParseTree* tree);
struct mDebugger;
bool mDebuggerEvaluateParseTree(struct mDebugger* debugger, struct ParseTree* tree, int32_t* value, int* segment);
CXX_GUARD_END
#endif

View file

@ -1,62 +0,0 @@
/* 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 STACK_TRACE_H
#define STACK_TRACE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
#include <mgba/core/log.h>
#include <mgba-util/vector.h>
struct mDebuggerSymbols;
enum mStackTraceMode {
STACK_TRACE_DISABLED = 0,
STACK_TRACE_ENABLED = 1,
STACK_TRACE_BREAK_ON_RETURN = 2,
STACK_TRACE_BREAK_ON_CALL = 4,
STACK_TRACE_BREAK_ON_BOTH = STACK_TRACE_BREAK_ON_RETURN | STACK_TRACE_BREAK_ON_CALL
};
struct mStackFrame {
int callSegment;
uint32_t callAddress;
int entrySegment;
uint32_t entryAddress;
int frameBaseSegment;
uint32_t frameBaseAddress;
void* regs;
bool finished;
bool breakWhenFinished;
bool interrupt;
};
DECLARE_VECTOR(mStackFrames, struct mStackFrame);
struct mStackTrace {
struct mStackFrames stack;
size_t registersSize;
void (*formatRegisters)(struct mStackFrame* frame, char* out, size_t* length);
};
void mStackTraceInit(struct mStackTrace* stack, size_t registersSize);
void mStackTraceDeinit(struct mStackTrace* stack);
void mStackTraceClear(struct mStackTrace* stack);
size_t mStackTraceGetDepth(struct mStackTrace* stack);
struct mStackFrame* mStackTracePush(struct mStackTrace* stack, uint32_t pc, uint32_t destAddress, uint32_t sp, void* regs);
struct mStackFrame* mStackTracePushSegmented(struct mStackTrace* stack, int pcSegment, uint32_t pc, int destSegment, uint32_t destAddress, int spSegment, uint32_t sp, void* regs);
struct mStackFrame* mStackTraceGetFrame(struct mStackTrace* stack, uint32_t frame);
void mStackTraceFormatFrame(struct mStackTrace* stack, struct mDebuggerSymbols* st, uint32_t frame, char* out, size_t* length);
void mStackTracePop(struct mStackTrace* stack);
CXX_GUARD_END
#endif

View file

@ -1,29 +0,0 @@
/* Copyright (c) 2013-2017 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 DEBUGGER_SYMBOLS_H
#define DEBUGGER_SYMBOLS_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct mDebuggerSymbols;
struct mDebuggerSymbols* mDebuggerSymbolTableCreate(void);
void mDebuggerSymbolTableDestroy(struct mDebuggerSymbols*);
bool mDebuggerSymbolLookup(const struct mDebuggerSymbols*, const char* name, int32_t* value, int* segment);
const char* mDebuggerSymbolReverseLookup(const struct mDebuggerSymbols*, int32_t value, int segment);
void mDebuggerSymbolAdd(struct mDebuggerSymbols*, const char* name, int32_t value, int segment);
void mDebuggerSymbolRemove(struct mDebuggerSymbols*, const char* name);
struct VFile;
void mDebuggerLoadARMIPSSymbols(struct mDebuggerSymbols*, struct VFile* vf);
CXX_GUARD_END
#endif

View file

@ -1,257 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_AUDIO_H
#define GB_AUDIO_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/timing.h>
DECL_BITFIELD(GBAudioRegisterDuty, uint8_t);
DECL_BITS(GBAudioRegisterDuty, Length, 0, 6);
DECL_BITS(GBAudioRegisterDuty, Duty, 6, 2);
DECL_BITFIELD(GBAudioRegisterSweep, uint8_t);
DECL_BITS(GBAudioRegisterSweep, StepTime, 0, 3);
DECL_BIT(GBAudioRegisterSweep, Direction, 3);
DECL_BITS(GBAudioRegisterSweep, InitialVolume, 4, 4);
DECL_BITFIELD(GBAudioRegisterControl, uint16_t);
DECL_BITS(GBAudioRegisterControl, Rate, 0, 11);
DECL_BITS(GBAudioRegisterControl, Frequency, 0, 11);
DECL_BIT(GBAudioRegisterControl, Stop, 14);
DECL_BIT(GBAudioRegisterControl, Restart, 15);
DECL_BITFIELD(GBAudioRegisterSquareSweep, uint8_t);
DECL_BITS(GBAudioRegisterSquareSweep, Shift, 0, 3);
DECL_BIT(GBAudioRegisterSquareSweep, Direction, 3);
DECL_BITS(GBAudioRegisterSquareSweep, Time, 4, 3);
DECL_BITFIELD(GBAudioRegisterBank, uint8_t);
DECL_BIT(GBAudioRegisterBank, Size, 5);
DECL_BIT(GBAudioRegisterBank, Bank, 6);
DECL_BIT(GBAudioRegisterBank, Enable, 7);
DECL_BITFIELD(GBAudioRegisterBankVolume, uint8_t);
DECL_BITS(GBAudioRegisterBankVolume, VolumeGB, 5, 2);
DECL_BITS(GBAudioRegisterBankVolume, VolumeGBA, 5, 3);
DECL_BITFIELD(GBAudioRegisterNoiseFeedback, uint8_t);
DECL_BITS(GBAudioRegisterNoiseFeedback, Ratio, 0, 3);
DECL_BIT(GBAudioRegisterNoiseFeedback, Power, 3);
DECL_BITS(GBAudioRegisterNoiseFeedback, Frequency, 4, 4);
DECL_BITFIELD(GBAudioRegisterNoiseControl, uint8_t);
DECL_BIT(GBAudioRegisterNoiseControl, Stop, 6);
DECL_BIT(GBAudioRegisterNoiseControl, Restart, 7);
DECL_BITFIELD(GBRegisterNR50, uint8_t);
DECL_BITS(GBRegisterNR50, VolumeRight, 0, 3);
DECL_BITS(GBRegisterNR50, VolumeLeft, 4, 3);
DECL_BITFIELD(GBRegisterNR51, uint8_t);
DECL_BIT(GBRegisterNR51, Ch1Right, 0);
DECL_BIT(GBRegisterNR51, Ch2Right, 1);
DECL_BIT(GBRegisterNR51, Ch3Right, 2);
DECL_BIT(GBRegisterNR51, Ch4Right, 3);
DECL_BIT(GBRegisterNR51, Ch1Left, 4);
DECL_BIT(GBRegisterNR51, Ch2Left, 5);
DECL_BIT(GBRegisterNR51, Ch3Left, 6);
DECL_BIT(GBRegisterNR51, Ch4Left, 7);
DECL_BITFIELD(GBAudioEnable, uint8_t);
DECL_BIT(GBAudioEnable, PlayingCh1, 0);
DECL_BIT(GBAudioEnable, PlayingCh2, 1);
DECL_BIT(GBAudioEnable, PlayingCh3, 2);
DECL_BIT(GBAudioEnable, PlayingCh4, 3);
DECL_BIT(GBAudioEnable, Enable, 7);
struct GB;
struct GBAudioEnvelope {
int length;
int duty;
int stepTime;
int initialVolume;
int currentVolume;
bool direction;
int dead;
int nextStep;
};
struct GBAudioSquareControl {
int frequency;
int length;
bool stop;
int hi;
};
struct GBAudioSweep {
int shift;
int time;
int step;
bool direction;
bool enable;
bool occurred;
int realFrequency;
};
struct GBAudioSquareChannel {
struct GBAudioSweep sweep;
struct GBAudioEnvelope envelope;
struct GBAudioSquareControl control;
int8_t sample;
};
struct GBAudioWaveChannel {
bool size;
bool bank;
bool enable;
unsigned length;
int volume;
int rate;
bool stop;
int window;
bool readable;
union {
uint32_t wavedata32[8];
uint8_t wavedata8[16];
};
int8_t sample;
};
struct GBAudioNoiseChannel {
struct GBAudioEnvelope envelope;
int ratio;
int frequency;
bool power;
bool stop;
int length;
uint32_t lfsr;
int nSamples;
int samples;
uint32_t lastEvent;
int8_t sample;
};
enum GBAudioStyle {
GB_AUDIO_DMG,
GB_AUDIO_MGB = GB_AUDIO_DMG, // TODO
GB_AUDIO_CGB,
GB_AUDIO_AGB, // GB in GBA
GB_AUDIO_GBA, // GBA PSG
};
struct GBAudio {
struct GB* p;
struct mTiming* timing;
unsigned timingFactor;
struct GBAudioSquareChannel ch1;
struct GBAudioSquareChannel ch2;
struct GBAudioWaveChannel ch3;
struct GBAudioNoiseChannel ch4;
struct blip_t* left;
struct blip_t* right;
int16_t lastLeft;
int16_t lastRight;
int32_t capLeft;
int32_t capRight;
int clock;
int32_t clockRate;
uint8_t volumeRight;
uint8_t volumeLeft;
bool ch1Right;
bool ch2Right;
bool ch3Right;
bool ch4Right;
bool ch1Left;
bool ch2Left;
bool ch3Left;
bool ch4Left;
bool playingCh1;
bool playingCh2;
bool playingCh3;
bool playingCh4;
uint8_t* nr52;
int frame;
bool skipFrame;
int32_t sampleInterval;
enum GBAudioStyle style;
struct mTimingEvent frameEvent;
struct mTimingEvent ch1Event;
struct mTimingEvent ch2Event;
struct mTimingEvent ch3Event;
struct mTimingEvent ch3Fade;
struct mTimingEvent ch4Event;
struct mTimingEvent sampleEvent;
bool enable;
size_t samples;
bool forceDisableCh[4];
int masterVolume;
};
void GBAudioInit(struct GBAudio* audio, size_t samples, uint8_t* nr52, enum GBAudioStyle style);
void GBAudioDeinit(struct GBAudio* audio);
void GBAudioReset(struct GBAudio* audio);
void GBAudioResizeBuffer(struct GBAudio* audio, size_t samples);
void GBAudioWriteNR10(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR11(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR12(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR13(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR14(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR21(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR22(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR23(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR24(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR30(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR31(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR32(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR33(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR34(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR41(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR42(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR43(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR44(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR50(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR51(struct GBAudio* audio, uint8_t);
void GBAudioWriteNR52(struct GBAudio* audio, uint8_t);
void GBAudioUpdateFrame(struct GBAudio* audio);
void GBAudioUpdateChannel4(struct GBAudio* audio);
void GBAudioSamplePSG(struct GBAudio* audio, int16_t* left, int16_t* right);
struct GBSerializedPSGState;
void GBAudioPSGSerialize(const struct GBAudio* audio, struct GBSerializedPSGState* state, uint32_t* flagsOut);
void GBAudioPSGDeserialize(struct GBAudio* audio, const struct GBSerializedPSGState* state, const uint32_t* flagsIn);
struct GBSerializedState;
void GBAudioSerialize(const struct GBAudio* audio, struct GBSerializedState* state);
void GBAudioDeserialize(struct GBAudio* audio, const struct GBSerializedState* state);
CXX_GUARD_END
#endif

View file

@ -1,26 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_CHEATS_H
#define GB_CHEATS_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cheats.h>
enum GBCheatType {
GB_CHEAT_AUTODETECT,
GB_CHEAT_GAMESHARK,
GB_CHEAT_GAME_GENIE,
GB_CHEAT_VBA
};
struct mCheatDevice* GBCheatDeviceCreate(void);
CXX_GUARD_END
#endif

View file

@ -1,20 +0,0 @@
/* Copyright (c) 2013-2019 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 GB_DEBUGGER_H
#define GB_DEBUGGER_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct GB;
struct mDebuggerPlatform;
struct mDebuggerPlatform* GBDebuggerCreate(struct GB* gb);
CXX_GUARD_END
#endif

View file

@ -1,19 +0,0 @@
/* Copyright (c) 2013-2017 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 GB_SYMBOLS_H
#define GB_SYMBOLS_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct mDebuggerSymbols;
struct VFile;
void GBLoadSymbols(struct mDebuggerSymbols*, struct VFile* vf);
CXX_GUARD_END
#endif

View file

@ -1,28 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_CLI_H
#define GB_CLI_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/internal/debugger/cli-debugger.h>
struct GBCLIDebugger {
struct CLIDebuggerSystem d;
struct mCore* core;
bool frameAdvance;
bool inVblank;
};
struct CLIDebuggerSystem* GBCLIDebuggerCreate(struct mCore*);
CXX_GUARD_END
#endif

View file

@ -1,189 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_H
#define GB_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/cpu.h>
#include <mgba/core/interface.h>
#include <mgba/core/log.h>
#include <mgba/core/timing.h>
#include <mgba/internal/gb/audio.h>
#include <mgba/internal/gb/memory.h>
#include <mgba/internal/gb/sio.h>
#include <mgba/internal/gb/timer.h>
#include <mgba/internal/gb/video.h>
extern const uint32_t DMG_SM83_FREQUENCY;
extern const uint32_t CGB_SM83_FREQUENCY;
extern const uint32_t SGB_SM83_FREQUENCY;
mLOG_DECLARE_CATEGORY(GB);
// TODO: Prefix GBAIRQ
enum GBIRQ {
GB_IRQ_VBLANK = 0x0,
GB_IRQ_LCDSTAT = 0x1,
GB_IRQ_TIMER = 0x2,
GB_IRQ_SIO = 0x3,
GB_IRQ_KEYPAD = 0x4,
};
enum GBIRQVector {
GB_VECTOR_VBLANK = 0x40,
GB_VECTOR_LCDSTAT = 0x48,
GB_VECTOR_TIMER = 0x50,
GB_VECTOR_SIO = 0x58,
GB_VECTOR_KEYPAD = 0x60,
};
enum GBSGBCommand {
SGB_PAL01 = 0,
SGB_PAL23,
SGB_PAL03,
SGB_PAL12,
SGB_ATTR_BLK,
SGB_ATTR_LIN,
SGB_ATTR_DIV,
SGB_ATTR_CHR,
SGB_SOUND,
SGB_SOU_TRN,
SGB_PAL_SET,
SGB_PAL_TRN,
SGB_ATRC_EN,
SGB_TEST_EN,
SGB_PICON_EN,
SGB_DATA_SND,
SGB_DATA_TRN,
SGB_MLT_REQ,
SGB_JUMP,
SGB_CHR_TRN,
SGB_PCT_TRN,
SGB_ATTR_TRN,
SGB_ATTR_SET,
SGB_MASK_EN,
SGB_OBJ_TRN
};
struct SM83Core;
struct mCoreSync;
struct mAVStream;
struct GB {
struct mCPUComponent d;
struct SM83Core* cpu;
struct GBMemory memory;
struct GBVideo video;
struct GBTimer timer;
struct GBAudio audio;
struct GBSIO sio;
enum GBModel model;
struct mCoreSync* sync;
struct mTiming timing;
uint8_t* keySource;
bool isPristine;
size_t pristineRomSize;
size_t yankedRomSize;
enum GBMemoryBankControllerType yankedMbc;
uint32_t romCrc32;
struct VFile* romVf;
struct VFile* biosVf;
struct VFile* sramVf;
struct VFile* sramRealVf;
uint32_t sramSize;
int sramDirty;
int32_t sramDirtAge;
bool sramMaskWriteback;
int sgbBit;
int currentSgbBits;
uint8_t sgbPacket[16];
uint8_t sgbControllers;
uint8_t sgbCurrentController;
bool sgbIncrement;
struct mCoreCallbacksList coreCallbacks;
struct mAVStream* stream;
bool cpuBlocked;
bool earlyExit;
struct mTimingEvent eiPending;
unsigned doubleSpeed;
bool allowOpposingDirections;
};
struct GBCartridge {
uint8_t entry[4];
uint8_t logo[48];
union {
char titleLong[16];
struct {
char titleShort[11];
char maker[4];
uint8_t cgb;
};
};
char licensee[2];
uint8_t sgb;
uint8_t type;
uint8_t romSize;
uint8_t ramSize;
uint8_t region;
uint8_t oldLicensee;
uint8_t version;
uint8_t headerChecksum;
uint16_t globalChecksum;
// And ROM data...
};
void GBCreate(struct GB* gb);
void GBDestroy(struct GB* gb);
void GBReset(struct SM83Core* cpu);
void GBSkipBIOS(struct GB* gb);
void GBMapBIOS(struct GB* gb);
void GBUnmapBIOS(struct GB* gb);
void GBDetectModel(struct GB* gb);
void GBUpdateIRQs(struct GB* gb);
void GBHalt(struct SM83Core* cpu);
struct VFile;
bool GBLoadROM(struct GB* gb, struct VFile* vf);
bool GBLoadSave(struct GB* gb, struct VFile* vf);
void GBUnloadROM(struct GB* gb);
void GBSynthesizeROM(struct VFile* vf);
void GBYankROM(struct GB* gb);
void GBLoadBIOS(struct GB* gb, struct VFile* vf);
void GBSramClean(struct GB* gb, uint32_t frameCount);
void GBResizeSram(struct GB* gb, size_t size);
void GBSavedataMask(struct GB* gb, struct VFile* vf, bool writeback);
void GBSavedataUnmask(struct GB* gb);
struct Patch;
void GBApplyPatch(struct GB* gb, struct Patch* patch);
void GBGetGameTitle(const struct GB* gba, char* out);
void GBGetGameCode(const struct GB* gba, char* out);
void GBTestKeypadIRQ(struct GB* gb);
void GBFrameStarted(struct GB* gb);
void GBFrameEnded(struct GB* gb);
CXX_GUARD_END
#endif

View file

@ -1,31 +0,0 @@
/* Copyright (c) 2013-2019 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 GB_INPUT_H
#define GB_INPUT_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/input.h>
extern MGBA_EXPORT const struct mInputPlatformInfo GBInputInfo;
enum GBKey {
GB_KEY_A = 0,
GB_KEY_B = 1,
GB_KEY_SELECT = 2,
GB_KEY_START = 3,
GB_KEY_RIGHT = 4,
GB_KEY_LEFT = 5,
GB_KEY_UP = 6,
GB_KEY_DOWN = 7,
GB_KEY_MAX,
};
CXX_GUARD_END
#endif

View file

@ -1,127 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_IO_H
#define GB_IO_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/log.h>
mLOG_DECLARE_CATEGORY(GB_IO);
enum GBIORegisters {
GB_REG_JOYP = 0x00,
GB_REG_SB = 0x01,
GB_REG_SC = 0x02,
// Timing
GB_REG_DIV = 0x04,
GB_REG_TIMA = 0x05,
GB_REG_TMA = 0x06,
GB_REG_TAC = 0x07,
// Interrupts
GB_REG_IF = 0x0F,
GB_REG_IE = 0xFF,
// Audio
GB_REG_NR10 = 0x10,
GB_REG_NR11 = 0x11,
GB_REG_NR12 = 0x12,
GB_REG_NR13 = 0x13,
GB_REG_NR14 = 0x14,
GB_REG_NR21 = 0x16,
GB_REG_NR22 = 0x17,
GB_REG_NR23 = 0x18,
GB_REG_NR24 = 0x19,
GB_REG_NR30 = 0x1A,
GB_REG_NR31 = 0x1B,
GB_REG_NR32 = 0x1C,
GB_REG_NR33 = 0x1D,
GB_REG_NR34 = 0x1E,
GB_REG_NR41 = 0x20,
GB_REG_NR42 = 0x21,
GB_REG_NR43 = 0x22,
GB_REG_NR44 = 0x23,
GB_REG_NR50 = 0x24,
GB_REG_NR51 = 0x25,
GB_REG_NR52 = 0x26,
GB_REG_WAVE_0 = 0x30,
GB_REG_WAVE_1 = 0x31,
GB_REG_WAVE_2 = 0x32,
GB_REG_WAVE_3 = 0x33,
GB_REG_WAVE_4 = 0x34,
GB_REG_WAVE_5 = 0x35,
GB_REG_WAVE_6 = 0x36,
GB_REG_WAVE_7 = 0x37,
GB_REG_WAVE_8 = 0x38,
GB_REG_WAVE_9 = 0x39,
GB_REG_WAVE_A = 0x3A,
GB_REG_WAVE_B = 0x3B,
GB_REG_WAVE_C = 0x3C,
GB_REG_WAVE_D = 0x3D,
GB_REG_WAVE_E = 0x3E,
GB_REG_WAVE_F = 0x3F,
// Video
GB_REG_LCDC = 0x40,
GB_REG_STAT = 0x41,
GB_REG_SCY = 0x42,
GB_REG_SCX = 0x43,
GB_REG_LY = 0x44,
GB_REG_LYC = 0x45,
GB_REG_DMA = 0x46,
GB_REG_BGP = 0x47,
GB_REG_OBP0 = 0x48,
GB_REG_OBP1 = 0x49,
GB_REG_WY = 0x4A,
GB_REG_WX = 0x4B,
// CGB
GB_REG_KEY0 = 0x4C,
GB_REG_KEY1 = 0x4D,
GB_REG_VBK = 0x4F,
GB_REG_BANK = 0x50,
GB_REG_HDMA1 = 0x51,
GB_REG_HDMA2 = 0x52,
GB_REG_HDMA3 = 0x53,
GB_REG_HDMA4 = 0x54,
GB_REG_HDMA5 = 0x55,
GB_REG_RP = 0x56,
GB_REG_BCPS = 0x68,
GB_REG_BCPD = 0x69,
GB_REG_OCPS = 0x6A,
GB_REG_OCPD = 0x6B,
GB_REG_OPRI = 0x6C,
GB_REG_SVBK = 0x70,
GB_REG_UNK72 = 0x72,
GB_REG_UNK73 = 0x73,
GB_REG_UNK74 = 0x74,
GB_REG_UNK75 = 0x75,
GB_REG_PCM12 = 0x76,
GB_REG_PCM34 = 0x77,
GB_REG_MAX = 0x100
};
extern MGBA_EXPORT const char* const GBIORegisterNames[];
struct GB;
void GBIOInit(struct GB* gb);
void GBIOReset(struct GB* gb);
void GBIOWrite(struct GB* gb, unsigned address, uint8_t value);
uint8_t GBIORead(struct GB* gb, unsigned address);
struct GBSerializedState;
void GBIOSerialize(const struct GB* gb, struct GBSerializedState* state);
void GBIODeserialize(struct GB* gb, const struct GBSerializedState* state);
CXX_GUARD_END
#endif

View file

@ -1,50 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_MBC_H
#define GB_MBC_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/log.h>
mLOG_DECLARE_CATEGORY(GB_MBC);
struct GB;
struct GBMemory;
void GBMBCInit(struct GB* gb);
void GBMBCReset(struct GB* gb);
void GBMBCSwitchBank(struct GB* gb, int bank);
void GBMBCSwitchBank0(struct GB* gb, int bank);
void GBMBCSwitchHalfBank(struct GB* gb, int half, int bank);
void GBMBCSwitchSramBank(struct GB* gb, int bank);
void GBMBCSwitchSramHalfBank(struct GB* gb, int half, int bank);
enum GBCam {
GBCAM_WIDTH = 128,
GBCAM_HEIGHT = 112
};
struct GBMBCRTCSaveBuffer {
uint32_t sec;
uint32_t min;
uint32_t hour;
uint32_t days;
uint32_t daysHi;
uint32_t latchedSec;
uint32_t latchedMin;
uint32_t latchedHour;
uint32_t latchedDays;
uint32_t latchedDaysHi;
uint64_t unixTime;
};
void GBMBCRTCRead(struct GB* gb);
void GBMBCRTCWrite(struct GB* gb);
CXX_GUARD_END
#endif

View file

@ -1,251 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_MEMORY_H
#define GB_MEMORY_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/log.h>
#include <mgba/core/timing.h>
#include <mgba/gb/interface.h>
mLOG_DECLARE_CATEGORY(GB_MBC);
mLOG_DECLARE_CATEGORY(GB_MEM);
struct GB;
enum {
GB_BASE_CART_BANK0 = 0x0000,
GB_BASE_CART_BANK1 = 0x4000,
GB_BASE_CART_HALFBANK1 = 0x4000,
GB_BASE_CART_HALFBANK2 = 0x6000,
GB_BASE_VRAM = 0x8000,
GB_BASE_EXTERNAL_RAM = 0xA000,
GB_BASE_EXTERNAL_RAM_HALFBANK0 = 0xA000,
GB_BASE_EXTERNAL_RAM_HALFBANK1 = 0xB000,
GB_BASE_WORKING_RAM_BANK0 = 0xC000,
GB_BASE_WORKING_RAM_BANK1 = 0xD000,
GB_BASE_OAM = 0xFE00,
GB_BASE_UNUSABLE = 0xFEA0,
GB_BASE_IO = 0xFF00,
GB_BASE_HRAM = 0xFF80,
GB_BASE_IE = 0xFFFF
};
enum {
GB_REGION_CART_BANK0 = 0x0,
GB_REGION_CART_BANK1 = 0x4,
GB_REGION_VRAM = 0x8,
GB_REGION_EXTERNAL_RAM = 0xA,
GB_REGION_WORKING_RAM_BANK0 = 0xC,
GB_REGION_WORKING_RAM_BANK1 = 0xD,
GB_REGION_WORKING_RAM_BANK1_MIRROR = 0xE,
GB_REGION_OTHER = 0xF,
};
enum {
GB_SIZE_CART_BANK0 = 0x4000,
GB_SIZE_CART_HALFBANK = 0x2000,
GB_SIZE_CART_MAX = 0x800000,
GB_SIZE_VRAM = 0x4000,
GB_SIZE_VRAM_BANK0 = 0x2000,
GB_SIZE_EXTERNAL_RAM = 0x2000,
GB_SIZE_EXTERNAL_RAM_HALFBANK = 0x1000,
GB_SIZE_WORKING_RAM = 0x8000,
GB_SIZE_WORKING_RAM_BANK0 = 0x1000,
GB_SIZE_OAM = 0xA0,
GB_SIZE_IO = 0x80,
GB_SIZE_HRAM = 0x7F,
GB_SIZE_MBC6_FLASH = 0x100000,
};
enum {
GB_SRAM_DIRT_NEW = 1,
GB_SRAM_DIRT_SEEN = 2
};
struct GBMemory;
typedef void (*GBMemoryBankControllerWrite)(struct GB*, uint16_t address, uint8_t value);
typedef uint8_t (*GBMemoryBankControllerRead)(struct GBMemory*, uint16_t address);
DECL_BITFIELD(GBMBC7Field, uint8_t);
DECL_BIT(GBMBC7Field, CS, 7);
DECL_BIT(GBMBC7Field, CLK, 6);
DECL_BIT(GBMBC7Field, DI, 1);
DECL_BIT(GBMBC7Field, DO, 0);
enum GBMBC7MachineState {
GBMBC7_STATE_IDLE = 0,
GBMBC7_STATE_READ_COMMAND = 1,
GBMBC7_STATE_DO = 2,
GBMBC7_STATE_EEPROM_EWDS = 0x10,
GBMBC7_STATE_EEPROM_WRAL = 0x11,
GBMBC7_STATE_EEPROM_ERAL = 0x12,
GBMBC7_STATE_EEPROM_EWEN = 0x13,
GBMBC7_STATE_EEPROM_WRITE = 0x14,
GBMBC7_STATE_EEPROM_READ = 0x18,
GBMBC7_STATE_EEPROM_ERASE = 0x1C,
};
enum GBTAMA5Register {
GBTAMA5_BANK_LO = 0x0,
GBTAMA5_BANK_HI = 0x1,
GBTAMA5_WRITE_LO = 0x4,
GBTAMA5_WRITE_HI = 0x5,
GBTAMA5_CS = 0x6,
GBTAMA5_ADDR_LO = 0x7,
GBTAMA5_MAX = 0x8,
GBTAMA5_ACTIVE = 0xA,
GBTAMA5_READ_LO = 0xC,
GBTAMA5_READ_HI = 0xD,
};
struct GBMBC1State {
int mode;
int multicartStride;
uint8_t bankLo;
uint8_t bankHi;
};
struct GBMBC6State {
int currentBank1;
uint8_t* romBank1;
bool sramAccess;
int currentSramBank1;
uint8_t* sramBank1;
bool flashBank0;
bool flashBank1;
};
struct GBMBC7State {
enum GBMBC7MachineState state;
uint16_t sr;
uint8_t address;
bool writable;
int srBits;
uint8_t access;
uint8_t latch;
GBMBC7Field eeprom;
};
struct GBMMM01State {
bool locked;
int currentBank0;
};
struct GBPocketCamState {
bool registersActive;
uint8_t registers[0x36];
};
struct GBTAMA5State {
uint8_t reg;
uint8_t registers[GBTAMA5_MAX];
};
struct GBPKJDState {
uint8_t reg[2];
};
struct GBBBDState {
int dataSwapMode;
int bankSwapMode;
};
union GBMBCState {
struct GBMBC1State mbc1;
struct GBMBC6State mbc6;
struct GBMBC7State mbc7;
struct GBMMM01State mmm01;
struct GBPocketCamState pocketCam;
struct GBTAMA5State tama5;
struct GBPKJDState pkjd;
struct GBBBDState bbd;
};
struct mRotationSource;
struct GBMemory {
uint8_t* rom;
uint8_t* romBase;
uint8_t* romBank;
enum GBMemoryBankControllerType mbcType;
GBMemoryBankControllerWrite mbcWrite;
GBMemoryBankControllerRead mbcRead;
union GBMBCState mbcState;
int currentBank;
int currentBank0;
uint8_t* wram;
uint8_t* wramBank;
int wramCurrentBank;
bool sramAccess;
bool directSramAccess;
uint8_t* sram;
uint8_t* sramBank;
int sramCurrentBank;
uint8_t io[GB_SIZE_IO];
bool ime;
uint8_t ie;
uint8_t hram[GB_SIZE_HRAM];
uint16_t dmaSource;
uint16_t dmaDest;
int dmaRemaining;
uint16_t hdmaSource;
uint16_t hdmaDest;
int hdmaRemaining;
bool isHdma;
struct mTimingEvent dmaEvent;
struct mTimingEvent hdmaEvent;
size_t romSize;
bool rtcAccess;
int activeRtcReg;
bool rtcLatched;
uint8_t rtcRegs[5];
time_t rtcLastLatch;
struct mRTCSource* rtc;
struct mRotationSource* rotation;
struct mRumble* rumble;
struct mImageSource* cam;
};
struct SM83Core;
void GBMemoryInit(struct GB* gb);
void GBMemoryDeinit(struct GB* gb);
void GBMemoryReset(struct GB* gb);
void GBMemorySwitchWramBank(struct GBMemory* memory, int bank);
uint8_t GBLoad8(struct SM83Core* cpu, uint16_t address);
void GBStore8(struct SM83Core* cpu, uint16_t address, int8_t value);
int GBCurrentSegment(struct SM83Core* cpu, uint16_t address);
uint8_t GBView8(struct SM83Core* cpu, uint16_t address, int segment);
void GBMemoryDMA(struct GB* gb, uint16_t base);
uint8_t GBMemoryWriteHDMA5(struct GB* gb, uint8_t value);
void GBPatch8(struct SM83Core* cpu, uint16_t address, int8_t value, int8_t* old, int segment);
struct GBSerializedState;
void GBMemorySerialize(const struct GB* gb, struct GBSerializedState* state);
void GBMemoryDeserialize(struct GB* gb, const struct GBSerializedState* state);
CXX_GUARD_END
#endif

View file

@ -1,34 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_OVERRIDES_H
#define GB_OVERRIDES_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/gb/interface.h>
struct GBCartridgeOverride {
int headerCrc32;
enum GBModel model;
enum GBMemoryBankControllerType mbc;
uint32_t gbColors[12];
};
struct Configuration;
bool GBOverrideFind(const struct Configuration*, struct GBCartridgeOverride* override);
bool GBOverrideColorFind(struct GBCartridgeOverride* override);
void GBOverrideSave(struct Configuration*, const struct GBCartridgeOverride* override);
struct GB;
void GBOverrideApply(struct GB*, const struct GBCartridgeOverride*);
void GBOverrideApplyDefaults(struct GB*);
CXX_GUARD_END
#endif

View file

@ -1,23 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_TILE_CACHE_H
#define GB_TILE_CACHE_H
#include <mgba-util/common.h>
CXX_GUARD_START
struct GBVideo;
struct mCacheSet;
void GBVideoCacheInit(struct mCacheSet* cache);
void GBVideoCacheAssociate(struct mCacheSet* cache, struct GBVideo* video);
void GBVideoCacheWriteVideoRegister(struct mCacheSet* cache, uint16_t address, uint8_t value);
CXX_GUARD_END
#endif

View file

@ -1,29 +0,0 @@
/* Copyright (c) 2013-2017 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 GB_VIDEO_PROXY_H
#define GB_VIDEO_PROXY_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/internal/gb/video.h>
#include <mgba/feature/video-logger.h>
struct GBVideoProxyRenderer {
struct GBVideoRenderer d;
struct GBVideoRenderer* backend;
struct mVideoLogger* logger;
enum GBModel model;
};
void GBVideoProxyRendererCreate(struct GBVideoProxyRenderer* renderer, struct GBVideoRenderer* backend);
void GBVideoProxyRendererShim(struct GBVideo* video, struct GBVideoProxyRenderer* renderer);
void GBVideoProxyRendererUnshim(struct GBVideo* video, struct GBVideoProxyRenderer* renderer);
CXX_GUARD_END
#endif

View file

@ -1,71 +0,0 @@
/* Copyright (c) 2013-2016 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 GB_RENDERER_SOFTWARE_H
#define GB_RENDERER_SOFTWARE_H
#include <mgba-util/common.h>
CXX_GUARD_START
#include <mgba/core/core.h>
#include <mgba/internal/gb/gb.h>
#include <mgba/internal/gb/video.h>
struct GBVideoRendererSprite {
struct GBObj obj;
int8_t index;
};
struct GBVideoSoftwareRenderer {
struct GBVideoRenderer d;
color_t* outputBuffer;
int outputBufferStride;
// TODO: Implement the pixel FIFO
uint16_t row[GB_VIDEO_HORIZONTAL_PIXELS + 8];
color_t palette[192];
uint8_t lookup[192];
uint32_t* temporaryBuffer;
uint8_t scy;
uint8_t scx;
uint8_t wy;
uint8_t wx;
uint8_t currentWy;
uint8_t currentWx;
int lastY;
int lastX;
bool hasWindow;
GBRegisterLCDC lcdc;
enum GBModel model;
struct GBVideoRendererSprite obj[GB_VIDEO_MAX_LINE_OBJ];
int objMax;
int16_t objOffsetX;
int16_t objOffsetY;
int16_t offsetScx;
int16_t offsetScy;
int16_t offsetWx;
int16_t offsetWy;
int sgbTransfer;
uint8_t sgbPacket[128];
uint8_t sgbCommandHeader;
bool sgbBorders;
uint8_t lastHighlightAmount;
};
void GBVideoSoftwareRendererCreate(struct GBVideoSoftwareRenderer*);
CXX_GUARD_END
#endif

Some files were not shown because too many files have changed in this diff Show more