diff options
| -rw-r--r-- | appveyor.yml | 17 | ||||
| -rw-r--r-- | src/citra_qt/bootmanager.cpp | 19 | ||||
| -rw-r--r-- | src/citra_qt/bootmanager.h | 12 | ||||
| -rw-r--r-- | src/citra_qt/debugger/callstack.cpp | 7 | ||||
| -rw-r--r-- | src/citra_qt/debugger/callstack.h | 3 | ||||
| -rw-r--r-- | src/citra_qt/debugger/disassembler.cpp | 7 | ||||
| -rw-r--r-- | src/citra_qt/debugger/disassembler.h | 3 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_framebuffer.cpp | 8 | ||||
| -rw-r--r-- | src/citra_qt/debugger/graphics_framebuffer.h | 4 | ||||
| -rw-r--r-- | src/citra_qt/debugger/registers.cpp | 7 | ||||
| -rw-r--r-- | src/citra_qt/debugger/registers.h | 3 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 14 | ||||
| -rw-r--r-- | src/core/arm/dyncom/arm_dyncom_interpreter.cpp | 60 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 3 |
14 files changed, 117 insertions, 50 deletions
diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..83d3b900e --- /dev/null +++ b/appveyor.yml | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | # it seems that Qt is only installed by default on unstable os at the moment | ||
| 2 | os: unstable | ||
| 3 | |||
| 4 | # shallow clone | ||
| 5 | clone_depth: 1 | ||
| 6 | |||
| 7 | environment: | ||
| 8 | QTDIR: C:\Qt\5.4\msvc2013_opengl | ||
| 9 | |||
| 10 | install: | ||
| 11 | - git submodule update --init --recursive | ||
| 12 | |||
| 13 | before_build: | ||
| 14 | - mkdir build | ||
| 15 | - cd build | ||
| 16 | - cmake .. | ||
| 17 | - cd .. | ||
diff --git a/src/citra_qt/bootmanager.cpp b/src/citra_qt/bootmanager.cpp index 3e24da596..196380105 100644 --- a/src/citra_qt/bootmanager.cpp +++ b/src/citra_qt/bootmanager.cpp | |||
| @@ -40,18 +40,35 @@ void EmuThread::SetFilename(std::string filename) | |||
| 40 | void EmuThread::run() | 40 | void EmuThread::run() |
| 41 | { | 41 | { |
| 42 | stop_run = false; | 42 | stop_run = false; |
| 43 | |||
| 44 | // holds whether the cpu was running during the last iteration, | ||
| 45 | // so that the DebugModeLeft signal can be emitted before the | ||
| 46 | // next execution step | ||
| 47 | bool was_active = false; | ||
| 43 | while (!stop_run) | 48 | while (!stop_run) |
| 44 | { | 49 | { |
| 45 | if (cpu_running) | 50 | if (cpu_running) |
| 46 | { | 51 | { |
| 52 | if (!was_active) | ||
| 53 | emit DebugModeLeft(); | ||
| 54 | |||
| 47 | Core::RunLoop(); | 55 | Core::RunLoop(); |
| 56 | |||
| 57 | was_active = cpu_running || exec_cpu_step; | ||
| 58 | if (!was_active) | ||
| 59 | emit DebugModeEntered(); | ||
| 48 | } | 60 | } |
| 49 | else if (exec_cpu_step) | 61 | else if (exec_cpu_step) |
| 50 | { | 62 | { |
| 63 | if (!was_active) | ||
| 64 | emit DebugModeLeft(); | ||
| 65 | |||
| 51 | exec_cpu_step = false; | 66 | exec_cpu_step = false; |
| 52 | Core::SingleStep(); | 67 | Core::SingleStep(); |
| 53 | emit CPUStepped(); | 68 | emit DebugModeEntered(); |
| 54 | yieldCurrentThread(); | 69 | yieldCurrentThread(); |
| 70 | |||
| 71 | was_active = false; | ||
| 55 | } | 72 | } |
| 56 | } | 73 | } |
| 57 | render_window->moveContext(); | 74 | render_window->moveContext(); |
diff --git a/src/citra_qt/bootmanager.h b/src/citra_qt/bootmanager.h index 1c893384c..a55db682a 100644 --- a/src/citra_qt/bootmanager.h +++ b/src/citra_qt/bootmanager.h | |||
| @@ -81,12 +81,18 @@ private: | |||
| 81 | 81 | ||
| 82 | signals: | 82 | signals: |
| 83 | /** | 83 | /** |
| 84 | * Emitted when CPU when we've finished processing a single Gekko instruction | 84 | * Emitted when the CPU has halted execution |
| 85 | * | 85 | * |
| 86 | * @warning This will only be emitted when the CPU is not running (SetCpuRunning(false)) | ||
| 87 | * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns) | 86 | * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns) |
| 88 | */ | 87 | */ |
| 89 | void CPUStepped(); | 88 | void DebugModeEntered(); |
| 89 | |||
| 90 | /** | ||
| 91 | * Emitted right before the CPU continues execution | ||
| 92 | * | ||
| 93 | * @warning When connecting to this signal from other threads, make sure to specify either Qt::QueuedConnection (invoke slot within the destination object's message thread) or even Qt::BlockingQueuedConnection (additionally block source thread until slot returns) | ||
| 94 | */ | ||
| 95 | void DebugModeLeft(); | ||
| 90 | }; | 96 | }; |
| 91 | 97 | ||
| 92 | class GRenderWindow : public QWidget, public EmuWindow | 98 | class GRenderWindow : public QWidget, public EmuWindow |
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp index 274c5cccd..025a5896b 100644 --- a/src/citra_qt/debugger/callstack.cpp +++ b/src/citra_qt/debugger/callstack.cpp | |||
| @@ -25,7 +25,7 @@ CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent) | |||
| 25 | ui.treeView->setModel(callstack_model); | 25 | ui.treeView->setModel(callstack_model); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | void CallstackWidget::OnCPUStepped() | 28 | void CallstackWidget::OnDebugModeEntered() |
| 29 | { | 29 | { |
| 30 | ARM_Disasm* disasm = new ARM_Disasm(); | 30 | ARM_Disasm* disasm = new ARM_Disasm(); |
| 31 | ARM_Interface* app_core = Core::g_app_core; | 31 | ARM_Interface* app_core = Core::g_app_core; |
| @@ -71,3 +71,8 @@ void CallstackWidget::OnCPUStepped() | |||
| 71 | } | 71 | } |
| 72 | } | 72 | } |
| 73 | } | 73 | } |
| 74 | |||
| 75 | void CallstackWidget::OnDebugModeLeft() | ||
| 76 | { | ||
| 77 | |||
| 78 | } | ||
diff --git a/src/citra_qt/debugger/callstack.h b/src/citra_qt/debugger/callstack.h index 4f4f74823..fb390f5c3 100644 --- a/src/citra_qt/debugger/callstack.h +++ b/src/citra_qt/debugger/callstack.h | |||
| @@ -15,7 +15,8 @@ public: | |||
| 15 | CallstackWidget(QWidget* parent = 0); | 15 | CallstackWidget(QWidget* parent = 0); |
| 16 | 16 | ||
| 17 | public slots: | 17 | public slots: |
| 18 | void OnCPUStepped(); | 18 | void OnDebugModeEntered(); |
| 19 | void OnDebugModeLeft(); | ||
| 19 | 20 | ||
| 20 | private: | 21 | private: |
| 21 | Ui::CallStack ui; | 22 | Ui::CallStack ui; |
diff --git a/src/citra_qt/debugger/disassembler.cpp b/src/citra_qt/debugger/disassembler.cpp index da084ab24..c61ace925 100644 --- a/src/citra_qt/debugger/disassembler.cpp +++ b/src/citra_qt/debugger/disassembler.cpp | |||
| @@ -235,7 +235,7 @@ void DisassemblerWidget::OnToggleStartStop() | |||
| 235 | emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning()); | 235 | emu_thread.SetCpuRunning(!emu_thread.IsCpuRunning()); |
| 236 | } | 236 | } |
| 237 | 237 | ||
| 238 | void DisassemblerWidget::OnCPUStepped() | 238 | void DisassemblerWidget::OnDebugModeEntered() |
| 239 | { | 239 | { |
| 240 | ARMword next_instr = Core::g_app_core->GetPC(); | 240 | ARMword next_instr = Core::g_app_core->GetPC(); |
| 241 | 241 | ||
| @@ -252,6 +252,11 @@ void DisassemblerWidget::OnCPUStepped() | |||
| 252 | disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); | 252 | disasm_ui.treeView->selectionModel()->setCurrentIndex(model_index, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); |
| 253 | } | 253 | } |
| 254 | 254 | ||
| 255 | void DisassemblerWidget::OnDebugModeLeft() | ||
| 256 | { | ||
| 257 | |||
| 258 | } | ||
| 259 | |||
| 255 | int DisassemblerWidget::SelectedRow() | 260 | int DisassemblerWidget::SelectedRow() |
| 256 | { | 261 | { |
| 257 | QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex(); | 262 | QModelIndex index = disasm_ui.treeView->selectionModel()->currentIndex(); |
diff --git a/src/citra_qt/debugger/disassembler.h b/src/citra_qt/debugger/disassembler.h index 6d3cef108..0deccc240 100644 --- a/src/citra_qt/debugger/disassembler.h +++ b/src/citra_qt/debugger/disassembler.h | |||
| @@ -61,7 +61,8 @@ public slots: | |||
| 61 | void OnPause(); | 61 | void OnPause(); |
| 62 | void OnToggleStartStop(); | 62 | void OnToggleStartStop(); |
| 63 | 63 | ||
| 64 | void OnCPUStepped(); | 64 | void OnDebugModeEntered(); |
| 65 | void OnDebugModeLeft(); | ||
| 65 | 66 | ||
| 66 | private: | 67 | private: |
| 67 | // returns -1 if no row is selected | 68 | // returns -1 if no row is selected |
diff --git a/src/citra_qt/debugger/graphics_framebuffer.cpp b/src/citra_qt/debugger/graphics_framebuffer.cpp index caa6896f9..a9423d6c7 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.cpp +++ b/src/citra_qt/debugger/graphics_framebuffer.cpp | |||
| @@ -158,17 +158,17 @@ void GraphicsFramebufferWidget::OnFramebufferAddressChanged(qint64 new_value) | |||
| 158 | } | 158 | } |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | void GraphicsFramebufferWidget::OnFramebufferWidthChanged(unsigned int new_value) | 161 | void GraphicsFramebufferWidget::OnFramebufferWidthChanged(int new_value) |
| 162 | { | 162 | { |
| 163 | if (framebuffer_width != new_value) { | 163 | if (framebuffer_width != static_cast<unsigned>(new_value)) { |
| 164 | framebuffer_width = new_value; | 164 | framebuffer_width = static_cast<unsigned>(new_value); |
| 165 | 165 | ||
| 166 | framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom)); | 166 | framebuffer_source_list->setCurrentIndex(static_cast<int>(Source::Custom)); |
| 167 | emit Update(); | 167 | emit Update(); |
| 168 | } | 168 | } |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | void GraphicsFramebufferWidget::OnFramebufferHeightChanged(unsigned int new_value) | 171 | void GraphicsFramebufferWidget::OnFramebufferHeightChanged(int new_value) |
| 172 | { | 172 | { |
| 173 | if (framebuffer_height != new_value) { | 173 | if (framebuffer_height != new_value) { |
| 174 | framebuffer_height = new_value; | 174 | framebuffer_height = new_value; |
diff --git a/src/citra_qt/debugger/graphics_framebuffer.h b/src/citra_qt/debugger/graphics_framebuffer.h index 02813525c..56215761e 100644 --- a/src/citra_qt/debugger/graphics_framebuffer.h +++ b/src/citra_qt/debugger/graphics_framebuffer.h | |||
| @@ -62,8 +62,8 @@ public: | |||
| 62 | public slots: | 62 | public slots: |
| 63 | void OnFramebufferSourceChanged(int new_value); | 63 | void OnFramebufferSourceChanged(int new_value); |
| 64 | void OnFramebufferAddressChanged(qint64 new_value); | 64 | void OnFramebufferAddressChanged(qint64 new_value); |
| 65 | void OnFramebufferWidthChanged(unsigned int new_value); | 65 | void OnFramebufferWidthChanged(int new_value); |
| 66 | void OnFramebufferHeightChanged(unsigned int new_value); | 66 | void OnFramebufferHeightChanged(int new_value); |
| 67 | void OnFramebufferFormatChanged(int new_value); | 67 | void OnFramebufferFormatChanged(int new_value); |
| 68 | void OnUpdate(); | 68 | void OnUpdate(); |
| 69 | 69 | ||
diff --git a/src/citra_qt/debugger/registers.cpp b/src/citra_qt/debugger/registers.cpp index e982dfb3f..ab3666156 100644 --- a/src/citra_qt/debugger/registers.cpp +++ b/src/citra_qt/debugger/registers.cpp | |||
| @@ -41,7 +41,7 @@ RegistersWidget::RegistersWidget(QWidget* parent) : QDockWidget(parent) | |||
| 41 | CSPR->addChild(new QTreeWidgetItem(QStringList("N"))); | 41 | CSPR->addChild(new QTreeWidgetItem(QStringList("N"))); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void RegistersWidget::OnCPUStepped() | 44 | void RegistersWidget::OnDebugModeEntered() |
| 45 | { | 45 | { |
| 46 | ARM_Interface* app_core = Core::g_app_core; | 46 | ARM_Interface* app_core = Core::g_app_core; |
| 47 | 47 | ||
| @@ -65,3 +65,8 @@ void RegistersWidget::OnCPUStepped() | |||
| 65 | CSPR->child(13)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 30) & 0x1)); // Z - Zero | 65 | CSPR->child(13)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 30) & 0x1)); // Z - Zero |
| 66 | CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than | 66 | CSPR->child(14)->setText(1, QString("%1").arg((app_core->GetCPSR() >> 31) & 0x1)); // N - Negative/Less than |
| 67 | } | 67 | } |
| 68 | |||
| 69 | void RegistersWidget::OnDebugModeLeft() | ||
| 70 | { | ||
| 71 | |||
| 72 | } | ||
diff --git a/src/citra_qt/debugger/registers.h b/src/citra_qt/debugger/registers.h index ac8429f2b..bf8955625 100644 --- a/src/citra_qt/debugger/registers.h +++ b/src/citra_qt/debugger/registers.h | |||
| @@ -17,7 +17,8 @@ public: | |||
| 17 | RegistersWidget(QWidget* parent = NULL); | 17 | RegistersWidget(QWidget* parent = NULL); |
| 18 | 18 | ||
| 19 | public slots: | 19 | public slots: |
| 20 | void OnCPUStepped(); | 20 | void OnDebugModeEntered(); |
| 21 | void OnDebugModeLeft(); | ||
| 21 | 22 | ||
| 22 | private: | 23 | private: |
| 23 | Ui::ARMRegisters cpu_regs_ui; | 24 | Ui::ARMRegisters cpu_regs_ui; |
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index c6671bef1..ece593e5d 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp | |||
| @@ -124,9 +124,13 @@ GMainWindow::GMainWindow() | |||
| 124 | connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog())); | 124 | connect(ui.action_Hotkeys, SIGNAL(triggered()), this, SLOT(OnOpenHotkeysDialog())); |
| 125 | 125 | ||
| 126 | // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues | 126 | // BlockingQueuedConnection is important here, it makes sure we've finished refreshing our views before the CPU continues |
| 127 | connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), disasmWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); | 127 | connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), disasmWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); |
| 128 | connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), registersWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); | 128 | connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), registersWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); |
| 129 | connect(&render_window->GetEmuThread(), SIGNAL(CPUStepped()), callstackWidget, SLOT(OnCPUStepped()), Qt::BlockingQueuedConnection); | 129 | connect(&render_window->GetEmuThread(), SIGNAL(DebugModeEntered()), callstackWidget, SLOT(OnDebugModeEntered()), Qt::BlockingQueuedConnection); |
| 130 | |||
| 131 | connect(&render_window->GetEmuThread(), SIGNAL(DebugModeLeft()), disasmWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection); | ||
| 132 | connect(&render_window->GetEmuThread(), SIGNAL(DebugModeLeft()), registersWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection); | ||
| 133 | connect(&render_window->GetEmuThread(), SIGNAL(DebugModeLeft()), callstackWidget, SLOT(OnDebugModeLeft()), Qt::BlockingQueuedConnection); | ||
| 130 | 134 | ||
| 131 | // Setup hotkeys | 135 | // Setup hotkeys |
| 132 | RegisterHotkey("Main Window", "Load File", QKeySequence::Open); | 136 | RegisterHotkey("Main Window", "Load File", QKeySequence::Open); |
| @@ -167,8 +171,8 @@ void GMainWindow::BootGame(std::string filename) | |||
| 167 | } | 171 | } |
| 168 | 172 | ||
| 169 | disasmWidget->Init(); | 173 | disasmWidget->Init(); |
| 170 | registersWidget->OnCPUStepped(); | 174 | registersWidget->OnDebugModeEntered(); |
| 171 | callstackWidget->OnCPUStepped(); | 175 | callstackWidget->OnDebugModeEntered(); |
| 172 | 176 | ||
| 173 | render_window->GetEmuThread().SetFilename(filename); | 177 | render_window->GetEmuThread().SetFilename(filename); |
| 174 | render_window->GetEmuThread().start(); | 178 | render_window->GetEmuThread().start(); |
diff --git a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp index e3ca02e98..4759c7653 100644 --- a/src/core/arm/dyncom/arm_dyncom_interpreter.cpp +++ b/src/core/arm/dyncom/arm_dyncom_interpreter.cpp | |||
| @@ -4964,39 +4964,41 @@ unsigned InterpreterMainLoop(ARMul_State* state) { | |||
| 4964 | } | 4964 | } |
| 4965 | MSR_INST: | 4965 | MSR_INST: |
| 4966 | { | 4966 | { |
| 4967 | msr_inst *inst_cream = (msr_inst *)inst_base->component; | 4967 | if (inst_base->cond == 0xE || CondPassed(cpu, inst_base->cond)) { |
| 4968 | const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; | 4968 | msr_inst *inst_cream = (msr_inst *)inst_base->component; |
| 4969 | unsigned int inst = inst_cream->inst; | 4969 | const uint32_t UnallocMask = 0x06f0fc00, UserMask = 0xf80f0200, PrivMask = 0x000001df, StateMask = 0x01000020; |
| 4970 | unsigned int operand; | 4970 | unsigned int inst = inst_cream->inst; |
| 4971 | unsigned int operand; | ||
| 4971 | 4972 | ||
| 4972 | if (BIT(inst, 25)) { | 4973 | if (BIT(inst, 25)) { |
| 4973 | int rot_imm = BITS(inst, 8, 11) * 2; | 4974 | int rot_imm = BITS(inst, 8, 11) * 2; |
| 4974 | operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); | 4975 | operand = ROTATE_RIGHT_32(BITS(inst, 0, 7), rot_imm); |
| 4975 | } else { | ||
| 4976 | operand = cpu->Reg[BITS(inst, 0, 3)]; | ||
| 4977 | } | ||
| 4978 | uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) | ||
| 4979 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); | ||
| 4980 | uint32_t mask; | ||
| 4981 | if (!inst_cream->R) { | ||
| 4982 | if (InAPrivilegedMode(cpu)) { | ||
| 4983 | if ((operand & StateMask) != 0) { | ||
| 4984 | /// UNPREDICTABLE | ||
| 4985 | DEBUG_MSG; | ||
| 4986 | } else | ||
| 4987 | mask = byte_mask & (UserMask | PrivMask); | ||
| 4988 | } else { | 4976 | } else { |
| 4989 | mask = byte_mask & UserMask; | 4977 | operand = cpu->Reg[BITS(inst, 0, 3)]; |
| 4990 | } | 4978 | } |
| 4991 | SAVE_NZCVT; | 4979 | uint32_t byte_mask = (BIT(inst, 16) ? 0xff : 0) | (BIT(inst, 17) ? 0xff00 : 0) |
| 4980 | | (BIT(inst, 18) ? 0xff0000 : 0) | (BIT(inst, 19) ? 0xff000000 : 0); | ||
| 4981 | uint32_t mask; | ||
| 4982 | if (!inst_cream->R) { | ||
| 4983 | if (InAPrivilegedMode(cpu)) { | ||
| 4984 | if ((operand & StateMask) != 0) { | ||
| 4985 | /// UNPREDICTABLE | ||
| 4986 | DEBUG_MSG; | ||
| 4987 | } else | ||
| 4988 | mask = byte_mask & (UserMask | PrivMask); | ||
| 4989 | } else { | ||
| 4990 | mask = byte_mask & UserMask; | ||
| 4991 | } | ||
| 4992 | SAVE_NZCVT; | ||
| 4992 | 4993 | ||
| 4993 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); | 4994 | cpu->Cpsr = (cpu->Cpsr & ~mask) | (operand & mask); |
| 4994 | switch_mode(cpu, cpu->Cpsr & 0x1f); | 4995 | switch_mode(cpu, cpu->Cpsr & 0x1f); |
| 4995 | LOAD_NZCVT; | 4996 | LOAD_NZCVT; |
| 4996 | } else { | 4997 | } else { |
| 4997 | if (CurrentModeHasSPSR) { | 4998 | if (CurrentModeHasSPSR) { |
| 4998 | mask = byte_mask & (UserMask | PrivMask | StateMask); | 4999 | mask = byte_mask & (UserMask | PrivMask | StateMask); |
| 4999 | cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); | 5000 | cpu->Spsr_copy = (cpu->Spsr_copy & ~mask) | (operand & mask); |
| 5001 | } | ||
| 5000 | } | 5002 | } |
| 5001 | } | 5003 | } |
| 5002 | cpu->Reg[15] += GET_INST_SIZE(cpu); | 5004 | cpu->Reg[15] += GET_INST_SIZE(cpu); |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index dd20ca30e..bc86a7c59 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -263,6 +263,9 @@ void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds) { | |||
| 263 | 263 | ||
| 264 | /// Resumes a thread from waiting by marking it as "ready" | 264 | /// Resumes a thread from waiting by marking it as "ready" |
| 265 | void Thread::ResumeFromWait() { | 265 | void Thread::ResumeFromWait() { |
| 266 | // Cancel any outstanding wakeup events | ||
| 267 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, GetHandle()); | ||
| 268 | |||
| 266 | status &= ~THREADSTATUS_WAIT; | 269 | status &= ~THREADSTATUS_WAIT; |
| 267 | wait_object = nullptr; | 270 | wait_object = nullptr; |
| 268 | wait_type = WAITTYPE_NONE; | 271 | wait_type = WAITTYPE_NONE; |