mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-28 07:29:45 +00:00
Merge pull request #24 from TomHarte/RAMPRGs
Adds a check for whether PRGs should be loaded to RAM and, if so, installs them post-boot and performs a 'RUN'
This commit is contained in:
commit
ee050d71ec
58
Machines/Typer.cpp
Normal file
58
Machines/Typer.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
//
|
||||||
|
// Typer.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 19/06/2016.
|
||||||
|
// Copyright © 2016 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Typer.hpp"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
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), _phase(0) {}
|
||||||
|
|
||||||
|
void Typer::update(int duration)
|
||||||
|
{
|
||||||
|
if(_string)
|
||||||
|
{
|
||||||
|
if(_counter < 0 && _counter + duration >= 0)
|
||||||
|
{
|
||||||
|
type_next_character();
|
||||||
|
}
|
||||||
|
|
||||||
|
_counter += duration;
|
||||||
|
while(_counter > _frequency)
|
||||||
|
{
|
||||||
|
_counter -= _frequency;
|
||||||
|
type_next_character();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Typer::type_next_character()
|
||||||
|
{
|
||||||
|
if(_delegate->typer_set_next_character(this, _string[_string_pointer], _phase))
|
||||||
|
{
|
||||||
|
_phase = 0;
|
||||||
|
if(!_string[_string_pointer])
|
||||||
|
{
|
||||||
|
free(_string);
|
||||||
|
_string = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_string_pointer++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_phase++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Typer::~Typer()
|
||||||
|
{
|
||||||
|
free(_string);
|
||||||
|
}
|
53
Machines/Typer.hpp
Normal file
53
Machines/Typer.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// 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 <memory>
|
||||||
|
|
||||||
|
namespace Utility {
|
||||||
|
|
||||||
|
class Typer {
|
||||||
|
public:
|
||||||
|
class Delegate {
|
||||||
|
public:
|
||||||
|
virtual bool typer_set_next_character(Typer *typer, char character, int phase) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Typer(const char *string, int delay, int frequency, Delegate *delegate);
|
||||||
|
~Typer();
|
||||||
|
void update(int duration);
|
||||||
|
|
||||||
|
private:
|
||||||
|
char *_string;
|
||||||
|
int _frequency;
|
||||||
|
int _counter;
|
||||||
|
int _phase;
|
||||||
|
Delegate *_delegate;
|
||||||
|
size_t _string_pointer;
|
||||||
|
|
||||||
|
void type_next_character();
|
||||||
|
};
|
||||||
|
|
||||||
|
class TypeRecipient: public Typer::Delegate {
|
||||||
|
public:
|
||||||
|
void set_typer_for_string(const char *string)
|
||||||
|
{
|
||||||
|
_typer = std::unique_ptr<Typer>(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> _typer;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* Typer_hpp */
|
@ -81,6 +81,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
|
|||||||
|
|
||||||
_userPortVIA.run_for_half_cycles(2);
|
_userPortVIA.run_for_half_cycles(2);
|
||||||
_keyboardVIA.run_for_half_cycles(2);
|
_keyboardVIA.run_for_half_cycles(2);
|
||||||
|
if(_typer) _typer->update(1);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,12 +126,125 @@ void Machine::add_prg(size_t length, const uint8_t *data)
|
|||||||
_rom_length = (uint16_t)(length - 2);
|
_rom_length = (uint16_t)(length - 2);
|
||||||
if(_rom_address >= 0x1000 && _rom_address+_rom_length < 0x2000)
|
if(_rom_address >= 0x1000 && _rom_address+_rom_length < 0x2000)
|
||||||
{
|
{
|
||||||
memcpy(&_screenMemory[_rom_address - 0x1000], &data[2], length - 2);
|
set_typer_for_string("RUN\n");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_rom = new uint8_t[length - 2];
|
|
||||||
memcpy(_rom, &data[2], length - 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_rom = new uint8_t[length - 2];
|
||||||
|
memcpy(_rom, &data[2], length - 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Typer
|
||||||
|
|
||||||
|
int Machine::get_typer_delay()
|
||||||
|
{
|
||||||
|
return get_reset_line() ? 1*263*60*65 : 0; // wait two seconds if resetting
|
||||||
|
}
|
||||||
|
|
||||||
|
int Machine::get_typer_frequency()
|
||||||
|
{
|
||||||
|
return 2*263*65; // accept a new character every two fields
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Machine::typer_set_next_character(::Utility::Typer *typer, char character, int phase)
|
||||||
|
{
|
||||||
|
// If there's a 'ROM' installed that can never be accessed, assume that this typing was scheduled because
|
||||||
|
// it should be in RAM. So copy it there.
|
||||||
|
if(_rom && _rom_address >= 0x1000 && _rom_address+_rom_length < 0x2000)
|
||||||
|
{
|
||||||
|
memcpy(&_screenMemory[_rom_address - 0x1000], _rom, _rom_length);
|
||||||
|
delete[] _rom;
|
||||||
|
_rom = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
{KeyLShift, Key1, TerminateSequence}, {KeyLShift, Key2, TerminateSequence}, // !, "
|
||||||
|
{KeyLShift, Key3, TerminateSequence}, {KeyLShift, Key4, TerminateSequence}, // #, $
|
||||||
|
{KeyLShift, Key5, TerminateSequence}, {KeyLShift, Key6, TerminateSequence}, // %, &
|
||||||
|
{KeyLShift, Key7, TerminateSequence}, {KeyLShift, Key8, TerminateSequence}, // ', (
|
||||||
|
{KeyLShift, Key9, TerminateSequence}, {KeyAsterisk, TerminateSequence}, // ), *
|
||||||
|
{KeyPlus, TerminateSequence}, {KeyComma, TerminateSequence}, // +, ,
|
||||||
|
{KeyDash, TerminateSequence}, {KeyFullStop, TerminateSequence}, // -, .
|
||||||
|
{KeySlash, 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
|
||||||
|
|
||||||
|
{KeyColon, TerminateSequence}, {KeySemicolon, TerminateSequence}, // :, ;
|
||||||
|
{KeyLShift, KeyComma, TerminateSequence}, {KeyEquals, TerminateSequence}, // <, =
|
||||||
|
{KeyLShift, KeyFullStop, TerminateSequence}, {KeyLShift, KeySlash, TerminateSequence}, // >, ?
|
||||||
|
{KeyAt, TerminateSequence}, // @
|
||||||
|
|
||||||
|
{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
|
||||||
|
|
||||||
|
{KeyLShift, KeyColon, TerminateSequence}, {NotMapped}, // [, '\'
|
||||||
|
{KeyLShift, KeyFullStop, TerminateSequence}, {NotMapped}, // ], ^
|
||||||
|
{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
|
||||||
|
// {KeyLShift, KeyA, TerminateSequence}, {KeyLShift, KeyB, TerminateSequence}, // a, b
|
||||||
|
// {KeyLShift, KeyC, TerminateSequence}, {KeyLShift, KeyD, TerminateSequence}, // c, d
|
||||||
|
// {KeyLShift, KeyE, TerminateSequence}, {KeyLShift, KeyF, TerminateSequence}, // e, f
|
||||||
|
// {KeyLShift, KeyG, TerminateSequence}, {KeyLShift, KeyH, TerminateSequence}, // g, h
|
||||||
|
// {KeyLShift, KeyI, TerminateSequence}, {KeyLShift, KeyJ, TerminateSequence}, // i, j
|
||||||
|
// {KeyLShift, KeyK, TerminateSequence}, {KeyLShift, KeyL, TerminateSequence}, // k, l
|
||||||
|
// {KeyLShift, KeyM, TerminateSequence}, {KeyLShift, KeyN, TerminateSequence}, // m, n
|
||||||
|
// {KeyLShift, KeyO, TerminateSequence}, {KeyLShift, KeyP, TerminateSequence}, // o, p
|
||||||
|
// {KeyLShift, KeyQ, TerminateSequence}, {KeyLShift, KeyR, TerminateSequence}, // q, r
|
||||||
|
// {KeyLShift, KeyS, TerminateSequence}, {KeyLShift, KeyT, TerminateSequence}, // s, t
|
||||||
|
// {KeyLShift, KeyU, TerminateSequence}, {KeyLShift, KeyV, TerminateSequence}, // u, v
|
||||||
|
// {KeyLShift, KeyW, TerminateSequence}, {KeyLShift, KeyX, TerminateSequence}, // w, x
|
||||||
|
// {KeyLShift, KeyY, TerminateSequence}, {KeyLShift, KeyZ, TerminateSequence}, // y, z
|
||||||
|
|
||||||
|
};
|
||||||
|
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 > 0)
|
||||||
|
{
|
||||||
|
set_key_state(key_sequence[phase-1], true);
|
||||||
|
return key_sequence[phase] == TerminateSequence;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
#include "../../Processors/6502/CPU6502.hpp"
|
#include "../../Processors/6502/CPU6502.hpp"
|
||||||
#include "../../Components/6560/6560.hpp"
|
#include "../../Components/6560/6560.hpp"
|
||||||
#include "../../Components/6522/6522.hpp"
|
#include "../../Components/6522/6522.hpp"
|
||||||
|
|
||||||
#include "../CRTMachine.hpp"
|
#include "../CRTMachine.hpp"
|
||||||
|
#include "../Typer.hpp"
|
||||||
|
|
||||||
namespace Vic20 {
|
namespace Vic20 {
|
||||||
|
|
||||||
@ -42,6 +44,8 @@ enum Key: uint16_t {
|
|||||||
KeyI = key(1, 0x10), KeyP = key(1, 0x20), KeyAsterisk = key(1, 0x40), KeyReturn = key(1, 0x80),
|
KeyI = key(1, 0x10), KeyP = key(1, 0x20), KeyAsterisk = key(1, 0x40), KeyReturn = key(1, 0x80),
|
||||||
Key1 = key(0, 0x01), Key3 = key(0, 0x02), Key5 = key(0, 0x04), Key7 = key(0, 0x08),
|
Key1 = key(0, 0x01), Key3 = key(0, 0x02), Key5 = key(0, 0x04), Key7 = key(0, 0x08),
|
||||||
Key9 = key(0, 0x10), KeyPlus = key(0, 0x20), KeyGBP = key(0, 0x40), KeyDelete = key(0, 0x80),
|
Key9 = key(0, 0x10), KeyPlus = key(0, 0x20), KeyGBP = key(0, 0x40), KeyDelete = key(0, 0x80),
|
||||||
|
|
||||||
|
TerminateSequence = 0, NotMapped = 0xffff
|
||||||
};
|
};
|
||||||
|
|
||||||
class UserPortVIA: public MOS::MOS6522<UserPortVIA>, public MOS::MOS6522IRQDelegate {
|
class UserPortVIA: public MOS::MOS6522<UserPortVIA>, public MOS::MOS6522IRQDelegate {
|
||||||
@ -88,7 +92,12 @@ class KeyboardVIA: public MOS::MOS6522<KeyboardVIA>, public MOS::MOS6522IRQDeleg
|
|||||||
uint8_t _activation_mask;
|
uint8_t _activation_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine, public MOS::MOS6522IRQDelegate::Delegate {
|
class Machine:
|
||||||
|
public CPU6502::Processor<Machine>,
|
||||||
|
public CRTMachine::Machine,
|
||||||
|
public MOS::MOS6522IRQDelegate::Delegate,
|
||||||
|
public Utility::TypeRecipient {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Machine();
|
Machine();
|
||||||
~Machine();
|
~Machine();
|
||||||
@ -114,6 +123,11 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine, p
|
|||||||
// to satisfy MOS::MOS6522::Delegate
|
// to satisfy MOS::MOS6522::Delegate
|
||||||
virtual void mos6522_did_change_interrupt_status(void *mos6522);
|
virtual void mos6522_did_change_interrupt_status(void *mos6522);
|
||||||
|
|
||||||
|
// for Utility::TypeRecipient
|
||||||
|
virtual int get_typer_delay();
|
||||||
|
virtual int get_typer_frequency();
|
||||||
|
virtual bool typer_set_next_character(Utility::Typer *typer, char character, int phase);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _characterROM[0x1000];
|
uint8_t _characterROM[0x1000];
|
||||||
uint8_t _basicROM[0x2000];
|
uint8_t _basicROM[0x2000];
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
4B14145E1B5887AA00E04248 /* CPU6502AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414591B58879D00E04248 /* CPU6502AllRAM.cpp */; };
|
4B14145E1B5887AA00E04248 /* CPU6502AllRAM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414591B58879D00E04248 /* CPU6502AllRAM.cpp */; };
|
||||||
4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */; };
|
4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */; };
|
||||||
4B1414621B58888700E04248 /* KlausDormannTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414611B58888700E04248 /* KlausDormannTests.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 */; };
|
4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2409531C45AB05004DA684 /* Speaker.cpp */; };
|
||||||
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; };
|
4B2A539F1D117D36003C6002 /* CSAudioQueue.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53911D117D36003C6002 /* CSAudioQueue.m */; };
|
||||||
4B2A53A01D117D36003C6002 /* CSMachine.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A53961D117D36003C6002 /* CSMachine.mm */; };
|
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 = "<group>"; };
|
4B14145A1B58879D00E04248 /* CPU6502AllRAM.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CPU6502AllRAM.hpp; sourceTree = "<group>"; };
|
||||||
4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WolfgangLorenzTests.swift; sourceTree = "<group>"; };
|
4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WolfgangLorenzTests.swift; sourceTree = "<group>"; };
|
||||||
4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = "<group>"; };
|
4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = "<group>"; };
|
||||||
|
4B1E85731D170228001EF87D /* Typer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Typer.cpp; sourceTree = "<group>"; };
|
||||||
|
4B1E85741D170228001EF87D /* Typer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Typer.hpp; sourceTree = "<group>"; };
|
||||||
4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = "<group>"; };
|
4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = "<group>"; };
|
||||||
4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = "<group>"; };
|
4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = "<group>"; };
|
||||||
4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = "<group>"; };
|
4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = "<group>"; };
|
||||||
@ -1251,6 +1254,8 @@
|
|||||||
4B2E2D961C3A06EC00138695 /* Atari2600 */,
|
4B2E2D961C3A06EC00138695 /* Atari2600 */,
|
||||||
4B2E2D9E1C3A070900138695 /* Electron */,
|
4B2E2D9E1C3A070900138695 /* Electron */,
|
||||||
4B886FF61D03B632004291C3 /* Vic-20 */,
|
4B886FF61D03B632004291C3 /* Vic-20 */,
|
||||||
|
4B1E85731D170228001EF87D /* Typer.cpp */,
|
||||||
|
4B1E85741D170228001EF87D /* Typer.hpp */,
|
||||||
);
|
);
|
||||||
name = Machines;
|
name = Machines;
|
||||||
path = ../../Machines;
|
path = ../../Machines;
|
||||||
@ -1764,6 +1769,7 @@
|
|||||||
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,
|
4B69FB441C4D941400B5F0AA /* TapeUEF.cpp in Sources */,
|
||||||
4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */,
|
4BBF99141C8FBA6F0075DAFB /* CRTInputBufferBuilder.cpp in Sources */,
|
||||||
4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */,
|
4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */,
|
||||||
|
4B1E85751D170228001EF87D /* Typer.cpp in Sources */,
|
||||||
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */,
|
4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */,
|
||||||
4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */,
|
4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */,
|
||||||
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,
|
4B55CE5D1C3B7D6F0093A61B /* CSOpenGLView.m in Sources */,
|
||||||
|
@ -80,6 +80,14 @@ class MachineDocument:
|
|||||||
super.close()
|
super.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: the pasteboard
|
||||||
|
func paste(sender: AnyObject!) {
|
||||||
|
let pasteboard = NSPasteboard.generalPasteboard()
|
||||||
|
if let string = pasteboard.stringForType(NSPasteboardTypeString) {
|
||||||
|
self.machine().paste(string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: CSBestEffortUpdaterDelegate
|
// MARK: CSBestEffortUpdaterDelegate
|
||||||
final func bestEffortUpdater(bestEffortUpdater: CSBestEffortUpdater!, runForCycles cycles: UInt, didSkipPreviousUpdate: Bool) {
|
final func bestEffortUpdater(bestEffortUpdater: CSBestEffortUpdater!, runForCycles cycles: UInt, didSkipPreviousUpdate: Bool) {
|
||||||
runForNumberOfCycles(Int32(cycles))
|
runForNumberOfCycles(Int32(cycles))
|
||||||
|
@ -30,4 +30,6 @@
|
|||||||
@property (nonatomic, weak) id<CSMachineDelegate> delegate;
|
@property (nonatomic, weak) id<CSMachineDelegate> delegate;
|
||||||
@property (nonatomic, readonly) double clockRate;
|
@property (nonatomic, readonly) double clockRate;
|
||||||
|
|
||||||
|
- (void)paste:(NSString *)string;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#import "CSMachine.h"
|
#import "CSMachine.h"
|
||||||
#import "CSMachine+Subclassing.h"
|
#import "CSMachine+Subclassing.h"
|
||||||
|
#include "Typer.hpp"
|
||||||
|
|
||||||
@interface CSMachine()
|
@interface CSMachine()
|
||||||
- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
- (void)speaker:(Outputs::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length;
|
||||||
@ -92,4 +93,10 @@ struct SpeakerDelegate: public Outputs::Speaker::Delegate {
|
|||||||
return self.machine->get_clock_rate();
|
return self.machine->get_clock_rate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)paste:(NSString *)paste {
|
||||||
|
Utility::TypeRecipient *typeRecipient = dynamic_cast<Utility::TypeRecipient *>(self.machine);
|
||||||
|
if(typeRecipient)
|
||||||
|
typeRecipient->set_typer_for_string([paste UTF8String]);
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
@ -1150,6 +1150,16 @@ template <class T> class Processor {
|
|||||||
_reset_line_is_enabled = active;
|
_reset_line_is_enabled = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Gets the current level of the RST line.
|
||||||
|
|
||||||
|
@returns @c true if the line is logically active; @c false otherwise.
|
||||||
|
*/
|
||||||
|
inline bool get_reset_line()
|
||||||
|
{
|
||||||
|
return _reset_line_is_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Sets the current level of the IRQ line.
|
Sets the current level of the IRQ line.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user