diff --git a/Analyser/Static/TandyCoCo/Target.hpp b/Analyser/Static/TandyCoCo/Target.hpp index 72c4953c9..18f5f776c 100644 --- a/Analyser/Static/TandyCoCo/Target.hpp +++ b/Analyser/Static/TandyCoCo/Target.hpp @@ -31,6 +31,7 @@ struct Target: public Analyser::Static::Target, public Reflection::StructImpl; @@ -39,6 +40,7 @@ private: AnnounceEnum(MemorySize); DeclareField(model); DeclareField(memory_size); + DeclareField(has_disk_drive); } }; diff --git a/Machines/Tandy/CoCo/CoCo.cpp b/Machines/Tandy/CoCo/CoCo.cpp index 6e0b506bb..bccd5d720 100644 --- a/Machines/Tandy/CoCo/CoCo.cpp +++ b/Machines/Tandy/CoCo/CoCo.cpp @@ -8,6 +8,7 @@ #include "CoCo.hpp" +#include "DiskController.hpp" #include "Keyboard.hpp" #include "Processors/6809/6809.hpp" @@ -370,7 +371,7 @@ static constexpr auto AudioDivider = Cycles(1); namespace TandyCoCo { -template +template class ConcreteMachine: public Activity::Source, public Configurable::Device, @@ -1056,18 +1057,38 @@ private: update_audio(); audio_.set_output(new_audio_output); } + + // MARK: - Disk. + + DiskController disk_controller_; }; } +namespace { + +template +std::unique_ptr create( + const Analyser::Static::TandyCoCo::Target &target, + const ROMMachine::ROMFetcher &rom_fetcher +) { + if(Analyser::Static::TandyCoCo::is_pal(target.model)) { + return std::make_unique>(target, rom_fetcher); + } else { + return std::make_unique>(target, rom_fetcher); + } +} + +} + std::unique_ptr Machine::create( const Analyser::Static::Target &target, const ROMMachine::ROMFetcher &rom_fetcher ) { const auto &coco_target = static_cast(target); - if(Analyser::Static::TandyCoCo::is_pal(coco_target.model)) { - return std::make_unique>(coco_target, rom_fetcher); + if(coco_target.has_disk_drive) { + return ::create(coco_target, rom_fetcher); } else { - return std::make_unique>(coco_target, rom_fetcher); + return ::create(coco_target, rom_fetcher); } } diff --git a/Machines/Tandy/CoCo/DiskController.cpp b/Machines/Tandy/CoCo/DiskController.cpp new file mode 100644 index 000000000..0613146b7 --- /dev/null +++ b/Machines/Tandy/CoCo/DiskController.cpp @@ -0,0 +1,15 @@ +// +// DiskController.cpp +// Clock Signal +// +// Created by Thomas Harte on 18/05/2026. +// Copyright © 2026 Thomas Harte. All rights reserved. +// + +#include "DiskController.hpp" + +using namespace Tandy::CoCo; + +DiskController::DiskController() : WD::WD1770(P1773) { + emplace_drives(2, 8'000'000, 300, 2); +} diff --git a/Machines/Tandy/CoCo/DiskController.hpp b/Machines/Tandy/CoCo/DiskController.hpp new file mode 100644 index 000000000..fd70414ac --- /dev/null +++ b/Machines/Tandy/CoCo/DiskController.hpp @@ -0,0 +1,21 @@ +// +// DiskController.hpp +// Clock Signal +// +// Created by Thomas Harte on 18/05/2026. +// Copyright © 2026 Thomas Harte. All rights reserved. +// + +#pragma once + +#include "Components/1770/1770.hpp" + +namespace Tandy::CoCo { + +class DiskController final: public WD::WD1770 { +public: + DiskController(); + +}; + +} diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 5f156f4ca..c22f60605 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -43,6 +43,9 @@ 42EB812E2B4700B700429AF4 /* MemoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42EB812C2B47008D00429AF4 /* MemoryMap.cpp */; }; 42EB812F2B4700B800429AF4 /* MemoryMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 42EB812C2B47008D00429AF4 /* MemoryMap.cpp */; }; 4B01710F2FB6ADA700302CEF /* QuickLoadCompositeDynamicCropOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B01710D2FB6ADA700302CEF /* QuickLoadCompositeDynamicCropOptions.xib */; }; + 4B0171122FBBA40F00302CEF /* DiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0171112FBBA40F00302CEF /* DiskController.cpp */; }; + 4B0171132FBBA40F00302CEF /* DiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0171112FBBA40F00302CEF /* DiskController.cpp */; }; + 4B0171142FBBA40F00302CEF /* DiskController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0171112FBBA40F00302CEF /* DiskController.cpp */; }; 4B018B89211930DE002A3937 /* 65C02_extended_opcodes_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */; }; 4B01A6881F22F0DB001FD6E3 /* Z80MemptrTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */; }; 4B0333AF2094081A0050B93D /* AppleDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B0333AD2094081A0050B93D /* AppleDSK.cpp */; }; @@ -1398,6 +1401,8 @@ 42EB81272B23AAC300429AF4 /* IMD.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = IMD.hpp; sourceTree = ""; }; 42EB812C2B47008D00429AF4 /* MemoryMap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryMap.cpp; sourceTree = ""; }; 4B01710E2FB6ADA700302CEF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/QuickLoadCompositeDynamicCropOptions.xib; sourceTree = ""; }; + 4B0171102FBBA40F00302CEF /* DiskController.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = DiskController.hpp; sourceTree = ""; }; + 4B0171112FBBA40F00302CEF /* DiskController.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = DiskController.cpp; sourceTree = ""; }; 4B018B88211930DE002A3937 /* 65C02_extended_opcodes_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = 65C02_extended_opcodes_test.bin; path = "Klaus Dormann/65C02_extended_opcodes_test.bin"; sourceTree = ""; }; 4B01A6871F22F0DB001FD6E3 /* Z80MemptrTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MemptrTests.swift; sourceTree = ""; }; 4B03291F2D0923E300C51EB5 /* Video.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Video.hpp; sourceTree = ""; }; @@ -3441,7 +3446,9 @@ isa = PBXGroup; children = ( 4B41EF6F2FA55F980086D909 /* CoCo.cpp */, + 4B0171112FBBA40F00302CEF /* DiskController.cpp */, 4B41EF6E2FA55F980086D909 /* CoCo.hpp */, + 4B0171102FBBA40F00302CEF /* DiskController.hpp */, 4B41EF842FAC26590086D909 /* Keyboard.hpp */, ); path = CoCo; @@ -6639,6 +6646,7 @@ 4B9BE401203A0C0600FFAE60 /* MultiSpeaker.cpp in Sources */, 4BB505812B962DDF0031C43C /* Plus3.cpp in Sources */, 4B055AA61FAE85EF0060FFFF /* Parser.cpp in Sources */, + 4B0171142FBBA40F00302CEF /* DiskController.cpp in Sources */, 4BF8D4D6251C11DD00BBE21B /* 65816Storage.cpp in Sources */, 4B055AEF1FAE9BF00060FFFF /* Typer.cpp in Sources */, 4B89453F201967B4007DE474 /* StaticAnalyser.cpp in Sources */, @@ -6928,6 +6936,7 @@ 4BEDA3BA25B25563000C2DBD /* Decoder.cpp in Sources */, 4BFEA2EF2682A7B900EBF94C /* Dave.cpp in Sources */, 4B4518A21F75FD1C00926311 /* G64.cpp in Sources */, + 4B0171132FBBA40F00302CEF /* DiskController.cpp in Sources */, 4B0B23A62D6AC53B00153879 /* CSFileContentChangeObserver.m in Sources */, 4B89452C201967B4007DE474 /* Tape.cpp in Sources */, 4B448E811F1C45A00009ABD6 /* TZX.cpp in Sources */, @@ -7402,6 +7411,7 @@ 4B06AB0E2C6461700034D014 /* MultiMediaTarget.cpp in Sources */, 42437B332AC70833006DFED1 /* HDV.cpp in Sources */, 4B06AAE82C645FCD0034D014 /* RP5C01.cpp in Sources */, + 4B0171122FBBA40F00302CEF /* DiskController.cpp in Sources */, 4B06AAEC2C645FF50034D014 /* Keyboard.cpp in Sources */, 4B06AAF02C6460240034D014 /* ReactiveDevice.cpp in Sources */, 4B7752C028217F3D0073E2C5 /* Line.cpp in Sources */,