all repos — mgba @ 0affe7c8d70db3631b5a567926caa459a1e30192

mGBA Game Boy Advance Emulator

Merge branch 'master' into port/3ds
Jeffrey Pfau jeffrey@endrift.com
Sun, 23 Aug 2015 07:21:23 -0700
commit

0affe7c8d70db3631b5a567926caa459a1e30192

parent

ca42faae3c397fb480966637ba99bdda85e7a644

M CHANGESCHANGES

@@ -10,6 +10,7 @@ - Qt: Window size command line options are now supported

- 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:
M CMakeLists.txtCMakeLists.txt

@@ -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)
M src/arm/decoder-arm.csrc/arm/decoder-arm.c

@@ -11,18 +11,16 @@ #include "isa-inlines.h"

#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) \

@@ -38,11 +36,6 @@ ADDR_MODE_1_SHIFT(ROR) \

if (!info->op3.shifterImm) { \ 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; \

@@ -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) \
M src/arm/emitter-arm.hsrc/arm/emitter-arm.h

@@ -17,13 +17,13 @@ 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 ## _LSLR), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \ DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \ - DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSRR), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \ 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 ## _RORR), \ + DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _ROR), \ DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSL), \ DECLARE_INSTRUCTION_ARM(EMITTER, EX1), \ DECLARE_INSTRUCTION_ARM(EMITTER, ALU ## _LSR), \
M src/arm/isa-arm.csrc/arm/isa-arm.c

@@ -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; - } 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; + 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 = 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; - } 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; + 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->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 @@

#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) \
M src/gba/supervisor/context.csrc/gba/supervisor/context.c

@@ -16,6 +16,7 @@ context->cpu = anonymousMemoryMap(sizeof(struct ARMCore));

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 @@ GBAConfigLoad(&context->config);

} 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;
M src/gba/supervisor/context.hsrc/gba/supervisor/context.h

@@ -18,6 +18,7 @@ struct GBAVideoRenderer* renderer;

struct VFile* rom; struct VFile* save; struct VFile* bios; + struct ARMComponent* components[GBA_COMPONENT_MAX]; struct GBAConfig config; struct GBAOptions opts; struct GBAInputMap inputMap;
A src/util/gui.h

@@ -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
A src/util/gui/file-select.c

@@ -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(); + } +}
A src/util/gui/file-select.h

@@ -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
A src/util/gui/font-metrics.c

@@ -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 +};
A src/util/gui/font-metrics.h

@@ -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
A src/util/gui/font.h

@@ -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