Permalink
Browse files

Cocoa Port: Give user feedback for when the emulation gets halted int…

…ernally.

- Also be more consistent when recovering from an internal emulation halt.
- Also apply enabling the external BIOS, external firmware and firmware boot settings at load/reset time instead of at frame time.
  • Loading branch information...
rogerman committed Sep 19, 2017
1 parent 1c59441 commit 830dd0d78cbcfbc952a4b67b359e7491d7145f56
View
@@ -1490,7 +1490,7 @@ void FASTCALL MMU_writeToSPIData(u16 val)
{
printf("SYSTEM POWERED OFF VIA ARM7 SPI POWER DEVICE\n");
printf("Did your main() return?\n");
emu_halt();
emu_halt(EMUHALT_REASON_SYSTEM_POWERED_OFF, NDSErrorTag_None);
}
}
View
@@ -83,11 +83,12 @@ BaseDriver* driver = &_stub_driver;
std::string InputDisplayString;
static BOOL LidClosed = FALSE;
static u8 countLid = 0;
static u8 countLid = 0;
static NDSError _lastNDSError;
GameInfo gameInfo;
NDSSystem nds;
CFIRMWARE *firmware = NULL;
CFIRMWARE *firmware = NULL;
using std::min;
using std::max;
@@ -2663,6 +2664,10 @@ void NDS_Reset()
//this needs to happen last, pretty much, since it establishes the correct scheduling state based on all of the above initialization
initSchedule();
_lastNDSError.code = NDSError_NoError;
_lastNDSError.tag = NDSErrorTag_None;
NDS_CurrentCPUInfoToNDSError(_lastNDSError);
}
static std::string MakeInputDisplayString(u16 pad, const std::string* Buttons, int count) {
@@ -3019,12 +3024,59 @@ void NDS_swapScreen()
}
}
NDSError NDS_GetLastError()
{
return _lastNDSError;
}
void emu_halt()
static void NDS_CurrentCPUInfoToNDSError(NDSError &ndsError)
{
//printf("halting emu: ARM9 PC=%08X/%08X, ARM7 PC=%08X/%08X\n", NDS_ARM9.R[15], NDS_ARM9.instruct_adr, NDS_ARM7.R[15], NDS_ARM7.instruct_adr);
execute = false;
ndsError.programCounterARM9 = NDS_ARM9.R[15];
ndsError.instructionARM9 = NDS_ARM9.instruction;
ndsError.instructionAddrARM9 = NDS_ARM9.instruct_adr;
ndsError.programCounterARM7 = NDS_ARM7.R[15];
ndsError.instructionARM7 = NDS_ARM7.instruction;
ndsError.instructionAddrARM7 = NDS_ARM7.instruct_adr;
}
void emu_halt(EmuHaltReasonCode reasonCode, NDSErrorTag errorTag)
{
switch (reasonCode)
{
case EMUHALT_REASON_USER_REQUESTED_HALT:
_lastNDSError.code = NDSError_NoError;
_lastNDSError.tag = NDSErrorTag_None;
break;
case EMUHALT_REASON_SYSTEM_POWERED_OFF:
_lastNDSError.code = NDSError_SystemPoweredOff;
_lastNDSError.tag = NDSErrorTag_None;
break;
case EMUHALT_REASON_JIT_UNMAPPED_ADDRESS_EXCEPTION:
_lastNDSError.code = NDSError_JITUnmappedAddressException;
_lastNDSError.tag = errorTag;
break;
case EMUHALT_REASON_ARM_RESERVED_0X14_EXCEPTION:
case EMUHALT_REASON_ARM_UNDEFINED_INSTRUCTION_EXCEPTION:
_lastNDSError.code = NDSError_ARMUndefinedInstructionException;
_lastNDSError.tag = errorTag;
break;
case EMUHALT_REASON_UNKNOWN:
default:
_lastNDSError.code = NDSError_UnknownError;
_lastNDSError.tag = errorTag;
break;
}
NDS_CurrentCPUInfoToNDSError(_lastNDSError);
GPU->ForceFrameStop();
execute = false;
//printf("halting emu: ARM9 PC=%08X/%08X, ARM7 PC=%08X/%08X\n", NDS_ARM9.R[15], NDS_ARM9.instruct_adr, NDS_ARM7.R[15], NDS_ARM7.instruct_adr);
#ifdef LOG_ARM9
if (fp_dis9)
View
@@ -82,6 +82,52 @@ enum
ROM_DSGBA
};
enum EmuHaltReasonCode
{
EMUHALT_REASON_USER_REQUESTED_HALT = 0,
EMUHALT_REASON_SYSTEM_POWERED_OFF = 1000,
EMUHALT_REASON_JIT_UNMAPPED_ADDRESS_EXCEPTION = 2000,
EMUHALT_REASON_ARM_RESERVED_0X14_EXCEPTION,
EMUHALT_REASON_ARM_UNDEFINED_INSTRUCTION_EXCEPTION,
EMUHALT_REASON_UNKNOWN = 10000
};
enum NDSErrorCode
{
NDSError_NoError = 0,
NDSError_SystemPoweredOff = 1000,
NDSError_JITUnmappedAddressException = 2000,
NDSError_ARMUndefinedInstructionException,
NDSError_UnknownError = 10000
};
enum NDSErrorTag
{
NDSErrorTag_None = 0,
NDSErrorTag_ARM9 = 1,
NDSErrorTag_ARM7 = 2,
NDSErrorTag_BothCPUs = 3,
};
struct NDSError
{
NDSErrorCode code;
NDSErrorTag tag;
u32 programCounterARM9;
u32 instructionARM9;
u32 instructionAddrARM9;
u32 programCounterARM7;
u32 instructionARM7;
u32 instructionAddrARM7;
};
typedef struct NDSError NDSError;
//#define LOG_ARM9
//#define LOG_ARM7
@@ -143,7 +189,9 @@ struct NDS_header
#include "PACKED_END.h"
extern void debug();
void emu_halt();
NDSError NDS_GetLastError();
static void NDS_CurrentCPUInfoToNDSError(NDSError &ndsError);
void emu_halt(EmuHaltReasonCode reasonCode, NDSErrorTag errorTag);
extern u64 nds_timer;
void NDS_Reschedule();
View
@@ -498,7 +498,7 @@ void armcpu_exception(armcpu_t *cpu, u32 number)
case EXCEPTION_SWI: cpumode = SVC; break;
case EXCEPTION_PREFETCH_ABORT: cpumode = ABT; break;
case EXCEPTION_DATA_ABORT: cpumode = ABT; break;
case EXCEPTION_RESERVED_0x14: emu_halt(); break;
case EXCEPTION_RESERVED_0x14: emu_halt(EMUHALT_REASON_ARM_RESERVED_0X14_EXCEPTION, (cpu->proc_ID == ARMCPU_ARM9) ? NDSErrorTag_ARM9 : NDSErrorTag_ARM7); break;
case EXCEPTION_IRQ: cpumode = IRQ; break;
case EXCEPTION_FAST_IRQ: cpumode = FIQ; break;
}
@@ -576,7 +576,7 @@ u32 TRAPUNDEF(armcpu_t* cpu)
}
else
{
emu_halt();
emu_halt(EMUHALT_REASON_ARM_UNDEFINED_INSTRUCTION_EXCEPTION, (cpu->proc_ID == ARMCPU_ARM9) ? NDSErrorTag_ARM9 : NDSErrorTag_ARM7);
return 4;
}
}
@@ -379,20 +379,20 @@ void ClientExecutionControl::SetEnableGameSpecificHacks(bool enable)
bool ClientExecutionControl::GetEnableExternalBIOS()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
const bool enable = this->_settingsPending.enableExternalBIOS;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return enable;
}
void ClientExecutionControl::SetEnableExternalBIOS(bool enable)
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_settingsPending.enableExternalBIOS = enable;
this->_newSettingsPendingOnNDSExec = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnNDSExec);
this->_newSettingsPendingOnReset = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
bool ClientExecutionControl::GetEnableBIOSInterrupts()
@@ -433,38 +433,38 @@ void ClientExecutionControl::SetEnableBIOSPatchDelayLoop(bool enable)
bool ClientExecutionControl::GetEnableExternalFirmware()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
const bool enable = this->_settingsPending.enableExternalFirmware;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return enable;
}
void ClientExecutionControl::SetEnableExternalFirmware(bool enable)
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_settingsPending.enableExternalFirmware = enable;
this->_newSettingsPendingOnNDSExec = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnNDSExec);
this->_newSettingsPendingOnReset = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
bool ClientExecutionControl::GetEnableFirmwareBoot()
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
const bool enable = this->_settingsPending.enableFirmwareBoot;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
return enable;
}
void ClientExecutionControl::SetEnableFirmwareBoot(bool enable)
{
pthread_mutex_lock(&this->_mutexSettingsPendingOnNDSExec);
pthread_mutex_lock(&this->_mutexSettingsPendingOnReset);
this->_settingsPending.enableFirmwareBoot = enable;
this->_newSettingsPendingOnNDSExec = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnNDSExec);
this->_newSettingsPendingOnReset = true;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
}
bool ClientExecutionControl::GetEnableDebugConsole()
@@ -702,18 +702,22 @@ void ClientExecutionControl::ApplySettingsOnReset()
if (this->_newSettingsPendingOnReset)
{
this->_settingsApplied.cpuEngineID = this->_settingsPending.cpuEngineID;
this->_settingsApplied.JITMaxBlockSize = this->_settingsPending.JITMaxBlockSize;
this->_settingsApplied.cpuEngineID = this->_settingsPending.cpuEngineID;
this->_settingsApplied.JITMaxBlockSize = this->_settingsPending.JITMaxBlockSize;
this->_settingsApplied.filePathARM9BIOS = this->_settingsPending.filePathARM9BIOS;
this->_settingsApplied.filePathARM7BIOS = this->_settingsPending.filePathARM7BIOS;
this->_settingsApplied.filePathFirmware = this->_settingsPending.filePathFirmware;
this->_settingsApplied.filePathSlot1R4 = this->_settingsPending.filePathSlot1R4;
this->_settingsApplied.filePathARM9BIOS = this->_settingsPending.filePathARM9BIOS;
this->_settingsApplied.filePathARM7BIOS = this->_settingsPending.filePathARM7BIOS;
this->_settingsApplied.filePathFirmware = this->_settingsPending.filePathFirmware;
this->_settingsApplied.filePathSlot1R4 = this->_settingsPending.filePathSlot1R4;
this->_settingsApplied.cpuEmulationEngineName = this->_settingsPending.cpuEmulationEngineName;
this->_settingsApplied.slot1DeviceName = this->_settingsPending.slot1DeviceName;
this->_ndsFrameInfo.cpuEmulationEngineName = this->_settingsApplied.cpuEmulationEngineName;
this->_ndsFrameInfo.slot1DeviceName = this->_settingsApplied.slot1DeviceName;
this->_settingsApplied.enableExternalBIOS = this->_settingsPending.enableExternalBIOS;
this->_settingsApplied.enableExternalFirmware = this->_settingsPending.enableExternalFirmware;
this->_settingsApplied.enableFirmwareBoot = this->_settingsPending.enableFirmwareBoot;
this->_settingsApplied.cpuEmulationEngineName = this->_settingsPending.cpuEmulationEngineName;
this->_settingsApplied.slot1DeviceName = this->_settingsPending.slot1DeviceName;
this->_ndsFrameInfo.cpuEmulationEngineName = this->_settingsApplied.cpuEmulationEngineName;
this->_ndsFrameInfo.slot1DeviceName = this->_settingsApplied.slot1DeviceName;
const bool didChangeSlot1Type = (this->_settingsApplied.slot1DeviceType != this->_settingsPending.slot1DeviceType);
if (didChangeSlot1Type)
@@ -724,8 +728,12 @@ void ClientExecutionControl::ApplySettingsOnReset()
this->_newSettingsPendingOnReset = false;
pthread_mutex_unlock(&this->_mutexSettingsPendingOnReset);
CommonSettings.use_jit = (this->_settingsApplied.cpuEngineID == CPUEmulationEngineID_DynamicRecompiler);
CommonSettings.jit_max_block_size = this->_settingsApplied.JITMaxBlockSize;
CommonSettings.use_jit = (this->_settingsApplied.cpuEngineID == CPUEmulationEngineID_DynamicRecompiler);
CommonSettings.jit_max_block_size = this->_settingsApplied.JITMaxBlockSize;
CommonSettings.UseExtBIOS = this->_settingsApplied.enableExternalBIOS;
CommonSettings.UseExtFirmware = this->_settingsApplied.enableExternalFirmware;
CommonSettings.UseExtFirmwareSettings = this->_settingsApplied.enableExternalFirmware;
CommonSettings.BootFromFirmware = this->_settingsApplied.enableFirmwareBoot;
if (this->_settingsApplied.filePathARM9BIOS.length() == 0)
{
@@ -842,11 +850,8 @@ void ClientExecutionControl::ApplySettingsOnNDSExec()
this->_settingsApplied.enableAdvancedBusLevelTiming = this->_settingsPending.enableAdvancedBusLevelTiming;
this->_settingsApplied.enableRigorous3DRenderingTiming = this->_settingsPending.enableRigorous3DRenderingTiming;
this->_settingsApplied.enableGameSpecificHacks = this->_settingsPending.enableGameSpecificHacks;
this->_settingsApplied.enableExternalBIOS = this->_settingsPending.enableExternalBIOS;
this->_settingsApplied.enableBIOSInterrupts = this->_settingsPending.enableBIOSInterrupts;
this->_settingsApplied.enableBIOSPatchDelayLoop = this->_settingsPending.enableBIOSPatchDelayLoop;
this->_settingsApplied.enableExternalFirmware = this->_settingsPending.enableExternalFirmware;
this->_settingsApplied.enableFirmwareBoot = this->_settingsPending.enableFirmwareBoot;
this->_settingsApplied.enableDebugConsole = this->_settingsPending.enableDebugConsole;
this->_settingsApplied.enableEnsataEmulation = this->_settingsPending.enableEnsataEmulation;
@@ -862,12 +867,8 @@ void ClientExecutionControl::ApplySettingsOnNDSExec()
CommonSettings.advanced_timing = this->_settingsApplied.enableAdvancedBusLevelTiming;
CommonSettings.rigorous_timing = this->_settingsApplied.enableRigorous3DRenderingTiming;
CommonSettings.UseExtBIOS = this->_settingsApplied.enableExternalBIOS;
CommonSettings.SWIFromBIOS = this->_settingsApplied.enableBIOSInterrupts;
CommonSettings.PatchSWI3 = this->_settingsApplied.enableBIOSPatchDelayLoop;
CommonSettings.UseExtFirmware = this->_settingsApplied.enableExternalFirmware;
CommonSettings.UseExtFirmwareSettings = this->_settingsApplied.enableExternalFirmware;
CommonSettings.BootFromFirmware = this->_settingsApplied.enableFirmwareBoot;
CommonSettings.DebugConsole = this->_settingsApplied.enableDebugConsole;
CommonSettings.EnsataEmulation = this->_settingsApplied.enableEnsataEmulation;
@@ -1422,6 +1422,11 @@
ABAE30BD1869484F00C92F4F /* Image_Piano.png in Resources */ = {isa = PBXBuildFile; fileRef = ABAE30BA1869484F00C92F4F /* Image_Piano.png */; };
ABAE30BE1869484F00C92F4F /* Image_Piano.png in Resources */ = {isa = PBXBuildFile; fileRef = ABAE30BA1869484F00C92F4F /* Image_Piano.png */; };
ABAE30BF1869484F00C92F4F /* Image_Piano.png in Resources */ = {isa = PBXBuildFile; fileRef = ABAE30BA1869484F00C92F4F /* Image_Piano.png */; };
ABAFD2751F7110E4007705BD /* gdbstub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF171345ACA900AF11D1 /* gdbstub.cpp */; };
ABAFD2761F7110E4007705BD /* gdbstub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF171345ACA900AF11D1 /* gdbstub.cpp */; };
ABAFD2771F7110E5007705BD /* gdbstub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF171345ACA900AF11D1 /* gdbstub.cpp */; };
ABAFD2781F7110E5007705BD /* gdbstub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF171345ACA900AF11D1 /* gdbstub.cpp */; };
ABAFD2791F7110E6007705BD /* gdbstub.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABD1FF171345ACA900AF11D1 /* gdbstub.cpp */; };
ABB6AD5D173A3F2B00EC2E8D /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = ABB6AD5C173A3F2B00EC2E8D /* Carbon.framework */; };
ABB9212117CEB4110049D4C5 /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB9212017CEB4110049D4C5 /* slot1comp_protocol.cpp */; };
ABB9212217CEB4110049D4C5 /* slot1comp_protocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ABB9212017CEB4110049D4C5 /* slot1comp_protocol.cpp */; };
@@ -4611,6 +4616,7 @@
ABD4F2741F54A51000D75A1F /* ClientExecutionControl.cpp in Sources */,
ABC04DA41F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */,
ABC04DCB1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */,
ABAFD2791F7110E6007705BD /* gdbstub.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -4798,6 +4804,7 @@
ABD4F2751F54A51000D75A1F /* ClientExecutionControl.cpp in Sources */,
ABC04DA51F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */,
ABC04DCC1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */,
ABAFD2781F7110E5007705BD /* gdbstub.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -5015,6 +5022,7 @@
ABD4F2731F54A51000D75A1F /* ClientExecutionControl.cpp in Sources */,
ABC04DA31F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */,
ABC04DCA1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */,
ABAFD2751F7110E4007705BD /* gdbstub.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -5232,6 +5240,7 @@
ABD4F2771F54A51000D75A1F /* ClientExecutionControl.cpp in Sources */,
ABC04DA71F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */,
ABC04DCE1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */,
ABAFD2761F7110E4007705BD /* gdbstub.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -5419,6 +5428,7 @@
ABD4F2761F54A51000D75A1F /* ClientExecutionControl.cpp in Sources */,
ABC04DA61F67A20500EA6ED7 /* ClientInputHandler.cpp in Sources */,
ABC04DCD1F67A2AC00EA6ED7 /* macosx_10_5_compat.cpp in Sources */,
ABAFD2771F7110E5007705BD /* gdbstub.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -5625,6 +5635,7 @@
GCC_PREPROCESSOR_DEFINITIONS = (
_DEBUG,
"DEBUG=1",
GDB_STUB,
);
GCC_STRICT_ALIASING = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
Oops, something went wrong.

0 comments on commit 830dd0d

Please sign in to comment.