From 47e9279bd46812f5495eb01cfda00db7bf8a99a3 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 16 Mar 2024 15:00:23 -0400 Subject: [PATCH] Add a target for I2C activity. --- Components/I2C/I2C.cpp | 35 +++++++++++++++++ Components/I2C/I2C.hpp | 39 +++++++++++++++++++ Machines/Acorn/Archimedes/Archimedes.cpp | 18 ++++++++- .../Clock Signal.xcodeproj/project.pbxproj | 8 ++++ OSBindings/Qt/clksignal.pro | 8 ++-- OSBindings/SDL/SConstruct | 1 + cmake/CLK_SOURCES.cmake | 1 + 7 files changed, 106 insertions(+), 4 deletions(-) create mode 100644 Components/I2C/I2C.cpp create mode 100644 Components/I2C/I2C.hpp diff --git a/Components/I2C/I2C.cpp b/Components/I2C/I2C.cpp new file mode 100644 index 000000000..3c83bd0e4 --- /dev/null +++ b/Components/I2C/I2C.cpp @@ -0,0 +1,35 @@ +// +// I2C.cpp +// Clock Signal +// +// Created by Thomas Harte on 16/03/2024. +// Copyright © 2024 Thomas Harte. All rights reserved. +// + +#include "I2C.hpp" + +using namespace I2C; + +void Bus::set_data(bool pulled) { + set_clock_data(clock_, pulled); +} +bool Bus::data() { + return data_; +} + +void Bus::set_clock(bool pulled) { + set_clock_data(pulled, data_); +} +bool Bus::clock() { + return clock_; +} + +void Bus::set_clock_data(bool clock_pulled, bool data_pulled) { + // TODO: all intelligence. + clock_ = clock_pulled; + data_ = data_pulled; +} + +void Bus::add_peripheral(Peripheral *peripheral, int address) { + peripherals_[address] = peripheral; +} diff --git a/Components/I2C/I2C.hpp b/Components/I2C/I2C.hpp new file mode 100644 index 000000000..aaf8942b2 --- /dev/null +++ b/Components/I2C/I2C.hpp @@ -0,0 +1,39 @@ +// +// I2C.hpp +// Clock Signal +// +// Created by Thomas Harte on 16/03/2024. +// Copyright © 2024 Thomas Harte. All rights reserved. +// + +#pragma once + +#include + +namespace I2C { + +/// Provides the virtual interface for an I2C peripheral; attaching this to a bus +/// provides automatic protocol handling. +class Peripheral { + +}; + +class Bus { +public: + void set_data(bool pulled); + bool data(); + + void set_clock(bool pulled); + bool clock(); + + void set_clock_data(bool clock_pulled, bool data_pulled); + + void add_peripheral(Peripheral *, int address); + +private: + bool data_ = false; + bool clock_ = false; + std::unordered_map peripherals_; +}; + +} diff --git a/Machines/Acorn/Archimedes/Archimedes.cpp b/Machines/Acorn/Archimedes/Archimedes.cpp index 775d64e6d..93489cc52 100644 --- a/Machines/Acorn/Archimedes/Archimedes.cpp +++ b/Machines/Acorn/Archimedes/Archimedes.cpp @@ -16,6 +16,7 @@ #include "../../../InstructionSets/ARM/Executor.hpp" #include "../../../Outputs/Log.hpp" +#include "../../../Components/I2C/I2C.hpp" #include #include @@ -385,7 +386,9 @@ struct Interrupts { case 0x3200000 & AddressMask: logger.error().append("TODO: IOC control read"); - value = 0; + value = control_; + value &= ~(i2c_.clock() ? 2 : 0); + value &= ~(i2c_.data() ? 1 : 0); return true; case 0x3200004 & AddressMask: @@ -465,6 +468,10 @@ struct Interrupts { break; case 0x320'0000 & AddressMask: + control_ = value; + i2c_.set_clock_data(!(value & 2), !(value & 1)); + + // TODO: rest relates to floppy control, maybe? logger.error().append("TODO: IOC control write %02x", value); return true; @@ -572,6 +579,7 @@ struct Interrupts { } private: + // IRQA, IRQB and FIQ states. struct Interrupt { uint8_t status, mask; uint8_t request() const { @@ -587,6 +595,7 @@ private: }; Interrupt irq_a_, irq_b_, fiq_; + // The IOCs four counters. struct Counter { uint16_t value; uint16_t reload; @@ -594,8 +603,15 @@ private: }; Counter counters_[4]; + // The KART and keyboard beyond it. HalfDuplexSerial serial_; Keyboard keyboard_; + + // The control register. + uint8_t control_ = 0xff; + + // The I2C bus. + I2C::Bus i2c_; }; /// Primarily models the MEMC. diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 5bdcaf68c..843a2c21c 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -215,6 +215,8 @@ 4B228CDB24DA41890077EF25 /* ScanTarget.metal in Sources */ = {isa = PBXBuildFile; fileRef = 4B228CDA24DA41880077EF25 /* ScanTarget.metal */; }; 4B2530F4244E6774007980BF /* fm.json in Resources */ = {isa = PBXBuildFile; fileRef = 4B2530F3244E6773007980BF /* fm.json */; }; 4B25B5F925BD083C00362C84 /* DiskIIDrive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B80CD6D2568A82600176FCC /* DiskIIDrive.cpp */; }; + 4B2A1CD52BA62066004496CE /* I2C.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A1CD32BA62066004496CE /* I2C.cpp */; }; + 4B2A1CD62BA62066004496CE /* I2C.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A1CD32BA62066004496CE /* I2C.cpp */; }; 4B2A332D1DB86821002876E3 /* OricOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2A332B1DB86821002876E3 /* OricOptions.xib */; }; 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; }; 4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2B3A471F9B8FA70062DABF /* Typer.cpp */; }; @@ -1351,6 +1353,8 @@ 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = ""; }; 4B2530F3244E6773007980BF /* fm.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = fm.json; sourceTree = ""; }; 4B262BFF29691F55002EC0F7 /* PersonalityTraits.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PersonalityTraits.hpp; sourceTree = ""; }; + 4B2A1CD32BA62066004496CE /* I2C.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = I2C.cpp; path = I2C/I2C.cpp; sourceTree = ""; }; + 4B2A1CD42BA62066004496CE /* I2C.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = I2C.hpp; path = I2C/I2C.hpp; sourceTree = ""; }; 4B2A332C1DB86821002876E3 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/OricOptions.xib"; sourceTree = SOURCE_ROOT; }; 4B2A3B5A29993DFA007CE366 /* Storage.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Storage.hpp; sourceTree = ""; }; 4B2A3B5B29995FF6007CE366 /* LineBuffer.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineBuffer.hpp; sourceTree = ""; }; @@ -4826,6 +4830,8 @@ 4BF0BC6E2973318E00CCA2B5 /* RP5C01 */, 4B0ACBFF237756EC008902D0 /* Serial */, 4BB0A6582044FD3000FB3688 /* SN76489 */, + 4B2A1CD32BA62066004496CE /* I2C.cpp */, + 4B2A1CD42BA62066004496CE /* I2C.hpp */, ); name = Components; path = ../../Components; @@ -5874,6 +5880,7 @@ 4B055A9E1FAE85DA0060FFFF /* G64.cpp in Sources */, 4B055AB81FAE860F0060FFFF /* ZX80O81P.cpp in Sources */, 4B055AB01FAE86070060FFFF /* PulseQueuedTape.cpp in Sources */, + 4B2A1CD62BA62066004496CE /* I2C.cpp in Sources */, 4B0F1C1D2604EA1000B85C66 /* Keyboard.cpp in Sources */, 4B055AAC1FAE85FD0060FFFF /* PCMSegment.cpp in Sources */, 4BB307BC235001C300457D33 /* 6850.cpp in Sources */, @@ -6069,6 +6076,7 @@ 4B4518A11F75FD1C00926311 /* D64.cpp in Sources */, 4BCE0052227CE8CA000CA200 /* DiskIICard.cpp in Sources */, 4BF0BC68297108D600CCA2B5 /* MemorySlotHandler.cpp in Sources */, + 4B2A1CD52BA62066004496CE /* I2C.cpp in Sources */, 4BCF1FA41DADC3DD0039D2E7 /* Oric.cpp in Sources */, 4BD67DCB209BE4D700AB2146 /* StaticAnalyser.cpp in Sources */, 4BB4BFB922A4372F0069048D /* StaticAnalyser.cpp in Sources */, diff --git a/OSBindings/Qt/clksignal.pro b/OSBindings/Qt/clksignal.pro index f41076a23..93ed5b54d 100644 --- a/OSBindings/Qt/clksignal.pro +++ b/OSBindings/Qt/clksignal.pro @@ -71,11 +71,12 @@ SOURCES += \ $$SRC/Components/AudioToggle/*.cpp \ $$SRC/Components/AY38910/*.cpp \ $$SRC/Components/DiskII/*.cpp \ + $$SRC/Components/I2C/*.cpp \ $$SRC/Components/KonamiSCC/*.cpp \ $$SRC/Components/OPx/*.cpp \ - $$SRC/Components/SN76489/*.cpp \ - $$SRC/Components/Serial/*.cpp \ $$SRC/Components/RP5C01/*.cpp \ + $$SRC/Components/Serial/*.cpp \ + $$SRC/Components/SN76489/*.cpp \ \ $$SRC/Inputs/*.cpp \ \ @@ -202,12 +203,13 @@ HEADERS += \ $$SRC/Components/AudioToggle/*.hpp \ $$SRC/Components/AY38910/*.hpp \ $$SRC/Components/DiskII/*.hpp \ + $$SRC/Components/I2C/*.hpp \ $$SRC/Components/KonamiSCC/*.hpp \ $$SRC/Components/OPx/*.hpp \ $$SRC/Components/OPx/Implementation/*.hpp \ + $$SRC/Components/RP5C01/*.hpp \ $$SRC/Components/Serial/*.hpp \ $$SRC/Components/SN76489/*.hpp \ - $$SRC/Components/RP5C01/*.hpp \ \ $$SRC/Concurrency/*.hpp \ \ diff --git a/OSBindings/SDL/SConstruct b/OSBindings/SDL/SConstruct index fdc859455..3e4cb0f9b 100644 --- a/OSBindings/SDL/SConstruct +++ b/OSBindings/SDL/SConstruct @@ -56,6 +56,7 @@ SOURCES += glob.glob('../../Components/9918/Implementation/*.cpp') SOURCES += glob.glob('../../Components/AudioToggle/*.cpp') SOURCES += glob.glob('../../Components/AY38910/*.cpp') SOURCES += glob.glob('../../Components/DiskII/*.cpp') +SOURCES += glob.glob('../../Components/I2C/*.cpp') SOURCES += glob.glob('../../Components/KonamiSCC/*.cpp') SOURCES += glob.glob('../../Components/OPx/*.cpp') SOURCES += glob.glob('../../Components/RP5C01/*.cpp') diff --git a/cmake/CLK_SOURCES.cmake b/cmake/CLK_SOURCES.cmake index 122b8396a..4a621669f 100644 --- a/cmake/CLK_SOURCES.cmake +++ b/cmake/CLK_SOURCES.cmake @@ -55,6 +55,7 @@ set(CLK_SOURCES Components/DiskII/DiskIIDrive.cpp Components/DiskII/IWM.cpp Components/DiskII/MacintoshDoubleDensityDrive.cpp + Components/I2C/I2C.cpp Components/KonamiSCC/KonamiSCC.cpp Components/OPx/OPLL.cpp Components/RP5C01/RP5C01.cpp