mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-20 14:29:11 +00:00
Factors out a little of the ZX81's keyboard logic.
This commit is contained in:
parent
44240773ef
commit
c3d96b30d7
@ -192,3 +192,53 @@ const uint16_t *CharacterMapper::sequence_for_character(char character) const {
|
|||||||
bool CharacterMapper::needs_pause_after_key(uint16_t key) const {
|
bool CharacterMapper::needs_pause_after_key(uint16_t key) const {
|
||||||
return key != KeyShift;
|
return key != KeyShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Keyboard::Keyboard(bool is_zx81) : is_zx81_(is_zx81) {
|
||||||
|
clear_all_keys();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keyboard::set_key_state(uint16_t key, bool is_pressed) {
|
||||||
|
const auto line = key >> 8;
|
||||||
|
|
||||||
|
// Check for special cases.
|
||||||
|
if(line > 7) {
|
||||||
|
switch(key) {
|
||||||
|
#define ShiftedKey(source, base) \
|
||||||
|
case source: \
|
||||||
|
set_key_state(KeyShift, is_pressed); \
|
||||||
|
set_key_state(base, is_pressed); \
|
||||||
|
break;
|
||||||
|
|
||||||
|
ShiftedKey(KeyDelete, Key0);
|
||||||
|
ShiftedKey(KeyBreak, KeySpace);
|
||||||
|
ShiftedKey(KeyUp, Key7);
|
||||||
|
ShiftedKey(KeyDown, Key6);
|
||||||
|
ShiftedKey(KeyLeft, Key5);
|
||||||
|
ShiftedKey(KeyRight, Key8);
|
||||||
|
ShiftedKey(KeyEdit, is_zx81_ ? Key1 : KeyEnter);
|
||||||
|
|
||||||
|
#undef ShiftedKey
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(is_pressed)
|
||||||
|
key_states_[line] &= uint8_t(~key);
|
||||||
|
else
|
||||||
|
key_states_[line] |= uint8_t(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Keyboard::clear_all_keys() {
|
||||||
|
memset(key_states_, 0xff, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t Keyboard::read(uint16_t address) {
|
||||||
|
uint8_t value = 0xff;
|
||||||
|
|
||||||
|
uint16_t mask = 0x100;
|
||||||
|
for(int c = 0; c < 8; c++) {
|
||||||
|
if(!(address & mask)) value &= key_states_[c];
|
||||||
|
mask <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
@ -30,6 +30,19 @@ enum Key: uint16_t {
|
|||||||
KeyBreak, KeyLeft, KeyRight, KeyUp, KeyDown, KeyEdit
|
KeyBreak, KeyLeft, KeyRight, KeyUp, KeyDown, KeyEdit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Keyboard {
|
||||||
|
Keyboard(bool is_zx81);
|
||||||
|
|
||||||
|
void set_key_state(uint16_t key, bool is_pressed);
|
||||||
|
void clear_all_keys();
|
||||||
|
|
||||||
|
uint8_t read(uint16_t address);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t key_states_[8];
|
||||||
|
const bool is_zx81_;
|
||||||
|
};
|
||||||
|
|
||||||
struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper {
|
struct KeyboardMapper: public MachineTypes::MappedKeyboardMachine::KeyboardMapper {
|
||||||
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const override;
|
uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const override;
|
||||||
};
|
};
|
||||||
|
@ -63,12 +63,12 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
ConcreteMachine(const Analyser::Static::ZX8081::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
ConcreteMachine(const Analyser::Static::ZX8081::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) :
|
||||||
Utility::TypeRecipient<CharacterMapper>(is_zx81),
|
Utility::TypeRecipient<CharacterMapper>(is_zx81),
|
||||||
z80_(*this),
|
z80_(*this),
|
||||||
|
keyboard_(is_zx81),
|
||||||
tape_player_(ZX8081ClockRate),
|
tape_player_(ZX8081ClockRate),
|
||||||
ay_(GI::AY38910::Personality::AY38910, audio_queue_),
|
ay_(GI::AY38910::Personality::AY38910, audio_queue_),
|
||||||
speaker_(ay_) {
|
speaker_(ay_) {
|
||||||
set_clock_rate(ZX8081ClockRate);
|
set_clock_rate(ZX8081ClockRate);
|
||||||
speaker_.set_input_rate(float(ZX8081ClockRate) / 2.0f);
|
speaker_.set_input_rate(float(ZX8081ClockRate) / 2.0f);
|
||||||
clear_all_keys();
|
|
||||||
|
|
||||||
const bool use_zx81_rom = target.is_ZX81 || target.ZX80_uses_ZX81_ROM;
|
const bool use_zx81_rom = target.is_ZX81 || target.ZX80_uses_ZX81_ROM;
|
||||||
const auto roms =
|
const auto roms =
|
||||||
@ -183,12 +183,7 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
if(!(address&1)) {
|
if(!(address&1)) {
|
||||||
if(!nmi_is_enabled_) set_vsync(true);
|
if(!nmi_is_enabled_) set_vsync(true);
|
||||||
|
|
||||||
uint16_t mask = 0x100;
|
value &= keyboard_.read(address);
|
||||||
for(int c = 0; c < 8; c++) {
|
|
||||||
if(!(address & mask)) value &= key_states_[c];
|
|
||||||
mask <<= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
value &= ~(tape_player_.get_input() ? 0x00 : 0x80);
|
value &= ~(tape_player_.get_input() ? 0x00 : 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,36 +334,11 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
|
|
||||||
// MARK: - Keyboard
|
// MARK: - Keyboard
|
||||||
void set_key_state(uint16_t key, bool is_pressed) final {
|
void set_key_state(uint16_t key, bool is_pressed) final {
|
||||||
const auto line = key >> 8;
|
keyboard_.set_key_state(key, is_pressed);
|
||||||
|
|
||||||
// Check for special cases.
|
|
||||||
if(line > 7) {
|
|
||||||
switch(key) {
|
|
||||||
#define ShiftedKey(source, base) \
|
|
||||||
case source: \
|
|
||||||
set_key_state(KeyShift, is_pressed); \
|
|
||||||
set_key_state(base, is_pressed); \
|
|
||||||
break;
|
|
||||||
|
|
||||||
ShiftedKey(KeyDelete, Key0);
|
|
||||||
ShiftedKey(KeyBreak, KeySpace);
|
|
||||||
ShiftedKey(KeyUp, Key7);
|
|
||||||
ShiftedKey(KeyDown, Key6);
|
|
||||||
ShiftedKey(KeyLeft, Key5);
|
|
||||||
ShiftedKey(KeyRight, Key8);
|
|
||||||
ShiftedKey(KeyEdit, is_zx81 ? Key1 : KeyEnter);
|
|
||||||
#undef ShiftedKey
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(is_pressed)
|
|
||||||
key_states_[line] &= uint8_t(~key);
|
|
||||||
else
|
|
||||||
key_states_[line] |= uint8_t(key);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_all_keys() final {
|
void clear_all_keys() final {
|
||||||
memset(key_states_, 0xff, 8);
|
keyboard_.clear_all_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Tape control
|
// MARK: - Tape control
|
||||||
@ -448,7 +418,7 @@ template<bool is_zx81> class ConcreteMachine:
|
|||||||
bool vsync_ = false, hsync_ = false;
|
bool vsync_ = false, hsync_ = false;
|
||||||
int line_counter_ = 0;
|
int line_counter_ = 0;
|
||||||
|
|
||||||
uint8_t key_states_[8];
|
Keyboard keyboard_;
|
||||||
ZX8081::KeyboardMapper keyboard_mapper_;
|
ZX8081::KeyboardMapper keyboard_mapper_;
|
||||||
|
|
||||||
HalfClockReceiver<Storage::Tape::BinaryTapePlayer> tape_player_;
|
HalfClockReceiver<Storage::Tape::BinaryTapePlayer> tape_player_;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user