From 8c70dc5891e76d9c6305ec7d1a0a497114b75c4d Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 3 Nov 2016 22:14:40 -0400 Subject: [PATCH 1/2] Implemented typer for the Oric, and I'm starting to think the code is a bit too repetitious. Refactoring will be forthcoming. Added CLOAD"" as the loading command for all Oric software. --- Machines/Oric/Oric.cpp | 107 ++++++++++++++++++++++++- Machines/Oric/Oric.hpp | 20 +++-- Machines/Typer.hpp | 4 +- StaticAnalyser/Oric/StaticAnalyser.cpp | 1 + 4 files changed, 123 insertions(+), 9 deletions(-) diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index cb1ffec81..8ecc51ce6 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -11,7 +11,10 @@ using namespace Oric; -Machine::Machine() : _cycles_since_video_update(0), _use_fast_tape_hack(false) +Machine::Machine() : + _cycles_since_video_update(0), + _use_fast_tape_hack(false), + _typer_delay(2500000) { set_clock_rate(1000000); _via.tape.reset(new TapePlayer); @@ -29,6 +32,11 @@ void Machine::configure_as_target(const StaticAnalyser::Target &target) { _via.tape->set_tape(target.tapes.front()); } + + if(target.loadingCommand.length()) // TODO: and automatic loading option enabled + { + set_typer_for_string(target.loadingCommand.c_str()); + } } void Machine::set_rom(std::vector data) @@ -65,12 +73,22 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin *value = _ram[address]; else { - if(address >= 0x9800) update_video(); + if(address >= 0x9800) { update_video(); _typer_delay = 0; } _ram[address] = *value; } } } +// if(_typer && operation == CPU6502::BusOperation::ReadOpcode && address == 0xEE22) +// { +// if(!_typer->type_next_character()) +// _typer.reset(); +// } + if(_typer) + { + _typer->update(1); + } + _via.run_for_cycles(1); _cycles_since_video_update++; return 1; @@ -152,6 +170,91 @@ void Machine::run_for_cycles(int number_of_cycles) CPU6502::Processor::run_for_cycles(number_of_cycles); } +#pragma mark - Automatic typing + +bool Machine::typer_set_next_character(::Utility::Typer *typer, char character, int phase) +{ + if(!phase) clear_all_keys(); + + // The following table is arranged in ASCII order + Key key_sequences[][3] = { + {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, + {KeyDelete, TerminateSequence}, + {NotMapped}, + {KeyReturn, TerminateSequence}, + {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, + {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, + {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, + {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, + {NotMapped}, {NotMapped}, {NotMapped}, {NotMapped}, + + {KeySpace, TerminateSequence}, // space + + {KeyLeftShift, Key1, TerminateSequence}, {KeyLeftShift, KeyQuote, TerminateSequence}, // !, " + {KeyLeftShift, Key3, TerminateSequence}, {KeyLeftShift, Key4, TerminateSequence}, // #, $ + {KeyLeftShift, Key5, TerminateSequence}, {KeyLeftShift, Key7, TerminateSequence}, // %, & + {KeyQuote, TerminateSequence}, {KeyLeftShift, Key9, TerminateSequence}, // ', ( + {KeyLeftShift, Key0, TerminateSequence}, {KeyLeftShift, Key8, TerminateSequence}, // ), * + {KeyLeftShift, KeyEquals, TerminateSequence}, {KeyComma, TerminateSequence}, // +, , + {KeyMinus, TerminateSequence}, {KeyFullStop, TerminateSequence}, // -, . + {KeyForwardSlash, TerminateSequence}, // / + + {Key0, TerminateSequence}, {Key1, TerminateSequence}, // 0, 1 + {Key2, TerminateSequence}, {Key3, TerminateSequence}, // 2, 3 + {Key4, TerminateSequence}, {Key5, TerminateSequence}, // 4, 5 + {Key6, TerminateSequence}, {Key7, TerminateSequence}, // 6, 7 + {Key8, TerminateSequence}, {Key9, TerminateSequence}, // 8, 9 + + {KeyLeftShift, KeySemiColon, TerminateSequence}, {KeySemiColon, TerminateSequence}, // :, ; + {KeyLeftShift, KeyComma, TerminateSequence}, {KeyEquals, TerminateSequence}, // <, = + {KeyLeftShift, KeyFullStop, TerminateSequence}, {KeyLeftShift, KeyForwardSlash, TerminateSequence}, // >, ? + {KeyLeftShift, Key2, TerminateSequence}, // @ + + {KeyLeftShift, KeyA, TerminateSequence}, {KeyLeftShift, KeyB, TerminateSequence}, {KeyLeftShift, KeyC, TerminateSequence}, {KeyLeftShift, KeyD, TerminateSequence}, // A, B, C, D + {KeyLeftShift, KeyE, TerminateSequence}, {KeyLeftShift, KeyF, TerminateSequence}, {KeyLeftShift, KeyG, TerminateSequence}, {KeyLeftShift, KeyH, TerminateSequence}, // E, F, G, H + {KeyLeftShift, KeyI, TerminateSequence}, {KeyLeftShift, KeyJ, TerminateSequence}, {KeyLeftShift, KeyK, TerminateSequence}, {KeyLeftShift, KeyL, TerminateSequence}, // I, J, K L + {KeyLeftShift, KeyM, TerminateSequence}, {KeyLeftShift, KeyN, TerminateSequence}, {KeyLeftShift, KeyO, TerminateSequence}, {KeyLeftShift, KeyP, TerminateSequence}, // M, N, O, P + {KeyLeftShift, KeyQ, TerminateSequence}, {KeyLeftShift, KeyR, TerminateSequence}, {KeyLeftShift, KeyS, TerminateSequence}, {KeyLeftShift, KeyT, TerminateSequence}, // Q, R, S, T + {KeyLeftShift, KeyU, TerminateSequence}, {KeyLeftShift, KeyV, TerminateSequence}, {KeyLeftShift, KeyW, TerminateSequence}, {KeyLeftShift, KeyX, TerminateSequence}, // U, V, W X + {KeyLeftShift, KeyY, TerminateSequence}, {KeyLeftShift, KeyZ, TerminateSequence}, // Y, Z + + {KeyOpenSquare, TerminateSequence}, {KeyBackSlash, TerminateSequence}, // [, '\' + {KeyCloseSquare, TerminateSequence}, {KeyLeftShift, Key6, TerminateSequence}, // ], ^ + {NotMapped}, {NotMapped}, // _, ` + + {KeyA, TerminateSequence}, {KeyB, TerminateSequence}, {KeyC, TerminateSequence}, {KeyD, TerminateSequence}, // A, B, C, D + {KeyE, TerminateSequence}, {KeyF, TerminateSequence}, {KeyG, TerminateSequence}, {KeyH, TerminateSequence}, // E, F, G, H + {KeyI, TerminateSequence}, {KeyJ, TerminateSequence}, {KeyK, TerminateSequence}, {KeyL, TerminateSequence}, // I, J, K L + {KeyM, TerminateSequence}, {KeyN, TerminateSequence}, {KeyO, TerminateSequence}, {KeyP, TerminateSequence}, // M, N, O, P + {KeyQ, TerminateSequence}, {KeyR, TerminateSequence}, {KeyS, TerminateSequence}, {KeyT, TerminateSequence}, // Q, R, S, T + {KeyU, TerminateSequence}, {KeyV, TerminateSequence}, {KeyW, TerminateSequence}, {KeyX, TerminateSequence}, // U, V, W X + {KeyY, TerminateSequence}, {KeyZ, TerminateSequence}, // Y, Z + + {KeyLeftShift, KeyOpenSquare, TerminateSequence}, {KeyLeftShift, KeyBackSlash, TerminateSequence}, // {, | + {KeyLeftShift, KeyCloseSquare, TerminateSequence}, // }, ~ + }; + Key *key_sequence = nullptr; + + character &= 0x7f; + if(character < sizeof(key_sequences) / sizeof(*key_sequences)) + { + key_sequence = key_sequences[character]; + + if(key_sequence[0] != NotMapped) + { + if(phase) + { + set_key_state(key_sequence[phase-1], true); + return key_sequence[phase] == TerminateSequence; + } + else + return false; + } + } + + return true; +} + #pragma mark - The 6522 Machine::VIA::VIA() : MOS::MOS6522(), _cycles_since_ay_update(0) {} diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index c84d189d1..b768c8ed9 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -9,17 +9,18 @@ #ifndef Oric_hpp #define Oric_hpp -#include "../../Processors/6502/CPU6502.hpp" -#include "../../Components/6522/6522.hpp" -#include "../../Components/AY38910/AY38910.hpp" -#include "../../Storage/Tape/Tape.hpp" - #include "../ConfigurationTarget.hpp" #include "../CRTMachine.hpp" #include "../Typer.hpp" +#include "../../Processors/6502/CPU6502.hpp" +#include "../../Components/6522/6522.hpp" +#include "../../Components/AY38910/AY38910.hpp" + #include "Video.hpp" +#include "../../Storage/Tape/Tape.hpp" + #include #include #include @@ -45,6 +46,8 @@ enum Key: uint16_t { KeyForwardSlash = 0x0700 | 0x08, Key0 = 0x0700 | 0x04, KeyL = 0x0700 | 0x02, Key8 = 0x0700 | 0x01, KeyNMI = 0xffff, + + TerminateSequence = 0xfffe, NotMapped = 0xfffc }; class Machine: @@ -52,6 +55,7 @@ class Machine: public CRTMachine::Machine, public ConfigurationTarget::Machine, public MOS::MOS6522IRQDelegate::Delegate, + public Utility::TypeRecipient, public Storage::Tape::BinaryTapePlayer::Delegate { public: @@ -83,6 +87,11 @@ class Machine: // to satisfy Storage::Tape::BinaryTapePlayer::Delegate void tape_did_change_input(Storage::Tape::BinaryTapePlayer *tape_player); + // for Utility::TypeRecipient + virtual bool typer_set_next_character(Utility::Typer *typer, char character, int phase); + virtual int get_typer_delay() { return _typer_delay; } + virtual int get_typer_frequency() { return 40000; } + private: // RAM and ROM uint8_t _ram[65536], _rom[16384]; @@ -98,6 +107,7 @@ class Machine: uint8_t row; uint8_t rows[8]; }; + int _typer_delay; // The tape class TapePlayer: public Storage::Tape::BinaryTapePlayer { diff --git a/Machines/Typer.hpp b/Machines/Typer.hpp index b85a689e4..229c5dd05 100644 --- a/Machines/Typer.hpp +++ b/Machines/Typer.hpp @@ -42,8 +42,8 @@ class TypeRecipient: public Typer::Delegate { } protected: - virtual int get_typer_delay() = 0; - virtual int get_typer_frequency() = 0; + virtual int get_typer_delay() { return 0; } + virtual int get_typer_frequency() { return 0; } std::unique_ptr _typer; }; diff --git a/StaticAnalyser/Oric/StaticAnalyser.cpp b/StaticAnalyser/Oric/StaticAnalyser.cpp index e99798690..295e92149 100644 --- a/StaticAnalyser/Oric/StaticAnalyser.cpp +++ b/StaticAnalyser/Oric/StaticAnalyser.cpp @@ -24,5 +24,6 @@ void StaticAnalyser::Oric::AddTargets( target.disks = disks; target.tapes = tapes; target.cartridges = cartridges; + target.loadingCommand = "CLOAD\"\"\n"; destination.push_back(target); } From a7e4c0c3b523d4e718730b15f6f40fe3e7465e5e Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Thu, 3 Nov 2016 22:21:05 -0400 Subject: [PATCH 2/2] Switched to a ROM trap for typing. --- Machines/Oric/Oric.cpp | 9 ++------- Machines/Oric/Oric.hpp | 2 -- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/Machines/Oric/Oric.cpp b/Machines/Oric/Oric.cpp index 8ecc51ce6..05aed5902 100644 --- a/Machines/Oric/Oric.cpp +++ b/Machines/Oric/Oric.cpp @@ -79,14 +79,9 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin } } -// if(_typer && operation == CPU6502::BusOperation::ReadOpcode && address == 0xEE22) -// { -// if(!_typer->type_next_character()) -// _typer.reset(); -// } - if(_typer) + if(_typer && operation == CPU6502::BusOperation::ReadOpcode && address == 0xF495) { - _typer->update(1); + if(!_typer->type_next_character()) _typer.reset(); } _via.run_for_cycles(1); diff --git a/Machines/Oric/Oric.hpp b/Machines/Oric/Oric.hpp index b768c8ed9..697dfe706 100644 --- a/Machines/Oric/Oric.hpp +++ b/Machines/Oric/Oric.hpp @@ -89,8 +89,6 @@ class Machine: // for Utility::TypeRecipient virtual bool typer_set_next_character(Utility::Typer *typer, char character, int phase); - virtual int get_typer_delay() { return _typer_delay; } - virtual int get_typer_frequency() { return 40000; } private: // RAM and ROM