From 882384b1f334b4b2a465ecb8ee3538be24a1fd68 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 10 May 2023 15:06:39 -0500 Subject: [PATCH 01/10] Disambiguate Storage.hpp. --- OSBindings/Mac/Clock SignalTests/TimeTests.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock SignalTests/TimeTests.mm b/OSBindings/Mac/Clock SignalTests/TimeTests.mm index 788395245..9f7b1755a 100644 --- a/OSBindings/Mac/Clock SignalTests/TimeTests.mm +++ b/OSBindings/Mac/Clock SignalTests/TimeTests.mm @@ -8,7 +8,7 @@ #import -#include "Storage.hpp" +#include "../../../Storage/Storage.hpp" @interface TimeTests : XCTestCase @end From 25a245e35c04703b287351ff22053c9ad8926a21 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 10 May 2023 15:17:00 -0500 Subject: [PATCH 02/10] Flailingly switch things until tests run. --- OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index fd6fd9a67..480346c72 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -6406,7 +6406,7 @@ 4B055A6E1FAE763F0060FFFF /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; FRAMEWORK_SEARCH_PATHS = ( @@ -6572,7 +6572,7 @@ CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES; CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES; CODE_SIGN_ENTITLEMENTS = "Clock Signal/Clock Signal.entitlements"; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; ENABLE_APP_SANDBOX = YES; @@ -6647,7 +6647,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; ENABLE_HARDENED_RUNTIME = NO; @@ -6665,7 +6665,7 @@ BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_CXX_LANGUAGE_STANDARD = "c++17"; CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-"; + "CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development"; CODE_SIGN_STYLE = Automatic; DEAD_CODE_STRIPPING = YES; ENABLE_HARDENED_RUNTIME = NO; From 2b56b7be0d2f22b2496cd401c4835b2c80b1cae1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 10 May 2023 16:02:18 -0500 Subject: [PATCH 03/10] Simplify namespace syntax. --- Analyser/Dynamic/ConfidenceCounter.hpp | 4 +-- Analyser/Dynamic/ConfidenceSource.hpp | 4 +-- Analyser/Dynamic/ConfidenceSummary.hpp | 4 +-- .../Implementation/MultiConfigurable.hpp | 4 +-- .../Implementation/MultiJoystickMachine.hpp | 4 +-- .../Implementation/MultiKeyboardMachine.hpp | 4 +-- .../Implementation/MultiMediaTarget.hpp | 4 +-- .../Implementation/MultiProducer.hpp | 5 +-- .../Implementation/MultiSpeaker.hpp | 4 +-- .../Dynamic/MultiMachine/MultiMachine.hpp | 4 +-- Analyser/Static/Acorn/Disk.hpp | 6 +--- Analyser/Static/Acorn/File.hpp | 6 +--- Analyser/Static/Acorn/StaticAnalyser.hpp | 6 +--- Analyser/Static/Acorn/Tape.hpp | 6 +--- Analyser/Static/Acorn/Target.hpp | 6 +--- Analyser/Static/Amiga/StaticAnalyser.hpp | 7 +--- Analyser/Static/Amiga/Target.hpp | 6 +--- Analyser/Static/AmstradCPC/StaticAnalyser.hpp | 6 +--- Analyser/Static/AmstradCPC/Target.hpp | 7 +--- Analyser/Static/AppleII/StaticAnalyser.hpp | 6 +--- Analyser/Static/AppleII/Target.hpp | 6 +--- Analyser/Static/AppleIIgs/StaticAnalyser.hpp | 6 +--- Analyser/Static/AppleIIgs/Target.hpp | 6 +--- Analyser/Static/Atari2600/StaticAnalyser.hpp | 6 +--- Analyser/Static/Atari2600/Target.hpp | 6 +--- Analyser/Static/AtariST/StaticAnalyser.hpp | 7 +--- Analyser/Static/AtariST/Target.hpp | 6 +--- Analyser/Static/Coleco/StaticAnalyser.hpp | 6 +--- Analyser/Static/Commodore/Disk.hpp | 6 +--- Analyser/Static/Commodore/File.hpp | 6 +--- Analyser/Static/Commodore/StaticAnalyser.hpp | 6 +--- Analyser/Static/Commodore/Tape.hpp | 6 +--- Analyser/Static/Commodore/Target.hpp | 6 +--- Analyser/Static/Disassembler/6502.hpp | 6 +--- .../Static/Disassembler/AddressMapper.hpp | 6 +--- Analyser/Static/Disassembler/Kernel.hpp | 6 +--- Analyser/Static/Disassembler/Z80.hpp | 6 +--- Analyser/Static/DiskII/StaticAnalyser.hpp | 7 +--- Analyser/Static/Enterprise/StaticAnalyser.hpp | 7 +--- Analyser/Static/Enterprise/Target.hpp | 6 +--- Analyser/Static/MSX/Cartridge.hpp | 6 +--- Analyser/Static/MSX/StaticAnalyser.hpp | 6 +--- Analyser/Static/MSX/Tape.hpp | 6 +--- Analyser/Static/MSX/Target.hpp | 6 +--- Analyser/Static/Macintosh/StaticAnalyser.hpp | 7 +--- Analyser/Static/Macintosh/Target.hpp | 6 +--- Analyser/Static/Oric/StaticAnalyser.hpp | 6 +--- Analyser/Static/Oric/Tape.hpp | 6 +--- Analyser/Static/Oric/Target.hpp | 6 +--- Analyser/Static/Sega/StaticAnalyser.hpp | 6 +--- Analyser/Static/Sega/Target.hpp | 6 +--- Analyser/Static/StaticAnalyser.hpp | 4 +-- Analyser/Static/ZX8081/StaticAnalyser.hpp | 6 +--- Analyser/Static/ZX8081/Target.hpp | 6 +--- Analyser/Static/ZXSpectrum/StaticAnalyser.hpp | 6 +--- Analyser/Static/ZXSpectrum/Target.hpp | 6 +--- Components/5380/ncr5380.hpp | 4 +-- Components/6522/6522.hpp | 4 +-- .../Implementation/6522Implementation.hpp | 4 +-- .../6522/Implementation/6522Storage.hpp | 4 +-- Components/6526/6526.hpp | 4 +-- .../Implementation/6526Implementation.hpp | 4 +-- .../6526/Implementation/6526Storage.hpp | 4 +-- Components/6560/6560.hpp | 4 +-- Components/6845/CRTC6845.hpp | 4 +-- Components/6850/6850.hpp | 4 +-- Components/68901/MFP68901.hpp | 4 +-- Components/8255/i8255.hpp | 4 +-- Components/8272/i8272.hpp | 4 +-- Components/8530/z8530.hpp | 5 +-- Components/AY38910/AY38910.hpp | 4 +-- Components/AppleClock/AppleClock.hpp | 4 +-- Components/DiskII/DiskIIDrive.hpp | 4 +-- .../DiskII/MacintoshDoubleDensityDrive.hpp | 4 +-- .../OPx/Implementation/EnvelopeGenerator.hpp | 4 +-- .../OPx/Implementation/KeyLevelScaler.hpp | 5 +-- .../Implementation/LowFrequencyOscillator.hpp | 4 +-- Components/OPx/Implementation/OPLBase.hpp | 4 +-- .../OPx/Implementation/PhaseGenerator.hpp | 4 +-- Components/OPx/Implementation/Tables.hpp | 4 +-- .../OPx/Implementation/WaveformGenerator.hpp | 4 +-- Components/OPx/OPLL.hpp | 4 +-- Components/RP5C01/RP5C01.hpp | 6 +--- InstructionSets/6809/OperationMapper.hpp | 4 +-- InstructionSets/AccessType.hpp | 1 - InstructionSets/M50740/Decoder.hpp | 4 +-- InstructionSets/M50740/Executor.hpp | 4 +-- InstructionSets/M50740/Instruction.hpp | 5 +-- InstructionSets/M50740/Parser.hpp | 4 +-- InstructionSets/M68k/Decoder.hpp | 4 +-- InstructionSets/M68k/ExceptionVectors.hpp | 4 +-- InstructionSets/M68k/Executor.hpp | 4 +-- .../Implementation/ExecutorImplementation.hpp | 4 +-- .../InstructionOperandFlags.hpp | 4 +-- .../Implementation/InstructionOperandSize.hpp | 4 +-- .../Implementation/PerformImplementation.hpp | 4 +-- InstructionSets/M68k/Instruction.hpp | 4 +-- InstructionSets/M68k/Model.hpp | 4 +-- InstructionSets/M68k/Perform.hpp | 4 +-- InstructionSets/M68k/RegisterSet.hpp | 4 +-- InstructionSets/M68k/Status.hpp | 4 +-- InstructionSets/PowerPC/Decoder.hpp | 4 +-- InstructionSets/PowerPC/Instruction.hpp | 4 +-- InstructionSets/x86/DataPointerResolver.hpp | 4 +-- InstructionSets/x86/Decoder.hpp | 4 +-- InstructionSets/x86/Instruction.hpp | 4 +-- InstructionSets/x86/Model.hpp | 4 +-- Machines/Apple/ADB/Bus.hpp | 4 +-- Machines/Apple/ADB/Keyboard.hpp | 4 +-- Machines/Apple/ADB/Mouse.hpp | 4 +-- Machines/Apple/ADB/ReactiveDevice.hpp | 4 +-- Machines/Apple/AppleII/AppleII.hpp | 4 +-- .../Apple/AppleII/AuxiliaryMemorySwitches.hpp | 4 +-- Machines/Apple/AppleII/Card.hpp | 4 +-- Machines/Apple/AppleII/DiskIICard.hpp | 4 +-- Machines/Apple/AppleII/Joystick.hpp | 4 +-- .../Apple/AppleII/LanguageCardSwitches.hpp | 4 +-- Machines/Apple/AppleII/MemorySwitches.hpp | 4 +-- Machines/Apple/AppleII/SCSICard.hpp | 4 +-- Machines/Apple/AppleII/Video.hpp | 6 +--- Machines/Apple/AppleII/VideoSwitches.hpp | 4 +-- Machines/Apple/AppleIIgs/ADB.hpp | 6 +--- Machines/Apple/AppleIIgs/AppleIIgs.hpp | 4 +-- Machines/Apple/AppleIIgs/MemoryMap.hpp | 4 +-- Machines/Apple/AppleIIgs/Sound.hpp | 6 +--- Machines/Apple/AppleIIgs/Video.hpp | 6 +--- Machines/Apple/Macintosh/Audio.hpp | 4 +-- Machines/Apple/Macintosh/DeferredAudio.hpp | 4 +-- .../Apple/Macintosh/DriveSpeedAccumulator.hpp | 4 +-- Machines/Apple/Macintosh/Keyboard.hpp | 4 +-- Machines/Apple/Macintosh/Macintosh.hpp | 5 +-- Machines/Apple/Macintosh/Video.hpp | 4 +-- .../Atari/2600/Cartridges/ActivisionStack.hpp | 4 +-- Machines/Atari/2600/Cartridges/Atari16k.hpp | 4 +-- Machines/Atari/2600/Cartridges/Atari32k.hpp | 4 +-- Machines/Atari/2600/Cartridges/Atari8k.hpp | 4 +-- Machines/Atari/2600/Cartridges/CBSRAMPlus.hpp | 4 +-- Machines/Atari/2600/Cartridges/Cartridge.hpp | 4 +-- Machines/Atari/2600/Cartridges/CommaVid.hpp | 4 +-- Machines/Atari/2600/Cartridges/MNetwork.hpp | 4 +-- Machines/Atari/2600/Cartridges/MegaBoy.hpp | 4 +-- Machines/Atari/2600/Cartridges/ParkerBros.hpp | 4 +-- Machines/Atari/2600/Cartridges/Pitfall2.hpp | 4 +-- .../Atari/2600/Cartridges/Tigervision.hpp | 4 +-- Machines/Atari/2600/Cartridges/Unpaged.hpp | 4 +-- Machines/Atari/ST/AtariST.hpp | 5 ++- Machines/Atari/ST/DMAController.hpp | 4 +-- Machines/Atari/ST/IntelligentKeyboard.hpp | 4 +-- Machines/Atari/ST/Video.hpp | 4 +-- Machines/ColecoVision/ColecoVision.hpp | 4 +-- Machines/Commodore/1540/C1540.hpp | 8 ++--- .../1540/Implementation/C1540Base.hpp | 4 +-- Machines/Commodore/SerialBus.hpp | 4 +-- Machines/Commodore/Vic-20/Keyboard.hpp | 4 +-- Machines/Commodore/Vic-20/Vic20.cpp | 4 +-- Machines/Commodore/Vic-20/Vic20.hpp | 4 +-- Machines/Enterprise/Dave.hpp | 4 +-- Machines/MasterSystem/MasterSystem.hpp | 4 +-- Machines/Sinclair/Keyboard/Keyboard.hpp | 6 +--- Machines/Sinclair/ZX8081/Video.hpp | 4 +-- Machines/Sinclair/ZX8081/ZX8081.hpp | 4 +-- Machines/Sinclair/ZXSpectrum/State.hpp | 5 +-- Machines/Sinclair/ZXSpectrum/Video.hpp | 6 +--- Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp | 5 +-- .../Clock Signal.xcodeproj/project.pbxproj | 32 +++++++++---------- Outputs/CRT/CRT.hpp | 4 +-- Outputs/CRT/Internals/Flywheel.hpp | 4 +-- Outputs/DisplayMetrics.hpp | 4 +-- Outputs/OpenGL/Primitives/Rectangle.hpp | 6 +--- Outputs/OpenGL/Primitives/Shader.hpp | 6 +--- Outputs/OpenGL/Primitives/TextureTarget.hpp | 6 +--- Outputs/OpenGL/ScanTarget.hpp | 6 +--- Outputs/OpenGL/Screenshot.hpp | 6 +--- Outputs/ScanTarget.hpp | 4 +-- Outputs/ScanTargets/BufferingScanTarget.hpp | 5 +-- .../Speaker/Implementation/CompoundSource.hpp | 4 +-- .../Speaker/Implementation/LowpassSpeaker.hpp | 4 +-- .../Speaker/Implementation/SampleSource.hpp | 4 +-- Outputs/Speaker/Speaker.hpp | 4 +-- Processors/6502/6502.hpp | 4 +-- Processors/6502/AllRAM/6502AllRAM.hpp | 4 +-- Processors/6502/State/State.hpp | 5 +-- Processors/6502Esque/6502Esque.hpp | 4 +-- Processors/6502Esque/6502Selector.hpp | 4 +-- .../6502Esque/Implementation/LazyFlags.hpp | 5 +-- Processors/65816/65816.hpp | 4 +-- Processors/68000Mk2/68000Mk2.hpp | 8 ++--- .../Implementation/68000Mk2Implementation.hpp | 4 +-- .../Implementation/68000Mk2Storage.hpp | 4 +-- Processors/Z80/AllRAM/Z80AllRAM.hpp | 4 +-- Processors/Z80/Z80.hpp | 4 +-- Storage/Cartridge/Cartridge.hpp | 4 +-- Storage/Cartridge/Encodings/CommodoreROM.hpp | 8 +---- Storage/Cartridge/Formats/BinaryDump.hpp | 4 +-- Storage/Cartridge/Formats/PRG.hpp | 4 +-- Storage/Data/BitReverse.hpp | 8 ++--- Storage/Data/Commodore.hpp | 6 +--- Storage/Data/ZX8081.hpp | 7 +--- Storage/Disk/Controller/DiskController.hpp | 4 +-- Storage/Disk/Controller/MFMDiskController.hpp | 4 +-- Storage/Disk/Disk.hpp | 4 +-- Storage/Disk/DiskImage/DiskImage.hpp | 4 +-- Storage/Disk/DiskImage/Formats/2MG.hpp | 4 +-- Storage/Disk/DiskImage/Formats/AcornADF.hpp | 4 +-- Storage/Disk/DiskImage/Formats/AmigaADF.hpp | 4 +-- Storage/Disk/DiskImage/Formats/AppleDSK.hpp | 5 +-- Storage/Disk/DiskImage/Formats/CPCDSK.hpp | 5 +-- Storage/Disk/DiskImage/Formats/D64.hpp | 4 +-- Storage/Disk/DiskImage/Formats/DMK.hpp | 4 +-- Storage/Disk/DiskImage/Formats/FAT12.hpp | 4 +-- Storage/Disk/DiskImage/Formats/G64.hpp | 4 +-- Storage/Disk/DiskImage/Formats/HFE.hpp | 5 +-- Storage/Disk/DiskImage/Formats/IPF.hpp | 4 +-- .../Disk/DiskImage/Formats/MFMSectorDump.hpp | 4 +-- Storage/Disk/DiskImage/Formats/MSA.hpp | 5 +-- .../Disk/DiskImage/Formats/MacintoshIMG.hpp | 4 +-- Storage/Disk/DiskImage/Formats/NIB.hpp | 4 +-- Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp | 4 +-- Storage/Disk/DiskImage/Formats/SSD.hpp | 4 +-- Storage/Disk/DiskImage/Formats/STX.hpp | 4 +-- .../Formats/Utility/ImplicitSectors.hpp | 4 +-- Storage/Disk/DiskImage/Formats/WOZ.hpp | 4 +-- Storage/Disk/Drive.hpp | 5 +-- Storage/Disk/Encodings/AppleGCR/Encoder.hpp | 6 +--- Storage/Disk/Encodings/AppleGCR/Sector.hpp | 6 +--- .../Disk/Encodings/AppleGCR/SegmentParser.hpp | 6 +--- Storage/Disk/Encodings/CommodoreGCR.hpp | 4 +-- Storage/Disk/Encodings/MFM/Constants.hpp | 6 +--- Storage/Disk/Encodings/MFM/Encoder.hpp | 6 +--- Storage/Disk/Encodings/MFM/Parser.hpp | 6 +--- Storage/Disk/Encodings/MFM/Sector.hpp | 6 +--- Storage/Disk/Encodings/MFM/SegmentParser.hpp | 6 +--- Storage/Disk/Encodings/MFM/Shifter.hpp | 6 +--- Storage/Disk/Parsers/CPM.hpp | 6 +--- Storage/Disk/Parsers/FAT.hpp | 6 +--- Storage/Disk/Track/PCMSegment.hpp | 4 +-- Storage/Disk/Track/PCMTrack.hpp | 4 +-- Storage/Disk/Track/Track.hpp | 4 +-- Storage/Disk/Track/TrackSerialiser.hpp | 4 +-- Storage/Disk/Track/UnformattedTrack.hpp | 4 +-- .../MassStorage/Encodings/AppleIIVolume.hpp | 8 +---- .../Encodings/ApplePartitionMap.hpp | 8 +---- .../MassStorage/Encodings/MacintoshVolume.hpp | 8 +---- Storage/MassStorage/Formats/DAT.hpp | 4 +-- Storage/MassStorage/Formats/DSK.hpp | 4 +-- Storage/MassStorage/Formats/HDV.hpp | 4 +-- Storage/MassStorage/Formats/HFV.hpp | 4 +-- Storage/MassStorage/Formats/RawSectorDump.hpp | 4 +-- Storage/MassStorage/MassStorageDevice.hpp | 4 +-- Storage/MassStorage/SCSI/Target.hpp | 4 +-- Storage/State/SNA.hpp | 4 +-- Storage/State/SZX.hpp | 4 +-- Storage/State/Z80.hpp | 4 +-- Storage/Tape/Formats/CAS.hpp | 4 +-- Storage/Tape/Formats/CSW.hpp | 4 +-- Storage/Tape/Formats/CommodoreTAP.hpp | 4 +-- Storage/Tape/Formats/OricTAP.hpp | 4 +-- Storage/Tape/Formats/TZX.hpp | 5 ++- Storage/Tape/Formats/TapePRG.hpp | 4 +-- Storage/Tape/Formats/TapeUEF.hpp | 4 +-- Storage/Tape/Formats/ZX80O81P.hpp | 4 +-- Storage/Tape/Formats/ZXSpectrumTAP.hpp | 5 +-- Storage/Tape/Parsers/Acorn.hpp | 6 +--- Storage/Tape/Parsers/Commodore.hpp | 6 +--- Storage/Tape/Parsers/MSX.hpp | 6 +--- Storage/Tape/Parsers/Oric.hpp | 7 +--- Storage/Tape/Parsers/Spectrum.hpp | 6 +--- Storage/Tape/Parsers/TapeParser.hpp | 4 +-- Storage/Tape/Parsers/ZX8081.hpp | 6 +--- Storage/Tape/PulseQueuedTape.hpp | 4 +-- Storage/Tape/Tape.hpp | 4 +-- 271 files changed, 291 insertions(+), 1024 deletions(-) diff --git a/Analyser/Dynamic/ConfidenceCounter.hpp b/Analyser/Dynamic/ConfidenceCounter.hpp index 9e409592f..a625a9d55 100644 --- a/Analyser/Dynamic/ConfidenceCounter.hpp +++ b/Analyser/Dynamic/ConfidenceCounter.hpp @@ -11,8 +11,7 @@ #include "ConfidenceSource.hpp" -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides a confidence source that calculates its probability by virtual of a history of events. @@ -41,7 +40,6 @@ class ConfidenceCounter: public ConfidenceSource { int misses_ = 1; }; -} } #endif /* ConfidenceCounter_hpp */ diff --git a/Analyser/Dynamic/ConfidenceSource.hpp b/Analyser/Dynamic/ConfidenceSource.hpp index 0211a6d19..fb2dd3518 100644 --- a/Analyser/Dynamic/ConfidenceSource.hpp +++ b/Analyser/Dynamic/ConfidenceSource.hpp @@ -9,8 +9,7 @@ #ifndef ConfidenceSource_hpp #define ConfidenceSource_hpp -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides an abstract interface through which objects can declare the probability @@ -22,7 +21,6 @@ struct ConfidenceSource { virtual float get_confidence() = 0; }; -} } #endif /* ConfidenceSource_hpp */ diff --git a/Analyser/Dynamic/ConfidenceSummary.hpp b/Analyser/Dynamic/ConfidenceSummary.hpp index ccab36761..e49ad921d 100644 --- a/Analyser/Dynamic/ConfidenceSummary.hpp +++ b/Analyser/Dynamic/ConfidenceSummary.hpp @@ -13,8 +13,7 @@ #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Summaries a collection of confidence sources by calculating their weighted sum. @@ -40,7 +39,6 @@ class ConfidenceSummary: public ConfidenceSource { float weight_sum_; }; -} } #endif /* ConfidenceSummary_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp index 2595fc69c..82838db84 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiConfigurable.hpp @@ -15,8 +15,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides a class that multiplexes the configurable interface to multiple machines. @@ -36,7 +35,6 @@ class MultiConfigurable: public Configurable::Device { std::vector devices_; }; -} } #endif /* MultiConfigurable_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp index 7c5457a16..dfe12c8a4 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiJoystickMachine.hpp @@ -14,8 +14,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides a class that multiplexes the joystick machine interface to multiple machines. @@ -34,7 +33,6 @@ class MultiJoystickMachine: public MachineTypes::JoystickMachine { std::vector> joysticks_; }; -} } #endif /* MultiJoystickMachine_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp index 2de296456..c01b93c57 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiKeyboardMachine.hpp @@ -15,8 +15,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides a class that multiplexes the keyboard machine interface to multiple machines. @@ -55,7 +54,6 @@ class MultiKeyboardMachine: public MachineTypes::KeyboardMachine { Inputs::Keyboard &get_keyboard() final; }; -} } #endif /* MultiKeyboardMachine_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiMediaTarget.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiMediaTarget.hpp index 274261462..0ec4ad1cf 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiMediaTarget.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiMediaTarget.hpp @@ -15,8 +15,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides a class that multiplexes the media target interface to multiple machines. @@ -35,7 +34,6 @@ struct MultiMediaTarget: public MachineTypes::MediaTarget { std::vector targets_; }; -} } #endif /* MultiMediaTarget_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiProducer.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiProducer.hpp index 02e27c4df..3a850f709 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiProducer.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiProducer.hpp @@ -19,8 +19,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { template class MultiInterface { public: @@ -116,7 +115,5 @@ class MultiAudioProducer: public MultiInterface, pu */ } -} - #endif /* MultiProducer_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp index e5946da1a..def9feaba 100644 --- a/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp +++ b/Analyser/Dynamic/MultiMachine/Implementation/MultiSpeaker.hpp @@ -16,8 +16,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides a class that multiplexes calls to and from Outputs::Speaker::Speaker in order @@ -55,7 +54,6 @@ class MultiSpeaker: public Outputs::Speaker::Speaker, Outputs::Speaker::Speaker: bool stereo_output_ = false; }; -} } #endif /* MultiSpeaker_hpp */ diff --git a/Analyser/Dynamic/MultiMachine/MultiMachine.hpp b/Analyser/Dynamic/MultiMachine/MultiMachine.hpp index ec7e10f48..a31c2f119 100644 --- a/Analyser/Dynamic/MultiMachine/MultiMachine.hpp +++ b/Analyser/Dynamic/MultiMachine/MultiMachine.hpp @@ -22,8 +22,7 @@ #include #include -namespace Analyser { -namespace Dynamic { +namespace Analyser::Dynamic { /*! Provides the same interface as to a single machine, while multiplexing all @@ -80,7 +79,6 @@ class MultiMachine: public ::Machine::DynamicMachine, public MultiTimedMachine:: bool has_picked_ = false; }; -} } #endif /* MultiMachine_hpp */ diff --git a/Analyser/Static/Acorn/Disk.hpp b/Analyser/Static/Acorn/Disk.hpp index bd3b519fc..87b11951c 100644 --- a/Analyser/Static/Acorn/Disk.hpp +++ b/Analyser/Static/Acorn/Disk.hpp @@ -12,9 +12,7 @@ #include "File.hpp" #include "../../../Storage/Disk/Disk.hpp" -namespace Analyser { -namespace Static { -namespace Acorn { +namespace Analyser::Static::Acorn { /// Describes a DFS- or ADFS-format catalogue(/directory): the list of files available and the catalogue's boot option. struct Catalogue { @@ -31,8 +29,6 @@ struct Catalogue { std::unique_ptr GetDFSCatalogue(const std::shared_ptr &disk); std::unique_ptr GetADFSCatalogue(const std::shared_ptr &disk); -} -} } #endif /* Disk_hpp */ diff --git a/Analyser/Static/Acorn/File.hpp b/Analyser/Static/Acorn/File.hpp index f0a9d612e..f268af247 100644 --- a/Analyser/Static/Acorn/File.hpp +++ b/Analyser/Static/Acorn/File.hpp @@ -13,9 +13,7 @@ #include #include -namespace Analyser { -namespace Static { -namespace Acorn { +namespace Analyser::Static::Acorn { struct File { std::string name; @@ -60,8 +58,6 @@ struct File { std::vector chunks; }; -} -} } #endif /* File_hpp */ diff --git a/Analyser/Static/Acorn/StaticAnalyser.hpp b/Analyser/Static/Acorn/StaticAnalyser.hpp index d7acbbc38..079178c96 100644 --- a/Analyser/Static/Acorn/StaticAnalyser.hpp +++ b/Analyser/Static/Acorn/StaticAnalyser.hpp @@ -13,14 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace Acorn { +namespace Analyser::Static::Acorn { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* AcornAnalyser_hpp */ diff --git a/Analyser/Static/Acorn/Tape.hpp b/Analyser/Static/Acorn/Tape.hpp index a02f83ce5..f01216910 100644 --- a/Analyser/Static/Acorn/Tape.hpp +++ b/Analyser/Static/Acorn/Tape.hpp @@ -14,14 +14,10 @@ #include "File.hpp" #include "../../../Storage/Tape/Tape.hpp" -namespace Analyser { -namespace Static { -namespace Acorn { +namespace Analyser::Static::Acorn { std::vector GetFiles(const std::shared_ptr &tape); -} -} } #endif /* Tape_hpp */ diff --git a/Analyser/Static/Acorn/Target.hpp b/Analyser/Static/Acorn/Target.hpp index 17dad7393..bf7f8ffc9 100644 --- a/Analyser/Static/Acorn/Target.hpp +++ b/Analyser/Static/Acorn/Target.hpp @@ -13,9 +13,7 @@ #include "../StaticAnalyser.hpp" #include -namespace Analyser { -namespace Static { -namespace Acorn { +namespace Analyser::Static::Acorn { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { bool has_acorn_adfs = false; @@ -37,8 +35,6 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl< } }; -} -} } #endif /* Analyser_Static_Acorn_Target_h */ diff --git a/Analyser/Static/Amiga/StaticAnalyser.hpp b/Analyser/Static/Amiga/StaticAnalyser.hpp index 99b6169ec..fe9dc6b56 100644 --- a/Analyser/Static/Amiga/StaticAnalyser.hpp +++ b/Analyser/Static/Amiga/StaticAnalyser.hpp @@ -13,15 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace Amiga { +namespace Analyser::Static::Amiga { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); } -} -} - #endif /* Analyser_Static_Amiga_StaticAnalyser_hpp */ diff --git a/Analyser/Static/Amiga/Target.hpp b/Analyser/Static/Amiga/Target.hpp index a41d37dd9..9ff9e99a3 100644 --- a/Analyser/Static/Amiga/Target.hpp +++ b/Analyser/Static/Amiga/Target.hpp @@ -12,9 +12,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace Amiga { +namespace Analyser::Static::Amiga { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(ChipRAM, @@ -41,8 +39,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace AmstradCPC { +namespace Analyser::Static::AmstradCPC { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* Analyser_Static_AmstradCPC_StaticAnalyser_hpp */ diff --git a/Analyser/Static/AmstradCPC/Target.hpp b/Analyser/Static/AmstradCPC/Target.hpp index 6f708d4b0..ce19355a6 100644 --- a/Analyser/Static/AmstradCPC/Target.hpp +++ b/Analyser/Static/AmstradCPC/Target.hpp @@ -14,9 +14,7 @@ #include "../StaticAnalyser.hpp" #include -namespace Analyser { -namespace Static { -namespace AmstradCPC { +namespace Analyser::Static::AmstradCPC { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(Model, CPC464, CPC664, CPC6128); @@ -32,8 +30,5 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace AppleII { +namespace Analyser::Static::AppleII { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* Analyser_Static_AppleII_StaticAnalyser_hpp */ diff --git a/Analyser/Static/AppleII/Target.hpp b/Analyser/Static/AppleII/Target.hpp index 030b81947..e351c24fc 100644 --- a/Analyser/Static/AppleII/Target.hpp +++ b/Analyser/Static/AppleII/Target.hpp @@ -13,9 +13,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace AppleII { +namespace Analyser::Static::AppleII { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(Model, @@ -51,8 +49,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace AppleIIgs { +namespace Analyser::Static::AppleIIgs { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* Analyser_Static_AppleIIgs_StaticAnalyser_hpp */ diff --git a/Analyser/Static/AppleIIgs/Target.hpp b/Analyser/Static/AppleIIgs/Target.hpp index a0eb988aa..dda1515d4 100644 --- a/Analyser/Static/AppleIIgs/Target.hpp +++ b/Analyser/Static/AppleIIgs/Target.hpp @@ -13,9 +13,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace AppleIIgs { +namespace Analyser::Static::AppleIIgs { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(Model, @@ -42,8 +40,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace Atari2600 { +namespace Analyser::Static::Atari2600 { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/Atari2600/Target.hpp b/Analyser/Static/Atari2600/Target.hpp index c372656ff..2ed2400a2 100644 --- a/Analyser/Static/Atari2600/Target.hpp +++ b/Analyser/Static/Atari2600/Target.hpp @@ -11,9 +11,7 @@ #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace Atari2600 { +namespace Analyser::Static::Atari2600 { struct Target: public ::Analyser::Static::Target { enum class PagingModel { @@ -38,8 +36,6 @@ struct Target: public ::Analyser::Static::Target { Target() : Analyser::Static::Target(Machine::Atari2600) {} }; -} -} } #endif /* Analyser_Static_Atari_Target_h */ diff --git a/Analyser/Static/AtariST/StaticAnalyser.hpp b/Analyser/Static/AtariST/StaticAnalyser.hpp index 54c041eed..061e2cb4c 100644 --- a/Analyser/Static/AtariST/StaticAnalyser.hpp +++ b/Analyser/Static/AtariST/StaticAnalyser.hpp @@ -13,15 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace AtariST { +namespace Analyser::Static::AtariST { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); } -} -} - #endif /* Analyser_Static_AtariST_StaticAnalyser_hpp */ diff --git a/Analyser/Static/AtariST/Target.hpp b/Analyser/Static/AtariST/Target.hpp index b4d01279f..a8cd792da 100644 --- a/Analyser/Static/AtariST/Target.hpp +++ b/Analyser/Static/AtariST/Target.hpp @@ -12,9 +12,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace AtariST { +namespace Analyser::Static::AtariST { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(MemorySize, @@ -31,8 +29,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace Coleco { +namespace Analyser::Static::Coleco { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/Commodore/Disk.hpp b/Analyser/Static/Commodore/Disk.hpp index 486ea086d..ec4376d87 100644 --- a/Analyser/Static/Commodore/Disk.hpp +++ b/Analyser/Static/Commodore/Disk.hpp @@ -14,14 +14,10 @@ #include -namespace Analyser { -namespace Static { -namespace Commodore { +namespace Analyser::Static::Commodore { std::vector GetFiles(const std::shared_ptr &disk); -} -} } #endif /* Disk_hpp */ diff --git a/Analyser/Static/Commodore/File.hpp b/Analyser/Static/Commodore/File.hpp index 5f943a3c8..61b4a9b10 100644 --- a/Analyser/Static/Commodore/File.hpp +++ b/Analyser/Static/Commodore/File.hpp @@ -12,9 +12,7 @@ #include #include -namespace Analyser { -namespace Static { -namespace Commodore { +namespace Analyser::Static::Commodore { struct File { std::wstring name; @@ -35,8 +33,6 @@ struct File { bool is_basic(); }; -} -} } #endif /* File_hpp */ diff --git a/Analyser/Static/Commodore/StaticAnalyser.hpp b/Analyser/Static/Commodore/StaticAnalyser.hpp index 86d7c9bed..548020ae5 100644 --- a/Analyser/Static/Commodore/StaticAnalyser.hpp +++ b/Analyser/Static/Commodore/StaticAnalyser.hpp @@ -13,14 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace Commodore { +namespace Analyser::Static::Commodore { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* CommodoreAnalyser_hpp */ diff --git a/Analyser/Static/Commodore/Tape.hpp b/Analyser/Static/Commodore/Tape.hpp index 1dec3a1cc..2531bb89c 100644 --- a/Analyser/Static/Commodore/Tape.hpp +++ b/Analyser/Static/Commodore/Tape.hpp @@ -12,14 +12,10 @@ #include "../../../Storage/Tape/Tape.hpp" #include "File.hpp" -namespace Analyser { -namespace Static { -namespace Commodore { +namespace Analyser::Static::Commodore { std::vector GetFiles(const std::shared_ptr &tape); -} -} } #endif /* Tape_hpp */ diff --git a/Analyser/Static/Commodore/Target.hpp b/Analyser/Static/Commodore/Target.hpp index 9da8506ec..4752544c0 100644 --- a/Analyser/Static/Commodore/Target.hpp +++ b/Analyser/Static/Commodore/Target.hpp @@ -14,9 +14,7 @@ #include "../StaticAnalyser.hpp" #include -namespace Analyser { -namespace Static { -namespace Commodore { +namespace Analyser::Static::Commodore { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { enum class MemoryModel { @@ -71,8 +69,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl #include -namespace Analyser { -namespace Static { -namespace MOS6502 { +namespace Analyser::Static::MOS6502 { /*! Describes a 6502 instruciton: its address, the operation it performs, its addressing mode @@ -95,7 +93,5 @@ Disassembly Disassemble( std::vector entry_points); } -} -} #endif /* Disassembler6502_hpp */ diff --git a/Analyser/Static/Disassembler/AddressMapper.hpp b/Analyser/Static/Disassembler/AddressMapper.hpp index 0bb8988c0..debc18600 100644 --- a/Analyser/Static/Disassembler/AddressMapper.hpp +++ b/Analyser/Static/Disassembler/AddressMapper.hpp @@ -11,9 +11,7 @@ #include -namespace Analyser { -namespace Static { -namespace Disassembler { +namespace Analyser::Static::Disassembler { /*! Provides an address mapper that relocates a chunk of memory so that it starts at @@ -25,8 +23,6 @@ template std::function OffsetMapper(T start_address }; } -} -} } #endif /* AddressMapper_hpp */ diff --git a/Analyser/Static/Disassembler/Kernel.hpp b/Analyser/Static/Disassembler/Kernel.hpp index d18e9e915..e6817b760 100644 --- a/Analyser/Static/Disassembler/Kernel.hpp +++ b/Analyser/Static/Disassembler/Kernel.hpp @@ -9,9 +9,7 @@ #ifndef Kernel_hpp #define Kernel_hpp -namespace Analyser { -namespace Static { -namespace Disassembly { +namespace Analyser::Static::Disassembly { template struct PartialDisassembly { D disassembly; @@ -45,8 +43,6 @@ template D Disassemble( return partial_disassembly.disassembly; } -} -} } #endif /* Kernel_hpp */ diff --git a/Analyser/Static/Disassembler/Z80.hpp b/Analyser/Static/Disassembler/Z80.hpp index 4f46b055d..ebed669d2 100644 --- a/Analyser/Static/Disassembler/Z80.hpp +++ b/Analyser/Static/Disassembler/Z80.hpp @@ -15,9 +15,7 @@ #include #include -namespace Analyser { -namespace Static { -namespace Z80 { +namespace Analyser::Static::Z80 { struct Instruction { /*! The address this instruction starts at. This is a mapped address. */ @@ -84,7 +82,5 @@ Disassembly Disassemble( std::vector entry_points); } -} -} #endif /* StaticAnalyser_Disassembler_Z80_hpp */ diff --git a/Analyser/Static/DiskII/StaticAnalyser.hpp b/Analyser/Static/DiskII/StaticAnalyser.hpp index a1f7a09f1..87ebc413b 100644 --- a/Analyser/Static/DiskII/StaticAnalyser.hpp +++ b/Analyser/Static/DiskII/StaticAnalyser.hpp @@ -13,15 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace DiskII { +namespace Analyser::Static::DiskII { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); } -} -} - #endif /* Analyser_Static_DiskII_StaticAnalyser_hpp */ diff --git a/Analyser/Static/Enterprise/StaticAnalyser.hpp b/Analyser/Static/Enterprise/StaticAnalyser.hpp index 0d7435d0a..ef03fc17f 100644 --- a/Analyser/Static/Enterprise/StaticAnalyser.hpp +++ b/Analyser/Static/Enterprise/StaticAnalyser.hpp @@ -13,15 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace Enterprise { +namespace Analyser::Static::Enterprise { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); } -} -} - #endif /* Analyser_Static_Enterprise_StaticAnalyser_hpp */ diff --git a/Analyser/Static/Enterprise/Target.hpp b/Analyser/Static/Enterprise/Target.hpp index 957852c5f..c1428ae73 100644 --- a/Analyser/Static/Enterprise/Target.hpp +++ b/Analyser/Static/Enterprise/Target.hpp @@ -15,9 +15,7 @@ #include -namespace Analyser { -namespace Static { -namespace Enterprise { +namespace Analyser::Static::Enterprise { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(Model, Enterprise64, Enterprise128, Enterprise256); @@ -50,8 +48,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace MSX { +namespace Analyser::Static::MSX { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_MSX_StaticAnalyser_hpp */ diff --git a/Analyser/Static/MSX/Tape.hpp b/Analyser/Static/MSX/Tape.hpp index eb0ca66bf..b57a5928c 100644 --- a/Analyser/Static/MSX/Tape.hpp +++ b/Analyser/Static/MSX/Tape.hpp @@ -14,9 +14,7 @@ #include #include -namespace Analyser { -namespace Static { -namespace MSX { +namespace Analyser::Static::MSX { struct File { std::string name; @@ -37,8 +35,6 @@ struct File { std::vector GetFiles(const std::shared_ptr &tape); -} -} } #endif /* StaticAnalyser_MSX_Tape_hpp */ diff --git a/Analyser/Static/MSX/Target.hpp b/Analyser/Static/MSX/Target.hpp index 13b95eff1..4b6ae5185 100644 --- a/Analyser/Static/MSX/Target.hpp +++ b/Analyser/Static/MSX/Target.hpp @@ -14,9 +14,7 @@ #include "../StaticAnalyser.hpp" #include -namespace Analyser { -namespace Static { -namespace MSX { +namespace Analyser::Static::MSX { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { bool has_disk_drive = false; @@ -46,8 +44,6 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl< } }; -} -} } #endif /* Analyser_Static_MSX_Target_h */ diff --git a/Analyser/Static/Macintosh/StaticAnalyser.hpp b/Analyser/Static/Macintosh/StaticAnalyser.hpp index 8b40c0120..e9b165c74 100644 --- a/Analyser/Static/Macintosh/StaticAnalyser.hpp +++ b/Analyser/Static/Macintosh/StaticAnalyser.hpp @@ -13,15 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace Macintosh { +namespace Analyser::Static::Macintosh { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); } -} -} - #endif /* Analyser_Static_Macintosh_StaticAnalyser_hpp */ diff --git a/Analyser/Static/Macintosh/Target.hpp b/Analyser/Static/Macintosh/Target.hpp index f00cb4a24..6a46ca1e0 100644 --- a/Analyser/Static/Macintosh/Target.hpp +++ b/Analyser/Static/Macintosh/Target.hpp @@ -13,9 +13,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace Macintosh { +namespace Analyser::Static::Macintosh { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(Model, Mac128k, Mac512k, Mac512ke, MacPlus); @@ -30,8 +28,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace Oric { +namespace Analyser::Static::Oric { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/Oric/Tape.hpp b/Analyser/Static/Oric/Tape.hpp index fc7734697..bf0931950 100644 --- a/Analyser/Static/Oric/Tape.hpp +++ b/Analyser/Static/Oric/Tape.hpp @@ -14,9 +14,7 @@ #include #include -namespace Analyser { -namespace Static { -namespace Oric { +namespace Analyser::Static::Oric { struct File { std::string name; @@ -33,8 +31,6 @@ struct File { std::vector GetFiles(const std::shared_ptr &tape); -} -} } #endif /* Tape_hpp */ diff --git a/Analyser/Static/Oric/Target.hpp b/Analyser/Static/Oric/Target.hpp index 74e686dff..4b43c4aff 100644 --- a/Analyser/Static/Oric/Target.hpp +++ b/Analyser/Static/Oric/Target.hpp @@ -14,9 +14,7 @@ #include "../StaticAnalyser.hpp" #include -namespace Analyser { -namespace Static { -namespace Oric { +namespace Analyser::Static::Oric { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(ROM, @@ -56,8 +54,6 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl -namespace Analyser { -namespace Static { -namespace Sega { +namespace Analyser::Static::Sega { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/Sega/Target.hpp b/Analyser/Static/Sega/Target.hpp index 24230293d..20142ca48 100644 --- a/Analyser/Static/Sega/Target.hpp +++ b/Analyser/Static/Sega/Target.hpp @@ -13,9 +13,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace Sega { +namespace Analyser::Static::Sega { struct Target: public Analyser::Static::Target, public Reflection::StructImpl { enum class Model { @@ -52,8 +50,6 @@ constexpr bool is_master_system(Analyser::Static::Sega::Target::Model model) { return model >= Analyser::Static::Sega::Target::Model::MasterSystem; } -} -} } #endif /* Analyser_Static_Sega_Target_h */ diff --git a/Analyser/Static/StaticAnalyser.hpp b/Analyser/Static/StaticAnalyser.hpp index 259f7cca9..f4e3fd317 100644 --- a/Analyser/Static/StaticAnalyser.hpp +++ b/Analyser/Static/StaticAnalyser.hpp @@ -21,8 +21,7 @@ #include #include -namespace Analyser { -namespace Static { +namespace Analyser::Static { struct State; @@ -79,7 +78,6 @@ TargetList GetTargets(const std::string &file_name); */ Media GetMedia(const std::string &file_name); -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/ZX8081/StaticAnalyser.hpp b/Analyser/Static/ZX8081/StaticAnalyser.hpp index 141a15945..2fa1ce49e 100644 --- a/Analyser/Static/ZX8081/StaticAnalyser.hpp +++ b/Analyser/Static/ZX8081/StaticAnalyser.hpp @@ -13,14 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace ZX8081 { +namespace Analyser::Static::ZX8081 { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/ZX8081/Target.hpp b/Analyser/Static/ZX8081/Target.hpp index c7dd7e60d..f4a27c4ad 100644 --- a/Analyser/Static/ZX8081/Target.hpp +++ b/Analyser/Static/ZX8081/Target.hpp @@ -14,9 +14,7 @@ #include "../StaticAnalyser.hpp" #include -namespace Analyser { -namespace Static { -namespace ZX8081 { +namespace Analyser::Static::ZX8081 { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(MemoryModel, @@ -40,8 +38,6 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl< } }; -} -} } #endif /* Analyser_Static_ZX8081_Target_h */ diff --git a/Analyser/Static/ZXSpectrum/StaticAnalyser.hpp b/Analyser/Static/ZXSpectrum/StaticAnalyser.hpp index 756c28ad0..7e5ef7945 100644 --- a/Analyser/Static/ZXSpectrum/StaticAnalyser.hpp +++ b/Analyser/Static/ZXSpectrum/StaticAnalyser.hpp @@ -13,14 +13,10 @@ #include "../../../Storage/TargetPlatforms.hpp" #include -namespace Analyser { -namespace Static { -namespace ZXSpectrum { +namespace Analyser::Static::ZXSpectrum { TargetList GetTargets(const Media &media, const std::string &file_name, TargetPlatform::IntType potential_platforms); -} -} } #endif /* StaticAnalyser_hpp */ diff --git a/Analyser/Static/ZXSpectrum/Target.hpp b/Analyser/Static/ZXSpectrum/Target.hpp index 76eada20e..bd42dbd8d 100644 --- a/Analyser/Static/ZXSpectrum/Target.hpp +++ b/Analyser/Static/ZXSpectrum/Target.hpp @@ -13,9 +13,7 @@ #include "../../../Reflection/Struct.hpp" #include "../StaticAnalyser.hpp" -namespace Analyser { -namespace Static { -namespace ZXSpectrum { +namespace Analyser::Static::ZXSpectrum { struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl { ReflectableEnum(Model, @@ -38,8 +36,6 @@ struct Target: public ::Analyser::Static::Target, public Reflection::StructImpl< } }; -} -} } #endif /* Target_h */ diff --git a/Components/5380/ncr5380.hpp b/Components/5380/ncr5380.hpp index 6ea409b53..18d4e367d 100644 --- a/Components/5380/ncr5380.hpp +++ b/Components/5380/ncr5380.hpp @@ -14,8 +14,7 @@ #include "../../Storage/MassStorage/SCSI/SCSI.hpp" -namespace NCR { -namespace NCR5380 { +namespace NCR::NCR5380 { /*! Models the NCR 5380, a SCSI interface chip. @@ -86,7 +85,6 @@ class NCR5380 final: public SCSI::Bus::Observer { bool phase_matches() const; }; -} } #endif /* ncr5380_hpp */ diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 3e09819d0..20eaeaa3e 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -15,8 +15,7 @@ #include "../../ClockReceiver/ClockReceiver.hpp" -namespace MOS { -namespace MOS6522 { +namespace MOS::MOS6522 { enum Port { A = 0, @@ -138,7 +137,6 @@ template class MOS6522: public MOS6522Storage { void evaluate_port_b_output(); }; -} } #include "Implementation/6522Implementation.hpp" diff --git a/Components/6522/Implementation/6522Implementation.hpp b/Components/6522/Implementation/6522Implementation.hpp index 3e23422eb..52edea000 100644 --- a/Components/6522/Implementation/6522Implementation.hpp +++ b/Components/6522/Implementation/6522Implementation.hpp @@ -12,8 +12,7 @@ // // PB6 count-down mode for timer 2. -namespace MOS { -namespace MOS6522 { +namespace MOS::MOS6522 { template void MOS6522::access(int address) { switch(address) { @@ -494,4 +493,3 @@ template void MOS6522::shift_out() { } } -} diff --git a/Components/6522/Implementation/6522Storage.hpp b/Components/6522/Implementation/6522Storage.hpp index 0c7f4c789..1488954e2 100644 --- a/Components/6522/Implementation/6522Storage.hpp +++ b/Components/6522/Implementation/6522Storage.hpp @@ -11,8 +11,7 @@ #include -namespace MOS { -namespace MOS6522 { +namespace MOS::MOS6522 { class MOS6522Storage { protected: @@ -107,7 +106,6 @@ class MOS6522Storage { } }; -} } #endif /* _522Storage_hpp */ diff --git a/Components/6526/6526.hpp b/Components/6526/6526.hpp index 99eb5e8e6..08c68cf6e 100644 --- a/Components/6526/6526.hpp +++ b/Components/6526/6526.hpp @@ -14,8 +14,7 @@ #include "Implementation/6526Storage.hpp" #include "../Serial/Line.hpp" -namespace MOS { -namespace MOS6526 { +namespace MOS::MOS6526 { enum Port { A = 0, @@ -86,7 +85,6 @@ template class MOS6526: bool serial_line_did_produce_bit(Serial::Line *line, int bit) final; }; -} } #include "Implementation/6526Implementation.hpp" diff --git a/Components/6526/Implementation/6526Implementation.hpp b/Components/6526/Implementation/6526Implementation.hpp index 92ecf5269..dad339574 100644 --- a/Components/6526/Implementation/6526Implementation.hpp +++ b/Components/6526/Implementation/6526Implementation.hpp @@ -12,8 +12,7 @@ #include #include -namespace MOS { -namespace MOS6526 { +namespace MOS::MOS6526 { enum Interrupts: uint8_t { TimerA = 1 << 0, @@ -238,7 +237,6 @@ bool MOS6526::serial_line_did_produce_bit(Serial::Line return true; } -} } #endif /* _526Implementation_h */ diff --git a/Components/6526/Implementation/6526Storage.hpp b/Components/6526/Implementation/6526Storage.hpp index 7a3c2bf1b..99978f67c 100644 --- a/Components/6526/Implementation/6526Storage.hpp +++ b/Components/6526/Implementation/6526Storage.hpp @@ -13,8 +13,7 @@ #include "../../../ClockReceiver/ClockReceiver.hpp" -namespace MOS { -namespace MOS6526 { +namespace MOS::MOS6526 { class TODBase { public: @@ -333,7 +332,6 @@ struct MOS6526Storage { int pending_ = 0; }; -} } #endif /* _526Storage_h */ diff --git a/Components/6560/6560.hpp b/Components/6560/6560.hpp index 1ebd3e6e8..91fc82a74 100644 --- a/Components/6560/6560.hpp +++ b/Components/6560/6560.hpp @@ -15,8 +15,7 @@ #include "../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" #include "../../Outputs/Speaker/Implementation/SampleSource.hpp" -namespace MOS { -namespace MOS6560 { +namespace MOS::MOS6560 { // audio state class AudioGenerator: public ::Outputs::Speaker::SampleSource { @@ -520,7 +519,6 @@ template class MOS6560 { OutputMode output_mode_ = OutputMode::NTSC; }; -} } #endif /* _560_hpp */ diff --git a/Components/6845/CRTC6845.hpp b/Components/6845/CRTC6845.hpp index 7006a37e9..fd7008041 100644 --- a/Components/6845/CRTC6845.hpp +++ b/Components/6845/CRTC6845.hpp @@ -14,8 +14,7 @@ #include #include -namespace Motorola { -namespace CRTC { +namespace Motorola::CRTC { struct BusState { bool display_enable = false; @@ -269,7 +268,6 @@ template class CRTC6845 { unsigned int character_is_visible_shifter_ = 0; }; -} } #endif /* CRTC6845_hpp */ diff --git a/Components/6850/6850.hpp b/Components/6850/6850.hpp index 69e192e90..280723e0b 100644 --- a/Components/6850/6850.hpp +++ b/Components/6850/6850.hpp @@ -15,8 +15,7 @@ #include "../../ClockReceiver/ClockingHintSource.hpp" #include "../Serial/Line.hpp" -namespace Motorola { -namespace ACIA { +namespace Motorola::ACIA { class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelegate { public: @@ -126,7 +125,6 @@ class ACIA: public ClockingHint::Source, private Serial::Line::ReadDelega uint8_t get_status(); }; -} } #endif /* Motorola_ACIA_6850_hpp */ diff --git a/Components/68901/MFP68901.hpp b/Components/68901/MFP68901.hpp index f1bda90dd..4c067d1f2 100644 --- a/Components/68901/MFP68901.hpp +++ b/Components/68901/MFP68901.hpp @@ -14,8 +14,7 @@ #include -namespace Motorola { -namespace MFP68901 { +namespace Motorola::MFP68901 { class PortHandler { public: @@ -182,7 +181,6 @@ class MFP68901: public ClockingHint::Source { } }; -} } #endif /* MFP68901_hpp */ diff --git a/Components/8255/i8255.hpp b/Components/8255/i8255.hpp index d8e2a42f6..2551c402e 100644 --- a/Components/8255/i8255.hpp +++ b/Components/8255/i8255.hpp @@ -11,8 +11,7 @@ #include -namespace Intel { -namespace i8255 { +namespace Intel::i8255 { class PortHandler { public: @@ -88,7 +87,6 @@ template class i8255 { T &port_handler_; }; -} } #endif /* i8255_hpp */ diff --git a/Components/8272/i8272.hpp b/Components/8272/i8272.hpp index cb589343c..0c502e3c8 100644 --- a/Components/8272/i8272.hpp +++ b/Components/8272/i8272.hpp @@ -15,8 +15,7 @@ #include #include -namespace Intel { -namespace i8272 { +namespace Intel::i8272 { class BusHandler { public: @@ -130,7 +129,6 @@ class i8272 : public Storage::Disk::MFMController { bool is_sleeping_ = false; }; -} } #endif /* i8272_hpp */ diff --git a/Components/8530/z8530.hpp b/Components/8530/z8530.hpp index 4826cb445..099aa6e24 100644 --- a/Components/8530/z8530.hpp +++ b/Components/8530/z8530.hpp @@ -11,8 +11,7 @@ #include -namespace Zilog { -namespace SCC { +namespace Zilog::SCC { /*! Models the Zilog 8530 SCC, a serial adaptor. @@ -110,7 +109,5 @@ class z8530 { }; } -} - #endif /* z8530_hpp */ diff --git a/Components/AY38910/AY38910.hpp b/Components/AY38910/AY38910.hpp index b06a92b2b..a42a51124 100644 --- a/Components/AY38910/AY38910.hpp +++ b/Components/AY38910/AY38910.hpp @@ -14,8 +14,7 @@ #include "../../Reflection/Struct.hpp" -namespace GI { -namespace AY38910 { +namespace GI::AY38910 { /*! A port handler provides all input for an AY's two 8-bit ports, and may optionally receive @@ -219,7 +218,6 @@ struct State: public Reflection::StructImpl { } }; -} } #endif /* AY_3_8910_hpp */ diff --git a/Components/AppleClock/AppleClock.hpp b/Components/AppleClock/AppleClock.hpp index 0b06bb2cf..cf27a796f 100644 --- a/Components/AppleClock/AppleClock.hpp +++ b/Components/AppleClock/AppleClock.hpp @@ -11,8 +11,7 @@ #include -namespace Apple { -namespace Clock { +namespace Apple::Clock { /*! Models Apple's real-time clocks, as contained in the Macintosh and IIgs. @@ -293,7 +292,6 @@ class ParallelClock: public ClockStorage { uint8_t control_; }; -} } #endif /* Apple_RealTimeClock_hpp */ diff --git a/Components/DiskII/DiskIIDrive.hpp b/Components/DiskII/DiskIIDrive.hpp index e003919aa..55e883e08 100644 --- a/Components/DiskII/DiskIIDrive.hpp +++ b/Components/DiskII/DiskIIDrive.hpp @@ -11,8 +11,7 @@ #include "IWM.hpp" -namespace Apple { -namespace Disk { +namespace Apple::Disk { class DiskIIDrive: public IWMDrive { public: @@ -27,7 +26,6 @@ class DiskIIDrive: public IWMDrive { int stepper_position_ = 0; }; -} } #endif /* DiskIIDrive_hpp */ diff --git a/Components/DiskII/MacintoshDoubleDensityDrive.hpp b/Components/DiskII/MacintoshDoubleDensityDrive.hpp index 3c6bf5b8f..31ab1934e 100644 --- a/Components/DiskII/MacintoshDoubleDensityDrive.hpp +++ b/Components/DiskII/MacintoshDoubleDensityDrive.hpp @@ -11,8 +11,7 @@ #include "IWM.hpp" -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { class DoubleDensityDrive: public IWMDrive { public: @@ -47,7 +46,6 @@ class DoubleDensityDrive: public IWMDrive { int step_direction_ = 1; }; -} } #endif /* MacintoshDoubleDensityDrive_hpp */ diff --git a/Components/OPx/Implementation/EnvelopeGenerator.hpp b/Components/OPx/Implementation/EnvelopeGenerator.hpp index 3d7b80c19..06c7f2eb6 100644 --- a/Components/OPx/Implementation/EnvelopeGenerator.hpp +++ b/Components/OPx/Implementation/EnvelopeGenerator.hpp @@ -13,8 +13,7 @@ #include #include "LowFrequencyOscillator.hpp" -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { /*! Models an OPL-style envelope generator. @@ -258,7 +257,6 @@ template class EnvelopeGenerator } }; -} } #endif /* EnvelopeGenerator_h */ diff --git a/Components/OPx/Implementation/KeyLevelScaler.hpp b/Components/OPx/Implementation/KeyLevelScaler.hpp index a86995bdf..e1dbc66fc 100644 --- a/Components/OPx/Implementation/KeyLevelScaler.hpp +++ b/Components/OPx/Implementation/KeyLevelScaler.hpp @@ -9,8 +9,7 @@ #ifndef KeyLevelScaler_h #define KeyLevelScaler_h -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { template class KeyLevelScaler { public: @@ -51,8 +50,6 @@ template class KeyLevelScaler { int shift_ = 0; }; - -} } #endif /* KeyLevelScaler_h */ diff --git a/Components/OPx/Implementation/LowFrequencyOscillator.hpp b/Components/OPx/Implementation/LowFrequencyOscillator.hpp index a3d852e67..5c53eac29 100644 --- a/Components/OPx/Implementation/LowFrequencyOscillator.hpp +++ b/Components/OPx/Implementation/LowFrequencyOscillator.hpp @@ -11,8 +11,7 @@ #include "../../../Numeric/LFSR.hpp" -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { /*! Models the output of the OPL low-frequency oscillator, which provides a couple of optional fixed-frequency @@ -62,7 +61,6 @@ class LowFrequencyOscillator { Numeric::LFSR noise_source_; }; -} } #endif /* LowFrequencyOscillator_hpp */ diff --git a/Components/OPx/Implementation/OPLBase.hpp b/Components/OPx/Implementation/OPLBase.hpp index 8183d4287..7ed6ca775 100644 --- a/Components/OPx/Implementation/OPLBase.hpp +++ b/Components/OPx/Implementation/OPLBase.hpp @@ -12,8 +12,7 @@ #include "../../../Outputs/Speaker/Implementation/SampleSource.hpp" #include "../../../Concurrency/AsyncTaskQueue.hpp" -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { template class OPLBase: public ::Outputs::Speaker::SampleSource { public: @@ -34,7 +33,6 @@ template class OPLBase: public ::Outputs::Speaker::SampleSource uint8_t selected_register_ = 0; }; -} } #endif /* OPLBase_h */ diff --git a/Components/OPx/Implementation/PhaseGenerator.hpp b/Components/OPx/Implementation/PhaseGenerator.hpp index 89ca27ebd..b5cb3ff73 100644 --- a/Components/OPx/Implementation/PhaseGenerator.hpp +++ b/Components/OPx/Implementation/PhaseGenerator.hpp @@ -13,8 +13,7 @@ #include "LowFrequencyOscillator.hpp" #include "Tables.hpp" -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { /*! Models an OPL-style phase generator of templated precision; having been told its period ('f-num'), octave ('block') and @@ -119,7 +118,6 @@ template class PhaseGenerator { int enable_vibrato_ = 0; }; -} } #endif /* PhaseGenerator_h */ diff --git a/Components/OPx/Implementation/Tables.hpp b/Components/OPx/Implementation/Tables.hpp index d50f2c391..242144ee7 100644 --- a/Components/OPx/Implementation/Tables.hpp +++ b/Components/OPx/Implementation/Tables.hpp @@ -9,8 +9,7 @@ #ifndef Tables_hpp #define Tables_hpp -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { /* These are the OPL's built-in log-sin and exponentiation tables, as recovered by @@ -221,7 +220,6 @@ inline int LogSign::level(int fractional) const { return power_two(*this, fractional); } -} } #endif /* Tables_hpp */ diff --git a/Components/OPx/Implementation/WaveformGenerator.hpp b/Components/OPx/Implementation/WaveformGenerator.hpp index 381fe7eea..f325b1012 100644 --- a/Components/OPx/Implementation/WaveformGenerator.hpp +++ b/Components/OPx/Implementation/WaveformGenerator.hpp @@ -12,8 +12,7 @@ #include "Tables.hpp" #include "LowFrequencyOscillator.hpp" -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { enum class Waveform { Sine, HalfSine, AbsSine, PulseSine @@ -86,7 +85,6 @@ template class WaveformGenerator { } }; -} } #endif /* WaveformGenerator_h */ diff --git a/Components/OPx/OPLL.hpp b/Components/OPx/OPLL.hpp index 530d84e77..5341f40ca 100644 --- a/Components/OPx/OPLL.hpp +++ b/Components/OPx/OPLL.hpp @@ -18,8 +18,7 @@ #include -namespace Yamaha { -namespace OPL { +namespace Yamaha::OPL { class OPLL: public OPLBase { public: @@ -125,7 +124,6 @@ class OPLL: public OPLBase { const uint8_t *instrument_definition(int instrument, int channel); }; -} } #endif /* OPLL_hpp */ diff --git a/Components/RP5C01/RP5C01.hpp b/Components/RP5C01/RP5C01.hpp index ba7e5fe71..5b6914d98 100644 --- a/Components/RP5C01/RP5C01.hpp +++ b/Components/RP5C01/RP5C01.hpp @@ -14,8 +14,7 @@ #include #include -namespace Ricoh { -namespace RP5C01 { +namespace Ricoh::RP5C01 { class RP5C01 { public: @@ -56,8 +55,5 @@ class RP5C01 { }; } -} - -#include #endif /* RP5C01_hpp */ diff --git a/InstructionSets/6809/OperationMapper.hpp b/InstructionSets/6809/OperationMapper.hpp index 8c6fafd45..478c12d84 100644 --- a/InstructionSets/6809/OperationMapper.hpp +++ b/InstructionSets/6809/OperationMapper.hpp @@ -14,8 +14,7 @@ // Subject to corrections: // // * CWAI and the pushes and pulls at 0x3x are immediate, not inherent. -namespace InstructionSet { -namespace M6809 { +namespace InstructionSet::M6809 { enum class AddressingMode { Illegal, @@ -239,7 +238,6 @@ template void OperationMapper::dispatc } } -} } #endif /* InstructionSets_M6809_OperationMapper_hpp */ diff --git a/InstructionSets/AccessType.hpp b/InstructionSets/AccessType.hpp index 196bfc44b..4b5635542 100644 --- a/InstructionSets/AccessType.hpp +++ b/InstructionSets/AccessType.hpp @@ -20,5 +20,4 @@ enum class AccessType { } - #endif /* AccessType_h */ diff --git a/InstructionSets/M50740/Decoder.hpp b/InstructionSets/M50740/Decoder.hpp index 4f3f3d5b2..409d5f535 100644 --- a/InstructionSets/M50740/Decoder.hpp +++ b/InstructionSets/M50740/Decoder.hpp @@ -14,8 +14,7 @@ #include #include -namespace InstructionSet { -namespace M50740 { +namespace InstructionSet::M50740 { class Decoder { public: @@ -33,7 +32,6 @@ class Decoder { Instruction instr_; }; -} } #endif /* InstructionSets_M50740_Decoder_hpp */ diff --git a/InstructionSets/M50740/Executor.hpp b/InstructionSets/M50740/Executor.hpp index 28c83e43d..6ab8bcf55 100644 --- a/InstructionSets/M50740/Executor.hpp +++ b/InstructionSets/M50740/Executor.hpp @@ -18,8 +18,7 @@ #include #include -namespace InstructionSet { -namespace M50740 { +namespace InstructionSet::M50740 { class Executor; using CachingExecutor = CachingExecutor; @@ -174,7 +173,6 @@ class Executor: public CachingExecutor { inline void subtract_duration(int duration); }; -} } #endif /* Executor_h */ diff --git a/InstructionSets/M50740/Instruction.hpp b/InstructionSets/M50740/Instruction.hpp index deafa692f..057a79640 100644 --- a/InstructionSets/M50740/Instruction.hpp +++ b/InstructionSets/M50740/Instruction.hpp @@ -15,8 +15,7 @@ #include #include "../AccessType.hpp" -namespace InstructionSet { -namespace M50740 { +namespace InstructionSet::M50740 { enum class AddressingMode { Implied, Accumulator, Immediate, @@ -236,7 +235,5 @@ inline std::ostream &operator <<(std::ostream &stream, const Instruction &instru } } -} - #endif /* InstructionSets_M50740_Instruction_h */ diff --git a/InstructionSets/M50740/Parser.hpp b/InstructionSets/M50740/Parser.hpp index 9c9937921..dc739048a 100644 --- a/InstructionSets/M50740/Parser.hpp +++ b/InstructionSets/M50740/Parser.hpp @@ -13,8 +13,7 @@ #include "Decoder.hpp" #include "../AccessType.hpp" -namespace InstructionSet { -namespace M50740 { +namespace InstructionSet::M50740 { template struct Parser { void parse(Target &target, const uint8_t *storage, uint16_t start, uint16_t closing_bound) { @@ -119,7 +118,6 @@ template struct Parser { } }; -} } #endif /* InstructionSets_M50740_Parser_hpp */ diff --git a/InstructionSets/M68k/Decoder.hpp b/InstructionSets/M68k/Decoder.hpp index d54cdabfd..2f4413df8 100644 --- a/InstructionSets/M68k/Decoder.hpp +++ b/InstructionSets/M68k/Decoder.hpp @@ -13,8 +13,7 @@ #include "Model.hpp" #include "../../Numeric/Sizes.hpp" -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { /*! A stateless decoder that can map from instruction words to preinstructions @@ -115,7 +114,6 @@ template class Predecoder { static constexpr Operation operation(OpT op); }; -} } #endif /* InstructionSets_M68k_Decoder_hpp */ diff --git a/InstructionSets/M68k/ExceptionVectors.hpp b/InstructionSets/M68k/ExceptionVectors.hpp index e56c71efb..99bab495a 100644 --- a/InstructionSets/M68k/ExceptionVectors.hpp +++ b/InstructionSets/M68k/ExceptionVectors.hpp @@ -9,8 +9,7 @@ #ifndef InstructionSets_M68k_ExceptionVectors_hpp #define InstructionSets_M68k_ExceptionVectors_hpp -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { enum Exception { InitialStackPointer = 0, @@ -44,7 +43,6 @@ enum Exception { MMUAccessLevelViolationError = 58, }; -} } #endif /* InstructionSets_M68k_ExceptionVectors_hpp */ diff --git a/InstructionSets/M68k/Executor.hpp b/InstructionSets/M68k/Executor.hpp index 7d86d8bfe..5c2737bd7 100644 --- a/InstructionSets/M68k/Executor.hpp +++ b/InstructionSets/M68k/Executor.hpp @@ -16,8 +16,7 @@ #include "RegisterSet.hpp" #include "Status.hpp" -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { /// Maps the 68k function codes such that bits 0, 1 and 2 represent /// FC0, FC1 and FC2 respectively. @@ -163,7 +162,6 @@ template class Executor { } state_; }; -} } #include "Implementation/ExecutorImplementation.hpp" diff --git a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp index 608f62161..b064237aa 100644 --- a/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp +++ b/InstructionSets/M68k/Implementation/ExecutorImplementation.hpp @@ -15,8 +15,7 @@ #include -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { #define An(x) state_.registers[8 + x] #define Dn(x) state_.registers[x] @@ -749,7 +748,6 @@ void Executor::State::movem_toR(Preinstruction instruction, u #undef An #undef AccessException -} } #endif /* InstructionSets_M68k_ExecutorImplementation_hpp */ diff --git a/InstructionSets/M68k/Implementation/InstructionOperandFlags.hpp b/InstructionSets/M68k/Implementation/InstructionOperandFlags.hpp index e78aca928..8e6630ef3 100644 --- a/InstructionSets/M68k/Implementation/InstructionOperandFlags.hpp +++ b/InstructionSets/M68k/Implementation/InstructionOperandFlags.hpp @@ -9,8 +9,7 @@ #ifndef InstructionSets_68k_InstructionOperandFlags_hpp #define InstructionSets_68k_InstructionOperandFlags_hpp -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { template constexpr uint8_t operand_flags(Operation r_operation) { switch((t_operation != Operation::Undefined) ? t_operation : r_operation) { @@ -168,7 +167,6 @@ template constexpr uint8_t operand_flags(Op } } -} } #endif /* InstructionSets_68k_InstructionOperandFlags_hpp */ diff --git a/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp b/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp index 44e07011e..3d6308dbc 100644 --- a/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp +++ b/InstructionSets/M68k/Implementation/InstructionOperandSize.hpp @@ -9,8 +9,7 @@ #ifndef InstructionSets_68k_InstructionOperandSize_hpp #define InstructionSets_68k_InstructionOperandSize_hpp -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { template constexpr DataSize operand_size(Operation r_operation) { @@ -128,7 +127,6 @@ constexpr DataSize operand_size(Operation r_operation) { } } -} } #endif /* InstructionSets_68k_InstructionOperandSize_hpp */ diff --git a/InstructionSets/M68k/Implementation/PerformImplementation.hpp b/InstructionSets/M68k/Implementation/PerformImplementation.hpp index 2291ef6b1..51c2fc81c 100644 --- a/InstructionSets/M68k/Implementation/PerformImplementation.hpp +++ b/InstructionSets/M68k/Implementation/PerformImplementation.hpp @@ -15,8 +15,7 @@ #include #include -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { /// Sign-extend @c x to 32 bits and return as an unsigned 32-bit int. inline uint32_t u_extend16(uint16_t x) { return uint32_t(int16_t(x)); } @@ -1030,7 +1029,6 @@ template < } -} } #endif /* InstructionSets_M68k_PerformImplementation_h */ diff --git a/InstructionSets/M68k/Instruction.hpp b/InstructionSets/M68k/Instruction.hpp index b7b7ce0ac..5251cf5af 100644 --- a/InstructionSets/M68k/Instruction.hpp +++ b/InstructionSets/M68k/Instruction.hpp @@ -15,8 +15,7 @@ #include #include -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { enum class Operation: uint8_t { Undefined, @@ -494,7 +493,6 @@ class Preinstruction { const char *operation_string() const; }; -} } #include "Implementation/InstructionOperandSize.hpp" diff --git a/InstructionSets/M68k/Model.hpp b/InstructionSets/M68k/Model.hpp index 3de18d405..65572331c 100644 --- a/InstructionSets/M68k/Model.hpp +++ b/InstructionSets/M68k/Model.hpp @@ -9,8 +9,7 @@ #ifndef InstructionSets_M68k_Model_hpp #define InstructionSets_M68k_Model_hpp -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { enum class Model { M68000, @@ -20,7 +19,6 @@ enum class Model { M68040, }; -} } #endif /* InstructionSets_M68k_Model_hpp */ diff --git a/InstructionSets/M68k/Perform.hpp b/InstructionSets/M68k/Perform.hpp index 300706b00..7bba658b3 100644 --- a/InstructionSets/M68k/Perform.hpp +++ b/InstructionSets/M68k/Perform.hpp @@ -14,8 +14,7 @@ #include "Status.hpp" #include "../../Numeric/RegisterSizes.hpp" -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { struct NullFlowController { // @@ -167,7 +166,6 @@ template < Operation operation = Operation::Undefined > void perform(Preinstruction instruction, CPU::RegisterPair32 &source, CPU::RegisterPair32 &dest, Status &status, FlowController &flow_controller); -} } #include "Implementation/PerformImplementation.hpp" diff --git a/InstructionSets/M68k/RegisterSet.hpp b/InstructionSets/M68k/RegisterSet.hpp index 87e98f70b..ee2a66f3b 100644 --- a/InstructionSets/M68k/RegisterSet.hpp +++ b/InstructionSets/M68k/RegisterSet.hpp @@ -9,8 +9,7 @@ #ifndef InstructionSets_M68k_RegisterSet_h #define InstructionSets_M68k_RegisterSet_h -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { struct RegisterSet { uint32_t data[8], address[7]; @@ -25,7 +24,6 @@ struct RegisterSet { } }; -} } #endif /* InstructionSets_M68k_RegisterSet_h */ diff --git a/InstructionSets/M68k/Status.hpp b/InstructionSets/M68k/Status.hpp index 22f15c52d..404eefb24 100644 --- a/InstructionSets/M68k/Status.hpp +++ b/InstructionSets/M68k/Status.hpp @@ -11,8 +11,7 @@ #include "Instruction.hpp" -namespace InstructionSet { -namespace M68k { +namespace InstructionSet::M68k { namespace ConditionCode { @@ -159,7 +158,6 @@ struct Status { } }; -} } #endif /* InstructionSets_M68k_Status_h */ diff --git a/InstructionSets/PowerPC/Decoder.hpp b/InstructionSets/PowerPC/Decoder.hpp index ac763217e..9f2cb6e1d 100644 --- a/InstructionSets/PowerPC/Decoder.hpp +++ b/InstructionSets/PowerPC/Decoder.hpp @@ -11,8 +11,7 @@ #include "Instruction.hpp" -namespace InstructionSet { -namespace PowerPC { +namespace InstructionSet::PowerPC { enum class Model { /// i.e. 32-bit, with POWER carry-over instructions. @@ -50,7 +49,6 @@ template struct Decoder { Instruction decode(uint32_t opcode); }; -} } #endif /* InstructionSets_PowerPC_Decoder_hpp */ diff --git a/InstructionSets/PowerPC/Instruction.hpp b/InstructionSets/PowerPC/Instruction.hpp index 07d9b0175..9348ea08b 100644 --- a/InstructionSets/PowerPC/Instruction.hpp +++ b/InstructionSets/PowerPC/Instruction.hpp @@ -11,8 +11,7 @@ #include -namespace InstructionSet { -namespace PowerPC { +namespace InstructionSet::PowerPC { enum class CacheLine: uint32_t { Instruction = 0b01100, @@ -1530,7 +1529,6 @@ struct Instruction { // Sanity check on Instruction size. static_assert(sizeof(Instruction) <= 8); -} } #endif /* InstructionSets_PowerPC_Instruction_h */ diff --git a/InstructionSets/x86/DataPointerResolver.hpp b/InstructionSets/x86/DataPointerResolver.hpp index 2a2197a25..df7aa53db 100644 --- a/InstructionSets/x86/DataPointerResolver.hpp +++ b/InstructionSets/x86/DataPointerResolver.hpp @@ -14,8 +14,7 @@ #include -namespace InstructionSet { -namespace x86 { +namespace InstructionSet::x86 { /// Unlike source, describes only registers, and breaks /// them down by conventional name — so AL, AH, AX and EAX are all @@ -314,7 +313,6 @@ template void DataPointerResolver #include -namespace InstructionSet { -namespace x86 { +namespace InstructionSet::x86 { /*! Implements Intel x86 instruction decoding. @@ -227,7 +226,6 @@ template class Decoder { } }; -} } #endif /* InstructionSets_x86_Decoder_hpp */ diff --git a/InstructionSets/x86/Instruction.hpp b/InstructionSets/x86/Instruction.hpp index d34acb44c..a3172f911 100644 --- a/InstructionSets/x86/Instruction.hpp +++ b/InstructionSets/x86/Instruction.hpp @@ -13,8 +13,7 @@ #include #include -namespace InstructionSet { -namespace x86 { +namespace InstructionSet::x86 { /* Operations are documented below to establish expectations as to which @@ -796,7 +795,6 @@ template class Instruction { static_assert(sizeof(Instruction) <= 16); static_assert(sizeof(Instruction) <= 10); -} } #endif /* InstructionSets_x86_Instruction_h */ diff --git a/InstructionSets/x86/Model.hpp b/InstructionSets/x86/Model.hpp index 304214475..4a4ac0bdb 100644 --- a/InstructionSets/x86/Model.hpp +++ b/InstructionSets/x86/Model.hpp @@ -9,8 +9,7 @@ #ifndef Model_h #define Model_h -namespace InstructionSet { -namespace x86 { +namespace InstructionSet::x86 { enum class Model { i8086, @@ -21,7 +20,6 @@ enum class Model { static constexpr bool is_32bit(Model model) { return model >= Model::i80386; } -} } #endif /* Model_h */ diff --git a/Machines/Apple/ADB/Bus.hpp b/Machines/Apple/ADB/Bus.hpp index a39f530ef..a6d35099f 100644 --- a/Machines/Apple/ADB/Bus.hpp +++ b/Machines/Apple/ADB/Bus.hpp @@ -16,8 +16,7 @@ #include #include -namespace Apple { -namespace ADB { +namespace Apple::ADB { struct Command { enum class Type { @@ -166,7 +165,6 @@ class Bus { } phase_ = Phase::AttentionCapture; }; -} } #endif /* Bus_hpp */ diff --git a/Machines/Apple/ADB/Keyboard.hpp b/Machines/Apple/ADB/Keyboard.hpp index a8213dd28..7438f6bc6 100644 --- a/Machines/Apple/ADB/Keyboard.hpp +++ b/Machines/Apple/ADB/Keyboard.hpp @@ -18,8 +18,7 @@ #include #include -namespace Apple { -namespace ADB { +namespace Apple::ADB { /*! Defines the keycodes that could be passed directly via set_key_pressed; these @@ -119,7 +118,6 @@ class KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final; }; -} } #endif /* Keyboard_hpp */ diff --git a/Machines/Apple/ADB/Mouse.hpp b/Machines/Apple/ADB/Mouse.hpp index 3e8a4dc1f..a085089e4 100644 --- a/Machines/Apple/ADB/Mouse.hpp +++ b/Machines/Apple/ADB/Mouse.hpp @@ -12,8 +12,7 @@ #include "ReactiveDevice.hpp" #include "../../../Inputs/Mouse.hpp" -namespace Apple { -namespace ADB { +namespace Apple::ADB { class Mouse: public ReactiveDevice, public Inputs::Mouse { public: @@ -32,7 +31,6 @@ class Mouse: public ReactiveDevice, public Inputs::Mouse { uint16_t last_posted_reg0_ = 0; }; -} } #endif /* Mouse_hpp */ diff --git a/Machines/Apple/ADB/ReactiveDevice.hpp b/Machines/Apple/ADB/ReactiveDevice.hpp index 54a3ad53c..215a2123c 100644 --- a/Machines/Apple/ADB/ReactiveDevice.hpp +++ b/Machines/Apple/ADB/ReactiveDevice.hpp @@ -15,8 +15,7 @@ #include #include -namespace Apple { -namespace ADB { +namespace Apple::ADB { class ReactiveDevice: public Bus::Device { protected: @@ -60,7 +59,6 @@ class ReactiveDevice: public Bus::Device { void reset(); }; -} } #endif /* ReactiveDevice_hpp */ diff --git a/Machines/Apple/AppleII/AppleII.hpp b/Machines/Apple/AppleII/AppleII.hpp index 97d348578..2e8733ce4 100644 --- a/Machines/Apple/AppleII/AppleII.hpp +++ b/Machines/Apple/AppleII/AppleII.hpp @@ -16,8 +16,7 @@ #include -namespace Apple { -namespace II { +namespace Apple::II { class Machine { public: @@ -42,7 +41,6 @@ class Machine { }; }; -} } #endif /* AppleII_hpp */ diff --git a/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp b/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp index 389083b95..3c12a5e00 100644 --- a/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp +++ b/Machines/Apple/AppleII/AuxiliaryMemorySwitches.hpp @@ -11,8 +11,7 @@ #include "MemorySwitches.hpp" -namespace Apple { -namespace II { +namespace Apple::II { /*! Models the auxiliary memory soft switches, added as of the Apple IIe, which allow access to the auxiliary 64kb of RAM and to @@ -271,7 +270,6 @@ template class AuxiliaryMemorySwitches { } }; -} } #endif /* AuxiliaryMemorySwitches_h */ diff --git a/Machines/Apple/AppleII/Card.hpp b/Machines/Apple/AppleII/Card.hpp index 60c3bd519..64f0e9c78 100644 --- a/Machines/Apple/AppleII/Card.hpp +++ b/Machines/Apple/AppleII/Card.hpp @@ -13,8 +13,7 @@ #include "../../../ClockReceiver/ClockReceiver.hpp" #include "../../../Activity/Observer.hpp" -namespace Apple { -namespace II { +namespace Apple::II { /*! This provides a small subset of the interface offered to cards installed in @@ -112,7 +111,6 @@ class Card { } }; -} } #endif /* Card_h */ diff --git a/Machines/Apple/AppleII/DiskIICard.hpp b/Machines/Apple/AppleII/DiskIICard.hpp index 979d31b07..0d3803ba5 100644 --- a/Machines/Apple/AppleII/DiskIICard.hpp +++ b/Machines/Apple/AppleII/DiskIICard.hpp @@ -20,8 +20,7 @@ #include #include -namespace Apple { -namespace II { +namespace Apple::II { class DiskIICard: public Card, public ClockingHint::Observer { public: @@ -43,7 +42,6 @@ class DiskIICard: public Card, public ClockingHint::Observer { ClockingHint::Preference diskii_clocking_preference_ = ClockingHint::Preference::RealTime; }; -} } #endif /* DiskIICard_hpp */ diff --git a/Machines/Apple/AppleII/Joystick.hpp b/Machines/Apple/AppleII/Joystick.hpp index 33f943c54..d76e02f99 100644 --- a/Machines/Apple/AppleII/Joystick.hpp +++ b/Machines/Apple/AppleII/Joystick.hpp @@ -14,8 +14,7 @@ #include #include -namespace Apple { -namespace II { +namespace Apple::II { class JoystickPair { public: @@ -106,7 +105,6 @@ class JoystickPair { } }; -} } #endif /* AppleII_Joystick_hpp */ diff --git a/Machines/Apple/AppleII/LanguageCardSwitches.hpp b/Machines/Apple/AppleII/LanguageCardSwitches.hpp index 873260a36..5efddf526 100644 --- a/Machines/Apple/AppleII/LanguageCardSwitches.hpp +++ b/Machines/Apple/AppleII/LanguageCardSwitches.hpp @@ -11,8 +11,7 @@ #include "MemorySwitches.hpp" -namespace Apple { -namespace II { +namespace Apple::II { /*! Models the language card soft switches, present on any Apple II with a language card and provided built-in from the IIe onwards. @@ -112,7 +111,6 @@ template class LanguageCardSwitches { bool pre_write_ = false; }; -} } #endif /* LanguageCard_h */ diff --git a/Machines/Apple/AppleII/MemorySwitches.hpp b/Machines/Apple/AppleII/MemorySwitches.hpp index c71bd4c1e..5be77517a 100644 --- a/Machines/Apple/AppleII/MemorySwitches.hpp +++ b/Machines/Apple/AppleII/MemorySwitches.hpp @@ -9,8 +9,7 @@ #ifndef MemorySwitches_h #define MemorySwitches_h -namespace Apple { -namespace II { +namespace Apple::II { enum PagingType: int { Main = 1 << 0, @@ -19,7 +18,6 @@ enum PagingType: int { LanguageCard = 1 << 3, }; -} } #endif /* MemorySwitches_h */ diff --git a/Machines/Apple/AppleII/SCSICard.hpp b/Machines/Apple/AppleII/SCSICard.hpp index 0859730b1..d12d12918 100644 --- a/Machines/Apple/AppleII/SCSICard.hpp +++ b/Machines/Apple/AppleII/SCSICard.hpp @@ -21,8 +21,7 @@ #include #include -namespace Apple { -namespace II { +namespace Apple::II { class SCSICard: public Card { public: @@ -51,7 +50,6 @@ class SCSICard: public Card { SCSI::Target::Target storage_; }; -} } #endif /* SCSICard_hpp */ diff --git a/Machines/Apple/AppleII/Video.hpp b/Machines/Apple/AppleII/Video.hpp index 1e66d1cc2..1e84d2c04 100644 --- a/Machines/Apple/AppleII/Video.hpp +++ b/Machines/Apple/AppleII/Video.hpp @@ -18,9 +18,7 @@ #include #include -namespace Apple { -namespace II { -namespace Video { +namespace Apple::II::Video { class BusHandler { public: @@ -439,8 +437,6 @@ template class Video: public VideoBase { BusHandler &bus_handler_; }; -} -} } #endif /* Apple_II_Video_hpp */ diff --git a/Machines/Apple/AppleII/VideoSwitches.hpp b/Machines/Apple/AppleII/VideoSwitches.hpp index 7852516f4..dd4845e2e 100644 --- a/Machines/Apple/AppleII/VideoSwitches.hpp +++ b/Machines/Apple/AppleII/VideoSwitches.hpp @@ -13,8 +13,7 @@ #include "../../../ClockReceiver/DeferredQueue.hpp" #include "../../ROMMachine.hpp" -namespace Apple { -namespace II { +namespace Apple::II { // Enumerates all Apple II and IIe display modes. enum class GraphicsMode { @@ -341,7 +340,6 @@ template class VideoSwitches { std::vector character_rom_; }; -} } #endif /* VideoSwitches_h */ diff --git a/Machines/Apple/AppleIIgs/ADB.hpp b/Machines/Apple/AppleIIgs/ADB.hpp index a57594335..fb055da26 100644 --- a/Machines/Apple/AppleIIgs/ADB.hpp +++ b/Machines/Apple/AppleIIgs/ADB.hpp @@ -17,9 +17,7 @@ #include "../ADB/Mouse.hpp" #include "../ADB/Keyboard.hpp" -namespace Apple { -namespace IIgs { -namespace ADB { +namespace Apple::IIgs::ADB { class GLU: public InstructionSet::M50740::PortHandler { public: @@ -85,8 +83,6 @@ class GLU: public InstructionSet::M50740::PortHandler { Apple::ADB::Keyboard keyboard_; }; -} -} } #endif /* Apple_IIgs_ADB_hpp */ diff --git a/Machines/Apple/AppleIIgs/AppleIIgs.hpp b/Machines/Apple/AppleIIgs/AppleIIgs.hpp index f92bfd11c..1cd1a862a 100644 --- a/Machines/Apple/AppleIIgs/AppleIIgs.hpp +++ b/Machines/Apple/AppleIIgs/AppleIIgs.hpp @@ -16,8 +16,7 @@ #include -namespace Apple { -namespace IIgs { +namespace Apple::IIgs { class Machine { public: @@ -27,7 +26,6 @@ class Machine { static Machine *AppleIIgs(const Analyser::Static::Target *target, const ROMMachine::ROMFetcher &rom_fetcher); }; -} } #endif /* Machines_Apple_AppleIIgs_hpp */ diff --git a/Machines/Apple/AppleIIgs/MemoryMap.hpp b/Machines/Apple/AppleIIgs/MemoryMap.hpp index f52b98dad..ff9ce110c 100644 --- a/Machines/Apple/AppleIIgs/MemoryMap.hpp +++ b/Machines/Apple/AppleIIgs/MemoryMap.hpp @@ -16,8 +16,7 @@ #include "../AppleII/LanguageCardSwitches.hpp" #include "../AppleII/AuxiliaryMemorySwitches.hpp" -namespace Apple { -namespace IIgs { +namespace Apple::IIgs { class MemoryMap { private: @@ -687,7 +686,6 @@ class MemoryMap { // // With a further twist: the modulo and pointer are indexed on ::IsShadowed to eliminate a branch even on that. -} } #endif /* MemoryMap_h */ diff --git a/Machines/Apple/AppleIIgs/Sound.hpp b/Machines/Apple/AppleIIgs/Sound.hpp index 942a94b7d..c9cba701e 100644 --- a/Machines/Apple/AppleIIgs/Sound.hpp +++ b/Machines/Apple/AppleIIgs/Sound.hpp @@ -15,9 +15,7 @@ #include "../../../Concurrency/AsyncTaskQueue.hpp" #include "../../../Outputs/Speaker/Implementation/SampleSource.hpp" -namespace Apple { -namespace IIgs { -namespace Sound { +namespace Apple::IIgs::Sound { class GLU: public Outputs::Speaker::SampleSource { public: @@ -104,8 +102,6 @@ class GLU: public Outputs::Speaker::SampleSource { int16_t output_range_ = 0; }; -} -} } #endif /* SoundGLU_hpp */ diff --git a/Machines/Apple/AppleIIgs/Video.hpp b/Machines/Apple/AppleIIgs/Video.hpp index d02e21d63..6d7ba977c 100644 --- a/Machines/Apple/AppleIIgs/Video.hpp +++ b/Machines/Apple/AppleIIgs/Video.hpp @@ -13,9 +13,7 @@ #include "../../../Outputs/CRT/CRT.hpp" #include "../../../ClockReceiver/ClockReceiver.hpp" -namespace Apple { -namespace IIgs { -namespace Video { +namespace Apple::IIgs::Video { /*! Provides IIgs video output; assumed clocking here is seven times the usual Apple II clock. @@ -205,8 +203,6 @@ class Video: public Apple::II::VideoSwitches { int megaii_frame_counter_ = 0; // To count up to quarter-second interrupts. }; -} -} } #endif /* Video_hpp */ diff --git a/Machines/Apple/Macintosh/Audio.hpp b/Machines/Apple/Macintosh/Audio.hpp index bdf0ebd40..457bec6b0 100644 --- a/Machines/Apple/Macintosh/Audio.hpp +++ b/Machines/Apple/Macintosh/Audio.hpp @@ -16,8 +16,7 @@ #include #include -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { /*! Implements the Macintosh's audio output hardware. @@ -83,7 +82,6 @@ class Audio: public ::Outputs::Speaker::SampleSource { void set_volume_multiplier(); }; -} } #endif /* Audio_hpp */ diff --git a/Machines/Apple/Macintosh/DeferredAudio.hpp b/Machines/Apple/Macintosh/DeferredAudio.hpp index 9277e1569..395632f14 100644 --- a/Machines/Apple/Macintosh/DeferredAudio.hpp +++ b/Machines/Apple/Macintosh/DeferredAudio.hpp @@ -12,8 +12,7 @@ #include "Audio.hpp" #include "../../../Outputs/Speaker/Implementation/LowpassSpeaker.hpp" -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { struct DeferredAudio { Concurrency::AsyncTaskQueue queue; @@ -28,7 +27,6 @@ struct DeferredAudio { } }; -} } #endif /* DeferredAudio_h */ diff --git a/Machines/Apple/Macintosh/DriveSpeedAccumulator.hpp b/Machines/Apple/Macintosh/DriveSpeedAccumulator.hpp index 45568e006..815e354f5 100644 --- a/Machines/Apple/Macintosh/DriveSpeedAccumulator.hpp +++ b/Machines/Apple/Macintosh/DriveSpeedAccumulator.hpp @@ -13,8 +13,7 @@ #include #include -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { class DriveSpeedAccumulator { public: @@ -40,7 +39,6 @@ class DriveSpeedAccumulator { Delegate *delegate_ = nullptr; }; -} } #endif /* DriveSpeedAccumulator_hpp */ diff --git a/Machines/Apple/Macintosh/Keyboard.hpp b/Machines/Apple/Macintosh/Keyboard.hpp index d69af1f56..9f77eb348 100644 --- a/Machines/Apple/Macintosh/Keyboard.hpp +++ b/Machines/Apple/Macintosh/Keyboard.hpp @@ -15,8 +15,7 @@ #include #include -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { constexpr uint16_t KeypadMask = 0x100; @@ -294,7 +293,6 @@ class KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const final; }; -} } #endif /* Apple_Macintosh_Keyboard_hpp */ diff --git a/Machines/Apple/Macintosh/Macintosh.hpp b/Machines/Apple/Macintosh/Macintosh.hpp index 5c42b555f..167106ff7 100644 --- a/Machines/Apple/Macintosh/Macintosh.hpp +++ b/Machines/Apple/Macintosh/Macintosh.hpp @@ -14,8 +14,7 @@ #include "../../../Analyser/Static/StaticAnalyser.hpp" #include "../../ROMMachine.hpp" -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { class Machine { public: @@ -36,8 +35,6 @@ class Machine { }; }; - -} } #endif /* Macintosh_hpp */ diff --git a/Machines/Apple/Macintosh/Video.hpp b/Machines/Apple/Macintosh/Video.hpp index 4ade61a19..87aa4b61d 100644 --- a/Machines/Apple/Macintosh/Video.hpp +++ b/Machines/Apple/Macintosh/Video.hpp @@ -14,8 +14,7 @@ #include "DeferredAudio.hpp" #include "DriveSpeedAccumulator.hpp" -namespace Apple { -namespace Macintosh { +namespace Apple::Macintosh { constexpr HalfCycles line_length(704); constexpr int number_of_lines = 370; @@ -102,7 +101,6 @@ class Video { bool use_alternate_audio_buffer_ = false; }; -} } #endif /* Video_hpp */ diff --git a/Machines/Atari/2600/Cartridges/ActivisionStack.hpp b/Machines/Atari/2600/Cartridges/ActivisionStack.hpp index 025a874b4..6fcc46712 100644 --- a/Machines/Atari/2600/Cartridges/ActivisionStack.hpp +++ b/Machines/Atari/2600/Cartridges/ActivisionStack.hpp @@ -9,8 +9,7 @@ #ifndef Atari2600_ActivisionStack_hpp #define Atari2600_ActivisionStack_hpp -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class ActivisionStack: public BusExtender { public: @@ -45,7 +44,6 @@ class ActivisionStack: public BusExtender { uint8_t last_opcode_; }; -} } #endif /* Atari2600_CartridgeActivisionStack_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Atari16k.hpp b/Machines/Atari/2600/Cartridges/Atari16k.hpp index a98ff72fd..b99381305 100644 --- a/Machines/Atari/2600/Cartridges/Atari16k.hpp +++ b/Machines/Atari/2600/Cartridges/Atari16k.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class Atari16k: public BusExtender { public: @@ -60,7 +59,6 @@ class Atari16kSuperChip: public BusExtender { uint8_t ram_[128]; }; -} } #endif /* Atari2600_CartridgeAtari16k_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Atari32k.hpp b/Machines/Atari/2600/Cartridges/Atari32k.hpp index eff10e86d..dba8c9a7b 100644 --- a/Machines/Atari/2600/Cartridges/Atari32k.hpp +++ b/Machines/Atari/2600/Cartridges/Atari32k.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class Atari32k: public BusExtender { public: @@ -56,7 +55,6 @@ class Atari32kSuperChip: public BusExtender { uint8_t ram_[128]; }; -} } #endif /* Atari2600_CartridgeAtari32k_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Atari8k.hpp b/Machines/Atari/2600/Cartridges/Atari8k.hpp index 9f57527f8..5fe346734 100644 --- a/Machines/Atari/2600/Cartridges/Atari8k.hpp +++ b/Machines/Atari/2600/Cartridges/Atari8k.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class Atari8k: public BusExtender { public: @@ -58,7 +57,6 @@ class Atari8kSuperChip: public BusExtender { uint8_t ram_[128]; }; -} } #endif /* Atari2600_CartridgeAtari8k_hpp */ diff --git a/Machines/Atari/2600/Cartridges/CBSRAMPlus.hpp b/Machines/Atari/2600/Cartridges/CBSRAMPlus.hpp index e10a5f287..4c064f3ef 100644 --- a/Machines/Atari/2600/Cartridges/CBSRAMPlus.hpp +++ b/Machines/Atari/2600/Cartridges/CBSRAMPlus.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class CBSRAMPlus: public BusExtender { public: @@ -37,7 +36,6 @@ class CBSRAMPlus: public BusExtender { uint8_t ram_[256]; }; -} } #endif /* Atari2600_CartridgeCBSRAMPlus_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Cartridge.hpp b/Machines/Atari/2600/Cartridges/Cartridge.hpp index 90706fb04..a2c6538da 100644 --- a/Machines/Atari/2600/Cartridges/Cartridge.hpp +++ b/Machines/Atari/2600/Cartridges/Cartridge.hpp @@ -12,8 +12,7 @@ #include "../../../../Processors/6502/6502.hpp" #include "../Bus.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class BusExtender: public CPU::MOS6502::BusHandler { public: @@ -214,7 +213,6 @@ template class Cartridge: }; -} } #endif /* Atari2600_Cartridge_hpp */ diff --git a/Machines/Atari/2600/Cartridges/CommaVid.hpp b/Machines/Atari/2600/Cartridges/CommaVid.hpp index 251abb139..d6c576387 100644 --- a/Machines/Atari/2600/Cartridges/CommaVid.hpp +++ b/Machines/Atari/2600/Cartridges/CommaVid.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class CommaVid: public BusExtender { public: @@ -39,7 +38,6 @@ class CommaVid: public BusExtender { uint8_t ram_[1024]; }; -} } #endif /* Atari2600_CartridgeCommaVid_hpp */ diff --git a/Machines/Atari/2600/Cartridges/MNetwork.hpp b/Machines/Atari/2600/Cartridges/MNetwork.hpp index 9ad5a0faa..c85b854a3 100644 --- a/Machines/Atari/2600/Cartridges/MNetwork.hpp +++ b/Machines/Atari/2600/Cartridges/MNetwork.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class MNetwork: public BusExtender { public: @@ -63,7 +62,6 @@ class MNetwork: public BusExtender { uint8_t low_ram_[1024], high_ram_[1024]; }; -} } #endif /* Atari2600_CartridgeMNetwork_hpp */ diff --git a/Machines/Atari/2600/Cartridges/MegaBoy.hpp b/Machines/Atari/2600/Cartridges/MegaBoy.hpp index a4cc2b91f..b00ab909d 100644 --- a/Machines/Atari/2600/Cartridges/MegaBoy.hpp +++ b/Machines/Atari/2600/Cartridges/MegaBoy.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class MegaBoy: public BusExtender { public: @@ -41,7 +40,6 @@ class MegaBoy: public BusExtender { uint8_t current_page_; }; -} } #endif /* CartridgeMegaBoy_h */ diff --git a/Machines/Atari/2600/Cartridges/ParkerBros.hpp b/Machines/Atari/2600/Cartridges/ParkerBros.hpp index 559491bad..9e3c9ee5d 100644 --- a/Machines/Atari/2600/Cartridges/ParkerBros.hpp +++ b/Machines/Atari/2600/Cartridges/ParkerBros.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class ParkerBros: public BusExtender { public: @@ -42,7 +41,6 @@ class ParkerBros: public BusExtender { uint8_t *rom_ptr_[4]; }; -} } #endif /* Atari2600_CartridgeParkerBros_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Pitfall2.hpp b/Machines/Atari/2600/Cartridges/Pitfall2.hpp index 3cd2dd557..35e7236bf 100644 --- a/Machines/Atari/2600/Cartridges/Pitfall2.hpp +++ b/Machines/Atari/2600/Cartridges/Pitfall2.hpp @@ -9,8 +9,7 @@ #ifndef Atari2600_CartridgePitfall2_hpp #define Atari2600_CartridgePitfall2_hpp -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class Pitfall2: public BusExtender { public: @@ -123,7 +122,6 @@ class Pitfall2: public BusExtender { Cycles cycles_since_audio_update_ = 0; }; -} } #endif /* Atari2600_CartridgePitfall2_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Tigervision.hpp b/Machines/Atari/2600/Cartridges/Tigervision.hpp index fa2f46a51..c9fa9856e 100644 --- a/Machines/Atari/2600/Cartridges/Tigervision.hpp +++ b/Machines/Atari/2600/Cartridges/Tigervision.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class Tigervision: public BusExtender { public: @@ -36,7 +35,6 @@ class Tigervision: public BusExtender { uint8_t *rom_ptr_[2]; }; -} } #endif /* Atari2600_CartridgeTigervision_hpp */ diff --git a/Machines/Atari/2600/Cartridges/Unpaged.hpp b/Machines/Atari/2600/Cartridges/Unpaged.hpp index 703e127c3..fbf192f78 100644 --- a/Machines/Atari/2600/Cartridges/Unpaged.hpp +++ b/Machines/Atari/2600/Cartridges/Unpaged.hpp @@ -11,8 +11,7 @@ #include "Cartridge.hpp" -namespace Atari2600 { -namespace Cartridge { +namespace Atari2600::Cartridge { class Unpaged: public BusExtender { public: @@ -25,7 +24,6 @@ class Unpaged: public BusExtender { } }; -} } #endif /* Atari2600_CartridgeUnpaged_hpp */ diff --git a/Machines/Atari/ST/AtariST.hpp b/Machines/Atari/ST/AtariST.hpp index 8f3274780..3db975087 100644 --- a/Machines/Atari/ST/AtariST.hpp +++ b/Machines/Atari/ST/AtariST.hpp @@ -16,8 +16,7 @@ #include -namespace Atari { -namespace ST { +namespace Atari::ST { class Machine { public: @@ -39,5 +38,5 @@ class Machine { }; } -} + #endif /* AtariST_hpp */ diff --git a/Machines/Atari/ST/DMAController.hpp b/Machines/Atari/ST/DMAController.hpp index 35d3ade03..8eeb5f202 100644 --- a/Machines/Atari/ST/DMAController.hpp +++ b/Machines/Atari/ST/DMAController.hpp @@ -17,8 +17,7 @@ #include "../../../Components/1770/1770.hpp" #include "../../../Activity/Source.hpp" -namespace Atari { -namespace ST { +namespace Atari::ST { class DMAController: public WD::WD1770::Delegate, public ClockingHint::Source, public ClockingHint::Observer { public: @@ -110,7 +109,6 @@ class DMAController: public WD::WD1770::Delegate, public ClockingHint::Source, p int byte_count_ = 0; }; -} } #endif /* DMAController_hpp */ diff --git a/Machines/Atari/ST/IntelligentKeyboard.hpp b/Machines/Atari/ST/IntelligentKeyboard.hpp index e876e0d88..8599ecf19 100644 --- a/Machines/Atari/ST/IntelligentKeyboard.hpp +++ b/Machines/Atari/ST/IntelligentKeyboard.hpp @@ -21,8 +21,7 @@ #include #include -namespace Atari { -namespace ST { +namespace Atari::ST { enum class Key: uint16_t { Escape = 1, @@ -196,7 +195,6 @@ class IntelligentKeyboard: std::vector> joysticks_; }; -} } #endif /* IntelligentKeyboard_hpp */ diff --git a/Machines/Atari/ST/Video.hpp b/Machines/Atari/ST/Video.hpp index a467c33cc..547c02cbe 100644 --- a/Machines/Atari/ST/Video.hpp +++ b/Machines/Atari/ST/Video.hpp @@ -18,8 +18,7 @@ // Testing hook; not for any other user. class VideoTester; -namespace Atari { -namespace ST { +namespace Atari::ST { struct LineLength { int length = 1024; @@ -249,7 +248,6 @@ class Video { friend class ::VideoTester; }; -} } #endif /* Atari_ST_Video_hpp */ diff --git a/Machines/ColecoVision/ColecoVision.hpp b/Machines/ColecoVision/ColecoVision.hpp index 4e5f0ce2c..1438e48bf 100644 --- a/Machines/ColecoVision/ColecoVision.hpp +++ b/Machines/ColecoVision/ColecoVision.hpp @@ -14,8 +14,7 @@ #include "../../Analyser/Static/StaticAnalyser.hpp" #include "../ROMMachine.hpp" -namespace Coleco { -namespace Vision { +namespace Coleco::Vision { class Machine { public: @@ -35,7 +34,6 @@ class Machine { }; }; -} } #endif /* ColecoVision_hpp */ diff --git a/Machines/Commodore/1540/C1540.hpp b/Machines/Commodore/1540/C1540.hpp index b04334423..52602f9da 100644 --- a/Machines/Commodore/1540/C1540.hpp +++ b/Machines/Commodore/1540/C1540.hpp @@ -9,8 +9,7 @@ #ifndef Commodore1540_hpp #define Commodore1540_hpp -namespace Commodore { -namespace C1540 { +namespace Commodore::C1540 { /// Defines the type of drive this 1540 hardware is configured as. enum class Personality { @@ -25,7 +24,6 @@ enum class Personality { to be to create a single file of public interface. */ -} } #include "../SerialBus.hpp" @@ -33,8 +31,7 @@ enum class Personality { #include "../../../Storage/Disk/Disk.hpp" #include "Implementation/C1540Base.hpp" -namespace Commodore { -namespace C1540 { +namespace Commodore::C1540 { /*! Provides an emulation of the C1540. @@ -56,7 +53,6 @@ class Machine final: public MachineBase { void set_disk(std::shared_ptr disk); }; -} } #endif /* Commodore1540_hpp */ diff --git a/Machines/Commodore/1540/Implementation/C1540Base.hpp b/Machines/Commodore/1540/Implementation/C1540Base.hpp index f0f50f8b3..db295f499 100644 --- a/Machines/Commodore/1540/Implementation/C1540Base.hpp +++ b/Machines/Commodore/1540/Implementation/C1540Base.hpp @@ -21,8 +21,7 @@ #include "../C1540.hpp" -namespace Commodore { -namespace C1540 { +namespace Commodore::C1540 { /*! An implementation of the serial-port VIA in a Commodore 1540: the VIA that facilitates all @@ -160,7 +159,6 @@ class MachineBase: virtual void process_index_hole(); }; -} } #endif /* C1540Base_hpp */ diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 52b6288b7..f62cc0e75 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -13,8 +13,7 @@ #include #include -namespace Commodore { -namespace Serial { +namespace Commodore::Serial { enum Line { ServiceRequest = 0, @@ -128,6 +127,5 @@ namespace Serial { }; } -} #endif /* SerialPort_hpp */ diff --git a/Machines/Commodore/Vic-20/Keyboard.hpp b/Machines/Commodore/Vic-20/Keyboard.hpp index cfe7f8a8b..77145d8f7 100644 --- a/Machines/Commodore/Vic-20/Keyboard.hpp +++ b/Machines/Commodore/Vic-20/Keyboard.hpp @@ -12,8 +12,7 @@ #include "../../KeyboardMachine.hpp" #include "../../Utility/Typer.hpp" -namespace Commodore { -namespace Vic20 { +namespace Commodore::Vic20 { enum Key: uint16_t { #define key(line, mask) (((mask) << 3) | (line)) @@ -55,7 +54,6 @@ struct CharacterMapper: public ::Utility::CharacterMapper { const uint16_t *sequence_for_character(char character) const final; }; -} } #endif /* Keyboard_hpp */ diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 03d8292e4..02d7b2d10 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -36,8 +36,7 @@ #include #include -namespace Commodore { -namespace Vic20 { +namespace Commodore::Vic20 { enum ROMSlot { Kernel = 0, @@ -755,7 +754,6 @@ class ConcreteMachine: std::shared_ptr<::Commodore::C1540::Machine> c1540_; }; -} } using namespace Commodore::Vic20; diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index c9583bfa4..51a8db20d 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -16,8 +16,7 @@ #include -namespace Commodore { -namespace Vic20 { +namespace Commodore::Vic20 { /// @returns The options available for a Vic-20. std::unique_ptr get_options(); @@ -45,7 +44,6 @@ class Machine { }; }; -} } #endif /* Vic20_hpp */ diff --git a/Machines/Enterprise/Dave.hpp b/Machines/Enterprise/Dave.hpp index efaa92d2b..88e282a2d 100644 --- a/Machines/Enterprise/Dave.hpp +++ b/Machines/Enterprise/Dave.hpp @@ -16,8 +16,7 @@ #include "../../Numeric/LFSR.hpp" #include "../../Outputs/Speaker/Implementation/SampleSource.hpp" -namespace Enterprise { -namespace Dave { +namespace Enterprise::Dave { enum class Interrupt: uint8_t { VariableFrequency = 0x02, @@ -182,7 +181,6 @@ class TimedInterruptSource { void update_channel(int c, bool is_linked, int decrement); }; -} } #endif /* Dave_hpp */ diff --git a/Machines/MasterSystem/MasterSystem.hpp b/Machines/MasterSystem/MasterSystem.hpp index 348842be9..c3b0fca6b 100644 --- a/Machines/MasterSystem/MasterSystem.hpp +++ b/Machines/MasterSystem/MasterSystem.hpp @@ -16,8 +16,7 @@ #include -namespace Sega { -namespace MasterSystem { +namespace Sega::MasterSystem { class Machine { public: @@ -36,7 +35,6 @@ class Machine { }; }; -} } #endif /* MasterSystem_hpp */ diff --git a/Machines/Sinclair/Keyboard/Keyboard.hpp b/Machines/Sinclair/Keyboard/Keyboard.hpp index 25fac9699..9ba4cfda4 100644 --- a/Machines/Sinclair/Keyboard/Keyboard.hpp +++ b/Machines/Sinclair/Keyboard/Keyboard.hpp @@ -12,9 +12,7 @@ #include "../../KeyboardMachine.hpp" #include "../../Utility/Typer.hpp" -namespace Sinclair { -namespace ZX { -namespace Keyboard { +namespace Sinclair::ZX::Keyboard { enum class Machine { ZX80, ZX81, ZXSpectrum @@ -74,8 +72,6 @@ class CharacterMapper: public ::Utility::CharacterMapper { const Machine machine_; }; -} -} } #endif /* KeyboardMapper_hpp */ diff --git a/Machines/Sinclair/ZX8081/Video.hpp b/Machines/Sinclair/ZX8081/Video.hpp index 555c75603..1b867d06b 100644 --- a/Machines/Sinclair/ZX8081/Video.hpp +++ b/Machines/Sinclair/ZX8081/Video.hpp @@ -12,8 +12,7 @@ #include "../../../Outputs/CRT/CRT.hpp" #include "../../../ClockReceiver/ClockReceiver.hpp" -namespace Sinclair { -namespace ZX8081 { +namespace Sinclair::ZX8081 { /*! Packages a ZX80/81-style video feed into a CRT-compatible waveform. @@ -58,7 +57,6 @@ class Video { void flush(bool next_sync); }; -} } #endif /* Video_hpp */ diff --git a/Machines/Sinclair/ZX8081/ZX8081.hpp b/Machines/Sinclair/ZX8081/ZX8081.hpp index d7ca68734..c755f8c94 100644 --- a/Machines/Sinclair/ZX8081/ZX8081.hpp +++ b/Machines/Sinclair/ZX8081/ZX8081.hpp @@ -16,8 +16,7 @@ #include -namespace Sinclair { -namespace ZX8081 { +namespace Sinclair::ZX8081 { /// The ZX80/81 machine. class Machine { @@ -47,7 +46,6 @@ class Machine { }; }; -} } #endif /* ZX8081_hpp */ diff --git a/Machines/Sinclair/ZXSpectrum/State.hpp b/Machines/Sinclair/ZXSpectrum/State.hpp index 3d3613c19..a65077f9a 100644 --- a/Machines/Sinclair/ZXSpectrum/State.hpp +++ b/Machines/Sinclair/ZXSpectrum/State.hpp @@ -15,9 +15,7 @@ #include "Video.hpp" #include "../../../Components/AY38910/AY38910.hpp" -namespace Sinclair { -namespace ZXSpectrum { - +namespace Sinclair::ZXSpectrum { struct State: public Reflection::StructImpl { CPU::Z80::State z80; @@ -47,7 +45,6 @@ struct State: public Reflection::StructImpl { } }; -} } #endif /* State_h */ diff --git a/Machines/Sinclair/ZXSpectrum/Video.hpp b/Machines/Sinclair/ZXSpectrum/Video.hpp index 805b4c2d3..fb6008297 100644 --- a/Machines/Sinclair/ZXSpectrum/Video.hpp +++ b/Machines/Sinclair/ZXSpectrum/Video.hpp @@ -16,9 +16,7 @@ #include -namespace Sinclair { -namespace ZXSpectrum { -namespace Video { +namespace Sinclair::ZXSpectrum::Video { enum class Timing { FortyEightK, @@ -492,8 +490,6 @@ struct State: public Reflection::StructImpl { } }; -} -} } #endif /* Video_hpp */ diff --git a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp index 7190c46ef..383252c90 100644 --- a/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp +++ b/Machines/Sinclair/ZXSpectrum/ZXSpectrum.hpp @@ -16,8 +16,7 @@ #include -namespace Sinclair { -namespace ZXSpectrum { +namespace Sinclair::ZXSpectrum { class Machine { public: @@ -47,8 +46,6 @@ class Machine { }; }; - -} } #endif /* ZXSpectrum_hpp */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 480346c72..95559cccf 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -2372,16 +2372,16 @@ 4B0ACC0E23775819008902D0 /* 2600 */ = { isa = PBXGroup; children = ( - 4B0ACC0F23775819008902D0 /* Cartridges */, + 4B0ACC2223775819008902D0 /* Atari2600.cpp */, 4B0ACC1D23775819008902D0 /* TIA.cpp */, - 4B0ACC1E23775819008902D0 /* TIASound.hpp */, + 4B0ACC2123775819008902D0 /* TIASound.cpp */, 4B0ACC1F23775819008902D0 /* Atari2600Inputs.h */, 4B0ACC2023775819008902D0 /* Atari2600.hpp */, - 4B0ACC2123775819008902D0 /* TIASound.cpp */, - 4B0ACC2223775819008902D0 /* Atari2600.cpp */, 4B0ACC2323775819008902D0 /* Bus.hpp */, 4B0ACC2423775819008902D0 /* PIA.hpp */, 4B0ACC2523775819008902D0 /* TIA.hpp */, + 4B0ACC1E23775819008902D0 /* TIASound.hpp */, + 4B0ACC0F23775819008902D0 /* Cartridges */, ); path = 2600; sourceTree = ""; @@ -2702,13 +2702,13 @@ 4B302181208A550100773308 /* DiskII */ = { isa = PBXGroup; children = ( - 4B80CD6D2568A82600176FCC /* DiskIIDrive.cpp */, - 4B80CD6E2568A82900176FCC /* DiskIIDrive.hpp */, - 4B302182208A550100773308 /* DiskII.hpp */, 4B302183208A550100773308 /* DiskII.cpp */, + 4B80CD6D2568A82600176FCC /* DiskIIDrive.cpp */, 4BEE1498227FC0EA00133682 /* IWM.cpp */, - 4BEE1499227FC0EA00133682 /* IWM.hpp */, 4BCD634722D6756400F567F1 /* MacintoshDoubleDensityDrive.cpp */, + 4B302182208A550100773308 /* DiskII.hpp */, + 4B80CD6E2568A82900176FCC /* DiskIIDrive.hpp */, + 4BEE1499227FC0EA00133682 /* IWM.hpp */, 4BCD634822D6756400F567F1 /* MacintoshDoubleDensityDrive.hpp */, ); path = DiskII; @@ -3558,11 +3558,11 @@ 4B8DD3832634D37E00B3C866 /* State */ = { isa = PBXGroup; children = ( - 4B2B946326377C0200E7097C /* SZX.cpp */, - 4B2B946426377C0200E7097C /* SZX.hpp */, 4B8DD3842634D37E00B3C866 /* SNA.cpp */, - 4B8DD3852634D37E00B3C866 /* SNA.hpp */, + 4B2B946326377C0200E7097C /* SZX.cpp */, 4B8DD39526360DDF00B3C866 /* Z80.cpp */, + 4B8DD3852634D37E00B3C866 /* SNA.hpp */, + 4B2B946426377C0200E7097C /* SZX.hpp */, 4B8DD39626360DDF00B3C866 /* Z80.hpp */, ); path = State; @@ -4543,9 +4543,9 @@ 4BC23A212467600E001A6030 /* OPx */ = { isa = PBXGroup; children = ( + 4BC23A2B2467600E001A6030 /* OPLL.cpp */, 4BC23A222467600E001A6030 /* OPLL.hpp */, 4BC23A232467600E001A6030 /* Implementation */, - 4BC23A2B2467600E001A6030 /* OPLL.cpp */, ); path = OPx; sourceTree = ""; @@ -4553,13 +4553,13 @@ 4BC23A232467600E001A6030 /* Implementation */ = { isa = PBXGroup; children = ( - 4BC23A242467600E001A6030 /* PhaseGenerator.hpp */, + 4BC23A2A2467600E001A6030 /* EnvelopeGenerator.hpp */, 4BC23A252467600E001A6030 /* KeyLevelScaler.hpp */, 4BC23A262467600E001A6030 /* LowFrequencyOscillator.hpp */, - 4BC23A272467600E001A6030 /* WaveformGenerator.hpp */, - 4BC23A282467600E001A6030 /* Tables.hpp */, 4BC23A292467600E001A6030 /* OPLBase.hpp */, - 4BC23A2A2467600E001A6030 /* EnvelopeGenerator.hpp */, + 4BC23A242467600E001A6030 /* PhaseGenerator.hpp */, + 4BC23A282467600E001A6030 /* Tables.hpp */, + 4BC23A272467600E001A6030 /* WaveformGenerator.hpp */, ); path = Implementation; sourceTree = ""; diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index 9749d5011..87abbda7f 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -17,8 +17,7 @@ #include "../ScanTarget.hpp" #include "Internals/Flywheel.hpp" -namespace Outputs { -namespace CRT { +namespace Outputs::CRT { class CRT; @@ -354,7 +353,6 @@ template class CRTFrequencyMismatchWarner: public Outputs::C size_t frame_record_pointer_ = 0; }; -} } #endif /* CRT_cpp */ diff --git a/Outputs/CRT/Internals/Flywheel.hpp b/Outputs/CRT/Internals/Flywheel.hpp index d4dc5655d..04f0c8e49 100644 --- a/Outputs/CRT/Internals/Flywheel.hpp +++ b/Outputs/CRT/Internals/Flywheel.hpp @@ -13,8 +13,7 @@ #include #include -namespace Outputs { -namespace CRT { +namespace Outputs::CRT { /*! Provides timing for a two-phase signal consisting of a retrace phase followed by a scan phase, @@ -259,7 +258,6 @@ struct Flywheel { */ }; -} } #endif /* Flywheel_hpp */ diff --git a/Outputs/DisplayMetrics.hpp b/Outputs/DisplayMetrics.hpp index 1983bdac1..792cbec68 100644 --- a/Outputs/DisplayMetrics.hpp +++ b/Outputs/DisplayMetrics.hpp @@ -15,8 +15,7 @@ #include #include -namespace Outputs { -namespace Display { +namespace Outputs::Display { /*! A class to derive various metrics about the input to a ScanTarget, @@ -56,7 +55,6 @@ class Metrics { std::atomic frames_missed_ = 0; }; -} } #endif /* DisplayMetrics_hpp */ diff --git a/Outputs/OpenGL/Primitives/Rectangle.hpp b/Outputs/OpenGL/Primitives/Rectangle.hpp index 0b15187b4..6e02b60db 100644 --- a/Outputs/OpenGL/Primitives/Rectangle.hpp +++ b/Outputs/OpenGL/Primitives/Rectangle.hpp @@ -13,9 +13,7 @@ #include "Shader.hpp" #include -namespace Outputs { -namespace Display { -namespace OpenGL { +namespace Outputs::Display::OpenGL { /*! Provides a wrapper for drawing a solid, single-colour rectangle. @@ -38,8 +36,6 @@ class Rectangle { GLint colour_uniform_; }; -} -} } #endif /* Rectangle_hpp */ diff --git a/Outputs/OpenGL/Primitives/Shader.hpp b/Outputs/OpenGL/Primitives/Shader.hpp index 221aedc5f..d41f70eb2 100644 --- a/Outputs/OpenGL/Primitives/Shader.hpp +++ b/Outputs/OpenGL/Primitives/Shader.hpp @@ -16,9 +16,7 @@ #include #include -namespace Outputs { -namespace Display { -namespace OpenGL { +namespace Outputs::Display::OpenGL { /*! A @c Shader compiles and holds a shader object, based on a single @@ -130,8 +128,6 @@ protected: void enqueue_function(std::function function); }; -} -} } #endif /* Shader_hpp */ diff --git a/Outputs/OpenGL/Primitives/TextureTarget.hpp b/Outputs/OpenGL/Primitives/TextureTarget.hpp index 39e4174bc..3a1e203b4 100644 --- a/Outputs/OpenGL/Primitives/TextureTarget.hpp +++ b/Outputs/OpenGL/Primitives/TextureTarget.hpp @@ -13,9 +13,7 @@ #include "Shader.hpp" #include -namespace Outputs { -namespace Display { -namespace OpenGL { +namespace Outputs::Display::OpenGL { /*! A @c TextureTarget is a framebuffer that can be bound as a texture. So this class @@ -88,8 +86,6 @@ class TextureTarget { mutable GLint threshold_uniform_; }; -} -} } #endif /* TextureTarget_hpp */ diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index fb7a75db5..2feac17a6 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -28,9 +28,7 @@ #include #include -namespace Outputs { -namespace Display { -namespace OpenGL { +namespace Outputs::Display::OpenGL { /*! @@ -156,8 +154,6 @@ class ScanTarget: public Outputs::Display::BufferingScanTarget { // TODO: use pr std::array line_metadata_buffer_; }; -} -} } #endif /* ScanTarget_hpp */ diff --git a/Outputs/OpenGL/Screenshot.hpp b/Outputs/OpenGL/Screenshot.hpp index 88468d392..7b70189ac 100644 --- a/Outputs/OpenGL/Screenshot.hpp +++ b/Outputs/OpenGL/Screenshot.hpp @@ -11,9 +11,7 @@ #include "OpenGL.hpp" -namespace Outputs { -namespace Display { -namespace OpenGL { +namespace Outputs::Display::OpenGL { /*! Upon construction, Screenshot will capture the centre portion of the currently-bound framebuffer, @@ -54,8 +52,6 @@ struct Screenshot { int width, height; }; -} -} } #endif /* Screenshot_h */ diff --git a/Outputs/ScanTarget.hpp b/Outputs/ScanTarget.hpp index 0a32ac346..6b01fe3cc 100644 --- a/Outputs/ScanTarget.hpp +++ b/Outputs/ScanTarget.hpp @@ -14,8 +14,7 @@ #include #include "../ClockReceiver/TimeTypes.hpp" -namespace Outputs { -namespace Display { +namespace Outputs::Display { enum class Type { PAL50, @@ -447,7 +446,6 @@ struct NullScanTarget: public ScanTarget { static NullScanTarget singleton; }; -} } #endif /* Outputs_Display_ScanTarget_h */ diff --git a/Outputs/ScanTargets/BufferingScanTarget.hpp b/Outputs/ScanTargets/BufferingScanTarget.hpp index 83d8a3013..1205aed23 100644 --- a/Outputs/ScanTargets/BufferingScanTarget.hpp +++ b/Outputs/ScanTargets/BufferingScanTarget.hpp @@ -18,8 +18,7 @@ #include #include -namespace Outputs { -namespace Display { +namespace Outputs::Display { /*! Provides basic thread-safe (hopefully) circular queues for any scan target that: @@ -273,8 +272,6 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget { #endif }; - -} } #endif /* BufferingScanTarget_hpp */ diff --git a/Outputs/Speaker/Implementation/CompoundSource.hpp b/Outputs/Speaker/Implementation/CompoundSource.hpp index a236d6aa1..ade6c4e54 100644 --- a/Outputs/Speaker/Implementation/CompoundSource.hpp +++ b/Outputs/Speaker/Implementation/CompoundSource.hpp @@ -15,8 +15,7 @@ #include #include -namespace Outputs { -namespace Speaker { +namespace Outputs::Speaker { /*! A CompoundSource adds together the sound generated by multiple individual SampleSources. @@ -174,7 +173,6 @@ template class CompoundSource: std::atomic average_output_peak_{1.0}; }; -} } #endif /* CompoundSource_h */ diff --git a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp index d94b84d31..2f1961b65 100644 --- a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp +++ b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp @@ -20,8 +20,7 @@ #include #include -namespace Outputs { -namespace Speaker { +namespace Outputs::Speaker { template class LowpassBase: public Speaker { public: @@ -410,7 +409,6 @@ template class PullLowpass: public LowpassBase #include -namespace Outputs { -namespace Speaker { +namespace Outputs::Speaker { /*! A sample source is something that can provide a stream of audio. @@ -71,7 +70,6 @@ class SampleSource { double get_average_output_peak() const { return 1.0; } }; -} } #endif /* SampleSource_hpp */ diff --git a/Outputs/Speaker/Speaker.hpp b/Outputs/Speaker/Speaker.hpp index 511b0e337..075dcd552 100644 --- a/Outputs/Speaker/Speaker.hpp +++ b/Outputs/Speaker/Speaker.hpp @@ -13,8 +13,7 @@ #include #include -namespace Outputs { -namespace Speaker { +namespace Outputs::Speaker { /*! Provides a communication point for sound; machines that have a speaker provide an @@ -145,7 +144,6 @@ class Speaker { std::vector mix_buffer_; }; -} } #endif /* Speaker_hpp */ diff --git a/Processors/6502/6502.hpp b/Processors/6502/6502.hpp index e177c495b..cc0d5b87d 100644 --- a/Processors/6502/6502.hpp +++ b/Processors/6502/6502.hpp @@ -18,8 +18,7 @@ #include "../../Numeric/RegisterSizes.hpp" #include "../../ClockReceiver/ClockReceiver.hpp" -namespace CPU { -namespace MOS6502 { +namespace CPU::MOS6502 { // Adopt a bunch of things from MOS6502Esque. using BusOperation = CPU::MOS6502Esque::BusOperation; @@ -162,7 +161,6 @@ template cl #include "Implementation/6502Implementation.hpp" -} } #endif /* MOS6502_cpp */ diff --git a/Processors/6502/AllRAM/6502AllRAM.hpp b/Processors/6502/AllRAM/6502AllRAM.hpp index 848d4e7de..94d8eda1f 100644 --- a/Processors/6502/AllRAM/6502AllRAM.hpp +++ b/Processors/6502/AllRAM/6502AllRAM.hpp @@ -12,8 +12,7 @@ #include "../../6502Esque/6502Selector.hpp" #include "../../AllRAMProcessor.hpp" -namespace CPU { -namespace MOS6502 { +namespace CPU::MOS6502 { class AllRAMProcessor: public ::CPU::AllRAMProcessor { @@ -35,7 +34,6 @@ class AllRAMProcessor: AllRAMProcessor(size_t memory_size) : ::CPU::AllRAMProcessor(memory_size) {} }; -} } #endif /* MOS6502AllRAM_cpp */ diff --git a/Processors/6502/State/State.hpp b/Processors/6502/State/State.hpp index adde3b761..9d9e7185f 100644 --- a/Processors/6502/State/State.hpp +++ b/Processors/6502/State/State.hpp @@ -13,8 +13,7 @@ #include "../../../Reflection/Struct.hpp" #include "../6502.hpp" -namespace CPU { -namespace MOS6502 { +namespace CPU::MOS6502 { /*! Provides a means for capturing or restoring complete 6502 state. @@ -89,8 +88,6 @@ struct State: public Reflection::StructImpl { void apply(ProcessorBase &target); }; - -} } #endif /* MOS6502_State_hpp */ diff --git a/Processors/6502Esque/6502Esque.hpp b/Processors/6502Esque/6502Esque.hpp index 89227804b..836c9747b 100644 --- a/Processors/6502Esque/6502Esque.hpp +++ b/Processors/6502Esque/6502Esque.hpp @@ -21,8 +21,7 @@ So: this is _very_ provisional stuff. */ -namespace CPU { -namespace MOS6502Esque { +namespace CPU::MOS6502Esque { /* The list of registers that can be accessed via @c set_value_of_register and @c set_value_of_register. @@ -143,7 +142,6 @@ template class BusHandler { } }; -} } #endif /* m6502Esque_h */ diff --git a/Processors/6502Esque/6502Selector.hpp b/Processors/6502Esque/6502Selector.hpp index 6dc1454d1..2b75d33d6 100644 --- a/Processors/6502Esque/6502Selector.hpp +++ b/Processors/6502Esque/6502Selector.hpp @@ -12,8 +12,7 @@ #include "../6502/6502.hpp" #include "../65816/65816.hpp" -namespace CPU { -namespace MOS6502Esque { +namespace CPU::MOS6502Esque { enum class Type { TNES6502, // the NES's 6502, which is like a 6502 but lacks decimal mode (though it retains the decimal flag) @@ -46,7 +45,6 @@ template class Processor class BusHandlerT: public BusHandler {}; template <> class BusHandlerT: public BusHandler {}; -} } #endif /* _502Selector_h */ diff --git a/Processors/6502Esque/Implementation/LazyFlags.hpp b/Processors/6502Esque/Implementation/LazyFlags.hpp index 2169d8c24..0466eb181 100644 --- a/Processors/6502Esque/Implementation/LazyFlags.hpp +++ b/Processors/6502Esque/Implementation/LazyFlags.hpp @@ -11,8 +11,7 @@ #include "../6502Esque.hpp" -namespace CPU { -namespace MOS6502Esque { +namespace CPU::MOS6502Esque { struct LazyFlags { /// Bit 7 is set if the negative flag is set; otherwise it is clear. @@ -76,8 +75,6 @@ struct LazyFlags { } }; - -} } #endif /* LazyFlags_h */ diff --git a/Processors/65816/65816.hpp b/Processors/65816/65816.hpp index d9390113e..20e680943 100644 --- a/Processors/65816/65816.hpp +++ b/Processors/65816/65816.hpp @@ -19,8 +19,7 @@ #include "../6502Esque/6502Esque.hpp" #include "../6502Esque/Implementation/LazyFlags.hpp" -namespace CPU { -namespace WDC65816 { +namespace CPU::WDC65816 { using BusOperation = CPU::MOS6502Esque::BusOperation; using Register = CPU::MOS6502Esque::Register; @@ -92,7 +91,6 @@ template class Processor: public Pro #include "Implementation/65816Implementation.hpp" -} } #endif /* WDC65816_hpp */ diff --git a/Processors/68000Mk2/68000Mk2.hpp b/Processors/68000Mk2/68000Mk2.hpp index be908db02..350f04446 100644 --- a/Processors/68000Mk2/68000Mk2.hpp +++ b/Processors/68000Mk2/68000Mk2.hpp @@ -13,8 +13,7 @@ #include "../../Numeric/RegisterSizes.hpp" #include "../../InstructionSets/M68k/RegisterSet.hpp" -namespace CPU { -namespace MC68000Mk2 { +namespace CPU::MC68000Mk2 { /*! A microcycle is an atomic unit of 68000 bus activity — it is a single item large enough @@ -358,13 +357,11 @@ struct State { InstructionSet::M68k::RegisterSet registers; }; -} } #include "Implementation/68000Mk2Storage.hpp" -namespace CPU { -namespace MC68000Mk2 { +namespace CPU::MC68000Mk2 { /*! Provides an emulation of the 68000 with accurate bus logic via the @c BusHandler, subject to the following template parameters: @@ -447,7 +444,6 @@ class Processor: private ProcessorBase { BusHandler &bus_handler_; }; -} } #include "Implementation/68000Mk2Implementation.hpp" diff --git a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp index df4358df0..425e038d2 100644 --- a/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp +++ b/Processors/68000Mk2/Implementation/68000Mk2Implementation.hpp @@ -14,8 +14,7 @@ #include "../../../InstructionSets/M68k/ExceptionVectors.hpp" -namespace CPU { -namespace MC68000Mk2 { +namespace CPU::MC68000Mk2 { #define AddressingDispatch(x) \ x, x##__end = x + InstructionSet::M68k::AddressingModeCount @@ -3104,7 +3103,6 @@ void Processor -namespace CPU { -namespace MC68000Mk2 { +namespace CPU::MC68000Mk2 { struct ProcessorBase: public InstructionSet::M68k::NullFlowController { ProcessorBase() { @@ -222,7 +221,6 @@ struct ProcessorBase: public InstructionSet::M68k::NullFlowController { Microcycle awaiting_dtack; }; -} } #endif /* _8000Mk2Storage_h */ diff --git a/Processors/Z80/AllRAM/Z80AllRAM.hpp b/Processors/Z80/AllRAM/Z80AllRAM.hpp index 85f4f04dc..713633e98 100644 --- a/Processors/Z80/AllRAM/Z80AllRAM.hpp +++ b/Processors/Z80/AllRAM/Z80AllRAM.hpp @@ -12,8 +12,7 @@ #include "../Z80.hpp" #include "../../AllRAMProcessor.hpp" -namespace CPU { -namespace Z80 { +namespace CPU::Z80 { class AllRAMProcessor: public ::CPU::AllRAMProcessor { @@ -52,7 +51,6 @@ class AllRAMProcessor: AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {} }; -} } #endif /* Z80AllRAM_hpp */ diff --git a/Processors/Z80/Z80.hpp b/Processors/Z80/Z80.hpp index 921c9d5dc..2d3585b7e 100644 --- a/Processors/Z80/Z80.hpp +++ b/Processors/Z80/Z80.hpp @@ -17,8 +17,7 @@ #include "../../ClockReceiver/ClockReceiver.hpp" #include "../../ClockReceiver/ForceInline.hpp" -namespace CPU { -namespace Z80 { +namespace CPU::Z80 { /* The list of registers that can be accessed via @c set_value_of_register and @c set_value_of_register. @@ -537,7 +536,6 @@ template class Processor: #include "Implementation/Z80Implementation.hpp" -} } #endif /* Z80_hpp */ diff --git a/Storage/Cartridge/Cartridge.hpp b/Storage/Cartridge/Cartridge.hpp index 0cb552811..89784665d 100644 --- a/Storage/Cartridge/Cartridge.hpp +++ b/Storage/Cartridge/Cartridge.hpp @@ -12,8 +12,7 @@ #include #include -namespace Storage { -namespace Cartridge { +namespace Storage::Cartridge { /*! Provides a base class for cartridges; the bus provided to cartridges and therefore @@ -81,7 +80,6 @@ class Cartridge { std::vector segments_; }; -} } #endif /* ROM_hpp */ diff --git a/Storage/Cartridge/Encodings/CommodoreROM.hpp b/Storage/Cartridge/Encodings/CommodoreROM.hpp index ee8f79759..21f0ccc14 100644 --- a/Storage/Cartridge/Encodings/CommodoreROM.hpp +++ b/Storage/Cartridge/Encodings/CommodoreROM.hpp @@ -12,16 +12,10 @@ #include #include -namespace Storage { -namespace Cartridge { -namespace Encodings { -namespace CommodoreROM { +namespace Storage::Cartridge::Encodings::CommodoreROM { bool isROM(const std::vector &); -} -} -} } #endif /* CommodoreROM_hpp */ diff --git a/Storage/Cartridge/Formats/BinaryDump.hpp b/Storage/Cartridge/Formats/BinaryDump.hpp index 2aba3cb25..c1c0281da 100644 --- a/Storage/Cartridge/Formats/BinaryDump.hpp +++ b/Storage/Cartridge/Formats/BinaryDump.hpp @@ -13,8 +13,7 @@ #include -namespace Storage { -namespace Cartridge { +namespace Storage::Cartridge { class BinaryDump : public Cartridge { public: @@ -25,7 +24,6 @@ class BinaryDump : public Cartridge { }; }; -} } #endif /* AcornROM_hpp */ diff --git a/Storage/Cartridge/Formats/PRG.hpp b/Storage/Cartridge/Formats/PRG.hpp index f26286efb..8ca179eb7 100644 --- a/Storage/Cartridge/Formats/PRG.hpp +++ b/Storage/Cartridge/Formats/PRG.hpp @@ -13,8 +13,7 @@ #include -namespace Storage { -namespace Cartridge { +namespace Storage::Cartridge { class PRG : public Cartridge { public: @@ -25,7 +24,6 @@ class PRG : public Cartridge { }; }; -} } #endif /* PRG_hpp */ diff --git a/Storage/Data/BitReverse.hpp b/Storage/Data/BitReverse.hpp index 2454352d0..eb88ba310 100644 --- a/Storage/Data/BitReverse.hpp +++ b/Storage/Data/BitReverse.hpp @@ -12,9 +12,7 @@ #include #include -namespace Storage { -namespace Data { -namespace BitReverse { +namespace Storage::Data::BitReverse { /*! Reverses the order of the bits in every byte of the vector: @@ -23,8 +21,8 @@ namespace BitReverse { */ void reverse(std::vector &vector); -} -} +// TODO: is this substantially different from Numeric/BitReverse.hpp? + } #endif /* BitReverse_hpp */ diff --git a/Storage/Data/Commodore.hpp b/Storage/Data/Commodore.hpp index 5fb10aa91..383fd2391 100644 --- a/Storage/Data/Commodore.hpp +++ b/Storage/Data/Commodore.hpp @@ -11,14 +11,10 @@ #include -namespace Storage { -namespace Data { -namespace Commodore { +namespace Storage::Data::Commodore { std::wstring petscii_from_bytes(const uint8_t *string, int length, bool shifted); -} -} } #endif /* Commodore_hpp */ diff --git a/Storage/Data/ZX8081.hpp b/Storage/Data/ZX8081.hpp index 85649041d..f1a88ce2a 100644 --- a/Storage/Data/ZX8081.hpp +++ b/Storage/Data/ZX8081.hpp @@ -14,9 +14,7 @@ #include #include -namespace Storage { -namespace Data { -namespace ZX8081 { +namespace Storage::Data::ZX8081 { struct File { std::vector data; @@ -29,9 +27,6 @@ std::shared_ptr FileFromData(const std::vector &data); std::wstring StringFromData(const std::vector &data, bool is_zx81); std::vector DataFromString(const std::wstring &string, bool is_zx81); - -} -} } #endif /* ZX8081_hpp */ diff --git a/Storage/Disk/Controller/DiskController.hpp b/Storage/Disk/Controller/DiskController.hpp index 57d574854..aad387a16 100644 --- a/Storage/Disk/Controller/DiskController.hpp +++ b/Storage/Disk/Controller/DiskController.hpp @@ -16,8 +16,7 @@ #include "../../../ClockReceiver/ClockReceiver.hpp" #include "../../../ClockReceiver/ClockingHintSource.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides the shell for emulating a disk controller: something that is connected to a disk drive and uses a @@ -163,7 +162,6 @@ class Controller: void digital_phase_locked_loop_output_bit(int value); }; -} } #endif /* DiskDrive_hpp */ diff --git a/Storage/Disk/Controller/MFMDiskController.hpp b/Storage/Disk/Controller/MFMDiskController.hpp index 34844b631..c802a5917 100644 --- a/Storage/Disk/Controller/MFMDiskController.hpp +++ b/Storage/Disk/Controller/MFMDiskController.hpp @@ -14,8 +14,7 @@ #include "../../../ClockReceiver/ClockReceiver.hpp" #include "../Encodings/MFM/Shifter.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Extends Controller with a built-in shift register and FM/MFM decoding logic, @@ -166,7 +165,6 @@ class MFMController: public Controller { CRC::CCITT crc_generator_; }; -} } #endif /* MFMDiskController_hpp */ diff --git a/Storage/Disk/Disk.hpp b/Storage/Disk/Disk.hpp index 46dac2db8..6677769ed 100644 --- a/Storage/Disk/Disk.hpp +++ b/Storage/Disk/Disk.hpp @@ -18,8 +18,7 @@ #include "Track/Track.hpp" #include "../../Concurrency/AsyncTaskQueue.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Models a flopy disk. @@ -69,7 +68,6 @@ class Disk { virtual bool tracks_differ(Track::Address, Track::Address) = 0; }; -} } #endif /* Disk_hpp */ diff --git a/Storage/Disk/DiskImage/DiskImage.hpp b/Storage/Disk/DiskImage/DiskImage.hpp index def1fbb41..17405f807 100644 --- a/Storage/Disk/DiskImage/DiskImage.hpp +++ b/Storage/Disk/DiskImage/DiskImage.hpp @@ -16,8 +16,7 @@ #include "../Track/Track.hpp" #include "../../TargetPlatforms.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { enum class Error { InvalidFormat = -2, @@ -119,7 +118,6 @@ template class DiskImageHolder: public DiskImageHolderBase, public #include "DiskImageImplementation.hpp" -} } #endif /* DiskImage_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/2MG.hpp b/Storage/Disk/DiskImage/Formats/2MG.hpp index 8b512e189..ca5c1973f 100644 --- a/Storage/Disk/DiskImage/Formats/2MG.hpp +++ b/Storage/Disk/DiskImage/Formats/2MG.hpp @@ -16,8 +16,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! 2MG is slightly special because it's just a container format; there's a brief header and then @@ -34,7 +33,6 @@ class Disk2MG { static DiskOrMassStorageDevice open(const std::string &file_name); }; -} } #endif /* _MG_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/AcornADF.hpp b/Storage/Disk/DiskImage/Formats/AcornADF.hpp index 1988579f1..ed4b529f4 100644 --- a/Storage/Disk/DiskImage/Formats/AcornADF.hpp +++ b/Storage/Disk/DiskImage/Formats/AcornADF.hpp @@ -13,8 +13,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing an ADF disk image: a decoded sector dump of an Acorn ADFS disk. @@ -37,7 +36,6 @@ class AcornADF: public MFMSectorDump { int head_count_ = 1; }; -} } #endif /* AcornADF_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/AmigaADF.hpp b/Storage/Disk/DiskImage/Formats/AmigaADF.hpp index 79a9ec6b3..53ae21b4a 100644 --- a/Storage/Disk/DiskImage/Formats/AmigaADF.hpp +++ b/Storage/Disk/DiskImage/Formats/AmigaADF.hpp @@ -13,8 +13,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing an Amiga ADF, which is an MFM sector contents dump, @@ -41,7 +40,6 @@ class AmigaADF: public DiskImage { }; -} } #endif /* AmigaADF_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/AppleDSK.hpp b/Storage/Disk/DiskImage/Formats/AppleDSK.hpp index 5a4f73062..59f3aeb41 100644 --- a/Storage/Disk/DiskImage/Formats/AppleDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/AppleDSK.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing an Apple DSK disk image: a representation of sector contents, @@ -47,7 +46,5 @@ class AppleDSK: public DiskImage { }; } -} - #endif /* AppleDSK_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/CPCDSK.hpp b/Storage/Disk/DiskImage/Formats/CPCDSK.hpp index 15129dd86..566cb2300 100644 --- a/Storage/Disk/DiskImage/Formats/CPCDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/CPCDSK.hpp @@ -16,8 +16,7 @@ #include #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing an Amstrad CPC-type disk image: some arrangement of sectors with status bits. @@ -72,7 +71,5 @@ class CPCDSK: public DiskImage { }; } -} - #endif /* CPCDSK_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/D64.hpp b/Storage/Disk/DiskImage/Formats/D64.hpp index 25a4718f2..a3624709e 100644 --- a/Storage/Disk/DiskImage/Formats/D64.hpp +++ b/Storage/Disk/DiskImage/Formats/D64.hpp @@ -12,8 +12,7 @@ #include "../DiskImage.hpp" #include "../../../FileHolder.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing a D64 disk image: a decoded sector dump of a C1540-format disk. @@ -39,7 +38,6 @@ class D64: public DiskImage { uint16_t disk_id_; }; -} } #endif /* D64_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/DMK.hpp b/Storage/Disk/DiskImage/Formats/DMK.hpp index c1962e03c..e836148c9 100644 --- a/Storage/Disk/DiskImage/Formats/DMK.hpp +++ b/Storage/Disk/DiskImage/Formats/DMK.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing a DMK disk image: mostly a decoded byte stream, but with @@ -49,7 +48,6 @@ class DMK: public DiskImage { bool is_purely_single_density_; }; -} } #endif /* DMK_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/FAT12.hpp b/Storage/Disk/DiskImage/Formats/FAT12.hpp index 044612466..b3a91ffa0 100644 --- a/Storage/Disk/DiskImage/Formats/FAT12.hpp +++ b/Storage/Disk/DiskImage/Formats/FAT12.hpp @@ -13,8 +13,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage holding an MSDOS-style FAT12 disk image: @@ -35,7 +34,6 @@ class FAT12: public MFMSectorDump { int sector_size_; }; -} } #endif /* MSXDSK_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/G64.hpp b/Storage/Disk/DiskImage/Formats/G64.hpp index b1d6ea978..e62a9c4ec 100644 --- a/Storage/Disk/DiskImage/Formats/G64.hpp +++ b/Storage/Disk/DiskImage/Formats/G64.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing a G64 disk image: a raw but perfectly-clocked GCR stream. @@ -42,7 +41,6 @@ class G64: public DiskImage { uint16_t maximum_track_size_; }; -} } #endif /* G64_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/HFE.hpp b/Storage/Disk/DiskImage/Formats/HFE.hpp index 7fcbc25e7..ee0b503d9 100644 --- a/Storage/Disk/DiskImage/Formats/HFE.hpp +++ b/Storage/Disk/DiskImage/Formats/HFE.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing an HFE: a bit stream representation of a floppy. @@ -48,7 +47,5 @@ class HFE: public DiskImage { }; } -} - #endif /* HFE_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/IPF.hpp b/Storage/Disk/DiskImage/Formats/IPF.hpp index fa29aafa8..9aa06689b 100644 --- a/Storage/Disk/DiskImage/Formats/IPF.hpp +++ b/Storage/Disk/DiskImage/Formats/IPF.hpp @@ -17,8 +17,7 @@ #include #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing an IPF, which is a mixed stream of raw flux windows and @@ -85,7 +84,6 @@ class IPF: public DiskImage, public TargetPlatform::TypeDistinguisher { void add_raw_data(std::vector &, Time bit_length, size_t num_bits); }; -} } #endif /* IPF_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp b/Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp index c8914614f..0c8982da1 100644 --- a/Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp +++ b/Storage/Disk/DiskImage/Formats/MFMSectorDump.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides the base for writeable [M]FM disk images that just contain contiguous sector content dumps. @@ -41,7 +40,6 @@ class MFMSectorDump: public DiskImage { uint8_t first_sector_ = 0; }; -} } #endif /* SectorDump_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/MSA.hpp b/Storage/Disk/DiskImage/Formats/MSA.hpp index eb28fc9fb..e78b912f7 100644 --- a/Storage/Disk/DiskImage/Formats/MSA.hpp +++ b/Storage/Disk/DiskImage/Formats/MSA.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage describing an Atari ST MSA disk image: @@ -41,8 +40,6 @@ class MSA final: public DiskImage { std::vector> uncompressed_tracks_; }; - -} } #endif /* MSA_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp b/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp index dc95f89bc..54c71e8f7 100644 --- a/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp +++ b/Storage/Disk/DiskImage/Formats/MacintoshIMG.hpp @@ -12,8 +12,7 @@ #include "../DiskImage.hpp" #include "../../../FileHolder.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing either: @@ -73,7 +72,6 @@ class MacintoshIMG: public DiskImage { long raw_offset_ = 0; }; -} } #endif /* DiskCopy42_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/NIB.hpp b/Storage/Disk/DiskImage/Formats/NIB.hpp index 8f4f71d9c..960729519 100644 --- a/Storage/Disk/DiskImage/Formats/NIB.hpp +++ b/Storage/Disk/DiskImage/Formats/NIB.hpp @@ -12,8 +12,7 @@ #include "../DiskImage.hpp" #include "../../../FileHolder.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage describing an Apple NIB disk image: @@ -36,7 +35,6 @@ class NIB: public DiskImage { long file_offset(Track::Address address); }; -} } #endif /* NIB_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp b/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp index 7bbd1f01d..75ab277c0 100644 --- a/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp +++ b/Storage/Disk/DiskImage/Formats/OricMFMDSK.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing an Oric MFM-stype disk image: a stream of the MFM data bits with clocks omitted. @@ -46,7 +45,6 @@ class OricMFMDSK: public DiskImage { uint32_t geometry_type_; }; -} } #endif /* OricMFMDSK_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/SSD.hpp b/Storage/Disk/DiskImage/Formats/SSD.hpp index d3df2abc8..6158227cf 100644 --- a/Storage/Disk/DiskImage/Formats/SSD.hpp +++ b/Storage/Disk/DiskImage/Formats/SSD.hpp @@ -11,8 +11,7 @@ #include "MFMSectorDump.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing a DSD or SSD disk image: a decoded sector dump of an Acorn DFS disk. @@ -37,7 +36,6 @@ class SSD: public MFMSectorDump { int track_count_; }; -} } #endif /* SSD_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/STX.hpp b/Storage/Disk/DiskImage/Formats/STX.hpp index c7aba86d8..15e3bbc11 100644 --- a/Storage/Disk/DiskImage/Formats/STX.hpp +++ b/Storage/Disk/DiskImage/Formats/STX.hpp @@ -12,8 +12,7 @@ #include "../DiskImage.hpp" #include "../../../FileHolder.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c Disk containing an STX disk image: sector contents plus a bunch of annotations as to sizing, @@ -44,7 +43,6 @@ class STX: public DiskImage { long offset_by_track_[256]; }; -} } #endif /* STX_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/Utility/ImplicitSectors.hpp b/Storage/Disk/DiskImage/Formats/Utility/ImplicitSectors.hpp index 8db583ee6..3714837d8 100644 --- a/Storage/Disk/DiskImage/Formats/Utility/ImplicitSectors.hpp +++ b/Storage/Disk/DiskImage/Formats/Utility/ImplicitSectors.hpp @@ -13,13 +13,11 @@ #include #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { std::shared_ptr track_for_sectors(const uint8_t *source, int number_of_sectors, uint8_t track, uint8_t side, uint8_t first_sector, uint8_t size, bool is_double_density); void decode_sectors(Track &track, uint8_t *destination, uint8_t first_sector, uint8_t last_sector, uint8_t sector_size, bool is_double_density); -} } #endif /* ImplicitSectors_hpp */ diff --git a/Storage/Disk/DiskImage/Formats/WOZ.hpp b/Storage/Disk/DiskImage/Formats/WOZ.hpp index cf2d2e5a6..ce091bc21 100644 --- a/Storage/Disk/DiskImage/Formats/WOZ.hpp +++ b/Storage/Disk/DiskImage/Formats/WOZ.hpp @@ -15,8 +15,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Provides a @c DiskImage containing a WOZ: a bit stream representation of a floppy. @@ -56,7 +55,6 @@ class WOZ: public DiskImage { constexpr static long NoSuchTrack = 0; // This is an offset a track definitely can't lie at. }; -} } #endif /* WOZ_hpp */ diff --git a/Storage/Disk/Drive.hpp b/Storage/Disk/Drive.hpp index accf4e4e0..660544f69 100644 --- a/Storage/Disk/Drive.hpp +++ b/Storage/Disk/Drive.hpp @@ -19,8 +19,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { class Drive: public ClockingHint::Source, public TimedEventLoop { public: @@ -296,8 +295,6 @@ class Drive: public ClockingHint::Source, public TimedEventLoop { float random_interval_; }; - -} } #endif /* Drive_hpp */ diff --git a/Storage/Disk/Encodings/AppleGCR/Encoder.hpp b/Storage/Disk/Encodings/AppleGCR/Encoder.hpp index 1dffc0bb0..2f775967d 100644 --- a/Storage/Disk/Encodings/AppleGCR/Encoder.hpp +++ b/Storage/Disk/Encodings/AppleGCR/Encoder.hpp @@ -12,9 +12,7 @@ #include #include "../../../Disk/Track/PCMSegment.hpp" -namespace Storage { -namespace Encodings { -namespace AppleGCR { +namespace Storage::Encodings::AppleGCR { /// Describes the standard three-byte prologue that begins a header on both the Macintosh and the Apple II from DOS 3.3. constexpr uint8_t header_prologue[3] = {0xd5, 0xaa, 0x96}; @@ -93,8 +91,6 @@ Storage::Disk::PCMSegment five_and_three_data(const uint8_t *source); */ Storage::Disk::PCMSegment five_and_three_sync(int length); -} -} } #endif /* AppleGCR_hpp */ diff --git a/Storage/Disk/Encodings/AppleGCR/Sector.hpp b/Storage/Disk/Encodings/AppleGCR/Sector.hpp index 315ee7459..b096782b9 100644 --- a/Storage/Disk/Encodings/AppleGCR/Sector.hpp +++ b/Storage/Disk/Encodings/AppleGCR/Sector.hpp @@ -12,9 +12,7 @@ #include #include -namespace Storage { -namespace Encodings { -namespace AppleGCR { +namespace Storage::Encodings::AppleGCR { struct Sector { /*! @@ -76,8 +74,6 @@ struct Sector { encoding(rhs.encoding) {} }; -} -} } #endif /* Sector_h */ diff --git a/Storage/Disk/Encodings/AppleGCR/SegmentParser.hpp b/Storage/Disk/Encodings/AppleGCR/SegmentParser.hpp index ca6e12291..4c4d0c06f 100644 --- a/Storage/Disk/Encodings/AppleGCR/SegmentParser.hpp +++ b/Storage/Disk/Encodings/AppleGCR/SegmentParser.hpp @@ -13,9 +13,7 @@ #include "../../Track/PCMSegment.hpp" #include -namespace Storage { -namespace Encodings { -namespace AppleGCR { +namespace Storage::Encodings::AppleGCR { /*! Scans @c segment for all included sectors, returning a set that maps from location within @@ -23,8 +21,6 @@ namespace AppleGCR { */ std::map sectors_from_segment(const Disk::PCMSegment &segment); -} -} } #endif /* TrackParser_hpp */ diff --git a/Storage/Disk/Encodings/CommodoreGCR.hpp b/Storage/Disk/Encodings/CommodoreGCR.hpp index ed6420c83..7d1acc201 100644 --- a/Storage/Disk/Encodings/CommodoreGCR.hpp +++ b/Storage/Disk/Encodings/CommodoreGCR.hpp @@ -12,8 +12,7 @@ #include "../../Storage.hpp" #include -namespace Storage { -namespace Encodings { +namespace Storage::Encodings { namespace CommodoreGCR { /*! @@ -48,7 +47,6 @@ namespace CommodoreGCR { unsigned int decoding_from_dectet(unsigned int dectet); } -} } #endif /* CommodoreGCR_hpp */ diff --git a/Storage/Disk/Encodings/MFM/Constants.hpp b/Storage/Disk/Encodings/MFM/Constants.hpp index 5db0f0bd2..011af4dc9 100644 --- a/Storage/Disk/Encodings/MFM/Constants.hpp +++ b/Storage/Disk/Encodings/MFM/Constants.hpp @@ -11,9 +11,7 @@ #include "../../../Storage.hpp" -namespace Storage { -namespace Encodings { -namespace MFM { +namespace Storage::Encodings::MFM { const uint8_t IndexAddressByte = 0xfc; const uint8_t IDAddressByte = 0xfe; @@ -35,8 +33,6 @@ const uint8_t MFMSyncByteValue = 0xa1; const Time MFMBitLength = Time(1, 100000); const Time FMBitLength = Time(1, 50000); -} -} } #endif /* Constants_h */ diff --git a/Storage/Disk/Encodings/MFM/Encoder.hpp b/Storage/Disk/Encodings/MFM/Encoder.hpp index 71a48661b..babec8b35 100644 --- a/Storage/Disk/Encodings/MFM/Encoder.hpp +++ b/Storage/Disk/Encodings/MFM/Encoder.hpp @@ -17,9 +17,7 @@ #include "../../Track/Track.hpp" #include "../../../../Numeric/CRC.hpp" -namespace Storage { -namespace Encodings { -namespace MFM { +namespace Storage::Encodings::MFM { extern const std::size_t DefaultSectorGapLength; /*! @@ -80,8 +78,6 @@ class Encoder { std::unique_ptr GetMFMEncoder(std::vector &target, std::vector *fuzzy_target = nullptr); std::unique_ptr GetFMEncoder(std::vector &target, std::vector *fuzzy_target = nullptr); -} -} } #endif /* MFM_hpp */ diff --git a/Storage/Disk/Encodings/MFM/Parser.hpp b/Storage/Disk/Encodings/MFM/Parser.hpp index 7e7a1e74f..cdf0dd034 100644 --- a/Storage/Disk/Encodings/MFM/Parser.hpp +++ b/Storage/Disk/Encodings/MFM/Parser.hpp @@ -13,9 +13,7 @@ #include "../../Track/Track.hpp" #include "../../Drive.hpp" -namespace Storage { -namespace Encodings { -namespace MFM { +namespace Storage::Encodings::MFM { /*! Provides a mechanism for collecting sectors from a disk. @@ -40,8 +38,6 @@ class Parser { std::map> sectors_by_address_by_track_; }; -} -} } #endif /* Parser_hpp */ diff --git a/Storage/Disk/Encodings/MFM/Sector.hpp b/Storage/Disk/Encodings/MFM/Sector.hpp index 2818b5b1e..ae4da862e 100644 --- a/Storage/Disk/Encodings/MFM/Sector.hpp +++ b/Storage/Disk/Encodings/MFM/Sector.hpp @@ -12,9 +12,7 @@ #include #include -namespace Storage { -namespace Encodings { -namespace MFM { +namespace Storage::Encodings::MFM { /*! Represents a single [M]FM sector, identified by its track, side and sector records, a blob of data @@ -54,8 +52,6 @@ struct Sector { is_deleted(rhs.is_deleted ){} }; -} -} } #endif /* Sector_h */ diff --git a/Storage/Disk/Encodings/MFM/SegmentParser.hpp b/Storage/Disk/Encodings/MFM/SegmentParser.hpp index 0bf428eab..d5b37f181 100644 --- a/Storage/Disk/Encodings/MFM/SegmentParser.hpp +++ b/Storage/Disk/Encodings/MFM/SegmentParser.hpp @@ -13,9 +13,7 @@ #include "../../Track/PCMSegment.hpp" #include -namespace Storage { -namespace Encodings { -namespace MFM { +namespace Storage::Encodings::MFM { /*! Scans @c segment for all included sectors, returning a set that maps from location within @@ -24,8 +22,6 @@ namespace MFM { */ std::map sectors_from_segment(const Disk::PCMSegment &&segment, bool is_double_density); -} -} } #endif /* SegmentParser_hpp */ diff --git a/Storage/Disk/Encodings/MFM/Shifter.hpp b/Storage/Disk/Encodings/MFM/Shifter.hpp index f55b8d417..a53689652 100644 --- a/Storage/Disk/Encodings/MFM/Shifter.hpp +++ b/Storage/Disk/Encodings/MFM/Shifter.hpp @@ -13,9 +13,7 @@ #include #include "../../../../Numeric/CRC.hpp" -namespace Storage { -namespace Encodings { -namespace MFM { +namespace Storage::Encodings::MFM { /*! The MFM shifter parses a stream of bits as input in order to produce @@ -80,8 +78,6 @@ class Shifter { CRC::CCITT *crc_generator_; }; -} -} } #endif /* Shifter_hpp */ diff --git a/Storage/Disk/Parsers/CPM.hpp b/Storage/Disk/Parsers/CPM.hpp index d7140c738..a34fea46f 100644 --- a/Storage/Disk/Parsers/CPM.hpp +++ b/Storage/Disk/Parsers/CPM.hpp @@ -16,9 +16,7 @@ #include #include -namespace Storage { -namespace Disk { -namespace CPM { +namespace Storage::Disk::CPM { struct ParameterBlock { int sectors_per_track; @@ -44,8 +42,6 @@ struct Catalogue { std::unique_ptr GetCatalogue(const std::shared_ptr &disk, const ParameterBlock ¶meters); -} -} } #endif /* Storage_Disk_Parsers_CPM_hpp */ diff --git a/Storage/Disk/Parsers/FAT.hpp b/Storage/Disk/Parsers/FAT.hpp index 3ede18518..f9d1d4866 100644 --- a/Storage/Disk/Parsers/FAT.hpp +++ b/Storage/Disk/Parsers/FAT.hpp @@ -16,9 +16,7 @@ #include #include -namespace Storage { -namespace Disk { -namespace FAT { +namespace Storage::Disk::FAT { struct File { std::string name; @@ -72,8 +70,6 @@ std::optional GetVolume(const std::shared_ptr &disk std::optional> GetFile(const std::shared_ptr &disk, const Volume &volume, const File &file); std::optional GetDirectory(const std::shared_ptr &disk, const Volume &volume, const File &file); -} -} } #endif /* FAT_hpp */ diff --git a/Storage/Disk/Track/PCMSegment.hpp b/Storage/Disk/Track/PCMSegment.hpp index 38389eb96..a53f72a79 100644 --- a/Storage/Disk/Track/PCMSegment.hpp +++ b/Storage/Disk/Track/PCMSegment.hpp @@ -17,8 +17,7 @@ #include "../../../Numeric/LFSR.hpp" #include "Track.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! A segment of PCM-sampled data. @@ -203,7 +202,6 @@ class PCMSegmentEventSource { Numeric::LFSR lfsr_; }; -} } #endif /* PCMSegment_hpp */ diff --git a/Storage/Disk/Track/PCMTrack.hpp b/Storage/Disk/Track/PCMTrack.hpp index 888dc1688..0fc26f0e2 100644 --- a/Storage/Disk/Track/PCMTrack.hpp +++ b/Storage/Disk/Track/PCMTrack.hpp @@ -15,8 +15,7 @@ #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! A subclass of @c Track that provides its @c Events by querying a pulse-code modulated record of original @@ -89,7 +88,6 @@ class PCMTrack: public Track { bool is_resampled_clone_ = false; }; -} } #endif /* PCMTrack_hpp */ diff --git a/Storage/Disk/Track/Track.hpp b/Storage/Disk/Track/Track.hpp index bb4ae83e1..c482a74c6 100644 --- a/Storage/Disk/Track/Track.hpp +++ b/Storage/Disk/Track/Track.hpp @@ -12,8 +12,7 @@ #include "../../Storage.hpp" #include -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Contains a head position, with some degree of sub-integral precision. @@ -126,7 +125,6 @@ class Track { virtual Track *clone() const = 0; }; -} } #endif /* Track_h */ diff --git a/Storage/Disk/Track/TrackSerialiser.hpp b/Storage/Disk/Track/TrackSerialiser.hpp index 85b025cfb..668a3498d 100644 --- a/Storage/Disk/Track/TrackSerialiser.hpp +++ b/Storage/Disk/Track/TrackSerialiser.hpp @@ -13,8 +13,7 @@ #include "PCMSegment.hpp" #include "Track.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! Instantiates a PLL with a target bit length of @c length_of_a_bit and provides a complete @@ -32,7 +31,6 @@ namespace Disk { */ PCMSegment track_serialisation(const Track &track, Time length_of_a_bit); -} } #endif /* TrackSerialiser_h */ diff --git a/Storage/Disk/Track/UnformattedTrack.hpp b/Storage/Disk/Track/UnformattedTrack.hpp index 91d84fa74..613f3fba9 100644 --- a/Storage/Disk/Track/UnformattedTrack.hpp +++ b/Storage/Disk/Track/UnformattedTrack.hpp @@ -11,8 +11,7 @@ #include "Track.hpp" -namespace Storage { -namespace Disk { +namespace Storage::Disk { /*! A subclass of @c Track with no contents. Just an index hole. @@ -24,7 +23,6 @@ class UnformattedTrack: public Track { Track *clone() const final; }; -} } #endif /* UnformattedTrack_hpp */ diff --git a/Storage/MassStorage/Encodings/AppleIIVolume.hpp b/Storage/MassStorage/Encodings/AppleIIVolume.hpp index 10d921d03..ea82734c9 100644 --- a/Storage/MassStorage/Encodings/AppleIIVolume.hpp +++ b/Storage/MassStorage/Encodings/AppleIIVolume.hpp @@ -11,10 +11,7 @@ #include "ApplePartitionMap.hpp" -namespace Storage { -namespace MassStorage { -namespace Encodings { -namespace AppleII { +namespace Storage::MassStorage::Encodings::AppleII { struct VolumeProvider { static constexpr bool HasDriver = false; @@ -30,9 +27,6 @@ struct VolumeProvider { using Mapper = Storage::MassStorage::Encodings::Apple::PartitionMap; -} -} -} } #endif /* AppleIIVolume_h */ diff --git a/Storage/MassStorage/Encodings/ApplePartitionMap.hpp b/Storage/MassStorage/Encodings/ApplePartitionMap.hpp index 846ddba28..a8acb2a33 100644 --- a/Storage/MassStorage/Encodings/ApplePartitionMap.hpp +++ b/Storage/MassStorage/Encodings/ApplePartitionMap.hpp @@ -15,10 +15,7 @@ #include #include -namespace Storage { -namespace MassStorage { -namespace Encodings { -namespace Apple { +namespace Storage::MassStorage::Encodings::Apple { enum class DriveType { SCSI @@ -249,9 +246,6 @@ template class PartitionMap { } }; -} -} -} } #endif /* ApplePartitionMap_hpp */ diff --git a/Storage/MassStorage/Encodings/MacintoshVolume.hpp b/Storage/MassStorage/Encodings/MacintoshVolume.hpp index 930c03c84..15bc77477 100644 --- a/Storage/MassStorage/Encodings/MacintoshVolume.hpp +++ b/Storage/MassStorage/Encodings/MacintoshVolume.hpp @@ -15,10 +15,7 @@ #include "ApplePartitionMap.hpp" -namespace Storage { -namespace MassStorage { -namespace Encodings { -namespace Macintosh { +namespace Storage::MassStorage::Encodings::Macintosh { using DriveType = Storage::MassStorage::Encodings::Apple::DriveType; @@ -56,9 +53,6 @@ struct VolumeProvider { */ using Mapper = Storage::MassStorage::Encodings::Apple::PartitionMap; -} -} -} } #endif /* MacintoshVolume_hpp */ diff --git a/Storage/MassStorage/Formats/DAT.hpp b/Storage/MassStorage/Formats/DAT.hpp index a47a537c5..d5dfeb31d 100644 --- a/Storage/MassStorage/Formats/DAT.hpp +++ b/Storage/MassStorage/Formats/DAT.hpp @@ -11,8 +11,7 @@ #include "RawSectorDump.hpp" -namespace Storage { -namespace MassStorage { +namespace Storage::MassStorage { /*! Provides a @c MassStorageDevice containing an Acorn ADFS image, which is just a @@ -24,7 +23,6 @@ class DAT: public RawSectorDump<256> { DAT(const std::string &file_name); }; -} } #endif /* MassStorage_DAT_hpp */ diff --git a/Storage/MassStorage/Formats/DSK.hpp b/Storage/MassStorage/Formats/DSK.hpp index bdf1b53cc..507501e87 100644 --- a/Storage/MassStorage/Formats/DSK.hpp +++ b/Storage/MassStorage/Formats/DSK.hpp @@ -11,8 +11,7 @@ #include "RawSectorDump.hpp" -namespace Storage { -namespace MassStorage { +namespace Storage::MassStorage { /*! Provides a @c MassStorageDevice containing a Macintosh DSK image, which is just a @@ -24,7 +23,6 @@ class DSK: public RawSectorDump<512> { DSK(const std::string &file_name); }; -} } #endif /* MassStorage_DSK_hpp */ diff --git a/Storage/MassStorage/Formats/HDV.hpp b/Storage/MassStorage/Formats/HDV.hpp index b891ddfc3..8b9b059b1 100644 --- a/Storage/MassStorage/Formats/HDV.hpp +++ b/Storage/MassStorage/Formats/HDV.hpp @@ -16,8 +16,7 @@ #include #include -namespace Storage { -namespace MassStorage { +namespace Storage::MassStorage { /*! Provides a @c MassStorageDevice containing an HDV image, which is a sector dump of @@ -50,7 +49,6 @@ class HDV: public MassStorageDevice { void set_block(size_t address, const std::vector &) final; }; -} } #endif /* HDV_hpp */ diff --git a/Storage/MassStorage/Formats/HFV.hpp b/Storage/MassStorage/Formats/HFV.hpp index ed1db3179..377385ad8 100644 --- a/Storage/MassStorage/Formats/HFV.hpp +++ b/Storage/MassStorage/Formats/HFV.hpp @@ -16,8 +16,7 @@ #include #include -namespace Storage { -namespace MassStorage { +namespace Storage::MassStorage { /*! Provides a @c MassStorageDevice containing an HFV image, which is a sector dump of @@ -48,7 +47,6 @@ class HFV: public MassStorageDevice, public Encodings::Macintosh::Volume { std::map> writes_; }; -} } #endif /* HFV_hpp */ diff --git a/Storage/MassStorage/Formats/RawSectorDump.hpp b/Storage/MassStorage/Formats/RawSectorDump.hpp index cb7fc19d6..107a9fa8a 100644 --- a/Storage/MassStorage/Formats/RawSectorDump.hpp +++ b/Storage/MassStorage/Formats/RawSectorDump.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace MassStorage { +namespace Storage::MassStorage { template class RawSectorDump: public MassStorageDevice { public: @@ -53,7 +52,6 @@ template class RawSectorDump: public MassStorageDevice { const long file_size_, file_start_; }; -} } #endif /* RawSectorDump_h */ diff --git a/Storage/MassStorage/MassStorageDevice.hpp b/Storage/MassStorage/MassStorageDevice.hpp index 61e48859c..c0d7c1758 100644 --- a/Storage/MassStorage/MassStorageDevice.hpp +++ b/Storage/MassStorage/MassStorageDevice.hpp @@ -13,8 +13,7 @@ #include #include -namespace Storage { -namespace MassStorage { +namespace Storage::MassStorage { /*! A mass storage device is usually: @@ -55,7 +54,6 @@ class MassStorageDevice { virtual void set_block([[maybe_unused]] size_t address, const std::vector &) {} }; -} } #endif /* MassStorageDevice_hpp */ diff --git a/Storage/MassStorage/SCSI/Target.hpp b/Storage/MassStorage/SCSI/Target.hpp index 4f34fa65f..7ca91d680 100644 --- a/Storage/MassStorage/SCSI/Target.hpp +++ b/Storage/MassStorage/SCSI/Target.hpp @@ -16,8 +16,7 @@ #include #include -namespace SCSI { -namespace Target { +namespace SCSI::Target { /*! Encapsulates the arguments supplied for a target SCSI command during @@ -396,7 +395,6 @@ template class Target: public Bus::Observer, public Responde #include "TargetImplementation.hpp" -} } #endif /* SCSI_Target_hpp */ diff --git a/Storage/State/SNA.hpp b/Storage/State/SNA.hpp index 2f2811d93..d312e8701 100644 --- a/Storage/State/SNA.hpp +++ b/Storage/State/SNA.hpp @@ -11,14 +11,12 @@ #include "../../Analyser/Static/StaticAnalyser.hpp" -namespace Storage { -namespace State { +namespace Storage::State { struct SNA { static std::unique_ptr load(const std::string &file_name); }; -} } #endif /* Storage_State_SNA_hpp */ diff --git a/Storage/State/SZX.hpp b/Storage/State/SZX.hpp index 56d8b0146..a7b813f7e 100644 --- a/Storage/State/SZX.hpp +++ b/Storage/State/SZX.hpp @@ -11,14 +11,12 @@ #include "../../Analyser/Static/StaticAnalyser.hpp" -namespace Storage { -namespace State { +namespace Storage::State { struct SZX { static std::unique_ptr load(const std::string &file_name); }; -} } #endif /* Storage_State_SZX_hpp */ diff --git a/Storage/State/Z80.hpp b/Storage/State/Z80.hpp index ef5a9af1e..f37000669 100644 --- a/Storage/State/Z80.hpp +++ b/Storage/State/Z80.hpp @@ -11,14 +11,12 @@ #include "../../Analyser/Static/StaticAnalyser.hpp" -namespace Storage { -namespace State { +namespace Storage::State { struct Z80 { static std::unique_ptr load(const std::string &file_name); }; -} } #endif /* Storage_State_Z80_hpp */ diff --git a/Storage/Tape/Formats/CAS.hpp b/Storage/Tape/Formats/CAS.hpp index e47ad3ab9..d9c0c9106 100644 --- a/Storage/Tape/Formats/CAS.hpp +++ b/Storage/Tape/Formats/CAS.hpp @@ -16,8 +16,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a CAS tape image, which is an MSX byte stream. @@ -67,7 +66,6 @@ class CAS: public Tape { std::size_t distance_into_bit_ = 0; }; -} } #endif /* CAS_hpp */ diff --git a/Storage/Tape/Formats/CSW.hpp b/Storage/Tape/Formats/CSW.hpp index 3c9d38369..aaa0d88d8 100644 --- a/Storage/Tape/Formats/CSW.hpp +++ b/Storage/Tape/Formats/CSW.hpp @@ -15,8 +15,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a CSW tape image, which is a compressed 1-bit sampling. @@ -62,7 +61,6 @@ class CSW: public Tape { std::size_t source_data_pointer_; }; -} } #endif /* CSW_hpp */ diff --git a/Storage/Tape/Formats/CommodoreTAP.hpp b/Storage/Tape/Formats/CommodoreTAP.hpp index 0d884eb08..8ed9ab6c8 100644 --- a/Storage/Tape/Formats/CommodoreTAP.hpp +++ b/Storage/Tape/Formats/CommodoreTAP.hpp @@ -15,8 +15,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a Commodore-format tape image, which is simply a timed list of downward-going zero crossings. @@ -49,7 +48,6 @@ class CommodoreTAP: public Tape { bool is_at_end_ = false; }; -} } #endif /* CommodoreTAP_hpp */ diff --git a/Storage/Tape/Formats/OricTAP.hpp b/Storage/Tape/Formats/OricTAP.hpp index f40734abc..da5937705 100644 --- a/Storage/Tape/Formats/OricTAP.hpp +++ b/Storage/Tape/Formats/OricTAP.hpp @@ -15,8 +15,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing an Oric-format tape image, which is a byte stream capture. @@ -54,7 +53,6 @@ class OricTAP: public Tape { uint16_t data_end_address_, data_start_address_; }; -} } #endif /* OricTAP_hpp */ diff --git a/Storage/Tape/Formats/TZX.hpp b/Storage/Tape/Formats/TZX.hpp index 277cd2464..b036aee11 100644 --- a/Storage/Tape/Formats/TZX.hpp +++ b/Storage/Tape/Formats/TZX.hpp @@ -14,8 +14,7 @@ #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a CSW tape image, which is a compressed 1-bit sampling. @@ -100,5 +99,5 @@ class TZX: public PulseQueuedTape { }; } -} + #endif /* TZX_hpp */ diff --git a/Storage/Tape/Formats/TapePRG.hpp b/Storage/Tape/Formats/TapePRG.hpp index 31d7c4447..18a1117ba 100644 --- a/Storage/Tape/Formats/TapePRG.hpp +++ b/Storage/Tape/Formats/TapePRG.hpp @@ -15,8 +15,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a .PRG, which is a direct local file. @@ -70,7 +69,6 @@ class PRG: public Tape { uint8_t copy_mask_ = 0x80; }; -} } #endif /* T64_hpp */ diff --git a/Storage/Tape/Formats/TapeUEF.hpp b/Storage/Tape/Formats/TapeUEF.hpp index 1016722cc..29325271e 100644 --- a/Storage/Tape/Formats/TapeUEF.hpp +++ b/Storage/Tape/Formats/TapeUEF.hpp @@ -17,8 +17,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a UEF tape image, a slightly-convoluted description of pulses. @@ -73,7 +72,6 @@ class UEF : public PulseQueuedTape, public TargetPlatform::TypeDistinguisher { void queue_implicit_byte(uint8_t byte); }; -} } #endif /* TapeUEF_hpp */ diff --git a/Storage/Tape/Formats/ZX80O81P.hpp b/Storage/Tape/Formats/ZX80O81P.hpp index 5f0d9006c..e1033e402 100644 --- a/Storage/Tape/Formats/ZX80O81P.hpp +++ b/Storage/Tape/Formats/ZX80O81P.hpp @@ -18,8 +18,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing a ZX80-format .O tape image, which is a byte stream capture. @@ -59,7 +58,6 @@ class ZX80O81P: public Tape, public TargetPlatform::TypeDistinguisher { std::size_t data_pointer_; }; -} } #endif /* ZX80O_hpp */ diff --git a/Storage/Tape/Formats/ZXSpectrumTAP.hpp b/Storage/Tape/Formats/ZXSpectrumTAP.hpp index ec1cc035c..cbb113178 100644 --- a/Storage/Tape/Formats/ZXSpectrumTAP.hpp +++ b/Storage/Tape/Formats/ZXSpectrumTAP.hpp @@ -15,8 +15,7 @@ #include #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape containing an Spectrum-format tape image, which contains a series of @@ -55,8 +54,6 @@ class ZXSpectrumTAP: public Tape { Pulse virtual_get_next_pulse() override; }; - -} } #endif /* SpectrumTAP_hpp */ diff --git a/Storage/Tape/Parsers/Acorn.hpp b/Storage/Tape/Parsers/Acorn.hpp index 8fd762f2e..4e6f0b4c9 100644 --- a/Storage/Tape/Parsers/Acorn.hpp +++ b/Storage/Tape/Parsers/Acorn.hpp @@ -13,9 +13,7 @@ #include "../../../Numeric/CRC.hpp" #include "../../Disk/DPLL/DigitalPhaseLockedLoop.hpp" -namespace Storage { -namespace Tape { -namespace Acorn { +namespace Storage::Tape::Acorn { class Shifter { public: @@ -66,8 +64,6 @@ class Parser: public Storage::Tape::Parser, public Shifter::Delegate Shifter shifter_; }; -} -} } #endif /* Acorn_hpp */ diff --git a/Storage/Tape/Parsers/Commodore.hpp b/Storage/Tape/Parsers/Commodore.hpp index 8a5040dc7..6d49b1a8f 100644 --- a/Storage/Tape/Parsers/Commodore.hpp +++ b/Storage/Tape/Parsers/Commodore.hpp @@ -13,9 +13,7 @@ #include #include -namespace Storage { -namespace Tape { -namespace Commodore { +namespace Storage::Tape::Commodore { enum class WaveType { Short, Medium, Long, Unrecognised @@ -131,8 +129,6 @@ class Parser: public Storage::Tape::PulseClassificationParser &waves) override; }; -} -} } #endif /* Commodore_hpp */ diff --git a/Storage/Tape/Parsers/MSX.hpp b/Storage/Tape/Parsers/MSX.hpp index 227b81efc..ddd146902 100644 --- a/Storage/Tape/Parsers/MSX.hpp +++ b/Storage/Tape/Parsers/MSX.hpp @@ -14,9 +14,7 @@ #include #include -namespace Storage { -namespace Tape { -namespace MSX { +namespace Storage::Tape::MSX { class Parser { public: @@ -49,8 +47,6 @@ class Parser { static int get_byte(const FileSpeed &speed, Storage::Tape::BinaryTapePlayer &tape_player); }; -} -} } #endif /* Storage_Tape_Parsers_MSX_hpp */ diff --git a/Storage/Tape/Parsers/Oric.hpp b/Storage/Tape/Parsers/Oric.hpp index bfbad1b86..34713a595 100644 --- a/Storage/Tape/Parsers/Oric.hpp +++ b/Storage/Tape/Parsers/Oric.hpp @@ -11,9 +11,7 @@ #include "TapeParser.hpp" -namespace Storage { -namespace Tape { -namespace Oric { +namespace Storage::Tape::Oric { enum class WaveType { Short, // i.e. 416 microseconds @@ -52,9 +50,6 @@ class Parser: public Storage::Tape::PulseClassificationParser &waves, const Pattern *pattern); }; - -} -} } #endif /* Oric_hpp */ diff --git a/Storage/Tape/Parsers/Spectrum.hpp b/Storage/Tape/Parsers/Spectrum.hpp index db51c8f1b..a0a6b6048 100644 --- a/Storage/Tape/Parsers/Spectrum.hpp +++ b/Storage/Tape/Parsers/Spectrum.hpp @@ -15,9 +15,7 @@ #include #include -namespace Storage { -namespace Tape { -namespace ZXSpectrum { +namespace Storage::Tape::ZXSpectrum { enum class WaveType { // All references to 't-states' below are cycles relative to the @@ -131,8 +129,6 @@ class Parser: public Storage::Tape::PulseClassificationParser #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { template class Parser { public: @@ -156,7 +155,6 @@ template class PulseClassificationParse std::vector wave_queue_; }; -} } #endif /* TapeParser_hpp */ diff --git a/Storage/Tape/Parsers/ZX8081.hpp b/Storage/Tape/Parsers/ZX8081.hpp index a3f3b8de7..88a25cc1d 100644 --- a/Storage/Tape/Parsers/ZX8081.hpp +++ b/Storage/Tape/Parsers/ZX8081.hpp @@ -17,9 +17,7 @@ #include #include -namespace Storage { -namespace Tape { -namespace ZX8081 { +namespace Storage::Tape::ZX8081 { enum class WaveType { Pulse, Gap, LongGap, Unrecognised @@ -57,8 +55,6 @@ class Parser: public Storage::Tape::PulseClassificationParser> get_next_file_data(const std::shared_ptr &tape); }; -} -} } #endif /* ZX8081_hpp */ diff --git a/Storage/Tape/PulseQueuedTape.hpp b/Storage/Tape/PulseQueuedTape.hpp index a55e717be..f050becb8 100644 --- a/Storage/Tape/PulseQueuedTape.hpp +++ b/Storage/Tape/PulseQueuedTape.hpp @@ -12,8 +12,7 @@ #include "Tape.hpp" #include -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Provides a @c Tape with a queue of upcoming pulses and an is-at-end flag. @@ -48,7 +47,6 @@ class PulseQueuedTape: public Tape { bool is_at_end_; }; -} } #endif /* PulseQueuedTape_hpp */ diff --git a/Storage/Tape/Tape.hpp b/Storage/Tape/Tape.hpp index 19e5bffbb..2fd566bda 100644 --- a/Storage/Tape/Tape.hpp +++ b/Storage/Tape/Tape.hpp @@ -18,8 +18,7 @@ #include "../../Activity/Source.hpp" -namespace Storage { -namespace Tape { +namespace Storage::Tape { /*! Models a tape as a sequence of pulses, each pulse being of arbitrary length and described @@ -164,7 +163,6 @@ class BinaryTapePlayer : public TapePlayer { Activity::Observer *observer_ = nullptr; }; -} } #endif /* Tape_hpp */ From e56db3c4e5a8f093fa4e9b8c82aaa7e5e2f7a789 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 10 May 2023 17:06:27 -0500 Subject: [PATCH 04/10] Eliminate the old 68000 implementation. --- Machines/Apple/Macintosh/Macintosh.cpp | 1 - .../Clock Signal.xcodeproj/project.pbxproj | 46 - .../Mac/Clock SignalTests/68000OldVsNew.mm | 3 +- OSBindings/Mac/Clock SignalTests/QLTests.mm | 2 +- Processors/68000/68000.hpp | 474 --- .../Implementation/68000Implementation.hpp | 2258 ----------- .../68000/Implementation/68000Storage.cpp | 3352 ----------------- .../68000/Implementation/68000Storage.hpp | 579 --- Processors/68000/State/State.cpp | 340 -- Processors/68000/State/State.hpp | 137 - 10 files changed, 3 insertions(+), 7189 deletions(-) delete mode 100644 Processors/68000/68000.hpp delete mode 100644 Processors/68000/Implementation/68000Implementation.hpp delete mode 100644 Processors/68000/Implementation/68000Storage.cpp delete mode 100644 Processors/68000/Implementation/68000Storage.hpp delete mode 100644 Processors/68000/State/State.cpp delete mode 100644 Processors/68000/State/State.hpp diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 02378af24..3900aeb11 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -34,7 +34,6 @@ #include "../../../Components/AppleClock/AppleClock.hpp" #include "../../../Components/DiskII/IWM.hpp" #include "../../../Components/DiskII/MacintoshDoubleDensityDrive.hpp" -#include "../../../Processors/68000/68000.hpp" #include "../../../Processors/68000Mk2/68000Mk2.hpp" diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 95559cccf..c34c23312 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -168,8 +168,6 @@ 4B1A1B1F27320FBC00119335 /* Disk.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A1B1C27320FBB00119335 /* Disk.cpp */; }; 4B1B58F6246CC4E8009C171E /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B58F4246CC4E8009C171E /* State.cpp */; }; 4B1B58F7246CC4E8009C171E /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B58F4246CC4E8009C171E /* State.cpp */; }; - 4B1B58FF246E19FD009C171E /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B58FD246E19FD009C171E /* State.cpp */; }; - 4B1B5900246E19FD009C171E /* State.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B58FD246E19FD009C171E /* State.cpp */; }; 4B1B88BB202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */; }; 4B1B88BC202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */; }; 4B1B88BD202E3D3D00B67DFF /* MultiMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FCC3F201EC24200960631 /* MultiMachine.cpp */; }; @@ -352,7 +350,6 @@ 4B7752C128217F490073E2C5 /* FAT.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B477709268FBE4D005C2340 /* FAT.cpp */; }; 4B7752C228217F5C0073E2C5 /* Spectrum.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B5D5C9525F56FC7001B4623 /* Spectrum.cpp */; }; 4B7752C328217F720073E2C5 /* Z80.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8DD39526360DDF00B3C866 /* Z80.cpp */; }; - 4B778EF023A5D68C0000D260 /* 68000Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFF1D3822337B0300838EA1 /* 68000Storage.cpp */; }; 4B778EF323A5DB230000D260 /* PCMSegment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4518731F75E91800926311 /* PCMSegment.cpp */; }; 4B778EF423A5DB3A0000D260 /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B8334941F5E25B60097E338 /* C1540.cpp */; }; 4B778EF523A5DB440000D260 /* StaticAnalyser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B894517201967B4007DE474 /* StaticAnalyser.cpp */; }; @@ -1080,8 +1077,6 @@ 4BFDD78C1F7F2DB4008579B9 /* ImplicitSectors.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFDD78B1F7F2DB4008579B9 /* ImplicitSectors.cpp */; }; 4BFEA2EF2682A7B900EBF94C /* Dave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFEA2ED2682A7B900EBF94C /* Dave.cpp */; }; 4BFEA2F02682A7B900EBF94C /* Dave.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFEA2ED2682A7B900EBF94C /* Dave.cpp */; }; - 4BFF1D3922337B0300838EA1 /* 68000Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFF1D3822337B0300838EA1 /* 68000Storage.cpp */; }; - 4BFF1D3A22337B0300838EA1 /* 68000Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BFF1D3822337B0300838EA1 /* 68000Storage.cpp */; }; 4BFF1D3D2235C3C100838EA1 /* EmuTOSTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BFF1D3C2235C3C100838EA1 /* EmuTOSTests.mm */; }; /* End PBXBuildFile section */ @@ -1228,8 +1223,6 @@ 4B1A1B1C27320FBB00119335 /* Disk.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Disk.cpp; sourceTree = ""; }; 4B1B58F4246CC4E8009C171E /* State.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = State.cpp; sourceTree = ""; }; 4B1B58F5246CC4E8009C171E /* State.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = State.hpp; sourceTree = ""; }; - 4B1B58FD246E19FD009C171E /* State.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = State.cpp; sourceTree = ""; }; - 4B1B58FE246E19FD009C171E /* State.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = State.hpp; sourceTree = ""; }; 4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiKeyboardMachine.cpp; sourceTree = ""; }; 4B1B88BA202E2EC100B67DFF /* MultiKeyboardMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MultiKeyboardMachine.hpp; sourceTree = ""; }; 4B1B88BE202E3DB200B67DFF /* MultiConfigurable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiConfigurable.cpp; sourceTree = ""; }; @@ -2248,10 +2241,6 @@ 4BFEA2ED2682A7B900EBF94C /* Dave.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Dave.cpp; sourceTree = ""; }; 4BFEA2EE2682A7B900EBF94C /* Dave.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Dave.hpp; sourceTree = ""; }; 4BFEA2F12682A90200EBF94C /* Sizes.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Sizes.hpp; sourceTree = ""; }; - 4BFF1D342233778C00838EA1 /* 68000.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 68000.hpp; sourceTree = ""; }; - 4BFF1D37223379D500838EA1 /* 68000Storage.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 68000Storage.hpp; sourceTree = ""; }; - 4BFF1D3822337B0300838EA1 /* 68000Storage.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = 68000Storage.cpp; sourceTree = ""; }; - 4BFF1D3B2235714900838EA1 /* 68000Implementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = 68000Implementation.hpp; sourceTree = ""; }; 4BFF1D3C2235C3C100838EA1 /* EmuTOSTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = EmuTOSTests.mm; sourceTree = ""; }; /* End PBXFileReference section */ @@ -2548,15 +2537,6 @@ path = State; sourceTree = ""; }; - 4B1B58FC246E19FD009C171E /* State */ = { - isa = PBXGroup; - children = ( - 4B1B58FD246E19FD009C171E /* State.cpp */, - 4B1B58FE246E19FD009C171E /* State.hpp */, - ); - path = State; - sourceTree = ""; - }; 4B1E85791D174DEC001EF87D /* 6532 */ = { isa = PBXGroup; children = ( @@ -4390,7 +4370,6 @@ 4B1414561B58879D00E04248 /* 6502 */, 4B4DEC15252BFA9C004583AC /* 6502Esque */, 4BF8D4CC251C0C9C00BBE21B /* 65816 */, - 4BFF1D332233778C00838EA1 /* 68000 */, 4BCA2F552832A643006C632A /* 68000Mk2 */, 4B77069E1EC9045B0053B588 /* Z80 */, ); @@ -5033,26 +5012,6 @@ path = Utility; sourceTree = ""; }; - 4BFF1D332233778C00838EA1 /* 68000 */ = { - isa = PBXGroup; - children = ( - 4BFF1D342233778C00838EA1 /* 68000.hpp */, - 4BFF1D36223379D500838EA1 /* Implementation */, - 4B1B58FC246E19FD009C171E /* State */, - ); - path = 68000; - sourceTree = ""; - }; - 4BFF1D36223379D500838EA1 /* Implementation */ = { - isa = PBXGroup; - children = ( - 4BFF1D37223379D500838EA1 /* 68000Storage.hpp */, - 4BFF1D3822337B0300838EA1 /* 68000Storage.cpp */, - 4BFF1D3B2235714900838EA1 /* 68000Implementation.hpp */, - ); - path = Implementation; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -5579,7 +5538,6 @@ 4B055AAA1FAE85F50060FFFF /* CPM.cpp in Sources */, 4B055A9A1FAE85CB0060FFFF /* MFMDiskController.cpp in Sources */, 4B0ACC3123775819008902D0 /* TIASound.cpp in Sources */, - 4B1B5900246E19FD009C171E /* State.cpp in Sources */, 4BC57CDA2436A62900FBC404 /* State.cpp in Sources */, 4B055ACB1FAE9AFB0060FFFF /* SerialBus.cpp in Sources */, 4B43983B29620FC9006B0BFC /* 9918.cpp in Sources */, @@ -5636,7 +5594,6 @@ 4B05401F219D1618001BF69C /* ScanTarget.cpp in Sources */, 4B055AE81FAE9B7B0060FFFF /* FIRFilter.cpp in Sources */, 4B055A901FAE85A90060FFFF /* TimedEventLoop.cpp in Sources */, - 4BFF1D3A22337B0300838EA1 /* 68000Storage.cpp in Sources */, 4B8318B722D3E54D006DB630 /* Video.cpp in Sources */, 4B7C681F2751A104001671EC /* Bitplanes.cpp in Sources */, 4B055AD21FAE9B0B0060FFFF /* Keyboard.cpp in Sources */, @@ -5919,7 +5876,6 @@ 4B4518A51F75FD1C00926311 /* SSD.cpp in Sources */, 4B7C681A275196E8001671EC /* MouseJoystick.cpp in Sources */, 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */, - 4B1B58FF246E19FD009C171E /* State.cpp in Sources */, 4B2B3A4C1F9B8FA70062DABF /* MemoryFuzzer.cpp in Sources */, 4B9EC0EA26B384080060A31F /* Keyboard.cpp in Sources */, 4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */, @@ -6061,7 +6017,6 @@ 4BCE0053227CE8CA000CA200 /* AppleII.cpp in Sources */, 4B8334821F5D9FF70097E338 /* PartialMachineCycle.cpp in Sources */, 4B1B88C0202E3DB200B67DFF /* MultiConfigurable.cpp in Sources */, - 4BFF1D3922337B0300838EA1 /* 68000Storage.cpp in Sources */, 4B54C0BC1F8D8E790050900F /* KeyboardMachine.cpp in Sources */, 4BB244D522AABAF600BE20E5 /* z8530.cpp in Sources */, 4BB73EA21B587A5100552FC2 /* AppDelegate.swift in Sources */, @@ -6159,7 +6114,6 @@ 4B7752C128217F490073E2C5 /* FAT.cpp in Sources */, 4B778F5B23A5F2DE0000D260 /* Tape.cpp in Sources */, 4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */, - 4B778EF023A5D68C0000D260 /* 68000Storage.cpp in Sources */, 4B7752B228217EAE0073E2C5 /* StaticAnalyser.cpp in Sources */, 4B7752BC28217F1D0073E2C5 /* Disk.cpp in Sources */, 4B04C899285E3DC800AA8FD6 /* 65816ComparativeTests.mm in Sources */, diff --git a/OSBindings/Mac/Clock SignalTests/68000OldVsNew.mm b/OSBindings/Mac/Clock SignalTests/68000OldVsNew.mm index 130914ccc..d37645845 100644 --- a/OSBindings/Mac/Clock SignalTests/68000OldVsNew.mm +++ b/OSBindings/Mac/Clock SignalTests/68000OldVsNew.mm @@ -9,7 +9,6 @@ #import -#include "68000.hpp" #include "68000Mk2.hpp" #include @@ -17,6 +16,7 @@ #include #include +/* namespace { struct RandomStore { @@ -694,3 +694,4 @@ void print_transactions(FILE *target, const std::vector &transactio } @end +*/ diff --git a/OSBindings/Mac/Clock SignalTests/QLTests.mm b/OSBindings/Mac/Clock SignalTests/QLTests.mm index d7d124d0c..20b8a61ec 100644 --- a/OSBindings/Mac/Clock SignalTests/QLTests.mm +++ b/OSBindings/Mac/Clock SignalTests/QLTests.mm @@ -16,7 +16,7 @@ #include -#include "68000.hpp" +#include "68000Mk2.hpp" #include "Comparative68000.hpp" #include "CSROMFetcher.hpp" diff --git a/Processors/68000/68000.hpp b/Processors/68000/68000.hpp deleted file mode 100644 index 30d161578..000000000 --- a/Processors/68000/68000.hpp +++ /dev/null @@ -1,474 +0,0 @@ -// -// 68000.hpp -// Clock Signal -// -// Created by Thomas Harte on 08/03/2019. -// Copyright © 2019 Thomas Harte. All rights reserved. -// - -#ifndef MC68000_h -#define MC68000_h - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../ClockReceiver/ForceInline.hpp" -#include "../../ClockReceiver/ClockReceiver.hpp" -#include "../../Numeric/RegisterSizes.hpp" - -namespace CPU { -namespace MC68000 { - -/*! - A microcycle is an atomic unit of 68000 bus activity — it is a single item large enough - fully to specify a sequence of bus events that occur without any possible interruption. - - Concretely, a standard read cycle breaks down into at least two microcycles: - - 1) a 4 half-cycle length microcycle in which the address strobe is signalled; and - 2) a 4 half-cycle length microcycle in which at least one of the data strobes is - signalled, and the data bus is sampled. - - That is, assuming DTack were signalled when microcycle (1) ended. If not then additional - wait state microcycles would fall between those two parts. - - The 68000 data sheet defines when the address becomes valid during microcycle (1), and - when the address strobe is actually asserted. But those timings are fixed. So simply - telling you that this was a microcycle during which the address trobe was signalled is - sufficient fully to describe the bus activity. - - (Aside: see the 68000 template's definition for options re: implicit DTack; if your - 68000 owner can always predict exactly how long it will hold DTack following observation - of an address-strobing microcycle, it can just supply those periods for accounting and - avoid the runtime cost of actual DTack emulation. But such as the bus allows.) -*/ -struct Microcycle { - using OperationT = unsigned int; - - /// Indicates that the address strobe and exactly one of the data strobes are active; you can determine - /// which by inspecting the low bit of the provided address. The RW line indicates a read. - static constexpr OperationT SelectByte = 1 << 0; - // Maintenance note: this is bit 0 to reduce the cost of getting a host-endian - // bytewise address. The assumption that it is bit 0 is also used for branchless - // selection in a few places. See implementation of host_endian_byte_address(), - // value8_high(), value8_low() and value16(). - - /// Indicates that the address and both data select strobes are active. - static constexpr OperationT SelectWord = 1 << 1; - - /// If set, indicates a read. Otherwise, a write. - static constexpr OperationT Read = 1 << 2; - - // Two-bit gap deliberately left here for PermitRead/Write below. - - /// A NewAddress cycle is one in which the address strobe is initially low but becomes high; - /// this correlates to states 0 to 5 of a standard read/write cycle. - static constexpr OperationT NewAddress = 1 << 5; - - /// A SameAddress cycle is one in which the address strobe is continuously asserted, but neither - /// of the data strobes are. - static constexpr OperationT SameAddress = 1 << 6; - - /// A Reset cycle is one in which the RESET output is asserted. - static constexpr OperationT Reset = 1 << 7; - - /// Contains the value of line FC0 if it is not implicit via InterruptAcknowledge. - static constexpr OperationT IsData = 1 << 8; - - /// Contains the value of line FC1 if it is not implicit via InterruptAcknowledge. - static constexpr OperationT IsProgram = 1 << 9; - - /// The interrupt acknowledge cycle is that during which the 68000 seeks to obtain the vector for - /// an interrupt it plans to observe. Noted on a real 68000 by all FCs being set to 1. - static constexpr OperationT InterruptAcknowledge = 1 << 10; - - /// Represents the state of the 68000's valid memory address line — indicating whether this microcycle - /// is synchronised with the E clock to satisfy a valid peripheral address request. - static constexpr OperationT IsPeripheral = 1 << 11; - - /// Provides the 68000's bus grant line — indicating whether a bus request has been acknowledged. - static constexpr OperationT BusGrant = 1 << 12; - - /// Contains a valid combination of the various static constexpr int flags, describing the operation - /// performed by this Microcycle. - OperationT operation = 0; - - /// Describes the duration of this Microcycle. - HalfCycles length = HalfCycles(4); - - /*! - For expediency, this provides a full 32-bit byte-resolution address — e.g. - if reading indirectly via an address register, this will indicate the full - value of the address register. - - The receiver should ignore bits 0 and 24+. Use word_address() automatically - to obtain the only the 68000's real address lines, giving a 23-bit address - at word resolution. - */ - const uint32_t *address = nullptr; - - /*! - If this is a write cycle, dereference value to get the value loaded onto - the data bus. - - If this is a read cycle, write the value on the data bus to it. - - Otherwise, this value is undefined. - - Byte values are provided via @c value.halves.low. @c value.halves.high is undefined. - This is true regardless of whether the upper or lower byte of a word is being - accessed. - - Word values occupy the entirety of @c value.full. - */ - RegisterPair16 *value = nullptr; - - /// @returns @c true if two Microcycles are equal; @c false otherwise. - bool operator ==(const Microcycle &rhs) const { - if(value != rhs.value) return false; - if(address != rhs.address) return false; - if(length != rhs.length) return false; - if(operation != rhs.operation) return false; - return true; - } - - // Various inspectors. - - /*! @returns true if any data select line is active; @c false otherwise. */ - forceinline bool data_select_active() const { - return bool(operation & (SelectWord | SelectByte | InterruptAcknowledge)); - } - - /*! - @returns 0 if this byte access wants the low part of a 16-bit word; 8 if it wants the high part. - */ - forceinline unsigned int byte_shift() const { - return (((*address) & 1) << 3) ^ 8; - } - - /*! - Obtains the mask to apply to a word that will leave only the byte this microcycle is selecting. - - @returns 0x00ff if this byte access wants the low part of a 16-bit word; 0xff00 if it wants the high part. - */ - forceinline uint16_t byte_mask() const { - return uint16_t(0xff00) >> (((*address) & 1) << 3); - } - - /*! - Obtains the mask to apply to a word that will leave only the byte this microcycle **isn't** selecting. - i.e. this is the part of a word that should be untouched by this microcycle. - - @returns 0xff00 if this byte access wants the low part of a 16-bit word; 0x00ff if it wants the high part. - */ - forceinline uint16_t untouched_byte_mask() const { - return uint16_t(uint16_t(0xff) << (((*address) & 1) << 3)); - } - - /*! - Assuming this cycle is a byte write, mutates @c destination by writing the byte to the proper upper or - lower part, retaining the other half. - */ - forceinline uint16_t write_byte(uint16_t destination) const { - return uint16_t((destination & untouched_byte_mask()) | (value->halves.low << byte_shift())); - } - - /*! - @returns non-zero if this is a byte read and 68000 LDS is asserted. - */ - forceinline int lower_data_select() const { - return (operation & SelectByte) & ((*address & 1) << 3); - } - - /*! - @returns non-zero if this is a byte read and 68000 UDS is asserted. - */ - forceinline int upper_data_select() const { - return (operation & SelectByte) & ~((*address & 1) << 3); - } - - /*! - @returns the address being accessed at the precision a 68000 supplies it — - only 24 address bit precision, with the low bit shifted out. So it's the - 68000 address at word precision: address 0 is the first word in the address - space, address 1 is the second word (i.e. the third and fourth bytes) in - the address space, etc. - */ - forceinline uint32_t word_address() const { - return (address ? (*address) & 0x00fffffe : 0) >> 1; - } - - /*! - @returns the address of the word or byte being accessed at byte precision, - in the endianness of the host platform. - - So: if this is a word access, and the 68000 wants to select the word at address - @c n, this will evaluate to @c n regardless of the host machine's endianness.. - - If this is a byte access and the host machine is big endian it will evalue to @c n. - - If the host machine is little endian then it will evaluate to @c n^1. - */ - forceinline uint32_t host_endian_byte_address() const { - #if TARGET_RT_BIG_ENDIAN - return *address & 0xffffff; - #else - return (*address ^ (1 & operation & SelectByte)) & 0xffffff; - #endif - } - - /*! - @returns the value on the data bus — all 16 bits, with any inactive lines - (as er the upper and lower data selects) being represented by 1s. Assumes - this is a write cycle. - */ - forceinline uint16_t value16() const { - const uint16_t values[] = { value->full, uint16_t((value->halves.low << 8) | value->halves.low) }; - return values[operation & SelectByte]; - } - - /*! - @returns the value currently on the high 8 lines of the data bus if any; - @c 0xff otherwise. Assumes this is a write cycle. - */ - forceinline uint8_t value8_high() const { - const uint8_t values[] = { uint8_t(value->full >> 8), value->halves.low}; - return values[operation & SelectByte]; - } - - /*! - @returns the value currently on the low 8 lines of the data bus if any; - @c 0xff otherwise. Assumes this is a write cycle. - */ - forceinline uint8_t value8_low() const { - const uint8_t values[] = { uint8_t(value->full), value->halves.low}; - return values[operation & SelectByte]; - } - - /*! - Sets to @c value the 8- or 16-bit portion of the supplied value that is - currently being read. Assumes this is a read cycle. - */ - forceinline void set_value16(uint16_t v) const { - assert(operation & Microcycle::Read); - if(operation & Microcycle::SelectWord) { - value->full = v; - } else { - value->halves.low = uint8_t(v >> byte_shift()); - } - } - - /*! - Equivalent to set_value16((v << 8) | 0x00ff). - */ - forceinline void set_value8_high(uint8_t v) const { - assert(operation & Microcycle::Read); - if(operation & Microcycle::SelectWord) { - value->full = uint16_t(0x00ff | (v << 8)); - } else { - value->halves.low = uint8_t(v | (0xff00 >> ((*address & 1) << 3))); - } - } - - /*! - Equivalent to set_value16((v) | 0xff00). - */ - forceinline void set_value8_low(uint8_t v) const { - assert(operation & Microcycle::Read); - if(operation & Microcycle::SelectWord) { - value->full = 0xff00 | v; - } else { - value->halves.low = uint8_t(v | (0x00ff << ((*address & 1) << 3))); - } - } - - /*! - @returns the same value as word_address() for any Microcycle with the NewAddress or - SameAddress flags set; undefined behaviour otherwise. - */ - forceinline uint32_t active_operation_word_address() const { - return ((*address) & 0x00fffffe) >> 1; - } - - // PermitRead and PermitWrite are used as part of the read/write mask - // supplied to @c apply; they are picked to be small enough values that - // a byte can be used for storage. - static constexpr OperationT PermitRead = 1 << 3; - static constexpr OperationT PermitWrite = 1 << 4; - - /*! - Assuming this to be a cycle with a data select active, applies it to @c target - subject to the read_write_mask, where 'applies' means: - - * if this is a byte read, reads a single byte from @c target; - * if this is a word read, reads a word (in the host platform's endianness) from @c target; and - * if this is a write, does the converse of a read. - */ - forceinline void apply(uint8_t *target, OperationT read_write_mask = PermitRead | PermitWrite) const { - assert( (operation & (SelectWord | SelectByte)) != (SelectWord | SelectByte)); - - switch((operation | read_write_mask) & (SelectWord | SelectByte | Read | PermitRead | PermitWrite)) { - default: - break; - - case SelectWord | Read | PermitRead: - case SelectWord | Read | PermitRead | PermitWrite: - value->full = *reinterpret_cast(target); - break; - case SelectByte | Read | PermitRead: - case SelectByte | Read | PermitRead | PermitWrite: - value->halves.low = *target; - break; - case SelectWord | PermitWrite: - case SelectWord | PermitWrite | PermitRead: - *reinterpret_cast(target) = value->full; - break; - case SelectByte | PermitWrite: - case SelectByte | PermitWrite | PermitRead: - *target = value->halves.low; - break; - } - } - -#ifndef NDEBUG - bool is_resizeable = false; -#endif -}; - -/*! - This is the prototype for a 68000 bus handler; real bus handlers can descend from this - in order to get default implementations of any changes that may occur in the expected interface. -*/ -class BusHandler { - public: - /*! - Provides the bus handler with a single Microcycle to 'perform'. - - FC0 and FC1 are provided inside the microcycle as the IsData and IsProgram - flags; FC2 is provided here as is_supervisor — it'll be either 0 or 1. - */ - HalfCycles perform_bus_operation([[maybe_unused]] const Microcycle &cycle, [[maybe_unused]] int is_supervisor) { - return HalfCycles(0); - } - - /*! - Provides information about the path of execution if enabled via the template. - */ - void will_perform([[maybe_unused]] uint32_t address, [[maybe_unused]] uint16_t opcode) {} -}; - -#include "Implementation/68000Storage.hpp" - -class ProcessorBase: public ProcessorStorage { -}; - -enum Flag: uint16_t { - Trace = 0x8000, - Supervisor = 0x2000, - - ConditionCodes = 0x1f, - - Extend = 0x0010, - Negative = 0x0008, - Zero = 0x0004, - Overflow = 0x0002, - Carry = 0x0001 -}; - -struct ProcessorState { - uint32_t data[8]; - uint32_t address[7]; - uint32_t user_stack_pointer, supervisor_stack_pointer; - uint32_t program_counter; - uint16_t status; - - /*! - @returns the supervisor stack pointer if @c status indicates that - the processor is in supervisor mode; the user stack pointer otherwise. - */ - uint32_t stack_pointer() const { - return (status & Flag::Supervisor) ? supervisor_stack_pointer : user_stack_pointer; - } - - // TODO: More state needed to indicate current instruction, the processor's - // progress through it, and anything it has fetched so far. -// uint16_t current_instruction; -}; - -template class Processor: public ProcessorBase { - public: - Processor(T &bus_handler) : ProcessorBase(), bus_handler_(bus_handler) {} - - void run_for(HalfCycles duration); - - using State = ProcessorState; - /// @returns The current processor state. - State get_state(); - - /// Sets the processor to the supplied state. - void set_state(const State &); - - /// Sets the DTack line — @c true for active, @c false for inactive. - inline void set_dtack(bool dtack) { - dtack_ = dtack; - } - - /// Sets the VPA (valid peripheral address) line — @c true for active, @c false for inactive. - inline void set_is_peripheral_address(bool is_peripheral_address) { - is_peripheral_address_ = is_peripheral_address; - } - - /// Sets the bus error line — @c true for active, @c false for inactive. - inline void set_bus_error(bool bus_error) { - bus_error_ = bus_error; - } - - /// Sets the interrupt lines, IPL0, IPL1 and IPL2. - inline void set_interrupt_level(int interrupt_level) { - bus_interrupt_level_ = interrupt_level; - } - - /// Sets the bus request line. - /// This area of functionality is TODO. - inline void set_bus_request(bool bus_request) { - bus_request_ = bus_request; - } - - /// Sets the bus acknowledge line. - /// This area of functionality is TODO. - inline void set_bus_acknowledge(bool bus_acknowledge) { - bus_acknowledge_ = bus_acknowledge; - } - - /// Sets the halt line. - inline void set_halt(bool halt) { - halt_ = halt; - } - - /// @returns The current phase of the E clock; this will be a number of - /// half-cycles between 0 and 19 inclusive, indicating how far the 68000 - /// is into the current E cycle. - /// - /// This is guaranteed to be 0 at initial 68000 construction. - HalfCycles get_e_clock_phase() { - return e_clock_phase_; - } - - void reset(); - - private: - T &bus_handler_; -}; - -#include "Implementation/68000Implementation.hpp" - -} -} - -#endif /* MC68000_h */ diff --git a/Processors/68000/Implementation/68000Implementation.hpp b/Processors/68000/Implementation/68000Implementation.hpp deleted file mode 100644 index 137f8bb17..000000000 --- a/Processors/68000/Implementation/68000Implementation.hpp +++ /dev/null @@ -1,2258 +0,0 @@ -// -// 68000Implementation.hpp -// Clock Signal -// -// Created by Thomas Harte on 10/03/2019. -// Copyright © 2019 Thomas Harte. All rights reserved. -// - -#define ccr() \ - ( \ - (carry_flag_ ? 0x0001 : 0x0000) | \ - (overflow_flag_ ? 0x0002 : 0x0000) | \ - (zero_result_ ? 0x0000 : 0x0004) | \ - (negative_flag_ ? 0x0008 : 0x0000) | \ - (extend_flag_ ? 0x0010 : 0x0000) \ - ) - -#define status() \ - uint16_t( \ - ccr() | \ - (interrupt_level_ << 8) | \ - (trace_flag_ ? 0x8000 : 0x0000) | \ - (is_supervisor_ << 13) \ - ) - -#define apply_ccr(x) \ - carry_flag_ = (x) & 0x0001; \ - overflow_flag_ = (x) & 0x0002; \ - zero_result_ = ((x) & 0x0004) ^ 0x0004; \ - negative_flag_ = (x) & 0x0008; \ - extend_flag_ = (x) & 0x0010; - -#define apply_status(x) \ - apply_ccr(x) \ - interrupt_level_ = ((x) >> 8) & 7; \ - trace_flag_ = (x) & 0x8000; \ - set_is_supervisor(!!(((x) >> 13) & 1)); - -#define get_bus_code() \ - uint16_t( \ - ((active_step_->microcycle.operation & Microcycle::IsProgram) ? 0x02 : 0x01) | \ - (is_supervisor_ << 2) | \ - (active_program_ ? 0x08 : 0) | \ - ((active_step_->microcycle.operation & Microcycle::Read) ? 0x10 : 0) | \ - (decoded_instruction_.full & 0xffe0) \ - ) - -#define u_extend16(x) uint32_t(int16_t(x)) -#define u_extend8(x) uint32_t(int8_t(x)) -#define s_extend16(x) int32_t(int16_t(x)) -#define s_extend8(x) int32_t(int8_t(x)) - -#define convert_to_bit_count_16(x) \ - x = ((x & 0xaaaa) >> 1) + (x & 0x5555); \ - x = ((x & 0xcccc) >> 2) + (x & 0x3333); \ - x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); \ - x = ((x & 0xff00) >> 8) + (x & 0x00ff); - -// Sets the length of the next microcycle; if this is a debug build, also confirms -// that the microcycle being adjusted is the one that it's permissible to adjust. -#ifdef NDEBUG -#define set_next_microcycle_length(x) \ - bus_program->microcycle.length = x -#else -#define set_next_microcycle_length(x) \ - assert(bus_program->microcycle.is_resizeable); \ - bus_program->microcycle.length = x -#endif - -template void Processor::run_for(HalfCycles duration) { - const HalfCycles remaining_duration = duration + half_cycles_left_to_run_; - - // This loop counts upwards rather than downwards because it simplifies calculation of - // E as and when required. - HalfCycles cycles_run_for; - while(cycles_run_for < remaining_duration) { - /* - PERFORM THE CURRENT BUS STEP'S MICROCYCLE. - */ - switch(execution_state_) { - default: - case ExecutionState::Executing: - // Check for entry into the halted state. - if(halt_ && active_step_[0].microcycle.operation & Microcycle::NewAddress) { - execution_state_ = ExecutionState::Halted; - continue; - } - - if(active_step_->microcycle.data_select_active()) { - // Check whether the processor needs to await DTack. - if(!dtack_is_implicit && !dtack_ && !bus_error_) { - execution_state_ = ExecutionState::WaitingForDTack; - dtack_cycle_ = active_step_->microcycle; - dtack_cycle_.length = HalfCycles(2); - dtack_cycle_.operation &= ~(Microcycle::SelectByte | Microcycle::SelectWord); - continue; - } - - // Check for bus error. - if(bus_error_ && !is_starting_interrupt_) { - const auto offending_address = *active_step_->microcycle.address; - active_program_ = nullptr; - active_micro_op_ = long_exception_micro_ops_; - populate_bus_error_steps(2, status(), get_bus_code(), offending_address); - program_counter_.full -= 4; - active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; - } - } - - // Check for an address error. Which I have assumed happens before the microcycle that - // would nominate the new address. - if( - (active_step_[0].microcycle.operation & Microcycle::NewAddress) && - (active_step_[1].microcycle.operation & Microcycle::SelectWord) && - *active_step_->microcycle.address & 1) { - const auto offending_address = *active_step_->microcycle.address; - active_program_ = nullptr; - active_micro_op_ = long_exception_micro_ops_; - populate_bus_error_steps(3, status(), get_bus_code(), offending_address); - program_counter_.full -= 4; - active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; - - // TODO: the above is only correct prior to the final microcycle of an - // instruction. If an exception occurs in the final microcycle then - // the next instruction will already have moved into the current instruction - // slot (decoded_instruction_ in my terms). - - // TODO: it's also not correct for a bus error that occurs during another exception. - } - - // Perform the microcycle if it is of non-zero length. If this is an operation that - // would normally strobe one of the data selects and VPA is active, it will also need - // stretching. - if(active_step_->microcycle.length != HalfCycles(0)) { - if(is_peripheral_address_ && active_step_->microcycle.data_select_active()) { - auto cycle_copy = active_step_->microcycle; - cycle_copy.operation |= Microcycle::IsPeripheral; - - // Length will be: (i) distance to next E cycle, plus (ii) difference between - // current length and a whole E cycle. - const auto phase_now = (e_clock_phase_ + cycles_run_for) % 20; - const auto time_to_boundary = (HalfCycles(20) - phase_now) % HalfCycles(20); - cycle_copy.length = HalfCycles(20) + time_to_boundary; - - cycles_run_for += - cycle_copy.length + - bus_handler_.perform_bus_operation(cycle_copy, is_supervisor_); - } else { - cycles_run_for += - active_step_->microcycle.length + - bus_handler_.perform_bus_operation(active_step_->microcycle, is_supervisor_); - } - } - -#ifdef LOG_TRACE - if(should_log && !(active_step_->microcycle.operation & Microcycle::IsProgram)) { - switch(active_step_->microcycle.operation & (Microcycle::SelectWord | Microcycle::SelectByte | Microcycle::Read)) { - default: break; - - case Microcycle::SelectWord | Microcycle::Read: - printf("[%08x -> %04x] ", *active_step_->microcycle.address, active_step_->microcycle.value->full); - break; - case Microcycle::SelectByte | Microcycle::Read: - printf("[%08x -> %02x] ", *active_step_->microcycle.address, active_step_->microcycle.value->halves.low); - break; - case Microcycle::SelectWord: - printf("{%04x -> %08x} ", active_step_->microcycle.value->full, *active_step_->microcycle.address); - break; - case Microcycle::SelectByte: - printf("{%02x -> %08x} ", active_step_->microcycle.value->halves.low, *active_step_->microcycle.address); - break; - } - } -#endif - - /* - PERFORM THE BUS STEP'S ACTION. - */ - switch(active_step_->action) { - default: - std::cerr << "Unimplemented 68000 bus step action: " << int(active_step_->action) << std::endl; - return; - break; - - case BusStep::Action::None: break; - - case BusStep::Action::IncrementEffectiveAddress0: effective_address_[0].full += 2; break; - case BusStep::Action::IncrementEffectiveAddress1: effective_address_[1].full += 2; break; - case BusStep::Action::DecrementEffectiveAddress0: effective_address_[0].full -= 2; break; - case BusStep::Action::DecrementEffectiveAddress1: effective_address_[1].full -= 2; break; - case BusStep::Action::IncrementProgramCounter: program_counter_.full += 2; break; - - case BusStep::Action::IncrementEffectiveAddress0AlignStackPointer: - effective_address_[0].full += 2; - address_[7].full &= 0xffff'fffe; - break; - - case BusStep::Action::AdvancePrefetch: - prefetch_queue_.halves.high = prefetch_queue_.halves.low; - - // During prefetch advance seems to be the only time the interrupt inputs are sampled; - // TODO: determine whether this really happens on *every* advance. - if(bus_interrupt_level_ > interrupt_level_) { - pending_interrupt_level_ = bus_interrupt_level_; - } - break; - } - - // Move to the next bus step. - ++ active_step_; - break; - - case ExecutionState::Stopped: - // If an interrupt (TODO: or reset) has finally arrived that will be serviced, - // exit the STOP. - if(bus_interrupt_level_ > interrupt_level_) { - pending_interrupt_level_ = bus_interrupt_level_; - program_counter_.full += 4; // Don't return to this stop. - execution_state_ = ExecutionState::WillBeginInterrupt; - continue; - } - - // Otherwise continue being stopped. - cycles_run_for += - stop_cycle_.length + - bus_handler_.perform_bus_operation(stop_cycle_, is_supervisor_); - continue; - - case ExecutionState::WaitingForDTack: - // If DTack or bus error has been signalled, stop waiting. - if(dtack_ || bus_error_) { - execution_state_ = ExecutionState::Executing; - continue; - } - - // Otherwise, signal another cycle of wait. - cycles_run_for += - dtack_cycle_.length + - bus_handler_.perform_bus_operation(dtack_cycle_, is_supervisor_); - continue; - - case ExecutionState::Halted: - if(!halt_) { - execution_state_ = ExecutionState::Executing; - continue; - } - - cycles_run_for += - stop_cycle_.length + - bus_handler_.perform_bus_operation(stop_cycle_, is_supervisor_); - continue; - - case ExecutionState::WillBeginInterrupt: -#ifdef LOG_TRACE -// should_log = true; -#endif - active_program_ = nullptr; - active_micro_op_ = interrupt_micro_ops_; - execution_state_ = ExecutionState::Executing; - active_step_ = &all_bus_steps_[active_micro_op_->bus_program]; - is_starting_interrupt_ = true; - break; - } - - /* - FIND THE NEXT MICRO-OP IF UNKNOWN. - */ - if(active_step_->is_terminal()) { - while(true) { - // If there are any more micro-operations available, just move onwards. - if(active_micro_op_ && !active_micro_op_->is_terminal()) { - ++active_micro_op_; - } else { - // Either the micro-operations for this instruction have been exhausted, or - // no instruction was ongoing. Either way, do a standard instruction operation. - - if(pending_interrupt_level_) { - execution_state_ = ExecutionState::WillBeginInterrupt; - break; - } - - if(trace_flag_ && last_trace_flag_) { - // The user has set the trace bit in the status register. - active_program_ = nullptr; - active_micro_op_ = short_exception_micro_ops_; - populate_trap_steps(9, status()); - program_counter_.full -= 4; - } else { -#ifdef LOG_TRACE - if(should_log) { - std::cout << std::setfill('0'); - std::cout << (extend_flag_ ? 'x' : '-') << (negative_flag_ ? 'n' : '-') << (zero_result_ ? '-' : 'z'); - std::cout << (overflow_flag_ ? 'v' : '-') << (carry_flag_ ? 'c' : '-') << '\t'; - std::cout << (is_supervisor_ ? 's' : 'u') << '\t'; - for(int c = 0; c < 8; ++ c) std::cout << "d" << c << ":" << std::setw(8) << data_[c].full << " "; - for(int c = 0; c < 8; ++ c) std::cout << "a" << c << ":" << std::setw(8) << address_[c].full << " "; - if(is_supervisor_) { - std::cout << "usp:" << std::setw(8) << std::setfill('0') << stack_pointers_[0].full << " "; - } else { - std::cout << "ssp:" << std::setw(8) << std::setfill('0') << stack_pointers_[1].full << " "; - } - std::cout << '\n'; - } -#endif - - decoded_instruction_.full = prefetch_queue_.halves.high.full; - -#ifndef NDEBUG - /* Debugging feature: reset the effective addresses and data latches, so that it's - more obvious if some of the instructions aren't properly feeding them. */ - effective_address_[0].full = effective_address_[1].full = source_bus_data_.full = destination_bus_data_.full = 0x12344321; -#endif - -#ifdef LOG_TRACE - if(should_log) { - std::cout << std::hex << (program_counter_.full - 4) << ": " << std::setw(4) << decoded_instruction_.full << '\t'; - } -#endif - - if constexpr (signal_will_perform) { - bus_handler_.will_perform(program_counter_.full - 4, decoded_instruction_.full); - } - -#ifdef LOG_TRACE -// const uint32_t fetched_pc = (program_counter_.full - 4)&0xffffff; - -// should_log |= fetched_pc == 0x6d9c; -// should_log = (fetched_pc >= 0x41806A && fetched_pc <= 0x418618); -// should_log |= fetched_pc == 0x4012A2; -// should_log &= fetched_pc != 0x4012AE; - -// should_log = (fetched_pc >= 0x408D66) && (fetched_pc <= 0x408D84); -#endif - - if(instructions[decoded_instruction_.full].micro_operations != Program::NoSuchProgram) { - if((instructions[decoded_instruction_.full].requires_supervisor) && !is_supervisor_) { - // A privilege violation has been detected. - active_program_ = nullptr; - active_micro_op_ = short_exception_micro_ops_; - populate_trap_steps(8, status()); - - // The location of the failed instruction is what should end up on the stack. - program_counter_.full -= 4; - } else { - // Standard instruction dispatch. - active_program_ = &instructions[decoded_instruction_.full]; - active_micro_op_ = &all_micro_ops_[active_program_->micro_operations]; - } - } else { - // The opcode fetched isn't valid. - active_program_ = nullptr; - active_micro_op_ = short_exception_micro_ops_; - - // The location of the failed instruction is what should end up on the stack. - program_counter_.full -= 4; - -#ifdef LOG_TRACE -// should_log = true; -#endif - - // The vector used depends on whether this is a vanilla unrecognised instruction, - // or one on the A or F lines. - switch(decoded_instruction_.full >> 12) { - default: - populate_trap_steps(4, status()); - break; - case 0xa: - populate_trap_steps(10, status()); - break; - case 0xf: - populate_trap_steps(11, status()); - break; - } - } - } - last_trace_flag_ = trace_flag_; - } - - auto bus_program = &all_bus_steps_[active_micro_op_->bus_program]; - using int_type = decltype(active_micro_op_->action); - switch(active_micro_op_->action) { - default: - std::cerr << "Unhandled 68000 micro op action " << std::hex << active_micro_op_->action << " within instruction " << decoded_instruction_.full << std::endl; - break; - - case int_type(MicroOp::Action::None): break; - -#define offset_pointer(x) reinterpret_cast(&reinterpret_cast(static_cast(this))[x]) -#define source() offset_pointer(active_program_->source_offset) -#define source_address() address_[active_program_->source] -#define destination() offset_pointer(active_program_->destination_offset) -#define destination_address() address_[active_program_->dest] - - case int_type(MicroOp::Action::PerformOperation): -#define sub_overflow() ((result ^ destination) & (destination ^ source)) -#define add_overflow() ((result ^ destination) & ~(destination ^ source)) - switch(active_program_->operation) { - /* - ABCD adds the lowest bytes form the source and destination using BCD arithmetic, - obeying the extend flag. - */ - case Operation::ABCD: { - // Pull out the two halves, for simplicity. - const uint8_t source = source()->halves.low.halves.low; - const uint8_t destination = destination()->halves.low.halves.low; - - // Perform the BCD add by evaluating the two nibbles separately. - const int unadjusted_result = destination + source + (extend_flag_ ? 1 : 0); - int result = (destination & 0xf) + (source & 0xf) + (extend_flag_ ? 1 : 0); - if(result > 0x09) result += 0x06; - result += (destination & 0xf0) + (source & 0xf0); - if(result > 0x99) result += 0x60; - - // Set all flags essentially as if this were normal addition. - zero_result_ |= result & 0xff; - extend_flag_ = carry_flag_ = uint_fast32_t(result & ~0xff); - negative_flag_ = result & 0x80; - overflow_flag_ = ~unadjusted_result & result & 0x80; - - // Store the result. - destination()->halves.low.halves.low = uint8_t(result); - } break; - - // ADD and ADDA add two quantities, the latter sign extending and without setting any flags; - // ADDQ and SUBQ act as ADD and SUB, but taking the second argument from the instruction code. -#define addop(a, b, x) a + b + (x ? 1 : 0) -#define subop(a, b, x) a - b - (x ? 1 : 0) -#define z_set(a, b) a = b -#define z_or(a, b) a |= b - -#define addsubb(a, b, dest, op, overflow, x, zero_op) \ - const int source = a; \ - const int destination = b; \ - const auto result = op(destination, source, x); \ -\ - dest = uint8_t(result); \ - zero_op(zero_result_, dest); \ - extend_flag_ = carry_flag_ = uint_fast32_t(result & ~0xff); \ - negative_flag_ = result & 0x80; \ - overflow_flag_ = overflow() & 0x80; - -#define addsubw(a, b, dest, op, overflow, x, zero_op) \ - const int source = a; \ - const int destination = b; \ - const auto result = op(destination, source, x); \ -\ - dest = uint16_t(result); \ - zero_op(zero_result_, dest); \ - extend_flag_ = carry_flag_ = uint_fast32_t(result & ~0xffff); \ - negative_flag_ = result & 0x8000; \ - overflow_flag_ = overflow() & 0x8000; - -#define addsubl(a, b, dest, op, overflow, x, zero_op) \ - const uint64_t source = a; \ - const uint64_t destination = b; \ - const auto result = op(destination, source, x); \ -\ - dest = uint32_t(result); \ - zero_op(zero_result_, dest); \ - extend_flag_ = carry_flag_ = uint_fast32_t(result >> 32); \ - negative_flag_ = result & 0x80000000; \ - overflow_flag_ = overflow() & 0x80000000; - -#define addb(a, b, dest, x, z) addsubb(a, b, dest, addop, add_overflow, x, z) -#define subb(a, b, dest, x, z) addsubb(a, b, dest, subop, sub_overflow, x, z) -#define addw(a, b, dest, x, z) addsubw(a, b, dest, addop, add_overflow, x, z) -#define subw(a, b, dest, x, z) addsubw(a, b, dest, subop, sub_overflow, x, z) -#define addl(a, b, dest, x, z) addsubl(a, b, dest, addop, add_overflow, x, z) -#define subl(a, b, dest, x, z) addsubl(a, b, dest, subop, sub_overflow, x, z) - -#define no_extend(op, a, b, c) op(a, b, c, 0, z_set) -#define extend(op, a, b, c) op(a, b, c, extend_flag_, z_or) - -#define q() (((decoded_instruction_.full >> 9)&7) ? ((decoded_instruction_.full >> 9)&7) : 8) - - case Operation::ADDb: { - no_extend( addb, - source()->halves.low.halves.low, - destination()->halves.low.halves.low, - destination()->halves.low.halves.low); - } break; - - case Operation::ADDXb: { - extend( addb, - source()->halves.low.halves.low, - destination()->halves.low.halves.low, - destination()->halves.low.halves.low); - } break; - - case Operation::ADDQb: { - no_extend( addb, - q(), - destination()->halves.low.halves.low, - destination()->halves.low.halves.low); - } break; - - case Operation::ADDw: { - no_extend( addw, - source()->halves.low.full, - destination()->halves.low.full, - destination()->halves.low.full); - } break; - - case Operation::ADDXw: { - extend( addw, - source()->halves.low.full, - destination()->halves.low.full, - destination()->halves.low.full); - } break; - - case Operation::ADDQw: { - no_extend( addw, - q(), - destination()->halves.low.full, - destination()->halves.low.full); - } break; - - case Operation::ADDl: { - no_extend( addl, - source()->full, - destination()->full, - destination()->full); - } break; - - case Operation::ADDXl: { - extend( addl, - source()->full, - destination()->full, - destination()->full); - } break; - - case Operation::ADDQl: { - no_extend( addl, - q(), - destination()->full, - destination()->full); - } break; - - case Operation::SUBb: { - no_extend( subb, - source()->halves.low.halves.low, - destination()->halves.low.halves.low, - destination()->halves.low.halves.low); - } break; - - case Operation::SUBXb: { - extend( subb, - source()->halves.low.halves.low, - destination()->halves.low.halves.low, - destination()->halves.low.halves.low); - } break; - - case Operation::SUBQb: { - no_extend( subb, - q(), - destination()->halves.low.halves.low, - destination()->halves.low.halves.low); - } break; - - case Operation::SUBw: { - no_extend( subw, - source()->halves.low.full, - destination()->halves.low.full, - destination()->halves.low.full); - } break; - - case Operation::SUBXw: { - extend( subw, - source()->halves.low.full, - destination()->halves.low.full, - destination()->halves.low.full); - } break; - - case Operation::SUBQw: { - no_extend( subw, - q(), - destination()->halves.low.full, - destination()->halves.low.full); - } break; - - case Operation::SUBl: { - no_extend( subl, - source()->full, - destination()->full, - destination()->full); - } break; - - case Operation::SUBXl: { - extend( subl, - source()->full, - destination()->full, - destination()->full); - } break; - - case Operation::SUBQl: { - no_extend( subl, - q(), - destination()->full, - destination()->full); - } break; - - case Operation::ADDQAl: - destination()->full += q(); - break; - - case Operation::SUBQAl: - destination()->full -= q(); - break; - -#undef addl -#undef addw -#undef addb -#undef subl -#undef subw -#undef subb -#undef addsubl -#undef addsubw -#undef addsubb -#undef q -#undef z_set -#undef z_or -#undef no_extend -#undef extend -#undef addop -#undef subop - - - case Operation::ADDAw: - destination()->full += u_extend16(source()->halves.low.full); - break; - - case Operation::ADDAl: - destination()->full += source()->full; - break; - - case Operation::SUBAw: - destination()->full -= u_extend16(source()->halves.low.full); - break; - - case Operation::SUBAl: - destination()->full -= source()->full; - break; - - - // BRA: alters the program counter, exclusively via the prefetch queue. - case Operation::BRA: { - const int8_t byte_offset = int8_t(prefetch_queue_.halves.high.halves.low); - - // A non-zero offset byte branches by just that amount; otherwise use the word - // after as an offset. In both cases, treat as signed. - if(byte_offset) { - program_counter_.full += uint32_t(byte_offset); - } else { - program_counter_.full += u_extend16(prefetch_queue_.halves.low.full); - } - program_counter_.full -= 2; - } break; - - // Two BTSTs: set the zero flag according to the value of the destination masked by - // the bit named in the source modulo the operation size. - case Operation::BTSTb: - zero_result_ = destination()->full & (1 << (source()->full & 7)); - break; - - case Operation::BTSTl: - zero_result_ = destination()->full & (1 << (source()->full & 31)); - break; - - case Operation::BCLRb: - zero_result_ = destination()->full & (1 << (source()->full & 7)); - destination()->full &= ~(1 << (source()->full & 7)); - break; - - case Operation::BCLRl: - zero_result_ = destination()->full & (1 << (source()->full & 31)); - destination()->full &= ~(1 << (source()->full & 31)); - - // Clearing in the top word requires an extra four cycles. - set_next_microcycle_length(HalfCycles(8 + ((source()->full & 31) / 16) * 4)); - break; - - case Operation::BCHGl: - zero_result_ = destination()->full & (1 << (source()->full & 31)); - destination()->full ^= 1 << (source()->full & 31); - set_next_microcycle_length(HalfCycles(4 + (((source()->full & 31) / 16) * 4))); - break; - - case Operation::BCHGb: - zero_result_ = destination()->halves.low.halves.low & (1 << (source()->full & 7)); - destination()->halves.low.halves.low ^= 1 << (source()->full & 7); - break; - - case Operation::BSETl: - zero_result_ = destination()->full & (1 << (source()->full & 31)); - destination()->full |= 1 << (source()->full & 31); - set_next_microcycle_length(HalfCycles(4 + (((source()->full & 31) / 16) * 4))); - break; - - case Operation::BSETb: - zero_result_ = destination()->halves.low.halves.low & (1 << (source()->full & 7)); - destination()->halves.low.halves.low |= 1 << (source()->full & 7); - break; - - // Bcc: ordinarily evaluates the relevant condition and displacement size and then: - // if condition is false, schedules bus operations to get past this instruction; - // otherwise applies the offset and schedules bus operations to refill the prefetch queue. - // - // Special case: the condition code is 1, which is ordinarily false. In that case this - // is the trailing step of a BSR. - case Operation::Bcc: { - // Grab the 8-bit offset. - const int8_t byte_offset = int8_t(prefetch_queue_.halves.high.halves.low); - - // Check whether this is secretly BSR. - const bool is_bsr = ((decoded_instruction_.full >> 8) & 0xf) == 1; - - // Test the conditional, treating 'false' as true. - const bool should_branch = is_bsr || evaluate_condition(decoded_instruction_.full >> 8); - - // Schedule something appropriate, by rewriting the program for this instruction temporarily. - if(should_branch) { - if(byte_offset) { - program_counter_.full += decltype(program_counter_.full)(byte_offset); - } else { - program_counter_.full += u_extend16(prefetch_queue_.halves.low.full); - } - program_counter_.full -= 2; - bus_program = is_bsr ? bsr_bus_steps_ : branch_taken_bus_steps_; - } else { - if(byte_offset) { - bus_program = branch_byte_not_taken_bus_steps_; - } else { - bus_program = branch_word_not_taken_bus_steps_; - } - } - } break; - - case Operation::DBcc: { - // Decide what sort of DBcc this is. - if(!evaluate_condition(decoded_instruction_.full >> 8)) { - -- source()->halves.low.full; - const auto target_program_counter = program_counter_.full + u_extend16(prefetch_queue_.halves.low.full) - 2; - - if(source()->halves.low.full == 0xffff) { - // This DBcc will be ignored as the counter has underflowed. - // Schedule n np np np and continue. Assumed: the first np - // is from where the branch would have been if taken? - bus_program = dbcc_condition_false_no_branch_steps_; - dbcc_false_address_ = target_program_counter; - } else { - // Take the branch. Change PC and schedule n np np. - bus_program = dbcc_condition_false_branch_steps_; - program_counter_.full = target_program_counter; - } - } else { - // This DBcc will be ignored as the condition is true; - // perform nn np np and continue. - bus_program = dbcc_condition_true_steps_; - } - } break; - - case Operation::Scc: { - destination()->halves.low.halves.low = - evaluate_condition(decoded_instruction_.full >> 8) ? 0xff : 0x00; - } break; - - /* - CLRs: store 0 to the destination, set the zero flag, and clear - negative, overflow and carry. - */ - case Operation::CLRb: - destination()->halves.low.halves.low = 0; - negative_flag_ = overflow_flag_ = carry_flag_ = zero_result_ = 0; - break; - - case Operation::CLRw: - destination()->halves.low.full = 0; - negative_flag_ = overflow_flag_ = carry_flag_ = zero_result_ = 0; - break; - - case Operation::CLRl: - destination()->full = 0; - negative_flag_ = overflow_flag_ = carry_flag_ = zero_result_ = 0; - break; - - /* - CMP.b, CMP.l and CMP.w: sets the condition flags (other than extend) based on a subtraction - of the source from the destination; the result of the subtraction is not stored. - */ - case Operation::CMPb: { - const uint8_t source = source()->halves.low.halves.low; - const uint8_t destination = destination()->halves.low.halves.low; - const int result = destination - source; - - zero_result_ = result & 0xff; - carry_flag_ = decltype(carry_flag_)(result & ~0xff); - negative_flag_ = result & 0x80; - overflow_flag_ = sub_overflow() & 0x80; - } break; - - case Operation::CMPw: { - const uint16_t source = source()->halves.low.full; - const uint16_t destination = destination()->halves.low.full; - const int result = destination - source; - - zero_result_ = result & 0xffff; - carry_flag_ = decltype(carry_flag_)(result & ~0xffff); - negative_flag_ = result & 0x8000; - overflow_flag_ = sub_overflow() & 0x8000; - } break; - - case Operation::CMPAw: { - const auto source = uint64_t(u_extend16(source()->halves.low.full)); - const uint64_t destination = destination()->full; - const auto result = destination - source; - - zero_result_ = uint32_t(result); - carry_flag_ = result >> 32; - negative_flag_ = result & 0x80000000; - overflow_flag_ = sub_overflow() & 0x80000000; - } break; - - case Operation::CMPl: { - const auto source = uint64_t(source()->full); - const auto destination = uint64_t(destination()->full); - const auto result = destination - source; - - zero_result_ = uint32_t(result); - carry_flag_ = result >> 32; - negative_flag_ = result & 0x80000000; - overflow_flag_ = sub_overflow() & 0x80000000; - } break; - - // JMP: copies EA(0) to the program counter. - case Operation::JMP: - program_counter_ = effective_address_[0]; - break; - - // JMP: copies the source bus data to the program counter. - case Operation::RTS: - program_counter_ = source_bus_data_; - break; - - /* - MOVE.b, MOVE.l and MOVE.w: move the least significant byte or word, or the entire long word, - and set negative, zero, overflow and carry as appropriate. - */ - case Operation::MOVEb: - zero_result_ = destination()->halves.low.halves.low = source()->halves.low.halves.low; - negative_flag_ = zero_result_ & 0x80; - overflow_flag_ = carry_flag_ = 0; - break; - - case Operation::MOVEw: - zero_result_ = destination()->halves.low.full = source()->halves.low.full; - negative_flag_ = zero_result_ & 0x8000; - overflow_flag_ = carry_flag_ = 0; - break; - - case Operation::MOVEl: - zero_result_ = destination()->full = source()->full; - negative_flag_ = zero_result_ & 0x80000000; - overflow_flag_ = carry_flag_ = 0; - break; - - /* - MOVE.q: a single byte is moved from the current instruction, and sign extended. - */ - case Operation::MOVEq: - zero_result_ = destination()->full = prefetch_queue_.halves.high.halves.low; - negative_flag_ = zero_result_ & 0x80; - overflow_flag_ = carry_flag_ = 0; - destination()->full |= negative_flag_ ? 0xffffff00 : 0; - break; - - /* - MOVEA.l: move the entire long word; - MOVEA.w: move the least significant word and sign extend it. - Neither sets any flags. - */ - case Operation::MOVEAw: - destination()->halves.low.full = source()->halves.low.full; - destination()->halves.high.full = (destination()->halves.low.full & 0x8000) ? 0xffff : 0; - break; - - case Operation::MOVEAl: - destination()->full = source()->full; - break; - - case Operation::PEA: - destination_bus_data_ = effective_address_[0]; - break; - - /* - Status word moves and manipulations. - */ - - case Operation::MOVEtoSR: - apply_status(source()->full); - break; - - case Operation::MOVEfromSR: - destination()->halves.low.full = status(); - break; - - case Operation::MOVEtoCCR: - apply_ccr(source()->full); - break; - - case Operation::EXTbtow: - destination()->halves.low.halves.high = - (destination()->halves.low.halves.low & 0x80) ? 0xff : 0x00; - overflow_flag_ = carry_flag_ = 0; - zero_result_ = destination()->halves.low.full; - negative_flag_ = zero_result_ & 0x8000; - break; - - case Operation::EXTwtol: - destination()->halves.high.full = - (destination()->halves.low.full & 0x8000) ? 0xffff : 0x0000; - overflow_flag_ = carry_flag_ = 0; - zero_result_ = destination()->full; - negative_flag_ = zero_result_ & 0x80000000; - break; - -#define and_op(a, b) a &= b -#define or_op(a, b) a |= b -#define eor_op(a, b) a ^= b - -#define apply(op, func) {\ - auto status = status(); \ - op(status, prefetch_queue_.halves.high.full); \ - func(status); \ - program_counter_.full -= 2; \ -} - -#define apply_op_sr(op) apply(op, apply_status) -#define apply_op_ccr(op) apply(op, apply_ccr) - - case Operation::ANDItoSR: apply_op_sr(and_op); break; - case Operation::EORItoSR: apply_op_sr(eor_op); break; - case Operation::ORItoSR: apply_op_sr(or_op); break; - - case Operation::ANDItoCCR: apply_op_ccr(and_op); break; - case Operation::EORItoCCR: apply_op_ccr(eor_op); break; - case Operation::ORItoCCR: apply_op_ccr(or_op); break; - -#undef apply_op_ccr -#undef apply_op_sr -#undef apply -#undef eor_op -#undef or_op -#undef and_op - - /* - Multiplications. - */ - - case Operation::MULU: { - destination()->full = destination()->halves.low.full * source()->halves.low.full; - carry_flag_ = overflow_flag_ = 0; - zero_result_ = destination()->full; - negative_flag_ = zero_result_ & 0x80000000; - - int number_of_ones = source()->halves.low.full; - convert_to_bit_count_16(number_of_ones); - - // Time taken = 38 cycles + 2 cycles per 1 in the source. - set_next_microcycle_length(HalfCycles(4 * number_of_ones + 34*2)); - } break; - - case Operation::MULS: { - destination()->full = - u_extend16(destination()->halves.low.full) * u_extend16(source()->halves.low.full); - carry_flag_ = overflow_flag_ = 0; - zero_result_ = destination()->full; - negative_flag_ = zero_result_ & 0x80000000; - - // Find the number of 01 or 10 pairs in the 17-bit number - // formed by the source value with a 0 suffix. - int number_of_pairs = source()->halves.low.full; - number_of_pairs = (number_of_pairs ^ (number_of_pairs << 1)) & 0xffff; - convert_to_bit_count_16(number_of_pairs); - - // Time taken = 38 cycles + 2 cycles per 1 in the source. - set_next_microcycle_length(HalfCycles(4 * number_of_pairs + 34*2)); - } break; - - /* - Divisions. - */ - -#define announce_divide_by_zero() \ - negative_flag_ = overflow_flag_ = 0; \ - zero_result_ = 1; \ - active_program_ = nullptr; \ - active_micro_op_ = short_exception_micro_ops_; \ - bus_program = &all_bus_steps_[active_micro_op_->bus_program]; \ - \ - populate_trap_steps(5, status()); \ - bus_program->microcycle.length = HalfCycles(20); \ - \ - program_counter_.full -= 6; - - case Operation::DIVU: { - carry_flag_ = 0; - - // An attempt to divide by zero schedules an exception. - if(!source()->halves.low.full) { - // Schedule a divide-by-zero exception. - announce_divide_by_zero(); - break; - } - - uint32_t dividend = destination()->full; - uint32_t divisor = source()->halves.low.full; - const auto quotient = dividend / divisor; - - // If overflow would occur, appropriate flags are set and the result is not written back. - if(quotient > 65535) { - overflow_flag_ = zero_result_ = negative_flag_ = 1; - set_next_microcycle_length(HalfCycles(3*2*2)); - break; - } - - const uint16_t remainder = uint16_t(dividend % divisor); - destination()->halves.high.full = remainder; - destination()->halves.low.full = uint16_t(quotient); - - overflow_flag_ = 0; - zero_result_ = quotient; - negative_flag_ = zero_result_ & 0x8000; - - // Calculate cost; this is based on the flowchart in yacht.txt. - // I could actually calculate the division result here, since this is - // a classic divide algorithm, but would rather that errors produce - // incorrect timing only, not incorrect timing plus incorrect results. - int cycles_expended = 12; // Covers the nn n to get into the loop. - - divisor <<= 16; - for(int c = 0; c < 15; ++c) { - if(dividend & 0x80000000) { - dividend = (dividend << 1) - divisor; - cycles_expended += 4; // Easy; just the fixed nn iteration cost. - } else { - dividend <<= 1; - - // Yacht.txt, and indeed a real microprogram, would just subtract here - // and test the sign of the result, but this is easier to follow: - if (dividend >= divisor) { - dividend -= divisor; - cycles_expended += 6; // i.e. the original nn plus one further n before going down the MSB=0 route. - } else { - cycles_expended += 8; // The costliest path (since in real life it's a subtraction and then a step - // back from there) — all costs accrue. So the fixed nn loop plus another n, - // plus another one. - } - } - } - set_next_microcycle_length(HalfCycles(cycles_expended * 2)); - } break; - - case Operation::DIVS: { - carry_flag_ = 0; - - // An attempt to divide by zero schedules an exception. - if(!source()->halves.low.full) { - // Schedule a divide-by-zero exception. - announce_divide_by_zero() - break; - } - - const int32_t signed_dividend = int32_t(destination()->full); - const int32_t signed_divisor = s_extend16(source()->halves.low.full); - const auto result_sign = - ( (0 <= signed_dividend) - (signed_dividend < 0) ) * - ( (0 <= signed_divisor) - (signed_divisor < 0) ); - - const uint32_t dividend = uint32_t(abs(signed_dividend)); - const uint32_t divisor = uint32_t(abs(signed_divisor)); - - int cycles_expended = 12; // Covers the nn nnn n to get beyond the sign test. - if(signed_dividend < 0) { - cycles_expended += 2; // An additional microycle applies if the dividend is negative. - } - - // Check for overflow. If it exists, work here is already done. - const auto quotient = dividend / divisor; - if(quotient > 32767) { - overflow_flag_ = 1; - set_next_microcycle_length(HalfCycles(6*2*2)); - break; - } - - const uint16_t remainder = uint16_t(signed_dividend % signed_divisor); - const int signed_quotient = result_sign*int(quotient); - destination()->halves.high.full = remainder; - destination()->halves.low.full = uint16_t(signed_quotient); - - zero_result_ = decltype(zero_result_)(signed_quotient); - negative_flag_ = zero_result_ & 0x8000; - overflow_flag_ = 0; - - // Algorithm here: there is a fixed cost per unset bit - // in the first 15 bits of the unsigned quotient. - auto positive_quotient_bits = ~quotient & 0xfffe; - convert_to_bit_count_16(positive_quotient_bits); - cycles_expended += 2 * positive_quotient_bits; - - // There's then no way to terminate the loop that isn't at least ten cycles long; - // there's also a fixed overhead per bit. The two together add up to the 104 below. - cycles_expended += 104; - - // This picks up at 'No more bits' in yacht.txt's diagram. - if(signed_divisor < 0) { - cycles_expended += 2; - } else if(signed_dividend < 0) { - cycles_expended += 4; - } - set_next_microcycle_length(HalfCycles(cycles_expended * 2)); - } break; - -#undef announce_divide_by_zero - - /* - MOVEP: move words and long-words a byte at a time. - */ - - case Operation::MOVEPtoMw: - // Write pattern is nW+ nw, which should write the low word of the source in big-endian form. - destination_bus_data_.halves.high.full = source()->halves.low.halves.high; - destination_bus_data_.halves.low.full = source()->halves.low.halves.low; - break; - - case Operation::MOVEPtoMl: - // Write pattern is nW+ nWr+ nw+ nwr, which should write the source in big-endian form. - destination_bus_data_.halves.high.full = source()->halves.high.halves.high; - source_bus_data_.halves.high.full = source()->halves.high.halves.low; - destination_bus_data_.halves.low.full = source()->halves.low.halves.high; - source_bus_data_.halves.low.full = source()->halves.low.halves.low; - break; - - case Operation::MOVEPtoRw: - // Read pattern is nRd+ nrd. - source()->halves.low.halves.high = destination_bus_data_.halves.high.halves.low; - source()->halves.low.halves.low = destination_bus_data_.halves.low.halves.low; - break; - - case Operation::MOVEPtoRl: - // Read pattern is nRd+ nR+ nrd+ nr. - source()->halves.high.halves.high = destination_bus_data_.halves.high.halves.low; - source()->halves.high.halves.low = source_bus_data_.halves.high.halves.low; - source()->halves.low.halves.high = destination_bus_data_.halves.low.halves.low; - source()->halves.low.halves.low = source_bus_data_.halves.low.halves.low; - break; - - /* - MOVEM: multi-word moves. - */ - -#define setup_movem(words_per_reg, base) \ - /* Count the number of long words to move. */ \ - size_t total_to_move = 0; \ - auto mask = next_word_; \ - while(mask) { \ - total_to_move += mask&1; \ - mask >>= 1; \ - } \ - \ - /* Twice that many words plus one will need to be moved */ \ - bus_program = base + (64 - total_to_move*words_per_reg)*2; \ - \ - /* Fill in the proper addresses and targets. */ \ - const auto mode = (decoded_instruction_.full >> 3) & 7; \ - uint32_t start_address; \ - if(mode <= 4) { \ - start_address = destination_address().full; \ - } else { \ - start_address = effective_address_[1].full; \ - } \ - \ - auto step = bus_program; \ - uint32_t *address_storage = precomputed_addresses_; \ - mask = next_word_; \ - int offset = 0; - -#define inc_action(x, v) x += v -#define dec_action(x, v) x -= v - -#define write_address_sequence_long(action, l) \ - while(mask) { \ - if(mask&1) { \ - address_storage[0] = start_address; \ - action(start_address, 2); \ - address_storage[1] = start_address; \ - action(start_address, 2); \ - \ - step[0].microcycle.address = step[1].microcycle.address = address_storage; \ - step[2].microcycle.address = step[3].microcycle.address = address_storage + 1; \ - \ - const auto target = (offset > 7) ? &address_[offset&7] : &data_[offset]; \ - step[l].microcycle.value = step[l+1].microcycle.value = &target->halves.high; \ - step[(l^2)].microcycle.value = step[(l^2)+1].microcycle.value = &target->halves.low; \ - \ - address_storage += 2; \ - step += 4; \ - } \ - mask >>= 1; \ - action(offset, 1); \ - } - -#define write_address_sequence_word(action) \ - while(mask) { \ - if(mask&1) { \ - address_storage[0] = start_address; \ - action(start_address, 2); \ - \ - step[0].microcycle.address = step[1].microcycle.address = address_storage; \ - \ - const auto target = (offset > 7) ? &address_[offset&7] : &data_[offset]; \ - step[0].microcycle.value = step[1].microcycle.value = &target->halves.low; \ - \ - ++ address_storage; \ - step += 2; \ - } \ - mask >>= 1; \ - action(offset, 1); \ - } - - case Operation::MOVEMtoRl: { - setup_movem(2, movem_read_steps_); - - // Everything for move to registers is based on an incrementing - // address; per M68000PRM: - // - // "[If using the postincrement addressing mode then] the incremented address - // register contains the address of the last operand loaded plus the operand length. - // If the addressing register is also loaded from memory, the memory value is ignored - // and the register is written with the postincremented effective address." - // - // The latter part is dealt with by MicroOp::Action::MOVEMtoRComplete, which also - // does any necessary sign extension. - write_address_sequence_long(inc_action, 0); - - // MOVEM to R always reads one word too many. - address_storage[0] = start_address; - step[0].microcycle.address = step[1].microcycle.address = address_storage; - step[0].microcycle.value = step[1].microcycle.value = &throwaway_value_; - movem_final_address_ = start_address; - } break; - - case Operation::MOVEMtoRw: { - setup_movem(1, movem_read_steps_); - write_address_sequence_word(inc_action); - - // MOVEM to R always reads one word too many. - address_storage[0] = start_address; - step[0].microcycle.address = step[1].microcycle.address = address_storage; - step[0].microcycle.value = step[1].microcycle.value = &throwaway_value_; - movem_final_address_ = start_address; - } break; - - case Operation::MOVEMtoMl: { - setup_movem(2, movem_write_steps_); - - // MOVEM to M counts downwards and enumerates the registers in reverse order - // if subject to the predecrementing mode; otherwise it counts upwards and - // operates exactly as does MOVEM to R. - // - // Note also: "The MC68000 and MC68010 write the initial register value - // (not decremented) [when writing a register that is providing - // pre-decrementing addressing]." - // - // Hence the decrementing register (if any) is updated - // by MicroOp::Action::MOVEMtoMComplete. - if(mode == 4) { - offset = 15; - start_address -= 2; - write_address_sequence_long(dec_action, 2); - movem_final_address_ = start_address + 2; - } else { - write_address_sequence_long(inc_action, 0); - } - } break; - - case Operation::MOVEMtoMw: { - setup_movem(1, movem_write_steps_); - - if(mode == 4) { - offset = 15; - start_address -= 2; - write_address_sequence_word(dec_action); - movem_final_address_ = start_address + 2; - } else { - write_address_sequence_word(inc_action); - } - } break; - -#undef setup_movem -#undef write_address_sequence_long -#undef write_address_sequence_word -#undef inc_action -#undef dec_action - - // TRAP, which is a nicer form of ILLEGAL. - case Operation::TRAP: { - // Select the trap steps as next; the initial microcycle should be 4 cycles long. - bus_program = trap_steps_; - populate_trap_steps((decoded_instruction_.full & 15) + 32, status()); - set_next_microcycle_length(HalfCycles(12)); - - // The program counter to push is actually one slot ago. - program_counter_.full -= 2; - } break; - - case Operation::TRAPV: { - if(overflow_flag_) { - // Select the trap steps as next; the initial microcycle should be skipped. - bus_program = trap_steps_; - populate_trap_steps(7, status()); - set_next_microcycle_length(HalfCycles(4)); - - // Push the address after the TRAPV. - program_counter_.full -= 4; - } - } break; - - case Operation::CHK: { - const bool is_under = s_extend16(destination()->halves.low.full) < 0; - const bool is_over = s_extend16(destination()->halves.low.full) > s_extend16(source()->halves.low.full); - - overflow_flag_ = carry_flag_ = 0; - zero_result_ = destination()->halves.low.full; - - // Test applied for N: - // - // if Dn < 0, set negative flag; - // otherwise, if Dn > , reset negative flag. - if(is_over) negative_flag_ = 0; - if(is_under) negative_flag_ = 1; - - // No exception is the default course of action; deviate only if an - // exception is necessary. - if(is_under || is_over) { - bus_program = trap_steps_; - populate_trap_steps(6, status()); - if(is_over) { - set_next_microcycle_length(HalfCycles(20)); - } else { - set_next_microcycle_length(HalfCycles(24)); - } - - // The program counter to push is two slots ago as whatever was the correct prefetch - // to continue without an exception has already happened, just in case. - program_counter_.full -= 4; - } - } break; - - /* - NEGs: negatives the destination, setting the zero, - negative, overflow and carry flags appropriate, and extend. - - NB: since the same logic as SUB is used to calculate overflow, - and SUB calculates `destination - source`, the NEGs deliberately - label 'source' and 'destination' differently from Motorola. - */ - case Operation::NEGb: { - const int destination = 0; - const int source = destination()->halves.low.halves.low; - const auto result = destination - source; - destination()->halves.low.halves.low = uint8_t(result); - - zero_result_ = result & 0xff; - extend_flag_ = carry_flag_ = decltype(carry_flag_)(result & ~0xff); - negative_flag_ = result & 0x80; - overflow_flag_ = sub_overflow() & 0x80; - } break; - - case Operation::NEGw: { - const int destination = 0; - const int source = destination()->halves.low.full; - const auto result = destination - source; - destination()->halves.low.full = uint16_t(result); - - zero_result_ = result & 0xffff; - extend_flag_ = carry_flag_ = decltype(carry_flag_)(result & ~0xffff); - negative_flag_ = result & 0x8000; - overflow_flag_ = sub_overflow() & 0x8000; - } break; - - case Operation::NEGl: { - const uint64_t destination = 0; - const uint64_t source = destination()->full; - const auto result = destination - source; - destination()->full = uint32_t(result); - - zero_result_ = uint_fast32_t(result); - extend_flag_ = carry_flag_ = result >> 32; - negative_flag_ = result & 0x80000000; - overflow_flag_ = sub_overflow() & 0x80000000; - } break; - - /* - NEGXs: NEG, with extend. - */ - case Operation::NEGXb: { - const int source = destination()->halves.low.halves.low; - const int destination = 0; - const auto result = destination - source - (extend_flag_ ? 1 : 0); - destination()->halves.low.halves.low = uint8_t(result); - - zero_result_ |= result & 0xff; - extend_flag_ = carry_flag_ = decltype(carry_flag_)(result & ~0xff); - negative_flag_ = result & 0x80; - overflow_flag_ = sub_overflow() & 0x80; - } break; - - case Operation::NEGXw: { - const int source = destination()->halves.low.full; - const int destination = 0; - const auto result = destination - source - (extend_flag_ ? 1 : 0); - destination()->halves.low.full = uint16_t(result); - - zero_result_ |= result & 0xffff; - extend_flag_ = carry_flag_ = decltype(carry_flag_)(result & ~0xffff); - negative_flag_ = result & 0x8000; - overflow_flag_ = sub_overflow() & 0x8000; - } break; - - case Operation::NEGXl: { - const uint64_t source = destination()->full; - const uint64_t destination = 0; - const auto result = destination - source - (extend_flag_ ? 1 : 0); - destination()->full = uint32_t(result); - - zero_result_ |= uint_fast32_t(result); - extend_flag_ = carry_flag_ = result >> 32; - negative_flag_ = result & 0x80000000; - overflow_flag_ = sub_overflow() & 0x80000000; - } break; - - /* - The no-op. - */ - case Operation::None: - break; - - /* - LINK and UNLINK help with stack frames, allowing a certain - amount of stack space to be allocated or deallocated. - */ - - case Operation::LINK: - // Make space for the new long-word value, and set up - // the proper target address for the stack operations to follow. - address_[7].full -= 4; - effective_address_[1].full = address_[7].full; - - // The current value of the address register will be pushed. - destination_bus_data_.full = source()->full; - - // The address register will then contain the bottom of the stack, - // and the stack pointer will be offset. - source()->full = address_[7].full; - address_[7].full += u_extend16(prefetch_queue_.halves.low.full); - break; - - case Operation::UNLINK: - address_[7].full = effective_address_[1].full + 2; - destination()->full = destination_bus_data_.full; - break; - - /* - TAS: sets zero and negative depending on the current value of the destination, - and sets the high bit. - */ - - case Operation::TAS: - overflow_flag_ = carry_flag_ = 0; - zero_result_ = destination()->halves.low.halves.low; - negative_flag_ = destination()->halves.low.halves.low & 0x80; - destination()->halves.low.halves.low |= 0x80; - break; - - /* - Bitwise operators: AND, OR and EOR. All three clear the overflow and carry flags, - and set zero and negative appropriately. - */ -#define op_and(x, y) x &= y -#define op_or(x, y) x |= y -#define op_eor(x, y) x ^= y - -#define bitwise(source, dest, sign_mask, operator) \ - operator(dest, source); \ - overflow_flag_ = carry_flag_ = 0; \ - zero_result_ = dest; \ - negative_flag_ = dest & sign_mask; - -#define andx(source, dest, sign_mask) bitwise(source, dest, sign_mask, op_and) -#define eorx(source, dest, sign_mask) bitwise(source, dest, sign_mask, op_eor) -#define orx(source, dest, sign_mask) bitwise(source, dest, sign_mask, op_or) - -#define op_bwl(name, op) \ - case Operation::name##b: op(source()->halves.low.halves.low, destination()->halves.low.halves.low, 0x80); break; \ - case Operation::name##w: op(source()->halves.low.full, destination()->halves.low.full, 0x8000); break; \ - case Operation::name##l: op(source()->full, destination()->full, 0x80000000); break; - - op_bwl(AND, andx); - op_bwl(EOR, eorx); - op_bwl(OR, orx); - -#undef op_bwl -#undef orx -#undef eorx -#undef andx -#undef bitwise -#undef op_eor -#undef op_or -#undef op_and - - // NOTs: take the logical inverse, affecting the negative and zero flags. - case Operation::NOTb: - destination()->halves.low.halves.low ^= 0xff; - zero_result_ = destination()->halves.low.halves.low; - negative_flag_ = zero_result_ & 0x80; - overflow_flag_ = carry_flag_ = 0; - break; - - case Operation::NOTw: - destination()->halves.low.full ^= 0xffff; - zero_result_ = destination()->halves.low.full; - negative_flag_ = zero_result_ & 0x8000; - overflow_flag_ = carry_flag_ = 0; - break; - - case Operation::NOTl: - destination()->full ^= 0xffffffff; - zero_result_ = destination()->full; - negative_flag_ = zero_result_ & 0x80000000; - overflow_flag_ = carry_flag_ = 0; - break; - -#define sbcd() \ - /* Perform the BCD arithmetic by evaluating the two nibbles separately. */ \ - const int unadjusted_result = destination - source - (extend_flag_ ? 1 : 0); \ - int result = (destination & 0xf) - (source & 0xf) - (extend_flag_ ? 1 : 0); \ - if((result & 0x1f) > 0x09) result -= 0x06; \ - result += (destination & 0xf0) - (source & 0xf0); \ - extend_flag_ = carry_flag_ = decltype(carry_flag_)((result & 0x1ff) > 0x99); \ - if(carry_flag_) result -= 0x60; \ - \ - /* Set all flags essentially as if this were normal subtraction. */ \ - zero_result_ |= result & 0xff; \ - negative_flag_ = result & 0x80; \ - overflow_flag_ = unadjusted_result & ~result & 0x80; \ - \ - /* Store the result. */ \ - destination()->halves.low.halves.low = uint8_t(result); - - /* - SBCD subtracts the lowest byte of the source from that of the destination using - BCD arithmetic, obeying the extend flag. - */ - case Operation::SBCD: { - const uint8_t source = source()->halves.low.halves.low; - const uint8_t destination = destination()->halves.low.halves.low; - sbcd(); - } break; - - /* - NBCD is like SBCD except that the result is 0 - destination rather than - destination - source. - */ - case Operation::NBCD: { - const uint8_t source = destination()->halves.low.halves.low; - const uint8_t destination = 0; - sbcd(); - } break; - - // EXG and SWAP exchange/swap words or long words. - - case Operation::EXG: { - const auto temporary = source()->full; - source()->full = destination()->full; - destination()->full = temporary; - } break; - - case Operation::SWAP: { - const auto temporary = destination()->halves.low.full; - destination()->halves.low.full = destination()->halves.high.full; - destination()->halves.high.full = temporary; - - zero_result_ = destination()->full; - negative_flag_ = temporary & 0x8000; - overflow_flag_ = carry_flag_ = 0; - } break; - -#undef sbcd - - /* - Shifts and rotates. - */ -#define set_neg_zero(v, m) \ - zero_result_ = decltype(zero_result_)(v); \ - negative_flag_ = zero_result_ & decltype(negative_flag_)(m); - -#define set_neg_zero_overflow(v, m) \ - set_neg_zero(v, m); \ - overflow_flag_ = (decltype(zero_result_)(value) ^ zero_result_) & decltype(overflow_flag_)(m); - -#define decode_shift_count() \ - int shift_count = (decoded_instruction_.full & 32) ? data_[(decoded_instruction_.full >> 9) & 7].full&63 : ( ((decoded_instruction_.full >> 9)&7) ? ((decoded_instruction_.full >> 9)&7) : 8) ; \ - set_next_microcycle_length(HalfCycles(4 * shift_count)); - -#define set_flags_b(t) set_flags(destination()->halves.low.halves.low, 0x80, t) -#define set_flags_w(t) set_flags(destination()->halves.low.full, 0x8000, t) -#define set_flags_l(t) set_flags(destination()->full, 0x80000000, t) - -#define asl(destination, size) {\ - decode_shift_count(); \ - const auto value = destination; \ -\ - if(!shift_count) { \ - carry_flag_ = overflow_flag_ = 0; \ - } else { \ - destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0; \ - extend_flag_ = carry_flag_ = decltype(carry_flag_)(value) & decltype(carry_flag_)( (1u << (size - 1)) >> (shift_count - 1) ); \ - \ - if(shift_count >= size) overflow_flag_ = value && (value != decltype(value)(-1)); \ - else { \ - const auto mask = decltype(destination)(0xffffffff << (size - shift_count)); \ - overflow_flag_ = mask & value && ((mask & value) != mask); \ - } \ - } \ -\ - set_neg_zero(destination, 1 << (size - 1)); \ -} - - case Operation::ASLm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = uint16_t(value << 1); - extend_flag_ = carry_flag_ = value & 0x8000; - set_neg_zero_overflow(destination()->halves.low.full, 0x8000); - } break; - case Operation::ASLb: asl(destination()->halves.low.halves.low, 8); break; - case Operation::ASLw: asl(destination()->halves.low.full, 16); break; - case Operation::ASLl: asl(destination()->full, 32); break; - - - -#define asr(destination, size) {\ - decode_shift_count(); \ - const auto value = destination; \ -\ - if(!shift_count) { \ - carry_flag_ = 0; \ - } else { \ - destination = (shift_count < size) ? \ - decltype(destination)(\ - (value >> shift_count) | \ - ((value & decltype(value)(1 << (size - 1)) ? 0xffffffff : 0x000000000) << (size - shift_count)) \ - ) : \ - decltype(destination)( \ - (value & decltype(value)(1 << (size - 1))) ? 0xffffffff : 0x000000000 \ - ); \ - extend_flag_ = carry_flag_ = decltype(carry_flag_)(value) & decltype(carry_flag_)(1 << (shift_count - 1)); \ - } \ -\ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ -} - - case Operation::ASRm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = (value&0x8000) | (value >> 1); - extend_flag_ = carry_flag_ = value & 1; - set_neg_zero_overflow(destination()->halves.low.full, 0x8000); - } break; - case Operation::ASRb: asr(destination()->halves.low.halves.low, 8); break; - case Operation::ASRw: asr(destination()->halves.low.full, 16); break; - case Operation::ASRl: asr(destination()->full, 32); break; - - -#undef set_neg_zero_overflow -#define set_neg_zero_overflow(v, m) \ - set_neg_zero(v, m); \ - overflow_flag_ = 0; - -#undef set_flags -#define set_flags(v, m, t) \ - zero_result_ = v; \ - negative_flag_ = zero_result_ & (m); \ - overflow_flag_ = 0; \ - carry_flag_ = value & (t); - -#define lsl(destination, size) {\ - decode_shift_count(); \ - const auto value = destination; \ -\ - if(!shift_count) { \ - carry_flag_ = 0; \ - } else { \ - destination = (shift_count < size) ? decltype(destination)(value << shift_count) : 0; \ - extend_flag_ = carry_flag_ = decltype(carry_flag_)(value) & decltype(carry_flag_)( (1u << (size - 1)) >> (shift_count - 1) ); \ - } \ -\ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ -} - - case Operation::LSLm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = uint16_t(value << 1); - extend_flag_ = carry_flag_ = value & 0x8000; - set_neg_zero_overflow(destination()->halves.low.full, 0x8000); - } break; - case Operation::LSLb: lsl(destination()->halves.low.halves.low, 8); break; - case Operation::LSLw: lsl(destination()->halves.low.full, 16); break; - case Operation::LSLl: lsl(destination()->full, 32); break; - -#define lsr(destination, size) {\ - decode_shift_count(); \ - const auto value = destination; \ -\ - if(!shift_count) { \ - carry_flag_ = 0; \ - } else { \ - destination = (shift_count < size) ? (value >> shift_count) : 0; \ - extend_flag_ = carry_flag_ = value & decltype(carry_flag_)(1 << (shift_count - 1)); \ - } \ -\ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ -} - - case Operation::LSRm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = value >> 1; - extend_flag_ = carry_flag_ = value & 1; - set_neg_zero_overflow(destination()->halves.low.full, 0x8000); - } break; - case Operation::LSRb: lsr(destination()->halves.low.halves.low, 8); break; - case Operation::LSRw: lsr(destination()->halves.low.full, 16); break; - case Operation::LSRl: lsr(destination()->full, 32); break; - -#define rol(destination, size) { \ - decode_shift_count(); \ - const auto value = destination; \ - \ - if(!shift_count) { \ - carry_flag_ = 0; \ - } else { \ - shift_count &= (size - 1); \ - destination = decltype(destination)( \ - (value << shift_count) | \ - (value >> (size - shift_count)) \ - ); \ - carry_flag_ = decltype(carry_flag_)(destination & 1); \ - } \ - \ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ - } - - case Operation::ROLm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = uint16_t((value << 1) | (value >> 15)); - carry_flag_ = destination()->halves.low.full & 1; - set_neg_zero_overflow(destination()->halves.low.full, 0x8000); - } break; - case Operation::ROLb: rol(destination()->halves.low.halves.low, 8); break; - case Operation::ROLw: rol(destination()->halves.low.full, 16); break; - case Operation::ROLl: rol(destination()->full, 32); break; - - -#define ror(destination, size) { \ - decode_shift_count(); \ - const auto value = destination; \ - \ - if(!shift_count) { \ - carry_flag_ = 0; \ - } else { \ - shift_count &= (size - 1); \ - destination = decltype(destination)(\ - (value >> shift_count) | \ - (value << (size - shift_count)) \ - );\ - carry_flag_ = destination & decltype(carry_flag_)(1 << (size - 1)); \ - } \ - \ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ - } - - case Operation::RORm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = uint16_t((value >> 1) | (value << 15)); - carry_flag_ = destination()->halves.low.full & 0x8000; - set_neg_zero_overflow(destination()->halves.low.full, 0x8000); - } break; - case Operation::RORb: ror(destination()->halves.low.halves.low, 8); break; - case Operation::RORw: ror(destination()->halves.low.full, 16); break; - case Operation::RORl: ror(destination()->full, 32); break; - -#define roxl(destination, size) { \ - decode_shift_count(); \ -\ - shift_count %= (size + 1); \ - uint64_t compound = uint64_t(destination) | (extend_flag_ ? (1ull << size) : 0); \ - compound = \ - (compound << shift_count) | \ - (compound >> (size + 1 - shift_count)); \ - carry_flag_ = extend_flag_ = decltype(carry_flag_)((compound >> size) & 1); \ - destination = decltype(destination)(compound); \ - \ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ -} - - - case Operation::ROXLm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = uint16_t((value << 1) | (extend_flag_ ? 0x0001 : 0x0000)); - extend_flag_ = value & 0x8000; - set_flags_w(0x8000); - } break; - case Operation::ROXLb: roxl(destination()->halves.low.halves.low, 8); break; - case Operation::ROXLw: roxl(destination()->halves.low.full, 16); break; - case Operation::ROXLl: roxl(destination()->full, 32); break; - -#define roxr(destination, size) { \ - decode_shift_count(); \ -\ - shift_count %= (size + 1); \ - uint64_t compound = uint64_t(destination) | (extend_flag_ ? (1ull << size) : 0); \ - compound = \ - (compound >> shift_count) | \ - (compound << (size + 1 - shift_count)); \ - carry_flag_ = extend_flag_ = decltype(carry_flag_)((compound >> size) & 1); \ - destination = decltype(destination)(compound); \ - \ - set_neg_zero_overflow(destination, 1 << (size - 1)); \ -} - - case Operation::ROXRm: { - const auto value = destination()->halves.low.full; - destination()->halves.low.full = (value >> 1) | (extend_flag_ ? 0x8000 : 0x0000); - extend_flag_ = value & 0x0001; - set_flags_w(0x0001); - } break; - case Operation::ROXRb: roxr(destination()->halves.low.halves.low, 8); break; - case Operation::ROXRw: roxr(destination()->halves.low.full, 16); break; - case Operation::ROXRl: roxr(destination()->full, 32); break; - -#undef roxr -#undef roxl -#undef ror -#undef rol -#undef asr -#undef lsr -#undef lsl -#undef asl - -#undef set_flagsx -#undef decode_shift_count -#undef set_flags_b -#undef set_flags_w -#undef set_flags_l -#undef set_neg_zero_overflow -#undef set_neg_zero - - /* - RTE and RTR share an implementation. - */ - case Operation::RTE_RTR: - // If this is RTR, patch out the supervisor half of the status register. - if(decoded_instruction_.full == 0x4e77) { - const auto current_status = status(); - source_bus_data_.halves.low.halves.high = - uint8_t(current_status >> 8); - } - apply_status(source_bus_data_.full); - break; - - /* - TSTs: compare to zero. - */ - - case Operation::TSTb: - carry_flag_ = overflow_flag_ = 0; - zero_result_ = source()->halves.low.halves.low; - negative_flag_ = zero_result_ & 0x80; - break; - - case Operation::TSTw: - carry_flag_ = overflow_flag_ = 0; - zero_result_ = source()->halves.low.full; - negative_flag_ = zero_result_ & 0x8000; - break; - - case Operation::TSTl: - carry_flag_ = overflow_flag_ = 0; - zero_result_ = source()->full; - negative_flag_ = zero_result_ & 0x80000000; - break; - - case Operation::STOP: - apply_status(prefetch_queue_.halves.low.full); - execution_state_ = ExecutionState::Stopped; - break; - - /* - Development period debugging. - */ - default: - std::cerr << "Should do something with program operation " << int(active_program_->operation) << std::endl; - break; - } -#undef sub_overflow -#undef add_overflow - break; - - case int_type(MicroOp::Action::MOVEMtoRComplete): { - // If this was a word-sized move, perform sign extension. - if(active_program_->operation == Operation::MOVEMtoRw) { - auto mask = next_word_; - int offset = 0; - while(mask) { - if(mask&1) { - const auto target = (offset > 7) ? &address_[offset&7] : &data_[offset]; - target->halves.high.full = (target->halves.low.full & 0x8000) ? 0xffff : 0x0000; - } - mask >>= 1; - ++offset; - } - } - - // If the post-increment mode was used, overwrite the source register. - const auto mode = (decoded_instruction_.full >> 3) & 7; - if(mode == 3) { - const auto reg = decoded_instruction_.full & 7; - address_[reg] = movem_final_address_; - } - } break; - - case int_type(MicroOp::Action::MOVEMtoMComplete): { - const auto mode = (decoded_instruction_.full >> 3) & 7; - if(mode == 4) { - const auto reg = decoded_instruction_.full & 7; - address_[reg] = movem_final_address_; - } - } break; - - case int_type(MicroOp::Action::PrepareJSR): { - const auto mode = (decoded_instruction_.full >> 3) & 7; - // Determine the proper resumption address. - switch(mode) { - case 2: destination_bus_data_.full = program_counter_.full - 2; break; /* (An) */ - default: - destination_bus_data_.full = program_counter_.full; /* Everything other than (An) */ - break; - } - address_[7].full -= 4; - effective_address_[1].full = address_[7].full; - } break; - - case int_type(MicroOp::Action::PrepareBSR): - destination_bus_data_.full = (decoded_instruction_.full & 0xff) ? program_counter_.full - 2 : program_counter_.full; - address_[7].full -= 4; - effective_address_[1].full = address_[7].full; - break; - - case int_type(MicroOp::Action::PrepareRTS): - effective_address_[0].full = address_[7].full; - address_[7].full += 4; - break; - - case int_type(MicroOp::Action::PrepareRTE_RTR): - precomputed_addresses_[0] = address_[7].full + 2; - precomputed_addresses_[1] = address_[7].full; - precomputed_addresses_[2] = address_[7].full + 4; - address_[7].full += 6; - break; - - case int_type(MicroOp::Action::PrepareINT): - // The INT sequence uses the same storage as the TRAP steps, so this'll get - // the necessary stack work set up. - populate_trap_steps(0, status()); - - // Mutate neessary internal state — effective_address_[0] is exposed - // on the data bus as the accepted interrupt number during the interrupt - // acknowledge cycle, with all other bits set, including the low bit as - // a real 68000 uses the lower data strobe to collect the corresponding vector byte. - // - // Cf. M68000 8-/16-/32-BIT MICROPROCESSORS USER'S MANUAL 5.1.4. - accepted_interrupt_level_ = interrupt_level_ = pending_interrupt_level_; - pending_interrupt_level_ = 0; - effective_address_[0].full = 0xfffffff1 | uint32_t(accepted_interrupt_level_ << 1); - - // Recede the program counter to where it would have been were there no - // prefetch; that's where the reading stream should pick up upon RTE. - program_counter_.full -= 4; - break; - - case int_type(MicroOp::Action::PrepareINTVector): - // Let bus error go back to causing exceptions. - is_starting_interrupt_ = false; - - // Bus error => spurious interrupt. - if(bus_error_) { - effective_address_[0].full = 24 << 2; - break; - } - - // Valid peripheral address => autovectored interrupt. - if(is_peripheral_address_) { - effective_address_[0].full = uint32_t(24 + accepted_interrupt_level_) << 2; - break; - } - - // Otherwise, the vector is whatever we were just told it is. - effective_address_[0].full = uint32_t(source_bus_data_.halves.low.halves.low << 2); - -// printf("Interrupt vector: %06x\n", effective_address_[0].full); - break; - - case int_type(MicroOp::Action::CopyNextWord): - next_word_ = prefetch_queue_.halves.low.full; - break; - - // Increments and decrements. -#define op_add(x, y) x += y -#define op_sub(x, y) x -= y -#define Adjust(op, quantity, effect) \ - case int_type(op) | MicroOp::SourceMask: effect(source_address().full, quantity); break; \ - case int_type(op) | MicroOp::DestinationMask: effect(destination_address().full, quantity); break; \ - case int_type(op) | MicroOp::SourceMask | MicroOp::DestinationMask: \ - effect(destination_address().full, quantity); \ - effect(source_address().full, quantity); \ - break; - - Adjust(MicroOp::Action::Decrement1, 1, op_sub); - Adjust(MicroOp::Action::Decrement2, 2, op_sub); - Adjust(MicroOp::Action::Decrement4, 4, op_sub); - Adjust(MicroOp::Action::Increment1, 1, op_add); - Adjust(MicroOp::Action::Increment2, 2, op_add); - Adjust(MicroOp::Action::Increment4, 4, op_add); - -#undef Adjust -#undef op_add -#undef op_sub - - case int_type(MicroOp::Action::SignExtendWord): - if(active_micro_op_->action & MicroOp::SourceMask) { - source()->halves.high.full = - (source()->halves.low.full & 0x8000) ? 0xffff : 0x0000; - } - if(active_micro_op_->action & MicroOp::DestinationMask) { - destination()->halves.high.full = - (destination()->halves.low.full & 0x8000) ? 0xffff : 0x0000; - } - break; - - case int_type(MicroOp::Action::SignExtendByte): - if(active_micro_op_->action & MicroOp::SourceMask) { - source()->full = (source()->full & 0xff) | - (source()->full & 0x80) ? 0xffffff : 0x000000; - } - if(active_micro_op_->action & MicroOp::DestinationMask) { - destination()->full = (destination()->full & 0xff) | - (destination()->full & 0x80) ? 0xffffff : 0x000000; - } - break; - - // 16-bit offset addressing modes. - - case int_type(MicroOp::Action::CalcD16PC) | MicroOp::SourceMask: - // The address the low part of the prefetch queue was read from was two bytes ago, hence - // the subtraction of 2. - effective_address_[0] = u_extend16(prefetch_queue_.halves.low.full) + program_counter_.full - 2; - break; - - case int_type(MicroOp::Action::CalcD16PC) | MicroOp::DestinationMask: - effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + program_counter_.full - 2; - break; - - case int_type(MicroOp::Action::CalcD16PC) | MicroOp::SourceMask | MicroOp::DestinationMask: - // Similar logic applies here to above, but the high part of the prefetch queue was four bytes - // ago rather than merely two. - effective_address_[0] = u_extend16(prefetch_queue_.halves.high.full) + program_counter_.full - 4; - effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + program_counter_.full - 2; - break; - - case int_type(MicroOp::Action::CalcD16An) | MicroOp::SourceMask: - effective_address_[0] = u_extend16(prefetch_queue_.halves.low.full) + source_address().full; - break; - - case int_type(MicroOp::Action::CalcD16An) | MicroOp::DestinationMask: - effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + destination_address().full; - break; - - case int_type(MicroOp::Action::CalcD16An) | MicroOp::SourceMask | MicroOp::DestinationMask: - effective_address_[0] = u_extend16(prefetch_queue_.halves.high.full) + source_address().full; - effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full) + destination_address().full; - break; - -#define CalculateD8AnXn(data, source, target) {\ - const auto register_index = (data.full >> 12) & 7; \ - const RegisterPair32 &displacement = (data.full & 0x8000) ? address_[register_index] : data_[register_index]; \ - target.full = u_extend8(data.halves.low) + source; \ -\ - if(data.full & 0x800) { \ - target.full += displacement.full; \ - } else { \ - target.full += u_extend16(displacement.halves.low.full); \ - } \ -} - case int_type(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask: { - CalculateD8AnXn(prefetch_queue_.halves.low, source_address().full, effective_address_[0]); - } break; - - case int_type(MicroOp::Action::CalcD8AnXn) | MicroOp::DestinationMask: { - CalculateD8AnXn(prefetch_queue_.halves.low, destination_address().full, effective_address_[1]); - } break; - - case int_type(MicroOp::Action::CalcD8AnXn) | MicroOp::SourceMask | MicroOp::DestinationMask: { - CalculateD8AnXn(prefetch_queue_.halves.high, source_address().full, effective_address_[0]); - CalculateD8AnXn(prefetch_queue_.halves.low, destination_address().full, effective_address_[1]); - } break; - - case int_type(MicroOp::Action::CalcD8PCXn) | MicroOp::SourceMask: { - CalculateD8AnXn(prefetch_queue_.halves.low, program_counter_.full - 2, effective_address_[0]); - } break; - - case int_type(MicroOp::Action::CalcD8PCXn) | MicroOp::DestinationMask: { - CalculateD8AnXn(prefetch_queue_.halves.low, program_counter_.full - 2, effective_address_[1]); - } break; - - case int_type(MicroOp::Action::CalcD8PCXn) | MicroOp::SourceMask | MicroOp::DestinationMask: { - CalculateD8AnXn(prefetch_queue_.halves.high, program_counter_.full - 4, effective_address_[0]); - CalculateD8AnXn(prefetch_queue_.halves.low, program_counter_.full - 2, effective_address_[1]); - } break; - -#undef CalculateD8AnXn - - case int_type(MicroOp::Action::AssembleWordAddressFromPrefetch) | MicroOp::SourceMask: - effective_address_[0] = u_extend16(prefetch_queue_.halves.low.full); - break; - - case int_type(MicroOp::Action::AssembleWordAddressFromPrefetch) | MicroOp::DestinationMask: - effective_address_[1] = u_extend16(prefetch_queue_.halves.low.full); - break; - - case int_type(MicroOp::Action::AssembleLongWordAddressFromPrefetch) | MicroOp::SourceMask: - effective_address_[0] = prefetch_queue_.full; - break; - - case int_type(MicroOp::Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask: - effective_address_[1] = prefetch_queue_.full; - break; - - case int_type(MicroOp::Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask: - source_bus_data_ = prefetch_queue_.halves.low.full; - break; - - case int_type(MicroOp::Action::AssembleWordDataFromPrefetch) | MicroOp::DestinationMask: - destination_bus_data_ = prefetch_queue_.halves.low.full; - break; - - case int_type(MicroOp::Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask: - source_bus_data_ = prefetch_queue_.full; - break; - - case int_type(MicroOp::Action::AssembleLongWordDataFromPrefetch) | MicroOp::DestinationMask: - destination_bus_data_ = prefetch_queue_.full; - break; - - case int_type(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::SourceMask: - effective_address_[0] = source_address(); - break; - - case int_type(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::DestinationMask: - effective_address_[1] = destination_address(); - break; - - case int_type(MicroOp::Action::CopyToEffectiveAddress) | MicroOp::SourceMask | MicroOp::DestinationMask: - effective_address_[0] = source_address(); - effective_address_[1] = destination_address(); - break; - } - - // If we've got to a micro-op that includes bus steps, break out of this loop. - if(!active_micro_op_->is_terminal()) { - active_step_ = bus_program; - if(!active_step_->is_terminal()) - break; - } - } - } - } - -#undef source -#undef source_address -#undef destination -#undef destination_address - - e_clock_phase_ = (e_clock_phase_ + cycles_run_for) % 20; - half_cycles_left_to_run_ = remaining_duration - cycles_run_for; -} - -template ProcessorState Processor::get_state() { - write_back_stack_pointer(); - - State state; - memcpy(state.data, data_, sizeof(state.data)); - memcpy(state.address, address_, sizeof(state.address)); - state.user_stack_pointer = stack_pointers_[0].full; - state.supervisor_stack_pointer = stack_pointers_[1].full; - state.program_counter = program_counter_.full; - - state.status = status(); - - return state; -} - -template void Processor::set_state(const ProcessorState &state) { - memcpy(data_, state.data, sizeof(state.data)); - memcpy(address_, state.address, sizeof(state.address)); - - apply_status(state.status); - - stack_pointers_[0].full = state.user_stack_pointer; - stack_pointers_[1].full = state.supervisor_stack_pointer; - address_[7] = stack_pointers_[is_supervisor_]; -} - -uint16_t ProcessorStorage::get_status() const { - return status(); -} - -void ProcessorStorage::set_status(uint16_t status) { - apply_status(status); -} - -template void Processor::reset() { - execution_state_ = ExecutionState::Executing; - active_step_ = reset_bus_steps_; - effective_address_[0] = 0; - is_supervisor_ = 1; - interrupt_level_ = 7; - half_cycles_left_to_run_ = HalfCycles(0); -} - -#undef status -#undef apply_status -#undef apply_ccr -#undef ccr -#undef u_extend16 -#undef u_extend8 -#undef s_extend16 -#undef s_extend8 -#undef set_next_microcycle_length -#undef convert_to_bit_count_16 - diff --git a/Processors/68000/Implementation/68000Storage.cpp b/Processors/68000/Implementation/68000Storage.cpp deleted file mode 100644 index 4c6c9a969..000000000 --- a/Processors/68000/Implementation/68000Storage.cpp +++ /dev/null @@ -1,3352 +0,0 @@ -// -// 68000Storage.cpp -// Clock Signal -// -// Created by Thomas Harte on 08/03/2019. -// Copyright © 2019 Thomas Harte. All rights reserved. -// - -#include "../68000.hpp" - -#include -#include -#include -#include -#include -#include - -namespace CPU { -namespace MC68000 { - -#define Dn 0x00 -#define An 0x01 -#define Ind 0x02 -#define PostInc 0x03 -#define PreDec 0x04 -#define d16An 0x05 -#define d8AnXn 0x06 -#define XXXw 0x10 -#define XXXl 0x11 -#define d16PC 0x12 -#define d8PCXn 0x13 -#define Imm 0x14 - -struct ProcessorStorageConstructor { - ProcessorStorageConstructor(ProcessorStorage &storage) : storage_(storage) {} - - using BusStep = ProcessorStorage::BusStep; - - /*! - */ - int calc_action_for_mode(int mode) const { - using Action = ProcessorBase::MicroOp::Action; - switch(mode & 0xff) { - default: assert(false); - case d16PC: return int(Action::CalcD16PC); - case d8PCXn: return int(Action::CalcD8PCXn); - case d16An: return int(Action::CalcD16An); - case d8AnXn: return int(Action::CalcD8AnXn); - } - } - - int address_assemble_for_mode(int mode) const { - using Action = ProcessorBase::MicroOp::Action; - assert((mode & 0xff) == XXXw || (mode & 0xff) == XXXl); - return int(((mode & 0xff) == XXXw) ? Action::AssembleWordAddressFromPrefetch : Action::AssembleLongWordAddressFromPrefetch); - } - - int address_action_for_mode(int mode) const { - using Action = ProcessorBase::MicroOp::Action; - switch(mode & 0xff) { - default: assert(false); - case d16PC: return int(Action::CalcD16PC); - case d8PCXn: return int(Action::CalcD8PCXn); - case d16An: return int(Action::CalcD16An); - case d8AnXn: return int(Action::CalcD8AnXn); - case XXXw: return int(Action::AssembleWordAddressFromPrefetch); - case XXXl: return int(Action::AssembleLongWordAddressFromPrefetch); - } - } - - int combined_mode(int mode, int reg, bool collapse_an_dn = false, bool collapse_postinc = false) { - if(collapse_an_dn && mode == An) mode = Dn; - if(collapse_postinc && mode == PostInc) mode = Ind; - return (mode == 7) ? (0x10 | reg) : mode; - } - - int data_assemble_for_mode(int mode) const { - using Action = ProcessorBase::MicroOp::Action; - assert((mode & 0xff) == XXXw || (mode & 0xff) == XXXl); - return int(((mode & 0xff) == XXXw) ? Action::AssembleWordDataFromPrefetch : Action::AssembleLongWordDataFromPrefetch); - } - - int byte_inc(int reg) const { - using Action = ProcessorBase::MicroOp::Action; - // Special case: stack pointer byte accesses adjust by two. - return int((reg == 7) ? Action::Increment2 : Action::Increment1); - } - - int byte_dec(int reg) const { - using Action = ProcessorBase::MicroOp::Action; - // Special case: stack pointer byte accesses adjust by two. - return int((reg == 7) ? Action::Decrement2 : Action::Decrement1); - } - - int increment_action(bool is_long_word_access, bool is_byte_access, int reg) const { - using Action = ProcessorBase::MicroOp::Action; - if(is_long_word_access) return int(Action::Increment4); - if(is_byte_access) return byte_inc(reg); - return int(Action::Increment2); - } - - int decrement_action(bool is_long_word_access, bool is_byte_access, int reg) const { - using Action = ProcessorBase::MicroOp::Action; - if(is_long_word_access) return int(Action::Decrement4); - if(is_byte_access) return byte_dec(reg); - return int(Action::Decrement2); - } - -#define pseq(x, m) ((((m)&0xff) == d8AnXn) || (((m)&0xff) == d8PCXn) ? "n " x : x) - - /*! - Installs BusSteps that implement the described program into the relevant - instance storage, returning the offset within @c all_bus_steps_ at which - the generated steps begin. - - @param access_pattern A string describing the bus activity that occurs - during this program. This should follow the same general pattern as - those in yacht.txt; full description below. - - @param addresses A vector of the addresses to place on the bus coincident - with those acess steps that require them. - - @param read_full_words @c true to indicate that read and write operations are - selecting a full word; @c false to signal byte accesses only. - - @discussion - The access pattern is defined to correlate closely to that in yacht.txt; it is - a space-separated sequence of the following actions: - - * n: no operation for four cycles; data bus is not used; - * nn: no operation for eight cycles; data bus is not used; - * r: a 'replaceable'-length no operation; data bus is not used and no guarantees are - made about the length of the cycle other than that when it reaches the interpreter, - it is safe to alter the length and leave it altered; - * np: program fetch; reads from the PC and adds two to it, advancing the prefetch queue; - * nW: write MSW of something onto the bus; - * nw: write LSW of something onto the bus; - * nR: read MSW of something from the bus into the source latch; - * nr: read LSW of soemthing from the bus into the source latch; - * nRd: read MSW of something from the bus into the destination latch; - * nrd: read LSW of soemthing from the bus into the destination latch; - * nS: push the MSW of something onto the stack **and then** decrement the pointer; - * ns: push the LSW of something onto the stack **and then** decrement the pointer; - * nU: pop the MSW of something from the stack; - * nu: pop the LSW of something from the stack; - * nV: fetch a vector's MSW; - * nv: fetch a vector's LSW; - * i: acquire interrupt vector in an IACK cycle; - * nF: fetch the current SPs MSW; - * nf: fetch the current SP's LSW; - * _: hold the reset line active for the usual period. - * tas: perform the final 6 cycles of a TAS: like an n nw but with the address strobe active for the entire period. - * int: the interrupt acknowledge cycle. - - Quite a lot of that is duplicative, implying both something about internal - state and something about what's observable on the bus, but it's helpful to - stick to that document's coding exactly for easier debugging. - - np fetches will fill the prefetch queue, attaching an action to both the - step that precedes them and to themselves. The SP fetches will go - to address_[7], whichever stack pointer that may currently be. - - Other actions will by default act via effective_address_ and bus_data_. - The user should fill in the steps necessary to get data into or extract - data from those. - - nr/nw-type operations may have a + or - suffix; if such a suffix is attached - then the corresponding effective address will be incremented or decremented - by two after the cycle has completed. - */ - size_t assemble_program(const char *access_pattern, const std::vector &addresses = {}, bool read_full_words = true) { - auto address_iterator = addresses.begin(); - using Action = BusStep::Action; - - std::vector steps; - - // Tokenise the access pattern by splitting on spaces. - const char *next_access_pattern = access_pattern; - while(true) { - /* - Ugly C-style string parsing here: - - next_access_pattern is the end of the previous access pattern, i.e. - it is where parsing should begin to find the next one. - - end_of_pattern will be where the current pattern ends, after any - modifier suffixes have been removed. - - access_pattern is the beginning of the current pattern. - - Obiter: this replaces a std::stringstream >> std::string implementation, - that was a lot cleaner but implied a lot of std::string constructions - that made this section of code measureable slower. Which, inter alia, - had a bit impact on the rate at which unit tests would run. - - So this ugliness is a net project improvement, I promise! - */ - while(*next_access_pattern == ' ') ++next_access_pattern; - access_pattern = next_access_pattern; - while(*next_access_pattern != ' ' && *next_access_pattern != '\0') ++next_access_pattern; - if(next_access_pattern == access_pattern) break; - const char *end_of_pattern = next_access_pattern; - - ProcessorBase::BusStep step; - - // Check for a plus-or-minus suffix. - int post_adjustment = 0; - if(end_of_pattern[-1] == '-' || end_of_pattern[-1] == '+') { - if(end_of_pattern[-1] == '-') { - post_adjustment = -1; - } - - if(end_of_pattern[-1] == '+') { - post_adjustment = 1; - } - - --end_of_pattern; - } - - const auto token_length = end_of_pattern - access_pattern; - - // Do nothing (possibly twice). - if( - access_pattern[0] == 'n' && - ( - token_length == 1 || - (token_length == 2 && access_pattern[1] == 'n') - ) - ) { - if(token_length == 2) { - step.microcycle.length = HalfCycles(8); - } - steps.push_back(step); - continue; - } - - // Do nothing, but with a length that definitely won't map it to the other do-nothings. - if( - access_pattern[0] == 'r' && - token_length == 1 - ) { -#ifndef NDEBUG - // If this is a debug build, not where the resizeable microcycle is - // (and double check that there's only the one). - step.microcycle.is_resizeable = true; -#endif - step.microcycle.length = HalfCycles(0); - steps.push_back(step); - continue; - } - - if( - token_length == 2 && - access_pattern[0] == 'n' - ) { - // Fetch SSP. - if(tolower(access_pattern[1]) == 'f') { - step.microcycle.operation = Microcycle::NewAddress | Microcycle::Read | Microcycle::IsProgram; // IsProgram is a guess. - step.microcycle.address = &storage_.effective_address_[0].full; - step.microcycle.value = isupper(access_pattern[1]) ? &storage_.address_[7].halves.high : &storage_.address_[7].halves.low; - steps.push_back(step); - - step.microcycle.operation = Microcycle::SameAddress | Microcycle::Read | Microcycle::IsProgram | Microcycle::SelectWord; - step.action = isupper(access_pattern[1]) ? Action::IncrementEffectiveAddress0 : Action::IncrementEffectiveAddress0AlignStackPointer; - steps.push_back(step); - - continue; - } - - // Fetch exception vector. - if(tolower(access_pattern[1]) == 'v') { - step.microcycle.operation = Microcycle::NewAddress | Microcycle::Read | Microcycle::IsProgram; // IsProgram is a guess. - step.microcycle.address = &storage_.effective_address_[0].full; - step.microcycle.value = isupper(access_pattern[1]) ? &storage_.program_counter_.halves.high : &storage_.program_counter_.halves.low; - steps.push_back(step); - - step.microcycle.operation = Microcycle::SameAddress | Microcycle::Read | Microcycle::IsProgram | Microcycle::SelectWord; - step.action = Action::IncrementEffectiveAddress0; - steps.push_back(step); - - continue; - } - - // Fetch from the program counter into the prefetch queue. - if(access_pattern[1] == 'p') { - step.microcycle.operation = Microcycle::NewAddress | Microcycle::Read | Microcycle::IsProgram; - step.microcycle.address = &storage_.program_counter_.full; - step.microcycle.value = &storage_.prefetch_queue_.halves.low; - step.action = Action::AdvancePrefetch; - steps.push_back(step); - - step.microcycle.operation = Microcycle::SameAddress | Microcycle::Read | Microcycle::IsProgram | Microcycle::SelectWord; - step.action = Action::IncrementProgramCounter; - steps.push_back(step); - - continue; - } - - // A stack write. - if(tolower(access_pattern[1]) == 's') { - step.microcycle.operation = Microcycle::NewAddress; - step.microcycle.address = &storage_.effective_address_[1].full; - step.microcycle.value = isupper(access_pattern[1]) ? &storage_.destination_bus_data_.halves.high : &storage_.destination_bus_data_.halves.low; - steps.push_back(step); - - step.microcycle.operation = Microcycle::SameAddress | Microcycle::SelectWord; - step.action = Action::DecrementEffectiveAddress1; - steps.push_back(step); - - continue; - } - - // A stack read. - if(tolower(access_pattern[1]) == 'u') { - RegisterPair32 *const scratch_data = &storage_.source_bus_data_; - - step.microcycle.operation = Microcycle::NewAddress | Microcycle::Read; - step.microcycle.address = &storage_.effective_address_[0].full; - step.microcycle.value = isupper(access_pattern[1]) ? &scratch_data->halves.high : &scratch_data->halves.low; - steps.push_back(step); - - step.microcycle.operation = Microcycle::SameAddress | Microcycle::Read | Microcycle::SelectWord; - step.action = Action::IncrementEffectiveAddress0; - steps.push_back(step); - - continue; - } - } - - // The reset cycle. - if(token_length == 1 && access_pattern[0] == '_') { - step.microcycle.length = HalfCycles(248); - step.microcycle.operation = Microcycle::Reset; - steps.push_back(step); - - continue; - } - - // A standard read or write. - if( - access_pattern[0] == 'n' && - (tolower(access_pattern[1]) == 'r' || tolower(access_pattern[1]) == 'w') && - ( - token_length == 2 || - ( - token_length == 3 && - (access_pattern[2] == 'd' || access_pattern[2] == 'r') - ) - ) - ) { - const bool is_read = tolower(access_pattern[1]) == 'r'; - const bool use_source_storage = tolower(end_of_pattern[-1]) == 'r'; - RegisterPair32 *const scratch_data = use_source_storage ? &storage_.source_bus_data_ : &storage_.destination_bus_data_; - - assert(address_iterator != addresses.end()); - - step.microcycle.operation = Microcycle::NewAddress | (is_read ? Microcycle::Read : 0); - step.microcycle.address = *address_iterator; - step.microcycle.value = isupper(access_pattern[1]) ? &scratch_data->halves.high : &scratch_data->halves.low; - steps.push_back(step); - - step.microcycle.operation = Microcycle::SameAddress | (is_read ? Microcycle::Read : 0) | (read_full_words ? Microcycle::SelectWord : Microcycle::SelectByte); - if(post_adjustment) { - assert((*address_iterator == &storage_.effective_address_[0].full) || (*address_iterator == &storage_.effective_address_[1].full)); - if(*address_iterator == &storage_.effective_address_[0].full) { - step.action = (post_adjustment > 0) ? Action::IncrementEffectiveAddress0 : Action::DecrementEffectiveAddress0; - } else { - step.action = (post_adjustment > 0) ? Action::IncrementEffectiveAddress1 : Action::DecrementEffectiveAddress1; - } - } - steps.push_back(step); - ++address_iterator; - - continue; - } - - if(token_length == 3) { - // The completing part of a TAS. - if(access_pattern[0] == 't' && access_pattern[1] == 'a' && access_pattern[2] == 's') { - RegisterPair32 *const scratch_data = &storage_.destination_bus_data_; - - assert(address_iterator != addresses.end()); - - step.microcycle.length = HalfCycles(9); - step.microcycle.operation = Microcycle::SameAddress; - step.microcycle.address = *address_iterator; - step.microcycle.value = &scratch_data->halves.low; - steps.push_back(step); - - step.microcycle.length = HalfCycles(3); - step.microcycle.operation = Microcycle::SameAddress | Microcycle::SelectByte; - steps.push_back(step); - ++address_iterator; - - continue; - } - - // Interrupt acknowledge. - if(access_pattern[0] == 'i' && access_pattern[1] == 'n' && access_pattern[2] == 't') { - step.microcycle.operation = Microcycle::InterruptAcknowledge | Microcycle::NewAddress; - step.microcycle.address = &storage_.effective_address_[0].full; // The selected interrupt should be in bits 1–3; but 0 should be set. - step.microcycle.value = &storage_.source_bus_data_.halves.low; - steps.push_back(step); - - step.microcycle.operation = Microcycle::InterruptAcknowledge | Microcycle::SameAddress | Microcycle::SelectByte; - steps.push_back(step); - - continue; - } - } - - std::cerr << "MC68000 program builder; Unknown access token " << std::string(access_pattern, end_of_pattern) << std::endl; - assert(false); - } - - // Add a final 'ScheduleNextProgram' sentinel. - BusStep end_program; - end_program.action = Action::ScheduleNextProgram; - steps.push_back(end_program); - - // If the new steps already exist, just return the existing index to them; - // otherwise insert them. - /*const auto position = std::search(storage_.all_bus_steps_.begin(), storage_.all_bus_steps_.end(), steps.begin(), steps.end()); - if(position != storage_.all_bus_steps_.end()) { - return size_t(position - storage_.all_bus_steps_.begin()); - } - - const auto start = storage_.all_bus_steps_.size(); - std::copy(steps.begin(), steps.end(), std::back_inserter(storage_.all_bus_steps_)); - return start;*/ - - // If the new steps already exist, just return the existing index to them; - // otherwise insert them. A lookup table of steps to start positions within - // all_bus_steps_ is maintained to shorten setup time here - auto potential_locations = locations_by_bus_step_[steps.front()]; - for(auto index: potential_locations) { - if(index + steps.size() > storage_.all_bus_steps_.size()) continue; - - if(std::equal( - storage_.all_bus_steps_.begin() + ssize_t(index), - storage_.all_bus_steps_.begin() + ssize_t(index + steps.size()), - steps.begin())) { - return index; - } - } - - // Copy to the end, and update potential_locations. - const auto start = storage_.all_bus_steps_.size(); - std::copy(steps.begin(), steps.end(), std::back_inserter(storage_.all_bus_steps_)); - auto index = start; - for(const auto &step: steps) { - locations_by_bus_step_[step].push_back(index); - ++index; - } - - return start; - } - - /*! - Walks through the sequence of bus steps beginning at @c start, replacing the value supplied for each write - encountered with the respective value from @c values. - */ - void replace_write_values(BusStep *start, const std::initializer_list &values) { - const auto end = replace_write_values(start, values.begin()); - assert(end == values.end()); - (void)end; - } - - /*! - Walks through the sequence of micro-ops beginning at @c start, replacing the value supplied for each write - encountered in each micro-op's bus steps with the respective value from @c values. - */ - void replace_write_values(ProcessorBase::MicroOp *start, const std::initializer_list &values) { - auto value = values.begin(); - while(!start->is_terminal()) { - value = replace_write_values(&storage_.all_bus_steps_[start->bus_program], value); - ++start; - } - assert(value == values.end()); - } - - /*! - Disassembles the instruction @c instruction and inserts it into the - appropriate lookup tables. - - install_instruction acts, in effect, in the manner of a disassembler. So this class is - formulated to run through all potential 65536 instuction encodings and attempt to - disassemble each, rather than going in the opposite direction. - - This has two benefits: - - (i) which addressing modes go with which instructions falls out automatically; - (ii) it is a lot easier during the manual verification stage of development to work - from known instructions to their disassembly rather than vice versa; especially - (iii) given that there are plentiful disassemblers against which to test work in progress. - */ - void install_instructions() { - enum class Decoder { - ABCD_SBCD, // Maps source and desintation registers and a register/memory selection bit to an ABCD or SBCD. - ADD_SUB, // Maps a register and a register and mode to an ADD or SUB. - ADDA_SUBA, // Maps a destination register and a source mode and register to an ADDA or SUBA. - ADDQ_SUBQ, // Maps a register and a mode to an ADDQ or SUBQ. - ADDX_SUBX, // Maps source and destination registers, and register/memory mode to an ADDX or SUBX. - - AND_OR_EOR, // Maps a source register, operation mode and destination register and mode to an AND, OR or EOR. - - BRA, // Maps to a BRA. All fields are decoded at runtime. - Bcc_BSR, // Maps to a Bcc or BSR. Other than determining the type of operation, fields are decoded at runtime. - - BTST, // Maps a source register and a destination register and mode to a BTST. - BTSTIMM, // Maps a destination mode and register to a BTST #. - - BCLR, // Maps a source register and a destination register and mode to a BCLR. - BCLRIMM, // Maps a destination mode and register to a BCLR #. - - CLR_NEG_NEGX_NOT, // Maps a destination mode and register to a CLR, NEG, NEGX or NOT. - - CMP, // Maps a destination register and a source mode and register to a CMP. - CMPI, // Maps a destination mode and register to a CMPI. - CMPA, // Maps a destination register and a source mode and register to a CMPA. - CMPM, // Maps to a CMPM. - - EORI_ORI_ANDI_SUBI_ADDI, // Maps a mode and register to one of EORI, ORI, ANDI, SUBI or ADDI. - - JMP, // Maps a mode and register to a JMP. - JSR, // Maps a mode and register to a JSR. - - LEA, // Maps a destination register and a source mode and register to an LEA. - - MOVE, // Maps a source mode and register and a destination mode and register to a MOVE. - MOVEtoSRCCR, // Maps a source mode and register to a MOVE to SR or MOVE to CCR. - MOVEfromSR_NBCD, // Maps a source mode and register to a MOVE fom SR. - MOVEq, // Maps a destination register to a MOVEQ. - - MULU_MULS, // Maps a destination register and a source mode and register to a MULU or MULS. - DIVU_DIVS, // Maps a destination register and a source mode and register to a DIVU or DIVS. - - RESET, // Maps to a RESET. - - ASLR_LSLR_ROLR_ROXLRr, // Maps a destination register to a AS[L/R], LS[L/R], RO[L/R], ROX[L/R]; shift quantities are - // decoded at runtime. - ASLR_LSLR_ROLR_ROXLRm, // Maps a destination mode and register to a memory-based AS[L/R], LS[L/R], RO[L/R], ROX[L/R]. - - MOVEM, // Maps a mode and register as if they were a 'destination' and sets up bus steps with a suitable - // hole for the runtime part to install proper MOVEM activity. - MOVEP, // Maps a data register, address register and operation mode to a MOVEP. - - RTE_RTR, // Maps to an RTE/RTR. - - Scc_DBcc, // Maps a mode and destination register to either a DBcc or Scc. - - TST, // Maps a mode and register to a TST. - - RTS, // Maps to an RST. - - MOVEUSP, // Maps a direction and register to a MOVE [to/from] USP. - - TRAP, // Maps to a TRAP. - TRAPV, // Maps to a TRAPV. - CHK, // Maps to a CHK. - - NOP, // Maps to a NOP. - - EXG, // Maps source and destination registers and an operation mode to an EXG. - EXT_SWAP, // Maps a source register to a SWAP or EXT. - - EORI_ORI_ANDI_SR, // Maps to an EORI, ORI or ANDI to SR/CCR. - - BCHG_BSET, // Maps a mode and register, and possibly a source register, to a BCHG or BSET. - - TAS, // Maps a mode and register to a TAS. - - PEA, // Maps a mode and register to a PEA. - - LINK, // Maps a register to a LINK. - UNLINK, // Maps a register to an UNLINK. - - STOP, // Maps to a STOP. - }; - - using Operation = ProcessorStorage::Operation; - using Action = ProcessorStorage::MicroOp::Action; - using MicroOp = ProcessorBase::MicroOp; - struct PatternMapping { - uint16_t mask, value; - Operation operation; - Decoder decoder; - }; - - /* - Inspired partly by 'wrm' (https://github.com/wrm-za I assume); the following - table draws from the M68000 Programmer's Reference Manual, currently available at - https://www.nxp.com/files-static/archives/doc/ref_manual/M68000PRM.pdf - - After each line is the internal page number on which documentation of that - instruction mapping can be found, followed by the page number within the PDF - linked above. - - NB: a vector is used to allow easy iteration. - */ - const std::initializer_list mappings = { - {0xf1f0, 0xc100, Operation::ABCD, Decoder::ABCD_SBCD}, // 4-3 (p107) - {0xf1f0, 0x8100, Operation::SBCD, Decoder::ABCD_SBCD}, // 4-171 (p275) - {0xffc0, 0x4800, Operation::NBCD, Decoder::MOVEfromSR_NBCD}, // 4-142 (p246) - - {0xf0c0, 0xc000, Operation::ANDb, Decoder::AND_OR_EOR}, // 4-15 (p119) - {0xf0c0, 0xc040, Operation::ANDw, Decoder::AND_OR_EOR}, // 4-15 (p119) - {0xf0c0, 0xc080, Operation::ANDl, Decoder::AND_OR_EOR}, // 4-15 (p119) - - {0xf0c0, 0x8000, Operation::ORb, Decoder::AND_OR_EOR}, // 4-150 (p254) - {0xf0c0, 0x8040, Operation::ORw, Decoder::AND_OR_EOR}, // 4-150 (p254) - {0xf0c0, 0x8080, Operation::ORl, Decoder::AND_OR_EOR}, // 4-150 (p254) - - {0xf0c0, 0xb000, Operation::EORb, Decoder::AND_OR_EOR}, // 4-100 (p204) - {0xf0c0, 0xb040, Operation::EORw, Decoder::AND_OR_EOR}, // 4-100 (p204) - {0xf0c0, 0xb080, Operation::EORl, Decoder::AND_OR_EOR}, // 4-100 (p204) - - {0xffc0, 0x0600, Operation::ADDb, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-9 (p113) - {0xffc0, 0x0640, Operation::ADDw, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-9 (p113) - {0xffc0, 0x0680, Operation::ADDl, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-9 (p113) - - {0xffc0, 0x0200, Operation::ANDb, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-18 (p122) - {0xffc0, 0x0240, Operation::ANDw, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-18 (p122) - {0xffc0, 0x0280, Operation::ANDl, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-18 (p122) - - {0xffc0, 0x0000, Operation::ORb, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-153 (p257) - {0xffc0, 0x0040, Operation::ORw, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-153 (p257) - {0xffc0, 0x0080, Operation::ORl, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-153 (p257) - - {0xffc0, 0x0a00, Operation::EORb, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-102 (p206) - {0xffc0, 0x0a40, Operation::EORw, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-102 (p206) - {0xffc0, 0x0a80, Operation::EORl, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-102 (p206) - - {0xffc0, 0x0400, Operation::SUBb, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-179 (p283) - {0xffc0, 0x0440, Operation::SUBw, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-179 (p283) - {0xffc0, 0x0480, Operation::SUBl, Decoder::EORI_ORI_ANDI_SUBI_ADDI}, // 4-179 (p283) - - {0xf000, 0x1000, Operation::MOVEb, Decoder::MOVE}, // 4-116 (p220) - {0xf000, 0x2000, Operation::MOVEl, Decoder::MOVE}, // 4-116 (p220) - {0xf000, 0x3000, Operation::MOVEw, Decoder::MOVE}, // 4-116 (p220) - - {0xffc0, 0x46c0, Operation::MOVEtoSR, Decoder::MOVEtoSRCCR}, // 6-19 (p473) - {0xffc0, 0x44c0, Operation::MOVEtoCCR, Decoder::MOVEtoSRCCR}, // 4-123 (p227) - {0xffc0, 0x40c0, Operation::MOVEfromSR, Decoder::MOVEfromSR_NBCD}, // 6-17 (p471) - - {0xf1c0, 0xb000, Operation::CMPb, Decoder::CMP}, // 4-75 (p179) - {0xf1c0, 0xb040, Operation::CMPw, Decoder::CMP}, // 4-75 (p179) - {0xf1c0, 0xb080, Operation::CMPl, Decoder::CMP}, // 4-75 (p179) - - {0xf1c0, 0xb0c0, Operation::CMPAw, Decoder::CMPA}, // 4-77 (p181) - {0xf1c0, 0xb1c0, Operation::CMPl, Decoder::CMPA}, // 4-77 (p181) - - {0xffc0, 0x0c00, Operation::CMPb, Decoder::CMPI}, // 4-79 (p183) - {0xffc0, 0x0c40, Operation::CMPw, Decoder::CMPI}, // 4-79 (p183) - {0xffc0, 0x0c80, Operation::CMPl, Decoder::CMPI}, // 4-79 (p183) - - {0xf1f8, 0xb108, Operation::CMPb, Decoder::CMPM}, // 4-81 (p185) - {0xf1f8, 0xb148, Operation::CMPw, Decoder::CMPM}, // 4-81 (p185) - {0xf1f8, 0xb188, Operation::CMPl, Decoder::CMPM}, // 4-81 (p185) - -// {0xff00, 0x6000, Operation::BRA, Decoder::BRA}, // 4-55 (p159) TODO: confirm that this really, really is just a special case of Bcc. - {0xf000, 0x6000, Operation::Bcc, Decoder::Bcc_BSR}, // 4-25 (p129) and 4-59 (p163) - - {0xf1c0, 0x41c0, Operation::MOVEAl, Decoder::LEA}, // 4-110 (p214) - {0xffc0, 0x4840, Operation::PEA, Decoder::PEA}, // 4-159 (p263) - - {0xf100, 0x7000, Operation::MOVEq, Decoder::MOVEq}, // 4-134 (p238) - - {0xffff, 0x4e70, Operation::None, Decoder::RESET}, // 6-83 (p537) - - {0xffc0, 0x4ec0, Operation::JMP, Decoder::JMP}, // 4-108 (p212) - {0xffc0, 0x4e80, Operation::JMP, Decoder::JSR}, // 4-109 (p213) - {0xffff, 0x4e75, Operation::RTS, Decoder::RTS}, // 4-169 (p273) - - {0xf0c0, 0x9000, Operation::SUBb, Decoder::ADD_SUB}, // 4-174 (p278) - {0xf0c0, 0x9040, Operation::SUBw, Decoder::ADD_SUB}, // 4-174 (p278) - {0xf0c0, 0x9080, Operation::SUBl, Decoder::ADD_SUB}, // 4-174 (p278) - - {0xf0c0, 0xd000, Operation::ADDb, Decoder::ADD_SUB}, // 4-4 (p108) - {0xf0c0, 0xd040, Operation::ADDw, Decoder::ADD_SUB}, // 4-4 (p108) - {0xf0c0, 0xd080, Operation::ADDl, Decoder::ADD_SUB}, // 4-4 (p108) - - {0xf1c0, 0xd0c0, Operation::ADDAw, Decoder::ADDA_SUBA}, // 4-7 (p111) - {0xf1c0, 0xd1c0, Operation::ADDAl, Decoder::ADDA_SUBA}, // 4-7 (p111) - {0xf1c0, 0x90c0, Operation::SUBAw, Decoder::ADDA_SUBA}, // 4-177 (p281) - {0xf1c0, 0x91c0, Operation::SUBAl, Decoder::ADDA_SUBA}, // 4-177 (p281) - - {0xf1c0, 0x5000, Operation::ADDQb, Decoder::ADDQ_SUBQ}, // 4-11 (p115) - {0xf1c0, 0x5040, Operation::ADDQw, Decoder::ADDQ_SUBQ}, // 4-11 (p115) - {0xf1c0, 0x5080, Operation::ADDQl, Decoder::ADDQ_SUBQ}, // 4-11 (p115) - - {0xf1c0, 0x5100, Operation::SUBQb, Decoder::ADDQ_SUBQ}, // 4-181 (p285) - {0xf1c0, 0x5140, Operation::SUBQw, Decoder::ADDQ_SUBQ}, // 4-181 (p285) - {0xf1c0, 0x5180, Operation::SUBQl, Decoder::ADDQ_SUBQ}, // 4-181 (p285) - - {0xf1f0, 0xd100, Operation::ADDXb, Decoder::ADDX_SUBX}, // 4-14 (p118) - {0xf1f0, 0xd140, Operation::ADDXw, Decoder::ADDX_SUBX}, // 4-14 (p118) - {0xf1f0, 0xd180, Operation::ADDXl, Decoder::ADDX_SUBX}, // 4-14 (p118) - - {0xf1f0, 0x9100, Operation::SUBXb, Decoder::ADDX_SUBX}, // 4-184 (p288) - {0xf1f0, 0x9140, Operation::SUBXw, Decoder::ADDX_SUBX}, // 4-184 (p288) - {0xf1f0, 0x9180, Operation::SUBXl, Decoder::ADDX_SUBX}, // 4-184 (p288) - - {0xf1c0, 0x0100, Operation::BTSTb, Decoder::BTST}, // 4-62 (p166) - {0xffc0, 0x0800, Operation::BTSTb, Decoder::BTSTIMM}, // 4-63 (p167) - - {0xf1c0, 0x0180, Operation::BCLRb, Decoder::BCLR}, // 4-31 (p135) - {0xffc0, 0x0880, Operation::BCLRb, Decoder::BCLRIMM}, // 4-32 (p136) - - {0xf0c0, 0x50c0, Operation::Scc, Decoder::Scc_DBcc}, // Scc: 4-173 (p276); DBcc: 4-91 (p195) - - {0xffc0, 0x4200, Operation::CLRb, Decoder::CLR_NEG_NEGX_NOT}, // 4-73 (p177) - {0xffc0, 0x4240, Operation::CLRw, Decoder::CLR_NEG_NEGX_NOT}, // 4-73 (p177) - {0xffc0, 0x4280, Operation::CLRl, Decoder::CLR_NEG_NEGX_NOT}, // 4-73 (p177) - {0xffc0, 0x4400, Operation::NEGb, Decoder::CLR_NEG_NEGX_NOT}, // 4-144 (p248) - {0xffc0, 0x4440, Operation::NEGw, Decoder::CLR_NEG_NEGX_NOT}, // 4-144 (p248) - {0xffc0, 0x4480, Operation::NEGl, Decoder::CLR_NEG_NEGX_NOT}, // 4-144 (p248) - {0xffc0, 0x4000, Operation::NEGXb, Decoder::CLR_NEG_NEGX_NOT}, // 4-146 (p250) - {0xffc0, 0x4040, Operation::NEGXw, Decoder::CLR_NEG_NEGX_NOT}, // 4-146 (p250) - {0xffc0, 0x4080, Operation::NEGXl, Decoder::CLR_NEG_NEGX_NOT}, // 4-146 (p250) - {0xffc0, 0x4600, Operation::NOTb, Decoder::CLR_NEG_NEGX_NOT}, // 4-148 (p250) - {0xffc0, 0x4640, Operation::NOTw, Decoder::CLR_NEG_NEGX_NOT}, // 4-148 (p250) - {0xffc0, 0x4680, Operation::NOTl, Decoder::CLR_NEG_NEGX_NOT}, // 4-148 (p250) - - {0xf1d8, 0xe100, Operation::ASLb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-22 (p126) - {0xf1d8, 0xe140, Operation::ASLw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-22 (p126) - {0xf1d8, 0xe180, Operation::ASLl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-22 (p126) - {0xffc0, 0xe1c0, Operation::ASLm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-22 (p126) - - {0xf1d8, 0xe000, Operation::ASRb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-22 (p126) - {0xf1d8, 0xe040, Operation::ASRw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-22 (p126) - {0xf1d8, 0xe080, Operation::ASRl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-22 (p126) - {0xffc0, 0xe0c0, Operation::ASRm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-22 (p126) - - {0xf1d8, 0xe108, Operation::LSLb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-113 (p217) - {0xf1d8, 0xe148, Operation::LSLw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-113 (p217) - {0xf1d8, 0xe188, Operation::LSLl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-113 (p217) - {0xffc0, 0xe3c0, Operation::LSLm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-113 (p217) - - {0xf1d8, 0xe008, Operation::LSRb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-113 (p217) - {0xf1d8, 0xe048, Operation::LSRw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-113 (p217) - {0xf1d8, 0xe088, Operation::LSRl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-113 (p217) - {0xffc0, 0xe2c0, Operation::LSRm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-113 (p217) - - {0xf1d8, 0xe118, Operation::ROLb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-160 (p264) - {0xf1d8, 0xe158, Operation::ROLw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-160 (p264) - {0xf1d8, 0xe198, Operation::ROLl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-160 (p264) - {0xffc0, 0xe7c0, Operation::ROLm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-160 (p264) - - {0xf1d8, 0xe018, Operation::RORb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-160 (p264) - {0xf1d8, 0xe058, Operation::RORw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-160 (p264) - {0xf1d8, 0xe098, Operation::RORl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-160 (p264) - {0xffc0, 0xe6c0, Operation::RORm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-160 (p264) - - {0xf1d8, 0xe110, Operation::ROXLb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-163 (p267) - {0xf1d8, 0xe150, Operation::ROXLw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-163 (p267) - {0xf1d8, 0xe190, Operation::ROXLl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-163 (p267) - {0xffc0, 0xe5c0, Operation::ROXLm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-163 (p267) - - {0xf1d8, 0xe010, Operation::ROXRb, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-163 (p267) - {0xf1d8, 0xe050, Operation::ROXRw, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-163 (p267) - {0xf1d8, 0xe090, Operation::ROXRl, Decoder::ASLR_LSLR_ROLR_ROXLRr}, // 4-163 (p267) - {0xffc0, 0xe4c0, Operation::ROXRm, Decoder::ASLR_LSLR_ROLR_ROXLRm}, // 4-163 (p267) - - {0xffc0, 0x48c0, Operation::MOVEMtoMl, Decoder::MOVEM}, // 4-128 (p232) - {0xffc0, 0x4880, Operation::MOVEMtoMw, Decoder::MOVEM}, // 4-128 (p232) - {0xffc0, 0x4cc0, Operation::MOVEMtoRl, Decoder::MOVEM}, // 4-128 (p232) - {0xffc0, 0x4c80, Operation::MOVEMtoRw, Decoder::MOVEM}, // 4-128 (p232) - - {0xf1f8, 0x0108, Operation::MOVEPtoRw, Decoder::MOVEP}, // 4-133 (p237) - {0xf1f8, 0x0148, Operation::MOVEPtoRl, Decoder::MOVEP}, // 4-133 (p237) - {0xf1f8, 0x0188, Operation::MOVEPtoMw, Decoder::MOVEP}, // 4-133 (p237) - {0xf1f8, 0x01c8, Operation::MOVEPtoMl, Decoder::MOVEP}, // 4-133 (p237) - - {0xffc0, 0x4a00, Operation::TSTb, Decoder::TST}, // 4-192 (p296) - {0xffc0, 0x4a40, Operation::TSTw, Decoder::TST}, // 4-192 (p296) - {0xffc0, 0x4a80, Operation::TSTl, Decoder::TST}, // 4-192 (p296) - - {0xf1c0, 0xc0c0, Operation::MULU, Decoder::MULU_MULS}, // 4-139 (p243) - {0xf1c0, 0xc1c0, Operation::MULS, Decoder::MULU_MULS}, // 4-136 (p240) - - {0xf1c0, 0x80c0, Operation::DIVU, Decoder::DIVU_DIVS}, // 4-97 (p201) - {0xf1c0, 0x81c0, Operation::DIVS, Decoder::DIVU_DIVS}, // 4-93 (p197) - - {0xfff0, 0x4e60, Operation::MOVEAl, Decoder::MOVEUSP}, // 6-21 (p475) - - {0xfff0, 0x4e40, Operation::TRAP, Decoder::TRAP}, // 4-188 (p292) - {0xffff, 0x4e76, Operation::TRAPV, Decoder::TRAPV}, // 4-191 (p295) - {0xf1c0, 0x4180, Operation::CHK, Decoder::CHK}, // 4-69 (p173) - - {0xffff, 0x4e77, Operation::RTE_RTR, Decoder::RTE_RTR}, // 4-168 (p272) [RTR] - {0xffff, 0x4e73, Operation::RTE_RTR, Decoder::RTE_RTR}, // 6-84 (p538) [RTE] - - {0xffff, 0x4e71, Operation::None, Decoder::NOP}, // 8-13 (p469) - - {0xf1f8, 0xc140, Operation::EXG, Decoder::EXG}, // 4-105 (p209) - {0xf1f8, 0xc148, Operation::EXG, Decoder::EXG}, // 4-105 (p209) - {0xf1f8, 0xc188, Operation::EXG, Decoder::EXG}, // 4-105 (p209) - - {0xfff8, 0x4840, Operation::SWAP, Decoder::EXT_SWAP}, // 4-185 (p289) - - {0xffff, 0x027c, Operation::ANDItoSR, Decoder::EORI_ORI_ANDI_SR}, - {0xffff, 0x023c, Operation::ANDItoCCR, Decoder::EORI_ORI_ANDI_SR}, - {0xffff, 0x0a7c, Operation::EORItoSR, Decoder::EORI_ORI_ANDI_SR}, - {0xffff, 0x0a3c, Operation::EORItoCCR, Decoder::EORI_ORI_ANDI_SR}, - {0xffff, 0x007c, Operation::ORItoSR, Decoder::EORI_ORI_ANDI_SR}, - {0xffff, 0x003c, Operation::ORItoCCR, Decoder::EORI_ORI_ANDI_SR}, - - {0xf1c0, 0x0140, Operation::BCHGb, Decoder::BCHG_BSET}, // 4-28 (p132) - {0xffc0, 0x0840, Operation::BCHGb, Decoder::BCHG_BSET}, // 4-29 (p133) - {0xf1c0, 0x01c0, Operation::BSETb, Decoder::BCHG_BSET}, // 4-57 (p161) - {0xffc0, 0x08c0, Operation::BSETb, Decoder::BCHG_BSET}, // 4-58 (p162) - - {0xffc0, 0x4ac0, Operation::TAS, Decoder::TAS}, // 4-186 (p290) - - {0xfff8, 0x4880, Operation::EXTbtow, Decoder::EXT_SWAP}, // 4-106 (p210) - {0xfff8, 0x48c0, Operation::EXTwtol, Decoder::EXT_SWAP}, // 4-106 (p210) - - {0xfff8, 0x4e50, Operation::LINK, Decoder::LINK}, // 4-111 (p215) - {0xfff8, 0x4e58, Operation::UNLINK, Decoder::UNLINK}, // 4-194 (p298) - - {0xffff, 0x4e72, Operation::STOP, Decoder::STOP}, // 6-85 (p539) - }; - - std::vector micro_op_pointers(65536, std::numeric_limits::max()); - - // The arbitrary_base is used so that the offsets returned by assemble_program into - // storage_.all_bus_steps_ can be retained and mapped into the final version of - // storage_.all_bus_steps_ at the end. -// BusStep arbitrary_base; - -#define op(...) storage_.all_micro_ops_.emplace_back(__VA_ARGS__) -#define seq(...) assemble_program(__VA_ARGS__) -#define ea(n) &storage_.effective_address_[n].full -#define a(n) &storage_.address_[n].full - -#define bw(x) (x) -#define l(x) (0x10000 | (x)) - - // Perform a linear search of the mappings above for this instruction. - for(ssize_t instruction = 65535; instruction >= 0; --instruction) { -#ifndef NDEBUG - int hits = 0; -#endif - for(const auto &mapping: mappings) { - if((instruction & mapping.mask) == mapping.value) { - auto operation = mapping.operation; - const auto micro_op_start = storage_.all_micro_ops_.size(); - - // The following fields are used commonly enough to be worth pulling out here. - const int ea_register = instruction & 7; - const int ea_mode = (instruction >> 3) & 7; - const int data_register = (instruction >> 9) & 7; - const int op_mode = (instruction >> 6)&7; - const bool op_mode_high_bit = !!(op_mode&4); - - // These are almost always true; they're non-const so that they can be corrected - // by the few deviations. - bool is_byte_access = (op_mode&3) == 0; - bool is_long_word_access = (op_mode&3) == 2; - - // Temporary storage for the Program fields. - ProcessorBase::Program program; - -#define dec(n) decrement_action(is_long_word_access, is_byte_access, n) -#define inc(n) increment_action(is_long_word_access, is_byte_access, n) - - switch(mapping.decoder) { - case Decoder::STOP: { - program.set_requires_supervisor(true); - op(Action::None, seq("n")); - op(Action::PerformOperation); - } break; - - case Decoder::LINK: { - program.set_source(storage_, An, ea_register); - op(Action::PerformOperation, seq("np nW+ nw np", { ea(1), ea(1) })); - } break; - - case Decoder::UNLINK: { - program.set_destination(storage_, An, ea_register); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation); - } break; - - case Decoder::TAS: { - const int mode = combined_mode(ea_mode, ea_register); - program.set_destination(storage_, ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // TAS Dn - op(Action::PerformOperation, seq("np")); - break; - - case Ind: // TAS (An) - case PostInc: // TAS (An)+ - op(Action::None, seq("nrd", { a(ea_register) }, false)); - op(Action::PerformOperation, seq("tas np", { a(ea_register) }, false)); - if(mode == PostInc) { - op(byte_inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case PreDec: // TAS -(An) - op(byte_dec(ea_register) | MicroOp::DestinationMask, seq("n nrd", { a(ea_register) }, false)); - op(Action::PerformOperation, seq("tas np", { a(ea_register) }, false)); - break; - - case XXXl: // TAS (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // TAS (xxx).w - case d16An: // TAS (d16, An) - case d8AnXn: // TAS (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq("np nrd", { ea(1) }, false)); - op(Action::PerformOperation, seq("tas np", { ea(1) }, false)); - break; - } - } break; - - case Decoder::BCHG_BSET: { - const int mode = combined_mode(ea_mode, ea_register); - - // Operations on a register are .l; all others are the default .b. - if(ea_mode == Dn) { - operation = (operation == Operation::BSETb) ? Operation::BSETl : Operation::BCHGl; - } - - program.set_destination(storage_, ea_mode, ea_register); - - if(instruction & 0x100) { - // The bit is nominated by a register. - program.set_source(storage_, Dn, data_register); - } else { - // The bit is nominated by a constant, that will be obtained right here. - program.set_source(storage_, Imm, 0); - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - } - - switch(mode) { - default: continue; - - case Dn: // [BCHG/BSET].l Dn, Dn - // Execution length depends on the selected bit, so allow flexible time for that. - op(Action::None, seq("np")); - op(Action::PerformOperation, seq("r")); - break; - - case Ind: // [BCHG/BSET].b Dn, (An) - case PostInc: // [BCHG/BSET].b Dn, (An)+ - op(Action::None, seq("nrd np", { a(ea_register) }, false)); - op(Action::PerformOperation, seq("nw", { a(ea_register) }, false)); - if(mode == PostInc) { - op(byte_inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case PreDec: // [BCHG/BSET].b Dn, -(An) - op(byte_dec(ea_register) | MicroOp::DestinationMask, seq("n nrd np", { a(ea_register) }, false)); - op(Action::PerformOperation, seq("nw", { a(ea_register) }, false)); - break; - - case XXXl: // [BCHG/BSET].b Dn, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // [BCHG/BSET].b Dn, (xxx).w - case d16An: // [BCHG/BSET].b Dn, (d16, An) - case d8AnXn: // [BCHG/BSET].b Dn, (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nrd np", mode), { ea(1) }, false)); - op(Action::PerformOperation, seq("nw", { ea(1) }, false)); - break; - } - } break; - - case Decoder::EORI_ORI_ANDI_SR: { - // The source used here is always the high word of the prefetch queue. - program.set_requires_supervisor(!!(instruction & 0x40)); - op(Action::None, seq("np nn nn")); - op(Action::PerformOperation, seq("np np")); - } break; - - case Decoder::EXT_SWAP: { - program.set_destination(storage_, Dn, ea_register); - op(Action::PerformOperation, seq("np")); - } break; - - case Decoder::EXG: { - switch((instruction >> 3)&31) { - default: continue; - - case 0x08: - program.set_source(storage_, Dn, data_register); - program.set_destination(storage_, Dn, ea_register); - break; - - case 0x09: - program.set_source(storage_, An, data_register); - program.set_destination(storage_, An, ea_register); - break; - - case 0x11: - program.set_source(storage_, Dn, data_register); - program.set_destination(storage_, An, ea_register); - break; - } - - op(Action::PerformOperation, seq("np n")); - } break; - - case Decoder::NOP: { - op(Action::None, seq("np")); - } break; - - case Decoder::RTE_RTR: { - program.set_requires_supervisor(instruction == 0x4e73); - - // The targets of the nR nr nr below are reset to the program counter elsewhere; - // look for the comment "relink the RTE and RTR bus steps". It is currently not - // explicitly tested that these bus steps are not shared with a non-RTE/RTR operation, - // just assumed because the repetition of nr is fairly silly. A more explicit soution - // might be preferable in the future. - op(Action::PrepareRTE_RTR, seq("nR nr nr", { &storage_.precomputed_addresses_[0], &storage_.precomputed_addresses_[1], &storage_.precomputed_addresses_[2] } )); - op(Action::PerformOperation, seq("np np")); - op(); - } break; - - case Decoder::AND_OR_EOR: { - const bool to_ea = op_mode_high_bit; - const bool is_eor = (instruction >> 12) == 0xb; - - // Weed out illegal operation modes. - if(op_mode == 7) continue; - - const int mode = combined_mode(ea_mode, ea_register); - - if(to_ea) { - program.set_destination(storage_, ea_mode, ea_register); - program.set_source(storage_, Dn, data_register); - - // Only EOR takes Dn as a destination effective address. - if(!is_eor && mode == Dn) continue; - - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // EOR.bw Dn, Dn - op(Action::PerformOperation, seq("np")); - break; - - case l(Dn): // EOR.l Dn, Dn - op(Action::PerformOperation, seq("np nn")); - break; - - case bw(Ind): // [AND/OR/EOR].bw Dn, (An) - case bw(PostInc): // [AND/OR/EOR].bw Dn, (An)+ - op(Action::None, seq("nrd", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { a(ea_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case bw(PreDec): // [AND/OR/EOR].bw Dn, -(An) - op(dec(ea_register) | MicroOp::DestinationMask, seq("n nrd", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { a(ea_register) }, !is_byte_access)); - break; - - case l(PreDec): // [AND/OR/EOR].l Dn, -(An) - op(int(Action::Decrement4) | MicroOp::DestinationMask, seq("n")); - [[fallthrough]]; - case l(Ind): // [AND/OR/EOR].l Dn, (An) - case l(PostInc): // [AND/OR/EOR].l Dn, (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("nRd+ nrd", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("np nw- nW", { ea(1), ea(1) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::DestinationMask); - } - break; - - case bw(XXXl): // [AND/OR/EOR].bw Dn, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // [AND/OR/EOR].bw Dn, (xxx).w - case bw(d16An): // [AND/OR/EOR].bw Dn, (d16, An) - case bw(d8AnXn): // [AND/OR/EOR].bw Dn, (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nrd", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { ea(1) }, !is_byte_access)); - break; - - case l(XXXl): // [AND/OR/EOR].l Dn, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // [AND/OR/EOR].l Dn, (xxx).w - case l(d16An): // [AND/OR/EOR].l Dn, (d16, An) - case l(d8AnXn): // [AND/OR/EOR].l Dn, (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nRd+ nrd", mode), { ea(1), ea(1) })); - op(Action::PerformOperation, seq("np nw- nW", { ea(1), ea(1) })); - break; - } - } else { - // EORs can be to EA only. - if(is_eor) continue; - - program.set_source(storage_, ea_mode, ea_register); - program.set_destination(storage_, Dn, data_register); - - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // [AND/OR].bw Dn, Dn - op(Action::PerformOperation, seq("np")); - break; - - case l(Dn): // [AND/OR].l Dn, Dn - op(Action::PerformOperation, seq("np nn")); - break; - - case bw(Ind): // [AND/OR].bw (An), Dn - case bw(PostInc): // [AND/OR].bw (An)+, Dn - op(Action::None, seq("nr", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np")); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - break; - - case bw(PreDec): // [AND/OR].bw -(An), Dn - op(dec(ea_register) | MicroOp::SourceMask, seq("n nr", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np")); - break; - - case l(PreDec): // [AND/OR].l -(An), Dn - op(int(Action::Decrement4) | MicroOp::SourceMask, seq("n")); - [[fallthrough]]; - case l(Ind): // [AND/OR].l (An), Dn, - case l(PostInc): // [AND/OR].l (An)+, Dn - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr", { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np n")); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::SourceMask); - } - break; - - case bw(XXXl): // [AND/OR].bw (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // [AND/OR].bw (xxx).w, Dn - case bw(d16An): // [AND/OR].bw (d16, An), Dn - case bw(d16PC): // [AND/OR].bw (d16, PC), Dn - case bw(d8AnXn): // [AND/OR].bw (d8, An, Xn), Dn - case bw(d8PCXn): // [AND/OR].bw (d8, PX, Xn), Dn - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr", mode), { ea(0) }, !is_byte_access)); - op(Action::PerformOperation, seq("np")); - break; - - case l(XXXl): // [AND/OR].bw (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // [AND/OR].bw (xxx).w, Dn - case l(d16An): // [AND/OR].l (d16, An), Dn - case l(d16PC): // [AND/OR].l (d16, PC), Dn - case l(d8AnXn): // [AND/OR].l (d8, An, Xn), Dn - case l(d8PCXn): // [AND/OR].l (d8, PX, Xn), Dn - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nR+ nr", mode), { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np n")); - break; - - case bw(Imm): // [AND/OR].bw #, Dn - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op(Action::PerformOperation, seq("np")); - break; - - case l(Imm): // [AND/OR].l #, Dn - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op(Action::PerformOperation, seq("np nn")); - break; - } - } - } break; - - case Decoder::DIVU_DIVS: { - program.set_source(storage_, ea_mode, ea_register); - program.set_destination(storage_, Dn, data_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // [DIVU/DIVS] Dn, Dn - op(Action::PerformOperation, seq("r")); - op(Action::None, seq("np")); - break; - - case Ind: // [DIVU/DIVS] (An), Dn - case PostInc: // [DIVU/DIVS] (An)+, Dn - op(Action::None, seq("nr", { a(ea_register) })); - op(Action::PerformOperation, seq("r np")); - if(mode == PostInc) { - op(int(Action::Increment2) | MicroOp::SourceMask); - } - break; - - case PreDec: // [DIVU/DIVS] -(An), Dn - op(int(Action::Decrement2) | MicroOp::SourceMask, seq("nr", { a(ea_register) })); - op(Action::PerformOperation, seq("r np")); - break; - - case XXXl: // [DIVU/DIVS] (XXX).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // [DIVU/DIVS] (XXX).w, Dn - case d16An: // [DIVU/DIVS] (d16, An), Dn - case d16PC: // [DIVU/DIVS] (d16, PC), Dn - case d8AnXn: // [DIVU/DIVS] (d8, An, Xn), Dn - case d8PCXn: // [DIVU/DIVS] (d8, PC, Xn), Dn - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq("np nr", { ea(0) })); - op(Action::PerformOperation, seq("r np")); - break; - - case Imm: // [DIVU/DIVS] #, Dn - // DEVIATION FROM YACHT.TXT. It shows an additional np, which is incorrect. - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op(Action::PerformOperation, seq("r np")); - break; - } - } break; - - case Decoder::MULU_MULS: { - program.set_source(storage_, ea_mode, ea_register); - program.set_destination(storage_, Dn, data_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // [MULU/MULS] Dn, Dn - op(Action::None, seq("np")); - op(Action::PerformOperation, seq("r")); - break; - - case Ind: // [MULU/MULS] (An), Dn - case PostInc: // [MULU/MULS] (An)+, Dn - op(Action::None, seq("nr np", { a(ea_register) })); - op(Action::PerformOperation, seq("r")); - if(mode == PostInc) { - op(int(Action::Increment2) | MicroOp::SourceMask); - } - break; - - case PreDec: // [MULU/MULS] -(An), Dn - op(int(Action::Decrement2) | MicroOp::SourceMask, seq("n nr np", { a(ea_register) })); - op(Action::PerformOperation, seq("r")); - break; - - case XXXl: // [MULU/MULS] (XXX).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // [MULU/MULS] (XXX).w, Dn - case d16An: // [MULU/MULS] (d16, An), Dn - case d16PC: // [MULU/MULS] (d16, PC), Dn - case d8AnXn: // [MULU/MULS] (d8, An, Xn), Dn - case d8PCXn: // [MULU/MULS] (d8, PX, Xn), Dn - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("n np nr np", mode), { ea(0) })); - op(Action::PerformOperation, seq("r")); - break; - - case Imm: // [MULU/MULS] #, Dn - // DEVIATION FROM YACHT.TXT. It shows an additional np, which is incorrect. - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op(Action::PerformOperation, seq("r")); - break; - } - } break; - - case Decoder::EORI_ORI_ANDI_SUBI_ADDI: { - const int mode = combined_mode(ea_mode, ea_register); - - // Source is always something cribbed from the instruction stream; - // destination is going to be in the write address unit. - program.set_source(storage_, Imm, 0); - program.set_destination(storage_, mode, ea_register); - - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, Dn - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op(Action::PerformOperation); - break; - - case l(Dn): // [EORI/ORI/ANDI/SUBI/ADDI].l #, Dn - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np nn")); - op(Action::PerformOperation); - break; - - case bw(Ind): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, (An) - case bw(PostInc): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, (An)+ - op( int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, - seq("np nrd np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { a(ea_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case l(Ind): // [EORI/ORI/ANDI/SUBI/ADDI].l #, (An) - case l(PostInc): // [EORI/ORI/ANDI/SUBI/ADDI].l #, (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("np")); - op( int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, - seq("np nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::DestinationMask); - } - break; - - case bw(PreDec): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, -(An) - op(dec(ea_register) | MicroOp::DestinationMask); - op( int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, - seq("np n nrd np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { a(ea_register) }, !is_byte_access)); - break; - - case l(PreDec): // [EORI/ORI/ANDI/SUBI/ADDI].l #, -(An) - op(int(Action::Decrement4) | MicroOp::DestinationMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("np")); - op( int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, - seq("np n nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - break; - - case bw(XXXw): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, (xxx).w - case bw(d8AnXn): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, (d8, An, Xn) - case bw(d16An): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, (d16, An) - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd np", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { ea(1) }, !is_byte_access)); - break; - - case l(XXXw): // [EORI/ORI/ANDI/SUBI/ADDI].l #, (xxx).w - case l(d8AnXn): // [EORI/ORI/ANDI/SUBI/ADDI].l #, (d8, An, Xn) - case l(d16An): // [EORI/ORI/ANDI/SUBI/ADDI].l #, (d16, An) - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nRd+ nrd np", mode), { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - break; - - case bw(XXXl): // [EORI/ORI/ANDI/SUBI/ADDI].bw #, (xxx).l - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("np nrd np", { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { ea(1) }, !is_byte_access)); - break; - - case l(XXXl): // [EORI/ORI/ANDI/SUBI/ADDI].l #, (xxx).l - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("np nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - break; - } - } break; - - case Decoder::ADD_SUB: { - // ADD and SUB definitely always involve a data register and an arbitrary addressing mode; - // which direction they operate in depends on bit 8. - const bool reverse_source_destination = !(instruction & 256); - - const int mode = combined_mode(ea_mode, ea_register); - - if(reverse_source_destination) { - program.set_destination(storage_, Dn, data_register); - program.set_source(storage_, Imm, ea_register); - - // Perform [ADD/SUB].blw , Dn - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // ADD/SUB.bw Dn, Dn - program.set_source(storage_, Dn, ea_register); -// program.source = &storage_.data_[ea_register]; - op(Action::PerformOperation, seq("np")); - break; - - case l(Dn): // ADD/SUB.l Dn, Dn - program.set_source(storage_, Dn, ea_register); -// program.source = &storage_.data_[ea_register]; - op(Action::PerformOperation, seq("np nn")); - break; - - case bw(An): // ADD/SUB.bw An, Dn - // Address registers can't provide single bytes. - if(is_byte_access) continue; - program.set_source(storage_, An, ea_register); -// program.source = &storage_.address_[ea_register]; - op(Action::PerformOperation, seq("np")); - break; - - case l(An): // ADD/SUB.l An, Dn - program.set_source(storage_, An, ea_register); -// program.source = &storage_.address_[ea_register]; - op(Action::PerformOperation, seq("np nn")); - break; - - case bw(Ind): // ADD/SUB.bw (An), Dn - case bw(PostInc): // ADD/SUB.bw (An)+, Dn - op(Action::None, seq("nr np", { a(ea_register) }, !is_byte_access)); - if(ea_mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case l(Ind): // ADD/SUB.l (An), Dn - case l(PostInc): // ADD/SUB.l (An)+, Dn - op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, - seq("nR+ nr np n", { ea(0), ea(0) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case bw(PreDec): // ADD/SUB.bw -(An), Dn - op( dec(ea_register) | MicroOp::SourceMask, - seq("n nr np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(PreDec): // ADD/SUB.l -(An), Dn - op(int(Action::Decrement4) | MicroOp::SourceMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, - seq("n nR+ nr np n", { ea(0), ea(0) })); - op(Action::PerformOperation); - break; - - case bw(XXXl): // ADD/SUB.bw (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // ADD/SUB.bw (xxx).w, Dn - case bw(d16PC): // ADD/SUB.bw (d16, PC), Dn - case bw(d8PCXn): // ADD/SUB.bw (d8, PC, Xn), Dn - case bw(d16An): // ADD/SUB.bw (d16, An), Dn - case bw(d8AnXn): // ADD/SUB.bw (d8, An, Xn), Dn - op( address_action_for_mode(mode) | MicroOp::SourceMask, - seq(pseq("np nr np", mode), { ea(0) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(XXXl): // ADD/SUB.l (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // ADD/SUB.l (xxx).w, Dn - case l(d16PC): // ADD/SUB.l (d16, PC), Dn - case l(d8PCXn): // ADD/SUB.l (d8, PC, Xn), Dn - case l(d16An): // ADD/SUB.l (d16, An), Dn - case l(d8AnXn): // ADD/SUB.l (d8, An, Xn), Dn - op( address_action_for_mode(mode) | MicroOp::SourceMask, - seq(pseq("np nR+ nr np n", mode), { ea(0), ea(0) })); - op(Action::PerformOperation); - break; - - case bw(Imm): // ADD/SUB.bw #, Dn - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op(Action::PerformOperation); - break; - - case l(Imm): // ADD/SUB.l #, Dn - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np nn")); - op(Action::PerformOperation); - break; - } - } else { - const auto destination_register = ea_register; - program.set_destination(storage_, Ind, destination_register); - program.set_source(storage_, Dn, data_register); - - // Perform [ADD/SUB].blw Dn, - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Ind): // ADD/SUB.bw Dn, (An) - case bw(PostInc): // ADD/SUB.bw Dn, (An)+ - op(Action::None, seq("nrd np", { a(destination_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { a(destination_register) }, !is_byte_access)); - if(ea_mode == PostInc) { - op(inc(destination_register) | MicroOp::DestinationMask); - } - break; - - case l(Ind): // ADD/SUB.l Dn, (An) - case l(PostInc): // ADD/SUB.l Dn, (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - if(ea_mode == PostInc) { - op(int(Action::Increment4) | MicroOp::DestinationMask); - } - break; - - case bw(PreDec): // ADD/SUB.bw Dn, -(An) - op( dec(destination_register) | MicroOp::DestinationMask, - seq("n nrd np", { a(destination_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { a(destination_register) }, !is_byte_access)); - break; - - case l(PreDec): // ADD/SUB.l Dn, -(An) - op( int(Action::Decrement4) | MicroOp::DestinationMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("n nRd+ nrd np", { ea(1), ea(1) })); - op( Action::PerformOperation, - seq("nw- nW", { ea(1), ea(1) })); - break; - - case bw(XXXl): // ADD/SUB.bw Dn, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // ADD/SUB.bw Dn, (xxx).w - case bw(d16An): // ADD/SUB.bw (d16, An), Dn - case bw(d8AnXn): // ADD/SUB.bw (d8, An, Xn), Dn - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd np", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { ea(1) }, !is_byte_access)); - break; - - case l(XXXl): // ADD/SUB.l Dn, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // ADD/SUB.l Dn, (xxx).w - case l(d16An): // ADD/SUB.l (d16, An), Dn - case l(d8AnXn): // ADD/SUB.l (d8, An, Xn), Dn - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nRd+ nrd np", mode), { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - break; - } - } - } break; - - case Decoder::ADDA_SUBA: { - program.set_destination(storage_, 1, data_register); - program.set_source(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - is_long_word_access = op_mode_high_bit; - - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // ADDA/SUBA.w Dn, An - case bw(An): // ADDA/SUBA.w An, An - case l(Dn): // ADDA/SUBA.l Dn, An - case l(An): // ADDA/SUBA.l An, An - op(Action::PerformOperation, seq("np nn")); - break; - - case bw(Ind): // ADDA/SUBA.w (An), An - case bw(PostInc): // ADDA/SUBA.w (An)+, An - op(Action::None, seq("nr np nn", { a(ea_register) })); - if(ea_mode == PostInc) { - op(int(Action::Increment2) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case l(Ind): // ADDA/SUBA.l (An), An - case l(PostInc): // ADDA/SUBA.l (An)+, An - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr np n", { ea(0), ea(0) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case bw(PreDec): // ADDA/SUBA.w -(An), An - op(int(Action::Decrement2) | MicroOp::SourceMask); - op(Action::None, seq("n nr np nn", { a(ea_register) })); - op(Action::PerformOperation); - break; - - case l(PreDec): // ADDA/SUBA.l -(An), An - op(int(Action::Decrement4) | MicroOp::SourceMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("n nR+ nr np n", { ea(0), ea(0) })); - op(Action::PerformOperation); - break; - - case bw(XXXl): // ADDA/SUBA.w (xxx).l, An - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // ADDA/SUBA.w (xxx).w, An - case bw(d16An): // ADDA/SUBA.w (d16, An), An - case bw(d8AnXn): // ADDA/SUBA.w (d8, An, Xn), An - case bw(d16PC): // ADDA/SUBA.w (d16, PC), An - case bw(d8PCXn): // ADDA/SUBA.w (d8, PC, Xn), An - op( address_action_for_mode(mode) | MicroOp::SourceMask, - seq(pseq("np nr np nn", mode), { ea(0) })); - op(Action::PerformOperation); - break; - - case l(XXXl): // ADDA/SUBA.l (xxx).l, An - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // ADDA/SUBA.l (xxx).w, An - case l(d16An): // ADDA/SUBA.l (d16, An), An - case l(d8AnXn): // ADDA/SUBA.l (d8, An, Xn), An - case l(d16PC): // ADDA/SUBA.l (d16, PC), An - case l(d8PCXn): // ADDA/SUBA.l (d8, PC, Xn), An - op( address_action_for_mode(mode) | MicroOp::SourceMask, - seq(pseq("np nR+ nr np n", mode), { ea(0), ea(0) })); - op(Action::PerformOperation); - break; - - case bw(Imm): // ADDA/SUBA.w #, An - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np nn")); - op(Action::PerformOperation); - break; - - case l(Imm): // ADDA/SUBA.l #, Dn - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np nn")); - op(Action::PerformOperation); - break; - } - } break; - - case Decoder::ADDQ_SUBQ: { - program.set_destination(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - - // If the destination is an address register then byte mode isn't allowed, and - // flags shouldn't be affected (so, a different operation is used). - if(mode == An) { - if(is_byte_access) continue; - switch(operation) { - default: break; - case Operation::ADDQl: // TODO: should the adds be distinguished? If so, how? - case Operation::ADDQw: operation = Operation::ADDQAl; break; - case Operation::SUBQl: - case Operation::SUBQw: operation = Operation::SUBQAl; break; - } - } - - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // [ADD/SUB]Q.bw #, Dn - op(Action::PerformOperation, seq("np")); - break; - - case l(Dn): // [ADD/SUB]Q.l #, Dn - case l(An): // [ADD/SUB]Q.l #, An - case bw(An): // [ADD/SUB]Q.bw #, An - op(Action::PerformOperation, seq("np nn")); - break; - - case bw(Ind): // [ADD/SUB]Q.bw #, (An) - case bw(PostInc): // [ADD/SUB]Q.bw #, (An)+ - op(Action::None, seq("nrd np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { a(ea_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case l(PreDec): // [ADD/SUB]Q.l #, -(An) - op(int(Action::Decrement4) | MicroOp::DestinationMask, seq("n")); - [[fallthrough]]; - case l(Ind): // [ADD/SUB]Q.l #, (An) - case l(PostInc): // [ADD/SUB]Q.l #, (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::DestinationMask); - } - break; - - case bw(PreDec): // [ADD/SUB]Q.bw #, -(An) - op( dec(ea_register) | MicroOp::DestinationMask, - seq("n nrd np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { a(ea_register) }, !is_byte_access)); - break; - - case bw(XXXl): // [ADD/SUB]Q.bw #, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // [ADD/SUB]Q.bw #, (xxx).w - case bw(d16An): // [ADD/SUB]Q.bw #, (d16, An) - case bw(d8AnXn): // [ADD/SUB]Q.bw #, (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nrd np", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { ea(1) }, !is_byte_access)); - break; - - case l(XXXl): // [ADD/SUB]Q.l #, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // [ADD/SUB]Q.l #, (xxx).w - case l(d16An): // [ADD/SUB]Q.l #, (d16, An) - case l(d8AnXn): // [ADD/SUB]Q.l #, (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nRd+ nrd np", mode), { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- nW", { ea(1), ea(1) })); - break; - } - } break; - - case Decoder::ADDX_SUBX: { - if(instruction & 0x8) { - // Use predecrementing address registers. - program.set_source(storage_, Ind, ea_register); - program.set_destination(storage_, Ind, data_register); - - if(is_long_word_access) { - // Access order is very atypical here: it's lower parts each for both words, - // and then also a lower-part-first write. - op(int(Action::Decrement2) | MicroOp::SourceMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, - seq("n nr- nR", { ea(0), ea(0) })); - op(int(Action::Decrement2) | MicroOp::DestinationMask | MicroOp::SourceMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("nrd- nRd+", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("nw- np nW", { ea(1), ea(1) })); - op(int(Action::Decrement2) | MicroOp::DestinationMask); - } else { - op(dec(ea_register) | MicroOp::SourceMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, - seq("n nr", { ea(0) }, !is_byte_access)); - op(dec(data_register) | MicroOp::DestinationMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("nrd np", { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("nw", { ea(1) }, !is_byte_access)); - } - } else { - // Use data registers. - program.set_source(storage_, Dn, ea_register); - program.set_destination(storage_, Dn, data_register); - - if(is_long_word_access) { - op(Action::PerformOperation, seq("np nn")); - } else { - op(Action::PerformOperation, seq("np")); - } - } - - } break; - - // This decoder actually decodes nothing; it just schedules a PerformOperation followed by an empty step. - case Decoder::Bcc_BSR: { - const int condition = (instruction >> 8) & 0xf; - if(condition == 1) { - // This is BSR, which is unconditional and means pushing a return address to the stack first. - - // Push the return address to the stack. - op(Action::PrepareBSR, seq("n nW+ nw", { ea(1), ea(1) })); - } - - // This is Bcc. - op(Action::PerformOperation); - op(); // The above looks terminal, but will be dynamically reprogrammed. - } break; - - // A little artificial, there's nothing really to decode for BRA. - case Decoder::BRA: { - op(Action::PerformOperation, seq("n np np")); - } break; - - // Decodes a BTST, potential mutating the operation into a BTSTl, - // or a BCLR. - case Decoder::BCLR: - case Decoder::BTST: { - const bool is_bclr = mapping.decoder == Decoder::BCLR; - - program.set_source(storage_, 0, data_register); - program.set_destination(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // BTST.l Dn, Dn - if(is_bclr) { - operation = Operation::BCLRl; - op(Action::None, seq("np")); - op(Action::PerformOperation, seq("r")); - } else { - operation = Operation::BTSTl; - op(Action::PerformOperation, seq("np n")); - } - break; - - case Ind: // BTST.b Dn, (An) - case PostInc: // BTST.b Dn, (An)+ - op(Action::None, seq("nrd np", { a(ea_register) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { a(ea_register) }, false) : MicroOp::NoBusProgram); - if(mode == PostInc) { - op(byte_inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case PreDec: // BTST.b Dn, -(An) - op(byte_dec(ea_register) | MicroOp::DestinationMask, seq("n nrd np", { a(ea_register) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { a(ea_register) }, false) : MicroOp::NoBusProgram); - break; - - case XXXl: // BTST.b Dn, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // BTST.b Dn, (xxx).w - case d16An: // BTST.b Dn, (d16, An) - case d8AnXn: // BTST.b Dn, (d8, An, Xn) - case d16PC: // BTST.b Dn, (d16, PC) - case d8PCXn: // BTST.b Dn, (d8, PC, Xn) - // PC-relative addressing isn't support for BCLR. - if((mode == d16PC || mode == d8PCXn) && is_bclr) continue; - - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd np", mode), { ea(1) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { ea(1) }, false) : MicroOp::NoBusProgram); - break; - - case Imm: // BTST.b Dn, # - if(is_bclr) continue; - - /* Yacht.txt doesn't cover this; this is a guess. */ - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::DestinationMask, seq("np")); - op(Action::PerformOperation, seq("np")); - break; - } - } break; - - case Decoder::BCLRIMM: - case Decoder::BTSTIMM: { - const bool is_bclr = mapping.decoder == Decoder::BCLRIMM; - - program.set_source(storage_, Imm, 0); - program.set_destination(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // BTST.l #, Dn - if(is_bclr) { - operation = Operation::BCLRl; - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op(Action::PerformOperation, seq("r")); - } else { - operation = Operation::BTSTl; - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np n")); - op(Action::PerformOperation); - } - break; - - case Ind: // BTST.b #, (An) - case PostInc: // BTST.b #, (An)+ - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np nrd np", { a(ea_register) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { a(ea_register) }, false) : MicroOp::NoBusProgram); - if(mode == PostInc) { - op(byte_inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case PreDec: // BTST.b #, -(An) - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op(byte_dec(ea_register) | MicroOp::DestinationMask, seq("n nrd np", { a(ea_register) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { a(ea_register) }, false) : MicroOp::NoBusProgram); - break; - - case XXXw: // BTST.b #, (xxx).w - case d16An: // BTST.b #, (d16, An) - case d8AnXn: // BTST.b #, (d8, An, Xn) - case d16PC: // BTST.b #, (d16, PC) - case d8PCXn: // BTST.b #, (d8, PC, Xn) - // PC-relative addressing isn't support for BCLR. - if((mode == d16PC || mode == d8PCXn) && is_bclr) continue; - - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd np", mode), { ea(1) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { ea(1) }, false) : MicroOp::NoBusProgram); - break; - - case XXXl: // BTST.b #, (xxx).l - op( int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("np nrd np", { ea(1) }, false)); - op(Action::PerformOperation, is_bclr ? seq("nw", { ea(1) }, false) : MicroOp::NoBusProgram); - break; - } - } break; - - // Decodes the format used by ABCD and SBCD. - case Decoder::ABCD_SBCD: { - if(instruction & 8) { - // [A/S]BCD -(An), -(An) - program.set_source(storage_, Ind, ea_register); - program.set_destination(storage_, Ind, data_register); - - op(MicroOp::SourceMask | dec(ea_register), seq("n nr", { a(ea_register) }, false )); - op(MicroOp::DestinationMask | dec(data_register), seq("nrd np", { a(data_register) }, false )); - op(Action::PerformOperation, seq("nw", { a(data_register) }, false)); - } else { - // [A/S]BCD Dn, Dn - program.set_source(storage_, Dn, ea_register); - program.set_destination(storage_, Dn, data_register); - - op(Action::PerformOperation, seq("np n")); - } - } break; - - case Decoder::ASLR_LSLR_ROLR_ROXLRr: { - program.set_destination(storage_, 0, ea_register); - - // All further decoding occurs at runtime; that's also when the proper number of - // no-op cycles will be scheduled. - if(((instruction >> 6) & 3) == 2) { - op(Action::None, seq("np nn")); // Long-word rotates take an extra two cycles. - } else { - op(Action::None, seq("np n")); - } - - // Use a no-op bus cycle that can have its length filled in later. - op(Action::PerformOperation, seq("r")); - } break; - - case Decoder::ASLR_LSLR_ROLR_ROXLRm: { - program.set_destination(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Ind: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w (An) - case PostInc: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w (An)+ - op(Action::None, seq("nrd np", { a(ea_register) })); - op(Action::PerformOperation, seq("nw", { a(ea_register) })); - if(ea_mode == PostInc) { - op(int(Action::Increment2) | MicroOp::DestinationMask); - } - break; - - case PreDec: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w -(An) - op(int(Action::Decrement2) | MicroOp::DestinationMask, seq("n nrd np", { a(ea_register) })); - op(Action::PerformOperation, seq("nw", { a(ea_register) })); - break; - - case XXXl: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w (xxx).w - case d16An: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w (d16, An) - case d8AnXn: // AS(L/R)/LS(L/R)/RO(L/R)/ROX(L/R).w (d8, An, Xn) - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd np", mode), { ea(1) })); - op(Action::PerformOperation, seq("nw", { ea(1) })); - break; - } - } break; - - case Decoder::CLR_NEG_NEGX_NOT: { - program.set_destination(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // [CLR/NEG/NEGX/NOT].bw Dn - op(Action::PerformOperation, seq("np")); - break; - - case l(Dn): // [CLR/NEG/NEGX/NOT].l Dn - op(Action::PerformOperation, seq("np n")); - break; - - case bw(Ind): // [CLR/NEG/NEGX/NOT].bw (An) - case bw(PostInc): // [CLR/NEG/NEGX/NOT].bw (An)+ - op(Action::None, seq("nrd", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { a(ea_register) }, !is_byte_access)); - if(ea_mode == PostInc) { - op(inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case l(Ind): // [CLR/NEG/NEGX/NOT].l (An) - case l(PostInc): // [CLR/NEG/NEGX/NOT].l (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("nRd+ nrd", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("np nw- nW", { ea(1), ea(1) })); - if(ea_mode == PostInc) { - op(int(Action::Increment4) | MicroOp::DestinationMask); - } - break; - - case bw(PreDec): // [CLR/NEG/NEGX/NOT].bw -(An) - op( dec(ea_register) | MicroOp::DestinationMask, - seq("nrd", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { a(ea_register) }, !is_byte_access)); - break; - - case l(PreDec): // [CLR/NEG/NEGX/NOT].l -(An) - op(int(Action::Decrement4) | MicroOp::DestinationMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("n nRd+ nrd", { ea(1), ea(1) })); - op(Action::PerformOperation, seq("np nw- nW", { ea(1), ea(1) })); - break; - - case bw(XXXl): // [CLR/NEG/NEGX/NOT].bw (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // [CLR/NEG/NEGX/NOT].bw (xxx).w - case bw(d16An): // [CLR/NEG/NEGX/NOT].bw (d16, An) - case bw(d8AnXn): // [CLR/NEG/NEGX/NOT].bw (d8, An, Xn) - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { ea(1) }, !is_byte_access)); - break; - - case l(XXXl): // [CLR/NEG/NEGX/NOT].l (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // [CLR/NEG/NEGX/NOT].l (xxx).w - case l(d16An): // [CLR/NEG/NEGX/NOT].l (d16, An) - case l(d8AnXn): // [CLR/NEG/NEGX/NOT].l (d8, An, Xn) - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nRd+ nrd", mode), { ea(1), ea(1) })); - op(Action::PerformOperation, seq("np nw- nW", { ea(1), ea(1) })); - break; - } - } break; - - case Decoder::CMP: { - program.set_destination(storage_, Dn, data_register); - program.set_source(storage_, ea_mode, ea_register); - - // Byte accesses are not allowed with address registers. - if(is_byte_access && ea_mode == An) { - continue; - } - - const int mode = combined_mode(ea_mode, ea_register); - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // CMP.bw Dn, Dn - case bw(An): // CMP.w An, Dn - op(Action::PerformOperation, seq("np")); - break; - - case l(Dn): // CMP.l Dn, Dn - case l(An): // CMP.l An, Dn - op(Action::PerformOperation, seq("np n")); - break; - - case bw(Ind): // CMP.bw (An), Dn - case bw(PostInc): // CMP.bw (An)+, Dn - op(Action::None, seq("nr np", { a(ea_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case l(Ind): // CMP.l (An), Dn - case l(PostInc): // CMP.l (An)+, Dn - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr np n", { ea(0), ea(0) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case bw(PreDec): // CMP.bw -(An), Dn - op( dec(ea_register) | MicroOp::SourceMask, - seq("n nr np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(PreDec): // CMP.l -(An), Dn - op(int(Action::Decrement4) | MicroOp::SourceMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("n nR+ nr np n", { ea(0), ea(0) })); - op(Action::PerformOperation); - break; - - case bw(XXXl): // CMP.bw (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // CMP.bw (xxx).w, Dn - case bw(d16An): // CMP.bw (d16, An), Dn - case bw(d8AnXn): // CMP.bw (d8, An, Xn), Dn - case bw(d16PC): // CMP.bw (d16, PC), Dn - case bw(d8PCXn): // CMP.bw (d8, PC, Xn), Dn - op( address_action_for_mode(mode) | MicroOp::SourceMask, - seq(pseq("np nr np", mode), { ea(0) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(XXXl): // CMP.l (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // CMP.l (xxx).w, Dn - case l(d16An): // CMP.l (d16, An), Dn - case l(d8AnXn): // CMP.l (d8, An, Xn), Dn - case l(d16PC): // CMP.l (d16, PC), Dn - case l(d8PCXn): // CMP.l (d8, PC, Xn), Dn - op( address_action_for_mode(mode) | MicroOp::SourceMask, - seq(pseq("np nR+ nr np n", mode), { ea(0), ea(0) })); - op(Action::PerformOperation); - break; - - case bw(Imm): // CMP.br #, Dn - program.set_source(storage_, &storage_.prefetch_queue_); - op(Action::PerformOperation, seq("np np")); - break; - - case l(Imm): // CMP.l #, Dn - program.set_source(storage_, &storage_.prefetch_queue_); - op(Action::None, seq("np")); - op(Action::PerformOperation, seq("np np n")); - break; - } - } break; - - case Decoder::CMPA: { - // Only operation modes 011 and 111 are accepted, and long words are selected - // by the top bit. - if(((op_mode)&3) != 3) continue; - is_long_word_access = op_mode == 7; - - program.set_source(storage_, ea_mode, ea_register); - program.set_destination(storage_, An, data_register); - - const int mode = combined_mode(ea_mode, ea_register, true); - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // CMPA.w [An/Dn], An - case l(Dn): // CMPA.l [An/Dn], An - op(Action::PerformOperation, seq("np n")); - break; - - case bw(Ind): // CMPA.w (An), An - case bw(PostInc): // CMPA.w (An)+, An - op(Action::None, seq("nr", { a(ea_register) })); - op(Action::PerformOperation, seq("np n")); - if(mode == PostInc) { - op(int(Action::Increment2) | MicroOp::SourceMask); - } - break; - - case l(Ind): // CMPA.l (An), An - case l(PostInc): // CMPA.l (An)+, An - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr", { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np n")); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::SourceMask); - } - break; - - case bw(PreDec): // CMPA.w -(An), An - op(int(Action::Decrement2) | MicroOp::SourceMask, seq("n nr", { a(ea_register) })); - op(Action::PerformOperation, seq("np n")); - break; - - case l(PreDec): // CMPA.l -(An), An - op(int(Action::Decrement4) | MicroOp::SourceMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr", { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np n")); - break; - - case bw(XXXl): // CMPA.w (xxx).l, An - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // CMPA.w (xxx).w, An - case bw(d16PC): // CMPA.w (d16, PC), An - case bw(d8PCXn): // CMPA.w (d8, PC, Xn), An - case bw(d16An): // CMPA.w (d16, An), An - case bw(d8AnXn): // CMPA.w (d8, An, Xn), An - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr", mode), { ea(0) })); - op(Action::PerformOperation, seq("np n")); - break; - - case l(XXXl): // CMPA.l (xxx).l, An - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // CMPA.l (xxx).w, An - case l(d16PC): // CMPA.l (d16, PC), An - case l(d8PCXn): // CMPA.l (d8, PC, Xn), An - case l(d16An): // CMPA.l (d16, An), An - case l(d8AnXn): // CMPA.l (d8, An, Xn), An - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nR+ nr", mode), { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np n")); - break; - - case bw(Imm): // CMPA.w #, An - program.set_source(storage_, &storage_.prefetch_queue_); - op(Action::PerformOperation, seq("np np n")); - break; - - case l(Imm): // CMPA.l #, An - program.set_source(storage_, &storage_.prefetch_queue_); - op(Action::None, seq("np")); - op(Action::PerformOperation, seq("np np n")); - break; - } - } break; - - case Decoder::CMPI: { - if(ea_mode == An) continue; - - const auto destination_mode = ea_mode; - const auto destination_register = ea_register; - - program.set_source(storage_, Imm, 0); // i.e. from the fetched data latch. - program.set_destination(storage_, destination_mode, destination_register); - - const int mode = combined_mode(destination_mode, destination_register); - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // CMPI.bw #, Dn - program.set_source(storage_, &storage_.prefetch_queue_); - op(Action::PerformOperation, seq("np np")); - break; - - case l(Dn): // CMPI.l #, Dn - program.set_source(storage_, &storage_.prefetch_queue_); - op(Action::None, seq("np")); - op(Action::PerformOperation, seq("np np n")); - break; - - case bw(Ind): // CMPI.bw #, (An) - case bw(PostInc): // CMPI.bw #, (An)+ - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np nrd np", { a(destination_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(destination_register) | MicroOp::DestinationMask); - } - op(Action::PerformOperation); - break; - - case l(Ind): // CMPI.l #, (An) - case l(PostInc): // CMPI.l #, (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np nRd+ nrd np", { ea(1), ea(1) })); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::DestinationMask); - } - op(Action::PerformOperation); - break; - - case bw(PreDec): // CMPI.bw #, -(An) - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np n")); - op(dec(destination_register) | MicroOp::DestinationMask, seq("nrd np", { a(destination_register) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(PreDec): // CMPI.l #, -(An) - op(int(Action::Decrement4) | MicroOp::DestinationMask, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np n")); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation); - break; - - case bw(XXXw): // CMPI.bw #, (xxx).w - case bw(d16An): // CMPI.bw #, (d16, An) - case bw(d8AnXn): // CMPI.bw #, (d8, An, Xn) - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op( address_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nrd np", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(d16An): // CMPI.l #, (d16, An) - case l(d8AnXn): // CMPI.l #, (d8, An, Xn) - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op( calc_action_for_mode(mode) | MicroOp::DestinationMask, - seq(pseq("np nRd+ nrd np", mode), { ea(1), ea(1) })); - op(Action::PerformOperation); - break; - - case l(XXXw): // CMPI.l #, (xxx).w - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - op(int(Action::AssembleWordAddressFromPrefetch) | MicroOp::DestinationMask, seq("np nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation); - break; - - case bw(XXXl): // CMPI.bw #, (xxx).l - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op(int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, seq("np nrd np", { ea(1) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case l(XXXl): // CMPI.l #, (xxx).l - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - op(int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, seq("np nRd+ nrd np", { ea(1), ea(1) })); - op(Action::PerformOperation); - break; - } - } break; - - case Decoder::CMPM: { - program.set_source(storage_, PostInc, ea_register); - program.set_destination(storage_, PostInc, data_register); - - const bool is_byte_operation = operation == Operation::CMPb; - - switch(operation) { - default: continue; - - case Operation::CMPb: // CMPM.b, (An)+, (An)+ - case Operation::CMPw: // CMPM.w, (An)+, (An)+ - op(Action::None, seq("nr", { a(ea_register) }, !is_byte_operation)); - op( inc(ea_register) | MicroOp::SourceMask, - seq("nrd np", { a(data_register) }, !is_byte_operation)); - op(inc(data_register) | MicroOp::DestinationMask); - op(Action::PerformOperation); - break; - - case Operation::CMPl: // CMPM.l, (An)+, (An)+ - op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, - seq("nR+ nr", {ea(0), ea(0)})); - op(int(Action::Increment4) | MicroOp::SourceMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("nRd+ nrd np", {ea(1), ea(1)})); - op(int(Action::Increment4) | MicroOp::DestinationMask); - op(Action::PerformOperation); - break; - } - } break; - - case Decoder::Scc_DBcc: { - if(ea_mode == 1) { - // This is a DBcc. Decode as such. - operation = Operation::DBcc; - program.set_source(storage_, Dn, ea_register); - - // Jump straight into deciding what steps to take next, - // which will be selected dynamically. - op(Action::PerformOperation); - op(); - } else { - // This is an Scc. - - // Scc is implemented on the 68000 a read-modify-write operation. - program.set_source(storage_, ea_mode, ea_register); - program.set_destination(storage_, ea_mode, ea_register); - - // Scc is always a byte operation. - is_byte_access = true; - is_long_word_access = false; - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: - op(Action::PerformOperation, seq("np")); - // TODO: if condition true, an extra n. - break; - - case Ind: - case PostInc: - op(Action::PerformOperation, seq("nr np nw", { a(ea_register), a(ea_register) }, false)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case PreDec: - op(dec(ea_register) | MicroOp::DestinationMask); - op(Action::PerformOperation, seq("n nr np nw", { a(ea_register), a(ea_register) }, false)); - break; - - case XXXl: - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: - case d16An: - case d8AnXn: - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nrd", mode), { ea(1) } , false)); - op(Action::PerformOperation, seq("np nw", { ea(1) } , false)); - break; - } - } - - } break; - - case Decoder::JSR: { - // Ensure a proper source register is connected up for (d16, An) and (d8, An, Xn)-type addressing. - program.set_source(storage_, ea_mode, ea_register); - - // ... but otherwise assume that the true source of a destination will be the computed source address. - program.set_source(storage_, &storage_.effective_address_[0]); - - // Beware below: PrepareJSR will pre-emptively subtract four from A7 in order - // to facilitate the peculiar stack write order of JSR. Therefore any address - // calculation that might be a function of A7 needs to be done before PrepareJSR. - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - case Ind: // JSR (An) - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask); - op(Action::PrepareJSR); - op(Action::PerformOperation, seq("np nW+ nw np", { ea(1), ea(1) })); - break; - - case XXXl: // JSR (xxx).L - op(Action::None, seq("np")); - op(Action::PrepareJSR); // TODO: improve PrepareJSR to be able to compute alternative - // offsets from the current PC, and thereby move this one slot earlier. - op(address_action_for_mode(mode) | MicroOp::SourceMask); - op(Action::PerformOperation, seq("np nW+ nw np", { ea(1), ea(1) })); - break; - - case XXXw: // JSR (xxx).W - case d16PC: // JSR (d16, PC) - case d16An: // JSR (d16, An) - op(address_action_for_mode(mode) | MicroOp::SourceMask); - op(Action::PrepareJSR); - op(Action::PerformOperation, seq("n np nW+ nw np", { ea(1), ea(1) })); - break; - - case d8PCXn: // JSR (d8, PC, Xn) - case d8AnXn: // JSR (d8, An, Xn) - op(calc_action_for_mode(mode) | MicroOp::SourceMask); - op(Action::PrepareJSR); - op(Action::PerformOperation, seq("n nn np nW+ nw np", { ea(1), ea(1) })); - break; - } - } break; - - case Decoder::RTS: { - op(Action::PrepareRTS, seq("nU nu")); - op(Action::PerformOperation, seq("np np")); - } break; - - case Decoder::JMP: { - program.set_source(storage_, ea_mode, ea_register); - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - case Ind: // JMP (An) - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask); - op(Action::PerformOperation, seq("np np")); - break; - - case XXXw: // JMP (xxx).W - case d16PC: // JMP (d16, PC) - case d16An: // JMP (d16, An) - op(address_action_for_mode(mode) | MicroOp::SourceMask); - op(Action::PerformOperation, seq("n np np")); - break; - - case d8PCXn: // JMP (d8, PC, Xn) - case d8AnXn: // JMP (d8, An, Xn) - op(calc_action_for_mode(mode) | MicroOp::SourceMask); - op(Action::PerformOperation, seq("n nn np np")); - break; - - case XXXl: // JMP (xxx).L - op(Action::None, seq("np")); - op(address_assemble_for_mode(mode) | MicroOp::SourceMask); - op(Action::PerformOperation, seq("np np")); - break; - } - } break; - - case Decoder::PEA: { - program.set_source(storage_, An, ea_register); - program.set_destination(storage_, Imm, 7); // Immediate destination => store to the destination bus latch. - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Ind: // PEA (An) - operation = Operation::MOVEAl; - op(Action::PerformOperation); - op(int(Action::Decrement4) | MicroOp::DestinationMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, seq("np nW+ nw", { ea(1), ea(1) })); - break; - - case XXXl: // PEA (XXX).l - case XXXw: // PEA (XXX).w - op(int(Action::Decrement4) | MicroOp::DestinationMask, (mode == XXXl) ? seq("np") : MicroOp::NoBusProgram); - op(address_assemble_for_mode(mode) | MicroOp::SourceMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask); - op(Action::PerformOperation, seq("np nW+ nw np", { ea(1), ea(1) })); - break; - - case d16An: // PEA (d16, An) - case d16PC: // PEA (d16, PC) - case d8AnXn: // PEA (d8, An, Xn) - case d8PCXn: // PEA (d8, PC, Xn) - op(calc_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np", mode))); - op(int(Action::Decrement4) | MicroOp::DestinationMask); - op(int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask); - op(Action::PerformOperation, seq(pseq("np nW+ nw", mode), { ea(1), ea(1) })); - break; - } - } break; - - case Decoder::LEA: { - program.set_destination(storage_, An, data_register); - - const int mode = combined_mode(ea_mode, ea_register); - program.set_source_address(storage_, ea_register); - program.set_source(storage_, - (mode == Ind) ? - &storage_.address_[ea_register] : - &storage_.effective_address_[0]); - - switch(mode) { - default: continue; - case Ind: // LEA (An), An (i.e. MOVEA) - op(Action::PerformOperation, seq("np")); - break; - - case XXXl: // LEA (xxx).L, An - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // LEA (xxx).W, An - case d16An: // LEA (d16, An), An - case d16PC: // LEA (d16, PC), An - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq("np np")); - op(Action::PerformOperation); - break; - - case d8AnXn: // LEA (d8, An, Xn), An - case d8PCXn: // LEA (d8, PC, Xn), An - op(calc_action_for_mode(mode) | MicroOp::SourceMask, seq("n np n np")); - op(Action::PerformOperation); - break; - } - } break; - - case Decoder::MOVEfromSR_NBCD: { - program.set_destination(storage_, ea_mode, ea_register); - - is_byte_access = operation == Operation::NBCD; - is_long_word_access = false; - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // MOVE SR, Dn - op(Action::PerformOperation, seq("np n")); - break; - - case Ind: // MOVE SR, (An) - case PostInc: // MOVE SR, (An)+ - op(Action::None, seq("nrd", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { a(ea_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::DestinationMask); - } - break; - - case PreDec: // MOVE SR, -(An) - op(dec(ea_register) | MicroOp::DestinationMask, seq("n nrd", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { a(ea_register) }, !is_byte_access)); - break; - - case XXXl: // MOVE SR, (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // MOVE SR, (xxx).w - case d16An: // MOVE SR, (d16, An) - case d8AnXn: // MOVE SR, (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np nrd", mode), { ea(1) }, !is_byte_access)); - op(Action::PerformOperation, seq("np nw", { ea(1) }, !is_byte_access)); - break; - } - } break; - - case Decoder::MOVEtoSRCCR: { - if(ea_mode == An) continue; - program.set_source(storage_, ea_mode, ea_register); - program.set_requires_supervisor(operation == Operation::MOVEtoSR); - - is_long_word_access = false; - is_byte_access = false; // Even MOVE, CCR is a .w. - - /* DEVIATION FROM YACHT.TXT: it has all of these reading an extra word from the PC; - this looks like a mistake so I've padded with nil cycles in the middle. */ - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // MOVE Dn, SR/CCR - op(Action::PerformOperation, seq("nn np")); - break; - - case Ind: // MOVE (An), SR/CCR - case PostInc: // MOVE (An)+, SR/CCR - op(Action::None, seq("nr nn nn np", { a(ea_register) }, !is_byte_access)); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - op(Action::PerformOperation); - break; - - case PreDec: // MOVE -(An), SR/CCR - op(dec(ea_register) | MicroOp::SourceMask, seq("n nr nn nn np", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case XXXl: // MOVE (xxx).L, SR/CCR - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // MOVE (xxx).W, SR/CCR - case d16PC: // MOVE (d16, PC), SR/CCR - case d8PCXn: // MOVE (d8, PC, Xn), SR/CCR - case d16An: // MOVE (d16, An), SR/CCR - case d8AnXn: // MOVE (d8, An, Xn), SR/CCR - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr nn nn np", mode), { ea(0) }, !is_byte_access)); - op(Action::PerformOperation); - break; - - case Imm: // MOVE #, SR/CCR - program.set_source(storage_, &storage_.prefetch_queue_); - op(int(Action::PerformOperation), seq("np nn nn np")); - break; - } - } break; - - case Decoder::MOVEq: { - program.set_destination(storage_, Dn, data_register); - op(Action::PerformOperation, seq("np")); - } break; - - case Decoder::MOVEP: { - program.set_destination(storage_, An, ea_register); - program.set_source(storage_, Dn, data_register); - - switch(operation) { - default: continue; - - // Both of the MOVEP to memory instructions perform their operation first — it will - // break up the source value into 8-bit chunks for the write section. - case Operation::MOVEPtoMw: - op(Action::PerformOperation); - op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nW+ nw np", { ea(1), ea(1) }, false)); - break; - - case Operation::MOVEPtoMl: - op(Action::PerformOperation); - op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nW+ nWr+ nw+ nwr np", { ea(1), ea(1), ea(1), ea(1) }, false)); - break; - - case Operation::MOVEPtoRw: - op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nRd+ nrd np", { ea(1), ea(1) }, false)); - op(Action::PerformOperation); - break; - - case Operation::MOVEPtoRl: - // TODO: nR+ increments EA(0), not EA(1). Fix. - op(int(Action::CalcD16An) | MicroOp::DestinationMask, seq("np nRd+ nR+ nrd+ nr np", { ea(1), ea(1), ea(1), ea(1) }, false)); - op(Action::PerformOperation); - break; - } - } break; - - case Decoder::MOVEM: { - // For the sake of commonality, both to R and to M will evaluate their addresses - // as if they were destinations. - program.set_destination(storage_, ea_mode, ea_register); - - // Standard prefix: acquire the register selection flags and fetch the next program - // word to replace them. - op(Action::CopyNextWord, seq("np")); - - // Do whatever is necessary to calculate the proper start address. - const int mode = combined_mode(ea_mode, ea_register); - const bool is_to_m = (operation == Operation::MOVEMtoMl || operation == Operation::MOVEMtoMw); - switch(mode) { - default: continue; - - case Ind: - case PreDec: - case PostInc: { - // Deal with the illegal combinations. - if(mode == PostInc && is_to_m) continue; - if(mode == PreDec && !is_to_m) continue; - } break; - - case XXXl: - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: - case d16An: - case d8AnXn: - case d16PC: - case d8PCXn: - // PC-relative addressing is permitted for moving to registers only. - if((mode == d16PC || mode == d8PCXn) && is_to_m) continue; - op(address_action_for_mode(mode) | MicroOp::DestinationMask, seq(pseq("np", mode))); - break; - } - - // Standard suffix: perform the MOVEM, which will mean evaluating the - // register selection flags and substituting the necessary reads or writes. - op(Action::PerformOperation); - - // A final program fetch will cue up the next instruction. - op(is_to_m ? Action::MOVEMtoMComplete : Action::MOVEMtoRComplete, seq("np")); - } break; - - case Decoder::MOVEUSP: { - program.set_requires_supervisor(true); - - // Observation here: because this is a privileged instruction, the user stack pointer - // definitely isn't currently [copied into] A7. - if(instruction & 0x8) { - // Transfer FROM the USP. - program.set_source(storage_, &storage_.stack_pointers_[0]); - program.set_destination(storage_, An, ea_register); - } else { - // Transfer TO the USP. - program.set_source(storage_, An, ea_register); - program.set_destination(storage_, &storage_.stack_pointers_[0]); - } - - op(Action::PerformOperation, seq("np")); - } break; - - // Decodes the format used by most MOVEs and all MOVEAs. - case Decoder::MOVE: { - const int destination_mode = (instruction >> 6) & 7; - - program.set_source(storage_, ea_mode, ea_register); - program.set_destination(storage_, destination_mode, data_register); - - // These don't come from the usual place. - is_byte_access = mapping.operation == Operation::MOVEb; - is_long_word_access = mapping.operation == Operation::MOVEl; - - // If the move is to an address register, switch the MOVE to a MOVEA. - // Also: there are no byte moves to address registers. - if(destination_mode == An) { - if(is_byte_access) { - continue; - } - operation = is_long_word_access ? Operation::MOVEAl : Operation::MOVEAw; - } - - // ... there are also no byte moves from address registers. - if(ea_mode == An && is_byte_access) continue; - - // Perform the MOVE[A]'s fetch.. - const int combined_source_mode = combined_mode(ea_mode, ea_register, true); - switch(is_long_word_access ? l(combined_source_mode) : bw(combined_source_mode)) { - default: continue; - - case l(Dn): // MOVE[A].l [An/Dn], - case bw(Dn): // MOVE[A].bw [An/Dn], - break; - - case bw(PreDec): // MOVE[A].bw -(An), - op(dec(ea_register) | MicroOp::SourceMask, seq("n nr", { a(ea_register) }, !is_byte_access)); - break; - - case bw(Ind): // MOVE[A].bw (An), - case bw(PostInc): // MOVE[A].bw (An)+, - op(Action::None, seq("nr", { a(ea_register) }, !is_byte_access)); - if(combined_source_mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - break; - - case l(PreDec): // MOVE[A].l -(An), - op(dec(ea_register) | MicroOp::SourceMask, seq("n")); - [[fallthrough]]; - case l(Ind): // MOVE[A].l (An), - case l(PostInc): // MOVE[A].l (An)+, - op( int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, - seq("nR+ nr", { ea(0), ea(0) })); - if(combined_source_mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - break; - - case bw(XXXl): // MOVE[A].bw (xxx).L, - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // MOVE[A].bw (xxx).W, - case bw(d16An): // MOVE[A].bw (d16, An), - case bw(d8AnXn): // MOVE[A].bw (d8, An, Xn), - case bw(d16PC): // MOVE[A].bw (d16, PC), - case bw(d8PCXn): // MOVE[A].bw (d8, PC, Xn), - op( address_action_for_mode(combined_source_mode) | MicroOp::SourceMask, - seq(pseq("np nr", combined_source_mode), { ea(0) }, - !is_byte_access)); - break; - - case l(XXXl): // MOVE[A].l (xxx).L, - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // MOVE[A].l (xxx).W, - case l(d16An): // MOVE[A].l (d16, An), - case l(d8AnXn): // MOVE[A].l (d8, An, Xn), - case l(d16PC): // MOVE[A].l (d16, PC), - case l(d8PCXn): // MOVE[A].l (d8, PC, Xn), - op( address_action_for_mode(combined_source_mode) | MicroOp::SourceMask, - seq(pseq("np nR+ nr", combined_source_mode), { ea(0), ea(0) })); - break; - - case l(Imm): // MOVE[A].l #, - op(Action::None, seq("np")); - op(int(Action::AssembleLongWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - break; - - case bw(Imm): // MOVE[A].bw #, - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np")); - break; - } - - // Perform the MOVE[A]'s store. - const int combined_destination_mode = combined_mode(destination_mode, data_register, true); - switch(is_long_word_access ? l(combined_destination_mode) : bw(combined_destination_mode)) { - default: continue; - - case l(Dn): // MOVE[A].l , [An/Dn] - case bw(Dn): // MOVE[A].bw , [An/Dn] - op(Action::PerformOperation, seq("np")); - break; - - case bw(PreDec): // MOVE[A].bw , -(An) - op(Action::PerformOperation); - op( dec(data_register) | MicroOp::DestinationMask, - seq("np nw", { a(data_register) }, !is_byte_access)); - break; - - case bw(Ind): // MOVE[A].bw , (An) - case bw(PostInc): // MOVE[A].bw , (An)+ - op(Action::PerformOperation, seq("nw np", { a(data_register) }, !is_byte_access)); - if(combined_destination_mode == PostInc) { - op(inc(data_register) | MicroOp::DestinationMask); - } - break; - - case l(PreDec): // MOVE[A].l , -(An) - op(Action::PerformOperation); - op(int(Action::Decrement2) | MicroOp::DestinationMask); - op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("np nw- nW", { ea(1), ea(1) })); - op(int(Action::Decrement2) | MicroOp::DestinationMask); - break; - - case l(Ind): // MOVE[A].l , (An) - case l(PostInc): // MOVE[A].l , (An)+ - op(Action::PerformOperation); - op( int(Action::CopyToEffectiveAddress) | MicroOp::DestinationMask, - seq("nW+ nw np", { ea(1), ea(1) })); - if(combined_destination_mode == PostInc) { - op(inc(data_register) | MicroOp::DestinationMask); - } - break; - - case bw(XXXw): // MOVE[A].bw , (xxx).W - case bw(d16An): // MOVE[A].bw , (d16, An) - case bw(d8AnXn): // MOVE[A].bw , (d8, An, Xn) - op(Action::PerformOperation); - op( address_action_for_mode(combined_destination_mode) | MicroOp::DestinationMask, - seq(pseq("np nw np", combined_destination_mode), { ea(1) }, - !is_byte_access)); - break; - - case l(XXXw): // MOVE[A].l , (xxx).W - case l(d16An): // MOVE[A].l , (d16, An) - case l(d8AnXn): // MOVE[A].l , (d8, An, Xn) - op(Action::PerformOperation); - op( address_action_for_mode(combined_destination_mode) | MicroOp::DestinationMask, - seq(pseq("np nW+ nw np", combined_destination_mode), { ea(1), ea(1) })); - break; - - case bw(XXXl): // MOVE[A].bw , (xxx).L - op(Action::PerformOperation, seq("np")); - switch(combined_source_mode) { // The pattern here is a function of source and destination. - case Dn: - case Imm: - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("np nw np", { ea(1) }, !is_byte_access)); - break; - - default: - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("nw np np", { ea(1) }, !is_byte_access)); - break; - } - break; - - case l(XXXl): // MOVE[A].l , (xxx).L - op(Action::PerformOperation, seq("np")); - switch(combined_source_mode) { // The pattern here is a function of source and destination. - case Dn: - case Imm: - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("np nW+ nw np", { ea(1), ea(1) })); - break; - - default: - op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask, - seq("nW+ nw np np", { ea(1), ea(1) })); - break; - } - break; - } - } break; - - case Decoder::RESET: - program.set_requires_supervisor(true); - op(Action::None, seq("nn _ np")); - break; - - case Decoder::TRAP: { - // TRAP involves some oddly-sequenced stack writes, so is calculated - // at runtime; also the same sequence is used for illegal instructions. - // So the entirety is scheduled at runtime. - op(Action::PerformOperation); - op(); - } break; - - case Decoder::TRAPV: { - op(Action::None, seq("np")); - op(Action::PerformOperation); - op(); - } break; - - case Decoder::CHK: { - program.set_destination(storage_, Dn, data_register); - program.set_source(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(mode) { - default: continue; - - case Dn: // CHK Dn, Dn - op(Action::None, seq("np")); - break; - - case Ind: // CHK (An), Dn - case PostInc: // CHK (An)+, Dn - op(Action::None, seq("nr np", { a(ea_register) })); - if(mode == PostInc) { - op(int(Action::Increment2) | MicroOp::SourceMask); - } - break; - - case PreDec: // CHK -(An), Dn - op(int(Action::Decrement2) | MicroOp::SourceMask, seq("n nr np", { a(ea_register) })); - break; - - case XXXl: // CHK (xxx).l, Dn - op(Action::None, seq("np")); - [[fallthrough]]; - case XXXw: // CHK (xxx).w, Dn - case d16An: // CHK (d16, An), Dn - case d16PC: // CHK (d16, PC), Dn - case d8AnXn: // CHK (d8, An, Xn), Dn - case d8PCXn: // CHK (d8, PC, Xn), Dn - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr np", mode), { ea(0) })); - break; - - case Imm: // CHK #, Dn - op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np")); - break; - } - - // The nn n here is correct if no exception is issued; otherwise this sequence will - // be replaced. - op(Action::PerformOperation, seq("nn n")); - } break; - - case Decoder::TST: { - program.set_source(storage_, ea_mode, ea_register); - - const int mode = combined_mode(ea_mode, ea_register); - switch(is_long_word_access ? l(mode) : bw(mode)) { - default: continue; - - case bw(Dn): // TST.bw Dn - case l(Dn): // TST.l Dn - op(Action::PerformOperation, seq("np")); - break; - - case bw(PreDec): // TST.bw -(An) - op(dec(ea_register) | MicroOp::SourceMask, seq("n")); - [[fallthrough]]; - case bw(Ind): // TST.bw (An) - case bw(PostInc): // TST.bw (An)+ - op(Action::None, seq("nr", { a(ea_register) }, !is_byte_access)); - op(Action::PerformOperation, seq("np")); - if(mode == PostInc) { - op(inc(ea_register) | MicroOp::SourceMask); - } - break; - - case l(PreDec): // TST.l -(An) - op(int(Action::Decrement4) | MicroOp::SourceMask, seq("n")); - [[fallthrough]]; - case l(Ind): // TST.l (An) - case l(PostInc): // TST.l (An)+ - op(int(Action::CopyToEffectiveAddress) | MicroOp::SourceMask, seq("nR+ nr", { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np")); - if(mode == PostInc) { - op(int(Action::Increment4) | MicroOp::SourceMask); - } - break; - - case bw(XXXl): // TST.bw (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case bw(XXXw): // TST.bw (xxx).w - case bw(d16An): // TST.bw (d16, An) - case bw(d8AnXn): // TST.bw (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nr", mode), { ea(0) }, !is_byte_access)); - op(Action::PerformOperation, seq("np")); - break; - - case l(XXXl): // TST.l (xxx).l - op(Action::None, seq("np")); - [[fallthrough]]; - case l(XXXw): // TST.l (xxx).w - case l(d16An): // TST.l (d16, An) - case l(d8AnXn): // TST.l (d8, An, Xn) - op(address_action_for_mode(mode) | MicroOp::SourceMask, seq(pseq("np nR+ nr", mode), { ea(0), ea(0) })); - op(Action::PerformOperation, seq("np")); - break; - } - } break; - - default: - std::cerr << "Unhandled decoder " << int(mapping.decoder) << std::endl; - continue; - } - - // Add a terminating micro operation if necessary. - if(!storage_.all_micro_ops_.back().is_terminal()) { - storage_.all_micro_ops_.emplace_back(); - } - - // Ensure that steps that weren't meant to look terminal aren't terminal; also check - // for improperly encoded address calculation-type actions. - for(auto index = micro_op_start; index < storage_.all_micro_ops_.size() - 1; ++index) { - -#ifdef DEBUG - // All of the actions below must also nominate a source and/or destination. - switch(storage_.all_micro_ops_[index].action) { - default: break; - case int(Action::CalcD16PC): - case int(Action::CalcD8PCXn): - case int(Action::CalcD16An): - case int(Action::CalcD8AnXn): - case int(Action::AssembleWordAddressFromPrefetch): - case int(Action::AssembleLongWordAddressFromPrefetch): - case int(Action::CopyToEffectiveAddress): - case int(Action::Increment1): - case int(Action::Increment2): - case int(Action::Increment4): - case int(Action::Decrement1): - case int(Action::Decrement2): - case int(Action::Decrement4): - assert(false); - } -#endif - - if(storage_.all_micro_ops_[index].is_terminal()) { - storage_.all_micro_ops_[index].bus_program = uint16_t(seq("")); - } - } - - // Install the operation and make a note of where micro-ops begin. - program.operation = operation; - storage_.instructions[instruction] = program; - micro_op_pointers[size_t(instruction)] = size_t(micro_op_start); - - // Don't search further through the list of possibilities, unless this is a debugging build, - // in which case verify there are no double mappings. -#ifndef NDEBUG - ++hits; - assert(hits == 1); -#else - break; -#endif - } - } - -#undef inc -#undef dec - } - - // Throw in the interrupt program. - const auto interrupt_pointer = storage_.all_micro_ops_.size(); - - // WORKAROUND FOR THE 68000 MAIN LOOP. Hopefully temporary. - op(Action::None, seq("")); - - // Perform a single write and then a cycle that will obtain an interrupt vector, or else dictate an autovector or a spurious interrupt. - op(Action::PrepareINT, seq("n nn nw int", { &storage_.precomputed_addresses_[0] })); - - // The reset of the standard trap steps occur here; PrepareINT will set them up according to the vector received. - op(Action::PrepareINTVector, seq("nn n nw nW nV nv np np", { &storage_.precomputed_addresses_[1], &storage_.precomputed_addresses_[2] })); - - // Terminate the sequence. - op(); - -#undef Dn -#undef An -#undef Ind -#undef PostDec -#undef PreDec -#undef d16An -#undef d8AnXn -#undef XXXw -#undef XXXl -#undef d16PC -#undef d8PCXn -#undef Imm - -#undef bw -#undef l -#undef source_dest - -#undef ea -#undef a -#undef seq -#undef op -#undef pseq - - /*! - Iterates through the micro-sequence beginning at @c start, finalising bus_program - pointers that have been transiently stored as relative to @c arbitrary_base. - */ -// const auto link_operations = [this](MicroOp *start, BusStep *arbitrary_base) { -// while(!start->is_terminal()) { -// const auto offset = size_t(start->bus_program - arbitrary_base); -// assert(offset >= 0 && offset < storage_.all_bus_steps_.size()); -// start->bus_program = &storage_.all_bus_steps_[offset]; -// ++start; -// } -// }; - - // Finalise micro-op and program pointers. - int total_instructions = 0; - for(size_t instruction = 0; instruction < 65536; ++instruction) { - if(micro_op_pointers[instruction] != std::numeric_limits::max()) { - storage_.instructions[instruction].micro_operations = uint32_t(micro_op_pointers[instruction]); - ++total_instructions; -// link_operations(&storage_.all_micro_ops_[micro_op_pointers[instruction]], &arbitrary_base); - } - } - - // Link up the interrupt micro ops. - storage_.interrupt_micro_ops_ = &storage_.all_micro_ops_[interrupt_pointer]; -// link_operations(storage_.interrupt_micro_ops_, &arbitrary_base); - - std::cout << total_instructions << " total opcodes" << std::endl; - std::cout << storage_.all_bus_steps_.size() << " total bus steps; at " << sizeof(BusStep) << " bytes per bus step implies " << storage_.all_bus_steps_.size() * sizeof(BusStep) << " bytes" << std::endl; - std::cout << storage_.all_micro_ops_.size() << " total micro ops; at " << sizeof(MicroOp) << " bytes per micro-op implies " << storage_.all_micro_ops_.size() * sizeof(MicroOp) << " bytes" << std::endl; - std::cout << "(Microcycles being " << sizeof(Microcycle) << " bytes; ProcessorStorage being " << sizeof(ProcessorStorage) << " bytes, or " << sizeof(ProcessorStorage) - sizeof(ProcessorStorage::instructions) << " bytes without the instructions table)" << std::endl; - } - - private: - ProcessorStorage &storage_; - - std::initializer_list::const_iterator replace_write_values(BusStep *start, std::initializer_list::const_iterator value) { - while(!start->is_terminal()) { - // Look for any bus step that writes. Then replace its value, and that of the cycle before it. - if(start->microcycle.data_select_active() && !(start->microcycle.operation & Microcycle::Read) && !(start->microcycle.operation & Microcycle::InterruptAcknowledge)) { - start[0].microcycle.value = start[-1].microcycle.value = *value; - ++value; - } - - ++start; - } - - return value; - } - - struct BusStepOrderer { - bool operator()( BusStep const& lhs, BusStep const& rhs ) const { - int action_diff = int(lhs.action) - int(rhs.action); - if(action_diff < 0) { - return true; - } - if(action_diff > 0) { - return false; - } - - return - std::make_tuple(lhs.microcycle.value, lhs.microcycle.address, lhs.microcycle.length, lhs.microcycle.operation) < - std::make_tuple(rhs.microcycle.value, rhs.microcycle.address, rhs.microcycle.length, rhs.microcycle.operation); - } - }; - std::map, BusStepOrderer> locations_by_bus_step_; -}; - -} -} - -CPU::MC68000::ProcessorStorage::ProcessorStorage() { - ProcessorStorageConstructor constructor(*this); - - // Create the special programs. - const size_t reset_offset = constructor.assemble_program("n n n n n nn nF nf nV nv np np"); - - const size_t branch_taken_offset = constructor.assemble_program("n np np"); - const size_t branch_byte_not_taken_offset = constructor.assemble_program("nn np"); - const size_t branch_word_not_taken_offset = constructor.assemble_program("nn np np"); - const size_t bsr_offset = constructor.assemble_program("np np"); - - const size_t dbcc_condition_true_offset = constructor.assemble_program("nn np np"); - const size_t dbcc_condition_false_no_branch_offset = constructor.assemble_program("n nr np np", { &dbcc_false_address_ }); - const size_t dbcc_condition_false_branch_offset = constructor.assemble_program("n np np"); - // That nr in dbcc_condition_false_no_branch_offset is to look like an np from the wrong address. - - // The reads steps needs to be 32 long-word reads plus an overflow word; the writes just the long words. - // Addresses and data sources/targets will be filled in at runtime, so anything will do here. - std::string movem_reads_pattern, movem_writes_pattern; - std::vector addresses; - for(auto c = 0; c < 64; ++c) { - movem_reads_pattern += "nr "; - movem_writes_pattern += "nw "; - addresses.push_back(nullptr); - } - movem_reads_pattern += "nr"; - addresses.push_back(nullptr); - const size_t movem_read_offset = constructor.assemble_program(movem_reads_pattern.c_str(), addresses); - const size_t movem_write_offset = constructor.assemble_program(movem_writes_pattern.c_str(), addresses); - - // Target addresses and values will be filled in by TRAP/illegal too. - const size_t trap_offset = constructor.assemble_program("r nw nw nW nV nv np np", { &precomputed_addresses_[0], &precomputed_addresses_[1], &precomputed_addresses_[2] }); - const size_t bus_error_offset = - constructor.assemble_program( - "nn nw nw nW nw nw nw nW nV nv np np", - { - &precomputed_addresses_[0], - &precomputed_addresses_[1], - &precomputed_addresses_[2], - &precomputed_addresses_[3], - &precomputed_addresses_[4], - &precomputed_addresses_[5], - &precomputed_addresses_[6] - } - ); - - // Chuck in the proper micro-ops for handling an exception. - const auto short_exception_offset = all_micro_ops_.size(); - all_micro_ops_.emplace_back(ProcessorBase::MicroOp::Action::None); - all_micro_ops_.emplace_back(); - - const auto long_exception_offset = all_micro_ops_.size(); - all_micro_ops_.emplace_back(ProcessorBase::MicroOp::Action::None); - all_micro_ops_.emplace_back(); - - // Install operations. -//#ifndef NDEBUG - const std::clock_t start = std::clock(); -//#endif - constructor.install_instructions(); -//#ifndef NDEBUG - std::cout << "Construction took " << double(std::clock() - start) / double(CLOCKS_PER_SEC / 1000) << "ms" << std::endl; -//#endif - - // Realise the special programs as direct pointers. - reset_bus_steps_ = &all_bus_steps_[reset_offset]; - - branch_taken_bus_steps_ = &all_bus_steps_[branch_taken_offset]; - branch_byte_not_taken_bus_steps_ = &all_bus_steps_[branch_byte_not_taken_offset]; - branch_word_not_taken_bus_steps_ = &all_bus_steps_[branch_word_not_taken_offset]; - bsr_bus_steps_ = &all_bus_steps_[bsr_offset]; - - dbcc_condition_true_steps_ = &all_bus_steps_[dbcc_condition_true_offset]; - dbcc_condition_false_no_branch_steps_ = &all_bus_steps_[dbcc_condition_false_no_branch_offset]; - dbcc_condition_false_no_branch_steps_[1].microcycle.operation |= Microcycle::IsProgram; - dbcc_condition_false_no_branch_steps_[2].microcycle.operation |= Microcycle::IsProgram; - dbcc_condition_false_branch_steps_ = &all_bus_steps_[dbcc_condition_false_branch_offset]; - - movem_read_steps_ = &all_bus_steps_[movem_read_offset]; - movem_write_steps_ = &all_bus_steps_[movem_write_offset]; - - // Link the trap steps but also fill in the program counter as the source - // for its parts, and use the computed addresses. - // - // Order of output is: PC.l, SR, PC.h. - trap_steps_ = &all_bus_steps_[trap_offset]; - constructor.replace_write_values(trap_steps_, { &program_counter_.halves.low, &destination_bus_data_.halves.low, &program_counter_.halves.high }); - - // Fill in the same order of writes for the interrupt micro-ops, though it divides the work differently. - constructor.replace_write_values(interrupt_micro_ops_, { &program_counter_.halves.low, &destination_bus_data_.halves.low, &program_counter_.halves.high }); - - // Link the bus error exception steps and fill in the proper sources. - bus_error_steps_ = &all_bus_steps_[bus_error_offset]; - constructor.replace_write_values(bus_error_steps_, { - &program_counter_.halves.low, - &destination_bus_data_.halves.low, - &program_counter_.halves.high, - &decoded_instruction_, - &effective_address_[1].halves.low, - &destination_bus_data_.halves.high, - &effective_address_[1].halves.high - }); - - // Also relink the RTE and RTR bus steps to collect the program counter. - // - // Assumed order of input: PC.h, SR, PC.l (i.e. the opposite of TRAP's output). - for(const int instruction: { 0x4e73, 0x4e77 }) { - auto steps = &all_bus_steps_[all_micro_ops_[instructions[instruction].micro_operations].bus_program]; - steps[0].microcycle.value = steps[1].microcycle.value = &program_counter_.halves.high; - steps[4].microcycle.value = steps[5].microcycle.value = &program_counter_.halves.low; - } - - // Setup the stop cycle. - stop_cycle_.length = HalfCycles(2); - - // Complete linkage of the exception micro program. - short_exception_micro_ops_ = &all_micro_ops_[short_exception_offset]; - short_exception_micro_ops_->bus_program = uint16_t(trap_offset); - - long_exception_micro_ops_ = &all_micro_ops_[long_exception_offset]; - long_exception_micro_ops_->bus_program = uint16_t(bus_error_offset); - - // Set initial state. - active_step_ = reset_bus_steps_; - effective_address_[0] = 0; - is_supervisor_ = 1; - interrupt_level_ = 7; - address_[7] = 0x00030000; -} - -void CPU::MC68000::ProcessorStorage::write_back_stack_pointer() { - stack_pointers_[is_supervisor_] = address_[7]; -} - -void CPU::MC68000::ProcessorStorage::set_is_supervisor(bool is_supervisor) { - const int new_is_supervisor = is_supervisor ? 1 : 0; - if(new_is_supervisor != is_supervisor_) { - stack_pointers_[is_supervisor_] = address_[7]; - is_supervisor_ = new_is_supervisor; - address_[7] = stack_pointers_[is_supervisor_]; - } -} diff --git a/Processors/68000/Implementation/68000Storage.hpp b/Processors/68000/Implementation/68000Storage.hpp deleted file mode 100644 index c3634d17d..000000000 --- a/Processors/68000/Implementation/68000Storage.hpp +++ /dev/null @@ -1,579 +0,0 @@ -// -// 68000Storage.hpp -// Clock Signal -// -// Created by Thomas Harte on 08/03/2019. -// Copyright © 2019 Thomas Harte. All rights reserved. -// - -#ifndef MC68000Storage_h -#define MC68000Storage_h - -class ProcessorStorage { - public: - ProcessorStorage(); - - protected: - RegisterPair32 data_[8]; - RegisterPair32 address_[8]; - RegisterPair32 program_counter_; - - RegisterPair32 stack_pointers_[2]; // [0] = user stack pointer; [1] = supervisor; the values from here - // are copied into/out of address_[7] upon mode switches. - - RegisterPair32 prefetch_queue_; // Each word will go into the low part of the word, then proceed upward. - - // Generic sources and targets for memory operations; - // by convention: effective_address_[0] = source, [1] = destination. - // - // These, and the various register contents above, should be kept - // close to the top of this class so that small-integer offsets can be - // used in instances of Program (see below). - RegisterPair32 effective_address_[2]; - RegisterPair32 source_bus_data_; - RegisterPair32 destination_bus_data_; - - enum class ExecutionState { - /// The normal mode, this means the 68000 is expending processing effort. - Executing, - - /// The 68000 is in a holding loop, waiting for either DTack or to be notified of a bus error. - WaitingForDTack, - - /// Occurs after executing a STOP instruction; the processor will idle waiting for an interrupt or reset. - Stopped, - - /// Occurs at the end of the current bus cycle after detection of the HALT input, continuing until - /// HALT is no longer signalled. - Halted, - - /// Signals a transition from some other straight directly to cueing up an interrupt. - WillBeginInterrupt, - } execution_state_ = ExecutionState::Executing; - Microcycle dtack_cycle_; - Microcycle stop_cycle_; - - // Various status parts. - int is_supervisor_; - int interrupt_level_; - uint_fast32_t zero_result_; // The zero flag is set if this value is zero. - uint_fast32_t carry_flag_; // The carry flag is set if this value is non-zero. - uint_fast32_t extend_flag_; // The extend flag is set if this value is non-zero. - uint_fast32_t overflow_flag_; // The overflow flag is set if this value is non-zero. - uint_fast32_t negative_flag_; // The negative flag is set if this value is non-zero. - uint_fast32_t trace_flag_; // The trace flag is set if this value is non-zero. - - uint_fast32_t last_trace_flag_ = 0; - - // Bus inputs. - int bus_interrupt_level_ = 0; - bool dtack_ = false; - bool is_peripheral_address_ = false; - bool bus_error_ = false; - bool bus_request_ = false; - bool bus_acknowledge_ = false; - bool halt_ = false; - - // Holds the interrupt level that should be serviced at the next instruction - // dispatch, if any. - int pending_interrupt_level_ = 0; - // Holds the interrupt level that is currently being serviced. - // TODO: surely this doesn't need to be distinct from the pending_interrupt_level_? - int accepted_interrupt_level_ = 0; - bool is_starting_interrupt_ = false; - - HalfCycles half_cycles_left_to_run_; - HalfCycles e_clock_phase_; - - enum class Operation: uint8_t { - None, - ABCD, SBCD, NBCD, - - ADDb, ADDw, ADDl, - ADDQb, ADDQw, ADDQl, - ADDAw, ADDAl, - ADDQAw, ADDQAl, - ADDXb, ADDXw, ADDXl, - - SUBb, SUBw, SUBl, - SUBQb, SUBQw, SUBQl, - SUBAw, SUBAl, - SUBQAw, SUBQAl, - SUBXb, SUBXw, SUBXl, - - MOVEb, MOVEw, MOVEl, MOVEq, - MOVEAw, MOVEAl, - PEA, - - MOVEtoSR, MOVEfromSR, - MOVEtoCCR, - - ORItoSR, ORItoCCR, - ANDItoSR, ANDItoCCR, - EORItoSR, EORItoCCR, - - BTSTb, BTSTl, - BCLRl, BCLRb, - CMPb, CMPw, CMPl, - CMPAw, - TSTb, TSTw, TSTl, - - JMP, RTS, - BRA, Bcc, - DBcc, - Scc, - - CLRb, CLRw, CLRl, - NEGXb, NEGXw, NEGXl, - NEGb, NEGw, NEGl, - - ASLb, ASLw, ASLl, ASLm, - ASRb, ASRw, ASRl, ASRm, - LSLb, LSLw, LSLl, LSLm, - LSRb, LSRw, LSRl, LSRm, - ROLb, ROLw, ROLl, ROLm, - RORb, RORw, RORl, RORm, - ROXLb, ROXLw, ROXLl, ROXLm, - ROXRb, ROXRw, ROXRl, ROXRm, - - MOVEMtoRl, MOVEMtoRw, - MOVEMtoMl, MOVEMtoMw, - - MOVEPtoRl, MOVEPtoRw, - MOVEPtoMl, MOVEPtoMw, - - ANDb, ANDw, ANDl, - EORb, EORw, EORl, - NOTb, NOTw, NOTl, - ORb, ORw, ORl, - - MULU, MULS, - DIVU, DIVS, - - RTE_RTR, - - TRAP, TRAPV, - CHK, - - EXG, SWAP, - - BCHGl, BCHGb, - BSETl, BSETb, - - TAS, - - EXTbtow, EXTwtol, - - LINK, UNLINK, - - STOP, - }; - - /*! - Bus steps are sequences of things to communicate to the bus. - Standard behaviour is: (i) perform microcycle; (ii) perform action. - */ - struct BusStep { - Microcycle microcycle; - enum class Action { - None, - - /// Performs effective_address_[0] += 2. - IncrementEffectiveAddress0, - - /// Performs effective_address_[1] += 2. - IncrementEffectiveAddress1, - - /// Performs effective_address_[0] -= 2. - DecrementEffectiveAddress0, - - /// Performs effective_address_[1] -= 2. - DecrementEffectiveAddress1, - - /// Performs program_counter_ += 2. - IncrementProgramCounter, - - /// Copies prefetch_queue_[1] to prefetch_queue_[0]. - AdvancePrefetch, - - /// Performs effective_address_[0] += 2 and zeroes the final bit of the stack pointer. - IncrementEffectiveAddress0AlignStackPointer, - - /*! - Terminates an atomic program; if nothing else is pending, schedules the next instruction. - This action is special in that it usurps any included microcycle. So any Step with this - as its action acts as an end-of-list sentinel. - */ - ScheduleNextProgram - - } action = Action::None; - - forceinline bool operator ==(const BusStep &rhs) const { - if(action != rhs.action) return false; - return microcycle == rhs.microcycle; - } - - forceinline bool is_terminal() const { - return action == Action::ScheduleNextProgram; - } - }; - - /*! - A micro-op is: (i) an action to take; and (ii) a sequence of bus operations - to perform after taking the action. - - NOTE: this therefore has the opposite order of behaviour compared to a BusStep, - the action occurs BEFORE the bus operations, not after. - - A nullptr bus_program terminates a sequence of micro operations; the is_terminal - test should be used to query for that. The action on the final operation will - be performed. - */ - struct MicroOp { - enum class Action: uint8_t { - None, - - /// Does whatever this instruction says is the main operation. - PerformOperation, - - /* - All of the below will honour the source and destination masks - in deciding where to apply their actions. - */ - - /// Subtracts 1 from the [source/destination]_address. - Decrement1, - /// Subtracts 2 from the [source/destination]_address. - Decrement2, - /// Subtracts 4 from the [source/destination]_address. - Decrement4, - - /// Adds 1 from the [source/destination]_address. - Increment1, - /// Adds 2 from the [source/destination]_address. - Increment2, - /// Adds 4 from the [source/destination]_address. - Increment4, - - /// Copies the source and/or destination to effective_address_. - CopyToEffectiveAddress, - - /// Peeking into the end of the prefetch queue, calculates the proper target of (d16,An) addressing. - CalcD16An, - - /// Peeking into the end of the prefetch queue, calculates the proper target of (d8,An,Xn) addressing. - CalcD8AnXn, - - /// Peeking into the prefetch queue, calculates the proper target of (d16,PC) addressing, - /// adjusting as though it had been performed after the proper PC fetches. The source - /// and destination mask flags affect only the destination of the result. - CalcD16PC, - - /// Peeking into the prefetch queue, calculates the proper target of (d8,An,Xn) addressing, - /// adjusting as though it had been performed after the proper PC fetches. The source - /// and destination mask flags affect only the destination of the result. - CalcD8PCXn, - - /// Sets the high word according to the MSB of the low word. - SignExtendWord, - - /// Sets the high three bytes according to the MSB of the low byte. - SignExtendByte, - - /// From the next word in the prefetch queue assembles a sign-extended long word in either or - /// both of effective_address_[0] and effective_address_[1]. - AssembleWordAddressFromPrefetch, - - /// From the next word in the prefetch queue assembles a 0-padded 32-bit long word in either or - /// both of bus_data_[0] and bus_data_[1]. - AssembleWordDataFromPrefetch, - - /// Copies the next two prefetch words into one of the effective_address_. - AssembleLongWordAddressFromPrefetch, - - /// Copies the next two prefetch words into one of the bus_data_. - AssembleLongWordDataFromPrefetch, - - /// Copies the low part of the prefetch queue into next_word_. - CopyNextWord, - - /// Performs write-back of post-increment address and/or sign extensions as necessary. - MOVEMtoRComplete, - - /// Performs write-back of pre-decrement address. - MOVEMtoMComplete, - - // (i) inspects the prefetch queue to determine the length of this instruction and copies the next PC to destination_bus_data_; - // (ii) copies the stack pointer minus 4 to effective_address_[1]; - // (iii) decrements the stack pointer by four. - PrepareJSR, - PrepareBSR, - - // (i) copies the stack pointer to effective_address_[0]; - // (ii) increments the stack pointer by four. - PrepareRTS, - - // (i) fills in the proper stack addresses to the bus steps for this micro-op; and - // (ii) adjusts the stack pointer appropriately. - PrepareRTE_RTR, - - // Performs the necessary status word substitution for the current interrupt level, - // and does the first part of initialising the trap steps. - PrepareINT, - - // Observes the bus_error_, valid_peripheral_address_ and/or the value currently in - // source_bus_data_ to determine an interrupt vector, and fills in the final trap - // steps detail appropriately. - PrepareINTVector, - }; - static_assert(uint8_t(Action::PrepareINTVector) < 32); // i.e. will fit into five bits. - - static constexpr int SourceMask = 1 << 5; - static constexpr int DestinationMask = 1 << 6; - uint8_t action = uint8_t(Action::None); // Requires 7 bits at present; sizeof(Action) + the two flags above. - - static constexpr uint16_t NoBusProgram = std::numeric_limits::max(); - uint16_t bus_program = NoBusProgram; // Empirically requires 11 bits at present. - - MicroOp(): action(uint8_t(Action::None)), bus_program(NoBusProgram) {} - MicroOp(uint8_t action) : action(action), bus_program(NoBusProgram) {} - MicroOp(uint8_t action, uint16_t bus_program) : action(action), bus_program(bus_program) {} - - MicroOp(Action action) : MicroOp(uint8_t(action)) {} - MicroOp(Action action, uint16_t bus_program) : MicroOp(uint8_t(action), bus_program) {} - - forceinline bool is_terminal() const { - return bus_program == NoBusProgram; - } - }; - - /*! - A program represents the implementation of a particular opcode, as a sequence - of micro-ops and, separately, the operation to perform plus whatever other - fields the operation requires. - - Some of the fields are slightly convoluted in how they identify the information - they reference; this is done to keep this struct as small as possible due to - concerns about cache size. - - On the 64-bit Intel processor this emulator was developed on, the struct below - adds up to 8 bytes; four for the initial uint32_t and then one each for the - remaining fields, with no additional padding being inserted by the compiler. - */ - struct Program { - Program() { - // Initialisers for bitfields aren't available until C++20. So, yuck, do it manually. - requires_supervisor = 0; - source = 0; - dest = 0; - destination_offset = 0; - source_offset = 0; - } - - static constexpr uint32_t NoSuchProgram = std::numeric_limits::max(); - - /// The offset into the all_micro_ops_ at which micro-ops for this instruction begin, - /// or std::numeric_limits::max() if this is an invalid Program. - uint32_t micro_operations = NoSuchProgram; - /// The overarching operation applied by this program when the moment comes. - Operation operation; - /// The number of bytes after the beginning of an instance of ProcessorStorage that the RegisterPair32 containing - /// a source value for this operation lies at. - uint8_t source_offset: 7; - /// The number of bytes after the beginning of an instance of ProcessorStorage that the RegisterPair32 containing - /// a destination value for this operation lies at. - uint8_t destination_offset: 7; - /// Set if this program requires supervisor mode. - bool requires_supervisor: 1; - /// The source address register (for pre-decrement and post-increment actions). - uint8_t source: 3; - /// Destination address register. - uint8_t dest: 3; - - void set_source_address([[maybe_unused]] ProcessorStorage &storage, int index) { - source = uint8_t(index); - assert(int(source) == index); - } - - void set_destination_address([[maybe_unused]] ProcessorStorage &storage, int index) { - dest = uint8_t(index); - assert(int(dest) == index); - } - - void set_requires_supervisor(bool req) { - requires_supervisor = req; - assert(requires_supervisor == req); - } - - void set_source(ProcessorStorage &storage, RegisterPair32 *target) { - source_offset = decltype(source_offset)(reinterpret_cast(target) - reinterpret_cast(&storage)); - // Test that destination_offset could be stored fully within the integer size provided for source_offset. - assert(source_offset == (reinterpret_cast(target) - reinterpret_cast(&storage))); - } - - void set_destination(ProcessorStorage &storage, RegisterPair32 *target) { - destination_offset = decltype(destination_offset)(reinterpret_cast(target) - reinterpret_cast(&storage)); - // Test that destination_offset could be stored fully within the integer size provided for destination_offset. - assert(destination_offset == (reinterpret_cast(target) - reinterpret_cast(&storage))); - } - - void set_source(ProcessorStorage &storage, int mode, int reg) { - set_source_address(storage, reg); - switch(mode) { - case 0: set_source(storage, &storage.data_[reg]); break; - case 1: set_source(storage, &storage.address_[reg]); break; - default: set_source(storage, &storage.source_bus_data_); break; - } - } - - void set_destination(ProcessorStorage &storage, int mode, int reg) { - set_destination_address(storage, reg); - switch(mode) { - case 0: set_destination(storage, &storage.data_[reg]); break; - case 1: set_destination(storage, &storage.address_[reg]); break; - default: set_destination(storage, &storage.destination_bus_data_); break; - } - } - }; - - // Storage for all the sequences of bus steps and micro-ops used throughout - // the 68000. - std::vector all_bus_steps_; - std::vector all_micro_ops_; - - // A lookup table from instructions to implementations. - Program instructions[65536]; - - // Special steps and programs for exception handlers. - BusStep *reset_bus_steps_; - MicroOp *long_exception_micro_ops_; // i.e. those that leave 14 bytes on the stack — bus error and address error. - MicroOp *short_exception_micro_ops_; // i.e. those that leave 6 bytes on the stack — everything else (other than interrupts). - MicroOp *interrupt_micro_ops_; - - // Special micro-op sequences and storage for conditionals. - BusStep *branch_taken_bus_steps_; - BusStep *branch_byte_not_taken_bus_steps_; - BusStep *branch_word_not_taken_bus_steps_; - BusStep *bsr_bus_steps_; - - uint32_t dbcc_false_address_; - BusStep *dbcc_condition_true_steps_; - BusStep *dbcc_condition_false_no_branch_steps_; - BusStep *dbcc_condition_false_branch_steps_; - - BusStep *movem_read_steps_; - BusStep *movem_write_steps_; - - // These two are dynamically modified depending on the particular - // TRAP and bus error. - BusStep *trap_steps_; - BusStep *bus_error_steps_; - - // Current bus step pointer, and outer program pointer. - const Program *active_program_ = nullptr; - const MicroOp *active_micro_op_ = nullptr; - const BusStep *active_step_ = nullptr; - RegisterPair16 decoded_instruction_ = 0; - uint16_t next_word_ = 0; - - /// Copies address_[7] to the proper stack pointer based on current mode. - void write_back_stack_pointer(); - - /// Sets or clears the supervisor flag, ensuring the stack pointer is properly updated. - void set_is_supervisor(bool); - - // Transient storage for MOVEM, TRAP and others. - RegisterPair16 throwaway_value_; - uint32_t movem_final_address_; - uint32_t precomputed_addresses_[65]; // This is a big chunk of rarely-used storage. It's placed last deliberately. - - /*! - Evaluates the conditional described by @c code and returns @c true or @c false to - indicate the result of that evaluation. - */ - forceinline bool evaluate_condition(uint8_t code) { - switch(code & 0xf) { - default: - case 0x00: return true; // true - case 0x01: return false; // false - case 0x02: return zero_result_ && !carry_flag_; // high - case 0x03: return !zero_result_ || carry_flag_; // low or same - case 0x04: return !carry_flag_; // carry clear - case 0x05: return carry_flag_; // carry set - case 0x06: return zero_result_; // not equal - case 0x07: return !zero_result_; // equal - case 0x08: return !overflow_flag_; // overflow clear - case 0x09: return overflow_flag_; // overflow set - case 0x0a: return !negative_flag_; // positive - case 0x0b: return negative_flag_; // negative - case 0x0c: // greater than or equal - return (negative_flag_ && overflow_flag_) || (!negative_flag_ && !overflow_flag_); - case 0x0d: // less than - return (negative_flag_ && !overflow_flag_) || (!negative_flag_ && overflow_flag_); - case 0x0e: // greater than - return zero_result_ && ((negative_flag_ && overflow_flag_) || (!negative_flag_ && !overflow_flag_)); - case 0x0f: // less than or equal - return !zero_result_ || (negative_flag_ && !overflow_flag_) || (!negative_flag_ && overflow_flag_); - } - } - - /*! - Fills in the appropriate addresses and values to complete the TRAP steps — those - representing a short-form exception — and mutates the status register as if one - were beginning. - */ - forceinline void populate_trap_steps(uint32_t vector, uint16_t status) { - // Fill in the status word value. - destination_bus_data_.full = status; - - // Switch to supervisor mode, disable the trace bit. - set_is_supervisor(true); - trace_flag_ = last_trace_flag_ = 0; - - // Pick a vector. - effective_address_[0].full = vector << 2; - - // Schedule the proper stack activity. - precomputed_addresses_[0] = address_[7].full - 2; // PC.l - precomputed_addresses_[1] = address_[7].full - 6; // status word (in destination_bus_data_) - precomputed_addresses_[2] = address_[7].full - 4; // PC.h - address_[7].full -= 6; - - // Set the default timing. - trap_steps_->microcycle.length = HalfCycles(8); - } - - forceinline void populate_bus_error_steps(uint32_t vector, uint16_t status, uint16_t bus_status, RegisterPair32 faulting_address) { - // Fill in the status word value. - destination_bus_data_.halves.low.full = status; - destination_bus_data_.halves.high.full = bus_status; - effective_address_[1] = faulting_address; - - // Switch to supervisor mode, disable the trace bit. - set_is_supervisor(true); - trace_flag_ = last_trace_flag_ = 0; - - // Pick a vector. - effective_address_[0].full = vector << 2; - - // Schedule the proper stack activity. - precomputed_addresses_[0] = address_[7].full - 2; // PC.l - precomputed_addresses_[1] = address_[7].full - 6; // status word - precomputed_addresses_[2] = address_[7].full - 4; // PC.h - precomputed_addresses_[3] = address_[7].full - 8; // current instruction - precomputed_addresses_[4] = address_[7].full - 10; // fault address.l - precomputed_addresses_[5] = address_[7].full - 14; // bus cycle status word - precomputed_addresses_[6] = address_[7].full - 12; // fault address.h - address_[7].full -= 14; - } - - inline uint16_t get_status() const; - inline void set_status(uint16_t); - - private: - friend struct ProcessorStorageConstructor; - friend class ProcessorStorageTests; - friend struct State; -}; - -#endif /* MC68000Storage_h */ diff --git a/Processors/68000/State/State.cpp b/Processors/68000/State/State.cpp deleted file mode 100644 index b8e8bb7ec..000000000 --- a/Processors/68000/State/State.cpp +++ /dev/null @@ -1,340 +0,0 @@ -// -// State.cpp -// Clock Signal -// -// Created by Thomas Harte on 14/05/2020. -// Copyright © 2020 Thomas Harte. All rights reserved. -// - -#include "State.hpp" - -#include - -using namespace CPU::MC68000; - -State::State(const ProcessorBase &src): State() { - // Registers. - for(int c = 0; c < 7; ++c) { - registers.address[c] = src.address_[c].full; - registers.data[c] = src.data_[c].full; - } - registers.data[7] = src.data_[7].full; - registers.user_stack_pointer = src.is_supervisor_ ? src.stack_pointers_[0].full : src.address_[7].full; - registers.supervisor_stack_pointer = src.is_supervisor_ ? src.address_[7].full : src.stack_pointers_[1].full; - registers.status = src.get_status(); - registers.program_counter = src.program_counter_.full; - registers.prefetch = src.prefetch_queue_.full; - registers.instruction = src.decoded_instruction_.full; - - // Inputs. - inputs.bus_interrupt_level = uint8_t(src.bus_interrupt_level_); - inputs.dtack = src.dtack_; - inputs.is_peripheral_address = src.is_peripheral_address_; - inputs.bus_error = src.bus_error_; - inputs.bus_request = src.bus_request_; - inputs.bus_grant = false; // TODO (within the 68000). - inputs.halt = src.halt_; - - // Execution state. - execution_state.e_clock_phase = src.e_clock_phase_.as(); - execution_state.effective_address[0] = src.effective_address_[0].full; - execution_state.effective_address[1] = src.effective_address_[1].full; - execution_state.source_data = src.source_bus_data_.full; - execution_state.destination_data = src.destination_bus_data_.full; - execution_state.last_trace_flag = src.last_trace_flag_; - execution_state.next_word = src.next_word_; - execution_state.dbcc_false_address = src.dbcc_false_address_; - execution_state.is_starting_interrupt = src.is_starting_interrupt_; - execution_state.pending_interrupt_level = uint8_t(src.pending_interrupt_level_); - execution_state.accepted_interrupt_level = uint8_t(src.accepted_interrupt_level_); - execution_state.movem_final_address = src.movem_final_address_; - - static_assert(sizeof(execution_state.source_addresses) == sizeof(src.precomputed_addresses_)); - memcpy(&execution_state.source_addresses, &src.precomputed_addresses_, sizeof(src.precomputed_addresses_)); - - // This is collapsed to a Boolean; if there is an active program then it's the - // one implied by the current instruction. - execution_state.active_program = src.active_program_; - - // Slightly dodgy assumption here: the Phase enum will always exactly track - // the 68000's ExecutionState enum. - execution_state.phase = ExecutionState::Phase(src.execution_state_); - - auto contained_by = [](const auto *source, const auto *reference) -> bool { - while(true) { - if(source == reference) return true; - if(source->is_terminal()) return false; - ++source; - } - }; - - // Store enough information to relocate the MicroOp. - const ProcessorBase::MicroOp *micro_op_base = nullptr; - if(src.active_program_) { - micro_op_base = &src.all_micro_ops_[src.instructions[src.decoded_instruction_.full].micro_operations]; - assert(contained_by(micro_op_base, src.active_micro_op_)); - execution_state.micro_op_source = ExecutionState::MicroOpSource::ActiveProgram; - } else { - if(contained_by(src.long_exception_micro_ops_, src.active_micro_op_)) { - execution_state.micro_op_source = ExecutionState::MicroOpSource::LongException; - micro_op_base = src.long_exception_micro_ops_; - } else if(contained_by(src.short_exception_micro_ops_, src.active_micro_op_)) { - execution_state.micro_op_source = ExecutionState::MicroOpSource::ShortException; - micro_op_base = src.short_exception_micro_ops_; - } else if(contained_by(src.interrupt_micro_ops_, src.active_micro_op_)) { - execution_state.micro_op_source = ExecutionState::MicroOpSource::Interrupt; - micro_op_base = src.interrupt_micro_ops_; - } else { - assert(false); - } - } - execution_state.micro_op = uint8_t(src.active_micro_op_ - micro_op_base); - - // Encode the BusStep. - struct BusStepOption { - const ProcessorBase::BusStep *const base; - const ExecutionState::BusStepSource source = ExecutionState::BusStepSource::FollowMicroOp; - }; - BusStepOption bus_step_options[] = { - { - src.reset_bus_steps_, - ExecutionState::BusStepSource::Reset - }, - { - src.branch_taken_bus_steps_, - ExecutionState::BusStepSource::BranchTaken - }, - { - src.branch_byte_not_taken_bus_steps_, - ExecutionState::BusStepSource::BranchByteNotTaken - }, - { - src.branch_word_not_taken_bus_steps_, - ExecutionState::BusStepSource::BranchWordNotTaken - }, - { - src.bsr_bus_steps_, - ExecutionState::BusStepSource::BSR - }, - { - src.dbcc_condition_true_steps_, - ExecutionState::BusStepSource::DBccConditionTrue - }, - { - src.dbcc_condition_false_no_branch_steps_, - ExecutionState::BusStepSource::DBccConditionFalseNoBranch - }, - { - src.dbcc_condition_false_branch_steps_, - ExecutionState::BusStepSource::DBccConditionFalseBranch - }, - { - src.movem_read_steps_, - ExecutionState::BusStepSource::MovemRead - }, - { - src.movem_write_steps_, - ExecutionState::BusStepSource::MovemWrite - }, - { - src.trap_steps_, - ExecutionState::BusStepSource::Trap - }, - { - src.bus_error_steps_, - ExecutionState::BusStepSource::BusError - }, - { - &src.all_bus_steps_[src.active_micro_op_->bus_program], - ExecutionState::BusStepSource::FollowMicroOp - }, - {nullptr} - }; - const BusStepOption *bus_step_option = bus_step_options; - const ProcessorBase::BusStep *bus_step_base = nullptr; - while(bus_step_option->base) { - if(contained_by(bus_step_option->base, src.active_step_)) { - bus_step_base = bus_step_option->base; - execution_state.bus_step_source = bus_step_option->source; - break; - } - ++bus_step_option; - } - assert(bus_step_base); - execution_state.bus_step = uint8_t(src.active_step_ - bus_step_base); -} - -void State::apply(ProcessorBase &target) { - // Registers. - for(int c = 0; c < 7; ++c) { - target.address_[c].full = registers.address[c]; - target.data_[c].full = registers.data[c]; - } - target.data_[7].full = registers.data[7]; - target.stack_pointers_[0] = registers.user_stack_pointer; - target.stack_pointers_[1] = registers.supervisor_stack_pointer; - target.address_[7] = target.stack_pointers_[(registers.status & 0x2000) >> 13]; - target.set_status(registers.status); - target.program_counter_.full = registers.program_counter; - target.prefetch_queue_.full = registers.prefetch; - target.decoded_instruction_.full = registers.instruction; - - // Inputs. - target.bus_interrupt_level_ = inputs.bus_interrupt_level; - target.dtack_ = inputs.dtack; - target.is_peripheral_address_ = inputs.is_peripheral_address; - target.bus_error_ = inputs.bus_error; - target.bus_request_ = inputs.bus_request; - // TODO: bus_grant. - target.halt_ = inputs.halt; - - // Execution state. - target.e_clock_phase_ = HalfCycles(execution_state.e_clock_phase); - target.effective_address_[0].full = execution_state.effective_address[0]; - target.effective_address_[1].full = execution_state.effective_address[1]; - target.source_bus_data_.full = execution_state.source_data; - target.destination_bus_data_.full = execution_state.destination_data; - target.last_trace_flag_ = execution_state.last_trace_flag; - target.next_word_ = execution_state.next_word; - target.dbcc_false_address_ = execution_state.dbcc_false_address; - target.is_starting_interrupt_ = execution_state.is_starting_interrupt; - target.pending_interrupt_level_ = execution_state.pending_interrupt_level; - target.accepted_interrupt_level_ = execution_state.accepted_interrupt_level; - target.movem_final_address_ = execution_state.movem_final_address; - - static_assert(sizeof(execution_state.source_addresses) == sizeof(target.precomputed_addresses_)); - memcpy(&target.precomputed_addresses_, &execution_state.source_addresses, sizeof(target.precomputed_addresses_)); - - // See above; this flag indicates whether to populate the field. - target.active_program_ = - execution_state.active_program ? - &target.instructions[target.decoded_instruction_.full] : nullptr; - - // Dodgy assumption duplicated here from above. - target.execution_state_ = CPU::MC68000::ProcessorStorage::ExecutionState(execution_state.phase); - - // Decode the MicroOp. - switch(execution_state.micro_op_source) { - case ExecutionState::MicroOpSource::ActiveProgram: - target.active_micro_op_ = &target.all_micro_ops_[target.active_program_->micro_operations]; - break; - case ExecutionState::MicroOpSource::LongException: - target.active_micro_op_ = target.long_exception_micro_ops_; - break; - case ExecutionState::MicroOpSource::ShortException: - target.active_micro_op_ = target.short_exception_micro_ops_; - break; - case ExecutionState::MicroOpSource::Interrupt: - target.active_micro_op_ = target.interrupt_micro_ops_; - break; - } - target.active_micro_op_ += execution_state.micro_op; - - - // Decode the BusStep. - switch(execution_state.bus_step_source) { - case ExecutionState::BusStepSource::Reset: - target.active_step_ = target.reset_bus_steps_; - break; - case ExecutionState::BusStepSource::BranchTaken: - target.active_step_ = target.branch_taken_bus_steps_; - break; - case ExecutionState::BusStepSource::BranchByteNotTaken: - target.active_step_ = target.branch_byte_not_taken_bus_steps_; - break; - case ExecutionState::BusStepSource::BranchWordNotTaken: - target.active_step_ = target.branch_word_not_taken_bus_steps_; - break; - case ExecutionState::BusStepSource::BSR: - target.active_step_ = target.bsr_bus_steps_; - break; - case ExecutionState::BusStepSource::DBccConditionTrue: - target.active_step_ = target.dbcc_condition_true_steps_; - break; - case ExecutionState::BusStepSource::DBccConditionFalseNoBranch: - target.active_step_ = target.dbcc_condition_false_no_branch_steps_; - break; - case ExecutionState::BusStepSource::DBccConditionFalseBranch: - target.active_step_ = target.dbcc_condition_false_branch_steps_; - break; - case ExecutionState::BusStepSource::MovemRead: - target.active_step_ = target.movem_read_steps_; - break; - case ExecutionState::BusStepSource::MovemWrite: - target.active_step_ = target.movem_write_steps_; - break; - case ExecutionState::BusStepSource::Trap: - target.active_step_ = target.trap_steps_; - break; - case ExecutionState::BusStepSource::BusError: - target.active_step_ = target.bus_error_steps_; - break; - case ExecutionState::BusStepSource::FollowMicroOp: - target.active_step_ = &target.all_bus_steps_[target.active_micro_op_->bus_program]; - break; - } - target.active_step_ += execution_state.bus_step; -} - -// Boilerplate follows here, to establish 'reflection'. -State::State() { - if(needs_declare()) { - DeclareField(registers); - DeclareField(execution_state); - DeclareField(inputs); - } -} - -State::Registers::Registers() { - if(needs_declare()) { - DeclareField(data); - DeclareField(address); - DeclareField(user_stack_pointer); - DeclareField(supervisor_stack_pointer); - DeclareField(status); - DeclareField(program_counter); - DeclareField(prefetch); - DeclareField(instruction); - } -} - -State::Inputs::Inputs() { - if(needs_declare()) { - DeclareField(bus_interrupt_level); - DeclareField(dtack); - DeclareField(is_peripheral_address); - DeclareField(bus_error); - DeclareField(bus_request); - DeclareField(bus_grant); - DeclareField(halt); - } -} - -State::ExecutionState::ExecutionState() { - if(needs_declare()) { - DeclareField(e_clock_phase); - DeclareField(effective_address); - DeclareField(source_data); - DeclareField(destination_data); - DeclareField(last_trace_flag); - DeclareField(next_word); - DeclareField(dbcc_false_address); - DeclareField(is_starting_interrupt); - DeclareField(pending_interrupt_level); - DeclareField(accepted_interrupt_level); - DeclareField(active_program); - DeclareField(movem_final_address); - DeclareField(source_addresses); - - AnnounceEnum(Phase); - DeclareField(phase); - - AnnounceEnum(MicroOpSource); - DeclareField(micro_op_source); - DeclareField(micro_op); - - AnnounceEnum(BusStepSource); - DeclareField(bus_step_source); - DeclareField(bus_step); - } -} diff --git a/Processors/68000/State/State.hpp b/Processors/68000/State/State.hpp deleted file mode 100644 index 08160d24a..000000000 --- a/Processors/68000/State/State.hpp +++ /dev/null @@ -1,137 +0,0 @@ -// -// State.hpp -// Clock Signal -// -// Created by Thomas Harte on 14/05/2020. -// Copyright © 2020 Thomas Harte. All rights reserved. -// - -#ifndef MC68000_State_hpp -#define MC68000_State_hpp - -#include "../../../Reflection/Enum.hpp" -#include "../../../Reflection/Struct.hpp" -#include "../68000.hpp" - -namespace CPU { -namespace MC68000 { - -/*! - Provides a means for capturing or restoring complete 68000 state. - - This is an optional adjunct to the 68000 class. If you want to take the rest of the 68000 - implementation but don't want any of the overhead of my sort-of half-reflection as - encapsulated in Reflection/[Enum/Struct].hpp just don't use this class. -*/ -struct State: public Reflection::StructImpl { - /*! - Provides the current state of the well-known, published internal registers. - */ - struct Registers: public Reflection::StructImpl { - // Official registers. - uint32_t data[8], address[7]; - uint32_t user_stack_pointer; - uint32_t supervisor_stack_pointer; - uint16_t status; - uint32_t program_counter; - - // The 68000's prefetch queue. - uint32_t prefetch; - uint16_t instruction; - - Registers(); - } registers; - - /*! - Provides the current state of the processor's various input lines that aren't - related to an access cycle. - */ - struct Inputs: public Reflection::StructImpl { - uint8_t bus_interrupt_level; - bool dtack; - bool is_peripheral_address; - bool bus_error; - bool bus_request; - bool bus_grant; - bool halt; - - Inputs(); - } inputs; - - /*! - Contains internal state used by this particular implementation of a 68000. Most of it - does not necessarily correlate with anything in a real 68000, and some of it very - obviously doesn't. - */ - struct ExecutionState: public Reflection::StructImpl { - uint8_t e_clock_phase; - uint32_t effective_address[2]; - uint32_t source_data; - uint32_t destination_data; - bool last_trace_flag; - uint16_t next_word; - uint32_t dbcc_false_address; - bool is_starting_interrupt; - uint8_t pending_interrupt_level; - uint8_t accepted_interrupt_level; - - // This is a reflective do-over of the ExecutionState enum within - // MC68000Storage; I've yet to decide how happy I am with that - // as an approach. - ReflectableEnum(Phase, - Executing, - WaitingForDTack, - Stopped, - Halted, - WillBeginInterrupt - ); - Phase phase; - - bool active_program; - uint32_t movem_final_address; - uint32_t source_addresses[65]; - - ReflectableEnum(MicroOpSource, - ActiveProgram, - LongException, - ShortException, - Interrupt - ); - MicroOpSource micro_op_source; - uint8_t micro_op; - - ReflectableEnum(BusStepSource, - FollowMicroOp, - BusError, - Trap, - Reset, - BranchTaken, - BranchByteNotTaken, - BranchWordNotTaken, - BSR, - DBccConditionTrue, - DBccConditionFalseNoBranch, - DBccConditionFalseBranch, - MovemRead, - MovemWrite, - ); - BusStepSource bus_step_source; - uint8_t bus_step; - - ExecutionState(); - } execution_state; - - /// Default constructor; makes no guarantees as to field values beyond those given above. - State(); - - /// Instantiates a new State based on the processor @c src. - State(const ProcessorBase &src); - - /// Applies this state to @c target. - void apply(ProcessorBase &target); -}; - -} -} - -#endif /* MC68000_State_hpp */ From 809cd7bca98f8ae731c717662577e1d28659e308 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 10 May 2023 17:13:01 -0500 Subject: [PATCH 05/10] Remove the 68000's Mk2 suffix. --- Machines/Amiga/Amiga.cpp | 6 +-- Machines/Amiga/Chipset.cpp | 4 +- Machines/Amiga/Chipset.hpp | 4 +- Machines/Amiga/MemoryMap.hpp | 8 ++-- Machines/Apple/Macintosh/Macintosh.cpp | 8 ++-- Machines/Atari/ST/AtariST.cpp | 6 +-- .../Clock Signal.xcodeproj/project.pbxproj | 44 +++++++++---------- .../68000ComparativeTests.mm | 10 ++--- .../Mac/Clock SignalTests/68000OldVsNew.mm | 2 +- .../Clock SignalTests/Comparative68000.hpp | 6 +-- .../Mac/Clock SignalTests/EmuTOSTests.mm | 10 ++--- OSBindings/Mac/Clock SignalTests/QLTests.mm | 10 ++--- .../Mac/Clock SignalTests/TestRunner68000.hpp | 12 ++--- .../68000Mk2.hpp => 68000/68000.hpp} | 20 ++++----- .../Implementation/68000Implementation.hpp} | 18 ++++---- .../Implementation/68000Storage.hpp} | 10 ++--- 16 files changed, 89 insertions(+), 89 deletions(-) rename Processors/{68000Mk2/68000Mk2.hpp => 68000/68000.hpp} (98%) rename Processors/{68000Mk2/Implementation/68000Mk2Implementation.hpp => 68000/Implementation/68000Implementation.hpp} (99%) rename Processors/{68000Mk2/Implementation/68000Mk2Storage.hpp => 68000/Implementation/68000Storage.hpp} (98%) diff --git a/Machines/Amiga/Amiga.cpp b/Machines/Amiga/Amiga.cpp index 370217d7c..5ad0a7bca 100644 --- a/Machines/Amiga/Amiga.cpp +++ b/Machines/Amiga/Amiga.cpp @@ -11,7 +11,7 @@ #include "../../Activity/Source.hpp" #include "../MachineTypes.hpp" -#include "../../Processors/68000Mk2/68000Mk2.hpp" +#include "../../Processors/68000/68000.hpp" #include "../../Analyser/Static/Amiga/Target.hpp" @@ -41,7 +41,7 @@ namespace Amiga { class ConcreteMachine: public Activity::Source, - public CPU::MC68000Mk2::BusHandler, + public CPU::MC68000::BusHandler, public MachineTypes::AudioProducer, public MachineTypes::JoystickMachine, public MachineTypes::MappedKeyboardMachine, @@ -177,7 +177,7 @@ class ConcreteMachine: } private: - CPU::MC68000Mk2::Processor mc68000_; + CPU::MC68000::Processor mc68000_; // MARK: - Memory map. diff --git a/Machines/Amiga/Chipset.cpp b/Machines/Amiga/Chipset.cpp index 8f1c23f25..5766c9b2c 100644 --- a/Machines/Amiga/Chipset.cpp +++ b/Machines/Amiga/Chipset.cpp @@ -841,8 +841,8 @@ void Chipset::update_interrupts() { } } -void Chipset::perform(const CPU::MC68000Mk2::Microcycle &cycle) { - using Microcycle = CPU::MC68000Mk2::Microcycle; +void Chipset::perform(const CPU::MC68000::Microcycle &cycle) { + using Microcycle = CPU::MC68000::Microcycle; const uint32_t register_address = *cycle.address & ChipsetAddressMask; if(cycle.operation & Microcycle::Read) { diff --git a/Machines/Amiga/Chipset.hpp b/Machines/Amiga/Chipset.hpp index 9957f0328..5b3ac8b10 100644 --- a/Machines/Amiga/Chipset.hpp +++ b/Machines/Amiga/Chipset.hpp @@ -20,7 +20,7 @@ #include "../../ClockReceiver/JustInTime.hpp" #include "../../Components/6526/6526.hpp" #include "../../Outputs/CRT/CRT.hpp" -#include "../../Processors/68000Mk2/68000Mk2.hpp" +#include "../../Processors/68000/68000.hpp" #include "../../Storage/Disk/Controller/DiskController.hpp" #include "../../Storage/Disk/Drive.hpp" @@ -58,7 +58,7 @@ class Chipset: private ClockingHint::Observer { Changes run_until_after_cpu_slot(); /// Performs the provided microcycle, which the caller guarantees to be a memory access. - void perform(const CPU::MC68000Mk2::Microcycle &); + void perform(const CPU::MC68000::Microcycle &); /// Sets the current state of the CIA interrupt lines. void set_cia_interrupts(bool cia_a, bool cia_b); diff --git a/Machines/Amiga/MemoryMap.hpp b/Machines/Amiga/MemoryMap.hpp index fbe920027..9e6c8fdf1 100644 --- a/Machines/Amiga/MemoryMap.hpp +++ b/Machines/Amiga/MemoryMap.hpp @@ -19,8 +19,8 @@ namespace Amiga { class MemoryMap { private: - static constexpr auto PermitRead = CPU::MC68000Mk2::Microcycle::PermitRead; - static constexpr auto PermitWrite = CPU::MC68000Mk2::Microcycle::PermitWrite; + static constexpr auto PermitRead = CPU::MC68000::Microcycle::PermitRead; + static constexpr auto PermitWrite = CPU::MC68000::Microcycle::PermitWrite; static constexpr auto PermitReadWrite = PermitRead | PermitWrite; public: @@ -109,12 +109,12 @@ class MemoryMap { /// Performs the provided microcycle, which the caller guarantees to be a memory access, /// and in the Zorro register range. - bool perform(const CPU::MC68000Mk2::Microcycle &cycle) { + bool perform(const CPU::MC68000::Microcycle &cycle) { if(!fast_autoconf_visible_) return false; const uint32_t register_address = *cycle.address & 0xfe; - using Microcycle = CPU::MC68000Mk2::Microcycle; + using Microcycle = CPU::MC68000::Microcycle; if(cycle.operation & Microcycle::Read) { // Re: Autoconf: // diff --git a/Machines/Apple/Macintosh/Macintosh.cpp b/Machines/Apple/Macintosh/Macintosh.cpp index 3900aeb11..d2f0dd11e 100644 --- a/Machines/Apple/Macintosh/Macintosh.cpp +++ b/Machines/Apple/Macintosh/Macintosh.cpp @@ -35,7 +35,7 @@ #include "../../../Components/DiskII/IWM.hpp" #include "../../../Components/DiskII/MacintoshDoubleDensityDrive.hpp" -#include "../../../Processors/68000Mk2/68000Mk2.hpp" +#include "../../../Processors/68000/68000.hpp" #include "../../../Storage/MassStorage/SCSI/SCSI.hpp" #include "../../../Storage/MassStorage/SCSI/DirectAccessDevice.hpp" @@ -73,7 +73,7 @@ template class ConcreteMachin public MachineTypes::MediaTarget, public MachineTypes::MouseMachine, public MachineTypes::MappedKeyboardMachine, - public CPU::MC68000Mk2::BusHandler, + public CPU::MC68000::BusHandler, public Zilog::SCC::z8530::Delegate, public Activity::Source, public Configurable::Device, @@ -191,7 +191,7 @@ template class ConcreteMachin mc68000_.run_for(cycles); } - using Microcycle = CPU::MC68000Mk2::Microcycle; + using Microcycle = CPU::MC68000::Microcycle; HalfCycles perform_bus_operation(const Microcycle &cycle, int) { // Advance time. @@ -747,7 +747,7 @@ template class ConcreteMachin Inputs::QuadratureMouse &mouse_; }; - CPU::MC68000Mk2::Processor mc68000_; + CPU::MC68000::Processor mc68000_; DriveSpeedAccumulator drive_speed_accumulator_; IWMActor iwm_; diff --git a/Machines/Atari/ST/AtariST.cpp b/Machines/Atari/ST/AtariST.cpp index 6925ad85a..f40e1de0a 100644 --- a/Machines/Atari/ST/AtariST.cpp +++ b/Machines/Atari/ST/AtariST.cpp @@ -13,7 +13,7 @@ //#define LOG_TRACE //bool should_log = false; -#include "../../../Processors/68000Mk2/68000Mk2.hpp" +#include "../../../Processors/68000/68000.hpp" #include "../../../Components/AY38910/AY38910.hpp" #include "../../../Components/68901/MFP68901.hpp" @@ -45,7 +45,7 @@ constexpr int CLOCK_RATE = 8021247; using Target = Analyser::Static::AtariST::Target; class ConcreteMachine: public Atari::ST::Machine, - public CPU::MC68000Mk2::BusHandler, + public CPU::MC68000::BusHandler, public MachineTypes::TimedMachine, public MachineTypes::ScanProducer, public MachineTypes::AudioProducer, @@ -492,7 +492,7 @@ class ConcreteMachine: speaker_.run_for(audio_queue_, cycles_since_audio_update_.divide_cycles(Cycles(4))); } - CPU::MC68000Mk2::Processor mc68000_; + CPU::MC68000::Processor mc68000_; HalfCycles bus_phase_; JustInTimeActor