Merge branch 'master' into port/3ds

This commit is contained in:
Jeffrey Pfau 2015-08-23 07:21:23 -07:00
commit 0affe7c8d7
14 changed files with 512 additions and 181 deletions

View File

@ -10,6 +10,7 @@ Misc:
- Qt: Increase usability of key mapper
- GBA Memory: Use a dynamically sized mask for ROM memory
- Qt: Remove useless help icons in dialogs
- ARM7: Combine shifter-immediate and shifter-register functions to reduce binary size
0.3.0: (2015-08-16)
Features:

View File

@ -28,6 +28,7 @@ file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
file(GLOB GBA_CHEATS_SRC ${CMAKE_SOURCE_DIR}/src/gba/cheats/*.c)
file(GLOB GBA_RR_SRC ${CMAKE_SOURCE_DIR}/src/gba/rr/*.c)
file(GLOB GBA_SV_SRC ${CMAKE_SOURCE_DIR}/src/gba/supervisor/*.c)
file(GLOB GUI_SRC ${CMAKE_SOURCE_DIR}/src/gui/*.c)
file(GLOB UTIL_SRC ${CMAKE_SOURCE_DIR}/src/util/*.[cSs])
file(GLOB RENDERER_SRC ${CMAKE_SOURCE_DIR}/src/gba/renderers/*.c)
file(GLOB SIO_SRC ${CMAKE_SOURCE_DIR}/src/gba/sio/lockstep.c)

BIN
res/font.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@ -11,18 +11,16 @@
#define ADDR_MODE_1_SHIFT(OP) \
info->op3.reg = opcode & 0x0000000F; \
info->op3.shifterOp = ARM_SHIFT_ ## OP; \
info->op3.shifterImm = (opcode >> 7) & 0x1F; \
info->operandFormat |= ARM_OPERAND_REGISTER_3 | \
ARM_OPERAND_SHIFT_IMMEDIATE_3;
#define ADDR_MODE_1_SHIFTR(OP) \
info->op3.reg = opcode & 0x0000000F; \
info->op3.shifterOp = ARM_SHIFT_ ## OP; \
info->op3.shifterReg = (opcode >> 8) & 0xF; \
++info->iCycles; \
info->operandFormat |= ARM_OPERAND_REGISTER_3 | \
ARM_OPERAND_SHIFT_REGISTER_3;
info->operandFormat |= ARM_OPERAND_REGISTER_3; \
if (opcode & 0x00000010) { \
info->op3.shifterOp = ARM_SHIFT_ ## OP; \
info->op3.shifterReg = (opcode >> 8) & 0xF; \
++info->iCycles; \
info->operandFormat |= ARM_OPERAND_SHIFT_REGISTER_3; \
} else { \
info->op3.shifterImm = (opcode >> 7) & 0x1F; \
info->operandFormat |= ARM_OPERAND_SHIFT_IMMEDIATE_3; \
}
#define ADDR_MODE_1_LSL \
ADDR_MODE_1_SHIFT(LSL) \
@ -39,11 +37,6 @@
info->op3.shifterOp = ARM_SHIFT_RRX; \
}
#define ADDR_MODE_1_LSLR ADDR_MODE_1_SHIFTR(LSL)
#define ADDR_MODE_1_LSRR ADDR_MODE_1_SHIFTR(LSR)
#define ADDR_MODE_1_ASRR ADDR_MODE_1_SHIFTR(ASR)
#define ADDR_MODE_1_RORR ADDR_MODE_1_SHIFTR(ROR)
#define ADDR_MODE_1_IMM \
int rotate = (opcode & 0x00000F00) >> 7; \
int immediate = opcode & 0x000000FF; \
@ -121,32 +114,20 @@
#define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 0, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSLR, NAME, 0, ADDR_MODE_1_LSLR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSLR, NAME, 1, ADDR_MODE_1_LSLR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 0, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSRR, NAME, 0, ADDR_MODE_1_LSRR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSRR, NAME, 1, ADDR_MODE_1_LSRR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 0, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASRR, NAME, 0, ADDR_MODE_1_ASRR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ASRR, NAME, 1, ADDR_MODE_1_ASRR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 0, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _RORR, NAME, 0, ADDR_MODE_1_RORR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## S_RORR, NAME, 1, ADDR_MODE_1_RORR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 0, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## SI, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED)
#define DEFINE_ALU_DECODER_S_ONLY_ARM(NAME) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSLR, NAME, 1, ADDR_MODE_1_LSLR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSRR, NAME, 1, ADDR_MODE_1_LSRR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASRR, NAME, 1, ADDR_MODE_1_ASRR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## _RORR, NAME, 1, ADDR_MODE_1_RORR, ARM_OPERAND_NONE, 1) \
DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_NONE, 1)
#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED) \

View File

@ -17,13 +17,13 @@
#define DECLARE_ARM_ALU_BLOCK(EMITTER, ALU, EX1, EX2, EX3, EX4) \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSLR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSRR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASRR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ASR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _RORR), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \
DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \
DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \

View File

@ -16,160 +16,156 @@
// Addressing mode 1
static inline void _shiftLSL(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int immediate = (opcode & 0x00000F80) >> 7;
if (!immediate) {
cpu->shifterOperand = cpu->gprs[rm];
cpu->shifterCarryOut = cpu->cpsr.c;
if (opcode & 0x00000010) {
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
int32_t shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (shift < 32) {
cpu->shifterOperand = shiftVal << shift;
cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;
} else if (shift == 32) {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = shiftVal & 1;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = 0;
}
} else {
cpu->shifterOperand = cpu->gprs[rm] << immediate;
cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;
}
}
static inline void _shiftLSLR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
int32_t shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (shift < 32) {
cpu->shifterOperand = shiftVal << shift;
cpu->shifterCarryOut = (shiftVal >> (32 - shift)) & 1;
} else if (shift == 32) {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = shiftVal & 1;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = 0;
int immediate = (opcode & 0x00000F80) >> 7;
if (!immediate) {
cpu->shifterOperand = cpu->gprs[rm];
cpu->shifterCarryOut = cpu->cpsr.c;
} else {
cpu->shifterOperand = cpu->gprs[rm] << immediate;
cpu->shifterCarryOut = (cpu->gprs[rm] >> (32 - immediate)) & 1;
}
}
}
static inline void _shiftLSR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int immediate = (opcode & 0x00000F80) >> 7;
if (immediate) {
cpu->shifterOperand = ((uint32_t) cpu->gprs[rm]) >> immediate;
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
if (opcode & 0x00000010) {
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
uint32_t shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (shift < 32) {
cpu->shifterOperand = shiftVal >> shift;
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
} else if (shift == 32) {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = shiftVal >> 31;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = 0;
}
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
}
}
static inline void _shiftLSRR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
uint32_t shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (shift < 32) {
cpu->shifterOperand = shiftVal >> shift;
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
} else if (shift == 32) {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = shiftVal >> 31;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = 0;
int immediate = (opcode & 0x00000F80) >> 7;
if (immediate) {
cpu->shifterOperand = ((uint32_t) cpu->gprs[rm]) >> immediate;
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
}
}
}
static inline void _shiftASR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int immediate = (opcode & 0x00000F80) >> 7;
if (immediate) {
cpu->shifterOperand = cpu->gprs[rm] >> immediate;
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
if (opcode & 0x00000010) {
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
int shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (shift < 32) {
cpu->shifterOperand = shiftVal >> shift;
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
} else if (cpu->gprs[rm] >> 31) {
cpu->shifterOperand = 0xFFFFFFFF;
cpu->shifterCarryOut = 1;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = 0;
}
} else {
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
cpu->shifterOperand = cpu->shifterCarryOut;
}
}
static inline void _shiftASRR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
int shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (shift < 32) {
cpu->shifterOperand = shiftVal >> shift;
cpu->shifterCarryOut = (shiftVal >> (shift - 1)) & 1;
} else if (cpu->gprs[rm] >> 31) {
cpu->shifterOperand = 0xFFFFFFFF;
cpu->shifterCarryOut = 1;
} else {
cpu->shifterOperand = 0;
cpu->shifterCarryOut = 0;
int immediate = (opcode & 0x00000F80) >> 7;
if (immediate) {
cpu->shifterOperand = cpu->gprs[rm] >> immediate;
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
} else {
cpu->shifterCarryOut = ARM_SIGN(cpu->gprs[rm]);
cpu->shifterOperand = cpu->shifterCarryOut;
}
}
}
static inline void _shiftROR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int immediate = (opcode & 0x00000F80) >> 7;
if (immediate) {
cpu->shifterOperand = ROR(cpu->gprs[rm], immediate);
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
if (opcode & 0x00000010) {
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
int shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
int rotate = shift & 0x1F;
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (rotate) {
cpu->shifterOperand = ROR(shiftVal, rotate);
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
} else {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = ARM_SIGN(shiftVal);
}
} else {
// RRX
cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001;
}
}
static inline void _shiftRORR(struct ARMCore* cpu, uint32_t opcode) {
int rm = opcode & 0x0000000F;
int rs = (opcode >> 8) & 0x0000000F;
++cpu->cycles;
int shift = cpu->gprs[rs];
if (rs == ARM_PC) {
shift += 4;
}
shift &= 0xFF;
int shiftVal = cpu->gprs[rm];
if (rm == ARM_PC) {
shiftVal += 4;
}
int rotate = shift & 0x1F;
if (!shift) {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = cpu->cpsr.c;
} else if (rotate) {
cpu->shifterOperand = ROR(shiftVal, rotate);
cpu->shifterCarryOut = (shiftVal >> (rotate - 1)) & 1;
} else {
cpu->shifterOperand = shiftVal;
cpu->shifterCarryOut = ARM_SIGN(shiftVal);
int immediate = (opcode & 0x00000F80) >> 7;
if (immediate) {
cpu->shifterOperand = ROR(cpu->gprs[rm], immediate);
cpu->shifterCarryOut = (cpu->gprs[rm] >> (immediate - 1)) & 1;
} else {
// RRX
cpu->shifterOperand = (cpu->cpsr.c << 31) | (((uint32_t) cpu->gprs[rm]) >> 1);
cpu->shifterCarryOut = cpu->gprs[rm] & 0x00000001;
}
}
}
@ -293,32 +289,20 @@ static inline void _immediate(struct ARMCore* cpu, uint32_t opcode) {
#define DEFINE_ALU_INSTRUCTION_ARM(NAME, S_BODY, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSL, , _shiftLSL, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_LSL, S_BODY, _shiftLSL, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSLR, , _shiftLSLR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_LSLR, S_BODY, _shiftLSLR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSR, , _shiftLSR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_LSR, S_BODY, _shiftLSR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSRR, , _shiftLSRR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_LSRR, S_BODY, _shiftLSRR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ASR, , _shiftASR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_ASR, S_BODY, _shiftASR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ASRR, , _shiftASRR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_ASRR, S_BODY, _shiftASRR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ROR, , _shiftROR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_ROR, S_BODY, _shiftROR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _RORR, , _shiftRORR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## S_RORR, S_BODY, _shiftRORR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, , _immediate, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## SI, S_BODY, _immediate, BODY)
#define DEFINE_ALU_INSTRUCTION_S_ONLY_ARM(NAME, S_BODY, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSL, S_BODY, _shiftLSL, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSLR, S_BODY, _shiftLSLR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSR, S_BODY, _shiftLSR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _LSRR, S_BODY, _shiftLSRR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ASR, S_BODY, _shiftASR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ASRR, S_BODY, _shiftASRR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _ROR, S_BODY, _shiftROR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## _RORR, S_BODY, _shiftRORR, BODY) \
DEFINE_ALU_INSTRUCTION_EX_ARM(NAME ## I, S_BODY, _immediate, BODY)
#define DEFINE_MULTIPLY_INSTRUCTION_EX_ARM(NAME, BODY, S_BODY) \

View File

@ -16,6 +16,7 @@ bool GBAContextInit(struct GBAContext* context, const char* port) {
context->rom = 0;
context->save = 0;
context->renderer = 0;
memset(context->components, 0, sizeof(context->components));
if (!context->gba || !context->cpu) {
if (context->gba) {
@ -33,7 +34,7 @@ bool GBAContextInit(struct GBAContext* context, const char* port) {
}
GBACreate(context->gba);
ARMSetComponents(context->cpu, &context->gba->d, 0, 0);
ARMSetComponents(context->cpu, &context->gba->d, 0, context->components);
ARMInit(context->cpu);
context->gba->sync = 0;

View File

@ -18,6 +18,7 @@ struct GBAContext {
struct VFile* rom;
struct VFile* save;
struct VFile* bios;
struct ARMComponent* components[GBA_COMPONENT_MAX];
struct GBAConfig config;
struct GBAOptions opts;
struct GBAInputMap inputMap;

35
src/util/gui.h Normal file
View File

@ -0,0 +1,35 @@
/* 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 "util/common.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,
};
struct GUIParams {
int width;
int height;
const struct GUIFont* font;
void (*drawStart)(void);
void (*drawEnd)(void);
int (*pollInput)(void);
};
#endif

128
src/util/gui/file-select.c Normal file
View File

@ -0,0 +1,128 @@
/* 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/. */
#include "file-select.h"
#include "util/gui/font.h"
#include "util/vector.h"
#include "util/vfs.h"
DECLARE_VECTOR(FileList, char*);
DEFINE_VECTOR(FileList, char*);
void _cleanFiles(struct FileList* currentFiles) {
size_t size = FileListSize(currentFiles);
size_t i;
for (i = 0; i < size; ++i) {
free(*FileListGetPointer(currentFiles, i));
}
FileListClear(currentFiles);
}
void _upDirectory(char* currentPath) {
char* end = strrchr(currentPath, '/');
if (!end) {
return;
}
end[0] = '\0';
if (end[1]) {
return;
}
// TODO: What if there was a trailing slash?
}
bool _refreshDirectory(const char* currentPath, struct FileList* currentFiles) {
_cleanFiles(currentFiles);
struct VDir* dir = VDirOpen(currentPath);
if (!dir) {
return false;
}
struct VDirEntry* de;
while ((de = dir->listNext(dir))) {
if (de->name(de)[0] == '.') {
continue;
}
*FileListAppend(currentFiles) = strdup(de->name(de));
}
dir->close(dir);
return true;
}
bool selectFile(const struct GUIParams* params, const char* basePath, char* outPath, size_t outLen, const char* suffix) {
char currentPath[256];
strncpy(currentPath, basePath, sizeof(currentPath));
int oldInput = -1;
size_t fileIndex = 0;
size_t start = 0;
struct FileList currentFiles;
FileListInit(&currentFiles, 0);
_refreshDirectory(currentPath, &currentFiles);
while (true) {
int input = params->pollInput();
int newInput = input & (oldInput ^ input);
oldInput = input;
if (newInput & (1 << GUI_INPUT_UP) && fileIndex > 0) {
--fileIndex;
}
if (newInput & (1 << GUI_INPUT_DOWN) && fileIndex < FileListSize(&currentFiles) - 1) {
++fileIndex;
}
if (fileIndex < start) {
start = fileIndex;
}
while ((fileIndex - start + 4) * GUIFontHeight(params->font) > params->height) {
++start;
}
if (newInput & (1 << GUI_INPUT_CANCEL)) {
_cleanFiles(&currentFiles);
FileListDeinit(&currentFiles);
return false;
}
if (newInput & (1 << GUI_INPUT_SELECT)) {
snprintf(currentPath, sizeof(currentPath), "%s%c%s", currentPath, '/', *FileListGetPointer(&currentFiles, fileIndex));
if (!_refreshDirectory(currentPath, &currentFiles)) {
strncpy(outPath, currentPath, outLen);
return true;
}
fileIndex = 0;
}
if (newInput & (1 << GUI_INPUT_BACK)) {
if (strncmp(currentPath, basePath, sizeof(currentPath)) == 0) {
_cleanFiles(&currentFiles);
FileListDeinit(&currentFiles);
return false;
}
_upDirectory(currentPath);
_refreshDirectory(currentPath, &currentFiles);
fileIndex = 0;
}
params->drawStart();
int y = GUIFontHeight(params->font);
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, 0xFFFFFFFF, "Current directory: %s", currentPath);
y += 2 * GUIFontHeight(params->font);
size_t i;
for (i = start; i < FileListSize(&currentFiles); ++i) {
int color = 0xE0A0A0A0;
char bullet = ' ';
if (i == fileIndex) {
color = 0xFFFFFFFF;
bullet = '>';
}
GUIFontPrintf(params->font, 0, y, GUI_TEXT_LEFT, color, "%c %s", bullet, *FileListGetPointer(&currentFiles, i));
y += GUIFontHeight(params->font);
if (y + GUIFontHeight(params->font) > params->height) {
break;
}
}
y += GUIFontHeight(params->font) * 2;
params->drawEnd();
}
}

View File

@ -0,0 +1,13 @@
/* 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 "util/gui.h"
bool selectFile(const struct GUIParams*, const char* basePath, char* outPath, size_t outLen, const char* suffix);
#endif

137
src/util/gui/font-metrics.c Normal file
View File

@ -0,0 +1,137 @@
/* 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/. */
#include "util/gui/font.h"
struct GUIFontGlyphMetric defaultFontMetrics[128] = {
{ 0, 0, { 0, 0, 0, 0 }}, // 0x00
{ 0, 0, { 0, 0, 0, 0 }}, // 0x01
{ 0, 0, { 0, 0, 0, 0 }}, // 0x02
{ 0, 0, { 0, 0, 0, 0 }}, // 0x03
{ 0, 0, { 0, 0, 0, 0 }}, // 0x04
{ 0, 0, { 0, 0, 0, 0 }}, // 0x05
{ 0, 0, { 0, 0, 0, 0 }}, // 0x06
{ 0, 0, { 0, 0, 0, 0 }}, // 0x07
{ 0, 0, { 0, 0, 0, 0 }}, // 0x08
{ 0, 0, { 0, 0, 0, 0 }}, // 0x09
{ 0, 0, { 0, 0, 0, 0 }}, // 0x0A
{ 0, 0, { 0, 0, 0, 0 }}, // 0x0B
{ 0, 0, { 0, 0, 0, 0 }}, // 0x0C
{ 0, 0, { 0, 0, 0, 0 }}, // 0x0D
{ 0, 0, { 0, 0, 0, 0 }}, // 0x0E
{ 0, 0, { 0, 0, 0, 0 }}, // 0x0F
{ 0, 0, { 0, 0, 0, 0 }}, // 0x10
{ 0, 0, { 0, 0, 0, 0 }}, // 0x11
{ 0, 0, { 0, 0, 0, 0 }}, // 0x12
{ 0, 0, { 0, 0, 0, 0 }}, // 0x13
{ 0, 0, { 0, 0, 0, 0 }}, // 0x14
{ 0, 0, { 0, 0, 0, 0 }}, // 0x15
{ 0, 0, { 0, 0, 0, 0 }}, // 0x16
{ 0, 0, { 0, 0, 0, 0 }}, // 0x17
{ 0, 0, { 0, 0, 0, 0 }}, // 0x18
{ 0, 0, { 0, 0, 0, 0 }}, // 0x19
{ 0, 0, { 0, 0, 0, 0 }}, // 0x1A
{ 0, 0, { 0, 0, 0, 0 }}, // 0x1B
{ 0, 0, { 0, 0, 0, 0 }}, // 0x1C
{ 0, 0, { 0, 0, 0, 0 }}, // 0x1D
{ 0, 0, { 0, 0, 0, 0 }}, // 0x1E
{ 0, 0, { 0, 0, 0, 0 }}, // 0x1F
{ 8, 1, { 0, 0, 0, 0 }}, // 0x20 " "
{ 10, 11, { 2, 3, 3, 3 }}, // 0x21 "!"
{ 10, 5, { 2, 3, 9, 3 }}, // 0x22 """
{ 12, 11, { 2, 2, 3, 2 }}, // 0x23 "#"
{ 10, 13, { 1, 3, 2, 3 }}, // 0x24 "&"
{ 14, 11, { 2, 1, 3, 1 }}, // 0x25 "%"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x26 "&"
{ 4, 5, { 2, 6, 9, 6 }}, // 0x27 "'"
{ 6, 11, { 2, 5, 3, 5 }}, // 0x28 "("
{ 6, 11, { 2, 5, 3, 5 }}, // 0x29 ")"
{ 8, 7, { 2, 4, 5, 4 }}, // 0x2A "*"
{ 10, 9, { 3, 0, 4, 0 }}, // 0x2B "+"
{ 4, 5, { 9, 6, 2, 6 }}, // 0x2C ","
{ 6, 3, { 6, 4, 7, 4 }}, // 0x2D "-"
{ 4, 4, { 9, 6, 3, 6 }}, // 0x2E "."
{ 8, 11, { 2, 4, 3, 4 }}, // 0x2F "/"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x30 "0"
{ 10, 11, { 2, 4, 3, 4 }}, // 0x31 "1"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x32 "2"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x33 "3"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x34 "4"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x35 "5"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x36 "6"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x37 "7"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x38 "8"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x39 "9"
{ 4, 11, { 2, 6, 3, 6 }}, // 0x3A ":"
{ 4, 12, { 2, 6, 2, 6 }}, // 0x3B ";"
{ 8, 11, { 2, 4, 3, 4 }}, // 0x3C "<"
{ 10, 7, { 4, 3, 5, 3 }}, // 0x3D "="
{ 8, 11, { 2, 4, 3, 4 }}, // 0x3E ">"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x3F "?"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x40 "@"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x41 "A"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x42 "B"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x43 "C"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x44 "D"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x45 "E"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x46 "F"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x47 "G"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x48 "H"
{ 6, 11, { 2, 5, 3, 5 }}, // 0x49 "I"
{ 7, 11, { 2, 5, 3, 4 }}, // 0x4A "J"
{ 9, 11, { 2, 3, 3, 4 }}, // 0x4B "K"
{ 8, 11, { 2, 4, 3, 4 }}, // 0x4C "L"
{ 11, 11, { 2, 3, 3, 2 }}, // 0x4D "M"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x4E "N"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x4F "O"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x50 "P"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x51 "Q"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x52 "R"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x53 "S"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x54 "T"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x55 "U"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x56 "V"
{ 11, 11, { 2, 3, 3, 2 }}, // 0x57 "W"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x58 "X"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x59 "Y"
{ 10, 11, { 2, 3, 3, 3 }}, // 0x5A "Z"
{ 6, 11, { 2, 5, 3, 5 }}, // 0x5B "["
{ 8, 11, { 2, 4, 3, 4 }}, // 0x5C "\"
{ 6, 11, { 2, 5, 3, 5 }}, // 0x5D "]"
{ 8, 7, { 2, 4, 7, 4 }}, // 0x5E "^"
{ 10, 3, { 10, 3, 3, 3 }}, // 0x5F "_"
{ 6, 5, { 8, 6, 3, 4 }}, // 0x60 "`"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x61 "a"
{ 8, 11, { 2, 4, 3, 4 }}, // 0x62 "b"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x63 "c"
{ 8, 11, { 2, 4, 3, 4 }}, // 0x64 "d"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x65 "e"
{ 7, 11, { 2, 5, 3, 4 }}, // 0x66 "f"
{ 8, 9, { 6, 4, 1, 4 }}, // 0x67 "g"
{ 8, 11, { 2, 4, 3, 4 }}, // 0x68 "h"
{ 6, 11, { 2, 5, 3, 5 }}, // 0x69 "i"
{ 7, 13, { 2, 5, 1, 4 }}, // 0x6A "j"
{ 8, 11, { 2, 4, 3, 4 }}, // 0x6B "k"
{ 5, 11, { 2, 5, 3, 6 }}, // 0x6C "l"
{ 10, 7, { 6, 2, 3, 2 }}, // 0x6D "m"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x6E "n"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x6F "o"
{ 8, 9, { 6, 4, 1, 4 }}, // 0x70 "p"
{ 8, 9, { 6, 4, 1, 4 }}, // 0x71 "q"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x72 "r"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x73 "s"
{ 8, 9, { 4, 4, 3, 4 }}, // 0x74 "t"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x75 "u"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x76 "v"
{ 9, 7, { 6, 4, 3, 3 }}, // 0x77 "w"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x78 "x"
{ 8, 9, { 6, 4, 1, 4 }}, // 0x79 "y"
{ 8, 7, { 6, 4, 3, 4 }}, // 0x7A "z"
{ 7, 11, { 2, 5, 3, 4 }}, // 0x7B "{"
{ 4, 11, { 2, 6, 3, 6 }}, // 0x7C "|"
{ 7, 11, { 2, 4, 3, 5 }}, // 0x7D "}"
{ 10, 5, { 5, 3, 6, 3 }}, // 0x7E "}"
{ 0, 0, { 0, 0, 0, 0 }}, // 0x7F
};

View File

@ -0,0 +1,13 @@
/* 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 "util/gui/font.h"
extern struct GUIFontGlyphMetric defaultFontMetrics[];
#endif

36
src/util/gui/font.h Normal file
View File

@ -0,0 +1,36 @@
/* 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 "util/common.h"
struct GUIFont;
struct GUIFont* GUIFontCreate(void);
void GUIFontDestroy(struct GUIFont*);
enum GUITextAlignment {
GUI_TEXT_LEFT = 0,
GUI_TEXT_CENTER,
GUI_TEXT_RIGHT
};
struct GUIFontGlyphMetric {
int width;
int height;
struct {
int top;
int right;
int bottom;
int left;
} padding;
};
int GUIFontHeight(const struct GUIFont*);
void GUIFontPrintf(const struct GUIFont*, int x, int y, enum GUITextAlignment, uint32_t color, const char* text, ...);
#endif