mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-08 18:55:14 +00:00
Merge pull request #25 from TomHarte/ElectronTyper
Implements `Utility::TypeRecipient` for the Electron
This commit is contained in:
commit
0cbf0cf8fc
@ -447,6 +447,8 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
|
|||||||
update_audio();
|
update_audio();
|
||||||
_tape.run_for_cycles(cycles);
|
_tape.run_for_cycles(cycles);
|
||||||
|
|
||||||
|
if(_typer) _typer->update(cycles);
|
||||||
|
|
||||||
return cycles;
|
return cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1051,3 +1053,98 @@ inline void Tape::run_for_cycles(unsigned int number_of_cycles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Typer
|
||||||
|
|
||||||
|
int Machine::get_typer_delay()
|
||||||
|
{
|
||||||
|
return get_reset_line() ? 625*25*128 : 0; // wait one second if resetting
|
||||||
|
}
|
||||||
|
|
||||||
|
int Machine::get_typer_frequency()
|
||||||
|
{
|
||||||
|
return 625*128; // accept a new character every frame
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
{KeyShift, Key1, TerminateSequence}, {KeyShift, Key2, TerminateSequence}, // !, "
|
||||||
|
{KeyShift, Key3, TerminateSequence}, {KeyShift, Key4, TerminateSequence}, // #, $
|
||||||
|
{KeyShift, Key5, TerminateSequence}, {KeyShift, Key6, TerminateSequence}, // %, &
|
||||||
|
{KeyShift, Key7, TerminateSequence}, {KeyShift, Key8, TerminateSequence}, // ', (
|
||||||
|
{KeyShift, Key9, TerminateSequence}, {KeyShift, KeyColon, TerminateSequence}, // ), *
|
||||||
|
{KeyShift, KeySemiColon, TerminateSequence}, {KeyComma, TerminateSequence}, // +, ,
|
||||||
|
{KeyMinus, 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}, // :, ;
|
||||||
|
{KeyShift, KeyComma, TerminateSequence}, {KeyShift, KeyMinus, TerminateSequence}, // <, =
|
||||||
|
{KeyShift, KeyFullStop, TerminateSequence}, {KeyShift, KeySlash, TerminateSequence}, // >, ?
|
||||||
|
{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
|
||||||
|
|
||||||
|
{NotMapped}, {KeyControl, KeyRight, TerminateSequence}, // [, '\'
|
||||||
|
{NotMapped}, {KeyShift, KeyLeft, TerminateSequence}, // ], ^
|
||||||
|
{KeyShift, KeyDown, TerminateSequence}, {NotMapped}, // _, `
|
||||||
|
|
||||||
|
{KeyShift, KeyA, TerminateSequence}, {KeyShift, KeyB, TerminateSequence}, {KeyShift, KeyC, TerminateSequence}, {KeyShift, KeyD, TerminateSequence}, // a, b, c, d
|
||||||
|
{KeyShift, KeyE, TerminateSequence}, {KeyShift, KeyF, TerminateSequence}, {KeyShift, KeyG, TerminateSequence}, {KeyShift, KeyH, TerminateSequence}, // e, f, g, h
|
||||||
|
{KeyShift, KeyI, TerminateSequence}, {KeyShift, KeyJ, TerminateSequence}, {KeyShift, KeyK, TerminateSequence}, {KeyShift, KeyL, TerminateSequence}, // i, j, k, l
|
||||||
|
{KeyShift, KeyM, TerminateSequence}, {KeyShift, KeyN, TerminateSequence}, {KeyShift, KeyO, TerminateSequence}, {KeyShift, KeyP, TerminateSequence}, // m, n, o, p
|
||||||
|
{KeyShift, KeyQ, TerminateSequence}, {KeyShift, KeyR, TerminateSequence}, {KeyShift, KeyS, TerminateSequence}, {KeyShift, KeyT, TerminateSequence}, // q, r, s, t
|
||||||
|
{KeyShift, KeyU, TerminateSequence}, {KeyShift, KeyV, TerminateSequence}, {KeyShift, KeyW, TerminateSequence}, {KeyShift, KeyX, TerminateSequence}, // u, v, w, x
|
||||||
|
{KeyShift, KeyY, TerminateSequence}, {KeyShift, KeyZ, TerminateSequence}, // y, z
|
||||||
|
|
||||||
|
{KeyControl, KeyUp, TerminateSequence}, {KeyShift, KeyRight, TerminateSequence}, // {, |
|
||||||
|
{KeyControl, KeyDown, TerminateSequence}, {KeyControl, KeyLeft, 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 > 0)
|
||||||
|
{
|
||||||
|
set_key_state(key_sequence[phase-1], true);
|
||||||
|
return key_sequence[phase] == TerminateSequence;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -11,8 +11,11 @@
|
|||||||
|
|
||||||
#include "../../Processors/6502/CPU6502.hpp"
|
#include "../../Processors/6502/CPU6502.hpp"
|
||||||
#include "../../Storage/Tape/Tape.hpp"
|
#include "../../Storage/Tape/Tape.hpp"
|
||||||
|
|
||||||
#include "../CRTMachine.hpp"
|
#include "../CRTMachine.hpp"
|
||||||
#include <stdint.h>
|
#include "../Typer.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace Electron {
|
namespace Electron {
|
||||||
|
|
||||||
@ -54,7 +57,9 @@ enum Key: uint16_t {
|
|||||||
KeyZ = 0x00c0 | 0x08, KeyA = 0x00c0 | 0x04, KeyQ = 0x00c0 | 0x02, Key1 = 0x00c0 | 0x01,
|
KeyZ = 0x00c0 | 0x08, KeyA = 0x00c0 | 0x04, KeyQ = 0x00c0 | 0x02, Key1 = 0x00c0 | 0x01,
|
||||||
KeyShift = 0x00d0 | 0x08, KeyControl = 0x00d0 | 0x04, KeyFunc = 0x00d0 | 0x02, KeyEscape = 0x00d0 | 0x01,
|
KeyShift = 0x00d0 | 0x08, KeyControl = 0x00d0 | 0x04, KeyFunc = 0x00d0 | 0x02, KeyEscape = 0x00d0 | 0x01,
|
||||||
|
|
||||||
KeyBreak = 0xffff
|
KeyBreak = 0xffff,
|
||||||
|
|
||||||
|
TerminateSequence = 0, NotMapped = 0xfffe,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Tape {
|
class Tape {
|
||||||
@ -141,10 +146,13 @@ class Speaker: public ::Outputs::Filter<Speaker> {
|
|||||||
@discussion An instance of Electron::Machine represents the current state of an
|
@discussion An instance of Electron::Machine represents the current state of an
|
||||||
Acorn Electron.
|
Acorn Electron.
|
||||||
*/
|
*/
|
||||||
class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine, Tape::Delegate {
|
class Machine:
|
||||||
|
public CPU6502::Processor<Machine>,
|
||||||
|
public CRTMachine::Machine,
|
||||||
|
Tape::Delegate,
|
||||||
|
public Utility::TypeRecipient {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Machine();
|
Machine();
|
||||||
|
|
||||||
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
|
void set_rom(ROMSlot slot, size_t length, const uint8_t *data);
|
||||||
@ -170,6 +178,11 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine, T
|
|||||||
// to satisfy Tape::Delegate
|
// to satisfy Tape::Delegate
|
||||||
virtual void tape_did_change_interrupt_status(Tape *tape);
|
virtual void tape_did_change_interrupt_status(Tape *tape);
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
|
||||||
inline void update_display();
|
inline void update_display();
|
||||||
|
Loading…
Reference in New Issue
Block a user