diff --git a/Emulator/Base/CoreComponentTypes.h b/Emulator/Base/CoreComponentTypes.h index e79ed4c13..77c8fc9eb 100644 --- a/Emulator/Base/CoreComponentTypes.h +++ b/Emulator/Base/CoreComponentTypes.h @@ -54,6 +54,9 @@ enum_long(OPT) OPT_CPU_OVERCLOCKING, OPT_CPU_RESET_VAL, + // FPU + OPT_FPU_REVISION, + // Real-time clock OPT_RTC_MODEL, @@ -187,6 +190,8 @@ struct OptionEnum : util::Reflection case OPT_CPU_RESET_VAL: return "CPU_RESET_VAL"; case OPT_CPU_DASM_SYNTAX: return "CPU_DASM_SYNTAX"; + case OPT_FPU_REVISION: return "FPU_REVISION"; + case OPT_RTC_MODEL: return "RTC_MODEL"; case OPT_CHIP_RAM: return "CHIP_RAM"; diff --git a/Emulator/Base/Defaults.cpp b/Emulator/Base/Defaults.cpp index 1faf43d42..6d80469fc 100644 --- a/Emulator/Base/Defaults.cpp +++ b/Emulator/Base/Defaults.cpp @@ -69,6 +69,7 @@ Defaults::Defaults() setFallback(OPT_CPU_DASM_SYNTAX, DASM_SYNTAX_MOIRA); setFallback(OPT_CPU_OVERCLOCKING, 0); setFallback(OPT_CPU_RESET_VAL, 0); + setFallback(OPT_FPU_REVISION, FPU_INTERNAL); setFallback(OPT_RTC_MODEL, RTC_OKI); setFallback(OPT_CHIP_RAM, 512); setFallback(OPT_SLOW_RAM, 512); diff --git a/Emulator/Base/Thread.cpp b/Emulator/Base/Thread.cpp index 106dc47ee..12337cf4f 100644 --- a/Emulator/Base/Thread.cpp +++ b/Emulator/Base/Thread.cpp @@ -58,7 +58,7 @@ Thread::execute() } // Compute all missing frames - for (isize i = 0; i < missing; i++) execute(); + for (isize i = 0; i < missing && isRunning(); i++) execute(); loadClock.stop(); } diff --git a/Emulator/Components/Amiga.cpp b/Emulator/Components/Amiga.cpp index f617c5e88..cd937f7a1 100644 --- a/Emulator/Components/Amiga.cpp +++ b/Emulator/Components/Amiga.cpp @@ -296,6 +296,7 @@ Amiga::getConfigItem(Option option) const case OPT_CPU_DASM_SYNTAX: case OPT_CPU_OVERCLOCKING: case OPT_CPU_RESET_VAL: + case OPT_FPU_REVISION: return cpu.getConfigItem(option); @@ -562,7 +563,8 @@ Amiga::configure(Option option, i64 value) case OPT_CPU_OVERCLOCKING: case OPT_CPU_RESET_VAL: case OPT_CPU_DASM_SYNTAX: - + case OPT_FPU_REVISION: + cpu.setConfigItem(option, value); break; @@ -830,6 +832,7 @@ Amiga::configure(ConfigScheme scheme) case CONFIG_A1000_OCS_1MB: configure(OPT_CPU_REVISION, CPU_68000); + configure(OPT_FPU_REVISION, FPU_INTERNAL); configure(OPT_AGNUS_REVISION, AGNUS_OCS_OLD); configure(OPT_DENISE_REVISION, DENISE_OCS); configure(OPT_VIDEO_FORMAT, PAL); @@ -840,6 +843,7 @@ Amiga::configure(ConfigScheme scheme) case CONFIG_A500_OCS_1MB: configure(OPT_CPU_REVISION, CPU_68000); + configure(OPT_FPU_REVISION, FPU_INTERNAL); configure(OPT_AGNUS_REVISION, AGNUS_OCS); configure(OPT_DENISE_REVISION, DENISE_OCS); configure(OPT_VIDEO_FORMAT, PAL); @@ -850,6 +854,7 @@ Amiga::configure(ConfigScheme scheme) case CONFIG_A500_ECS_1MB: configure(OPT_CPU_REVISION, CPU_68000); + configure(OPT_FPU_REVISION, FPU_INTERNAL); configure(OPT_AGNUS_REVISION, AGNUS_ECS_1MB); configure(OPT_DENISE_REVISION, DENISE_OCS); configure(OPT_VIDEO_FORMAT, PAL); @@ -860,13 +865,14 @@ Amiga::configure(ConfigScheme scheme) case CONFIG_A500_PLUS_1MB: configure(OPT_CPU_REVISION, CPU_68000); + configure(OPT_FPU_REVISION, FPU_INTERNAL); configure(OPT_AGNUS_REVISION, AGNUS_ECS_2MB); configure(OPT_DENISE_REVISION, DENISE_ECS); configure(OPT_VIDEO_FORMAT, PAL); configure(OPT_CHIP_RAM, 512); configure(OPT_SLOW_RAM, 512); break; - + default: fatalError; } diff --git a/Emulator/Components/Amiga.h b/Emulator/Components/Amiga.h index b0ff4ca45..5bbec09c1 100644 --- a/Emulator/Components/Amiga.h +++ b/Emulator/Components/Amiga.h @@ -288,7 +288,9 @@ class Amiga : public Thread { // Reverts to factory settings void revertToFactorySettings(); - + // Returns whether experimental FPU support should be enabled + bool fpuSupport() { return FPU_SUPPORT; } + private: // Overrides a config option if the corresponding debug option is enabled diff --git a/Emulator/Components/AmigaTypes.h b/Emulator/Components/AmigaTypes.h index 975e1d676..6f7add977 100644 --- a/Emulator/Components/AmigaTypes.h +++ b/Emulator/Components/AmigaTypes.h @@ -125,7 +125,6 @@ struct ConfigSchemeEnum : util::Reflection case CONFIG_A1000_OCS_1MB: return "A1000_OCS_1MB"; case CONFIG_A500_OCS_1MB: return "A500_OCS_1MB"; case CONFIG_A500_ECS_1MB: return "A500_ECS_1MB"; - case CONFIG_A500_PLUS_1MB: return "A500_PLUS_1MB"; } return "???"; } diff --git a/Emulator/Components/CPU/CPU.cpp b/Emulator/Components/CPU/CPU.cpp index 0c2b08649..1a5cd2ee5 100644 --- a/Emulator/Components/CPU/CPU.cpp +++ b/Emulator/Components/CPU/CPU.cpp @@ -14,13 +14,11 @@ #include "IOUtils.h" #include "Memory.h" #include "MsgQueue.h" -#include "softfloat.h" // // Moira // - namespace vamiga::moira { void @@ -141,7 +139,13 @@ Moira::willExecute(const char *func, Instr I, Mode M, Size S, u16 opcode) break; default: + { + + char str[128]; + disassemble(str, reg.pc0); + printf("%s\n", str); break; + } } } @@ -288,6 +292,8 @@ CPU::getConfigItem(Option option) const case OPT_CPU_OVERCLOCKING: return (long)config.overclocking; case OPT_CPU_RESET_VAL: return (long)config.regResetVal; + case OPT_FPU_REVISION: return (long)config.fpuRevision; + default: fatalError; } @@ -297,6 +303,7 @@ void CPU::setConfigItem(Option option, i64 value) { auto cpuModel = [&](CPURevision rev) { return moira::Model(rev); }; + auto fpuModel = [&](FPURevision rev) { return moira::FPUModel(rev); }; auto dasmModel = [&](DasmRevision rev) { return moira::Model(rev); }; auto syntax = [&](DasmSyntax rev) { return moira::DasmSyntax(rev); }; @@ -314,6 +321,22 @@ CPU::setConfigItem(Option option, i64 value) resume(); return; + case OPT_FPU_REVISION: + + if (!amiga.fpuSupport()) { + throw VAError(ERROR_OPT_UNSUPPORTED); + } + + if (!FPURevisionEnum::isValid(value)) { + throw VAError(ERROR_OPT_INVARG, FPURevisionEnum::keyList()); + } + + suspend(); + config.fpuRevision = FPURevision(value); + cpu.setFpuModel(fpuModel(config.fpuRevision)); + resume(); + return; + case OPT_CPU_DASM_REVISION: if (!DasmRevisionEnum::isValid(value)) { @@ -365,8 +388,12 @@ CPU::resetConfig() std::vector