diff --git a/Machines/Sinclair/ZX8081/Keyboard.cpp b/Machines/Sinclair/ZX8081/Keyboard.cpp index 02e681a44..afd477f3d 100644 --- a/Machines/Sinclair/ZX8081/Keyboard.cpp +++ b/Machines/Sinclair/ZX8081/Keyboard.cpp @@ -192,3 +192,53 @@ const uint16_t *CharacterMapper::sequence_for_character(char character) const { bool CharacterMapper::needs_pause_after_key(uint16_t key) const { 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; +} diff --git a/Machines/Sinclair/ZX8081/Keyboard.hpp b/Machines/Sinclair/ZX8081/Keyboard.hpp index 354647ad4..8f52e701a 100644 --- a/Machines/Sinclair/ZX8081/Keyboard.hpp +++ b/Machines/Sinclair/ZX8081/Keyboard.hpp @@ -30,6 +30,19 @@ enum Key: uint16_t { 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 { uint16_t mapped_key_for_key(Inputs::Keyboard::Key key) const override; }; diff --git a/Machines/Sinclair/ZX8081/ZX8081.cpp b/Machines/Sinclair/ZX8081/ZX8081.cpp index 814cb4c80..c1749fdbb 100644 --- a/Machines/Sinclair/ZX8081/ZX8081.cpp +++ b/Machines/Sinclair/ZX8081/ZX8081.cpp @@ -63,12 +63,12 @@ template class ConcreteMachine: ConcreteMachine(const Analyser::Static::ZX8081::Target &target, const ROMMachine::ROMFetcher &rom_fetcher) : Utility::TypeRecipient(is_zx81), z80_(*this), + keyboard_(is_zx81), tape_player_(ZX8081ClockRate), ay_(GI::AY38910::Personality::AY38910, audio_queue_), speaker_(ay_) { set_clock_rate(ZX8081ClockRate); 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 auto roms = @@ -183,12 +183,7 @@ template class ConcreteMachine: if(!(address&1)) { if(!nmi_is_enabled_) set_vsync(true); - uint16_t mask = 0x100; - for(int c = 0; c < 8; c++) { - if(!(address & mask)) value &= key_states_[c]; - mask <<= 1; - } - + value &= keyboard_.read(address); value &= ~(tape_player_.get_input() ? 0x00 : 0x80); } @@ -339,36 +334,11 @@ template class ConcreteMachine: // MARK: - Keyboard void set_key_state(uint16_t key, bool is_pressed) final { - 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); - } + keyboard_.set_key_state(key, is_pressed); } void clear_all_keys() final { - memset(key_states_, 0xff, 8); + keyboard_.clear_all_keys(); } // MARK: - Tape control @@ -448,7 +418,7 @@ template class ConcreteMachine: bool vsync_ = false, hsync_ = false; int line_counter_ = 0; - uint8_t key_states_[8]; + Keyboard keyboard_; ZX8081::KeyboardMapper keyboard_mapper_; HalfClockReceiver tape_player_;