From e7aeed2f033054b21b70342ddb888172522a7189 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 19 Jun 2016 13:10:52 -0400 Subject: [PATCH] Established a general pattern for machines that can type things. Started working on the Vic typing itself. --- Machines/Typer.cpp | 47 +++++++++++++++++ Machines/Typer.hpp | 50 +++++++++++++++++++ Machines/Vic-20/Vic20.cpp | 29 ++++++++++- Machines/Vic-20/Vic20.hpp | 14 +++++- .../Clock Signal.xcodeproj/project.pbxproj | 6 +++ 5 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 Machines/Typer.cpp create mode 100644 Machines/Typer.hpp diff --git a/Machines/Typer.cpp b/Machines/Typer.cpp new file mode 100644 index 000000000..d030708c9 --- /dev/null +++ b/Machines/Typer.cpp @@ -0,0 +1,47 @@ +// +// Typer.cpp +// Clock Signal +// +// Created by Thomas Harte on 19/06/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "Typer.hpp" +#include + +using namespace Utility; + +Typer::Typer(const char *string, int delay, int frequency, Delegate *delegate) : + _counter(-delay), _frequency(frequency), _string(strdup(string)), _string_pointer(0), _delegate(delegate) {} + +void Typer::update(int duration) +{ + if(_string) + { + if(_counter < 0 && _counter + duration >= 0) + { + _delegate->typer_set_next_character(this, _string[_string_pointer]); + _string_pointer++; + } + + _counter += duration; + while(_counter > _frequency) + { + _counter -= _frequency; + _delegate->typer_set_next_character(this, _string[_string_pointer]); + _string_pointer++; + + if(!_string[_string_pointer]) + { + free(_string); + _string = nullptr; + return; + } + } + } +} + +Typer::~Typer() +{ + free(_string); +} diff --git a/Machines/Typer.hpp b/Machines/Typer.hpp new file mode 100644 index 000000000..3596b9a12 --- /dev/null +++ b/Machines/Typer.hpp @@ -0,0 +1,50 @@ +// +// Typer.hpp +// Clock Signal +// +// Created by Thomas Harte on 19/06/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef Typer_hpp +#define Typer_hpp + +#include + +namespace Utility { + +class Typer { + public: + class Delegate { + public: + virtual void typer_set_next_character(Typer *typer, char character) = 0; + }; + + Typer(const char *string, int delay, int frequency, Delegate *delegate); + ~Typer(); + void update(int duration); + + private: + char *_string; + int _frequency; + int _counter; + Delegate *_delegate; + size_t _string_pointer; +}; + +class TypeRecipient: public Typer::Delegate { + public: + void set_typer_for_string(const char *string) + { + _typer = std::unique_ptr(new Typer(string, get_typer_delay(), get_typer_frequency(), this)); + } + + protected: + virtual int get_typer_delay() = 0; + virtual int get_typer_frequency() = 0; + std::unique_ptr _typer; +}; + +} + +#endif /* Typer_hpp */ diff --git a/Machines/Vic-20/Vic20.cpp b/Machines/Vic-20/Vic20.cpp index 71888551f..d92bdbcb9 100644 --- a/Machines/Vic-20/Vic20.cpp +++ b/Machines/Vic-20/Vic20.cpp @@ -81,6 +81,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin _userPortVIA.run_for_half_cycles(2); _keyboardVIA.run_for_half_cycles(2); + if(_typer) _typer->update(1); return 1; } @@ -125,7 +126,8 @@ void Machine::add_prg(size_t length, const uint8_t *data) _rom_length = (uint16_t)(length - 2); if(_rom_address >= 0x1000 && _rom_address+_rom_length < 0x2000) { - memcpy(&_screenMemory[_rom_address - 0x1000], &data[2], length - 2); + set_typer_for_string("run\n"); +// memcpy(&_screenMemory[_rom_address - 0x1000], &data[2], length - 2); } else { @@ -134,3 +136,28 @@ void Machine::add_prg(size_t length, const uint8_t *data) } } } + +#pragma mark - Typer + +int Machine::get_typer_delay() +{ + return 263*60*65 / 2; // wait half a second +} + +int Machine::get_typer_frequency() +{ + return 2*263*65; // accept a new character every two fields +} + +void Machine::typer_set_next_character(::Utility::Typer *typer, char character) +{ + clear_all_keys(); + switch(character) + { + case 'r': set_key_state(Key::KeyR, true); break; + case 'u': set_key_state(Key::KeyU, true); break; + case 'n': set_key_state(Key::KeyN, true); break; + case '\n': set_key_state(Key::KeyReturn, true); break; + } + printf("."); +} diff --git a/Machines/Vic-20/Vic20.hpp b/Machines/Vic-20/Vic20.hpp index 4fb639a55..768eb2fd6 100644 --- a/Machines/Vic-20/Vic20.hpp +++ b/Machines/Vic-20/Vic20.hpp @@ -12,7 +12,9 @@ #include "../../Processors/6502/CPU6502.hpp" #include "../../Components/6560/6560.hpp" #include "../../Components/6522/6522.hpp" + #include "../CRTMachine.hpp" +#include "../Typer.hpp" namespace Vic20 { @@ -88,7 +90,12 @@ class KeyboardVIA: public MOS::MOS6522, public MOS::MOS6522IRQDeleg uint8_t _activation_mask; }; -class Machine: public CPU6502::Processor, public CRTMachine::Machine, public MOS::MOS6522IRQDelegate::Delegate { +class Machine: + public CPU6502::Processor, + public CRTMachine::Machine, + public MOS::MOS6522IRQDelegate::Delegate, + public Utility::TypeRecipient { + public: Machine(); ~Machine(); @@ -114,6 +121,11 @@ class Machine: public CPU6502::Processor, public CRTMachine::Machine, p // to satisfy MOS::MOS6522::Delegate virtual void mos6522_did_change_interrupt_status(void *mos6522); + // for Utility::TypeRecipient + virtual int get_typer_delay(); + virtual int get_typer_frequency(); + virtual void typer_set_next_character(Utility::Typer *typer, char character); + private: uint8_t _characterROM[0x1000]; uint8_t _basicROM[0x2000]; diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 1571aec89..d7c054aac 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ 4B14145E1B5887AA00E04248 /* CPU6502AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414591B58879D00E04248 /* CPU6502AllRAM.cpp */; }; 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 */; }; 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2409531C45AB05004DA684 /* Speaker.cpp */; }; 4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; }; 4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53961D117D36003C6002 /* CSMachine.mm */; }; @@ -352,6 +353,8 @@ 4B14145A1B58879D00E04248 /* CPU6502AllRAM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CPU6502AllRAM.hpp; sourceTree = ""; }; 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WolfgangLorenzTests.swift; sourceTree = ""; }; 4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = ""; }; + 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 = ""; }; 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 = ""; }; 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = ""; }; @@ -1251,6 +1254,8 @@ 4B2E2D961C3A06EC00138695 /* Atari2600 */, 4B2E2D9E1C3A070900138695 /* Electron */, 4B886FF61D03B632004291C3 /* Vic-20 */, + 4B1E85731D170228001EF87D /* Typer.cpp */, + 4B1E85741D170228001EF87D /* Typer.hpp */, ); name = Machines; path = ../../Machines; @@ -1764,6 +1769,7 @@ 4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */, 4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */, 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */, + 4B1E85751D170228001EF87D /* Typer.cpp in Sources */, 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */, 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, 4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,