summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/citra/config.cpp36
-rw-r--r--src/citra/emu_window/emu_window_glfw.cpp29
-rw-r--r--src/citra_qt/bootmanager.cpp29
-rw-r--r--src/citra_qt/config.cpp63
-rw-r--r--src/citra_qt/main.cpp3
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.cpp25
-rw-r--r--src/core/arm/dyncom/arm_dyncom_dec.h16
-rw-r--r--src/core/arm/dyncom/arm_dyncom_interpreter.cpp133
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.cpp28
-rw-r--r--src/core/arm/dyncom/arm_dyncom_thumb.h28
-rw-r--r--src/core/arm/skyeye_common/armstate.h25
-rw-r--r--src/core/hle/service/hid/hid.cpp10
-rw-r--r--src/core/hle/service/hid/hid.h5
-rw-r--r--src/core/hle/service/soc_u.cpp10
-rw-r--r--src/core/settings.h54
15 files changed, 216 insertions, 278 deletions
diff --git a/src/citra/config.cpp b/src/citra/config.cpp
index 506cb7939..2c1407a6f 100644
--- a/src/citra/config.cpp
+++ b/src/citra/config.cpp
@@ -40,31 +40,21 @@ bool Config::LoadINI(INIReader* config, const char* location, const std::string&
40 return true; 40 return true;
41} 41}
42 42
43static const std::array<int, Settings::NativeInput::NUM_INPUTS> defaults = {
44 GLFW_KEY_A, GLFW_KEY_S, GLFW_KEY_Z, GLFW_KEY_X,
45 GLFW_KEY_Q, GLFW_KEY_W, GLFW_KEY_1, GLFW_KEY_2,
46 GLFW_KEY_M, GLFW_KEY_N, GLFW_KEY_B,
47 GLFW_KEY_T, GLFW_KEY_G, GLFW_KEY_F, GLFW_KEY_H,
48 GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT,
49 GLFW_KEY_I, GLFW_KEY_K, GLFW_KEY_J, GLFW_KEY_L
50};
51
43void Config::ReadValues() { 52void Config::ReadValues() {
44 // Controls 53 // Controls
45 Settings::values.pad_a_key = glfw_config->GetInteger("Controls", "pad_a", GLFW_KEY_A); 54 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
46 Settings::values.pad_b_key = glfw_config->GetInteger("Controls", "pad_b", GLFW_KEY_S); 55 Settings::values.input_mappings[Settings::NativeInput::All[i]] =
47 Settings::values.pad_x_key = glfw_config->GetInteger("Controls", "pad_x", GLFW_KEY_Z); 56 glfw_config->GetInteger("Controls", Settings::NativeInput::Mapping[i], defaults[i]);
48 Settings::values.pad_y_key = glfw_config->GetInteger("Controls", "pad_y", GLFW_KEY_X); 57 }
49 Settings::values.pad_l_key = glfw_config->GetInteger("Controls", "pad_l", GLFW_KEY_Q);
50 Settings::values.pad_r_key = glfw_config->GetInteger("Controls", "pad_r", GLFW_KEY_W);
51 Settings::values.pad_zl_key = glfw_config->GetInteger("Controls", "pad_zl", GLFW_KEY_1);
52 Settings::values.pad_zr_key = glfw_config->GetInteger("Controls", "pad_zr", GLFW_KEY_2);
53 Settings::values.pad_start_key = glfw_config->GetInteger("Controls", "pad_start", GLFW_KEY_M);
54 Settings::values.pad_select_key = glfw_config->GetInteger("Controls", "pad_select", GLFW_KEY_N);
55 Settings::values.pad_home_key = glfw_config->GetInteger("Controls", "pad_home", GLFW_KEY_B);
56 Settings::values.pad_dup_key = glfw_config->GetInteger("Controls", "pad_dup", GLFW_KEY_T);
57 Settings::values.pad_ddown_key = glfw_config->GetInteger("Controls", "pad_ddown", GLFW_KEY_G);
58 Settings::values.pad_dleft_key = glfw_config->GetInteger("Controls", "pad_dleft", GLFW_KEY_F);
59 Settings::values.pad_dright_key = glfw_config->GetInteger("Controls", "pad_dright", GLFW_KEY_H);
60 Settings::values.pad_sup_key = glfw_config->GetInteger("Controls", "pad_sup", GLFW_KEY_UP);
61 Settings::values.pad_sdown_key = glfw_config->GetInteger("Controls", "pad_sdown", GLFW_KEY_DOWN);
62 Settings::values.pad_sleft_key = glfw_config->GetInteger("Controls", "pad_sleft", GLFW_KEY_LEFT);
63 Settings::values.pad_sright_key = glfw_config->GetInteger("Controls", "pad_sright", GLFW_KEY_RIGHT);
64 Settings::values.pad_cup_key = glfw_config->GetInteger("Controls", "pad_cup", GLFW_KEY_I);
65 Settings::values.pad_cdown_key = glfw_config->GetInteger("Controls", "pad_cdown", GLFW_KEY_K);
66 Settings::values.pad_cleft_key = glfw_config->GetInteger("Controls", "pad_cleft", GLFW_KEY_J);
67 Settings::values.pad_cright_key = glfw_config->GetInteger("Controls", "pad_cright", GLFW_KEY_L);
68 58
69 // Core 59 // Core
70 Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0); 60 Settings::values.frame_skip = glfw_config->GetInteger("Core", "frame_skip", 0);
diff --git a/src/citra/emu_window/emu_window_glfw.cpp b/src/citra/emu_window/emu_window_glfw.cpp
index 42fb683a9..6d6656b5a 100644
--- a/src/citra/emu_window/emu_window_glfw.cpp
+++ b/src/citra/emu_window/emu_window_glfw.cpp
@@ -150,32 +150,9 @@ void EmuWindow_GLFW::DoneCurrent() {
150} 150}
151 151
152void EmuWindow_GLFW::ReloadSetKeymaps() { 152void EmuWindow_GLFW::ReloadSetKeymaps() {
153 KeyMap::SetKeyMapping({Settings::values.pad_a_key, keyboard_id}, Service::HID::PAD_A); 153 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
154 KeyMap::SetKeyMapping({Settings::values.pad_b_key, keyboard_id}, Service::HID::PAD_B); 154 KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]);
155 KeyMap::SetKeyMapping({Settings::values.pad_select_key, keyboard_id}, Service::HID::PAD_SELECT); 155 }
156 KeyMap::SetKeyMapping({Settings::values.pad_start_key, keyboard_id}, Service::HID::PAD_START);
157 KeyMap::SetKeyMapping({Settings::values.pad_dright_key, keyboard_id}, Service::HID::PAD_RIGHT);
158 KeyMap::SetKeyMapping({Settings::values.pad_dleft_key, keyboard_id}, Service::HID::PAD_LEFT);
159 KeyMap::SetKeyMapping({Settings::values.pad_dup_key, keyboard_id}, Service::HID::PAD_UP);
160 KeyMap::SetKeyMapping({Settings::values.pad_ddown_key, keyboard_id}, Service::HID::PAD_DOWN);
161 KeyMap::SetKeyMapping({Settings::values.pad_r_key, keyboard_id}, Service::HID::PAD_R);
162 KeyMap::SetKeyMapping({Settings::values.pad_l_key, keyboard_id}, Service::HID::PAD_L);
163 KeyMap::SetKeyMapping({Settings::values.pad_x_key, keyboard_id}, Service::HID::PAD_X);
164 KeyMap::SetKeyMapping({Settings::values.pad_y_key, keyboard_id}, Service::HID::PAD_Y);
165
166 KeyMap::SetKeyMapping({Settings::values.pad_zl_key, keyboard_id}, Service::HID::PAD_ZL);
167 KeyMap::SetKeyMapping({Settings::values.pad_zr_key, keyboard_id}, Service::HID::PAD_ZR);
168
169 // KeyMap::SetKeyMapping({Settings::values.pad_touch_key, keyboard_id}, Service::HID::PAD_TOUCH);
170
171 KeyMap::SetKeyMapping({Settings::values.pad_cright_key, keyboard_id}, Service::HID::PAD_C_RIGHT);
172 KeyMap::SetKeyMapping({Settings::values.pad_cleft_key, keyboard_id}, Service::HID::PAD_C_LEFT);
173 KeyMap::SetKeyMapping({Settings::values.pad_cup_key, keyboard_id}, Service::HID::PAD_C_UP);
174 KeyMap::SetKeyMapping({Settings::values.pad_cdown_key, keyboard_id}, Service::HID::PAD_C_DOWN);
175 KeyMap::SetKeyMapping({Settings::values.pad_sright_key, keyboard_id}, Service::HID::PAD_CIRCLE_RIGHT);
176 KeyMap::SetKeyMapping({Settings::values.pad_sleft_key, keyboard_id}, Service::HID::PAD_CIRCLE_LEFT);
177 KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, Service::HID::PAD_CIRCLE_UP);
178 KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, Service::HID::PAD_CIRCLE_DOWN);
179} 156}
180 157
181void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) { 158void EmuWindow_GLFW::OnMinimalClientAreaChangeRequest(const std::pair<unsigned,unsigned>& minimal_size) {
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp
index fa7bce466..b12bd858b 100644
--- a/src/citra_qt/bootmanager.cpp
+++ b/src/citra_qt/bootmanager.cpp
@@ -248,32 +248,9 @@ void GRenderWindow::mouseReleaseEvent(QMouseEvent *event)
248 248
249void GRenderWindow::ReloadSetKeymaps() 249void GRenderWindow::ReloadSetKeymaps()
250{ 250{
251 KeyMap::SetKeyMapping({Settings::values.pad_a_key, keyboard_id}, Service::HID::PAD_A); 251 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
252 KeyMap::SetKeyMapping({Settings::values.pad_b_key, keyboard_id}, Service::HID::PAD_B); 252 KeyMap::SetKeyMapping({Settings::values.input_mappings[Settings::NativeInput::All[i]], keyboard_id}, Service::HID::pad_mapping[i]);
253 KeyMap::SetKeyMapping({Settings::values.pad_select_key, keyboard_id}, Service::HID::PAD_SELECT); 253 }
254 KeyMap::SetKeyMapping({Settings::values.pad_start_key, keyboard_id}, Service::HID::PAD_START);
255 KeyMap::SetKeyMapping({Settings::values.pad_dright_key, keyboard_id}, Service::HID::PAD_RIGHT);
256 KeyMap::SetKeyMapping({Settings::values.pad_dleft_key, keyboard_id}, Service::HID::PAD_LEFT);
257 KeyMap::SetKeyMapping({Settings::values.pad_dup_key, keyboard_id}, Service::HID::PAD_UP);
258 KeyMap::SetKeyMapping({Settings::values.pad_ddown_key, keyboard_id}, Service::HID::PAD_DOWN);
259 KeyMap::SetKeyMapping({Settings::values.pad_r_key, keyboard_id}, Service::HID::PAD_R);
260 KeyMap::SetKeyMapping({Settings::values.pad_l_key, keyboard_id}, Service::HID::PAD_L);
261 KeyMap::SetKeyMapping({Settings::values.pad_x_key, keyboard_id}, Service::HID::PAD_X);
262 KeyMap::SetKeyMapping({Settings::values.pad_y_key, keyboard_id}, Service::HID::PAD_Y);
263
264 KeyMap::SetKeyMapping({Settings::values.pad_zl_key, keyboard_id}, Service::HID::PAD_ZL);
265 KeyMap::SetKeyMapping({Settings::values.pad_zr_key, keyboard_id}, Service::HID::PAD_ZR);
266
267 // KeyMap::SetKeyMapping({Settings::values.pad_touch_key, keyboard_id}, Service::HID::PAD_TOUCH);
268
269 KeyMap::SetKeyMapping({Settings::values.pad_cright_key, keyboard_id}, Service::HID::PAD_C_RIGHT);
270 KeyMap::SetKeyMapping({Settings::values.pad_cleft_key, keyboard_id}, Service::HID::PAD_C_LEFT);
271 KeyMap::SetKeyMapping({Settings::values.pad_cup_key, keyboard_id}, Service::HID::PAD_C_UP);
272 KeyMap::SetKeyMapping({Settings::values.pad_cdown_key, keyboard_id}, Service::HID::PAD_C_DOWN);
273 KeyMap::SetKeyMapping({Settings::values.pad_sright_key, keyboard_id}, Service::HID::PAD_CIRCLE_RIGHT);
274 KeyMap::SetKeyMapping({Settings::values.pad_sleft_key, keyboard_id}, Service::HID::PAD_CIRCLE_LEFT);
275 KeyMap::SetKeyMapping({Settings::values.pad_sup_key, keyboard_id}, Service::HID::PAD_CIRCLE_UP);
276 KeyMap::SetKeyMapping({Settings::values.pad_sdown_key, keyboard_id}, Service::HID::PAD_CIRCLE_DOWN);
277} 254}
278 255
279void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) 256void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height)
diff --git a/src/citra_qt/config.cpp b/src/citra_qt/config.cpp
index 5c056446e..5716634ee 100644
--- a/src/citra_qt/config.cpp
+++ b/src/citra_qt/config.cpp
@@ -21,31 +21,21 @@ Config::Config() {
21 Reload(); 21 Reload();
22} 22}
23 23
24static const std::array<QVariant, Settings::NativeInput::NUM_INPUTS> defaults = {
25 Qt::Key_A, Qt::Key_S, Qt::Key_Z, Qt::Key_X,
26 Qt::Key_Q, Qt::Key_W, Qt::Key_1, Qt::Key_2,
27 Qt::Key_M, Qt::Key_N, Qt::Key_B,
28 Qt::Key_T, Qt::Key_G, Qt::Key_F, Qt::Key_H,
29 Qt::Key_Up, Qt::Key_Down, Qt::Key_Left, Qt::Key_Right,
30 Qt::Key_I, Qt::Key_K, Qt::Key_J, Qt::Key_L
31};
32
24void Config::ReadValues() { 33void Config::ReadValues() {
25 qt_config->beginGroup("Controls"); 34 qt_config->beginGroup("Controls");
26 Settings::values.pad_a_key = qt_config->value("pad_a", Qt::Key_A).toInt(); 35 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
27 Settings::values.pad_b_key = qt_config->value("pad_b", Qt::Key_S).toInt(); 36 Settings::values.input_mappings[Settings::NativeInput::All[i]] =
28 Settings::values.pad_x_key = qt_config->value("pad_x", Qt::Key_Z).toInt(); 37 qt_config->value(QString::fromStdString(Settings::NativeInput::Mapping[i]), defaults[i]).toInt();
29 Settings::values.pad_y_key = qt_config->value("pad_y", Qt::Key_X).toInt(); 38 }
30 Settings::values.pad_l_key = qt_config->value("pad_l", Qt::Key_Q).toInt();
31 Settings::values.pad_r_key = qt_config->value("pad_r", Qt::Key_W).toInt();
32 Settings::values.pad_zl_key = qt_config->value("pad_zl", Qt::Key_1).toInt();
33 Settings::values.pad_zr_key = qt_config->value("pad_zr", Qt::Key_2).toInt();
34 Settings::values.pad_start_key = qt_config->value("pad_start", Qt::Key_M).toInt();
35 Settings::values.pad_select_key = qt_config->value("pad_select", Qt::Key_N).toInt();
36 Settings::values.pad_home_key = qt_config->value("pad_home", Qt::Key_B).toInt();
37 Settings::values.pad_dup_key = qt_config->value("pad_dup", Qt::Key_T).toInt();
38 Settings::values.pad_ddown_key = qt_config->value("pad_ddown", Qt::Key_G).toInt();
39 Settings::values.pad_dleft_key = qt_config->value("pad_dleft", Qt::Key_F).toInt();
40 Settings::values.pad_dright_key = qt_config->value("pad_dright", Qt::Key_H).toInt();
41 Settings::values.pad_sup_key = qt_config->value("pad_sup", Qt::Key_Up).toInt();
42 Settings::values.pad_sdown_key = qt_config->value("pad_sdown", Qt::Key_Down).toInt();
43 Settings::values.pad_sleft_key = qt_config->value("pad_sleft", Qt::Key_Left).toInt();
44 Settings::values.pad_sright_key = qt_config->value("pad_sright", Qt::Key_Right).toInt();
45 Settings::values.pad_cup_key = qt_config->value("pad_cup", Qt::Key_I).toInt();
46 Settings::values.pad_cdown_key = qt_config->value("pad_cdown", Qt::Key_K).toInt();
47 Settings::values.pad_cleft_key = qt_config->value("pad_cleft", Qt::Key_J).toInt();
48 Settings::values.pad_cright_key = qt_config->value("pad_cright", Qt::Key_L).toInt();
49 qt_config->endGroup(); 39 qt_config->endGroup();
50 40
51 qt_config->beginGroup("Core"); 41 qt_config->beginGroup("Core");
@@ -75,29 +65,10 @@ void Config::ReadValues() {
75 65
76void Config::SaveValues() { 66void Config::SaveValues() {
77 qt_config->beginGroup("Controls"); 67 qt_config->beginGroup("Controls");
78 qt_config->setValue("pad_a", Settings::values.pad_a_key); 68 for (int i = 0; i < Settings::NativeInput::NUM_INPUTS; ++i) {
79 qt_config->setValue("pad_b", Settings::values.pad_b_key); 69 qt_config->setValue(QString::fromStdString(Settings::NativeInput::Mapping[i]),
80 qt_config->setValue("pad_x", Settings::values.pad_x_key); 70 Settings::values.input_mappings[Settings::NativeInput::All[i]]);
81 qt_config->setValue("pad_y", Settings::values.pad_y_key); 71 }
82 qt_config->setValue("pad_l", Settings::values.pad_l_key);
83 qt_config->setValue("pad_r", Settings::values.pad_r_key);
84 qt_config->setValue("pad_zl", Settings::values.pad_zl_key);
85 qt_config->setValue("pad_zr", Settings::values.pad_zr_key);
86 qt_config->setValue("pad_start", Settings::values.pad_start_key);
87 qt_config->setValue("pad_select", Settings::values.pad_select_key);
88 qt_config->setValue("pad_home", Settings::values.pad_home_key);
89 qt_config->setValue("pad_dup", Settings::values.pad_dup_key);
90 qt_config->setValue("pad_ddown", Settings::values.pad_ddown_key);
91 qt_config->setValue("pad_dleft", Settings::values.pad_dleft_key);
92 qt_config->setValue("pad_dright", Settings::values.pad_dright_key);
93 qt_config->setValue("pad_sup", Settings::values.pad_sup_key);
94 qt_config->setValue("pad_sdown", Settings::values.pad_sdown_key);
95 qt_config->setValue("pad_sleft", Settings::values.pad_sleft_key);
96 qt_config->setValue("pad_sright", Settings::values.pad_sright_key);
97 qt_config->setValue("pad_cup", Settings::values.pad_cup_key);
98 qt_config->setValue("pad_cdown", Settings::values.pad_cdown_key);
99 qt_config->setValue("pad_cleft", Settings::values.pad_cleft_key);
100 qt_config->setValue("pad_cright", Settings::values.pad_cright_key);
101 qt_config->endGroup(); 72 qt_config->endGroup();
102 73
103 qt_config->beginGroup("Core"); 74 qt_config->beginGroup("Core");
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 2746de779..34831f2ec 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -263,6 +263,7 @@ void GMainWindow::ShutdownGame() {
263 263
264 // Update the GUI 264 // Update the GUI
265 ui.action_Start->setEnabled(false); 265 ui.action_Start->setEnabled(false);
266 ui.action_Start->setText(tr("Start"));
266 ui.action_Pause->setEnabled(false); 267 ui.action_Pause->setEnabled(false);
267 ui.action_Stop->setEnabled(false); 268 ui.action_Stop->setEnabled(false);
268 render_window->hide(); 269 render_window->hide();
@@ -291,6 +292,8 @@ void GMainWindow::OnStartGame()
291 emu_thread->SetRunning(true); 292 emu_thread->SetRunning(true);
292 293
293 ui.action_Start->setEnabled(false); 294 ui.action_Start->setEnabled(false);
295 ui.action_Start->setText(tr("Continue"));
296
294 ui.action_Pause->setEnabled(true); 297 ui.action_Pause->setEnabled(true);
295 ui.action_Stop->setEnabled(true); 298 ui.action_Stop->setEnabled(true);
296} 299}
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.cpp b/src/core/arm/dyncom/arm_dyncom_dec.cpp
index 3ab9f2c17..ee4288314 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_dec.cpp
@@ -5,7 +5,7 @@
5#include "core/arm/dyncom/arm_dyncom_dec.h" 5#include "core/arm/dyncom/arm_dyncom_dec.h"
6#include "core/arm/skyeye_common/armsupp.h" 6#include "core/arm/skyeye_common/armsupp.h"
7 7
8const ISEITEM arm_instruction[] = { 8const InstructionSetEncodingItem arm_instruction[] = {
9 { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }}, 9 { "vmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x0, 9, 11, 0x5, 4, 4, 0 }},
10 { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }}, 10 { "vmls", 7, ARMVFP2, { 28, 31, 0xF, 25, 27, 0x1, 23, 23, 1, 11, 11, 0, 8, 9, 0x2, 6, 6, 1, 4, 4, 0 }},
11 { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }}, 11 { "vnmla", 4, ARMVFP2, { 23, 27, 0x1C, 20, 21, 0x1, 9, 11, 0x5, 4, 4, 0 }},
@@ -207,7 +207,7 @@ const ISEITEM arm_instruction[] = {
207 { "bbl", 1, 0, { 25, 27, 0x00000005 }}, 207 { "bbl", 1, 0, { 25, 27, 0x00000005 }},
208}; 208};
209 209
210const ISEITEM arm_exclusion_code[] = { 210const InstructionSetEncodingItem arm_exclusion_code[] = {
211 { "vmla", 0, ARMVFP2, { 0 }}, 211 { "vmla", 0, ARMVFP2, { 0 }},
212 { "vmls", 0, ARMVFP2, { 0 }}, 212 { "vmls", 0, ARMVFP2, { 0 }},
213 { "vnmla", 0, ARMVFP2, { 0 }}, 213 { "vnmla", 0, ARMVFP2, { 0 }},
@@ -414,14 +414,13 @@ const ISEITEM arm_exclusion_code[] = {
414 { "invalid", 0, INVALID, { 0 }} 414 { "invalid", 0, INVALID, { 0 }}
415}; 415};
416 416
417int decode_arm_instr(u32 instr, s32* idx) { 417ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx) {
418 int n = 0; 418 int n = 0;
419 int base = 0; 419 int base = 0;
420 int ret = DECODE_FAILURE; 420 int instr_slots = sizeof(arm_instruction) / sizeof(InstructionSetEncodingItem);
421 int i = 0; 421 ARMDecodeStatus ret = ARMDecodeStatus::FAILURE;
422 int instr_slots = sizeof(arm_instruction) / sizeof(ISEITEM);
423 422
424 for (i = 0; i < instr_slots; i++) { 423 for (int i = 0; i < instr_slots; i++) {
425 n = arm_instruction[i].attribute_value; 424 n = arm_instruction[i].attribute_value;
426 base = 0; 425 base = 0;
427 426
@@ -438,11 +437,11 @@ int decode_arm_instr(u32 instr, s32* idx) {
438 n--; 437 n--;
439 } 438 }
440 439
441 // All conditions is satisfied. 440 // All conditions are satisfied.
442 if (n == 0) 441 if (n == 0)
443 ret = DECODE_SUCCESS; 442 ret = ARMDecodeStatus::SUCCESS;
444 443
445 if (ret == DECODE_SUCCESS) { 444 if (ret == ARMDecodeStatus::SUCCESS) {
446 n = arm_exclusion_code[i].attribute_value; 445 n = arm_exclusion_code[i].attribute_value;
447 if (n != 0) { 446 if (n != 0) {
448 base = 0; 447 base = 0;
@@ -454,13 +453,13 @@ int decode_arm_instr(u32 instr, s32* idx) {
454 n--; 453 n--;
455 } 454 }
456 455
457 // All conditions is satisfied. 456 // All conditions are satisfied.
458 if (n == 0) 457 if (n == 0)
459 ret = DECODE_FAILURE; 458 ret = ARMDecodeStatus::FAILURE;
460 } 459 }
461 } 460 }
462 461
463 if (ret == DECODE_SUCCESS) { 462 if (ret == ARMDecodeStatus::SUCCESS) {
464 *idx = i; 463 *idx = i;
465 return ret; 464 return ret;
466 } 465 }
diff --git a/src/core/arm/dyncom/arm_dyncom_dec.h b/src/core/arm/dyncom/arm_dyncom_dec.h
index 5f6279627..d7170e0fc 100644
--- a/src/core/arm/dyncom/arm_dyncom_dec.h
+++ b/src/core/arm/dyncom/arm_dyncom_dec.h
@@ -6,22 +6,20 @@
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8 8
9int decode_arm_instr(u32 instr, s32* idx); 9enum class ARMDecodeStatus {
10 10 SUCCESS,
11enum DECODE_STATUS { 11 FAILURE
12 DECODE_SUCCESS,
13 DECODE_FAILURE
14}; 12};
15 13
16struct instruction_set_encoding_item { 14ARMDecodeStatus DecodeARMInstruction(u32 instr, s32* idx);
15
16struct InstructionSetEncodingItem {
17 const char *name; 17 const char *name;
18 int attribute_value; 18 int attribute_value;
19 int version; 19 int version;
20 u32 content[21]; 20 u32 content[21];
21}; 21};
22 22
23typedef struct instruction_set_encoding_item ISEITEM;
24
25// ARM versions 23// ARM versions
26enum { 24enum {
27 INVALID = 0, 25 INVALID = 0,
@@ -38,4 +36,4 @@ enum {
38 ARMV6K, 36 ARMV6K,
39}; 37};
40 38
41extern const ISEITEM arm_instruction[]; 39extern const InstructionSetEncodingItem arm_instruction[];
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
index cf09acb4e..0c20c2bc3 100644
--- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp
@@ -47,27 +47,6 @@ enum {
47 47
48typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper); 48typedef unsigned int (*shtop_fp_t)(ARMul_State* cpu, unsigned int sht_oper);
49 49
50// Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
51// This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
52// support LDR/STREXD.
53static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
54
55// Exclusive memory access
56static int exclusive_detect(ARMul_State* state, u32 addr) {
57 if(state->exclusive_tag == (addr & RESERVATION_GRANULE_MASK))
58 return 0;
59 else
60 return -1;
61}
62
63static void add_exclusive_addr(ARMul_State* state, u32 addr){
64 state->exclusive_tag = addr & RESERVATION_GRANULE_MASK;
65}
66
67static void remove_exclusive(ARMul_State* state, u32 addr){
68 state->exclusive_tag = 0xFFFFFFFF;
69}
70
71static int CondPassed(ARMul_State* cpu, unsigned int cond) { 50static int CondPassed(ARMul_State* cpu, unsigned int cond) {
72 const u32 NFLAG = cpu->NFlag; 51 const u32 NFLAG = cpu->NFlag;
73 const u32 ZFLAG = cpu->ZFlag; 52 const u32 ZFLAG = cpu->ZFlag;
@@ -3489,21 +3468,15 @@ enum {
3489 FETCH_FAILURE 3468 FETCH_FAILURE
3490}; 3469};
3491 3470
3492static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) { 3471static ThumbDecodeStatus DecodeThumbInstruction(u32 inst, u32 addr, u32* arm_inst, u32* inst_size, ARM_INST_PTR* ptr_inst_base) {
3493 // Check if in Thumb mode 3472 // Check if in Thumb mode
3494 tdstate ret = thumb_translate (addr, inst, arm_inst, inst_size); 3473 ThumbDecodeStatus ret = TranslateThumbInstruction (addr, inst, arm_inst, inst_size);
3495 if(ret == t_branch){ 3474 if (ret == ThumbDecodeStatus::BRANCH) {
3496 // TODO: FIXME, endian should be judged
3497 u32 tinstr;
3498 if((addr & 0x3) != 0)
3499 tinstr = inst >> 16;
3500 else
3501 tinstr = inst & 0xFFFF;
3502
3503 int inst_index; 3475 int inst_index;
3504 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t); 3476 int table_length = sizeof(arm_instruction_trans) / sizeof(transop_fp_t);
3477 u32 tinstr = GetThumbInstruction(inst, addr);
3505 3478
3506 switch((tinstr & 0xF800) >> 11){ 3479 switch ((tinstr & 0xF800) >> 11) {
3507 case 26: 3480 case 26:
3508 case 27: 3481 case 27:
3509 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){ 3482 if (((tinstr & 0x0F00) != 0x0E00) && ((tinstr & 0x0F00) != 0x0F00)){
@@ -3536,7 +3509,7 @@ static tdstate decode_thumb_instr(u32 inst, u32 addr, u32* arm_inst, u32* inst_s
3536 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index); 3509 *ptr_inst_base = arm_instruction_trans[inst_index](tinstr, inst_index);
3537 break; 3510 break;
3538 default: 3511 default:
3539 ret = t_undefined; 3512 ret = ThumbDecodeStatus::UNDEFINED;
3540 break; 3513 break;
3541 } 3514 }
3542 } 3515 }
@@ -3548,10 +3521,6 @@ enum {
3548 FETCH_EXCEPTION 3521 FETCH_EXCEPTION
3549}; 3522};
3550 3523
3551typedef struct instruction_set_encoding_item ISEITEM;
3552
3553extern const ISEITEM arm_instruction[];
3554
3555static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) { 3524static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
3556 Common::Profiling::ScopeTimer timer_decode(profile_decode); 3525 Common::Profiling::ScopeTimer timer_decode(profile_decode);
3557 3526
@@ -3573,20 +3542,19 @@ static int InterpreterTranslate(ARMul_State* cpu, int& bb_start, u32 addr) {
3573 inst = Memory::Read32(phys_addr & 0xFFFFFFFC); 3542 inst = Memory::Read32(phys_addr & 0xFFFFFFFC);
3574 3543
3575 size++; 3544 size++;
3576 // If we are in thumb instruction, we will translate one thumb to one corresponding arm instruction 3545 // If we are in Thumb mode, we'll translate one Thumb instruction to the corresponding ARM instruction
3577 if (cpu->TFlag) { 3546 if (cpu->TFlag) {
3578 uint32_t arm_inst; 3547 uint32_t arm_inst;
3579 tdstate state = decode_thumb_instr(inst, phys_addr, &arm_inst, &inst_size, &inst_base); 3548 ThumbDecodeStatus state = DecodeThumbInstruction(inst, phys_addr, &arm_inst, &inst_size, &inst_base);
3580 3549
3581 // We have translated the branch instruction of thumb in thumb decoder 3550 // We have translated the Thumb branch instruction in the Thumb decoder
3582 if(state == t_branch){ 3551 if (state == ThumbDecodeStatus::BRANCH) {
3583 goto translated; 3552 goto translated;
3584 } 3553 }
3585 inst = arm_inst; 3554 inst = arm_inst;
3586 } 3555 }
3587 3556
3588 ret = decode_arm_instr(inst, &idx); 3557 if (DecodeARMInstruction(inst, &idx) == ARMDecodeStatus::FAILURE) {
3589 if (ret == DECODE_FAILURE) {
3590 std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst); 3558 std::string disasm = ARM_Disasm::Disassemble(phys_addr, inst);
3591 LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst); 3559 LOG_ERROR(Core_ARM11, "Decode failure.\tPC : [0x%x]\tInstruction : %s [%x]", phys_addr, disasm.c_str(), inst);
3592 LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]); 3560 LOG_ERROR(Core_ARM11, "cpsr=0x%x, cpu->TFlag=%d, r15=0x%x", cpu->Cpsr, cpu->TFlag, cpu->Reg[15]);
@@ -3956,9 +3924,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
3956 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 3924 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
3957 adc_inst* const inst_cream = (adc_inst*)inst_base->component; 3925 adc_inst* const inst_cream = (adc_inst*)inst_base->component;
3958 3926
3927 u32 rn_val = RN;
3928 if (inst_cream->Rn == 15)
3929 rn_val += 2 * cpu->GetInstructionSize();
3930
3959 bool carry; 3931 bool carry;
3960 bool overflow; 3932 bool overflow;
3961 RD = AddWithCarry(RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); 3933 RD = AddWithCarry(rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
3962 3934
3963 if (inst_cream->S && (inst_cream->Rd == 15)) { 3935 if (inst_cream->S && (inst_cream->Rd == 15)) {
3964 if (CurrentModeHasSPSR) { 3936 if (CurrentModeHasSPSR) {
@@ -4019,11 +3991,17 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4019 } 3991 }
4020 AND_INST: 3992 AND_INST:
4021 { 3993 {
4022 and_inst *inst_cream = (and_inst *)inst_base->component; 3994 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4023 if ((inst_base->cond == 0xe) || CondPassed(cpu, inst_base->cond)) { 3995 and_inst* const inst_cream = (and_inst*)inst_base->component;
3996
4024 u32 lop = RN; 3997 u32 lop = RN;
4025 u32 rop = SHIFTER_OPERAND; 3998 u32 rop = SHIFTER_OPERAND;
3999
4000 if (inst_cream->Rn == 15)
4001 lop += 2 * cpu->GetInstructionSize();
4002
4026 RD = lop & rop; 4003 RD = lop & rop;
4004
4027 if (inst_cream->S && (inst_cream->Rd == 15)) { 4005 if (inst_cream->S && (inst_cream->Rd == 15)) {
4028 if (CurrentModeHasSPSR) { 4006 if (CurrentModeHasSPSR) {
4029 cpu->Cpsr = cpu->Spsr_copy; 4007 cpu->Cpsr = cpu->Spsr_copy;
@@ -4174,9 +4152,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4174 4152
4175 CLREX_INST: 4153 CLREX_INST:
4176 { 4154 {
4177 remove_exclusive(cpu, 0); 4155 cpu->UnsetExclusiveMemoryAddress();
4178 cpu->exclusive_state = 0;
4179
4180 cpu->Reg[15] += cpu->GetInstructionSize(); 4156 cpu->Reg[15] += cpu->GetInstructionSize();
4181 INC_PC(sizeof(clrex_inst)); 4157 INC_PC(sizeof(clrex_inst));
4182 FETCH_INST; 4158 FETCH_INST;
@@ -4198,9 +4174,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4198 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 4174 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
4199 cmn_inst* const inst_cream = (cmn_inst*)inst_base->component; 4175 cmn_inst* const inst_cream = (cmn_inst*)inst_base->component;
4200 4176
4177 u32 rn_val = RN;
4178 if (inst_cream->Rn == 15)
4179 rn_val += 2 * cpu->GetInstructionSize();
4180
4201 bool carry; 4181 bool carry;
4202 bool overflow; 4182 bool overflow;
4203 u32 result = AddWithCarry(RN, SHIFTER_OPERAND, 0, &carry, &overflow); 4183 u32 result = AddWithCarry(rn_val, SHIFTER_OPERAND, 0, &carry, &overflow);
4204 4184
4205 UPDATE_NFLAG(result); 4185 UPDATE_NFLAG(result);
4206 UPDATE_ZFLAG(result); 4186 UPDATE_ZFLAG(result);
@@ -4543,8 +4523,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4543 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 4523 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4544 unsigned int read_addr = RN; 4524 unsigned int read_addr = RN;
4545 4525
4546 add_exclusive_addr(cpu, read_addr); 4526 cpu->SetExclusiveMemoryAddress(read_addr);
4547 cpu->exclusive_state = 1;
4548 4527
4549 RD = cpu->ReadMemory32(read_addr); 4528 RD = cpu->ReadMemory32(read_addr);
4550 if (inst_cream->Rd == 15) { 4529 if (inst_cream->Rd == 15) {
@@ -4563,8 +4542,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4563 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 4542 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4564 unsigned int read_addr = RN; 4543 unsigned int read_addr = RN;
4565 4544
4566 add_exclusive_addr(cpu, read_addr); 4545 cpu->SetExclusiveMemoryAddress(read_addr);
4567 cpu->exclusive_state = 1;
4568 4546
4569 RD = Memory::Read8(read_addr); 4547 RD = Memory::Read8(read_addr);
4570 if (inst_cream->Rd == 15) { 4548 if (inst_cream->Rd == 15) {
@@ -4583,8 +4561,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4583 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 4561 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4584 unsigned int read_addr = RN; 4562 unsigned int read_addr = RN;
4585 4563
4586 add_exclusive_addr(cpu, read_addr); 4564 cpu->SetExclusiveMemoryAddress(read_addr);
4587 cpu->exclusive_state = 1;
4588 4565
4589 RD = cpu->ReadMemory16(read_addr); 4566 RD = cpu->ReadMemory16(read_addr);
4590 if (inst_cream->Rd == 15) { 4567 if (inst_cream->Rd == 15) {
@@ -4603,8 +4580,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4603 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 4580 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
4604 unsigned int read_addr = RN; 4581 unsigned int read_addr = RN;
4605 4582
4606 add_exclusive_addr(cpu, read_addr); 4583 cpu->SetExclusiveMemoryAddress(read_addr);
4607 cpu->exclusive_state = 1;
4608 4584
4609 RD = cpu->ReadMemory32(read_addr); 4585 RD = cpu->ReadMemory32(read_addr);
4610 RD2 = cpu->ReadMemory32(read_addr + 4); 4586 RD2 = cpu->ReadMemory32(read_addr + 4);
@@ -4943,6 +4919,10 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
4943 4919
4944 u32 lop = RN; 4920 u32 lop = RN;
4945 u32 rop = SHIFTER_OPERAND; 4921 u32 rop = SHIFTER_OPERAND;
4922
4923 if (inst_cream->Rn == 15)
4924 lop += 2 * cpu->GetInstructionSize();
4925
4946 RD = lop | rop; 4926 RD = lop | rop;
4947 4927
4948 if (inst_cream->S && (inst_cream->Rd == 15)) { 4928 if (inst_cream->S && (inst_cream->Rd == 15)) {
@@ -5233,9 +5213,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5233 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 5213 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5234 rsc_inst* const inst_cream = (rsc_inst*)inst_base->component; 5214 rsc_inst* const inst_cream = (rsc_inst*)inst_base->component;
5235 5215
5216 u32 rn_val = RN;
5217 if (inst_cream->Rn == 15)
5218 rn_val += 2 * cpu->GetInstructionSize();
5219
5236 bool carry; 5220 bool carry;
5237 bool overflow; 5221 bool overflow;
5238 RD = AddWithCarry(~RN, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); 5222 RD = AddWithCarry(~rn_val, SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
5239 5223
5240 if (inst_cream->S && (inst_cream->Rd == 15)) { 5224 if (inst_cream->S && (inst_cream->Rd == 15)) {
5241 if (CurrentModeHasSPSR) { 5225 if (CurrentModeHasSPSR) {
@@ -5373,9 +5357,13 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
5373 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { 5357 if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) {
5374 sbc_inst* const inst_cream = (sbc_inst*)inst_base->component; 5358 sbc_inst* const inst_cream = (sbc_inst*)inst_base->component;
5375 5359
5360 u32 rn_val = RN;
5361 if (inst_cream->Rn == 15)
5362 rn_val += 2 * cpu->GetInstructionSize();
5363
5376 bool carry; 5364 bool carry;
5377 bool overflow; 5365 bool overflow;
5378 RD = AddWithCarry(RN, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow); 5366 RD = AddWithCarry(rn_val, ~SHIFTER_OPERAND, cpu->CFlag, &carry, &overflow);
5379 5367
5380 if (inst_cream->S && (inst_cream->Rd == 15)) { 5368 if (inst_cream->S && (inst_cream->Rd == 15)) {
5381 if (CurrentModeHasSPSR) { 5369 if (CurrentModeHasSPSR) {
@@ -6089,10 +6077,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6089 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 6077 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6090 unsigned int write_addr = cpu->Reg[inst_cream->Rn]; 6078 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
6091 6079
6092 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { 6080 if (cpu->IsExclusiveMemoryAccess(write_addr)) {
6093 remove_exclusive(cpu, write_addr); 6081 cpu->UnsetExclusiveMemoryAddress();
6094 cpu->exclusive_state = 0;
6095
6096 cpu->WriteMemory32(write_addr, RM); 6082 cpu->WriteMemory32(write_addr, RM);
6097 RD = 0; 6083 RD = 0;
6098 } else { 6084 } else {
@@ -6111,10 +6097,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6111 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 6097 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6112 unsigned int write_addr = cpu->Reg[inst_cream->Rn]; 6098 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
6113 6099
6114 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { 6100 if (cpu->IsExclusiveMemoryAccess(write_addr)) {
6115 remove_exclusive(cpu, write_addr); 6101 cpu->UnsetExclusiveMemoryAddress();
6116 cpu->exclusive_state = 0;
6117
6118 Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]); 6102 Memory::Write8(write_addr, cpu->Reg[inst_cream->Rm]);
6119 RD = 0; 6103 RD = 0;
6120 } else { 6104 } else {
@@ -6133,9 +6117,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6133 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 6117 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6134 unsigned int write_addr = cpu->Reg[inst_cream->Rn]; 6118 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
6135 6119
6136 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { 6120 if (cpu->IsExclusiveMemoryAccess(write_addr)) {
6137 remove_exclusive(cpu, write_addr); 6121 cpu->UnsetExclusiveMemoryAddress();
6138 cpu->exclusive_state = 0;
6139 6122
6140 const u32 rt = cpu->Reg[inst_cream->Rm + 0]; 6123 const u32 rt = cpu->Reg[inst_cream->Rm + 0];
6141 const u32 rt2 = cpu->Reg[inst_cream->Rm + 1]; 6124 const u32 rt2 = cpu->Reg[inst_cream->Rm + 1];
@@ -6165,10 +6148,8 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6165 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component; 6148 generic_arm_inst* inst_cream = (generic_arm_inst*)inst_base->component;
6166 unsigned int write_addr = cpu->Reg[inst_cream->Rn]; 6149 unsigned int write_addr = cpu->Reg[inst_cream->Rn];
6167 6150
6168 if ((exclusive_detect(cpu, write_addr) == 0) && (cpu->exclusive_state == 1)) { 6151 if (cpu->IsExclusiveMemoryAccess(write_addr)) {
6169 remove_exclusive(cpu, write_addr); 6152 cpu->UnsetExclusiveMemoryAddress();
6170 cpu->exclusive_state = 0;
6171
6172 cpu->WriteMemory16(write_addr, RM); 6153 cpu->WriteMemory16(write_addr, RM);
6173 RD = 0; 6154 RD = 0;
6174 } else { 6155 } else {
@@ -6216,7 +6197,7 @@ unsigned InterpreterMainLoop(ARMul_State* cpu) {
6216 6197
6217 u32 rn_val = RN; 6198 u32 rn_val = RN;
6218 if (inst_cream->Rn == 15) 6199 if (inst_cream->Rn == 15)
6219 rn_val += 8; 6200 rn_val += 2 * cpu->GetInstructionSize();
6220 6201
6221 bool carry; 6202 bool carry;
6222 bool overflow; 6203 bool overflow;
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.cpp b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
index 2860af376..29272fd5d 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.cpp
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.cpp
@@ -12,15 +12,9 @@
12// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions 12// with the following Thumb instruction held in the high 16-bits. Passing in two Thumb instructions
13// allows easier simulation of the special dual BL instruction. 13// allows easier simulation of the special dual BL instruction.
14 14
15tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) { 15ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
16 tdstate valid = t_uninitialized; 16 ThumbDecodeStatus valid = ThumbDecodeStatus::UNINITIALIZED;
17 u32 tinstr = instr; 17 u32 tinstr = GetThumbInstruction(instr, addr);
18
19 // The endian should be judge here
20 if((addr & 0x3) != 0)
21 tinstr = instr >> 16;
22 else
23 tinstr &= 0xFFFF;
24 18
25 *ainstr = 0xDEADC0DE; // Debugging to catch non updates 19 *ainstr = 0xDEADC0DE; // Debugging to catch non updates
26 20
@@ -357,21 +351,21 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
357 else 351 else
358 *ainstr |= (tinstr & 0x00FF); 352 *ainstr |= (tinstr & 0x00FF);
359 } else if ((tinstr & 0x0F00) != 0x0E00) 353 } else if ((tinstr & 0x0F00) != 0x0E00)
360 valid = t_branch; 354 valid = ThumbDecodeStatus::BRANCH;
361 else // UNDEFINED : cc=1110(AL) uses different format 355 else // UNDEFINED : cc=1110(AL) uses different format
362 valid = t_undefined; 356 valid = ThumbDecodeStatus::UNDEFINED;
363 357
364 break; 358 break;
365 359
366 case 28: // B 360 case 28: // B
367 valid = t_branch; 361 valid = ThumbDecodeStatus::BRANCH;
368 break; 362 break;
369 363
370 case 29: 364 case 29:
371 if(tinstr & 0x1) 365 if (tinstr & 0x1)
372 valid = t_undefined; 366 valid = ThumbDecodeStatus::UNDEFINED;
373 else 367 else
374 valid = t_branch; 368 valid = ThumbDecodeStatus::BRANCH;
375 break; 369 break;
376 370
377 case 30: // BL instruction 1 371 case 30: // BL instruction 1
@@ -380,7 +374,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
380 // simulation simple (from the user perspective) we check if the following instruction is 374 // simulation simple (from the user perspective) we check if the following instruction is
381 // the second half of this BL, and if it is we simulate it immediately 375 // the second half of this BL, and if it is we simulate it immediately
382 376
383 valid = t_branch; 377 valid = ThumbDecodeStatus::BRANCH;
384 break; 378 break;
385 379
386 case 31: // BL instruction 2 380 case 31: // BL instruction 2
@@ -389,7 +383,7 @@ tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size) {
389 // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the 383 // ever be matched with the fmt19 "BL instruction 1" instruction. However, we do allow the
390 // simulation of it on its own, with undefined results if r14 is not suitably initialised. 384 // simulation of it on its own, with undefined results if r14 is not suitably initialised.
391 385
392 valid = t_branch; 386 valid = ThumbDecodeStatus::BRANCH;
393 break; 387 break;
394 } 388 }
395 389
diff --git a/src/core/arm/dyncom/arm_dyncom_thumb.h b/src/core/arm/dyncom/arm_dyncom_thumb.h
index c06f09580..447974363 100644
--- a/src/core/arm/dyncom/arm_dyncom_thumb.h
+++ b/src/core/arm/dyncom/arm_dyncom_thumb.h
@@ -28,20 +28,22 @@
28 28
29#include "common/common_types.h" 29#include "common/common_types.h"
30 30
31enum tdstate { 31enum class ThumbDecodeStatus {
32 t_undefined, // Undefined Thumb instruction 32 UNDEFINED, // Undefined Thumb instruction
33 t_decoded, // Instruction decoded to ARM equivalent 33 DECODED, // Instruction decoded to ARM equivalent
34 t_branch, // Thumb branch (already processed) 34 BRANCH, // Thumb branch (already processed)
35 t_uninitialized, 35 UNINITIALIZED,
36}; 36};
37 37
38tdstate thumb_translate(u32 addr, u32 instr, u32* ainstr, u32* inst_size); 38// Translates a Thumb mode instruction into its ARM equivalent.
39ThumbDecodeStatus TranslateThumbInstruction(u32 addr, u32 instr, u32* ainstr, u32* inst_size);
39 40
40static inline u32 get_thumb_instr(u32 instr, u32 pc) { 41static inline u32 GetThumbInstruction(u32 instr, u32 address) {
41 u32 tinstr; 42 // Normally you would need to handle instruction endianness,
42 if ((pc & 0x3) != 0) 43 // however, it is fixed to little-endian on the MPCore, so
43 tinstr = instr >> 16; 44 // there's no need to check for this beforehand.
44 else 45 if ((address & 0x3) != 0)
45 tinstr = instr & 0xFFFF; 46 return instr >> 16;
46 return tinstr; 47
48 return instr & 0xFFFF;
47} 49}
diff --git a/src/core/arm/skyeye_common/armstate.h b/src/core/arm/skyeye_common/armstate.h
index 88c1dab9d..b364e2621 100644
--- a/src/core/arm/skyeye_common/armstate.h
+++ b/src/core/arm/skyeye_common/armstate.h
@@ -163,6 +163,19 @@ public:
163 u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const; 163 u32 ReadCP15Register(u32 crn, u32 opcode_1, u32 crm, u32 opcode_2) const;
164 void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2); 164 void WriteCP15Register(u32 value, u32 crn, u32 opcode_1, u32 crm, u32 opcode_2);
165 165
166 // Exclusive memory access functions
167 bool IsExclusiveMemoryAccess(u32 address) const {
168 return exclusive_state && exclusive_tag == (address & RESERVATION_GRANULE_MASK);
169 }
170 void SetExclusiveMemoryAddress(u32 address) {
171 exclusive_tag = address & RESERVATION_GRANULE_MASK;
172 exclusive_state = true;
173 }
174 void UnsetExclusiveMemoryAddress() {
175 exclusive_tag = 0xFFFFFFFF;
176 exclusive_state = false;
177 }
178
166 // Whether or not the given CPU is in big endian mode (E bit is set) 179 // Whether or not the given CPU is in big endian mode (E bit is set)
167 bool InBigEndianMode() const { 180 bool InBigEndianMode() const {
168 return (Cpsr & (1 << 9)) != 0; 181 return (Cpsr & (1 << 9)) != 0;
@@ -203,9 +216,6 @@ public:
203 216
204 u32 Mode; // The current mode 217 u32 Mode; // The current mode
205 u32 Bank; // The current register bank 218 u32 Bank; // The current register bank
206 u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
207 u32 exclusive_state;
208 u32 exclusive_result;
209 219
210 u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed 220 u32 NFlag, ZFlag, CFlag, VFlag, IFFlags; // Dummy flags for speed
211 unsigned int shifter_carry_out; 221 unsigned int shifter_carry_out;
@@ -230,4 +240,13 @@ public:
230 240
231private: 241private:
232 void ResetMPCoreCP15Registers(); 242 void ResetMPCoreCP15Registers();
243
244 // Defines a reservation granule of 2 words, which protects the first 2 words starting at the tag.
245 // This is the smallest granule allowed by the v7 spec, and is coincidentally just large enough to
246 // support LDR/STREXD.
247 static const u32 RESERVATION_GRANULE_MASK = 0xFFFFFFF8;
248
249 u32 exclusive_tag; // The address for which the local monitor is in exclusive access mode
250 u32 exclusive_result;
251 bool exclusive_state;
233}; 252};
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 70caa7d80..c35b13b25 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -35,6 +35,16 @@ static Kernel::SharedPtr<Kernel::Event> event_debug_pad;
35static u32 next_pad_index; 35static u32 next_pad_index;
36static u32 next_touch_index; 36static u32 next_touch_index;
37 37
38const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping = {
39 Service::HID::PAD_A, Service::HID::PAD_B, Service::HID::PAD_X, Service::HID::PAD_Y,
40 Service::HID::PAD_L, Service::HID::PAD_R, Service::HID::PAD_ZL, Service::HID::PAD_ZR,
41 Service::HID::PAD_START, Service::HID::PAD_SELECT, Service::HID::PAD_NONE,
42 Service::HID::PAD_UP, Service::HID::PAD_DOWN, Service::HID::PAD_LEFT, Service::HID::PAD_RIGHT,
43 Service::HID::PAD_CIRCLE_UP, Service::HID::PAD_CIRCLE_DOWN, Service::HID::PAD_CIRCLE_LEFT, Service::HID::PAD_CIRCLE_RIGHT,
44 Service::HID::PAD_C_UP, Service::HID::PAD_C_DOWN, Service::HID::PAD_C_LEFT, Service::HID::PAD_C_RIGHT
45};
46
47
38// TODO(peachum): 48// TODO(peachum):
39// Add a method for setting analog input from joystick device for the circle Pad. 49// Add a method for setting analog input from joystick device for the circle Pad.
40// 50//
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index d50d479f8..517f4f2ae 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -9,7 +9,7 @@
9#ifndef _MSC_VER 9#ifndef _MSC_VER
10#include <cstddef> 10#include <cstddef>
11#endif 11#endif
12 12#include "core/settings.h"
13#include "common/bit_field.h" 13#include "common/bit_field.h"
14#include "common/common_funcs.h" 14#include "common/common_funcs.h"
15#include "common/common_types.h" 15#include "common/common_types.h"
@@ -157,6 +157,9 @@ const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
157const PadState PAD_CIRCLE_UP = {{1u << 30}}; 157const PadState PAD_CIRCLE_UP = {{1u << 30}};
158const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; 158const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
159 159
160
161extern const std::array<Service::HID::PadState, Settings::NativeInput::NUM_INPUTS> pad_mapping;
162
160/** 163/**
161 * HID::GetIPCHandles service function 164 * HID::GetIPCHandles service function
162 * Inputs: 165 * Inputs:
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp
index d0e166fdf..d768a3fc7 100644
--- a/src/core/hle/service/soc_u.cpp
+++ b/src/core/hle/service/soc_u.cpp
@@ -481,11 +481,17 @@ static void GetHostId(Service::Interface* self) {
481 481
482 char name[128]; 482 char name[128];
483 gethostname(name, sizeof(name)); 483 gethostname(name, sizeof(name));
484 hostent* host = gethostbyname(name); 484 addrinfo hints = {};
485 in_addr* addr = reinterpret_cast<in_addr*>(host->h_addr); 485 addrinfo* res;
486
487 hints.ai_family = AF_INET;
488 getaddrinfo(name, NULL, &hints, &res);
489 sockaddr_in* sock_addr = reinterpret_cast<sockaddr_in*>(res->ai_addr);
490 in_addr* addr = &sock_addr->sin_addr;
486 491
487 cmd_buffer[2] = addr->s_addr; 492 cmd_buffer[2] = addr->s_addr;
488 cmd_buffer[1] = 0; 493 cmd_buffer[1] = 0;
494 freeaddrinfo(res);
489} 495}
490 496
491static void Close(Service::Interface* self) { 497static void Close(Service::Interface* self) {
diff --git a/src/core/settings.h b/src/core/settings.h
index 5a70d157a..2775ee257 100644
--- a/src/core/settings.h
+++ b/src/core/settings.h
@@ -5,34 +5,42 @@
5#pragma once 5#pragma once
6 6
7#include <string> 7#include <string>
8#include <array>
8 9
9namespace Settings { 10namespace Settings {
10 11
12namespace NativeInput {
13enum Values {
14 A, B, X, Y,
15 L, R, ZL, ZR,
16 START, SELECT, HOME,
17 DUP, DDOWN, DLEFT, DRIGHT,
18 SUP, SDOWN, SLEFT, SRIGHT,
19 CUP, CDOWN, CLEFT, CRIGHT,
20 NUM_INPUTS
21};
22static const std::array<const char*, NUM_INPUTS> Mapping = {
23 "pad_a", "pad_b", "pad_x", "pad_y",
24 "pad_l", "pad_r", "pad_zl", "pad_zr",
25 "pad_start", "pad_select", "pad_home",
26 "pad_dup", "pad_ddown", "pad_dleft", "pad_dright",
27 "pad_sup", "pad_sdown", "pad_sleft", "pad_sright",
28 "pad_cup", "pad_cdown", "pad_cleft", "pad_cright"
29};
30static const std::array<Values, NUM_INPUTS> All = {
31 A, B, X, Y,
32 L, R, ZL, ZR,
33 START, SELECT, HOME,
34 DUP, DDOWN, DLEFT, DRIGHT,
35 SUP, SDOWN, SLEFT, SRIGHT,
36 CUP, CDOWN, CLEFT, CRIGHT
37};
38}
39
40
11struct Values { 41struct Values {
12 // Controls 42 // Controls
13 int pad_a_key; 43 std::array<int, NativeInput::NUM_INPUTS> input_mappings;
14 int pad_b_key;
15 int pad_x_key;
16 int pad_y_key;
17 int pad_l_key;
18 int pad_r_key;
19 int pad_zl_key;
20 int pad_zr_key;
21 int pad_start_key;
22 int pad_select_key;
23 int pad_home_key;
24 int pad_dup_key;
25 int pad_ddown_key;
26 int pad_dleft_key;
27 int pad_dright_key;
28 int pad_sup_key;
29 int pad_sdown_key;
30 int pad_sleft_key;
31 int pad_sright_key;
32 int pad_cup_key;
33 int pad_cdown_key;
34 int pad_cleft_key;
35 int pad_cright_key;
36 44
37 // Core 45 // Core
38 int frame_skip; 46 int frame_skip;