From 0d3d0fbe4dbb6218912875d8d3ad211000dff1b4 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 13:28:27 -0400 Subject: [PATCH 01/42] Created a namespace for `Commodore` and an empty container file for the 1540[/1] implementation. --- Machines/Commodore/1540/Commodore1540.cpp | 9 ++ Machines/Commodore/1540/Commodore1540.hpp | 14 +++ Machines/{ => Commodore}/Vic-20/Vic20.cpp | 2 +- Machines/{ => Commodore}/Vic-20/Vic20.hpp | 14 ++- .../Clock Signal.xcodeproj/project.pbxproj | 50 ++++++--- .../Clock Signal/Machine/Wrappers/CSVic20.mm | 106 +++++++++--------- 6 files changed, 122 insertions(+), 73 deletions(-) create mode 100644 Machines/Commodore/1540/Commodore1540.cpp create mode 100644 Machines/Commodore/1540/Commodore1540.hpp rename Machines/{ => Commodore}/Vic-20/Vic20.cpp (99%) rename Machines/{ => Commodore}/Vic-20/Vic20.hpp (96%) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp new file mode 100644 index 000000000..bec2a9567 --- /dev/null +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -0,0 +1,9 @@ +// +// Commodore1540.cpp +// Clock Signal +// +// Created by Thomas Harte on 05/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "Commodore1540.hpp" diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp new file mode 100644 index 000000000..f661b740a --- /dev/null +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -0,0 +1,14 @@ +// +// Commodore1540.hpp +// Clock Signal +// +// Created by Thomas Harte on 05/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef Commodore1540_hpp +#define Commodore1540_hpp + +#include + +#endif /* Commodore1540_hpp */ diff --git a/Machines/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp similarity index 99% rename from Machines/Vic-20/Vic20.cpp rename to Machines/Commodore/Vic-20/Vic20.cpp index c912908b4..b3b50f231 100644 --- a/Machines/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -10,7 +10,7 @@ #include -using namespace Vic20; +using namespace Commodore::Vic20; Machine::Machine() : _rom(nullptr) diff --git a/Machines/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp similarity index 96% rename from Machines/Vic-20/Vic20.hpp rename to Machines/Commodore/Vic-20/Vic20.hpp index 4c298aa13..af1453120 100644 --- a/Machines/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -9,14 +9,15 @@ #ifndef Vic20_hpp #define Vic20_hpp -#include "../../Processors/6502/CPU6502.hpp" -#include "../../Storage/Tape/Tape.hpp" -#include "../../Components/6560/6560.hpp" -#include "../../Components/6522/6522.hpp" +#include "../../../Processors/6502/CPU6502.hpp" +#include "../../../Storage/Tape/Tape.hpp" +#include "../../../Components/6560/6560.hpp" +#include "../../../Components/6522/6522.hpp" -#include "../CRTMachine.hpp" -#include "../Typer.hpp" +#include "../../CRTMachine.hpp" +#include "../../Typer.hpp" +namespace Commodore { namespace Vic20 { enum ROMSlot { @@ -292,6 +293,7 @@ class Machine: bool _use_fast_tape_hack; }; +} } #endif /* Vic20_hpp */ diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index b4c059c73..a0a688053 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; + 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; + 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; }; 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */; }; 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; }; 4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */; }; @@ -34,7 +36,6 @@ 4B69FB461C4D950F00B5F0AA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4B69FB451C4D950F00B5F0AA /* libz.tbd */; }; 4B73C71A1D036BD90074D992 /* Vic20Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B73C7191D036BD90074D992 /* Vic20Document.swift */; }; 4B73C71D1D036C030074D992 /* Vic20Document.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B73C71B1D036C030074D992 /* Vic20Document.xib */; }; - 4B886FF21D03B517004291C3 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B886FF01D03B517004291C3 /* Vic20.cpp */; }; 4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */; }; 4BB298EE1B587D8400A49093 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */; }; 4BB298EF1B587D8400A49093 /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E11B587D8300A49093 /* AllSuiteA.bin */; }; @@ -384,6 +385,10 @@ 4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = ""; }; 4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = ""; }; 4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = ""; }; + 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = ""; }; + 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = ""; }; + 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = ""; }; + 4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Commodore1540.hpp; sourceTree = ""; }; 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600Document.swift; sourceTree = ""; }; 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronDocument.swift; sourceTree = ""; }; 4B55CE5B1C3B7D6F0093A61B /* CSOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSOpenGLView.h; sourceTree = ""; }; @@ -396,8 +401,6 @@ 4B69FB451C4D950F00B5F0AA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; 4B73C7191D036BD90074D992 /* Vic20Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vic20Document.swift; sourceTree = ""; }; 4B73C71C1D036C030074D992 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Vic20Document.xib"; sourceTree = SOURCE_ROOT; }; - 4B886FF01D03B517004291C3 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vic20.cpp; path = "Vic-20/Vic20.cpp"; sourceTree = ""; }; - 4B886FF11D03B517004291C3 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Vic20.hpp; path = "Vic-20/Vic20.hpp"; sourceTree = ""; }; 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6502TimingTests.swift; sourceTree = ""; }; 4BB297DF1B587D8200A49093 /* Clock SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Clock SignalTests-Bridging-Header.h"; sourceTree = ""; }; 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = ""; }; @@ -859,6 +862,33 @@ name = Outputs; sourceTree = ""; }; + 4B4DC81D1D2C2425003C5BF8 /* Commodore */ = { + isa = PBXGroup; + children = ( + 4B4DC8251D2C2470003C5BF8 /* 1540 */, + 4B4DC81E1D2C2425003C5BF8 /* Vic-20 */, + ); + path = Commodore; + sourceTree = ""; + }; + 4B4DC81E1D2C2425003C5BF8 /* Vic-20 */ = { + isa = PBXGroup; + children = ( + 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */, + 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */, + ); + path = "Vic-20"; + sourceTree = ""; + }; + 4B4DC8251D2C2470003C5BF8 /* 1540 */ = { + isa = PBXGroup; + children = ( + 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */, + 4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */, + ); + path = 1540; + sourceTree = ""; + }; 4B55CE551C3B7D360093A61B /* Documents */ = { isa = PBXGroup; children = ( @@ -913,15 +943,6 @@ path = Formats; sourceTree = ""; }; - 4B886FF61D03B632004291C3 /* Vic-20 */ = { - isa = PBXGroup; - children = ( - 4B886FF01D03B517004291C3 /* Vic20.cpp */, - 4B886FF11D03B517004291C3 /* Vic20.hpp */, - ); - name = "Vic-20"; - sourceTree = ""; - }; 4BB297E41B587D8300A49093 /* Wolfgang Lorenz 6502 test suite */ = { isa = PBXGroup; children = ( @@ -1275,10 +1296,10 @@ 4BB73EDC1B587CA500552FC2 /* Machines */ = { isa = PBXGroup; children = ( + 4B4DC81D1D2C2425003C5BF8 /* Commodore */, 4B046DC31CFE651500E9E45E /* CRTMachine.hpp */, 4B2E2D961C3A06EC00138695 /* Atari2600 */, 4B2E2D9E1C3A070900138695 /* Electron */, - 4B886FF61D03B632004291C3 /* Vic-20 */, 4B1E85731D170228001EF87D /* Typer.cpp */, 4B1E85741D170228001EF87D /* Typer.hpp */, ); @@ -1780,7 +1801,6 @@ 4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */, 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */, 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */, - 4B886FF21D03B517004291C3 /* Vic20.cpp in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, 4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */, @@ -1791,8 +1811,10 @@ 4B55CE5F1C3B7D960093A61B /* MachineDocument.swift in Sources */, 4B2A53A11D117D36003C6002 /* CSAtari2600.mm in Sources */, 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */, + 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */, 4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */, 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */, + 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */, 4B1E85751D170228001EF87D /* Typer.cpp in Sources */, 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */, 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm index 434c7f197..3e576ca20 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm @@ -11,8 +11,10 @@ #include "Vic20.hpp" #include "CommodoreTAP.hpp" +using namespace Commodore::Vic20; + @implementation CSVic20 { - Vic20::Machine _vic20; + Machine _vic20; BOOL _joystickMode; } @@ -20,22 +22,22 @@ return &_vic20; } -- (void)setROM:(nonnull NSData *)rom slot:(Vic20::ROMSlot)slot { +- (void)setROM:(nonnull NSData *)rom slot:(ROMSlot)slot { @synchronized(self) { _vic20.set_rom(slot, rom.length, (const uint8_t *)rom.bytes); } } - (void)setKernelROM:(nonnull NSData *)rom { - [self setROM:rom slot:Vic20::ROMSlotKernel]; + [self setROM:rom slot:ROMSlotKernel]; } - (void)setBASICROM:(nonnull NSData *)rom { - [self setROM:rom slot:Vic20::ROMSlotBASIC]; + [self setROM:rom slot:ROMSlotBASIC]; } - (void)setCharactersROM:(nonnull NSData *)rom { - [self setROM:rom slot:Vic20::ROMSlotCharacters]; + [self setROM:rom slot:ROMSlotCharacters]; } - (BOOL)openTAPAtURL:(NSURL *)URL { @@ -59,50 +61,50 @@ - (void)setKey:(uint16_t)key isPressed:(BOOL)isPressed { static NSDictionary *vicKeysByKeys = @{ - @(VK_ANSI_1): @(Vic20::Key::Key1), @(VK_ANSI_2): @(Vic20::Key::Key2), - @(VK_ANSI_3): @(Vic20::Key::Key3), @(VK_ANSI_4): @(Vic20::Key::Key4), - @(VK_ANSI_5): @(Vic20::Key::Key5), @(VK_ANSI_6): @(Vic20::Key::Key6), - @(VK_ANSI_7): @(Vic20::Key::Key7), @(VK_ANSI_8): @(Vic20::Key::Key8), - @(VK_ANSI_9): @(Vic20::Key::Key9), @(VK_ANSI_0): @(Vic20::Key::Key0), + @(VK_ANSI_1): @(Key::Key1), @(VK_ANSI_2): @(Key::Key2), + @(VK_ANSI_3): @(Key::Key3), @(VK_ANSI_4): @(Key::Key4), + @(VK_ANSI_5): @(Key::Key5), @(VK_ANSI_6): @(Key::Key6), + @(VK_ANSI_7): @(Key::Key7), @(VK_ANSI_8): @(Key::Key8), + @(VK_ANSI_9): @(Key::Key9), @(VK_ANSI_0): @(Key::Key0), - @(VK_ANSI_Q): @(Vic20::Key::KeyQ), @(VK_ANSI_W): @(Vic20::Key::KeyW), - @(VK_ANSI_E): @(Vic20::Key::KeyE), @(VK_ANSI_R): @(Vic20::Key::KeyR), - @(VK_ANSI_T): @(Vic20::Key::KeyT), @(VK_ANSI_Y): @(Vic20::Key::KeyY), - @(VK_ANSI_U): @(Vic20::Key::KeyU), @(VK_ANSI_I): @(Vic20::Key::KeyI), - @(VK_ANSI_O): @(Vic20::Key::KeyO), @(VK_ANSI_P): @(Vic20::Key::KeyP), - @(VK_ANSI_A): @(Vic20::Key::KeyA), @(VK_ANSI_S): @(Vic20::Key::KeyS), - @(VK_ANSI_D): @(Vic20::Key::KeyD), @(VK_ANSI_F): @(Vic20::Key::KeyF), - @(VK_ANSI_G): @(Vic20::Key::KeyG), @(VK_ANSI_H): @(Vic20::Key::KeyH), - @(VK_ANSI_J): @(Vic20::Key::KeyJ), @(VK_ANSI_K): @(Vic20::Key::KeyK), - @(VK_ANSI_L): @(Vic20::Key::KeyL), @(VK_ANSI_Z): @(Vic20::Key::KeyZ), - @(VK_ANSI_X): @(Vic20::Key::KeyX), @(VK_ANSI_C): @(Vic20::Key::KeyC), - @(VK_ANSI_V): @(Vic20::Key::KeyV), @(VK_ANSI_B): @(Vic20::Key::KeyB), - @(VK_ANSI_N): @(Vic20::Key::KeyN), @(VK_ANSI_M): @(Vic20::Key::KeyM), + @(VK_ANSI_Q): @(Key::KeyQ), @(VK_ANSI_W): @(Key::KeyW), + @(VK_ANSI_E): @(Key::KeyE), @(VK_ANSI_R): @(Key::KeyR), + @(VK_ANSI_T): @(Key::KeyT), @(VK_ANSI_Y): @(Key::KeyY), + @(VK_ANSI_U): @(Key::KeyU), @(VK_ANSI_I): @(Key::KeyI), + @(VK_ANSI_O): @(Key::KeyO), @(VK_ANSI_P): @(Key::KeyP), + @(VK_ANSI_A): @(Key::KeyA), @(VK_ANSI_S): @(Key::KeyS), + @(VK_ANSI_D): @(Key::KeyD), @(VK_ANSI_F): @(Key::KeyF), + @(VK_ANSI_G): @(Key::KeyG), @(VK_ANSI_H): @(Key::KeyH), + @(VK_ANSI_J): @(Key::KeyJ), @(VK_ANSI_K): @(Key::KeyK), + @(VK_ANSI_L): @(Key::KeyL), @(VK_ANSI_Z): @(Key::KeyZ), + @(VK_ANSI_X): @(Key::KeyX), @(VK_ANSI_C): @(Key::KeyC), + @(VK_ANSI_V): @(Key::KeyV), @(VK_ANSI_B): @(Key::KeyB), + @(VK_ANSI_N): @(Key::KeyN), @(VK_ANSI_M): @(Key::KeyM), - @(VK_Space): @(Vic20::Key::KeySpace), - @(VK_Return): @(Vic20::Key::KeyReturn), - @(VK_Delete): @(Vic20::Key::KeyDelete), - @(VK_ANSI_Comma): @(Vic20::Key::KeyComma), - @(VK_ANSI_Period): @(Vic20::Key::KeyFullStop), - @(VK_ANSI_Minus): @(Vic20::Key::KeyDash), - @(VK_ANSI_Equal): @(Vic20::Key::KeyEquals), - @(VK_ANSI_Semicolon): @(Vic20::Key::KeyColon), - @(VK_ANSI_Quote): @(Vic20::Key::KeySemicolon), - @(VK_ANSI_Slash): @(Vic20::Key::KeySlash), - @(VK_Option): @(Vic20::Key::KeyCBM), - @(VK_Control): @(Vic20::Key::KeyControl), + @(VK_Space): @(Key::KeySpace), + @(VK_Return): @(Key::KeyReturn), + @(VK_Delete): @(Key::KeyDelete), + @(VK_ANSI_Comma): @(Key::KeyComma), + @(VK_ANSI_Period): @(Key::KeyFullStop), + @(VK_ANSI_Minus): @(Key::KeyDash), + @(VK_ANSI_Equal): @(Key::KeyEquals), + @(VK_ANSI_Semicolon): @(Key::KeyColon), + @(VK_ANSI_Quote): @(Key::KeySemicolon), + @(VK_ANSI_Slash): @(Key::KeySlash), + @(VK_Option): @(Key::KeyCBM), + @(VK_Control): @(Key::KeyControl), - @(VK_F1): @(Vic20::Key::KeyF1), @(VK_F3): @(Vic20::Key::KeyF3), - @(VK_F5): @(Vic20::Key::KeyF5), @(VK_F7): @(Vic20::Key::KeyF7), + @(VK_F1): @(Key::KeyF1), @(VK_F3): @(Key::KeyF3), + @(VK_F5): @(Key::KeyF5), @(VK_F7): @(Key::KeyF7), - @(VK_ANSI_Grave): @(Vic20::Key::KeyLeft), - @(VK_Tab): @(Vic20::Key::KeyRunStop), - @(VK_ANSI_LeftBracket): @(Vic20::Key::KeyAt), - @(VK_ANSI_RightBracket): @(Vic20::Key::KeyAsterisk), - @(VK_ANSI_Backslash): @(Vic20::Key::KeyUp), + @(VK_ANSI_Grave): @(Key::KeyLeft), + @(VK_Tab): @(Key::KeyRunStop), + @(VK_ANSI_LeftBracket): @(Key::KeyAt), + @(VK_ANSI_RightBracket): @(Key::KeyAsterisk), + @(VK_ANSI_Backslash): @(Key::KeyUp), - @(VK_RightArrow): @(Vic20::Key::KeyRight), - @(VK_DownArrow): @(Vic20::Key::KeyDown), + @(VK_RightArrow): @(Key::KeyRight), + @(VK_DownArrow): @(Key::KeyDown), }; // Not yet mapped: @@ -120,11 +122,11 @@ { switch(key) { - case VK_UpArrow: _vic20.set_joystick_state(Vic20::JoystickInput::Up, isPressed); break; - case VK_DownArrow: _vic20.set_joystick_state(Vic20::JoystickInput::Down, isPressed); break; - case VK_LeftArrow: _vic20.set_joystick_state(Vic20::JoystickInput::Left, isPressed); break; - case VK_RightArrow: _vic20.set_joystick_state(Vic20::JoystickInput::Right, isPressed); break; - case VK_ANSI_A: _vic20.set_joystick_state(Vic20::JoystickInput::Fire, isPressed); break; + case VK_UpArrow: _vic20.set_joystick_state(JoystickInput::Up, isPressed); break; + case VK_DownArrow: _vic20.set_joystick_state(JoystickInput::Down, isPressed); break; + case VK_LeftArrow: _vic20.set_joystick_state(JoystickInput::Left, isPressed); break; + case VK_RightArrow: _vic20.set_joystick_state(JoystickInput::Right, isPressed); break; + case VK_ANSI_A: _vic20.set_joystick_state(JoystickInput::Fire, isPressed); break; } } else @@ -135,7 +137,7 @@ NSNumber *targetKey = vicKeysByKeys[@(key)]; if(targetKey) { - _vic20.set_key_state((Vic20::Key)targetKey.integerValue, isPressed); + _vic20.set_key_state((Key)targetKey.integerValue, isPressed); } else NSLog(@"Unmapped: %02x", key); @@ -143,8 +145,8 @@ case VK_Shift: // Yuck - _vic20.set_key_state(Vic20::Key::KeyLShift, isPressed); - _vic20.set_key_state(Vic20::Key::KeyRShift, isPressed); + _vic20.set_key_state(Key::KeyLShift, isPressed); + _vic20.set_key_state(Key::KeyRShift, isPressed); break; } } From d2cded7b591cf3bd625e570cc610421361017c17 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 14:55:20 -0400 Subject: [PATCH 02/42] Attempted to separate out the concept of a serial port and a serial bus, since the bus may be shared, and to establish half duplex communications from the Vic. --- Machines/Commodore/SerialBus.cpp | 43 ++++++++++++ Machines/Commodore/SerialBus.hpp | 67 +++++++++++++++++++ Machines/Commodore/Vic-20/Vic20.cpp | 38 +++-------- Machines/Commodore/Vic-20/Vic20.hpp | 19 ++---- .../Clock Signal.xcodeproj/project.pbxproj | 6 ++ 5 files changed, 134 insertions(+), 39 deletions(-) create mode 100644 Machines/Commodore/SerialBus.cpp create mode 100644 Machines/Commodore/SerialBus.hpp diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp new file mode 100644 index 000000000..7d7ca7a09 --- /dev/null +++ b/Machines/Commodore/SerialBus.cpp @@ -0,0 +1,43 @@ +// +// SerialPort.cpp +// Clock Signal +// +// Created by Thomas Harte on 05/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "SerialBus.hpp" + +using namespace Commodore::Serial; + +void Bus::add_port(std::shared_ptr port) +{ + _ports.push_back(port); +} + +void Bus::set_line_output_did_change(Line line) +{ + bool new_line_value = false; + for(std::weak_ptr port : _ports) + { + std::shared_ptr locked_port = port.lock(); + if(locked_port) + { + new_line_value |= locked_port->get_output(line); + } + } + + if(new_line_value != _line_values[line]) + { + _line_values[line] = new_line_value; + + for(std::weak_ptr port : _ports) + { + std::shared_ptr locked_port = port.lock(); + if(locked_port) + { + locked_port->set_input(line, new_line_value); + } + } + } +} diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp new file mode 100644 index 000000000..9f1034c7a --- /dev/null +++ b/Machines/Commodore/SerialBus.hpp @@ -0,0 +1,67 @@ +// +// SerialPort.hpp +// Clock Signal +// +// Created by Thomas Harte on 05/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef SerialBus_hpp +#define SerialBus_hpp + +#import + +namespace Commodore { +namespace Serial { + + enum Line { + ServiceRequest = 0, + Attention, + Clock, + Data, + Reset + }; + + class Port; + + class Bus { + public: + Bus() : _line_values{false, false, false, false, false} {} + + void add_port(std::shared_ptr port); + void set_line_output_did_change(Line line); + + private: + bool _line_values[5]; + std::vector> _ports; + }; + + class Port { + public: + Port() : _line_values{false, false, false, false, false} {} + + void set_output(Line line, bool value) { + _line_values[line] = value; + std::shared_ptr bus = _serial_bus.lock(); + if(bus) bus->set_line_output_did_change(line); + } + + bool get_output(Line line) { + return _line_values[line]; + } + + virtual void set_input(Line line, bool value) = 0; + + inline void set_serial_bus(std::shared_ptr serial_bus) { + _serial_bus = serial_bus; + } + + private: + std::weak_ptr _serial_bus; + bool _line_values[5]; + }; + +} +} + +#endif /* SerialPort_hpp */ diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index b3b50f231..af4f4db76 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -15,18 +15,27 @@ using namespace Commodore::Vic20; Machine::Machine() : _rom(nullptr) { + // create 6522s, serial port and bus _userPortVIA.reset(new UserPortVIA); _keyboardVIA.reset(new KeyboardVIA); _serialPort.reset(new SerialPort); + _serialBus.reset(new ::Commodore::Serial::Bus); + // wire up the serial bus and serial port + _serialBus->add_port(_serialPort); + _serialPort->set_serial_bus(_serialBus); + + // wire up 6522s and serial port _userPortVIA->set_serial_port(_serialPort); _keyboardVIA->set_serial_port(_serialPort); _serialPort->set_vias(_userPortVIA, _keyboardVIA); + // wire up the 6522s, tape and machine _userPortVIA->set_delegate(this); _keyboardVIA->set_delegate(this); _tape.set_delegate(this); + // establish the memory maps memset(_videoMemoryMap, 0, sizeof(_videoMemoryMap)); memset(_processorReadMemoryMap, 0, sizeof(_processorReadMemoryMap)); memset(_processorWriteMemoryMap, 0, sizeof(_processorWriteMemoryMap)); @@ -317,32 +326,7 @@ void Tape::process_input_pulse(Storage::Tape::Pulse pulse) #pragma mark - Serial Port -void SerialPort::set_clock_output(bool value) +void SerialPort::set_input(::Commodore::Serial::Line line, bool value) { - printf("Serial port clock output %s\n", value ? "on" : "off"); -} - -void SerialPort::set_data_output(bool value) -{ - printf("Serial port data output %s\n", value ? "on" : "off"); -} - -void SerialPort::set_attention_output(bool value) -{ - printf("Serial port attention output %s\n", value ? "on" : "off"); -} - -void SerialPort::set_clock_input(bool value) -{ - printf("Serial port clock input %s\n", value ? "on" : "off"); -} - -void SerialPort::set_data_input(bool value) -{ - printf("Serial port data input %s\n", value ? "on" : "off"); -} - -void SerialPort::set_attention_input(bool value) -{ - printf("Serial port attention input %s\n", value ? "on" : "off"); + printf("Serial port line %d: %s\n", line, value ? "on" : "off"); } diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index af1453120..ea91d4516 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -13,6 +13,7 @@ #include "../../../Storage/Tape/Tape.hpp" #include "../../../Components/6560/6560.hpp" #include "../../../Components/6522/6522.hpp" +#include "../SerialBus.hpp" #include "../../CRTMachine.hpp" #include "../../Typer.hpp" @@ -26,7 +27,6 @@ enum ROMSlot { ROMSlotCharacters, }; - #define key(line, mask) (((mask) << 3) | (line)) enum Key: uint16_t { @@ -61,15 +61,9 @@ enum JoystickInput { class UserPortVIA; class KeyboardVIA; -class SerialPort { +class SerialPort : public ::Commodore::Serial::Port { public: - void set_clock_output(bool value); - void set_data_output(bool value); - void set_attention_output(bool value); - - void set_clock_input(bool value); - void set_data_input(bool value); - void set_attention_input(bool value); + void set_input(::Commodore::Serial::Line line, bool value); void set_vias(std::shared_ptr userPortVIA, std::shared_ptr keyboardVIA) { _userPortVIA = userPortVIA; @@ -106,7 +100,7 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg void set_port_output(Port port, uint8_t value, uint8_t mask) { if(!port) { std::shared_ptr serialPort = _serialPort.lock(); - if(serialPort) serialPort->set_attention_output(!(value&0x80)); + if(serialPort) serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80)); } } @@ -165,9 +159,9 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg std::shared_ptr serialPort = _serialPort.lock(); if(serialPort) { if(port == Port::A) { - serialPort->set_clock_output(value); + serialPort->set_output(::Commodore::Serial::Line::Clock, value); } else { - serialPort->set_data_output(value); + serialPort->set_output(::Commodore::Serial::Line::Data, value); } } } @@ -287,6 +281,7 @@ class Machine: std::shared_ptr _userPortVIA; std::shared_ptr _keyboardVIA; std::shared_ptr _serialPort; + std::shared_ptr<::Commodore::Serial::Bus> _serialBus; // Tape Tape _tape; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index a0a688053..007ef4c80 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; }; + 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */; }; 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; }; 4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE5C1C3B7D6F0093A61B /* CSOpenGLView.m */; }; @@ -389,6 +390,8 @@ 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = ""; }; 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = ""; }; 4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Commodore1540.hpp; sourceTree = ""; }; + 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = ""; }; + 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = ""; }; 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600Document.swift; sourceTree = ""; }; 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ElectronDocument.swift; sourceTree = ""; }; 4B55CE5B1C3B7D6F0093A61B /* CSOpenGLView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CSOpenGLView.h; sourceTree = ""; }; @@ -867,6 +870,8 @@ children = ( 4B4DC8251D2C2470003C5BF8 /* 1540 */, 4B4DC81E1D2C2425003C5BF8 /* Vic-20 */, + 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */, + 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */, ); path = Commodore; sourceTree = ""; @@ -1801,6 +1806,7 @@ 4BBF99151C8FBA6F0075DAFB /* CRTOpenGL.cpp in Sources */, 4B0CCC451C62D0B3001CAC5F /* CRT.cpp in Sources */, 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */, + 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */, 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */, 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */, 4BBB14311CD2CECE00BDB55C /* IntermediateShader.cpp in Sources */, From a25fcc71905a3821d5520c17fd8dda278583cac1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 16:10:54 -0400 Subject: [PATCH 03/42] Made a first attempt at wiring back serial port input. --- Machines/Commodore/Vic-20/Vic20.cpp | 9 +----- Machines/Commodore/Vic-20/Vic20.hpp | 50 +++++++++++++++++------------ 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index af4f4db76..a4d8e7523 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -28,7 +28,7 @@ Machine::Machine() : // wire up 6522s and serial port _userPortVIA->set_serial_port(_serialPort); _keyboardVIA->set_serial_port(_serialPort); - _serialPort->set_vias(_userPortVIA, _keyboardVIA); + _serialPort->set_user_port_via(_userPortVIA); // wire up the 6522s, tape and machine _userPortVIA->set_delegate(this); @@ -323,10 +323,3 @@ void Tape::process_input_pulse(Storage::Tape::Pulse pulse) if(_delegate) _delegate->tape_did_change_input(this); } } - -#pragma mark - Serial Port - -void SerialPort::set_input(::Commodore::Serial::Line line, bool value) -{ - printf("Serial port line %d: %s\n", line, value ? "on" : "off"); -} diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index ea91d4516..1791b4034 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -61,20 +61,6 @@ enum JoystickInput { class UserPortVIA; class KeyboardVIA; -class SerialPort : public ::Commodore::Serial::Port { - public: - void set_input(::Commodore::Serial::Line line, bool value); - - void set_vias(std::shared_ptr userPortVIA, std::shared_ptr keyboardVIA) { - _userPortVIA = userPortVIA; - _keyboardVIA = keyboardVIA; - } - - private: - std::weak_ptr _userPortVIA; - std::weak_ptr _keyboardVIA; -}; - class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: uint8_t get_port_input(Port port) { @@ -90,6 +76,15 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg // } } + void set_serial_line_state(::Commodore::Serial::Line line, bool value) { + printf("Serial port line %d: %s\n", line, value ? "on" : "off"); + switch(line) { + default: break; + case ::Commodore::Serial::Line::Data: _portA = (_portA & ~0x02) | (value ? 0 : 0x02); break; + case ::Commodore::Serial::Line::Clock: _portA = (_portA & ~0x01) | (value ? 0 : 0x01); break; + } + } + void set_joystick_state(JoystickInput input, bool value) { if(input != JoystickInput::Right) { @@ -99,7 +94,7 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg void set_port_output(Port port, uint8_t value, uint8_t mask) { if(!port) { - std::shared_ptr serialPort = _serialPort.lock(); + std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80)); } } @@ -108,13 +103,13 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg UserPortVIA() : _portA(0xbf) {} - void set_serial_port(std::shared_ptr serialPort) { + void set_serial_port(std::shared_ptr<::Commodore::Serial::Port> serialPort) { _serialPort = serialPort; } private: uint8_t _portA; - std::weak_ptr _serialPort; + std::weak_ptr<::Commodore::Serial::Port> _serialPort; }; class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { @@ -156,7 +151,7 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg void set_control_line_output(Port port, Line line, bool value) { if(line == Line::Two) { - std::shared_ptr serialPort = _serialPort.lock(); + std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { if(port == Port::A) { serialPort->set_output(::Commodore::Serial::Line::Clock, value); @@ -176,7 +171,7 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg using MOS6522IRQDelegate::set_interrupt_status; - void set_serial_port(std::shared_ptr serialPort) { + void set_serial_port(std::shared_ptr<::Commodore::Serial::Port> serialPort) { _serialPort = serialPort; } @@ -184,7 +179,22 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg uint8_t _portB; uint8_t _columns[8]; uint8_t _activation_mask; - std::weak_ptr _serialPort; + std::weak_ptr<::Commodore::Serial::Port> _serialPort; +}; + +class SerialPort : public ::Commodore::Serial::Port { + public: + void set_input(::Commodore::Serial::Line line, bool value) { + std::shared_ptr userPortVIA = _userPortVIA.lock(); + if(userPortVIA) userPortVIA->set_serial_line_state(line, value); + } + + void set_user_port_via(std::shared_ptr userPortVIA) { + _userPortVIA = userPortVIA; + } + + private: + std::weak_ptr _userPortVIA; }; class Tape: public Storage::TapePlayer { From 86dabd007bc90d8db1dd575abdcce7f5f56ce2c5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 16:39:18 -0400 Subject: [PATCH 04/42] Furthered fleshing out of the 1540. Though it doesn't yet receive a ROM so won't even attempt to do anything meaningful. --- Machines/Commodore/1540/Commodore1540.cpp | 26 +++++++++++++++++++ Machines/Commodore/1540/Commodore1540.hpp | 22 +++++++++++++++- Machines/Commodore/Vic-20/Vic20.cpp | 19 +++++++++++--- Machines/Commodore/Vic-20/Vic20.hpp | 12 ++++++--- .../Clock Signal/Machine/Wrappers/CSVic20.h | 1 + .../Clock Signal/Machine/Wrappers/CSVic20.mm | 10 ++++--- ROMImages/Commodore1540/readme.txt | 5 ++++ 7 files changed, 85 insertions(+), 10 deletions(-) create mode 100644 ROMImages/Commodore1540/readme.txt diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index bec2a9567..5fe054b7a 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -7,3 +7,29 @@ // #include "Commodore1540.hpp" +#include + +using namespace Commodore::C1540; + +unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) +{ + if(address < 0x800) + { + if(isReadOperation(operation)) + *value = _ram[address]; + else + _ram[address] = *value; + } + else if(address >= 0xc000) + { + if(isReadOperation(operation)) + *value = _rom[address & 0x3fff]; + } + + return 1; +} + +void Machine::set_rom(uint8_t *rom) +{ + memcpy(_rom, rom, sizeof(_rom)); +} diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index f661b740a..e0d28d248 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -9,6 +9,26 @@ #ifndef Commodore1540_hpp #define Commodore1540_hpp -#include +#include "../../../Processors/6502/CPU6502.hpp" +#include "../../../Components/6522/6522.hpp" + +namespace Commodore { +namespace C1540 { + +class Machine: + public CPU6502::Processor { + + public: + unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); + + void set_rom(uint8_t *rom); + + private: + uint8_t _ram[0x800]; + uint8_t _rom[0x4000]; +}; + +} +} #endif /* Commodore1540_hpp */ diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index a4d8e7523..ab9c61a20 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -54,6 +54,9 @@ Machine::Machine() : write_to_map(_processorWriteMemoryMap, _userBASICMemory, 0x0000, sizeof(_userBASICMemory)); write_to_map(_processorWriteMemoryMap, _screenMemory, 0x1000, sizeof(_screenMemory)); write_to_map(_processorWriteMemoryMap, _colorMemory, 0x9400, sizeof(_colorMemory)); + + // TEMPORARY: attach a [diskless] 1540 + set_disc(); } void Machine::write_to_map(uint8_t **map, uint8_t *area, uint16_t address, uint16_t length) @@ -121,6 +124,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin _keyboardVIA->run_for_half_cycles(2); if(_typer) _typer->update(1); _tape.run_for_cycles(1); + if(_c1540) _c1540->run_for_cycles(1); return 1; } @@ -150,9 +154,11 @@ void Machine::set_rom(ROMSlot slot, size_t length, const uint8_t *data) size_t max_length = 0x2000; switch(slot) { - case ROMSlotKernel: target = _kernelROM; break; - case ROMSlotCharacters: target = _characterROM; max_length = 0x1000; break; - case ROMSlotBASIC: target = _basicROM; break; + case Kernel: target = _kernelROM; break; + case Characters: target = _characterROM; max_length = 0x1000; break; + case BASIC: target = _basicROM; break; + case Drive: + return; } if(target) @@ -323,3 +329,10 @@ void Tape::process_input_pulse(Storage::Tape::Pulse pulse) if(_delegate) _delegate->tape_did_change_input(this); } } + +#pragma mark - Disc + +void Machine::set_disc() +{ + _c1540.reset(new ::Commodore::C1540::Machine); +} diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 1791b4034..9f625531e 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -13,6 +13,7 @@ #include "../../../Storage/Tape/Tape.hpp" #include "../../../Components/6560/6560.hpp" #include "../../../Components/6522/6522.hpp" +#include "../1540/Commodore1540.hpp" #include "../SerialBus.hpp" #include "../../CRTMachine.hpp" @@ -22,9 +23,10 @@ namespace Commodore { namespace Vic20 { enum ROMSlot { - ROMSlotKernel, - ROMSlotBASIC, - ROMSlotCharacters, + Kernel, + BASIC, + Characters, + Drive }; #define key(line, mask) (((mask) << 3) | (line)) @@ -235,6 +237,7 @@ class Machine: void set_rom(ROMSlot slot, size_t length, const uint8_t *data); void add_prg(size_t length, const uint8_t *data); void set_tape(std::shared_ptr tape); + void set_disc(); void set_key_state(Key key, bool isPressed) { _keyboardVIA->set_key_state(key, isPressed); } void clear_all_keys() { _keyboardVIA->clear_all_keys(); } @@ -296,6 +299,9 @@ class Machine: // Tape Tape _tape; bool _use_fast_tape_hack; + + // Disc + std::shared_ptr<::Commodore::C1540::Machine> _c1540; }; } diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h index ef04a1f78..83f3c7863 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.h @@ -15,6 +15,7 @@ - (void)setKernelROM:(nonnull NSData *)rom; - (void)setBASICROM:(nonnull NSData *)rom; - (void)setCharactersROM:(nonnull NSData *)rom; +- (void)setDriveROM:(nonnull NSData *)rom; - (void)setPRG:(nonnull NSData *)prg; - (BOOL)openTAPAtURL:(nonnull NSURL *)URL; diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm index 3e576ca20..6407fcd9e 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm @@ -29,15 +29,19 @@ using namespace Commodore::Vic20; } - (void)setKernelROM:(nonnull NSData *)rom { - [self setROM:rom slot:ROMSlotKernel]; + [self setROM:rom slot:Kernel]; } - (void)setBASICROM:(nonnull NSData *)rom { - [self setROM:rom slot:ROMSlotBASIC]; + [self setROM:rom slot:BASIC]; } - (void)setCharactersROM:(nonnull NSData *)rom { - [self setROM:rom slot:ROMSlotCharacters]; + [self setROM:rom slot:Characters]; +} + +- (void)setDriveROM:(nonnull NSData *)rom { + [self setROM:rom slot:Drive]; } - (BOOL)openTAPAtURL:(NSURL *)URL { diff --git a/ROMImages/Commodore1540/readme.txt b/ROMImages/Commodore1540/readme.txt new file mode 100644 index 000000000..f5ba5b233 --- /dev/null +++ b/ROMImages/Commodore1540/readme.txt @@ -0,0 +1,5 @@ +ROM files would ordinarily go here; the copyright status of these is uncertain so they have not been included in this repository. + +Expected files: + +1540.rom; a 16kb image of the 1540's ROM area. From 47548dcedce7c73a40bfdae05b3c41adb93fed3f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 16:39:31 -0400 Subject: [PATCH 05/42] Fixed an erroneous #import. --- OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm index 39bb10e8a..ceb1c2a15 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSAtari2600.mm @@ -8,7 +8,7 @@ #import "CSAtari2600.h" -#import "Atari2600.hpp" +#include "Atari2600.hpp" #import "CSMachine+Subclassing.h" @interface CSAtari2600 () From d1eea6943d61f5a5b6e28a0fa6f13be30fe9922e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 16:54:25 -0400 Subject: [PATCH 06/42] Ensured the 1540 ROM gets installed, at least. --- Machines/Commodore/1540/Commodore1540.cpp | 2 +- Machines/Commodore/1540/Commodore1540.hpp | 2 +- Machines/Commodore/Vic-20/Vic20.cpp | 1 + OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift | 4 ++++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 5fe054b7a..f53fa0527 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -29,7 +29,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin return 1; } -void Machine::set_rom(uint8_t *rom) +void Machine::set_rom(const uint8_t *rom) { memcpy(_rom, rom, sizeof(_rom)); } diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index e0d28d248..1e5608986 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -21,7 +21,7 @@ class Machine: public: unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); - void set_rom(uint8_t *rom); + void set_rom(const uint8_t *rom); private: uint8_t _ram[0x800]; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index ab9c61a20..ba463e594 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -158,6 +158,7 @@ void Machine::set_rom(ROMSlot slot, size_t length, const uint8_t *data) case Characters: target = _characterROM; max_length = 0x1000; break; case BASIC: target = _basicROM; break; case Drive: + if(_c1540) _c1540->set_rom(data); return; } diff --git a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift b/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift index f4b647b09..bbf5ddaee 100644 --- a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift +++ b/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift @@ -31,6 +31,10 @@ class Vic20Document: MachineDocument { vic20.setBASICROM(basic) vic20.setCharactersROM(characters) } + + if let drive = dataForResource("1540", ofType: "bin", inDirectory: "ROMImages/Commodore1540") { + vic20.setDriveROM(drive) + } } override class func autosavesInPlace() -> Bool { From d16b79073e98b145ac2f62cb86483069222050f1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 17:27:02 -0400 Subject: [PATCH 07/42] Further fleshing out: added a serial port for the serial bus. --- Machines/Commodore/1540/Commodore1540.cpp | 22 +++++++++++++++++++++ Machines/Commodore/1540/Commodore1540.hpp | 24 +++++++++++++++++++++++ Machines/Commodore/Vic-20/Vic20.cpp | 4 ++++ Machines/Commodore/Vic-20/Vic20.hpp | 3 --- 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index f53fa0527..14ed86671 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -11,6 +11,19 @@ using namespace Commodore::C1540; +Machine::Machine() +{ + _serialPortVIA.reset(new SerialPortVIA); + _serialPort.reset(new SerialPort); + _serialPort->set_serial_port_via(_serialPortVIA); +} + +void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) +{ + _serialPort->set_serial_bus(serial_bus); + serial_bus->add_port(_serialPort); +} + unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { if(address < 0x800) @@ -25,6 +38,15 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin if(isReadOperation(operation)) *value = _rom[address & 0x3fff]; } + else if(address >= 0x1800 && address <= 0x180f) + { + if(isReadOperation(operation)) + *value = _serialPortVIA->get_register(address); + else + _serialPortVIA->set_register(address, *value); + } + + _serialPortVIA->run_for_half_cycles(2); return 1; } diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 1e5608986..2975edd3e 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -11,21 +11,45 @@ #include "../../../Processors/6502/CPU6502.hpp" #include "../../../Components/6522/6522.hpp" +#include "../SerialBus.hpp" namespace Commodore { namespace C1540 { +class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { + public: + using MOS6522IRQDelegate::set_interrupt_status; +}; + +class SerialPort : public ::Commodore::Serial::Port { + public: + void set_input(::Commodore::Serial::Line line, bool value) { + } + + void set_serial_port_via(std::shared_ptr serialPortVIA) { + _serialPortVIA = serialPortVIA; + } + + private: + std::weak_ptr _serialPortVIA; +}; + class Machine: public CPU6502::Processor { public: + Machine(); unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); void set_rom(const uint8_t *rom); + void set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus); private: uint8_t _ram[0x800]; uint8_t _rom[0x4000]; + + std::shared_ptr _serialPortVIA; + std::shared_ptr _serialPort; }; } diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index ba463e594..fb616ec80 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -335,5 +335,9 @@ void Tape::process_input_pulse(Storage::Tape::Pulse pulse) void Machine::set_disc() { + // construct the 1540 _c1540.reset(new ::Commodore::C1540::Machine); + + // attach it to the serial bus + _c1540->set_serial_bus(_serialBus); } diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 9f625531e..386001b61 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -60,9 +60,6 @@ enum JoystickInput { Fire = 0x20 }; -class UserPortVIA; -class KeyboardVIA; - class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: uint8_t get_port_input(Port port) { From 11fc43aa04f2ed5941cce7b99435d968a968480a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 19:12:43 -0400 Subject: [PATCH 08/42] Made an attempt to allow the 1540 to talk back to the Vic, and to receive interrupts. Also slightly disambiguated debugging logging. --- Machines/Commodore/1540/Commodore1540.cpp | 9 ++++ Machines/Commodore/1540/Commodore1540.hpp | 50 ++++++++++++++++++++++- Machines/Commodore/Vic-20/Vic20.hpp | 2 +- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 14ed86671..44379a9d3 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -15,7 +15,9 @@ Machine::Machine() { _serialPortVIA.reset(new SerialPortVIA); _serialPort.reset(new SerialPort); + _serialPort->set_serial_port_via(_serialPortVIA); + _serialPortVIA->set_serial_port(_serialPort); } void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) @@ -55,3 +57,10 @@ void Machine::set_rom(const uint8_t *rom) { memcpy(_rom, rom, sizeof(_rom)); } + +#pragma mark - 6522 delegate + +void Machine::mos6522_did_change_interrupt_status(void *mos6522) +{ + set_irq_line(_serialPortVIA->get_interrupt_line()); +} diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 2975edd3e..f47cb3120 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -19,11 +19,55 @@ namespace C1540 { class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: using MOS6522IRQDelegate::set_interrupt_status; + + SerialPortVIA() : _portB(0x1f) {} + + uint8_t get_port_input(Port port) { + if(port) { + return _portB; + } + + return 0xff; + } + + void set_port_output(Port port, uint8_t value, uint8_t mask) { + if(port) { + std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); + if(serialPort) { + serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); + serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08)); + serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02)); + } + printf("1540 serial port VIA port B: %02x\n", value); + } + else + printf("1540 serial port VIA port A: %02x\n", value); + } + + void set_serial_line_state(::Commodore::Serial::Line line, bool value) { + printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); + switch(line) { + default: break; + case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0 : 0x01); break; + case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; + case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); break; + } + } + + void set_serial_port(std::shared_ptr<::Commodore::Serial::Port> serialPort) { + _serialPort = serialPort; + } + + private: + uint8_t _portB; + std::weak_ptr<::Commodore::Serial::Port> _serialPort; }; class SerialPort : public ::Commodore::Serial::Port { public: void set_input(::Commodore::Serial::Line line, bool value) { + std::shared_ptr serialPortVIA = _serialPortVIA.lock(); + if(serialPortVIA) serialPortVIA->set_serial_line_state(line, value); } void set_serial_port_via(std::shared_ptr serialPortVIA) { @@ -35,7 +79,8 @@ class SerialPort : public ::Commodore::Serial::Port { }; class Machine: - public CPU6502::Processor { + public CPU6502::Processor, + public MOS::MOS6522IRQDelegate::Delegate { public: Machine(); @@ -44,6 +89,9 @@ class Machine: void set_rom(const uint8_t *rom); void set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus); + // to satisfy MOS::MOS6522::Delegate + virtual void mos6522_did_change_interrupt_status(void *mos6522); + private: uint8_t _ram[0x800]; uint8_t _rom[0x4000]; diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 386001b61..ca2b55d53 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -76,7 +76,7 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg } void set_serial_line_state(::Commodore::Serial::Line line, bool value) { - printf("Serial port line %d: %s\n", line, value ? "on" : "off"); + printf("VIC Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; case ::Commodore::Serial::Line::Data: _portA = (_portA & ~0x02) | (value ? 0 : 0x02); break; From c3b7d24293b12b4b7e61173567016099233a4b8d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 19:19:46 -0400 Subject: [PATCH 09/42] It appears that the attention line is also wired to CB2. So the ball is back in the 6522's court. --- Components/6522/6522.hpp | 2 +- Machines/Commodore/1540/Commodore1540.hpp | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 34bb53f74..a71b16255 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -112,7 +112,7 @@ template class MOS6522 { _registers.auxiliary_control = value; break; case 0xc: -// printf("Peripheral control %02x\n", value); + printf("Peripheral control %02x\n", value); _registers.peripheral_control = value; switch(value & 0x0e) { diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index f47cb3120..0d1e7d52a 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -50,7 +50,10 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD default: break; case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0 : 0x01); break; case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; - case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); break; + case ::Commodore::Serial::Line::Attention: + _portB = (_portB & ~0x80) | (value ? 0 : 0x80); + set_control_line_input(Port::B, Line::Two, !!(value&0x80)); + break; } } From 1bb109a23b84a9e8c4e06b64f1889db0f834cf63 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 20:39:15 -0400 Subject: [PATCH 10/42] Made a quick attempt at basic C[A/B]2 interrupts. --- Components/6522/6522.hpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index a71b16255..887b3f709 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -112,7 +112,7 @@ template class MOS6522 { _registers.auxiliary_control = value; break; case 0xc: - printf("Peripheral control %02x\n", value); +// printf("Peripheral control %02x\n", value); _registers.peripheral_control = value; switch(value & 0x0e) { @@ -207,7 +207,16 @@ template class MOS6522 { break; case Line::Two: - // TODO + // TODO: independence (?) + if( value != _control_inputs[port].line_two && // i.e. value has changed ... + !(_registers.peripheral_control & (port ? 0x80 : 0x08)) && // ... and line is input ... + value == !!(_registers.peripheral_control & (port ? 0x40 : 0x04)) // ... and it's either high or low, as required + ) + { + _registers.interrupt_flags |= port ? InterruptFlag::CB2ActiveEdge : InterruptFlag::CA2ActiveEdge; + reevaluate_interrupts(); + } + _control_inputs[port].line_two = value; break; } } From 1e6d90de17a625a1191073b4e2f2a68c59ddf30d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 20:52:33 -0400 Subject: [PATCH 11/42] Made an attempt properly to deal with initial bus state. --- Machines/Commodore/1540/Commodore1540.hpp | 2 +- Machines/Commodore/SerialBus.cpp | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 0d1e7d52a..378ecb35c 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -52,7 +52,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); - set_control_line_input(Port::B, Line::Two, !!(value&0x80)); + set_control_line_input(Port::B, Line::Two, value); break; } } diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index 7d7ca7a09..c4e3a3f2c 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -13,10 +13,13 @@ using namespace Commodore::Serial; void Bus::add_port(std::shared_ptr port) { _ports.push_back(port); + for(int line = (int)ServiceRequest; line <= (int)Reset; line++) + set_line_output_did_change((Line)line); } void Bus::set_line_output_did_change(Line line) { + // i.e. I believe these lines to be open collector, active low bool new_line_value = false; for(std::weak_ptr port : _ports) { @@ -27,6 +30,7 @@ void Bus::set_line_output_did_change(Line line) } } + // post an update only if one occurred if(new_line_value != _line_values[line]) { _line_values[line] = new_line_value; From 6c4fa4ec5d047e85c3198cf38007ac9c192e2f39 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 20:57:31 -0400 Subject: [PATCH 12/42] Improved commenting and initial state communication. --- Machines/Commodore/1540/Commodore1540.hpp | 2 +- Machines/Commodore/SerialBus.cpp | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 378ecb35c..7e57eb2ff 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -52,7 +52,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); - set_control_line_input(Port::B, Line::Two, value); + set_control_line_input(Port::B, Line::Two, !value); // from active low to active high break; } } diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index c4e3a3f2c..be76aaef5 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -14,7 +14,13 @@ void Bus::add_port(std::shared_ptr port) { _ports.push_back(port); for(int line = (int)ServiceRequest; line <= (int)Reset; line++) + { + // the addition of a new device may change the line output... set_line_output_did_change((Line)line); + + // ... but the new device will need to be told the current state regardless + port->set_input((Line)line, _line_values[line]); + } } void Bus::set_line_output_did_change(Line line) From 93c2bb80a2412ae16fb2d64a930a1884ed151fe9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 21:11:51 -0400 Subject: [PATCH 13/42] Improved a comment, added independent C[A/B]2 input mode. --- Components/6522/6522.hpp | 6 +++--- Machines/Commodore/1540/Commodore1540.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 887b3f709..730e21a96 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -59,7 +59,7 @@ template class MOS6522 { _registers.output[1] = value; static_cast(this)->set_port_output(Port::B, value, _registers.data_direction[1]); // TODO: handshake - _registers.interrupt_flags &= ~(InterruptFlag::CB1ActiveEdge | InterruptFlag::CB2ActiveEdge); + _registers.interrupt_flags &= ~(InterruptFlag::CB1ActiveEdge | ((_registers.peripheral_control&0x20) ? 0 : InterruptFlag::CB2ActiveEdge)); reevaluate_interrupts(); break; case 0xf: @@ -67,7 +67,7 @@ template class MOS6522 { _registers.output[0] = value; static_cast(this)->set_port_output(Port::A, value, _registers.data_direction[0]); // TODO: handshake - _registers.interrupt_flags &= ~(InterruptFlag::CA1ActiveEdge | InterruptFlag::CA2ActiveEdge); + _registers.interrupt_flags &= ~(InterruptFlag::CA1ActiveEdge | ((_registers.peripheral_control&0x02) ? 0 : InterruptFlag::CB2ActiveEdge)); reevaluate_interrupts(); break; // // No handshake, so write directly @@ -207,7 +207,7 @@ template class MOS6522 { break; case Line::Two: - // TODO: independence (?) + // TODO: output modes, but probably elsewhere? if( value != _control_inputs[port].line_two && // i.e. value has changed ... !(_registers.peripheral_control & (port ? 0x80 : 0x08)) && // ... and line is input ... value == !!(_registers.peripheral_control & (port ? 0x40 : 0x04)) // ... and it's either high or low, as required diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 7e57eb2ff..7ef1d1734 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -52,7 +52,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); - set_control_line_input(Port::B, Line::Two, !value); // from active low to active high + set_control_line_input(Port::B, Line::Two, !value); // truth here is active low; the 6522 takes true to be high break; } } From 602e7f01c7281cc257460da4afd35df3c93d01f5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 21:15:29 -0400 Subject: [PATCH 14/42] Control lines seem to have evolved to pure push. --- Components/6522/6522.hpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 730e21a96..4353c6a6b 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -114,17 +114,25 @@ template class MOS6522 { case 0xc: // printf("Peripheral control %02x\n", value); _registers.peripheral_control = value; - switch(value & 0x0e) + + // TODO: simplify below; tryig to avoid improper logging of unimplemented warnings in input mode + if(value & 0x08) { - default: printf("Unimplemented control line mode %d\n", (value >> 1)&7); break; - case 0x0c: static_cast(this)->set_control_line_output(Port::A, Line::Two, false); break; - case 0x0e: static_cast(this)->set_control_line_output(Port::A, Line::Two, true); break; + switch(value & 0x0e) + { + default: printf("Unimplemented control line mode %d\n", (value >> 1)&7); break; + case 0x0c: static_cast(this)->set_control_line_output(Port::A, Line::Two, false); break; + case 0x0e: static_cast(this)->set_control_line_output(Port::A, Line::Two, true); break; + } } - switch(value & 0xe0) + if(value & 0x80) { - default: printf("Unimplemented control line mode %d\n", (value >> 5)&7); break; - case 0xc0: static_cast(this)->set_control_line_output(Port::B, Line::Two, false); break; - case 0xe0: static_cast(this)->set_control_line_output(Port::B, Line::Two, true); break; + switch(value & 0xe0) + { + default: printf("Unimplemented control line mode %d\n", (value >> 5)&7); break; + case 0xc0: static_cast(this)->set_control_line_output(Port::B, Line::Two, false); break; + case 0xe0: static_cast(this)->set_control_line_output(Port::B, Line::Two, true); break; + } } break; @@ -293,9 +301,8 @@ template class MOS6522 { // Expected to be overridden uint8_t get_port_input(Port port) { return 0xff; } void set_port_output(Port port, uint8_t value, uint8_t direction_mask) {} - bool get_control_line(Port port, Line line) { return true; } void set_control_line_output(Port port, Line line, bool value) {} - void set_interrupt_status(bool status) {} + void set_interrupt_status(bool status) {} // Input/output multiplexer uint8_t get_port_input(Port port, uint8_t output_mask, uint8_t output) From 8819711bc8056d2cf7f14f0a24dcb4e3a378466b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Tue, 5 Jul 2016 22:22:09 -0400 Subject: [PATCH 15/42] Threw in the second VIA as a currently clearly incorrect thing. --- Components/6522/6522.hpp | 2 +- Machines/Commodore/1540/Commodore1540.cpp | 10 ++++++++++ Machines/Commodore/1540/Commodore1540.hpp | 6 ++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 4353c6a6b..e35f6c039 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -1,4 +1,4 @@ -// + // // 6522.hpp // Clock Signal // diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 44379a9d3..9ad308ff6 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -18,6 +18,8 @@ Machine::Machine() _serialPort->set_serial_port_via(_serialPortVIA); _serialPortVIA->set_serial_port(_serialPort); + _serialPortVIA->set_delegate(this); + _driveVIA.set_delegate(this); } void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) @@ -47,8 +49,16 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin else _serialPortVIA->set_register(address, *value); } + else if(address >= 0x1c00 && address <= 0x1c0f) + { + if(isReadOperation(operation)) + *value = _driveVIA.get_register(address); + else + _driveVIA.set_register(address, *value); + } _serialPortVIA->run_for_half_cycles(2); + _driveVIA.run_for_half_cycles(2); return 1; } diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 7ef1d1734..69ee5a44e 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -66,6 +66,11 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD std::weak_ptr<::Commodore::Serial::Port> _serialPort; }; +class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { + public: + using MOS6522IRQDelegate::set_interrupt_status; +}; + class SerialPort : public ::Commodore::Serial::Port { public: void set_input(::Commodore::Serial::Line line, bool value) { @@ -101,6 +106,7 @@ class Machine: std::shared_ptr _serialPortVIA; std::shared_ptr _serialPort; + DriveVIA _driveVIA; }; } From 428fcdb978493abc5780ffc12cfec4d13c638f11 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Jul 2016 07:46:21 -0400 Subject: [PATCH 16/42] Centralised and improved serial logging. --- Machines/Commodore/1540/Commodore1540.hpp | 8 ++++---- Machines/Commodore/SerialBus.cpp | 13 +++++++++++++ Machines/Commodore/SerialBus.hpp | 2 ++ Machines/Commodore/Vic-20/Vic20.hpp | 2 +- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 69ee5a44e..2eae8b37d 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -38,14 +38,14 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08)); serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02)); } - printf("1540 serial port VIA port B: %02x\n", value); +// printf("1540 serial port VIA port B: %02x\n", value); } - else - printf("1540 serial port VIA port A: %02x\n", value); +// else +// printf("1540 serial port VIA port A: %02x\n", value); } void set_serial_line_state(::Commodore::Serial::Line line, bool value) { - printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); +// printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0 : 0x01); break; diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index be76aaef5..3692fbfda 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -10,6 +10,18 @@ using namespace Commodore::Serial; +const char *::Commodore::Serial::StringForLine(Line line) +{ + switch(line) + { + case ServiceRequest: return "Service request"; + case Attention: return "Attention"; + case Clock: return "Clock"; + case Data: return "Data"; + case Reset: return "Reset"; + } +} + void Bus::add_port(std::shared_ptr port) { _ports.push_back(port); @@ -39,6 +51,7 @@ void Bus::set_line_output_did_change(Line line) // post an update only if one occurred if(new_line_value != _line_values[line]) { + printf("[Bus] %s is %s\n", StringForLine(line), new_line_value ? "true" : "false"); _line_values[line] = new_line_value; for(std::weak_ptr port : _ports) diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 9f1034c7a..44aa908a3 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -22,6 +22,8 @@ namespace Serial { Reset }; + const char *StringForLine(Line line); + class Port; class Bus { diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index ca2b55d53..6d940a34d 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -76,7 +76,7 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg } void set_serial_line_state(::Commodore::Serial::Line line, bool value) { - printf("VIC Serial port line %d: %s\n", line, value ? "on" : "off"); +// printf("VIC Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; case ::Commodore::Serial::Line::Data: _portA = (_portA & ~0x02) | (value ? 0 : 0x02); break; From f64cd8cfcb911b6c42cb7e10c42d71f3ef12b619 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Jul 2016 20:22:46 -0400 Subject: [PATCH 17/42] Quick fixes properly to declare the DriveVIA, to ensure its interrupts take effect, and to wire ATN IN to CA1 rather than CB2. --- Machines/Commodore/1540/Commodore1540.cpp | 2 +- Machines/Commodore/1540/Commodore1540.hpp | 4 ++-- Machines/Commodore/Vic-20/Vic20.cpp | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 9ad308ff6..eaaadf37b 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -72,5 +72,5 @@ void Machine::set_rom(const uint8_t *rom) void Machine::mos6522_did_change_interrupt_status(void *mos6522) { - set_irq_line(_serialPortVIA->get_interrupt_line()); + set_irq_line(_serialPortVIA->get_interrupt_line() || _driveVIA.get_interrupt_line()); } diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 2eae8b37d..dae51c38f 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -52,7 +52,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); - set_control_line_input(Port::B, Line::Two, !value); // truth here is active low; the 6522 takes true to be high + set_control_line_input(Port::A, Line::One, !value); // truth here is active low; the 6522 takes true to be high break; } } @@ -66,7 +66,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD std::weak_ptr<::Commodore::Serial::Port> _serialPort; }; -class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { +class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: using MOS6522IRQDelegate::set_interrupt_status; }; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index fb616ec80..60b8838ca 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -71,7 +71,6 @@ void Machine::write_to_map(uint8_t **map, uint8_t *area, uint16_t address, uint1 } } - Machine::~Machine() { delete[] _rom; From 4f174786b51098ba8d684e98139f911e954054e5 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Jul 2016 21:39:09 -0400 Subject: [PATCH 18/42] Fixed potential buffer overrun. --- Machines/Typer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Machines/Typer.cpp b/Machines/Typer.cpp index a580d9747..e22c67f21 100644 --- a/Machines/Typer.cpp +++ b/Machines/Typer.cpp @@ -24,7 +24,7 @@ void Typer::update(int duration) } _counter += duration; - while(_counter > _frequency) + while(_string && _counter > _frequency) { _counter -= _frequency; type_next_character(); From 1baf21827c21777b3919d7de9bb47314584dcf85 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Jul 2016 22:17:32 -0400 Subject: [PATCH 19/42] Since the ROM is well disassembled, let's actually try to be a 1541 first. --- Components/6522/6522.hpp | 3 ++- Machines/Commodore/1540/Commodore1540.cpp | 1 + Machines/Commodore/1540/Commodore1540.hpp | 10 +++++++--- Machines/Commodore/Vic-20/Vic20.cpp | 8 ++++++-- .../Mac/Clock Signal/Documents/Vic20Document.swift | 2 +- Processors/6502/CPU6502.hpp | 1 + 6 files changed, 18 insertions(+), 7 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index e35f6c039..dd5cb5526 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -10,6 +10,7 @@ #define _522_hpp #include +#include #include namespace MOS { @@ -52,7 +53,7 @@ template class MOS6522 { inline void set_register(int address, uint8_t value) { address &= 0xf; -// printf("6522 %p: %d <- %02x\n", this, address, value); +// printf("6522 [%s]: %0x <- %02x\n", typeid(*this).name(), address, value); switch(address) { case 0x0: diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index eaaadf37b..5fb1840f2 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -72,5 +72,6 @@ void Machine::set_rom(const uint8_t *rom) void Machine::mos6522_did_change_interrupt_status(void *mos6522) { + printf("?"); set_irq_line(_serialPortVIA->get_interrupt_line() || _driveVIA.get_interrupt_line()); } diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index dae51c38f..73659d738 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -20,7 +20,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD public: using MOS6522IRQDelegate::set_interrupt_status; - SerialPortVIA() : _portB(0x1f) {} + SerialPortVIA() : _portB(0x9f) {} uint8_t get_port_input(Port port) { if(port) { @@ -48,8 +48,8 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD // printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; - case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0 : 0x01); break; - case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0 : 0x04); break; + case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break; + case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); set_control_line_input(Port::A, Line::One, !value); // truth here is active low; the 6522 takes true to be high @@ -69,6 +69,10 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: using MOS6522IRQDelegate::set_interrupt_status; + + uint8_t get_port_input(Port port) { + return 0xff; + } }; class SerialPort : public ::Commodore::Serial::Port { diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 60b8838ca..ae251f6d1 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -96,7 +96,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin *value = result; // test for PC at F92F - if(_use_fast_tape_hack && address == 0xf92f && operation == CPU6502::BusOperation::ReadOpcode) + if(_use_fast_tape_hack && _tape.has_tape() && address == 0xf92f && operation == CPU6502::BusOperation::ReadOpcode) { // advance time on the tape and the VIAs until an interrupt is signalled while(!_userPortVIA->get_interrupt_line() && !_keyboardVIA->get_interrupt_line()) @@ -157,7 +157,11 @@ void Machine::set_rom(ROMSlot slot, size_t length, const uint8_t *data) case Characters: target = _characterROM; max_length = 0x1000; break; case BASIC: target = _basicROM; break; case Drive: - if(_c1540) _c1540->set_rom(data); + if(_c1540) + { + _c1540->set_rom(data); + _c1540->run_for_cycles(2000000); // pretend it booted a couple of seconds ago + } return; } diff --git a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift b/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift index bbf5ddaee..e74f67274 100644 --- a/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift +++ b/OSBindings/Mac/Clock Signal/Documents/Vic20Document.swift @@ -32,7 +32,7 @@ class Vic20Document: MachineDocument { vic20.setCharactersROM(characters) } - if let drive = dataForResource("1540", ofType: "bin", inDirectory: "ROMImages/Commodore1540") { + if let drive = dataForResource("1541", ofType: "bin", inDirectory: "ROMImages/Commodore1540") { vic20.setDriveROM(drive) } } diff --git a/Processors/6502/CPU6502.hpp b/Processors/6502/CPU6502.hpp index 3c4a608ef..4b0434eb8 100644 --- a/Processors/6502/CPU6502.hpp +++ b/Processors/6502/CPU6502.hpp @@ -666,6 +666,7 @@ template class Processor { break; case OperationDecodeOperation: +// printf("d %02x\n", _operation); decode_operation(_operation); break; From dcb86a027a9392f6a658c3235754fb45e517130b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Wed, 6 Jul 2016 22:31:14 -0400 Subject: [PATCH 20/42] Okay, so the 1540 doesn't toggle the actual attention line. I don't know what it does yet but this helps. --- Machines/Commodore/1540/Commodore1540.cpp | 1 - Machines/Commodore/1540/Commodore1540.hpp | 4 ++-- Machines/Commodore/Vic-20/Vic20.hpp | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 5fb1840f2..eaaadf37b 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -72,6 +72,5 @@ void Machine::set_rom(const uint8_t *rom) void Machine::mos6522_did_change_interrupt_status(void *mos6522) { - printf("?"); set_irq_line(_serialPortVIA->get_interrupt_line() || _driveVIA.get_interrupt_line()); } diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 73659d738..3160ab996 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -34,7 +34,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD if(port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { - serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); +// serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08)); serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02)); } @@ -52,7 +52,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Attention: _portB = (_portB & ~0x80) | (value ? 0 : 0x80); - set_control_line_input(Port::A, Line::One, !value); // truth here is active low; the 6522 takes true to be high + set_control_line_input(Port::A, Line::One, !value); // truth here is active low; my 6522 takes true to be high break; } } diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 6d940a34d..dc214cadf 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -94,7 +94,8 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg void set_port_output(Port port, uint8_t value, uint8_t mask) { if(!port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); - if(serialPort) serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80)); + if(serialPort) + serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80)); } } From c9479f923ba6207b1b696ce72baae0a00f9a0a39 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 7 Jul 2016 06:44:13 -0400 Subject: [PATCH 21/42] The inversion of truth was clearly just a problematic API. Got explicit. LineLevel might need to become more pervasive. --- Machines/Commodore/1540/Commodore1540.hpp | 16 ++++++++-------- Machines/Commodore/SerialBus.cpp | 16 ++++++++-------- Machines/Commodore/SerialBus.hpp | 23 ++++++++++++++--------- Machines/Commodore/Vic-20/Vic20.hpp | 10 +++++----- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 3160ab996..732318a9b 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -35,8 +35,8 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { // serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); - serialPort->set_output(::Commodore::Serial::Line::Clock, !(value&0x08)); - serialPort->set_output(::Commodore::Serial::Line::Data, !(value&0x02)); + serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)(value&0x08)); + serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)(value&0x02)); } // printf("1540 serial port VIA port B: %02x\n", value); } @@ -48,11 +48,11 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD // printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; - case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break; - case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; + case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x01 : 0x00); break; + case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x04 : 0x00); break; case ::Commodore::Serial::Line::Attention: - _portB = (_portB & ~0x80) | (value ? 0 : 0x80); - set_control_line_input(Port::A, Line::One, !value); // truth here is active low; my 6522 takes true to be high + _portB = (_portB & ~0x80) | (value ? 0x80 : 0x00); + set_control_line_input(Port::A, Line::One, value); break; } } @@ -77,9 +77,9 @@ class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { class SerialPort : public ::Commodore::Serial::Port { public: - void set_input(::Commodore::Serial::Line line, bool value) { + void set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) { std::shared_ptr serialPortVIA = _serialPortVIA.lock(); - if(serialPortVIA) serialPortVIA->set_serial_line_state(line, value); + if(serialPortVIA) serialPortVIA->set_serial_line_state(line, (bool)level); } void set_serial_port_via(std::shared_ptr serialPortVIA) { diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index 3692fbfda..057a210f7 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -31,35 +31,35 @@ void Bus::add_port(std::shared_ptr port) set_line_output_did_change((Line)line); // ... but the new device will need to be told the current state regardless - port->set_input((Line)line, _line_values[line]); + port->set_input((Line)line, _line_levels[line]); } } void Bus::set_line_output_did_change(Line line) { - // i.e. I believe these lines to be open collector, active low - bool new_line_value = false; + // i.e. I believe these lines to be open collector + LineLevel new_line_level = High; for(std::weak_ptr port : _ports) { std::shared_ptr locked_port = port.lock(); if(locked_port) { - new_line_value |= locked_port->get_output(line); + new_line_level = (LineLevel)((bool)new_line_level & (bool)locked_port->get_output(line)); } } // post an update only if one occurred - if(new_line_value != _line_values[line]) + if(new_line_level != _line_levels[line]) { - printf("[Bus] %s is %s\n", StringForLine(line), new_line_value ? "true" : "false"); - _line_values[line] = new_line_value; + printf("[Bus] %s is %s\n", StringForLine(line), new_line_level ? "high" : "low"); + _line_levels[line] = new_line_level; for(std::weak_ptr port : _ports) { std::shared_ptr locked_port = port.lock(); if(locked_port) { - locked_port->set_input(line, new_line_value); + locked_port->set_input(line, new_line_level); } } } diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 44aa908a3..7973f98ae 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -22,37 +22,42 @@ namespace Serial { Reset }; + enum LineLevel: bool { + High = true, + Low = false + }; + const char *StringForLine(Line line); class Port; class Bus { public: - Bus() : _line_values{false, false, false, false, false} {} + Bus() : _line_levels{High, High, High, High, High} {} void add_port(std::shared_ptr port); void set_line_output_did_change(Line line); private: - bool _line_values[5]; + LineLevel _line_levels[5]; std::vector> _ports; }; class Port { public: - Port() : _line_values{false, false, false, false, false} {} + Port() : _line_levels{High, High, High, High, High} {} - void set_output(Line line, bool value) { - _line_values[line] = value; + void set_output(Line line, LineLevel level) { + _line_levels[line] = level; std::shared_ptr bus = _serial_bus.lock(); if(bus) bus->set_line_output_did_change(line); } - bool get_output(Line line) { - return _line_values[line]; + LineLevel get_output(Line line) { + return _line_levels[line]; } - virtual void set_input(Line line, bool value) = 0; + virtual void set_input(Line line, LineLevel value) = 0; inline void set_serial_bus(std::shared_ptr serial_bus) { _serial_bus = serial_bus; @@ -60,7 +65,7 @@ namespace Serial { private: std::weak_ptr _serial_bus; - bool _line_values[5]; + LineLevel _line_levels[5]; }; } diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index dc214cadf..6a512633c 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -95,7 +95,7 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg if(!port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) - serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x80)); + serialPort->set_output(::Commodore::Serial::Line::Attention, (::Commodore::Serial::LineLevel)(value&0x80)); } } @@ -154,9 +154,9 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { if(port == Port::A) { - serialPort->set_output(::Commodore::Serial::Line::Clock, value); + serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)value); } else { - serialPort->set_output(::Commodore::Serial::Line::Data, value); + serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)value); } } } @@ -184,9 +184,9 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg class SerialPort : public ::Commodore::Serial::Port { public: - void set_input(::Commodore::Serial::Line line, bool value) { + void set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) { std::shared_ptr userPortVIA = _userPortVIA.lock(); - if(userPortVIA) userPortVIA->set_serial_line_state(line, value); + if(userPortVIA) userPortVIA->set_serial_line_state(line, (bool)level); } void set_user_port_via(std::shared_ptr userPortVIA) { From 81e6cc34e5b143e2a3b2bc45df52f7d3934f6340 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 7 Jul 2016 06:57:21 -0400 Subject: [PATCH 22/42] Per the ROM disassembly, the Vic's VIA outputs are inverted for the benefit of the serial bus. --- Machines/Commodore/Vic-20/Vic20.hpp | 8 +++++--- OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 6a512633c..39ce2b35b 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -92,10 +92,11 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg } void set_port_output(Port port, uint8_t value, uint8_t mask) { + // Line 7 of port A is inverted and output as serial ATN if(!port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) - serialPort->set_output(::Commodore::Serial::Line::Attention, (::Commodore::Serial::LineLevel)(value&0x80)); + serialPort->set_output(::Commodore::Serial::Line::Attention, (::Commodore::Serial::LineLevel)!(value&0x80)); } } @@ -153,10 +154,11 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg if(line == Line::Two) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { + // CB2 is inverted to become serial data; CA2 is inverted to become serial clock if(port == Port::A) { - serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)value); + serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!value); } else { - serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)value); + serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)!value); } } } diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm index 6407fcd9e..bb0be94d3 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm @@ -144,7 +144,9 @@ using namespace Commodore::Vic20; _vic20.set_key_state((Key)targetKey.integerValue, isPressed); } else + { NSLog(@"Unmapped: %02x", key); + } } break; case VK_Shift: From 199c0e27e09d98f83f4d99091b205537f143e28d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 7 Jul 2016 07:16:36 -0400 Subject: [PATCH 23/42] Mostly just random guesses now, to be honest. It's approaching the end of my window for the morning. --- Machines/Commodore/1540/Commodore1540.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 732318a9b..fdf79761d 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -34,9 +34,10 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD if(port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { + printf("1540 output: %02x\n", value); // serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); - serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)(value&0x08)); - serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)(value&0x02)); + serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!(value&0x08)); + serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)!(value&0x02)); } // printf("1540 serial port VIA port B: %02x\n", value); } @@ -48,11 +49,11 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD // printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; - case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x01 : 0x00); break; - case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x04 : 0x00); break; + case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break; + case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Attention: - _portB = (_portB & ~0x80) | (value ? 0x80 : 0x00); - set_control_line_input(Port::A, Line::One, value); + _portB = (_portB & ~0x80) | (value ? 0x00 : 0x80); + set_control_line_input(Port::A, Line::One, !value); break; } } From 9a08ef61cb28e87cb9c55c3baef02c7479307ad9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 7 Jul 2016 22:13:18 -0400 Subject: [PATCH 24/42] Still fumbling in the margins: made an effort not to imply that the 1540 is forever reading syncs. --- Machines/Commodore/1540/Commodore1540.cpp | 2 ++ Machines/Commodore/1540/Commodore1540.hpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index eaaadf37b..335113474 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -30,6 +30,8 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { +// if(operation == CPU6502::BusOperation::ReadOpcode) printf("%04x\n", address); + if(address < 0x800) { if(isReadOperation(operation)) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index fdf79761d..f5df4c36e 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -20,7 +20,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD public: using MOS6522IRQDelegate::set_interrupt_status; - SerialPortVIA() : _portB(0x9f) {} + SerialPortVIA() : _portB(0x9f), _attention_acknowledge_level(false) {} uint8_t get_port_input(Port port) { if(port) { @@ -35,9 +35,12 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { printf("1540 output: %02x\n", value); -// serialPort->set_output(::Commodore::Serial::Line::Attention, !(value&0x10)); + // "ATNA (Attention Acknowledge) is an output from PB4 which is sensed on the serial data line after being exclusively "ored" by the attention line and inverted" + _attention_acknowledge_level = !(value&0x10); serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!(value&0x08)); serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)!(value&0x02)); + +// serialPort->set_output(::Commodore::Serial::Line::Data, _attention_acknowledge_level ) } // printf("1540 serial port VIA port B: %02x\n", value); } @@ -52,6 +55,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break; case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Attention: + // "ATN (Attention) is an input on pin 3 of P2 and P3 that is sensed at PB7 and CA1 of UC3 after being inverted by UA1" _portB = (_portB & ~0x80) | (value ? 0x00 : 0x80); set_control_line_input(Port::A, Line::One, !value); break; @@ -65,6 +69,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD private: uint8_t _portB; std::weak_ptr<::Commodore::Serial::Port> _serialPort; + bool _attention_acknowledge_level; }; class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { @@ -72,6 +77,10 @@ class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { using MOS6522IRQDelegate::set_interrupt_status; uint8_t get_port_input(Port port) { + if(port) + { + return 0x7f; // imply not sync, write protect tab uncovered + } return 0xff; } }; From 8827597363ac5d7c8bb555ea14841b144cd2d003 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Fri, 8 Jul 2016 19:00:39 -0400 Subject: [PATCH 25/42] Messier and messier, but I've at least attempted to implement hardware attention acknowledge. --- Machines/Commodore/1540/Commodore1540.cpp | 13 +++++++++++- Machines/Commodore/1540/Commodore1540.hpp | 25 ++++++++++++++++++----- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 335113474..0d803fc6e 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -30,7 +30,14 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { -// if(operation == CPU6502::BusOperation::ReadOpcode) printf("%04x\n", address); + static bool log = false; + + if(operation == CPU6502::BusOperation::ReadOpcode) + { + log = (address >= 0xE85B && address <= 0xE907) || (address >= 0xE9C9 && address <= 0xEA2D); + if(log) printf("\n%04x: ", address); + } + if(log) printf("[%c %04x] ", isReadOperation(operation) ? 'r' : 'w', address); if(address < 0x800) { @@ -46,6 +53,10 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin } else if(address >= 0x1800 && address <= 0x180f) { + if(address == 0x1805) + { + printf("Timer\n"); + } if(isReadOperation(operation)) *value = _serialPortVIA->get_register(address); else diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index f5df4c36e..153dc5b8c 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -20,7 +20,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD public: using MOS6522IRQDelegate::set_interrupt_status; - SerialPortVIA() : _portB(0x9f), _attention_acknowledge_level(false) {} + SerialPortVIA() : _portB(0x00), _attention_acknowledge_level(false), _attention_level_input(true), _data_level_output(false) {} uint8_t get_port_input(Port port) { if(port) { @@ -37,10 +37,10 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD printf("1540 output: %02x\n", value); // "ATNA (Attention Acknowledge) is an output from PB4 which is sensed on the serial data line after being exclusively "ored" by the attention line and inverted" _attention_acknowledge_level = !(value&0x10); - serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!(value&0x08)); - serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)!(value&0x02)); + _data_level_output = (value&0x02); -// serialPort->set_output(::Commodore::Serial::Line::Data, _attention_acknowledge_level ) + serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!(value&0x08)); + update_data_line(); } // printf("1540 serial port VIA port B: %02x\n", value); } @@ -56,8 +56,10 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Attention: // "ATN (Attention) is an input on pin 3 of P2 and P3 that is sensed at PB7 and CA1 of UC3 after being inverted by UA1" + _attention_level_input = !value; _portB = (_portB & ~0x80) | (value ? 0x00 : 0x80); set_control_line_input(Port::A, Line::One, !value); + update_data_line(); break; } } @@ -69,7 +71,20 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD private: uint8_t _portB; std::weak_ptr<::Commodore::Serial::Port> _serialPort; - bool _attention_acknowledge_level; + bool _attention_acknowledge_level, _attention_level_input, _data_level_output; + + void update_data_line() + { + std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); + if(serialPort) { + serialPort->set_output(::Commodore::Serial::Line::Data, + (::Commodore::Serial::LineLevel)!(_data_level_output + || (_attention_level_input == _attention_acknowledge_level)) + ); + +// + } + } }; class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { From 7cc4bf3fe7cca85d9fc6f9a53a4e578b563e8c84 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 15:40:25 -0400 Subject: [PATCH 26/42] Hit and hope is getting me nowhere. Time to unit test this thing. --- Components/6522/6522.hpp | 6 +- Machines/Commodore/1540/Commodore1540.cpp | 4 +- Machines/Commodore/1540/Commodore1540.hpp | 7 +- Machines/Commodore/SerialBus.cpp | 1 + Machines/Commodore/SerialBus.hpp | 9 +- .../Clock Signal.xcodeproj/project.pbxproj | 6 ++ .../Clock Signal/Machine/Wrappers/CSVic20.mm | 2 +- .../Mac/Clock SignalTests/C1540Bridge.h | 20 +++++ .../Mac/Clock SignalTests/C1540Bridge.mm | 83 +++++++++++++++++++ 9 files changed, 124 insertions(+), 14 deletions(-) create mode 100644 OSBindings/Mac/Clock SignalTests/C1540Bridge.h create mode 100644 OSBindings/Mac/Clock SignalTests/C1540Bridge.mm diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index dd5cb5526..e7524f7e3 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -117,15 +117,15 @@ template class MOS6522 { _registers.peripheral_control = value; // TODO: simplify below; tryig to avoid improper logging of unimplemented warnings in input mode - if(value & 0x08) - { +// if(value & 0x08) +// { switch(value & 0x0e) { default: printf("Unimplemented control line mode %d\n", (value >> 1)&7); break; case 0x0c: static_cast(this)->set_control_line_output(Port::A, Line::Two, false); break; case 0x0e: static_cast(this)->set_control_line_output(Port::A, Line::Two, true); break; } - } +// } if(value & 0x80) { switch(value & 0xe0) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 0d803fc6e..a59cfcb8d 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -30,14 +30,14 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { - static bool log = false; +/* static bool log = false; if(operation == CPU6502::BusOperation::ReadOpcode) { log = (address >= 0xE85B && address <= 0xE907) || (address >= 0xE9C9 && address <= 0xEA2D); if(log) printf("\n%04x: ", address); } - if(log) printf("[%c %04x] ", isReadOperation(operation) ? 'r' : 'w', address); + if(log) printf("[%c %04x] ", isReadOperation(operation) ? 'r' : 'w', address);*/ if(address < 0x800) { diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 153dc5b8c..a6057ef35 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -34,7 +34,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD if(port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { - printf("1540 output: %02x\n", value); +// printf("1540 output: %02x\n", value); // "ATNA (Attention Acknowledge) is an output from PB4 which is sensed on the serial data line after being exclusively "ored" by the attention line and inverted" _attention_acknowledge_level = !(value&0x10); _data_level_output = (value&0x02); @@ -79,10 +79,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD if(serialPort) { serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)!(_data_level_output - || (_attention_level_input == _attention_acknowledge_level)) - ); - -// + || (_attention_level_input == _attention_acknowledge_level))); } } }; diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index 057a210f7..d3c3a5659 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -45,6 +45,7 @@ void Bus::set_line_output_did_change(Line line) if(locked_port) { new_line_level = (LineLevel)((bool)new_line_level & (bool)locked_port->get_output(line)); +// printf("[%s] %s is now %s\n", typeid(locked_port).name(), (bool)locked_port->get_output(line) ? "high" : "low"); } } diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 7973f98ae..4b2b654f8 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -48,9 +48,12 @@ namespace Serial { Port() : _line_levels{High, High, High, High, High} {} void set_output(Line line, LineLevel level) { - _line_levels[line] = level; - std::shared_ptr bus = _serial_bus.lock(); - if(bus) bus->set_line_output_did_change(line); + if(_line_levels[line] != level) + { + _line_levels[line] = level; + std::shared_ptr bus = _serial_bus.lock(); + if(bus) bus->set_line_output_did_change(line); + } } LineLevel get_output(Line line) { diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 007ef4c80..82189b583 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; + 4B3BA0C11D31882D005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C01D31882D005DD7A7 /* C1540Bridge.mm */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; }; 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; @@ -386,6 +387,8 @@ 4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = ""; }; 4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = ""; }; 4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = ""; }; + 4B3BA0BF1D31882D005DD7A7 /* C1540Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = C1540Bridge.h; sourceTree = ""; }; + 4B3BA0C01D31882D005DD7A7 /* C1540Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = C1540Bridge.mm; sourceTree = ""; }; 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = ""; }; 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = ""; }; 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = ""; }; @@ -1285,6 +1288,8 @@ 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */, 4B1414631B588A1100E04248 /* Test Binaries */, 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */, + 4B3BA0BF1D31882D005DD7A7 /* C1540Bridge.h */, + 4B3BA0C01D31882D005DD7A7 /* C1540Bridge.mm */, ); path = "Clock SignalTests"; sourceTree = ""; @@ -1843,6 +1848,7 @@ files = ( 4BC751B61D157EB3006C31D9 /* MOS6522Bridge.mm in Sources */, 4B14145E1B5887AA00E04248 /* CPU6502AllRAM.cpp in Sources */, + 4B3BA0C11D31882D005DD7A7 /* C1540Bridge.mm in Sources */, 4B14145D1B5887A600E04248 /* CPU6502.cpp in Sources */, 4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */, 4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */, diff --git a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm index bb0be94d3..7d7cffc8e 100644 --- a/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm +++ b/OSBindings/Mac/Clock Signal/Machine/Wrappers/CSVic20.mm @@ -126,7 +126,7 @@ using namespace Commodore::Vic20; { switch(key) { - case VK_UpArrow: _vic20.set_joystick_state(JoystickInput::Up, isPressed); break; + case VK_UpArrow: _vic20.set_joystick_state(JoystickInput::Up, isPressed); break; case VK_DownArrow: _vic20.set_joystick_state(JoystickInput::Down, isPressed); break; case VK_LeftArrow: _vic20.set_joystick_state(JoystickInput::Left, isPressed); break; case VK_RightArrow: _vic20.set_joystick_state(JoystickInput::Right, isPressed); break; diff --git a/OSBindings/Mac/Clock SignalTests/C1540Bridge.h b/OSBindings/Mac/Clock SignalTests/C1540Bridge.h new file mode 100644 index 000000000..c1e6dd963 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/C1540Bridge.h @@ -0,0 +1,20 @@ +// +// C1540Bridge.h +// Clock Signal +// +// Created by Thomas Harte on 09/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#import + +@interface C1540Bridge : NSObject + +@property (nonatomic) BOOL attentionLine; +@property (nonatomic) BOOL dataLine; +@property (nonatomic) BOOL clockLine; + +- (void)runForCycles:(NSUInteger)numberOfCycles; +- (void)setROM:(NSData *)ROM; + +@end diff --git a/OSBindings/Mac/Clock SignalTests/C1540Bridge.mm b/OSBindings/Mac/Clock SignalTests/C1540Bridge.mm new file mode 100644 index 000000000..ba29751b4 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/C1540Bridge.mm @@ -0,0 +1,83 @@ +// +// C1540Bridge.m +// Clock Signal +// +// Created by Thomas Harte on 09/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#import "C1540Bridge.h" +#include "Commodore1540.hpp" + +class VanillaSerialPort: public Commodore::Serial::Port { + public: + void set_input(Commodore::Serial::Line line, Commodore::Serial::LineLevel value) + { + _input_line_levels[(int)line] = value; + } + + Commodore::Serial::LineLevel _input_line_levels[5]; +}; + +@implementation C1540Bridge +{ + Commodore::C1540::Machine _c1540; + std::shared_ptr _serialBus; + std::shared_ptr _serialPort; +} + +- (instancetype)init +{ + self = [super init]; + if(self) + { + _serialBus.reset(new ::Commodore::Serial::Bus); + _serialPort.reset(new VanillaSerialPort); + + _c1540.set_serial_bus(_serialBus); + _serialBus->add_port(_serialPort); + } + return self; +} + +- (void)setROM:(NSData *)ROM +{ + _c1540.set_rom((uint8_t *)ROM.bytes); +} + +- (void)runForCycles:(NSUInteger)numberOfCycles +{ + _c1540.run_for_cycles((int)numberOfCycles); +} + +- (void)setAttentionLine:(BOOL)attentionLine +{ + _serialPort->set_input(Commodore::Serial::Line::Attention, attentionLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); +} + +- (BOOL)attentionLine +{ + return _serialPort->_input_line_levels[Commodore::Serial::Line::Attention]; +} + +- (void)setDataLine:(BOOL)dataLine +{ + _serialPort->set_input(Commodore::Serial::Line::Data, dataLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); +} + +- (BOOL)dataLine +{ + return _serialPort->_input_line_levels[Commodore::Serial::Line::Data]; +} + +- (void)setClockLine:(BOOL)clockLine +{ + _serialPort->set_input(Commodore::Serial::Line::Clock, clockLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); +} + +- (BOOL)clockLine +{ + return _serialPort->_input_line_levels[Commodore::Serial::Line::Clock]; +} + +@end From 865eb421cd1a8f612f748da14a4afe2d63d2aa15 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 15:44:55 -0400 Subject: [PATCH 27/42] Quick on-disk tidy up. --- .../Clock Signal.xcodeproj/project.pbxproj | 72 +++++++++++-------- .../{ => Bridges}/C1540Bridge.h | 0 .../{ => Bridges}/C1540Bridge.mm | 0 .../Clock SignalTests-Bridging-Header.h | 1 + .../{ => Bridges}/MOS6522Bridge.h | 0 .../{ => Bridges}/MOS6522Bridge.mm | 0 .../{ => Bridges}/MOS6532Bridge.h | 0 .../{ => Bridges}/MOS6532Bridge.mm | 0 .../{ => Bridges}/TestMachine.h | 0 .../{ => Bridges}/TestMachine.mm | 0 .../Mac/Clock SignalTests/C1540Tests.swift | 13 ++++ 11 files changed, 56 insertions(+), 30 deletions(-) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/C1540Bridge.h (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/C1540Bridge.mm (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/Clock SignalTests-Bridging-Header.h (88%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/MOS6522Bridge.h (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/MOS6522Bridge.mm (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/MOS6532Bridge.h (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/MOS6532Bridge.mm (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/TestMachine.h (100%) rename OSBindings/Mac/Clock SignalTests/{ => Bridges}/TestMachine.mm (100%) create mode 100644 OSBindings/Mac/Clock SignalTests/C1540Tests.swift diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 82189b583..2602afa7e 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -14,7 +14,6 @@ 4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */; }; 4B1414621B58888700E04248 /* KlausDormannTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414611B58888700E04248 /* KlausDormannTests.swift */; }; 4B1E85751D170228001EF87D /* Typer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E85731D170228001EF87D /* Typer.cpp */; }; - 4B1E857F1D17644D001EF87D /* MOS6532Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E857E1D17644D001EF87D /* MOS6532Bridge.mm */; }; 4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1E85801D176468001EF87D /* 6532Tests.swift */; }; 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2409531C45AB05004DA684 /* Speaker.cpp */; }; 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; }; @@ -25,7 +24,11 @@ 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D9B1C3A070400138695 /* Electron.cpp */; }; - 4B3BA0C11D31882D005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C01D31882D005DD7A7 /* C1540Bridge.mm */; }; + 4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */; }; + 4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */; }; + 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */; }; + 4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */; }; + 4B3BA0D11D318B44005DD7A7 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CD1D318B44005DD7A7 /* TestMachine.mm */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; }; 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; @@ -41,7 +44,6 @@ 4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */; }; 4BB298EE1B587D8400A49093 /* 6502_functional_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */; }; 4BB298EF1B587D8400A49093 /* AllSuiteA.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E11B587D8300A49093 /* AllSuiteA.bin */; }; - 4BB298F01B587D8400A49093 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BB297E31B587D8300A49093 /* TestMachine.mm */; }; 4BB298F11B587D8400A49093 /* start in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E51B587D8300A49093 /* start */; }; 4BB298F21B587D8400A49093 /* adca in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E61B587D8300A49093 /* adca */; }; 4BB298F31B587D8400A49093 /* adcax in Resources */ = {isa = PBXBuildFile; fileRef = 4BB297E71B587D8300A49093 /* adcax */; }; @@ -320,7 +322,6 @@ 4BC3B74F1CD194CC00F86E85 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B74D1CD194CC00F86E85 /* Shader.cpp */; }; 4BC3B7521CD1956900F86E85 /* OutputShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC3B7501CD1956900F86E85 /* OutputShader.cpp */; }; 4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B11D157E61006C31D9 /* 6522Tests.swift */; }; - 4BC751B61D157EB3006C31D9 /* MOS6522Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BC751B51D157EB3006C31D9 /* MOS6522Bridge.mm */; }; 4BC76E691C98E31700E6EF73 /* FIRFilter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */; }; 4BC76E6B1C98F43700E6EF73 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */; }; 4BC91B831D1F160E00884B76 /* CommodoreTAP.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BC91B811D1F160E00884B76 /* CommodoreTAP.cpp */; }; @@ -362,8 +363,6 @@ 4B1E85731D170228001EF87D /* Typer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Typer.cpp; sourceTree = ""; }; 4B1E85741D170228001EF87D /* Typer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Typer.hpp; sourceTree = ""; }; 4B1E857B1D174DEC001EF87D /* 6532.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 6532.hpp; sourceTree = ""; }; - 4B1E857D1D17644D001EF87D /* MOS6532Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOS6532Bridge.h; sourceTree = ""; }; - 4B1E857E1D17644D001EF87D /* MOS6532Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MOS6532Bridge.mm; sourceTree = ""; }; 4B1E85801D176468001EF87D /* 6532Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6532Tests.swift; sourceTree = ""; }; 4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = ""; }; 4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = ""; }; @@ -387,8 +386,16 @@ 4B2E2D991C3A06EC00138695 /* Atari2600Inputs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Atari2600Inputs.h; sourceTree = ""; }; 4B2E2D9B1C3A070400138695 /* Electron.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Electron.cpp; path = Electron/Electron.cpp; sourceTree = ""; }; 4B2E2D9C1C3A070400138695 /* Electron.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Electron.hpp; path = Electron/Electron.hpp; sourceTree = ""; }; - 4B3BA0BF1D31882D005DD7A7 /* C1540Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = C1540Bridge.h; sourceTree = ""; }; - 4B3BA0C01D31882D005DD7A7 /* C1540Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = C1540Bridge.mm; sourceTree = ""; }; + 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = C1540Tests.swift; sourceTree = ""; }; + 4B3BA0C51D318B44005DD7A7 /* C1540Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = C1540Bridge.h; sourceTree = ""; }; + 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = C1540Bridge.mm; sourceTree = ""; }; + 4B3BA0C71D318B44005DD7A7 /* Clock SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Clock SignalTests-Bridging-Header.h"; sourceTree = ""; }; + 4B3BA0C81D318B44005DD7A7 /* MOS6522Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOS6522Bridge.h; sourceTree = ""; }; + 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MOS6522Bridge.mm; sourceTree = ""; }; + 4B3BA0CA1D318B44005DD7A7 /* MOS6532Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOS6532Bridge.h; sourceTree = ""; }; + 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MOS6532Bridge.mm; sourceTree = ""; }; + 4B3BA0CC1D318B44005DD7A7 /* TestMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine.h; sourceTree = ""; }; + 4B3BA0CD1D318B44005DD7A7 /* TestMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine.mm; sourceTree = ""; }; 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = ""; }; 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = ""; }; 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = ""; }; @@ -408,11 +415,8 @@ 4B73C7191D036BD90074D992 /* Vic20Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Vic20Document.swift; sourceTree = ""; }; 4B73C71C1D036C030074D992 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Clock Signal/Base.lproj/Vic20Document.xib"; sourceTree = SOURCE_ROOT; }; 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6502TimingTests.swift; sourceTree = ""; }; - 4BB297DF1B587D8200A49093 /* Clock SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Clock SignalTests-Bridging-Header.h"; sourceTree = ""; }; 4BB297E01B587D8300A49093 /* 6502_functional_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = 6502_functional_test.bin; sourceTree = ""; }; 4BB297E11B587D8300A49093 /* AllSuiteA.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; path = AllSuiteA.bin; sourceTree = ""; }; - 4BB297E21B587D8300A49093 /* TestMachine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TestMachine.h; sourceTree = ""; }; - 4BB297E31B587D8300A49093 /* TestMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine.mm; sourceTree = ""; }; 4BB297E51B587D8300A49093 /* start */ = {isa = PBXFileReference; lastKnownFileType = file; path = " start"; sourceTree = ""; }; 4BB297E61B587D8300A49093 /* adca */ = {isa = PBXFileReference; lastKnownFileType = file; path = adca; sourceTree = ""; }; 4BB297E71B587D8300A49093 /* adcax */ = {isa = PBXFileReference; lastKnownFileType = file; path = adcax; sourceTree = ""; }; @@ -708,8 +712,6 @@ 4BC3B7501CD1956900F86E85 /* OutputShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputShader.cpp; sourceTree = ""; }; 4BC3B7511CD1956900F86E85 /* OutputShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OutputShader.hpp; sourceTree = ""; }; 4BC751B11D157E61006C31D9 /* 6522Tests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = 6522Tests.swift; sourceTree = ""; }; - 4BC751B41D157EB3006C31D9 /* MOS6522Bridge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MOS6522Bridge.h; sourceTree = ""; }; - 4BC751B51D157EB3006C31D9 /* MOS6522Bridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MOS6522Bridge.mm; sourceTree = ""; }; 4BC76E671C98E31700E6EF73 /* FIRFilter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FIRFilter.cpp; sourceTree = ""; }; 4BC76E681C98E31700E6EF73 /* FIRFilter.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FIRFilter.hpp; sourceTree = ""; }; 4BC76E6A1C98F43700E6EF73 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; @@ -868,6 +870,22 @@ name = Outputs; sourceTree = ""; }; + 4B3BA0C41D318B44005DD7A7 /* Bridges */ = { + isa = PBXGroup; + children = ( + 4B3BA0C51D318B44005DD7A7 /* C1540Bridge.h */, + 4B3BA0C61D318B44005DD7A7 /* C1540Bridge.mm */, + 4B3BA0C71D318B44005DD7A7 /* Clock SignalTests-Bridging-Header.h */, + 4B3BA0C81D318B44005DD7A7 /* MOS6522Bridge.h */, + 4B3BA0C91D318B44005DD7A7 /* MOS6522Bridge.mm */, + 4B3BA0CA1D318B44005DD7A7 /* MOS6532Bridge.h */, + 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */, + 4B3BA0CC1D318B44005DD7A7 /* TestMachine.h */, + 4B3BA0CD1D318B44005DD7A7 /* TestMachine.mm */, + ); + path = Bridges; + sourceTree = ""; + }; 4B4DC81D1D2C2425003C5BF8 /* Commodore */ = { isa = PBXGroup; children = ( @@ -1272,24 +1290,17 @@ 4BB73EB51B587A5100552FC2 /* Clock SignalTests */ = { isa = PBXGroup; children = ( - 4BB297DF1B587D8200A49093 /* Clock SignalTests-Bridging-Header.h */, - 4BC751B41D157EB3006C31D9 /* MOS6522Bridge.h */, - 4B1E857D1D17644D001EF87D /* MOS6532Bridge.h */, - 4BB297E21B587D8300A49093 /* TestMachine.h */, - 4B1E857E1D17644D001EF87D /* MOS6532Bridge.mm */, - 4BC751B51D157EB3006C31D9 /* MOS6522Bridge.mm */, - 4BB297E31B587D8300A49093 /* TestMachine.mm */, 4BB73EB81B587A5100552FC2 /* Info.plist */, + 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */, + 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */, 4BC751B11D157E61006C31D9 /* 6522Tests.swift */, 4B1E85801D176468001EF87D /* 6532Tests.swift */, 4BB73EB61B587A5100552FC2 /* AllSuiteATests.swift */, + 4B3BA0C21D318AEB005DD7A7 /* C1540Tests.swift */, 4B1414611B58888700E04248 /* KlausDormannTests.swift */, - 4B92EAC91B7C112B00246143 /* 6502TimingTests.swift */, 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */, + 4B3BA0C41D318B44005DD7A7 /* Bridges */, 4B1414631B588A1100E04248 /* Test Binaries */, - 4BC9E1ED1D23449A003FCEE4 /* 6502InterruptTests.swift */, - 4B3BA0BF1D31882D005DD7A7 /* C1540Bridge.h */, - 4B3BA0C01D31882D005DD7A7 /* C1540Bridge.mm */, ); path = "Clock SignalTests"; sourceTree = ""; @@ -1846,18 +1857,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 4BC751B61D157EB3006C31D9 /* MOS6522Bridge.mm in Sources */, 4B14145E1B5887AA00E04248 /* CPU6502AllRAM.cpp in Sources */, - 4B3BA0C11D31882D005DD7A7 /* C1540Bridge.mm in Sources */, 4B14145D1B5887A600E04248 /* CPU6502.cpp in Sources */, 4B1E85811D176468001EF87D /* 6532Tests.swift in Sources */, 4BC9E1EE1D23449A003FCEE4 /* 6502InterruptTests.swift in Sources */, + 4B3BA0CE1D318B44005DD7A7 /* C1540Bridge.mm in Sources */, + 4B3BA0D11D318B44005DD7A7 /* TestMachine.mm in Sources */, 4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */, 4BB73EB71B587A5100552FC2 /* AllSuiteATests.swift in Sources */, + 4B3BA0CF1D318B44005DD7A7 /* MOS6522Bridge.mm in Sources */, 4BC751B21D157E61006C31D9 /* 6522Tests.swift in Sources */, + 4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */, + 4B3BA0C31D318AEC005DD7A7 /* C1540Tests.swift in Sources */, 4B1414621B58888700E04248 /* KlausDormannTests.swift in Sources */, - 4BB298F01B587D8400A49093 /* TestMachine.mm in Sources */, - 4B1E857F1D17644D001EF87D /* MOS6532Bridge.mm in Sources */, 4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2048,7 +2060,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "TH.Clock-SignalTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Clock SignalTests/Clock SignalTests-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Clock Signal.app/Contents/MacOS/Clock Signal"; }; @@ -2064,7 +2076,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "TH.Clock-SignalTests"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Clock SignalTests/Clock SignalTests-Bridging-Header.h"; + SWIFT_OBJC_BRIDGING_HEADER = "Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h"; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Clock Signal.app/Contents/MacOS/Clock Signal"; }; name = Release; diff --git a/OSBindings/Mac/Clock SignalTests/C1540Bridge.h b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.h similarity index 100% rename from OSBindings/Mac/Clock SignalTests/C1540Bridge.h rename to OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.h diff --git a/OSBindings/Mac/Clock SignalTests/C1540Bridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm similarity index 100% rename from OSBindings/Mac/Clock SignalTests/C1540Bridge.mm rename to OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm diff --git a/OSBindings/Mac/Clock SignalTests/Clock SignalTests-Bridging-Header.h b/OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h similarity index 88% rename from OSBindings/Mac/Clock SignalTests/Clock SignalTests-Bridging-Header.h rename to OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h index b14444445..8333797fa 100644 --- a/OSBindings/Mac/Clock SignalTests/Clock SignalTests-Bridging-Header.h +++ b/OSBindings/Mac/Clock SignalTests/Bridges/Clock SignalTests-Bridging-Header.h @@ -5,3 +5,4 @@ #import "TestMachine.h" #import "MOS6522Bridge.h" #import "MOS6532Bridge.h" +#import "C1540Bridge.h" diff --git a/OSBindings/Mac/Clock SignalTests/MOS6522Bridge.h b/OSBindings/Mac/Clock SignalTests/Bridges/MOS6522Bridge.h similarity index 100% rename from OSBindings/Mac/Clock SignalTests/MOS6522Bridge.h rename to OSBindings/Mac/Clock SignalTests/Bridges/MOS6522Bridge.h diff --git a/OSBindings/Mac/Clock SignalTests/MOS6522Bridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/MOS6522Bridge.mm similarity index 100% rename from OSBindings/Mac/Clock SignalTests/MOS6522Bridge.mm rename to OSBindings/Mac/Clock SignalTests/Bridges/MOS6522Bridge.mm diff --git a/OSBindings/Mac/Clock SignalTests/MOS6532Bridge.h b/OSBindings/Mac/Clock SignalTests/Bridges/MOS6532Bridge.h similarity index 100% rename from OSBindings/Mac/Clock SignalTests/MOS6532Bridge.h rename to OSBindings/Mac/Clock SignalTests/Bridges/MOS6532Bridge.h diff --git a/OSBindings/Mac/Clock SignalTests/MOS6532Bridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/MOS6532Bridge.mm similarity index 100% rename from OSBindings/Mac/Clock SignalTests/MOS6532Bridge.mm rename to OSBindings/Mac/Clock SignalTests/Bridges/MOS6532Bridge.mm diff --git a/OSBindings/Mac/Clock SignalTests/TestMachine.h b/OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.h similarity index 100% rename from OSBindings/Mac/Clock SignalTests/TestMachine.h rename to OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.h diff --git a/OSBindings/Mac/Clock SignalTests/TestMachine.mm b/OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.mm similarity index 100% rename from OSBindings/Mac/Clock SignalTests/TestMachine.mm rename to OSBindings/Mac/Clock SignalTests/Bridges/TestMachine.mm diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift new file mode 100644 index 000000000..cce738162 --- /dev/null +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -0,0 +1,13 @@ +// +// C1540Tests.swift +// Clock Signal +// +// Created by Thomas Harte on 09/07/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +import XCTest + +class C1540Tests: XCTestCase { + +} From da6fe2e9832501672afc62d1dcde96fa79d424f9 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 15:47:53 -0400 Subject: [PATCH 28/42] This should be enough of a shell to write some actual tests. --- .../Mac/Clock SignalTests/C1540Tests.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index cce738162..5f169902b 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -10,4 +10,22 @@ import XCTest class C1540Tests: XCTestCase { + private func with1540(action: (C1540Bridge) -> ()) { + let bridge = C1540Bridge() + + if let path = NSBundle.mainBundle().pathForResource("1541", ofType: "bin", inDirectory: "ROMImages/Commodore1540") { + let data = NSData(contentsOfFile: path) + bridge.setROM(data) + } + + action(bridge) + } + + // MARK: EOI + + func testEOI() { + with1540 { + $0.runForCycles(20) + } + } } From bf03985ea46598e08af8316e063867546998feec Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 17:22:10 -0400 Subject: [PATCH 29/42] Here's an instantly failing test... --- .../Mac/Clock SignalTests/Bridges/C1540Bridge.mm | 6 +++--- OSBindings/Mac/Clock SignalTests/C1540Tests.swift | 12 ++++++++++-- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm index ba29751b4..12eb13be6 100644 --- a/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm +++ b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm @@ -52,7 +52,7 @@ class VanillaSerialPort: public Commodore::Serial::Port { - (void)setAttentionLine:(BOOL)attentionLine { - _serialPort->set_input(Commodore::Serial::Line::Attention, attentionLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); + _serialPort->set_output(Commodore::Serial::Line::Attention, attentionLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); } - (BOOL)attentionLine @@ -62,7 +62,7 @@ class VanillaSerialPort: public Commodore::Serial::Port { - (void)setDataLine:(BOOL)dataLine { - _serialPort->set_input(Commodore::Serial::Line::Data, dataLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); + _serialPort->set_output(Commodore::Serial::Line::Data, dataLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); } - (BOOL)dataLine @@ -72,7 +72,7 @@ class VanillaSerialPort: public Commodore::Serial::Port { - (void)setClockLine:(BOOL)clockLine { - _serialPort->set_input(Commodore::Serial::Line::Clock, clockLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); + _serialPort->set_output(Commodore::Serial::Line::Clock, clockLine ? Commodore::Serial::LineLevel::High : Commodore::Serial::LineLevel::Low); } - (BOOL)clockLine diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index 5f169902b..46e05b831 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -23,9 +23,17 @@ class C1540Tests: XCTestCase { // MARK: EOI - func testEOI() { + func testTransmission() { with1540 { - $0.runForCycles(20) + // allow some booting time + $0.runForCycles(2000000) + + // I want to be talker, so hold attention and clock low + $0.clockLine = false + $0.attentionLine = false + $0.runForCycles(200) + + XCTAssert($0.dataLine == false, "Listener should have taken data line low") } } } From 66caa3c6dc4e20fe03f4b708a64ed589267e75a4 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 17:23:43 -0400 Subject: [PATCH 30/42] Fixed setup of bridge class. --- OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm index 12eb13be6..72339ef4d 100644 --- a/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm +++ b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm @@ -36,6 +36,7 @@ class VanillaSerialPort: public Commodore::Serial::Port { _c1540.set_serial_bus(_serialBus); _serialBus->add_port(_serialPort); + _serialPort->set_serial_bus(_serialBus); } return self; } From 3560babd7ee66a8e9906ad22952e3d4f88141bcb Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 17:39:51 -0400 Subject: [PATCH 31/42] Got back to a failing test, now while trying to transmit a whole byte. Good stuff! --- .../Mac/Clock SignalTests/C1540Tests.swift | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index 46e05b831..e3438ecf2 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -21,6 +21,34 @@ class C1540Tests: XCTestCase { action(bridge) } + private func transmit(c1540: C1540Bridge, value: Int) { + var shiftedValue = value + for _ in 1..<8 { + // load data line + c1540.dataLine = (shiftedValue & 1) == 1 + shiftedValue >>= 1 + + // toggle clock + c1540.clockLine = false + c1540.runForCycles(40) + c1540.clockLine = true + c1540.runForCycles(40) + + // wait up to 70 µs for an acknowledge + var cyclesWaited = 0 + while c1540.clockLine == true && cyclesWaited < 140 { + c1540.runForCycles(1) + cyclesWaited = cyclesWaited + 1 + } + XCTAssert(c1540.clockLine == false, "Listener should have started to acknowledge bit") + while c1540.clockLine == false && cyclesWaited < 140 { + c1540.runForCycles(1) + cyclesWaited = cyclesWaited + 1 + } + XCTAssert(c1540.clockLine == true, "Listener should have completed acknowledging bit") + } + } + // MARK: EOI func testTransmission() { @@ -28,12 +56,17 @@ class C1540Tests: XCTestCase { // allow some booting time $0.runForCycles(2000000) - // I want to be talker, so hold attention and clock low + // I want to be talker, so hold attention and clock low with data high $0.clockLine = false $0.attentionLine = false - $0.runForCycles(200) + $0.dataLine = true + // proceed 1 ms and check that the 1540 pulled the data line low + $0.runForCycles(2000) XCTAssert($0.dataLine == false, "Listener should have taken data line low") + + // transmit LISTEN #8 + self.transmit($0, value: 0x28) } } } From cd362b46b36b8342b08d67f839e555d1e37a4241 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 17:51:04 -0400 Subject: [PATCH 32/42] This is a valid attempt to send a whole byte, I think. --- .../Mac/Clock SignalTests/C1540Tests.swift | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index e3438ecf2..a0dfd2c43 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -23,30 +23,33 @@ class C1540Tests: XCTestCase { private func transmit(c1540: C1540Bridge, value: Int) { var shiftedValue = value + + c1540.dataLine = true + c1540.runForCycles(256) + XCTAssert(c1540.dataLine == false, "Listener should have taken data line low for start of transmission") + + c1540.clockLine = true + c1540.runForCycles(256) // this isn't time limited on real hardware + XCTAssert(c1540.dataLine == true, "Listener should have let data line go high again") + for _ in 1..<8 { + // ensure the closk is true again + c1540.clockLine = true + c1540.runForCycles(40) + // load data line - c1540.dataLine = (shiftedValue & 1) == 1 + c1540.dataLine = (shiftedValue & 1) == 0 shiftedValue >>= 1 // toggle clock c1540.clockLine = false c1540.runForCycles(40) - c1540.clockLine = true - c1540.runForCycles(40) - - // wait up to 70 µs for an acknowledge - var cyclesWaited = 0 - while c1540.clockLine == true && cyclesWaited < 140 { - c1540.runForCycles(1) - cyclesWaited = cyclesWaited + 1 - } - XCTAssert(c1540.clockLine == false, "Listener should have started to acknowledge bit") - while c1540.clockLine == false && cyclesWaited < 140 { - c1540.runForCycles(1) - cyclesWaited = cyclesWaited + 1 - } - XCTAssert(c1540.clockLine == true, "Listener should have completed acknowledging bit") } + + // check for acknowledgment + c1540.dataLine = true + c1540.runForCycles(1000) + XCTAssert(c1540.dataLine == false, "Listener should have acknowledged byte") } // MARK: EOI @@ -62,7 +65,7 @@ class C1540Tests: XCTestCase { $0.dataLine = true // proceed 1 ms and check that the 1540 pulled the data line low - $0.runForCycles(2000) + $0.runForCycles(1000) XCTAssert($0.dataLine == false, "Listener should have taken data line low") // transmit LISTEN #8 From cd84c35552a6e46b127db12e01405073ea0c6319 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 17:51:46 -0400 Subject: [PATCH 33/42] Whoops, one bit too short. --- OSBindings/Mac/Clock SignalTests/C1540Tests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index a0dfd2c43..bb80f2d76 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -32,7 +32,7 @@ class C1540Tests: XCTestCase { c1540.runForCycles(256) // this isn't time limited on real hardware XCTAssert(c1540.dataLine == true, "Listener should have let data line go high again") - for _ in 1..<8 { + for _ in 0..<8 { // ensure the closk is true again c1540.clockLine = true c1540.runForCycles(40) From 01746f0512c5654613494d100011d983f3b7f4ce Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 18:01:04 -0400 Subject: [PATCH 34/42] This is probably a valid test. But I'm not completely sure. Time to figure out what's happening on the 1540 end. --- OSBindings/Mac/Clock SignalTests/C1540Tests.swift | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index bb80f2d76..9facf16ee 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -32,16 +32,20 @@ class C1540Tests: XCTestCase { c1540.runForCycles(256) // this isn't time limited on real hardware XCTAssert(c1540.dataLine == true, "Listener should have let data line go high again") - for _ in 0..<8 { - // ensure the closk is true again - c1540.clockLine = true - c1540.runForCycles(40) + // set up for byte transfer + c1540.clockLine = false + c1540.dataLine = true + c1540.runForCycles(40) + // transmit bits + for _ in 0..<8 { // load data line c1540.dataLine = (shiftedValue & 1) == 0 shiftedValue >>= 1 // toggle clock + c1540.clockLine = true + c1540.runForCycles(40) c1540.clockLine = false c1540.runForCycles(40) } From 656cd211d737884fb3ecd9745cee9973ca2ff105 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 18:06:49 -0400 Subject: [PATCH 35/42] Was transmitting bit levels backwards (probably?); 1540 now acknowledges byte received. --- Machines/Commodore/1540/Commodore1540.cpp | 3 +++ OSBindings/Mac/Clock SignalTests/C1540Tests.swift | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index a59cfcb8d..521e0fdbf 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -30,6 +30,9 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { +// if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xE9C9 && address <= 0xEA2D)) printf("%04x\n", address); +// if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A)); + /* static bool log = false; if(operation == CPU6502::BusOperation::ReadOpcode) diff --git a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift index 9facf16ee..add83142e 100644 --- a/OSBindings/Mac/Clock SignalTests/C1540Tests.swift +++ b/OSBindings/Mac/Clock SignalTests/C1540Tests.swift @@ -40,7 +40,7 @@ class C1540Tests: XCTestCase { // transmit bits for _ in 0..<8 { // load data line - c1540.dataLine = (shiftedValue & 1) == 0 + c1540.dataLine = (shiftedValue & 1) == 1 shiftedValue >>= 1 // toggle clock From 693c8b2438b6f831f8670649ab12f3062ec41e03 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 20:03:38 -0400 Subject: [PATCH 36/42] After all that, it seems likely that inputs just aren't inverted for the Vic. --- Machines/Commodore/1540/Commodore1540.hpp | 4 ++-- Machines/Commodore/Vic-20/Vic20.cpp | 7 +++++++ Machines/Commodore/Vic-20/Vic20.hpp | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index a6057ef35..baa350e69 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -78,8 +78,8 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { serialPort->set_output(::Commodore::Serial::Line::Data, - (::Commodore::Serial::LineLevel)!(_data_level_output - || (_attention_level_input == _attention_acknowledge_level))); + (::Commodore::Serial::LineLevel)(!_data_level_output + && (_attention_level_input != _attention_acknowledge_level))); } } }; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index ae251f6d1..5a0b6c049 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -78,6 +78,13 @@ Machine::~Machine() unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { + static int logCount = 0; + if(operation == CPU6502::BusOperation::ReadOpcode && address == 0xee17) logCount = 500; + if(operation == CPU6502::BusOperation::ReadOpcode && logCount) { + logCount--; + printf("%04x\n", address); + } + // run the phase-1 part of this cycle, in which the VIC accesses memory uint16_t video_address = _mos6560->get_address(); uint8_t video_value = _videoMemoryMap[video_address >> 10] ? _videoMemoryMap[video_address >> 10][video_address & 0x3ff] : 0xff; // TODO diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 39ce2b35b..ee7f73800 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -79,8 +79,8 @@ class UserPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg // printf("VIC Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; - case ::Commodore::Serial::Line::Data: _portA = (_portA & ~0x02) | (value ? 0 : 0x02); break; - case ::Commodore::Serial::Line::Clock: _portA = (_portA & ~0x01) | (value ? 0 : 0x01); break; + case ::Commodore::Serial::Line::Data: _portA = (_portA & ~0x02) | (value ? 0x02 : 0x00); break; + case ::Commodore::Serial::Line::Clock: _portA = (_portA & ~0x01) | (value ? 0x01 : 0x00); break; } } From f589d639db1b336149510a0f8d72b96f3373689a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 22:25:44 -0400 Subject: [PATCH 37/42] Okay, so it seems that sync also works the other way around. --- Machines/Commodore/1540/Commodore1540.cpp | 6 +----- Machines/Commodore/1540/Commodore1540.hpp | 15 +++++++++++++- Machines/Commodore/SerialBus.cpp | 24 +++++++++++++++++++++-- Machines/Commodore/SerialBus.hpp | 12 ++++++++++++ Machines/Commodore/Vic-20/Vic20.cpp | 4 ++++ Machines/Commodore/Vic-20/Vic20.hpp | 1 + 6 files changed, 54 insertions(+), 8 deletions(-) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 521e0fdbf..3b4e3db67 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -30,7 +30,7 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { -// if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xE9C9 && address <= 0xEA2D)) printf("%04x\n", address); + if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF556 && address <= 0xF56D)) printf("%04x\n", address); // if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A)); /* static bool log = false; @@ -56,10 +56,6 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin } else if(address >= 0x1800 && address <= 0x180f) { - if(address == 0x1805) - { - printf("Timer\n"); - } if(isReadOperation(operation)) *value = _serialPortVIA->get_register(address); else diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index baa350e69..40af76f4e 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -91,10 +91,23 @@ class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { uint8_t get_port_input(Port port) { if(port) { - return 0x7f; // imply not sync, write protect tab uncovered + return 0xff; // imply not sync, write protect tab uncovered } return 0xff; } + + void set_port_output(Port port, uint8_t value, uint8_t direction_mask) { + if(port) + { + if(value&4) + { + printf("Head step: %d\n", value&3); + printf("Motor: %s\n", value&4 ? "On" : "Off"); + printf("LED: %s\n", value&8 ? "On" : "Off"); + printf("Density: %d\n", (value >> 5)&3); + } + } + } }; class SerialPort : public ::Commodore::Serial::Port { diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index d3c3a5659..13ee704b3 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -45,14 +45,12 @@ void Bus::set_line_output_did_change(Line line) if(locked_port) { new_line_level = (LineLevel)((bool)new_line_level & (bool)locked_port->get_output(line)); -// printf("[%s] %s is now %s\n", typeid(locked_port).name(), (bool)locked_port->get_output(line) ? "high" : "low"); } } // post an update only if one occurred if(new_line_level != _line_levels[line]) { - printf("[Bus] %s is %s\n", StringForLine(line), new_line_level ? "high" : "low"); _line_levels[line] = new_line_level; for(std::weak_ptr port : _ports) @@ -65,3 +63,25 @@ void Bus::set_line_output_did_change(Line line) } } } + +#pragma mark - The debug port + +void DebugPort::set_input(Line line, LineLevel value) +{ + _input_levels[line] = value; + + printf("[Bus] %s is %s\n", StringForLine(line), value ? "high" : "low"); + if(!_incoming_count) + { + _incoming_count = (!_input_levels[Line::Clock] && !_input_levels[Line::Data]) ? 8 : 0; + } + else + { + if(line == Line::Clock && value) + { + _incoming_byte = (_incoming_byte >> 1) | (_input_levels[Line::Data] ? 0x80 : 0x00); + } + _incoming_count--; + if(_incoming_count == 0) printf("[Bus] Observed %02x\n", _incoming_byte); + } +} diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 4b2b654f8..78ee5be70 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -71,6 +71,18 @@ namespace Serial { LineLevel _line_levels[5]; }; + class DebugPort: public Port { + public: + void set_input(Line line, LineLevel value); + + DebugPort() : _incoming_count(0) {} + + private: + uint8_t _incoming_byte; + int _incoming_count; + LineLevel _input_levels[5]; + }; + } } diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 5a0b6c049..5560a3a06 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -57,6 +57,10 @@ Machine::Machine() : // TEMPORARY: attach a [diskless] 1540 set_disc(); + + _debugPort.reset(new ::Commodore::Serial::DebugPort); + _debugPort->set_serial_bus(_serialBus); + _serialBus->add_port(_debugPort); } void Machine::write_to_map(uint8_t **map, uint8_t *area, uint16_t address, uint16_t length) diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index ee7f73800..49f11d6b4 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -295,6 +295,7 @@ class Machine: std::shared_ptr _keyboardVIA; std::shared_ptr _serialPort; std::shared_ptr<::Commodore::Serial::Bus> _serialBus; + std::shared_ptr<::Commodore::Serial::DebugPort> _debugPort; // Tape Tape _tape; From c0ab45a73d632f8fc2a740afc18df537c315f9c1 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 9 Jul 2016 22:29:11 -0400 Subject: [PATCH 38/42] Disabled a bunch of the caveman debug logging. --- Components/6522/6522.hpp | 8 ++++---- Machines/Commodore/1540/Commodore1540.cpp | 2 +- Machines/Commodore/1540/Commodore1540.hpp | 14 +++++++------- Machines/Commodore/Vic-20/Vic20.cpp | 18 +++++++++--------- Machines/Commodore/Vic-20/Vic20.hpp | 2 +- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index e7524f7e3..19f8ccb66 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -116,16 +116,16 @@ template class MOS6522 { // printf("Peripheral control %02x\n", value); _registers.peripheral_control = value; - // TODO: simplify below; tryig to avoid improper logging of unimplemented warnings in input mode -// if(value & 0x08) -// { + // TODO: simplify below; trying to avoid improper logging of unimplemented warnings in input mode + if(value & 0x08) + { switch(value & 0x0e) { default: printf("Unimplemented control line mode %d\n", (value >> 1)&7); break; case 0x0c: static_cast(this)->set_control_line_output(Port::A, Line::Two, false); break; case 0x0e: static_cast(this)->set_control_line_output(Port::A, Line::Two, true); break; } -// } + } if(value & 0x80) { switch(value & 0xe0) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/Commodore1540.cpp index 3b4e3db67..fa7bb49e9 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/Commodore1540.cpp @@ -30,7 +30,7 @@ void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bu unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { - if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF556 && address <= 0xF56D)) printf("%04x\n", address); +// if(operation == CPU6502::BusOperation::ReadOpcode && (address >= 0xF556 && address <= 0xF56D)) printf("%04x\n", address); // if(operation == CPU6502::BusOperation::ReadOpcode && (address == 0xE887)) printf("A: %02x\n", get_value_of_register(CPU6502::Register::A)); /* static bool log = false; diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/Commodore1540.hpp index 40af76f4e..2d0fffec3 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/Commodore1540.hpp @@ -99,13 +99,13 @@ class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { void set_port_output(Port port, uint8_t value, uint8_t direction_mask) { if(port) { - if(value&4) - { - printf("Head step: %d\n", value&3); - printf("Motor: %s\n", value&4 ? "On" : "Off"); - printf("LED: %s\n", value&8 ? "On" : "Off"); - printf("Density: %d\n", (value >> 5)&3); - } +// if(value&4) +// { +// printf("Head step: %d\n", value&3); +// printf("Motor: %s\n", value&4 ? "On" : "Off"); +// printf("LED: %s\n", value&8 ? "On" : "Off"); +// printf("Density: %d\n", (value >> 5)&3); +// } } } }; diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 5560a3a06..454b061ee 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -58,9 +58,9 @@ Machine::Machine() : // TEMPORARY: attach a [diskless] 1540 set_disc(); - _debugPort.reset(new ::Commodore::Serial::DebugPort); - _debugPort->set_serial_bus(_serialBus); - _serialBus->add_port(_debugPort); +// _debugPort.reset(new ::Commodore::Serial::DebugPort); +// _debugPort->set_serial_bus(_serialBus); +// _serialBus->add_port(_debugPort); } void Machine::write_to_map(uint8_t **map, uint8_t *area, uint16_t address, uint16_t length) @@ -82,12 +82,12 @@ Machine::~Machine() unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) { - static int logCount = 0; - if(operation == CPU6502::BusOperation::ReadOpcode && address == 0xee17) logCount = 500; - if(operation == CPU6502::BusOperation::ReadOpcode && logCount) { - logCount--; - printf("%04x\n", address); - } +// static int logCount = 0; +// if(operation == CPU6502::BusOperation::ReadOpcode && address == 0xee17) logCount = 500; +// if(operation == CPU6502::BusOperation::ReadOpcode && logCount) { +// logCount--; +// printf("%04x\n", address); +// } // run the phase-1 part of this cycle, in which the VIC accesses memory uint16_t video_address = _mos6560->get_address(); diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index 49f11d6b4..a6ad74501 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -295,7 +295,7 @@ class Machine: std::shared_ptr _keyboardVIA; std::shared_ptr _serialPort; std::shared_ptr<::Commodore::Serial::Bus> _serialBus; - std::shared_ptr<::Commodore::Serial::DebugPort> _debugPort; +// std::shared_ptr<::Commodore::Serial::DebugPort> _debugPort; // Tape Tape _tape; From d8334edf4a9fe4e25dc251b946b8aebdcd42343f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 10 Jul 2016 07:46:20 -0400 Subject: [PATCH 39/42] Started trying to clean up, including commuting the C1540 source file name to match its class name but mainly by adding documentation. --- .../1540/{Commodore1540.cpp => C1540.cpp} | 2 +- .../1540/{Commodore1540.hpp => C1540.hpp} | 56 ++++++++++++++++--- Machines/Commodore/SerialBus.cpp | 6 ++ Machines/Commodore/SerialBus.hpp | 44 ++++++++++++++- Machines/Commodore/Vic-20/Vic20.cpp | 3 +- Machines/Commodore/Vic-20/Vic20.hpp | 2 +- .../Clock Signal.xcodeproj/project.pbxproj | 12 ++-- .../Clock SignalTests/Bridges/C1540Bridge.mm | 5 +- 8 files changed, 108 insertions(+), 22 deletions(-) rename Machines/Commodore/1540/{Commodore1540.cpp => C1540.cpp} (98%) rename Machines/Commodore/1540/{Commodore1540.hpp => C1540.hpp} (65%) diff --git a/Machines/Commodore/1540/Commodore1540.cpp b/Machines/Commodore/1540/C1540.cpp similarity index 98% rename from Machines/Commodore/1540/Commodore1540.cpp rename to Machines/Commodore/1540/C1540.cpp index fa7bb49e9..69672ddb5 100644 --- a/Machines/Commodore/1540/Commodore1540.cpp +++ b/Machines/Commodore/1540/C1540.cpp @@ -6,7 +6,7 @@ // Copyright © 2016 Thomas Harte. All rights reserved. // -#include "Commodore1540.hpp" +#include "C1540.hpp" #include using namespace Commodore::C1540; diff --git a/Machines/Commodore/1540/Commodore1540.hpp b/Machines/Commodore/1540/C1540.hpp similarity index 65% rename from Machines/Commodore/1540/Commodore1540.hpp rename to Machines/Commodore/1540/C1540.hpp index 2d0fffec3..92ceccb6e 100644 --- a/Machines/Commodore/1540/Commodore1540.hpp +++ b/Machines/Commodore/1540/C1540.hpp @@ -16,6 +16,21 @@ namespace Commodore { namespace C1540 { +/*! + An implementation of the serial-port VIA in a Commodore 1540 — the VIA that facilitates all + IEC bus communications. + + It is wired up such that Port B contains: + Bit 0: data input; 1 if the line is low, 0 if it is high; + Bit 1: data output; 1 if the line should be low, 0 if it should be high; + Bit 2: clock input; 1 if the line is low, 0 if it is high; + Bit 3: clock output; 1 if the line is low, 0 if it is high; + Bit 4: attention acknowledge output; exclusive ORd with the attention input and ORd onto the data output; + Bits 5/6: device select input; the 1540 will act as device 8 + [value of bits] + Bit 7: attention input; 1 if the line is low, 0 if it is high + + The attention input is also connected to CA1, similarly inverted — the CA1 wire will be high when the bus is low and vice versa. +*/ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: using MOS6522IRQDelegate::set_interrupt_status; @@ -34,28 +49,21 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD if(port) { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { -// printf("1540 output: %02x\n", value); - // "ATNA (Attention Acknowledge) is an output from PB4 which is sensed on the serial data line after being exclusively "ored" by the attention line and inverted" _attention_acknowledge_level = !(value&0x10); _data_level_output = (value&0x02); serialPort->set_output(::Commodore::Serial::Line::Clock, (::Commodore::Serial::LineLevel)!(value&0x08)); update_data_line(); } -// printf("1540 serial port VIA port B: %02x\n", value); } -// else -// printf("1540 serial port VIA port A: %02x\n", value); } void set_serial_line_state(::Commodore::Serial::Line line, bool value) { -// printf("1540 Serial port line %d: %s\n", line, value ? "on" : "off"); switch(line) { default: break; case ::Commodore::Serial::Line::Data: _portB = (_portB & ~0x01) | (value ? 0x00 : 0x01); break; case ::Commodore::Serial::Line::Clock: _portB = (_portB & ~0x04) | (value ? 0x00 : 0x04); break; case ::Commodore::Serial::Line::Attention: - // "ATN (Attention) is an input on pin 3 of P2 and P3 that is sensed at PB7 and CA1 of UC3 after being inverted by UA1" _attention_level_input = !value; _portB = (_portB & ~0x80) | (value ? 0x00 : 0x80); set_control_line_input(Port::A, Line::One, !value); @@ -77,6 +85,7 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD { std::shared_ptr<::Commodore::Serial::Port> serialPort = _serialPort.lock(); if(serialPort) { + // "ATN (Attention) is an input on pin 3 of P2 and P3 that is sensed at PB7 and CA1 of UC3 after being inverted by UA1" serialPort->set_output(::Commodore::Serial::Line::Data, (::Commodore::Serial::LineLevel)(!_data_level_output && (_attention_level_input != _attention_acknowledge_level))); @@ -84,6 +93,22 @@ class SerialPortVIA: public MOS::MOS6522, public MOS::MOS6522IRQD } }; +/*! + An implementation of the drive VIA in a Commodore 1540 — the VIA that is used to interface with the disk. + + It is wired up such that Port B contains: + Bits 0/1: head step direction (TODO) + Bit 2: motor control (TODO) + Bit 3: LED control (TODO) + Bit 4: write protect photocell status (TODO) + Bits 5/6: write density (TODO) + Bit 7: 0 if sync marks are currently being detected, 1 otherwise; + + ... and Port A contains the byte most recently read from the disk or the byte next to write to the disk, depending on data direction. + + It is implied that CA2 might be used to set processor overflow, CA1 a strobe for data input, and one of the CBs being definitive on + whether the disk head is being told to read or write, but it's unclear and I've yet to investigate. So, TODO. +*/ class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { public: using MOS6522IRQDelegate::set_interrupt_status; @@ -110,6 +135,9 @@ class DriveVIA: public MOS::MOS6522, public MOS::MOS6522IRQDelegate { } }; +/*! + An implementation of the C1540's serial port; this connects incoming line levels to the serial-port VIA. +*/ class SerialPort : public ::Commodore::Serial::Port { public: void set_input(::Commodore::Serial::Line line, ::Commodore::Serial::LineLevel level) { @@ -125,17 +153,29 @@ class SerialPort : public ::Commodore::Serial::Port { std::weak_ptr _serialPortVIA; }; +/*! + Provides an emulation of the C1540. +*/ class Machine: public CPU6502::Processor, public MOS::MOS6522IRQDelegate::Delegate { public: Machine(); - unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); + /*! + Sets the ROM image to use for this drive; it is assumed that the buffer provided will be at least 16 kb in size. + */ void set_rom(const uint8_t *rom); + + /*! + Sets the serial bus to which this drive should attach itself. + */ void set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus); + // to satisfy CPU6502::Processor + unsigned int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); + // to satisfy MOS::MOS6522::Delegate virtual void mos6522_did_change_interrupt_status(void *mos6522); diff --git a/Machines/Commodore/SerialBus.cpp b/Machines/Commodore/SerialBus.cpp index 13ee704b3..69b187472 100644 --- a/Machines/Commodore/SerialBus.cpp +++ b/Machines/Commodore/SerialBus.cpp @@ -22,6 +22,12 @@ const char *::Commodore::Serial::StringForLine(Line line) } } +void ::Commodore::Serial::AttachPortAndBus(std::shared_ptr port, std::shared_ptr bus) +{ + port->set_serial_bus(bus); + bus->add_port(port); +} + void Bus::add_port(std::shared_ptr port) { _ports.push_back(port); diff --git a/Machines/Commodore/SerialBus.hpp b/Machines/Commodore/SerialBus.hpp index 78ee5be70..324ef235e 100644 --- a/Machines/Commodore/SerialBus.hpp +++ b/Machines/Commodore/SerialBus.hpp @@ -27,15 +27,38 @@ namespace Serial { Low = false }; + class Port; + class Bus; + + /*! + Returns a C string giving a human-readable name for the supplied line. + */ const char *StringForLine(Line line); - class Port; + /*! + Calls both of the necessary methods to (i) set @c bus as the target for @c port outputs; and + (ii) add @c port as one of the targets to which @c bus propagates line changes. + */ + void AttachPortAndBus(std::shared_ptr port, std::shared_ptr bus); + /*! + A serial bus is responsible for retaining a weakly-held collection of attached ports and for deciding the + current bus levels based upon the net result of each port's output, and for communicating changes in bus + levels to every port. + */ class Bus { public: Bus() : _line_levels{High, High, High, High, High} {} + /*! + Adds the supplied port to the bus. + */ void add_port(std::shared_ptr port); + + /*! + Communicates to the bus that one of its attached port has changed its output level for the given line. + The bus will therefore recalculate bus state and propagate as necessary. + */ void set_line_output_did_change(Line line); private: @@ -43,10 +66,17 @@ namespace Serial { std::vector> _ports; }; + /*! + A serial port is an endpoint on a serial bus; this class provides a direct setter for current line outputs and + expects to be subclassed in order for specific port-housing devices to deal with input. + */ class Port { public: Port() : _line_levels{High, High, High, High, High} {} + /*! + Sets the current level of an output line on this serial port. + */ void set_output(Line line, LineLevel level) { if(_line_levels[line] != level) { @@ -56,12 +86,21 @@ namespace Serial { } } + /*! + Gets the previously set level of an output line. + */ LineLevel get_output(Line line) { return _line_levels[line]; } + /*! + Called by the bus to signal a change in any input line level. Subclasses should implement this. + */ virtual void set_input(Line line, LineLevel value) = 0; + /*! + Sets the supplied serial bus as that to which line levels will be communicated. + */ inline void set_serial_bus(std::shared_ptr serial_bus) { _serial_bus = serial_bus; } @@ -71,6 +110,9 @@ namespace Serial { LineLevel _line_levels[5]; }; + /*! + A debugging port, which makes some attempt to log bus activity. Incomplete. TODO: complete. + */ class DebugPort: public Port { public: void set_input(Line line, LineLevel value); diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index 454b061ee..e417c2849 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -22,8 +22,7 @@ Machine::Machine() : _serialBus.reset(new ::Commodore::Serial::Bus); // wire up the serial bus and serial port - _serialBus->add_port(_serialPort); - _serialPort->set_serial_bus(_serialBus); + Commodore::Serial::AttachPortAndBus(_serialPort, _serialBus); // wire up 6522s and serial port _userPortVIA->set_serial_port(_serialPort); diff --git a/Machines/Commodore/Vic-20/Vic20.hpp b/Machines/Commodore/Vic-20/Vic20.hpp index a6ad74501..fcbac0fbf 100644 --- a/Machines/Commodore/Vic-20/Vic20.hpp +++ b/Machines/Commodore/Vic-20/Vic20.hpp @@ -13,7 +13,7 @@ #include "../../../Storage/Tape/Tape.hpp" #include "../../../Components/6560/6560.hpp" #include "../../../Components/6522/6522.hpp" -#include "../1540/Commodore1540.hpp" +#include "../1540/C1540.hpp" #include "../SerialBus.hpp" #include "../../CRTMachine.hpp" diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 2602afa7e..302bceebd 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -30,7 +30,7 @@ 4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */; }; 4B3BA0D11D318B44005DD7A7 /* TestMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CD1D318B44005DD7A7 /* TestMachine.mm */; }; 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */; }; - 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */; }; + 4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */; }; 4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */; }; 4B55CE581C3B7D360093A61B /* Atari2600Document.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */; }; 4B55CE591C3B7D360093A61B /* ElectronDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B55CE571C3B7D360093A61B /* ElectronDocument.swift */; }; @@ -398,8 +398,8 @@ 4B3BA0CD1D318B44005DD7A7 /* TestMachine.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine.mm; sourceTree = ""; }; 4B4DC81F1D2C2425003C5BF8 /* Vic20.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Vic20.cpp; sourceTree = ""; }; 4B4DC8201D2C2425003C5BF8 /* Vic20.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Vic20.hpp; sourceTree = ""; }; - 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Commodore1540.cpp; sourceTree = ""; }; - 4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Commodore1540.hpp; sourceTree = ""; }; + 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = C1540.cpp; sourceTree = ""; }; + 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = C1540.hpp; sourceTree = ""; }; 4B4DC8291D2C27A4003C5BF8 /* SerialBus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SerialBus.cpp; sourceTree = ""; }; 4B4DC82A1D2C27A4003C5BF8 /* SerialBus.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = SerialBus.hpp; sourceTree = ""; }; 4B55CE561C3B7D360093A61B /* Atari2600Document.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Atari2600Document.swift; sourceTree = ""; }; @@ -909,8 +909,8 @@ 4B4DC8251D2C2470003C5BF8 /* 1540 */ = { isa = PBXGroup; children = ( - 4B4DC8261D2C2470003C5BF8 /* Commodore1540.cpp */, - 4B4DC8271D2C2470003C5BF8 /* Commodore1540.hpp */, + 4B4DC8261D2C2470003C5BF8 /* C1540.cpp */, + 4B4DC8271D2C2470003C5BF8 /* C1540.hpp */, ); path = 1540; sourceTree = ""; @@ -1836,7 +1836,7 @@ 4B4DC8211D2C2425003C5BF8 /* Vic20.cpp in Sources */, 4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */, 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */, - 4B4DC8281D2C2470003C5BF8 /* Commodore1540.cpp in Sources */, + 4B4DC8281D2C2470003C5BF8 /* C1540.cpp in Sources */, 4B1E85751D170228001EF87D /* Typer.cpp in Sources */, 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */, 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, diff --git a/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm index 72339ef4d..b062016c5 100644 --- a/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm +++ b/OSBindings/Mac/Clock SignalTests/Bridges/C1540Bridge.mm @@ -7,7 +7,7 @@ // #import "C1540Bridge.h" -#include "Commodore1540.hpp" +#include "C1540.hpp" class VanillaSerialPort: public Commodore::Serial::Port { public: @@ -35,8 +35,7 @@ class VanillaSerialPort: public Commodore::Serial::Port { _serialPort.reset(new VanillaSerialPort); _c1540.set_serial_bus(_serialBus); - _serialBus->add_port(_serialPort); - _serialPort->set_serial_bus(_serialBus); + Commodore::Serial::AttachPortAndBus(_serialPort, _serialBus); } return self; } From 824d9ea92b6f7a9bc141b37a198e012a10acad9c Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 10 Jul 2016 08:01:16 -0400 Subject: [PATCH 40/42] Added further comments. --- Machines/Commodore/1540/C1540.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Machines/Commodore/1540/C1540.cpp b/Machines/Commodore/1540/C1540.cpp index 69672ddb5..49209d1a4 100644 --- a/Machines/Commodore/1540/C1540.cpp +++ b/Machines/Commodore/1540/C1540.cpp @@ -13,19 +13,22 @@ using namespace Commodore::C1540; Machine::Machine() { + // create a serial port and a VIA to run it _serialPortVIA.reset(new SerialPortVIA); _serialPort.reset(new SerialPort); + // attach the serial port to its VIA and vice versa _serialPort->set_serial_port_via(_serialPortVIA); _serialPortVIA->set_serial_port(_serialPort); + + // set this instance as the delegate to receive interrupt requests from both VIAs _serialPortVIA->set_delegate(this); _driveVIA.set_delegate(this); } void Machine::set_serial_bus(std::shared_ptr<::Commodore::Serial::Bus> serial_bus) { - _serialPort->set_serial_bus(serial_bus); - serial_bus->add_port(_serialPort); + Commodore::Serial::AttachPortAndBus(_serialPort, serial_bus); } unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) @@ -42,6 +45,14 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin } if(log) printf("[%c %04x] ", isReadOperation(operation) ? 'r' : 'w', address);*/ + /* + Memory map (given that I'm unsure yet on any potential mirroring): + + 0x0000–0x07ff RAM + 0x1800–0x180f the serial-port VIA + 0x1c00–0x1c0f the drive VIA + 0xc000–0xffff ROM + */ if(address < 0x800) { if(isReadOperation(operation)) @@ -84,5 +95,6 @@ void Machine::set_rom(const uint8_t *rom) void Machine::mos6522_did_change_interrupt_status(void *mos6522) { + // both VIAs are connected to the IRQ line set_irq_line(_serialPortVIA->get_interrupt_line() || _driveVIA.get_interrupt_line()); } From 4ca6883f7c46c6943490282d290f36245375e96a Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 10 Jul 2016 08:03:36 -0400 Subject: [PATCH 41/42] Disabled attachment of a 1540 again, as I probably need to move to opening an actual disk image next. --- Machines/Commodore/Vic-20/Vic20.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Machines/Commodore/Vic-20/Vic20.cpp b/Machines/Commodore/Vic-20/Vic20.cpp index e417c2849..6a44f64e0 100644 --- a/Machines/Commodore/Vic-20/Vic20.cpp +++ b/Machines/Commodore/Vic-20/Vic20.cpp @@ -55,7 +55,7 @@ Machine::Machine() : write_to_map(_processorWriteMemoryMap, _colorMemory, 0x9400, sizeof(_colorMemory)); // TEMPORARY: attach a [diskless] 1540 - set_disc(); +// set_disc(); // _debugPort.reset(new ::Commodore::Serial::DebugPort); // _debugPort->set_serial_bus(_serialBus); From 11cd541786bfebcd4e3d4999d10d5931c26e822b Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 10 Jul 2016 08:05:05 -0400 Subject: [PATCH 42/42] Fixed accidental indentation. --- Components/6522/6522.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Components/6522/6522.hpp b/Components/6522/6522.hpp index 19f8ccb66..ecb118d91 100644 --- a/Components/6522/6522.hpp +++ b/Components/6522/6522.hpp @@ -1,4 +1,4 @@ - // +// // 6522.hpp // Clock Signal //