summaryrefslogtreecommitdiff
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/interpreter/armemu.cpp241
-rw-r--r--src/core/file_sys/archive_savedata.h3
-rw-r--r--src/core/file_sys/archive_systemsavedata.cpp33
-rw-r--r--src/core/file_sys/archive_systemsavedata.h33
-rw-r--r--src/core/hle/kernel/shared_memory.h14
-rw-r--r--src/core/hle/service/fs/archive.cpp9
-rw-r--r--src/core/hle/service/gsp_gpu.cpp26
-rw-r--r--src/core/hle/svc.cpp4
9 files changed, 272 insertions, 93 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index f71232c1a..3381524e3 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -20,6 +20,7 @@ set(SRCS
20 file_sys/archive_romfs.cpp 20 file_sys/archive_romfs.cpp
21 file_sys/archive_savedata.cpp 21 file_sys/archive_savedata.cpp
22 file_sys/archive_sdmc.cpp 22 file_sys/archive_sdmc.cpp
23 file_sys/archive_systemsavedata.cpp
23 file_sys/disk_archive.cpp 24 file_sys/disk_archive.cpp
24 file_sys/file_romfs.cpp 25 file_sys/file_romfs.cpp
25 file_sys/directory_romfs.cpp 26 file_sys/directory_romfs.cpp
@@ -101,6 +102,7 @@ set(HEADERS
101 file_sys/archive_romfs.h 102 file_sys/archive_romfs.h
102 file_sys/archive_savedata.h 103 file_sys/archive_savedata.h
103 file_sys/archive_sdmc.h 104 file_sys/archive_sdmc.h
105 file_sys/archive_systemsavedata.h
104 file_sys/disk_archive.h 106 file_sys/disk_archive.h
105 file_sys/file_backend.h 107 file_sys/file_backend.h
106 file_sys/file_romfs.h 108 file_sys/file_romfs.h
diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 1a589e39c..63cfd03c6 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -1356,7 +1356,13 @@ mainswitch:
1356 } 1356 }
1357 break; 1357 break;
1358 1358
1359 case 0x04: /* SUB reg */ 1359 case 0x04: /* SUB reg */
1360 // Signifies UMAAL
1361 if (state->is_v6 && BITS(4, 7) == 0x09) {
1362 if (handle_v6_insn(state, instr))
1363 break;
1364 }
1365
1360#ifdef MODET 1366#ifdef MODET
1361 if (BITS (4, 7) == 0xB) { 1367 if (BITS (4, 7) == 0xB) {
1362 /* STRH immediate offset, no write-back, down, post indexed. */ 1368 /* STRH immediate offset, no write-back, down, post indexed. */
@@ -3103,12 +3109,18 @@ mainswitch:
3103 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000); 3109 state->Reg[idest] = (state->Reg[rfis] & 0xFFFF) | ((state->Reg[rlast] << ishi) & 0xFFFF0000);
3104 break; 3110 break;
3105 } else if ((instr & 0x70) == 0x50) { //pkhtb 3111 } else if ((instr & 0x70) == 0x50) { //pkhtb
3106 u8 idest = BITS(12, 15); 3112 const u8 rd_idx = BITS(12, 15);
3107 u8 rfis = BITS(16, 19); 3113 const u8 rn_idx = BITS(16, 19);
3108 u8 rlast = BITS(0, 3); 3114 const u8 rm_idx = BITS(0, 3);
3109 u8 ishi = BITS(7, 11); 3115 const u8 imm5 = BITS(7, 11);
3110 if (ishi == 0)ishi = 0x20; 3116
3111 state->Reg[idest] = (((int)(state->Reg[rlast]) >> (int)(ishi))& 0xFFFF) | ((state->Reg[rfis]) & 0xFFFF0000); 3117 ARMword val;
3118 if (imm5 >= 32)
3119 val = (state->Reg[rm_idx] >> 31);
3120 else
3121 val = (state->Reg[rm_idx] >> imm5);
3122
3123 state->Reg[rd_idx] = (val & 0xFFFF) | ((state->Reg[rn_idx]) & 0xFFFF0000);
3112 break; 3124 break;
3113 } else if (BIT (4)) { 3125 } else if (BIT (4)) {
3114#ifdef MODE32 3126#ifdef MODE32
@@ -5669,16 +5681,29 @@ L_stm_s_takeabort:
5669 /* Attempt to emulate an ARMv6 instruction. 5681 /* Attempt to emulate an ARMv6 instruction.
5670 Returns non-zero upon success. */ 5682 Returns non-zero upon success. */
5671 5683
5672 static int 5684 static int handle_v6_insn(ARMul_State* state, ARMword instr) {
5673 handle_v6_insn (ARMul_State * state, ARMword instr) { 5685 switch (BITS(20, 27)) {
5674 ARMword lhs, temp;
5675
5676 switch (BITS (20, 27)) {
5677 case 0x03: 5686 case 0x03:
5678 printf ("Unhandled v6 insn: ldr\n"); 5687 printf ("Unhandled v6 insn: ldr\n");
5679 break; 5688 break;
5680 case 0x04: 5689 case 0x04: // UMAAL
5681 printf ("Unhandled v6 insn: umaal\n"); 5690 {
5691 const u8 rm_idx = BITS(8, 11);
5692 const u8 rn_idx = BITS(0, 3);
5693 const u8 rd_lo_idx = BITS(12, 15);
5694 const u8 rd_hi_idx = BITS(16, 19);
5695
5696 const u32 rm_val = state->Reg[rm_idx];
5697 const u32 rn_val = state->Reg[rn_idx];
5698 const u32 rd_lo_val = state->Reg[rd_lo_idx];
5699 const u32 rd_hi_val = state->Reg[rd_hi_idx];
5700
5701 const u64 result = (rn_val * rm_val) + rd_lo_val + rd_hi_val;
5702
5703 state->Reg[rd_lo_idx] = (result & 0xFFFFFFFF);
5704 state->Reg[rd_hi_idx] = ((result >> 32) & 0xFFFFFFFF);
5705 return 1;
5706 }
5682 break; 5707 break;
5683 case 0x06: 5708 case 0x06:
5684 printf ("Unhandled v6 insn: mls/str\n"); 5709 printf ("Unhandled v6 insn: mls/str\n");
@@ -5691,7 +5716,7 @@ L_stm_s_takeabort:
5691 /* strex */ 5716 /* strex */
5692 u32 l = LHSReg; 5717 u32 l = LHSReg;
5693 u32 r = RHSReg; 5718 u32 r = RHSReg;
5694 lhs = LHS; 5719 u32 lhs = LHS;
5695 5720
5696 bool enter = false; 5721 bool enter = false;
5697 5722
@@ -5716,7 +5741,7 @@ L_stm_s_takeabort:
5716 case 0x19: 5741 case 0x19:
5717 /* ldrex */ 5742 /* ldrex */
5718 if (BITS(4, 7) == 0x9) { 5743 if (BITS(4, 7) == 0x9) {
5719 lhs = LHS; 5744 u32 lhs = LHS;
5720 5745
5721 state->currentexaddr = lhs; 5746 state->currentexaddr = lhs;
5722 state->currentexval = ARMul_ReadWord(state, lhs); 5747 state->currentexval = ARMul_ReadWord(state, lhs);
@@ -5735,7 +5760,7 @@ L_stm_s_takeabort:
5735 case 0x1c: 5760 case 0x1c:
5736 if (BITS(4, 7) == 0x9) { 5761 if (BITS(4, 7) == 0x9) {
5737 /* strexb */ 5762 /* strexb */
5738 lhs = LHS; 5763 u32 lhs = LHS;
5739 5764
5740 bool enter = false; 5765 bool enter = false;
5741 5766
@@ -5765,11 +5790,11 @@ L_stm_s_takeabort:
5765 case 0x1d: 5790 case 0x1d:
5766 if ((BITS(4, 7)) == 0x9) { 5791 if ((BITS(4, 7)) == 0x9) {
5767 /* ldrexb */ 5792 /* ldrexb */
5768 temp = LHS; 5793 u32 lhs = LHS;
5769 LoadByte(state, instr, temp, LUNSIGNED); 5794 LoadByte(state, instr, lhs, LUNSIGNED);
5770 5795
5771 state->currentexaddr = temp; 5796 state->currentexaddr = lhs;
5772 state->currentexval = (u32)ARMul_ReadByte(state, temp); 5797 state->currentexval = (u32)ARMul_ReadByte(state, lhs);
5773 5798
5774 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]); 5799 //state->Reg[BITS(12, 15)] = ARMul_LoadByte(state, state->Reg[BITS(16, 19)]);
5775 //printf("ldrexb\n"); 5800 //printf("ldrexb\n");
@@ -5799,49 +5824,63 @@ L_stm_s_takeabort:
5799 case 0x3f: 5824 case 0x3f:
5800 printf ("Unhandled v6 insn: rbit\n"); 5825 printf ("Unhandled v6 insn: rbit\n");
5801 break; 5826 break;
5802 case 0x61: 5827 case 0x61: // SSUB16, SADD16, SSAX, and SASX
5803 if ((instr & 0xFF0) == 0xf70) { //ssub16 5828 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10 ||
5804 u8 tar = BITS(12, 15); 5829 (instr & 0xFF0) == 0xf50 || (instr & 0xFF0) == 0xf30)
5805 u8 src1 = BITS(16, 19); 5830 {
5806 u8 src2 = BITS(0, 3);
5807 s16 a1 = (state->Reg[src1] & 0xFFFF);
5808 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF);
5809 s16 b1 = (state->Reg[src2] & 0xFFFF);
5810 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF);
5811 state->Reg[tar] = ((a1 - a2) & 0xFFFF) | (((b1 - b2) & 0xFFFF) << 0x10);
5812 return 1;
5813 } else if ((instr & 0xFF0) == 0xf10) { //sadd16
5814 const u8 rd_idx = BITS(12, 15); 5831 const u8 rd_idx = BITS(12, 15);
5815 const u8 rm_idx = BITS(0, 3); 5832 const u8 rm_idx = BITS(0, 3);
5816 const u8 rn_idx = BITS(16, 19); 5833 const u8 rn_idx = BITS(16, 19);
5817 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5818 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5819 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF); 5834 const s16 rn_lo = (state->Reg[rn_idx] & 0xFFFF);
5820 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF); 5835 const s16 rn_hi = ((state->Reg[rn_idx] >> 16) & 0xFFFF);
5836 const s16 rm_lo = (state->Reg[rm_idx] & 0xFFFF);
5837 const s16 rm_hi = ((state->Reg[rm_idx] >> 16) & 0xFFFF);
5821 5838
5822 state->Reg[rd_idx] = ((rn_lo + rm_lo) & 0xFFFF) | (((rn_hi + rm_hi) & 0xFFFF) << 16); 5839 s32 lo_result;
5823 return 1; 5840 s32 hi_result;
5824 } else if ((instr & 0xFF0) == 0xf50) { //ssax 5841
5825 u8 tar = BITS(12, 15); 5842 // SSUB16
5826 u8 src1 = BITS(16, 19); 5843 if ((instr & 0xFF0) == 0xf70) {
5827 u8 src2 = BITS(0, 3); 5844 lo_result = (rn_lo - rm_lo);
5828 s16 a1 = (state->Reg[src1] & 0xFFFF); 5845 hi_result = (rn_hi - rm_hi);
5829 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5846 }
5830 s16 b1 = (state->Reg[src2] & 0xFFFF); 5847 // SADD16
5831 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5848 else if ((instr & 0xFF0) == 0xf10) {
5832 state->Reg[tar] = ((a1 + b2) & 0xFFFF) | (((a2 - b1) & 0xFFFF) << 0x10); 5849 lo_result = (rn_lo + rm_lo);
5833 return 1; 5850 hi_result = (rn_hi + rm_hi);
5834 } else if ((instr & 0xFF0) == 0xf30) { //sasx 5851 }
5835 u8 tar = BITS(12, 15); 5852 // SSAX
5836 u8 src1 = BITS(16, 19); 5853 else if ((instr & 0xFF0) == 0xf50) {
5837 u8 src2 = BITS(0, 3); 5854 lo_result = (rn_lo + rm_hi);
5838 s16 a1 = (state->Reg[src1] & 0xFFFF); 5855 hi_result = (rn_hi - rm_lo);
5839 s16 a2 = ((state->Reg[src1] >> 0x10) & 0xFFFF); 5856 }
5840 s16 b1 = (state->Reg[src2] & 0xFFFF); 5857 // SASX
5841 s16 b2 = ((state->Reg[src2] >> 0x10) & 0xFFFF); 5858 else {
5842 state->Reg[tar] = ((a1 - b2) & 0xFFFF) | (((a2 + b1) & 0xFFFF) << 0x10); 5859 lo_result = (rn_lo - rm_hi);
5860 hi_result = (rn_hi + rm_lo);
5861 }
5862
5863 state->Reg[rd_idx] = (lo_result & 0xFFFF) | ((hi_result & 0xFFFF) << 16);
5864
5865 if (lo_result >= 0) {
5866 state->Cpsr |= (1 << 16);
5867 state->Cpsr |= (1 << 17);
5868 } else {
5869 state->Cpsr &= ~(1 << 16);
5870 state->Cpsr &= ~(1 << 17);
5871 }
5872
5873 if (hi_result >= 0) {
5874 state->Cpsr |= (1 << 18);
5875 state->Cpsr |= (1 << 19);
5876 } else {
5877 state->Cpsr &= ~(1 << 18);
5878 state->Cpsr &= ~(1 << 19);
5879 }
5843 return 1; 5880 return 1;
5844 } else printf ("Unhandled v6 insn: sadd/ssub/ssax/sasx\n"); 5881 } else {
5882 printf("Unhandled v6 insn: %08x", BITS(20, 27));
5883 }
5845 break; 5884 break;
5846 case 0x62: // QSUB16 and QADD16 5885 case 0x62: // QSUB16 and QADD16
5847 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) { 5886 if ((instr & 0xFF0) == 0xf70 || (instr & 0xFF0) == 0xf10) {
@@ -5930,11 +5969,29 @@ L_stm_s_takeabort:
5930 b2 = ((u8)(from >> 8) + (u8)(to >> 8)); 5969 b2 = ((u8)(from >> 8) + (u8)(to >> 8));
5931 b3 = ((u8)(from >> 16) + (u8)(to >> 16)); 5970 b3 = ((u8)(from >> 16) + (u8)(to >> 16));
5932 b4 = ((u8)(from >> 24) + (u8)(to >> 24)); 5971 b4 = ((u8)(from >> 24) + (u8)(to >> 24));
5933 if (b1 & 0xffffff00) state->Cpsr |= (1 << 16); 5972
5934 if (b2 & 0xffffff00) state->Cpsr |= (1 << 17); 5973 if (b1 & 0xffffff00)
5935 if (b3 & 0xffffff00) state->Cpsr |= (1 << 18); 5974 state->Cpsr |= (1 << 16);
5936 if (b4 & 0xffffff00) state->Cpsr |= (1 << 19); 5975 else
5976 state->Cpsr &= ~(1 << 16);
5977
5978 if (b2 & 0xffffff00)
5979 state->Cpsr |= (1 << 17);
5980 else
5981 state->Cpsr &= ~(1 << 17);
5982
5983 if (b3 & 0xffffff00)
5984 state->Cpsr |= (1 << 18);
5985 else
5986 state->Cpsr &= ~(1 << 18);
5987
5988
5989 if (b4 & 0xffffff00)
5990 state->Cpsr |= (1 << 19);
5991 else
5992 state->Cpsr &= ~(1 << 19);
5937 } 5993 }
5994
5938 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24); 5995 state->Reg[rd] = (u32)(b1 | (b2 & 0xff) << 8 | (b3 & 0xff) << 16 | (b4 & 0xff) << 24);
5939 return 1; 5996 return 1;
5940 } 5997 }
@@ -6049,7 +6106,7 @@ L_stm_s_takeabort:
6049 break; 6106 break;
6050 } 6107 }
6051 6108
6052 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); 6109 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF);
6053 if (Rm & 0x80) 6110 if (Rm & 0x80)
6054 Rm |= 0xffffff00; 6111 Rm |= 0xffffff00;
6055 6112
@@ -6058,11 +6115,12 @@ L_stm_s_takeabort:
6058 state->Reg[BITS(12, 15)] = Rm; 6115 state->Reg[BITS(12, 15)] = Rm;
6059 else 6116 else
6060 /* SXTAB */ 6117 /* SXTAB */
6061 state->Reg[BITS(12, 15)] += Rm; 6118 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6062 6119
6063 return 1; 6120 return 1;
6064 } 6121 }
6065 case 0x6b: { 6122 case 0x6b:
6123 {
6066 ARMword Rm; 6124 ARMword Rm;
6067 int ror = -1; 6125 int ror = -1;
6068 6126
@@ -6080,10 +6138,10 @@ L_stm_s_takeabort:
6080 ror = 24; 6138 ror = 24;
6081 break; 6139 break;
6082 6140
6083 case 0xf3: 6141 case 0xf3: // REV
6084 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24); 6142 DEST = ((RHS & 0xFF) << 24) | ((RHS & 0xFF00)) << 8 | ((RHS & 0xFF0000) >> 8) | ((RHS & 0xFF000000) >> 24);
6085 return 1; 6143 return 1;
6086 case 0xfb: 6144 case 0xfb: // REV16
6087 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8); 6145 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00)) >> 8 | ((RHS & 0xFF0000) << 8) | ((RHS & 0xFF000000) >> 8);
6088 return 1; 6146 return 1;
6089 default: 6147 default:
@@ -6093,7 +6151,7 @@ L_stm_s_takeabort:
6093 if (ror == -1) 6151 if (ror == -1)
6094 break; 6152 break;
6095 6153
6096 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); 6154 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
6097 if (Rm & 0x8000) 6155 if (Rm & 0x8000)
6098 Rm |= 0xffff0000; 6156 Rm |= 0xffff0000;
6099 6157
@@ -6156,18 +6214,27 @@ L_stm_s_takeabort:
6156 //ichfly 6214 //ichfly
6157 //USAT16 6215 //USAT16
6158 { 6216 {
6159 u8 tar = BITS(12, 15); 6217 const u8 rd_idx = BITS(12, 15);
6160 u8 src = BITS(0, 3); 6218 const u8 rn_idx = BITS(0, 3);
6161 u8 val = BITS(16, 19); 6219 const u8 num_bits = BITS(16, 19);
6162 s16 a1 = (state->Reg[src]); 6220 const s16 max = 0xFFFF >> (16 - num_bits);
6163 s16 a2 = (state->Reg[src] >> 0x10); 6221 s16 rn_lo = (state->Reg[rn_idx]);
6164 s16 max = 0xFFFF >> (16 - val); 6222 s16 rn_hi = (state->Reg[rn_idx] >> 16);
6165 if (max < a1) a1 = max; 6223
6166 if (max < a2) a2 = max; 6224 if (max < rn_lo)
6167 u32 temp2 = ((u32)(a2)) << 0x10; 6225 rn_lo = max;
6168 state->Reg[tar] = (a1 & 0xFFFF) | (temp2); 6226 else if (rn_lo < 0)
6227 rn_lo = 0;
6228
6229 if (max < rn_hi)
6230 rn_hi = max;
6231 else if (rn_hi < 0)
6232 rn_hi = 0;
6233
6234 state->Reg[rd_idx] = (rn_lo & 0xFFFF) | ((rn_hi << 16) & 0xFFFF);
6235 return 1;
6169 } 6236 }
6170 return 1; 6237
6171 default: 6238 default:
6172 break; 6239 break;
6173 } 6240 }
@@ -6180,7 +6247,7 @@ L_stm_s_takeabort:
6180 break; 6247 break;
6181 } 6248 }
6182 6249
6183 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF); 6250 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFF) & 0xFF);
6184 6251
6185 if (BITS(16, 19) == 0xf) 6252 if (BITS(16, 19) == 0xf)
6186 /* UXTB */ 6253 /* UXTB */
@@ -6210,9 +6277,13 @@ L_stm_s_takeabort:
6210 ror = 24; 6277 ror = 24;
6211 break; 6278 break;
6212 6279
6213 case 0xfb: 6280 case 0xfb: // REVSH
6214 printf("Unhandled v6 insn: revsh\n"); 6281 {
6215 return 0; 6282 DEST = ((RHS & 0xFF) << 8) | ((RHS & 0xFF00) >> 8);
6283 if (DEST & 0x8000)
6284 DEST |= 0xffff0000;
6285 return 1;
6286 }
6216 default: 6287 default:
6217 break; 6288 break;
6218 } 6289 }
@@ -6220,13 +6291,13 @@ L_stm_s_takeabort:
6220 if (ror == -1) 6291 if (ror == -1)
6221 break; 6292 break;
6222 6293
6223 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF); 6294 Rm = ((state->Reg[BITS(0, 3)] >> ror) & 0xFFFF) | (((state->Reg[BITS(0, 3)] << (32 - ror)) & 0xFFFF) & 0xFFFF);
6224 6295
6225 /* UXT */ 6296 /* UXT */
6226 /* state->Reg[BITS (12, 15)] = Rm; */ 6297 /* state->Reg[BITS (12, 15)] = Rm; */
6227 /* dyf add */ 6298 /* dyf add */
6228 if (BITS(16, 19) == 0xf) { 6299 if (BITS(16, 19) == 0xf) {
6229 state->Reg[BITS(12, 15)] = (Rm >> (8 * BITS(10, 11))) & 0x0000FFFF; 6300 state->Reg[BITS(12, 15)] = Rm;
6230 } 6301 }
6231 else { 6302 else {
6232 /* UXTAH */ 6303 /* UXTAH */
@@ -6234,7 +6305,7 @@ L_stm_s_takeabort:
6234 // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)] 6305 // printf("rd is %x rn is %x rm is %x rotate is %x\n", state->Reg[BITS (12, 15)], state->Reg[BITS (16, 19)]
6235 // , Rm, BITS(10, 11)); 6306 // , Rm, BITS(10, 11));
6236 // printf("icounter is %lld\n", state->NumInstrs); 6307 // printf("icounter is %lld\n", state->NumInstrs);
6237 state->Reg[BITS(12, 15)] = (state->Reg[BITS(16, 19)] >> (8 * (BITS(10, 11)))) + Rm; 6308 state->Reg[BITS(12, 15)] = state->Reg[BITS(16, 19)] + Rm;
6238 // printf("rd is %x\n", state->Reg[BITS (12, 15)]); 6309 // printf("rd is %x\n", state->Reg[BITS (12, 15)]);
6239 // exit(-1); 6310 // exit(-1);
6240 } 6311 }
diff --git a/src/core/file_sys/archive_savedata.h b/src/core/file_sys/archive_savedata.h
index b3e561130..d394ad37e 100644
--- a/src/core/file_sys/archive_savedata.h
+++ b/src/core/file_sys/archive_savedata.h
@@ -21,8 +21,7 @@ public:
21 21
22 /** 22 /**
23 * Initialize the archive. 23 * Initialize the archive.
24 * @return CreateSaveDataResult AlreadyExists if the SaveData folder already exists, 24 * @return true if it initialized successfully
25 * Success if it was created properly and Failure if there was any error
26 */ 25 */
27 bool Initialize(); 26 bool Initialize();
28 27
diff --git a/src/core/file_sys/archive_systemsavedata.cpp b/src/core/file_sys/archive_systemsavedata.cpp
new file mode 100644
index 000000000..dc2c23b41
--- /dev/null
+++ b/src/core/file_sys/archive_systemsavedata.cpp
@@ -0,0 +1,33 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#include <sys/stat.h>
6
7#include "common/common_types.h"
8#include "common/file_util.h"
9
10#include "core/file_sys/archive_systemsavedata.h"
11#include "core/file_sys/disk_archive.h"
12#include "core/settings.h"
13
14////////////////////////////////////////////////////////////////////////////////////////////////////
15// FileSys namespace
16
17namespace FileSys {
18
19Archive_SystemSaveData::Archive_SystemSaveData(const std::string& mount_point)
20 : DiskArchive(mount_point) {
21 LOG_INFO(Service_FS, "Directory %s set as SystemSaveData.", this->mount_point.c_str());
22}
23
24bool Archive_SystemSaveData::Initialize() {
25 if (!FileUtil::CreateFullPath(mount_point)) {
26 LOG_ERROR(Service_FS, "Unable to create SystemSaveData path.");
27 return false;
28 }
29
30 return true;
31}
32
33} // namespace FileSys
diff --git a/src/core/file_sys/archive_systemsavedata.h b/src/core/file_sys/archive_systemsavedata.h
new file mode 100644
index 000000000..360ed1e13
--- /dev/null
+++ b/src/core/file_sys/archive_systemsavedata.h
@@ -0,0 +1,33 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2+
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "common/common_types.h"
8
9#include "core/file_sys/disk_archive.h"
10#include "core/loader/loader.h"
11
12////////////////////////////////////////////////////////////////////////////////////////////////////
13// FileSys namespace
14
15namespace FileSys {
16
17/// File system interface to the SystemSaveData archive
18/// TODO(Subv): This archive should point to a location in the NAND,
19/// specifically nand:/data/<ID0>/sysdata/<SaveID-Low>/<SaveID-High>
20class Archive_SystemSaveData final : public DiskArchive {
21public:
22 Archive_SystemSaveData(const std::string& mount_point);
23
24 /**
25 * Initialize the archive.
26 * @return true if it initialized successfully
27 */
28 bool Initialize();
29
30 std::string GetName() const override { return "SystemSaveData"; }
31};
32
33} // namespace FileSys
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index 304cf5b67..bb778ec26 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -12,11 +12,15 @@ namespace Kernel {
12 12
13/// Permissions for mapped shared memory blocks 13/// Permissions for mapped shared memory blocks
14enum class MemoryPermission : u32 { 14enum class MemoryPermission : u32 {
15 None = 0, 15 None = 0,
16 Read = (1u << 0), 16 Read = (1u << 0),
17 Write = (1u << 1), 17 Write = (1u << 1),
18 ReadWrite = (Read | Write), 18 ReadWrite = (Read | Write),
19 DontCare = (1u << 28) 19 Execute = (1u << 2),
20 ReadExecute = (Read | Execute),
21 WriteExecute = (Write | Execute),
22 ReadWriteExecute = (Read | Write | Execute),
23 DontCare = (1u << 28)
20}; 24};
21 25
22/** 26/**
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index 9c3834733..5ab82729c 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -419,6 +419,15 @@ void ArchiveInit() {
419 CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC); 419 CreateArchive(std::move(sdmc_archive), ArchiveIdCode::SDMC);
420 else 420 else
421 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str()); 421 LOG_ERROR(Service_FS, "Can't instantiate SDMC archive with path %s", sdmc_directory.c_str());
422
423 std::string systemsavedata_directory = FileUtil::GetUserPath(D_SYSSAVEDATA_IDX);
424 auto systemsavedata_archive = std::make_unique<FileSys::Archive_SDMC>(systemsavedata_directory);
425 if (systemsavedata_archive->Initialize()) {
426 CreateArchive(std::move(systemsavedata_archive), ArchiveIdCode::SystemSaveData);
427 } else {
428 LOG_ERROR(Service_FS, "Can't instantiate SystemSaveData archive with path %s",
429 systemsavedata_directory.c_str());
430 }
422} 431}
423 432
424/// Shutdown archives 433/// Shutdown archives
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp
index db8027142..8c9ad2712 100644
--- a/src/core/hle/service/gsp_gpu.cpp
+++ b/src/core/hle/service/gsp_gpu.cpp
@@ -145,6 +145,30 @@ static void SetBufferSwap(Service::Interface* self) {
145} 145}
146 146
147/** 147/**
148 * GSP_GPU::FlushDataCache service function
149 *
150 * This Function is a no-op, We aren't emulating the CPU cache any time soon.
151 *
152 * Inputs:
153 * 1 : Address
154 * 2 : Size
155 * 3 : Value 0, some descriptor for the KProcess Handle
156 * 4 : KProcess handle
157 * Outputs:
158 * 1 : Result of function, 0 on success, otherwise error code
159 */
160static void FlushDataCache(Service::Interface* self) {
161 u32* cmd_buff = Kernel::GetCommandBuffer();
162 u32 address = cmd_buff[1];
163 u32 size = cmd_buff[2];
164 u32 process = cmd_buff[4];
165
166 // TODO(purpasmart96): Verify return header on HW
167
168 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
169}
170
171/**
148 * GSP_GPU::RegisterInterruptRelayQueue service function 172 * GSP_GPU::RegisterInterruptRelayQueue service function
149 * Inputs: 173 * Inputs:
150 * 1 : "Flags" field, purpose is unknown 174 * 1 : "Flags" field, purpose is unknown
@@ -335,7 +359,7 @@ const Interface::FunctionInfo FunctionTable[] = {
335 {0x00050200, SetBufferSwap, "SetBufferSwap"}, 359 {0x00050200, SetBufferSwap, "SetBufferSwap"},
336 {0x00060082, nullptr, "SetCommandList"}, 360 {0x00060082, nullptr, "SetCommandList"},
337 {0x000700C2, nullptr, "RequestDma"}, 361 {0x000700C2, nullptr, "RequestDma"},
338 {0x00080082, nullptr, "FlushDataCache"}, 362 {0x00080082, FlushDataCache, "FlushDataCache"},
339 {0x00090082, nullptr, "InvalidateDataCache"}, 363 {0x00090082, nullptr, "InvalidateDataCache"},
340 {0x000A0044, nullptr, "RegisterInterruptEvents"}, 364 {0x000A0044, nullptr, "RegisterInterruptEvents"},
341 {0x000B0040, nullptr, "SetLcdForceBlack"}, 365 {0x000B0040, nullptr, "SetLcdForceBlack"},
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 15cc240f4..47e9bf77e 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -64,6 +64,10 @@ static Result MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 other
64 case Kernel::MemoryPermission::Read: 64 case Kernel::MemoryPermission::Read:
65 case Kernel::MemoryPermission::Write: 65 case Kernel::MemoryPermission::Write:
66 case Kernel::MemoryPermission::ReadWrite: 66 case Kernel::MemoryPermission::ReadWrite:
67 case Kernel::MemoryPermission::Execute:
68 case Kernel::MemoryPermission::ReadExecute:
69 case Kernel::MemoryPermission::WriteExecute:
70 case Kernel::MemoryPermission::ReadWriteExecute:
67 case Kernel::MemoryPermission::DontCare: 71 case Kernel::MemoryPermission::DontCare:
68 Kernel::MapSharedMemory(handle, addr, permissions_type, 72 Kernel::MapSharedMemory(handle, addr, permissions_type,
69 static_cast<Kernel::MemoryPermission>(other_permissions)); 73 static_cast<Kernel::MemoryPermission>(other_permissions));