Skip to content

Commit e53fb61

Browse files
committed
Merge branch 'dev'
Conflicts: Emulator/Utilities/Types.h
2 parents 6d5f076 + 96b96ac commit e53fb61

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+5200
-396
lines changed

Emulator/Base/CoreComponentTypes.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ enum_long(OPT)
5454
OPT_CPU_OVERCLOCKING,
5555
OPT_CPU_RESET_VAL,
5656

57+
// FPU
58+
OPT_FPU_REVISION,
59+
5760
// Real-time clock
5861
OPT_RTC_MODEL,
5962

@@ -187,6 +190,8 @@ struct OptionEnum : util::Reflection<OptionEnum, Option>
187190
case OPT_CPU_RESET_VAL: return "CPU_RESET_VAL";
188191
case OPT_CPU_DASM_SYNTAX: return "CPU_DASM_SYNTAX";
189192

193+
case OPT_FPU_REVISION: return "FPU_REVISION";
194+
190195
case OPT_RTC_MODEL: return "RTC_MODEL";
191196

192197
case OPT_CHIP_RAM: return "CHIP_RAM";

Emulator/Base/Defaults.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Defaults::Defaults()
6969
setFallback(OPT_CPU_DASM_SYNTAX, DASM_SYNTAX_MOIRA);
7070
setFallback(OPT_CPU_OVERCLOCKING, 0);
7171
setFallback(OPT_CPU_RESET_VAL, 0);
72+
setFallback(OPT_FPU_REVISION, FPU_INTERNAL);
7273
setFallback(OPT_RTC_MODEL, RTC_OKI);
7374
setFallback(OPT_CHIP_RAM, 512);
7475
setFallback(OPT_SLOW_RAM, 512);

Emulator/Base/Thread.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Thread::execute<THREAD_ADAPTIVE>()
5858
}
5959

6060
// Compute all missing frames
61-
for (isize i = 0; i < missing; i++) execute();
61+
for (isize i = 0; i < missing && isRunning(); i++) execute();
6262

6363
loadClock.stop();
6464
}

Emulator/Components/Amiga.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,7 @@ Amiga::getConfigItem(Option option) const
296296
case OPT_CPU_DASM_SYNTAX:
297297
case OPT_CPU_OVERCLOCKING:
298298
case OPT_CPU_RESET_VAL:
299+
case OPT_FPU_REVISION:
299300

300301
return cpu.getConfigItem(option);
301302

@@ -562,7 +563,8 @@ Amiga::configure(Option option, i64 value)
562563
case OPT_CPU_OVERCLOCKING:
563564
case OPT_CPU_RESET_VAL:
564565
case OPT_CPU_DASM_SYNTAX:
565-
566+
case OPT_FPU_REVISION:
567+
566568
cpu.setConfigItem(option, value);
567569
break;
568570

@@ -830,6 +832,7 @@ Amiga::configure(ConfigScheme scheme)
830832
case CONFIG_A1000_OCS_1MB:
831833

832834
configure(OPT_CPU_REVISION, CPU_68000);
835+
configure(OPT_FPU_REVISION, FPU_INTERNAL);
833836
configure(OPT_AGNUS_REVISION, AGNUS_OCS_OLD);
834837
configure(OPT_DENISE_REVISION, DENISE_OCS);
835838
configure(OPT_VIDEO_FORMAT, PAL);
@@ -840,6 +843,7 @@ Amiga::configure(ConfigScheme scheme)
840843
case CONFIG_A500_OCS_1MB:
841844

842845
configure(OPT_CPU_REVISION, CPU_68000);
846+
configure(OPT_FPU_REVISION, FPU_INTERNAL);
843847
configure(OPT_AGNUS_REVISION, AGNUS_OCS);
844848
configure(OPT_DENISE_REVISION, DENISE_OCS);
845849
configure(OPT_VIDEO_FORMAT, PAL);
@@ -850,6 +854,7 @@ Amiga::configure(ConfigScheme scheme)
850854
case CONFIG_A500_ECS_1MB:
851855

852856
configure(OPT_CPU_REVISION, CPU_68000);
857+
configure(OPT_FPU_REVISION, FPU_INTERNAL);
853858
configure(OPT_AGNUS_REVISION, AGNUS_ECS_1MB);
854859
configure(OPT_DENISE_REVISION, DENISE_OCS);
855860
configure(OPT_VIDEO_FORMAT, PAL);
@@ -860,13 +865,14 @@ Amiga::configure(ConfigScheme scheme)
860865
case CONFIG_A500_PLUS_1MB:
861866

862867
configure(OPT_CPU_REVISION, CPU_68000);
868+
configure(OPT_FPU_REVISION, FPU_INTERNAL);
863869
configure(OPT_AGNUS_REVISION, AGNUS_ECS_2MB);
864870
configure(OPT_DENISE_REVISION, DENISE_ECS);
865871
configure(OPT_VIDEO_FORMAT, PAL);
866872
configure(OPT_CHIP_RAM, 512);
867873
configure(OPT_SLOW_RAM, 512);
868874
break;
869-
875+
870876
default:
871877
fatalError;
872878
}

Emulator/Components/Amiga.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,9 @@ class Amiga : public Thread {
288288
// Reverts to factory settings
289289
void revertToFactorySettings();
290290

291-
291+
// Returns whether experimental FPU support should be enabled
292+
bool fpuSupport() { return FPU_SUPPORT; }
293+
292294
private:
293295

294296
// Overrides a config option if the corresponding debug option is enabled

Emulator/Components/AmigaTypes.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,6 @@ struct ConfigSchemeEnum : util::Reflection<ConfigSchemeEnum, ConfigScheme>
125125
case CONFIG_A1000_OCS_1MB: return "A1000_OCS_1MB";
126126
case CONFIG_A500_OCS_1MB: return "A500_OCS_1MB";
127127
case CONFIG_A500_ECS_1MB: return "A500_ECS_1MB";
128-
case CONFIG_A500_PLUS_1MB: return "A500_PLUS_1MB";
129128
}
130129
return "???";
131130
}

Emulator/Components/CPU/CPU.cpp

Lines changed: 77 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@
1414
#include "IOUtils.h"
1515
#include "Memory.h"
1616
#include "MsgQueue.h"
17-
#include "softfloat.h"
1817

1918
//
2019
// Moira
2120
//
2221

23-
2422
namespace vamiga::moira {
2523

2624
void
@@ -141,7 +139,13 @@ Moira::willExecute(const char *func, Instr I, Mode M, Size S, u16 opcode)
141139
break;
142140

143141
default:
142+
{
143+
144+
char str[128];
145+
disassemble(str, reg.pc0);
146+
printf("%s\n", str);
144147
break;
148+
}
145149
}
146150
}
147151

@@ -288,6 +292,8 @@ CPU::getConfigItem(Option option) const
288292
case OPT_CPU_OVERCLOCKING: return (long)config.overclocking;
289293
case OPT_CPU_RESET_VAL: return (long)config.regResetVal;
290294

295+
case OPT_FPU_REVISION: return (long)config.fpuRevision;
296+
291297
default:
292298
fatalError;
293299
}
@@ -297,6 +303,7 @@ void
297303
CPU::setConfigItem(Option option, i64 value)
298304
{
299305
auto cpuModel = [&](CPURevision rev) { return moira::Model(rev); };
306+
auto fpuModel = [&](FPURevision rev) { return moira::FPUModel(rev); };
300307
auto dasmModel = [&](DasmRevision rev) { return moira::Model(rev); };
301308
auto syntax = [&](DasmSyntax rev) { return moira::DasmSyntax(rev); };
302309

@@ -314,6 +321,22 @@ CPU::setConfigItem(Option option, i64 value)
314321
resume();
315322
return;
316323

324+
case OPT_FPU_REVISION:
325+
326+
if (!amiga.fpuSupport()) {
327+
throw VAError(ERROR_OPT_UNSUPPORTED);
328+
}
329+
330+
if (!FPURevisionEnum::isValid(value)) {
331+
throw VAError(ERROR_OPT_INVARG, FPURevisionEnum::keyList());
332+
}
333+
334+
suspend();
335+
config.fpuRevision = FPURevision(value);
336+
cpu.setFpuModel(fpuModel(config.fpuRevision));
337+
resume();
338+
return;
339+
317340
case OPT_CPU_DASM_REVISION:
318341

319342
if (!DasmRevisionEnum::isValid(value)) {
@@ -365,8 +388,12 @@ CPU::resetConfig()
365388
std::vector <Option> options = {
366389

367390
OPT_CPU_REVISION,
391+
OPT_CPU_DASM_REVISION,
392+
OPT_CPU_DASM_SYNTAX,
368393
OPT_CPU_OVERCLOCKING,
369-
OPT_CPU_RESET_VAL
394+
OPT_CPU_RESET_VAL,
395+
396+
OPT_FPU_REVISION
370397
};
371398

372399
for (auto &option : options) {
@@ -460,8 +487,13 @@ CPU::_dump(Category category, std::ostream& os) const
460487

461488
if (category == Category::Config) {
462489

490+
string fputxt =
491+
config.fpuRevision == FPU_INTERNAL ? " (none)" : " (external coprocessor)";
492+
463493
os << util::tab("CPU revision");
464494
os << CPURevisionEnum::key(config.revision) << std::endl;
495+
os << util::tab("FPU revision");
496+
os << FPURevisionEnum::key(config.fpuRevision) << fputxt << std::endl;
465497
os << util::tab("DASM revision");
466498
os << DasmRevisionEnum::key(config.dasmRevision) << std::endl;
467499
os << util::tab("DASM syntax");
@@ -547,22 +579,39 @@ CPU::_dump(Category category, std::ostream& os) const
547579
}
548580

549581
if (category == Category::Fpu) {
550-
551-
os << util::tab("FPIAR");
552-
os << util::hex(fpu.fpiar) << std::endl;
553-
os << util::tab("FPSR");
554-
os << util::hex(fpu.fpsr) << std::endl;
582+
555583
os << util::tab("FPCR");
556584
os << util::hex(fpu.fpcr) << std::endl;
557-
558-
/*
559-
for (isize i = 0; i < 8; i++) {
560-
561-
auto value = softfloat::floatx80_to_float32(fpu.fpr[i].raw);
562-
os << util::tab("FP" + std::to_string(i));
563-
os << util::hex(u32(value)) << std::endl;
564-
}
565-
*/
585+
os << util::tab("FPSR");
586+
os << util::hex(fpu.fpsr) << std::endl;
587+
os << util::tab("FPIAR");
588+
os << util::hex(fpu.fpiar) << std::endl;
589+
os << std::endl;
590+
591+
os << util::tab("Rounding mode");
592+
switch (fpu.getRoundingMode()) {
593+
case moira::FPU_RND_NEAREST: os << "NEAREST"; break;
594+
case moira::FPU_RND_ZERO: os << "ZERO"; break;
595+
case moira::FPU_RND_DOWNWARD: os << "DOWNWARD"; break;
596+
case moira::FPU_RND_UPWARD: os << "UPDWARD"; break;
597+
}
598+
os << std::endl;
599+
os << util::tab("Precision");
600+
switch (fpu.getPrecision()) {
601+
case moira::FPU_PREC_EXTENDED: os << "EXTENDED"; break;
602+
case moira::FPU_PREC_SINGLE: os << "SINGLE"; break;
603+
case moira::FPU_PREC_DOUBLE: os << "DOUBLE"; break;
604+
case moira::FPU_PREC_UNDEFINED: os << "UNDEFINED"; break;
605+
}
606+
os << std::endl << std::endl;
607+
608+
for (isize i = 0; i < 8; i++) {
609+
610+
os << util::tab("FP" + std::to_string(i));
611+
// os << fpu.fpr[i] << std::endl;
612+
os << util::hex(fpu.fpr[i].val.raw.high) << ":";
613+
os << util::hex(fpu.fpr[i].val.raw.low) << std::endl;
614+
}
566615
}
567616

568617
if (category == Category::Breakpoints) {
@@ -638,6 +687,7 @@ CPU::_trackOff()
638687
debugger.disableLogging();
639688
}
640689

690+
/*
641691
isize
642692
CPU::_load(const u8 *buffer)
643693
{
@@ -653,10 +703,19 @@ CPU::_load(const u8 *buffer)
653703
654704
return isize(reader.ptr - buffer);
655705
}
706+
*/
656707

657708
isize
658709
CPU::didLoadFromBuffer(const u8 *buffer)
659710
{
711+
auto cpuModel = (moira::Model)config.revision;
712+
auto fpuModel = (moira::FPUModel)config.fpuRevision;
713+
auto dasmModel = (moira::Model)config.dasmRevision;
714+
715+
// Rectify the CPU and FPU type
716+
setModel(cpuModel, dasmModel);
717+
fpu.setModel(fpuModel);
718+
660719
/* Because we don't save breakpoints and watchpoints in a snapshot, the
661720
* CPU flags for checking breakpoints and watchpoints can be in a corrupt
662721
* state after loading. These flags need to be updated according to the
@@ -741,7 +800,7 @@ CPU::disassembleWords(u32 addr, isize len)
741800
{
742801
static char result[64];
743802

744-
dump16(result, addr, len);
803+
dump16(result, addr, (int)len);
745804
return result;
746805
}
747806

Emulator/Components/CPU/CPU.h

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class CPU : public moira::Moira {
7676
worker
7777

7878
<< config.revision
79+
<< config.fpuRevision
7980
<< config.dasmRevision
8081
<< config.overclocking
8182
<< config.regResetVal;
@@ -128,13 +129,34 @@ class CPU : public moira::Moira {
128129
<< loopModeDelay
129130
<< readBuffer
130131
<< writeBuffer
131-
<< flags;
132+
<< flags
133+
134+
// << fpu.model
135+
<< fpu.fpr[0].val.raw.high
136+
<< fpu.fpr[0].val.raw.low
137+
<< fpu.fpr[1].val.raw.high
138+
<< fpu.fpr[1].val.raw.low
139+
<< fpu.fpr[2].val.raw.high
140+
<< fpu.fpr[2].val.raw.low
141+
<< fpu.fpr[3].val.raw.high
142+
<< fpu.fpr[3].val.raw.low
143+
<< fpu.fpr[4].val.raw.high
144+
<< fpu.fpr[4].val.raw.low
145+
<< fpu.fpr[5].val.raw.high
146+
<< fpu.fpr[5].val.raw.low
147+
<< fpu.fpr[6].val.raw.high
148+
<< fpu.fpr[6].val.raw.low
149+
<< fpu.fpr[7].val.raw.high
150+
<< fpu.fpr[7].val.raw.low
151+
<< fpu.fpcr
152+
<< fpu.fpsr
153+
<< fpu.fpiar;
132154
}
133155
}
134156

135157
isize _size() override { COMPUTE_SNAPSHOT_SIZE }
136158
u64 _checksum() override { COMPUTE_SNAPSHOT_CHECKSUM }
137-
isize _load(const u8 *buffer) override;
159+
isize _load(const u8 *buffer) override { LOAD_SNAPSHOT_ITEMS }
138160
isize _save(u8 *buffer) override { SAVE_SNAPSHOT_ITEMS }
139161
isize didLoadFromBuffer(const u8 *buffer) override;
140162

Emulator/Components/CPU/CPUTypes.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ struct CPURevisionEnum : util::Reflection<CPURevisionEnum, CPURevision>
5252
};
5353
#endif
5454

55+
enum_long(FPU_REVISION)
56+
{
57+
FPU_INTERNAL,
58+
FPU_68881,
59+
FPU_68882
60+
};
61+
typedef FPU_REVISION FPURevision;
62+
63+
#ifdef __cplusplus
64+
struct FPURevisionEnum : util::Reflection<FPURevisionEnum, FPURevision>
65+
{
66+
static constexpr long minVal = 0;
67+
static constexpr long maxVal = FPU_68882;
68+
static bool isValid(auto val) { return val >= minVal && val <= maxVal; }
69+
70+
static const char *prefix() { return "FPU"; }
71+
static const char *key(CPURevision value)
72+
{
73+
switch (value) {
74+
75+
case FPU_INTERNAL: return "INTERNAL";
76+
case FPU_68881: return "68881";
77+
case FPU_68882: return "68882";
78+
}
79+
return "???";
80+
}
81+
};
82+
#endif
83+
5584
enum_long(DASM_REVISION)
5685
{
5786
DASM_68000,
@@ -134,6 +163,7 @@ struct DasmSyntaxEnum : util::Reflection<DasmSyntaxEnum, DasmSyntax>
134163
typedef struct
135164
{
136165
CPURevision revision;
166+
FPURevision fpuRevision;
137167
DasmRevision dasmRevision;
138168
DasmSyntax dasmSyntax;
139169
isize overclocking;

Emulator/Components/CPU/Moira/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,7 @@ target_include_directories(vAmigaCore PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
33
target_sources(vAmigaCore PRIVATE
44

55
Moira.cpp
6+
MoiraFPU.cpp
67
MoiraDebugger.cpp
8+
FpuFormats.cpp
79
)

0 commit comments

Comments
 (0)