From 08ad35efd9dab72a1a871269c01d8870f9e15fda Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 1 Aug 2017 16:34:13 -0400 Subject: [PATCH] It's barely an implementation of the 8255, but ensured that data is bounced into the PortHandler, conveniently assuming the interaction mode used by the CPC. --- Components/8255/i8255.hpp | 49 +++++++++++++++---- Machines/AmstradCPC/AmstradCPC.cpp | 21 +++++++- .../Clock Signal.xcodeproj/project.pbxproj | 6 +-- 3 files changed, 60 insertions(+), 16 deletions(-) diff --git a/Components/8255/i8255.hpp b/Components/8255/i8255.hpp index 2aa73f635..96e4e0a0a 100644 --- a/Components/8255/i8255.hpp +++ b/Components/8255/i8255.hpp @@ -13,28 +13,57 @@ namespace Intel { namespace i8255 { class PortHandler { + public: + void set_value(int port, uint8_t value) {} + uint8_t get_value(int port) { return 0xff; } }; +// TODO: most of the implementation below. Right now it just blindly passes data in all directions, +// ignoring operation mode. But at least it establishes proper ownership and hand-off of decision making. template class i8255 { public: + i8255() : control_(0), outputs_{0, 0, 0} {} + void set_register(int address, uint8_t value) { - switch((address >> 8) & 3) { - case 0: printf("PSG data: %d\n", value); break; - case 1: printf("Vsync, etc: %02x\n", value); break; - case 2: printf("Key row, etc: %02x\n", value); break; - case 3: printf("PIO control: %02x\n", value); break; + switch(address & 3) { + case 0: outputs_[0] = value; port_handler_.set_value(0, value); break; + case 1: outputs_[1] = value; port_handler_.set_value(1, value); break; + case 2: outputs_[2] = value; port_handler_.set_value(2, value); break; + case 3: + if(value & 0x80) { + control_ = value; + } else { + if(value & 1) { + outputs_[2] |= 1 << ((value >> 1)&7); + } else { + outputs_[2] &= ~(1 << ((value >> 1)&7)); + } + } + update_outputs(); + break; } } uint8_t get_register(int address) { - switch((address >> 8) & 3) { - case 0: printf("[In] PSG data\n"); break; - case 1: printf("[In] Vsync, etc\n"); break; - case 2: printf("[In] Key row, etc\n"); break; - case 3: printf("[In] PIO control\n"); break; + switch(address & 3) { + case 0: return port_handler_.get_value(0); + case 1: return port_handler_.get_value(1); + case 2: return port_handler_.get_value(2); + case 3: return control_; } return 0xff; } + + private: + void update_outputs() { + port_handler_.set_value(0, outputs_[0]); + port_handler_.set_value(1, outputs_[1]); + port_handler_.set_value(2, outputs_[2]); + } + + uint8_t control_; + uint8_t outputs_[3]; + T port_handler_; }; } diff --git a/Machines/AmstradCPC/AmstradCPC.cpp b/Machines/AmstradCPC/AmstradCPC.cpp index 598171786..249653cca 100644 --- a/Machines/AmstradCPC/AmstradCPC.cpp +++ b/Machines/AmstradCPC/AmstradCPC.cpp @@ -16,7 +16,7 @@ using namespace AmstradCPC; -struct CRTCBusHandler { +class CRTCBusHandler { public: CRTCBusHandler(uint8_t *ram) : cycles_(0), @@ -249,7 +249,24 @@ struct CRTCBusHandler { int interrupt_reset_counter_; }; -struct i8255PortHandler : public Intel::i8255::PortHandler { +class i8255PortHandler : public Intel::i8255::PortHandler { + public: + void set_value(int port, uint8_t value) { + switch(port) { + case 0: printf("PSG data: %d\n", value); break; + case 1: printf("Vsync, etc: %02x\n", value); break; + case 2: printf("Key row, etc: %02x\n", value); break; + } + } + + uint8_t get_value(int port) { + switch(port) { + case 0: printf("PSG data\n"); break; + case 1: printf("[In] Vsync, etc\n"); break; + case 2: printf("[In] Key row, etc\n"); break; + } + return 0xff; + } }; class ConcreteMachine: diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index ff15f9843..31873f6f7 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -421,7 +421,6 @@ 4BD4A8D01E077FD20020D856 /* PCMTrackTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BD4A8CF1E077FD20020D856 /* PCMTrackTests.mm */; }; 4BD5F1951D13528900631CD1 /* CSBestEffortUpdater.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */; }; 4BD69F941D98760000243FE1 /* AcornADF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD69F921D98760000243FE1 /* AcornADF.cpp */; }; - 4BD9137B1F3115A8009BCF85 /* i8255.hpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD913791F3115A8009BCF85 /* i8255.hpp */; }; 4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */; }; 4BE77A2E1D84ADFB00BC3827 /* File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE77A2C1D84ADFB00BC3827 /* File.cpp */; }; 4BE7C9181E3D397100A5496D /* TIA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE7C9161E3D397100A5496D /* TIA.cpp */; }; @@ -997,7 +996,7 @@ 4BD5F1941D13528900631CD1 /* CSBestEffortUpdater.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CSBestEffortUpdater.m; path = Updater/CSBestEffortUpdater.m; sourceTree = ""; }; 4BD69F921D98760000243FE1 /* AcornADF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AcornADF.cpp; sourceTree = ""; }; 4BD69F931D98760000243FE1 /* AcornADF.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = AcornADF.hpp; sourceTree = ""; }; - 4BD913791F3115A8009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = ""; }; + 4BD9137D1F311BC5009BCF85 /* i8255.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = i8255.hpp; path = 8255/i8255.hpp; sourceTree = ""; }; 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = ""; }; 4BE77A2C1D84ADFB00BC3827 /* File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = File.cpp; path = ../../StaticAnalyser/Commodore/File.cpp; sourceTree = ""; }; 4BE77A2D1D84ADFB00BC3827 /* File.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = File.hpp; path = ../../StaticAnalyser/Commodore/File.hpp; sourceTree = ""; }; @@ -2127,7 +2126,7 @@ 4BD9137C1F3115AC009BCF85 /* 8255 */ = { isa = PBXGroup; children = ( - 4BD913791F3115A8009BCF85 /* i8255.hpp */, + 4BD9137D1F311BC5009BCF85 /* i8255.hpp */, ); name = 8255; sourceTree = ""; @@ -2684,7 +2683,6 @@ 4B2A332A1DB8544D002876E3 /* MemoryFuzzer.cpp in Sources */, 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */, 4B2A332F1DB86869002876E3 /* OricOptionsPanel.swift in Sources */, - 4BD9137B1F3115A8009BCF85 /* i8255.hpp in Sources */, 4B7913CC1DFCD80E00175A82 /* Video.cpp in Sources */, 4B2A53A11D117D36003C6002 /* CSAtari2600.mm in Sources */, 4BF829661D8F732B001BAE39 /* Disk.cpp in Sources */,