summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp199
-rw-r--r--src/core/arm/dyncom/arm_dyncom_run.h12
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h8
-rw-r--r--src/core/arm/interpreter/armsupp.cpp20
-rw-r--r--src/core/arm/skyeye_common/armdefs.h5
-rw-r--r--src/core/arm/skyeye_common/armemu.h6
-rw-r--r--src/core/arm/skyeye_common/skyeye_types.h30
-rw-r--r--src/core/core.cpp4
-rw-r--r--src/core/core.h2
-rw-r--r--src/core/file_sys/disk_archive.cpp11
-rw-r--r--src/core/file_sys/disk_archive.h6
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp11
-rw-r--r--src/core/hle/kernel/mutex.cpp4
-rw-r--r--src/core/hle/service/apt_a.cpp4
-rw-r--r--src/core/hle/service/cfg/cfg_u.cpp6
-rw-r--r--src/core/hle/service/csnd_snd.cpp13
-rw-r--r--src/core/hle/service/dsp_dsp.cpp22
-rw-r--r--src/core/hle/service/dsp_dsp.h3
-rw-r--r--src/core/hle/service/ir_rst.cpp7
-rw-r--r--src/core/hle/service/ldr_ro.cpp12
-rw-r--r--src/core/hle/service/ndm_u.cpp11
-rw-r--r--src/core/hle/service/service.cpp2
-rw-r--r--src/core/hle/service/soc_u.cpp8
-rw-r--r--src/core/hle/service/srv.cpp16
-rw-r--r--src/core/hle/service/y2r_u.cpp45
-rw-r--r--src/core/hle/service/y2r_u.h23
-rw-r--r--src/core/hw/gpu.cpp8
-rw-r--r--src/core/loader/loader.cpp2
29 files changed, 369 insertions, 133 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index addcb953c..b67226d8d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -66,6 +66,7 @@ set(SRCS
hle/service/soc_u.cpp
hle/service/srv.cpp
hle/service/ssl_c.cpp
+ hle/service/y2r_u.cpp
hle/config_mem.cpp
hle/hle.cpp
hle/svc.cpp
@@ -157,6 +158,7 @@ set(HEADERS
hle/service/soc_u.h
hle/service/srv.h
hle/service/ssl_c.h
+ hle/service/y2r_u.h
hle/config_mem.h
hle/result.h
hle/function_wrappers.h
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index ba23ef383..9b291862c 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -1083,7 +1083,7 @@ typedef struct _cdp_inst {
unsigned int cp_num;
unsigned int opcode_2;
unsigned int CRm;
- uint32 inst;
+ unsigned int inst;
}cdp_inst;
typedef struct _uxtb_inst {
@@ -1423,15 +1423,19 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(bx)(unsigned int inst, int index)
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(bx_inst));
bx_inst *inst_cream = (bx_inst *)inst_base->component;
- inst_base->cond = BITS(inst, 28, 31);
- inst_base->idx = index;
- inst_base->br = INDIRECT_BRANCH;
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = INDIRECT_BRANCH;
- inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rm = BITS(inst, 0, 3);
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("BXJ"); }
+ARM_INST_PTR INTERPRETER_TRANSLATE(bxj)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(bx)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(cdp)(unsigned int inst, int index){
arm_inst *inst_base = (arm_inst *)AllocBuffer(sizeof(arm_inst) + sizeof(cdp_inst));
cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -2057,7 +2061,37 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(pld)(unsigned int inst, int index)
return inst_base;
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QADD"); }
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(qadd)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->op1 = BITS(inst, 21, 22);
+ inst_cream->Rm = BITS(inst, 0, 3);
+ inst_cream->Rn = BITS(inst, 16, 19);
+ inst_cream->Rd = BITS(inst, 12, 15);
+
+ return inst_base;
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index)
+{
+ return INTERPRETER_TRANSLATE(qadd)(inst, index);
+}
+
ARM_INST_PTR INTERPRETER_TRANSLATE(qadd8)(unsigned int inst, int index)
{
arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(generic_arm_inst));
@@ -2084,9 +2118,6 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(qaddsubx)(unsigned int inst, int index)
{
return INTERPRETER_TRANSLATE(qadd8)(inst, index);
}
-ARM_INST_PTR INTERPRETER_TRANSLATE(qdadd)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDADD"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(qdsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QDSUB"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(qsub)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("QSUB"); }
ARM_INST_PTR INTERPRETER_TRANSLATE(qsub8)(unsigned int inst, int index)
{
return INTERPRETER_TRANSLATE(qadd8)(inst, index);
@@ -2373,7 +2404,25 @@ ARM_INST_PTR INTERPRETER_TRANSLATE(smlal)(unsigned int inst, int index)
}
ARM_INST_PTR INTERPRETER_TRANSLATE(smlalxy)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLALXY"); }
-ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index) { UNIMPLEMENTED_INSTRUCTION("SMLAW"); }
+
+ARM_INST_PTR INTERPRETER_TRANSLATE(smlaw)(unsigned int inst, int index)
+{
+ arm_inst* const inst_base = (arm_inst*)AllocBuffer(sizeof(arm_inst) + sizeof(smlad_inst));
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ inst_base->cond = BITS(inst, 28, 31);
+ inst_base->idx = index;
+ inst_base->br = NON_BRANCH;
+ inst_base->load_r15 = 0;
+
+ inst_cream->Ra = BITS(inst, 12, 15);
+ inst_cream->Rm = BITS(inst, 8, 11);
+ inst_cream->Rn = BITS(inst, 0, 3);
+ inst_cream->Rd = BITS(inst, 16, 19);
+ inst_cream->m = BIT(inst, 6);
+
+ return inst_base;
+}
ARM_INST_PTR INTERPRETER_TRANSLATE(smlald)(unsigned int inst, int index)
{
@@ -3444,7 +3493,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size);
if(ret == t_branch){
// TODO: FIXME, endian should be judged
- uint32 tinstr;
+ u32 tinstr;
if((addr & 0x3) != 0)
tinstr = inst >> 16;
else
@@ -3457,7 +3506,7 @@ static tdstate decode_thumb_instr(arm_processor *cpu, uint32_t inst, addr_t addr
case 26:
case 27:
if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
- uint32 cond = (tinstr & 0x0F00) >> 8;
+ u32 cond = (tinstr & 0x0F00) >> 8;
inst_index = table_length - 4;
*ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
} else {
@@ -4088,22 +4137,35 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
INC_PC(sizeof(blx_inst));
goto DISPATCH;
}
+
BX_INST:
+ BXJ_INST:
{
- bx_inst *inst_cream = (bx_inst *)inst_base->component;
- if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) {
+ // Note that only the 'fail' case of BXJ is emulated. This is because
+ // the facilities for Jazelle emulation are not implemented.
+ //
+ // According to the ARM documentation on BXJ, if setting the J bit in the APSR
+ // fails, then BXJ functions identically like a regular BX instruction.
+ //
+ // This is sufficient for citra, as the CPU for the 3DS does not implement Jazelle.
+
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ bx_inst* const inst_cream = (bx_inst*)inst_base->component;
+
if (inst_cream->Rm == 15)
LOG_WARNING(Core_ARM11, "BX at pc %x: use of Rm = R15 is discouraged", cpu->Reg[15]);
+
cpu->TFlag = cpu->Reg[inst_cream->Rm] & 0x1;
cpu->Reg[15] = cpu->Reg[inst_cream->Rm] & 0xfffffffe;
INC_PC(sizeof(bx_inst));
goto DISPATCH;
}
+
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(bx_inst));
goto DISPATCH;
}
- BXJ_INST:
+
CDP_INST:
{
cdp_inst *inst_cream = (cdp_inst *)inst_base->component;
@@ -5027,6 +5089,78 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
QADD_INST:
+ QDADD_INST:
+ QDSUB_INST:
+ QSUB_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ generic_arm_inst* const inst_cream = (generic_arm_inst*)inst_base->component;
+ const u8 op1 = inst_cream->op1;
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+
+ u32 result = 0;
+
+ // QADD
+ if (op1 == 0x00) {
+ result = rm_val + rn_val;
+
+ if (AddOverflow(rm_val, rn_val, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QSUB
+ else if (op1 == 0x01) {
+ result = rm_val - rn_val;
+
+ if (SubOverflow(rm_val, rn_val, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QDADD
+ else if (op1 == 0x02) {
+ u32 mul = (rn_val * 2);
+
+ if (AddOverflow(rn_val, rn_val, rn_val * 2)) {
+ mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+
+ result = mul + rm_val;
+
+ if (AddOverflow(rm_val, mul, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+ // QDSUB
+ else if (op1 == 0x03) {
+ u32 mul = (rn_val * 2);
+
+ if (AddOverflow(rn_val, rn_val, mul)) {
+ mul = POS(mul) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+
+ result = rm_val - mul;
+
+ if (SubOverflow(rm_val, mul, result)) {
+ result = POS(result) ? 0x80000000 : 0x7FFFFFFF;
+ cpu->Cpsr |= (1 << 27);
+ }
+ }
+
+ RD = result;
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(generic_arm_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
+
QADD8_INST:
QADD16_INST:
QADDSUBX_INST:
@@ -5089,10 +5223,6 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
GOTO_NEXT_INST;
}
- QDADD_INST:
- QDSUB_INST:
- QSUB_INST:
-
REV_INST:
REV16_INST:
REVSH_INST:
@@ -5461,7 +5591,8 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
operand2 = (BIT(RS, 31)) ? (BITS(RS, 16, 31) | 0xffff0000) : BITS(RS, 16, 31);
RD = operand1 * operand2 + RN;
- // TODO: FIXME: UPDATE Q FLAGS
+ if (AddOverflow(operand1 * operand2, RN, RD))
+ cpu->Cpsr |= (1 << 27);
}
cpu->Reg[15] += GET_INST_SIZE(cpu);
INC_PC(sizeof(smla_inst));
@@ -5555,7 +5686,31 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
}
SMLALXY_INST:
+
SMLAW_INST:
+ {
+ if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
+ smlad_inst* const inst_cream = (smlad_inst*)inst_base->component;
+
+ const u32 rm_val = RM;
+ const u32 rn_val = RN;
+ const u32 ra_val = cpu->Reg[inst_cream->Ra];
+ const bool high = (inst_cream->m == 1);
+
+ const s16 operand2 = (high) ? ((rm_val >> 16) & 0xFFFF) : (rm_val & 0xFFFF);
+ const s64 result = (s64)(s32)rn_val * (s64)(s32)operand2 + ((s64)(s32)ra_val << 16);
+
+ RD = (result & (0xFFFFFFFFFFFFFFFFLL >> 15)) >> 16;
+
+ if ((result >> 16) != (s32)RD)
+ cpu->Cpsr |= (1 << 27);
+ }
+
+ cpu->Reg[15] += GET_INST_SIZE(cpu);
+ INC_PC(sizeof(smlad_inst));
+ FETCH_INST;
+ GOTO_NEXT_INST;
+ }
SMLALD_INST:
SMLSLD_INST:
@@ -6585,7 +6740,7 @@ unsigned InterpreterMainLoop(ARMul_State* state) {
BLX_1_THUMB:
{
// BLX 1 for armv5t and above
- uint32 tmp = cpu->Reg[15];
+ u32 tmp = cpu->Reg[15];
blx_1_thumb *inst_cream = (blx_1_thumb *)inst_base->component;
cpu->Reg[15] = (cpu->Reg[14] + inst_cream->imm) & 0xFFFFFFFC;
cpu->Reg[14] = ((tmp + 2) | 1);
diff --git a/src/core/arm/dyncom/arm_dyncom_run.h b/src/core/arm/dyncom/arm_dyncom_run.h
index aeabeac16..c70522274 100644
--- a/src/core/arm/dyncom/arm_dyncom_run.h
+++ b/src/core/arm/dyncom/arm_dyncom_run.h
@@ -24,8 +24,8 @@
void switch_mode(arm_core_t *core, uint32_t mode);
/* FIXME, we temporarily think thumb instruction is always 16 bit */
-static inline uint32 GET_INST_SIZE(arm_core_t* core){
- return core->TFlag? 2 : 4;
+static inline u32 GET_INST_SIZE(arm_core_t* core) {
+ return core->TFlag? 2 : 4;
}
/**
@@ -36,8 +36,8 @@ static inline uint32 GET_INST_SIZE(arm_core_t* core){
*
* @return
*/
-static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
- return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn) {
+ return (Rn == 15)? ((core->Reg[15] & ~0x3) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
}
/**
@@ -48,8 +48,8 @@ static inline addr_t CHECK_READ_REG15_WA(arm_core_t* core, int Rn){
*
* @return
*/
-static inline uint32 CHECK_READ_REG15(arm_core_t* core, int Rn){
- return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
+static inline u32 CHECK_READ_REG15(arm_core_t* core, int Rn) {
+ return (Rn == 15)? ((core->Reg[15] & ~0x1) + GET_INST_SIZE(core) * 2) : core->Reg[Rn];
}
#endif
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index 5541de9d1..bf69b2fd4 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -37,10 +37,10 @@ enum tdstate {
t_uninitialized,
};
-tdstate
-thumb_translate(addr_t addr, uint32_t instr, uint32_t* ainstr, uint32_t* inst_size);
-static inline uint32 get_thumb_instr(uint32 instr, addr_t pc){
- uint32 tinstr;
+tdstate thumb_translate(addr_t addr, u32 instr, u32* ainstr, u32* inst_size);
+
+static inline u32 get_thumb_instr(u32 instr, addr_t pc) {
+ u32 tinstr;
if ((pc & 0x3) != 0)
tinstr = instr >> 16;
else
diff --git a/src/core/arm/interpreter/armsupp.cpp b/src/core/arm/interpreter/armsupp.cpp
index eec34143e..68ac2a0ce 100644
--- a/src/core/arm/interpreter/armsupp.cpp
+++ b/src/core/arm/interpreter/armsupp.cpp
@@ -418,22 +418,18 @@ ARMul_NegZero (ARMul_State * state, ARMword result)
}
}
-/* Compute whether an addition of A and B, giving RESULT, overflowed. */
-
-int
-AddOverflow (ARMword a, ARMword b, ARMword result)
+// Compute whether an addition of A and B, giving RESULT, overflowed.
+bool AddOverflow(ARMword a, ARMword b, ARMword result)
{
- return ((NEG (a) && NEG (b) && POS (result))
- || (POS (a) && POS (b) && NEG (result)));
+ return ((NEG(a) && NEG(b) && POS(result)) ||
+ (POS(a) && POS(b) && NEG(result)));
}
-/* Compute whether a subtraction of A and B, giving RESULT, overflowed. */
-
-int
-SubOverflow (ARMword a, ARMword b, ARMword result)
+// Compute whether a subtraction of A and B, giving RESULT, overflowed.
+bool SubOverflow(ARMword a, ARMword b, ARMword result)
{
- return ((NEG (a) && POS (b) && POS (result))
- || (POS (a) && NEG (b) && NEG (result)));
+ return ((NEG(a) && POS(b) && POS(result)) ||
+ (POS(a) && NEG(b) && NEG(result)));
}
/* Assigns the C flag after an addition of a and b to give result. */
diff --git a/src/core/arm/skyeye_common/armdefs.h b/src/core/arm/skyeye_common/armdefs.h
index 4592c5808..1b2cef451 100644
--- a/src/core/arm/skyeye_common/armdefs.h
+++ b/src/core/arm/skyeye_common/armdefs.h
@@ -70,6 +70,9 @@
#define DATACACHE 1
#define INSTCACHE 2
+#define POS(i) ( (~(i)) >> 31 )
+#define NEG(i) ( (i) >> 31 )
+
#ifndef __STDC__
typedef char *VoidStar;
#endif
@@ -783,6 +786,8 @@ RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
//#define PXA250 0x69052903
// 0x69052903; //PXA250 B1 from intel 278522-001.pdf
+extern bool AddOverflow(ARMword, ARMword, ARMword);
+extern bool SubOverflow(ARMword, ARMword, ARMword);
extern void ARMul_UndefInstr(ARMul_State*, ARMword);
extern void ARMul_FixCPSR(ARMul_State*, ARMword, ARMword);
diff --git a/src/core/arm/skyeye_common/armemu.h b/src/core/arm/skyeye_common/armemu.h
index e1b286f0f..1dfcc635a 100644
--- a/src/core/arm/skyeye_common/armemu.h
+++ b/src/core/arm/skyeye_common/armemu.h
@@ -42,9 +42,6 @@
#define R15FBIT (1L << 26)
#define R15IFBITS (3L << 26)
-#define POS(i) ( (~(i)) >> 31 )
-#define NEG(i) ( (i) >> 31 )
-
#ifdef MODET /* Thumb support. */
/* ??? This bit is actually in the low order bit of the PC in the hardware.
It isn't clear if the simulator needs to model that or not. */
@@ -561,8 +558,7 @@ tdstate;
/* Prototypes for exported functions. */
extern unsigned ARMul_NthReg (ARMword, unsigned);
-extern int AddOverflow (ARMword, ARMword, ARMword);
-extern int SubOverflow (ARMword, ARMword, ARMword);
+
/* Prototypes for exported functions. */
#ifdef __cplusplus
extern "C" {
diff --git a/src/core/arm/skyeye_common/skyeye_types.h b/src/core/arm/skyeye_common/skyeye_types.h
index e7f022f19..fc7d8d922 100644
--- a/src/core/arm/skyeye_common/skyeye_types.h
+++ b/src/core/arm/skyeye_common/skyeye_types.h
@@ -22,34 +22,10 @@
* 12/16/2006 Michael.Kang <blackfin.kang@gmail.com>
*/
-#ifndef __SKYEYE_TYPES_H
-#define __SKYEYE_TYPES_H
+#pragma once
-#include <stdint.h>
-
-/*default machine word length */
-
-#ifndef __BEOS__
-/* To avoid the type conflict with the qemu */
-#ifndef QEMU
-typedef uint8_t uint8;
-typedef uint16_t uint16;
-typedef uint32_t uint32;
-typedef uint64_t uint64;
-
-typedef int8_t sint8;
-typedef int16_t sint16;
-typedef int32_t sint32;
-typedef int64_t sint64;
-#endif
+#include <cstdint>
typedef uint32_t address_t;
-typedef uint32_t uinteger_t;
-typedef int32_t integer_t;
-
typedef uint32_t physical_address_t;
-typedef uint32_t generic_address_t;
-
-#endif
-
-#endif
+typedef uint32_t generic_address_t;
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 22213d647..8ac4481cc 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -53,10 +53,10 @@ int Init() {
g_sys_core = new ARM_Interpreter();
switch (Settings::values.cpu_core) {
- case CPU_FastInterpreter:
+ case CPU_Interpreter:
g_app_core = new ARM_DynCom();
break;
- case CPU_Interpreter:
+ case CPU_OldInterpreter:
default:
g_app_core = new ARM_Interpreter();
break;
diff --git a/src/core/core.h b/src/core/core.h
index 05dbe0ae5..ecd58a73a 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -13,7 +13,7 @@ namespace Core {
enum CPUCore {
CPU_Interpreter,
- CPU_FastInterpreter
+ CPU_OldInterpreter,
};
extern ARM_Interface* g_app_core; ///< ARM11 application core
diff --git a/src/core/file_sys/disk_archive.cpp b/src/core/file_sys/disk_archive.cpp
index 0197f727d..c6e033fcd 100644
--- a/src/core/file_sys/disk_archive.cpp
+++ b/src/core/file_sys/disk_archive.cpp
@@ -6,6 +6,7 @@
#include "common/common_types.h"
#include "common/file_util.h"
+#include "common/make_unique.h"
#include "core/file_sys/disk_archive.h"
#include "core/settings.h"
@@ -17,10 +18,10 @@ namespace FileSys {
std::unique_ptr<FileBackend> DiskArchive::OpenFile(const Path& path, const Mode mode) const {
LOG_DEBUG(Service_FS, "called path=%s mode=%01X", path.DebugStr().c_str(), mode.hex);
- DiskFile* file = new DiskFile(this, path, mode);
+ auto file = Common::make_unique<DiskFile>(this, path, mode);
if (!file->Open())
return nullptr;
- return std::unique_ptr<FileBackend>(file);
+ return std::move(file);
}
bool DiskArchive::DeleteFile(const Path& path) const {
@@ -66,10 +67,10 @@ bool DiskArchive::RenameDirectory(const Path& src_path, const Path& dest_path) c
std::unique_ptr<DirectoryBackend> DiskArchive::OpenDirectory(const Path& path) const {
LOG_DEBUG(Service_FS, "called path=%s", path.DebugStr().c_str());
- DiskDirectory* directory = new DiskDirectory(this, path);
+ auto directory = Common::make_unique<DiskDirectory>(this, path);
if (!directory->Open())
return nullptr;
- return std::unique_ptr<DirectoryBackend>(directory);
+ return std::move(directory);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -100,7 +101,7 @@ bool DiskFile::Open() {
// Open the file in binary mode, to avoid problems with CR/LF on Windows systems
mode_string += "b";
- file = new FileUtil::IOFile(path, mode_string.c_str());
+ file = Common::make_unique<FileUtil::IOFile>(path, mode_string.c_str());
return true;
}
diff --git a/src/core/file_sys/disk_archive.h b/src/core/file_sys/disk_archive.h
index f18d96f5a..3472f6874 100644
--- a/src/core/file_sys/disk_archive.h
+++ b/src/core/file_sys/disk_archive.h
@@ -56,10 +56,6 @@ public:
DiskFile();
DiskFile(const DiskArchive* archive, const Path& path, const Mode mode);
- ~DiskFile() override {
- Close();
- }
-
bool Open() override;
size_t Read(const u64 offset, const u32 length, u8* buffer) const override;
size_t Write(const u64 offset, const u32 length, const u32 flush, const u8* buffer) const override;
@@ -75,7 +71,7 @@ protected:
const DiskArchive* archive;
std::string path;
Mode mode;
- FileUtil::IOFile* file;
+ std::unique_ptr<FileUtil::IOFile> file;
};
class DiskDirectory : public DirectoryBackend {
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 38705e3cd..736bbc36a 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -51,6 +51,17 @@ ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s3
HLE::Reschedule(__func__);
}
break;
+
+ case ArbitrationType::DecrementAndWaitIfLessThan:
+ {
+ s32 memory_value = Memory::Read32(address) - 1;
+ Memory::Write32(address, memory_value);
+ if (memory_value <= value) {
+ Kernel::WaitCurrentThread(WAITTYPE_ARB, handle, address);
+ HLE::Reschedule(__func__);
+ }
+ break;
+ }
default:
LOG_ERROR(Kernel, "unknown type=%d", type);
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 558068c79..3dfeffc9b 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -168,9 +168,9 @@ Handle CreateMutex(bool initial_locked, const std::string& name) {
ResultVal<bool> Mutex::WaitSynchronization() {
bool wait = locked;
if (locked) {
+ waiting_threads.push_back(GetCurrentThreadHandle());
Kernel::WaitCurrentThread(WAITTYPE_MUTEX, GetHandle());
- }
- else {
+ } else {
// Lock the mutex when the first thread accesses it
locked = true;
MutexAcquireLock(this);
diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp
index 4b0f761d9..37be4b027 100644
--- a/src/core/hle/service/apt_a.cpp
+++ b/src/core/hle/service/apt_a.cpp
@@ -25,12 +25,12 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00040040, nullptr, "Finalize?"},
{0x00050040, nullptr, "GetAppletManInfo?"},
{0x00060040, nullptr, "GetAppletInfo?"},
+ {0x000D0080, APT_U::ReceiveParameter, "ReceiveParameter?"},
+ {0x000E0080, APT_U::GlanceParameter, "GlanceParameter?"},
{0x003B0040, nullptr, "CancelLibraryApplet?"},
{0x00430040, nullptr, "NotifyToWait?"},
{0x004B00C2, nullptr, "AppletUtility?"},
{0x00550040, nullptr, "WriteInputToNsState?"},
- {0x000D0080, APT_U::ReceiveParameter, "ReceiveParameter" },
- {0x000E0080, APT_U::GlanceParameter, "GlanceParameter" },
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp
index 03c01cf90..835620909 100644
--- a/src/core/hle/service/cfg/cfg_u.cpp
+++ b/src/core/hle/service/cfg/cfg_u.cpp
@@ -172,12 +172,12 @@ static void GetModelNintendo2DS(Service::Interface* self) {
const Interface::FunctionInfo FunctionTable[] = {
{0x00010082, GetConfigInfoBlk2, "GetConfigInfoBlk2"},
{0x00020000, nullptr, "SecureInfoGetRegion"},
- {0x00030000, nullptr, "GenHashConsoleUnique"},
+ {0x00030040, nullptr, "GenHashConsoleUnique"},
{0x00040000, nullptr, "GetRegionCanadaUSA"},
{0x00050000, GetSystemModel, "GetSystemModel"},
{0x00060000, GetModelNintendo2DS, "GetModelNintendo2DS"},
- {0x00070040, nullptr, "unknown"},
- {0x00080080, nullptr, "unknown"},
+ {0x00070040, nullptr, "WriteToFirstByteCfgSavegame"},
+ {0x00080080, nullptr, "GoThroughTable"},
{0x00090040, GetCountryCodeString, "GetCountryCodeString"},
{0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
};
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp
index aef8cfbca..3a557efe1 100644
--- a/src/core/hle/service/csnd_snd.cpp
+++ b/src/core/hle/service/csnd_snd.cpp
@@ -14,16 +14,15 @@ namespace CSND_SND {
const Interface::FunctionInfo FunctionTable[] = {
{0x00010140, nullptr, "Initialize"},
{0x00020000, nullptr, "Shutdown"},
- {0x00030040, nullptr, "Unknown"},
- {0x00040080, nullptr, "Unknown"},
- {0x00050000, nullptr, "Unknown"},
- {0x00060000, nullptr, "Unknown"},
- {0x00070000, nullptr, "Unknown"},
- {0x00080040, nullptr, "Unknown"},
+ {0x00030040, nullptr, "ExecuteType0Commands"},
+ {0x00040080, nullptr, "ExecuteType1Commands"},
+ {0x00050000, nullptr, "AcquireSoundChannels"},
+ {0x00060000, nullptr, "ReleaseSoundChannels"},
+ {0x00070000, nullptr, "AcquireCaptureDevice"},
+ {0x00080040, nullptr, "ReleaseCaptureDevice"},
{0x00090082, nullptr, "FlushDCache"},
{0x000A0082, nullptr, "StoreDCache"},
{0x000B0082, nullptr, "InvalidateDCache"},
- {0x000C0000, nullptr, "Unknown"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp
index 2cf4d118f..d4affdfbf 100644
--- a/src/core/hle/service/dsp_dsp.cpp
+++ b/src/core/hle/service/dsp_dsp.cpp
@@ -12,9 +12,23 @@
namespace DSP_DSP {
-static u32 read_pipe_count;
-static Handle semaphore_event;
-static Handle interrupt_event;
+static u32 read_pipe_count = 0;
+static Handle semaphore_event = 0;
+static Handle interrupt_event = 0;
+
+void SignalInterrupt() {
+ // TODO(bunnei): This is just a stub, it does not do anything other than signal to the emulated
+ // application that a DSP interrupt occurred, without specifying which one. Since we do not
+ // emulate the DSP yet (and how it works is largely unknown), this is a work around to get games
+ // that check the DSP interrupt signal event to run. We should figure out the different types of
+ // DSP interrupts, and trigger them at the appropriate times.
+
+ if (interrupt_event == 0) {
+ LOG_WARNING(Service_DSP, "cannot signal interrupt until DSP event has been created!");
+ return;
+ }
+ Kernel::SignalEvent(interrupt_event);
+}
/**
* DSP_DSP::ConvertProcessAddressFromDspDram service function
@@ -102,7 +116,7 @@ void RegisterInterruptEvents(Service::Interface* self) {
void WriteReg0x10(Service::Interface* self) {
u32* cmd_buff = Kernel::GetCommandBuffer();
- Kernel::SignalEvent(interrupt_event);
+ SignalInterrupt();
cmd_buff[1] = 0; // No error
diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h
index 0b8b64600..fa13bfb7c 100644
--- a/src/core/hle/service/dsp_dsp.h
+++ b/src/core/hle/service/dsp_dsp.h
@@ -20,4 +20,7 @@ public:
}
};
+/// Signals that a DSP interrupt has occurred to userland code
+void SignalInterrupt();
+
} // namespace
diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp
index b388afb15..d49bd5335 100644
--- a/src/core/hle/service/ir_rst.cpp
+++ b/src/core/hle/service/ir_rst.cpp
@@ -15,12 +15,7 @@ const Interface::FunctionInfo FunctionTable[] = {
{0x00010000, nullptr, "GetHandles"},
{0x00020080, nullptr, "Initialize"},
{0x00030000, nullptr, "Shutdown"},
- {0x00040000, nullptr, "Unknown"},
- {0x00050000, nullptr, "Unknown"},
- {0x00060000, nullptr, "Unknown"},
- {0x00070080, nullptr, "Unknown"},
- {0x00080000, nullptr, "Unknown"},
- {0x00090000, nullptr, "Unknown"},
+ {0x00090000, nullptr, "WriteToTwoFields"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp
index 9c9e90a40..7d6e2e8e8 100644
--- a/src/core/hle/service/ldr_ro.cpp
+++ b/src/core/hle/service/ldr_ro.cpp
@@ -13,10 +13,14 @@ namespace LDR_RO {
const Interface::FunctionInfo FunctionTable[] = {
{0x000100C2, nullptr, "Initialize"},
- {0x00020082, nullptr, "CRR_Load"},
- {0x00030042, nullptr, "CRR_Unload"},
- {0x000402C2, nullptr, "CRO_LoadAndFix"},
- {0x000500C2, nullptr, "CRO_ApplyRelocationPatchesAndLink"}
+ {0x00020082, nullptr, "LoadCRR"},
+ {0x00030042, nullptr, "UnloadCCR"},
+ {0x000402C2, nullptr, "LoadExeCRO"},
+ {0x000500C2, nullptr, "LoadCROSymbols"},
+ {0x00060042, nullptr, "CRO_Load?"},
+ {0x00070042, nullptr, "LoadCROSymbols"},
+ {0x00080042, nullptr, "Shutdown"},
+ {0x000902C2, nullptr, "LoadExeCRO_New?"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp
index 233b14f6d..0f03de6ae 100644
--- a/src/core/hle/service/ndm_u.cpp
+++ b/src/core/hle/service/ndm_u.cpp
@@ -11,10 +11,13 @@
namespace NDM_U {
const Interface::FunctionInfo FunctionTable[] = {
- {0x00060040, nullptr, "SuspendDaemons"},
- {0x00080040, nullptr, "DisableWifiUsage"},
- {0x00090000, nullptr, "EnableWifiUsage"},
- {0x00140040, nullptr, "OverrideDefaultDaemons"},
+ {0x00010042, nullptr, "EnterExclusiveState"},
+ {0x00020002, nullptr, "LeaveExclusiveState"},
+ {0x00030000, nullptr, "QueryExclusiveMode"},
+ {0x00060040, nullptr, "SuspendDaemons"},
+ {0x00080040, nullptr, "DisableWifiUsage"},
+ {0x00090000, nullptr, "EnableWifiUsage"},
+ {0x00140040, nullptr, "OverrideDefaultDaemons"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0f3cc2aa8..c5233e687 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -37,6 +37,7 @@
#include "core/hle/service/soc_u.h"
#include "core/hle/service/srv.h"
#include "core/hle/service/ssl_c.h"
+#include "core/hle/service/y2r_u.h"
namespace Service {
@@ -122,6 +123,7 @@ void Init() {
g_manager->AddService(new PTM_U::Interface);
g_manager->AddService(new SOC_U::Interface);
g_manager->AddService(new SSL_C::Interface);
+ g_manager->AddService(new Y2R_U::Interface);
LOG_DEBUG(Service, "initialized OK");
}
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index 8e7abcf9c..f502c6afe 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -308,11 +308,11 @@ static void Socket(Service::Interface* self) {
u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol));
- if (socket_handle != SOCKET_ERROR_VALUE)
+ if ((s32)socket_handle != SOCKET_ERROR_VALUE)
open_sockets[socket_handle] = { socket_handle, true };
int result = 0;
- if (socket_handle == SOCKET_ERROR_VALUE)
+ if ((s32)socket_handle == SOCKET_ERROR_VALUE)
result = TranslateError(GET_ERRNO);
cmd_buffer[1] = result;
@@ -436,11 +436,11 @@ static void Accept(Service::Interface* self) {
socklen_t addr_len = sizeof(addr);
u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
- if (ret != SOCKET_ERROR_VALUE)
+ if ((s32)ret != SOCKET_ERROR_VALUE)
open_sockets[ret] = { ret, true };
int result = 0;
- if (ret == SOCKET_ERROR_VALUE) {
+ if ((s32)ret == SOCKET_ERROR_VALUE) {
result = TranslateError(GET_ERRNO);
} else {
CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr);
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 25fab1a4f..912b52adf 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -52,13 +52,15 @@ static void GetServiceHandle(Service::Interface* self) {
}
const Interface::FunctionInfo FunctionTable[] = {
- {0x00010002, Initialize, "Initialize"},
- {0x00020000, GetProcSemaphore, "GetProcSemaphore"},
- {0x00030100, nullptr, "RegisterService"},
- {0x000400C0, nullptr, "UnregisterService"},
- {0x00050100, GetServiceHandle, "GetServiceHandle"},
- {0x000B0000, nullptr, "ReceiveNotification"},
- {0x000C0080, nullptr, "PublishToSubscriber"}
+ {0x00010002, Initialize, "Initialize"},
+ {0x00020000, GetProcSemaphore, "GetProcSemaphore"},
+ {0x00030100, nullptr, "RegisterService"},
+ {0x000400C0, nullptr, "UnregisterService"},
+ {0x00050100, GetServiceHandle, "GetServiceHandle"},
+ {0x000600C2, nullptr, "RegisterHandle"},
+ {0x00090040, nullptr, "Subscribe"},
+ {0x000B0000, nullptr, "ReceiveNotification"},
+ {0x000C0080, nullptr, "PublishToSubscriber"},
};
////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp
new file mode 100644
index 000000000..f9e3619dd
--- /dev/null
+++ b/src/core/hle/service/y2r_u.cpp
@@ -0,0 +1,45 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/log.h"
+#include "core/hle/hle.h"
+#include "core/hle/kernel/event.h"
+#include "core/hle/service/y2r_u.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Y2R_U
+
+namespace Y2R_U {
+
+const Interface::FunctionInfo FunctionTable[] = {
+ {0x00010040, nullptr, "SetInputFormat"},
+ {0x00030040, nullptr, "SetOutputFormat"},
+ {0x00050040, nullptr, "SetRotation"},
+ {0x00070040, nullptr, "SetBlockAlignment"},
+ {0x000D0040, nullptr, "SetTransferEndInterrupt"},
+ {0x000F0000, nullptr, "GetTransferEndEvent"},
+ {0x00100102, nullptr, "SetSendingY"},
+ {0x00110102, nullptr, "SetSendingU"},
+ {0x00120102, nullptr, "SetSendingV"},
+ {0x00180102, nullptr, "SetReceiving"},
+ {0x001A0040, nullptr, "SetInputLineWidth"},
+ {0x001C0040, nullptr, "SetInputLines"},
+ {0x00200040, nullptr, "SetStandardCoefficient"},
+ {0x00220040, nullptr, "SetAlpha"},
+ {0x00260000, nullptr, "StartConversion"},
+ {0x00270000, nullptr, "StopConversion"},
+ {0x00280000, nullptr, "IsBusyConversion"},
+ {0x002A0000, nullptr, "PingProcess"},
+ {0x002B0000, nullptr, "DriverInitialize"},
+ {0x002C0000, nullptr, "DriverFinalize"}
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Interface class
+
+Interface::Interface() {
+ Register(FunctionTable, ARRAY_SIZE(FunctionTable));
+}
+
+} // namespace
diff --git a/src/core/hle/service/y2r_u.h b/src/core/hle/service/y2r_u.h
new file mode 100644
index 000000000..171aecfd1
--- /dev/null
+++ b/src/core/hle/service/y2r_u.h
@@ -0,0 +1,23 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include "core/hle/service/service.h"
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// Namespace Y2R_U
+
+namespace Y2R_U {
+
+class Interface : public Service::Interface {
+public:
+ Interface();
+
+ std::string GetPortName() const override {
+ return "y2r:u";
+ }
+};
+
+} // namespace
diff --git a/src/core/hw/gpu.cpp b/src/core/hw/gpu.cpp
index 0ff6c6cde..e346e0ad6 100644
--- a/src/core/hw/gpu.cpp
+++ b/src/core/hw/gpu.cpp
@@ -10,6 +10,7 @@
#include "core/hle/hle.h"
#include "core/hle/service/gsp_gpu.h"
+#include "core/hle/service/dsp_dsp.h"
#include "core/hw/gpu.h"
@@ -214,13 +215,18 @@ void Update() {
// - If frameskip == 0 (disabled), always swap buffers
// - If frameskip == 1, swap buffers every other frame (starting from the first frame)
// - If frameskip > 1, swap buffers every frameskip^n frames (starting from the second frame)
-
if ((((Settings::values.frame_skip != 1) ^ last_skip_frame) && last_skip_frame != g_skip_frame) ||
Settings::values.frame_skip == 0) {
VideoCore::g_renderer->SwapBuffers();
}
+ // Signal to GSP that GPU interrupt has occurred
GSP_GPU::SignalInterrupt(GSP_GPU::InterruptId::PDC1);
+
+ // TODO(bunnei): Fake a DSP interrupt on each frame. This does not belong here, but
+ // until we can emulate DSP interrupts, this is probably the only reasonable place to do
+ // this. Certain games expect this to be periodically signaled.
+ DSP_DSP::SignalInterrupt();
}
}
}
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 87580cb2a..45cf425df 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -45,6 +45,8 @@ FileType IdentifyFile(const std::string &filename) {
return FileType::CCI;
} else if (extension == ".bin") {
return FileType::BIN;
+ } else if (extension == ".3ds") {
+ return FileType::CCI;
} else if (extension == ".3dsx") {
return FileType::THREEDSX;
}