mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 16:31:31 +00:00
Merge pull request #438 from TomHarte/OricTyper
Corrects Oric text pasting.
This commit is contained in:
commit
72e07d4e83
@ -13,6 +13,7 @@
|
||||
#include "../CRTMachine.hpp"
|
||||
#include "../KeyboardMachine.hpp"
|
||||
#include "../Utility/MemoryFuzzer.hpp"
|
||||
#include "../Utility/StringSerialiser.hpp"
|
||||
|
||||
#include "../../Processors/6502/6502.hpp"
|
||||
#include "../../Components/AudioToggle/AudioToggle.hpp"
|
||||
@ -118,8 +119,7 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
// MARK - typing
|
||||
std::string input_string_;
|
||||
std::size_t input_string_pointer_ = std::numeric_limits<std::size_t>::max();
|
||||
std::unique_ptr<Utility::StringSerialiser> string_serialiser_;
|
||||
|
||||
public:
|
||||
ConcreteMachine():
|
||||
@ -201,8 +201,8 @@ class ConcreteMachine:
|
||||
default: break;
|
||||
|
||||
case 0xc000:
|
||||
if(input_string_pointer_ != std::numeric_limits<std::size_t>::max()) {
|
||||
*value = static_cast<uint8_t>(input_string_[input_string_pointer_]) | 0x80;
|
||||
if(string_serialiser_) {
|
||||
*value = string_serialiser_->head() | 0x80;
|
||||
} else {
|
||||
*value = keyboard_input_;
|
||||
}
|
||||
@ -225,10 +225,9 @@ class ConcreteMachine:
|
||||
|
||||
case 0xc010:
|
||||
keyboard_input_ &= 0x7f;
|
||||
if(input_string_pointer_ != std::numeric_limits<std::size_t>::max()) {
|
||||
++input_string_pointer_;
|
||||
if(input_string_pointer_ == input_string_.size())
|
||||
input_string_pointer_ = std::numeric_limits<std::size_t>::max();
|
||||
if(string_serialiser_) {
|
||||
if(!string_serialiser_->advance())
|
||||
string_serialiser_.reset();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -361,22 +360,7 @@ class ConcreteMachine:
|
||||
}
|
||||
|
||||
void type_string(const std::string &string) override {
|
||||
input_string_.clear();
|
||||
input_string_.reserve(string.size());
|
||||
|
||||
// Commute any \ns that are not immediately after \rs to \rs; remove the rest.
|
||||
bool saw_carriage_return = false;
|
||||
for(auto character: string) {
|
||||
if(character != '\n') {
|
||||
input_string_.push_back(character);
|
||||
} else {
|
||||
if(!saw_carriage_return) {
|
||||
input_string_.push_back('\r');
|
||||
}
|
||||
}
|
||||
saw_carriage_return = character == '\r';
|
||||
}
|
||||
input_string_pointer_ = 0;
|
||||
string_serialiser_.reset(new Utility::StringSerialiser(string, true));
|
||||
}
|
||||
|
||||
// MARK: ConfigurationTarget
|
||||
|
@ -659,7 +659,7 @@ class ConcreteMachine:
|
||||
|
||||
user_port_via_.run_for(Cycles(1));
|
||||
keyboard_via_.run_for(Cycles(1));
|
||||
if(typer_ && operation == CPU::MOS6502::BusOperation::ReadOpcode && address == 0xEB1E) {
|
||||
if(typer_ && address == 0xeb1e && operation == CPU::MOS6502::BusOperation::ReadOpcode) {
|
||||
if(!typer_->type_next_character()) {
|
||||
clear_all_keys();
|
||||
typer_.reset();
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "../KeyboardMachine.hpp"
|
||||
|
||||
#include "../Utility/MemoryFuzzer.hpp"
|
||||
#include "../Utility/Typer.hpp"
|
||||
#include "../Utility/StringSerialiser.hpp"
|
||||
|
||||
#include "../../Processors/6502/6502.hpp"
|
||||
#include "../../Components/6522/6522.hpp"
|
||||
@ -305,13 +305,11 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
||||
switch(rom_type_) {
|
||||
case Analyser::Static::Oric::Target::ROM::BASIC10:
|
||||
tape_get_byte_address_ = 0xe630;
|
||||
scan_keyboard_address_ = 0xf43c;
|
||||
tape_speed_address_ = 0x67;
|
||||
break;
|
||||
case Analyser::Static::Oric::Target::ROM::BASIC11:
|
||||
case Analyser::Static::Oric::Target::ROM::Pravetz:
|
||||
tape_get_byte_address_ = 0xe6c9;
|
||||
scan_keyboard_address_ = 0xf495;
|
||||
tape_speed_address_ = 0x024d;
|
||||
break;
|
||||
}
|
||||
@ -424,14 +422,13 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
||||
}
|
||||
}
|
||||
|
||||
if(typer_ && address == scan_keyboard_address_ && operation == CPU::MOS6502::BusOperation::ReadOpcode) {
|
||||
// the Oric 1 misses any key pressed on the very first entry into the read keyboard routine, so don't
|
||||
// do anything until at least the second, regardless of machine
|
||||
if(!keyboard_read_count_) keyboard_read_count_++;
|
||||
else if(!typer_->type_next_character()) {
|
||||
clear_all_keys();
|
||||
typer_.reset();
|
||||
}
|
||||
// $02df is where the Oric ROMs — all of them, including BASIC 1.0, 1.1 and the Pravetz — have the
|
||||
// IRQ routine store an incoming keystroke in order for reading to occur later. By capturing the
|
||||
// read rather than the decode and write: (i) nothing is lost while BASIC is parsing; and
|
||||
// (ii) keyboard input is much more rapid.
|
||||
if(string_serialiser_ && address == 0x02df && operation == CPU::MOS6502::BusOperation::Read) {
|
||||
*value = string_serialiser_->head() | 0x80;
|
||||
if(!string_serialiser_->advance()) string_serialiser_.reset();
|
||||
}
|
||||
|
||||
via_.run_for(Cycles(1));
|
||||
@ -490,8 +487,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
||||
|
||||
// for Utility::TypeRecipient::Delegate
|
||||
void type_string(const std::string &string) override final {
|
||||
std::unique_ptr<CharacterMapper> mapper(new CharacterMapper);
|
||||
Utility::TypeRecipient::add_typer(string, std::move(mapper));
|
||||
string_serialiser_.reset(new Utility::StringSerialiser(string, true));
|
||||
}
|
||||
|
||||
// for Microdisc::Delegate
|
||||
@ -581,7 +577,7 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
||||
}
|
||||
|
||||
// ROM bookkeeping
|
||||
uint16_t tape_get_byte_address_ = 0, scan_keyboard_address_ = 0, tape_speed_address_ = 0;
|
||||
uint16_t tape_get_byte_address_ = 0, tape_speed_address_ = 0;
|
||||
int keyboard_read_count_ = 0;
|
||||
|
||||
// Outputs
|
||||
@ -625,6 +621,9 @@ template <Analyser::Static::Oric::Target::DiskInterface disk_interface> class Co
|
||||
irq_line |= microdisc_.get_interrupt_request_line();
|
||||
m6502_.set_irq_line(irq_line);
|
||||
}
|
||||
|
||||
// MARK - typing
|
||||
std::unique_ptr<Utility::StringSerialiser> string_serialiser_;
|
||||
};
|
||||
|
||||
}
|
||||
|
46
Machines/Utility/StringSerialiser.cpp
Normal file
46
Machines/Utility/StringSerialiser.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// StringSerialiser.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 13/05/2018.
|
||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "StringSerialiser.hpp"
|
||||
|
||||
using namespace Utility;
|
||||
|
||||
StringSerialiser::StringSerialiser(const std::string &source, bool use_linefeed_only) {
|
||||
if(!use_linefeed_only) {
|
||||
input_string_ = source;
|
||||
} else {
|
||||
input_string_.reserve(source.size());
|
||||
|
||||
// Commute any \ns that are not immediately after \rs to \rs; remove the rest.
|
||||
bool saw_carriage_return = false;
|
||||
for(auto character: source) {
|
||||
if(character != '\n') {
|
||||
input_string_.push_back(character);
|
||||
} else {
|
||||
if(!saw_carriage_return) {
|
||||
input_string_.push_back('\r');
|
||||
}
|
||||
}
|
||||
saw_carriage_return = character == '\r';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t StringSerialiser::head() {
|
||||
if(input_string_pointer_ == input_string_.size())
|
||||
return '\0';
|
||||
return static_cast<uint8_t>(input_string_[input_string_pointer_]);
|
||||
}
|
||||
|
||||
bool StringSerialiser::advance() {
|
||||
if(input_string_pointer_ != input_string_.size()) {
|
||||
++input_string_pointer_;
|
||||
return input_string_pointer_ != input_string_.size();
|
||||
}
|
||||
return false;
|
||||
}
|
30
Machines/Utility/StringSerialiser.hpp
Normal file
30
Machines/Utility/StringSerialiser.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
//
|
||||
// StringSerialiser.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 13/05/2018.
|
||||
// Copyright © 2018 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef StringSerialiser_hpp
|
||||
#define StringSerialiser_hpp
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Utility {
|
||||
|
||||
class StringSerialiser {
|
||||
public:
|
||||
StringSerialiser(const std::string &source, bool use_linefeed_only = false);
|
||||
|
||||
uint8_t head();
|
||||
bool advance();
|
||||
|
||||
private:
|
||||
std::string input_string_;
|
||||
std::size_t input_string_pointer_ = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* StringSerialiser_hpp */
|
@ -140,6 +140,8 @@
|
||||
4B15AA0E2082C799005E6C8D /* Video.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B15AA0A2082C799005E6C8D /* Video.cpp */; };
|
||||
4B15AA0F2082C799005E6C8D /* AppleII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B15AA0C2082C799005E6C8D /* AppleII.cpp */; };
|
||||
4B15AA102082C799005E6C8D /* AppleII.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B15AA0C2082C799005E6C8D /* AppleII.cpp */; };
|
||||
4B17B58B20A8A9D9007CCA8F /* StringSerialiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B17B58920A8A9D9007CCA8F /* StringSerialiser.cpp */; };
|
||||
4B17B58C20A8A9D9007CCA8F /* StringSerialiser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B17B58920A8A9D9007CCA8F /* StringSerialiser.cpp */; };
|
||||
4B1B88BB202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */; };
|
||||
4B1B88BC202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */; };
|
||||
4B1B88BD202E3D3D00B67DFF /* MultiMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FCC3F201EC24200960631 /* MultiMachine.cpp */; };
|
||||
@ -740,6 +742,8 @@
|
||||
4B1667F91FFF215E00A16032 /* ASCII16kb.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ASCII16kb.hpp; path = MSX/Cartridges/ASCII16kb.hpp; sourceTree = "<group>"; };
|
||||
4B1667FA1FFF215E00A16032 /* ASCII8kb.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ASCII8kb.hpp; path = MSX/Cartridges/ASCII8kb.hpp; sourceTree = "<group>"; };
|
||||
4B1667FB1FFF215F00A16032 /* KonamiWithSCC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = KonamiWithSCC.hpp; path = MSX/Cartridges/KonamiWithSCC.hpp; sourceTree = "<group>"; };
|
||||
4B17B58920A8A9D9007CCA8F /* StringSerialiser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StringSerialiser.cpp; sourceTree = "<group>"; };
|
||||
4B17B58A20A8A9D9007CCA8F /* StringSerialiser.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = StringSerialiser.hpp; sourceTree = "<group>"; };
|
||||
4B1B88B9202E2EC100B67DFF /* MultiKeyboardMachine.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiKeyboardMachine.cpp; sourceTree = "<group>"; };
|
||||
4B1B88BA202E2EC100B67DFF /* MultiKeyboardMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MultiKeyboardMachine.hpp; sourceTree = "<group>"; };
|
||||
4B1B88BE202E3DB200B67DFF /* MultiConfigurable.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MultiConfigurable.cpp; sourceTree = "<group>"; };
|
||||
@ -1674,6 +1678,8 @@
|
||||
4B2B3A491F9B8FA70062DABF /* MemoryFuzzer.hpp */,
|
||||
4B2B3A4A1F9B8FA70062DABF /* Typer.hpp */,
|
||||
4B79A4FE1FC9082300EEDAD5 /* TypedDynamicMachine.hpp */,
|
||||
4B17B58920A8A9D9007CCA8F /* StringSerialiser.cpp */,
|
||||
4B17B58A20A8A9D9007CCA8F /* StringSerialiser.hpp */,
|
||||
);
|
||||
path = Utility;
|
||||
sourceTree = "<group>";
|
||||
@ -3672,6 +3678,7 @@
|
||||
4B15AA102082C799005E6C8D /* AppleII.cpp in Sources */,
|
||||
4B055AA91FAE85EF0060FFFF /* CommodoreGCR.cpp in Sources */,
|
||||
4B055ADB1FAE9B460060FFFF /* 6560.cpp in Sources */,
|
||||
4B17B58C20A8A9D9007CCA8F /* StringSerialiser.cpp in Sources */,
|
||||
4B055AA01FAE85DA0060FFFF /* MFMSectorDump.cpp in Sources */,
|
||||
4BEBFB522002DB30000708CC /* DiskROM.cpp in Sources */,
|
||||
4B055AA11FAE85DA0060FFFF /* OricMFMDSK.cpp in Sources */,
|
||||
@ -3838,6 +3845,7 @@
|
||||
4B2B3A4B1F9B8FA70062DABF /* Typer.cpp in Sources */,
|
||||
4B4518821F75E91A00926311 /* PCMSegment.cpp in Sources */,
|
||||
4B894522201967B4007DE474 /* StaticAnalyser.cpp in Sources */,
|
||||
4B17B58B20A8A9D9007CCA8F /* StringSerialiser.cpp in Sources */,
|
||||
4BE7C9181E3D397100A5496D /* TIA.cpp in Sources */,
|
||||
4B80AD001F85CACA00176895 /* BestEffortUpdater.cpp in Sources */,
|
||||
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */,
|
||||
|
Loading…
Reference in New Issue
Block a user