rustzx_core/zx/
keys.rs

1//! Module with hardware key port\masks
2
3/// Struct, which contains mast and port of key
4#[rustfmt::skip]
5#[cfg_attr(feature = "strum", derive(strum::EnumIter))]
6#[derive(Debug, Clone, Copy)]
7pub enum ZXKey {
8    // Port 0xFEFE
9    Shift, Z, X, C, V,
10    // Port 0xFDFE
11    A, S, D, F, G,
12    // Port 0xFBFE
13    Q, W, E, R, T,
14    // Port 0xF7FE
15    N1, N2, N3, N4, N5,
16    // Port 0xEFFE
17    N0, N9, N8, N7, N6,
18    // Port 0xDFFE
19    P, O, I, U, Y,
20    // Port 0xBFFE
21    Enter, L, K, J, H,
22    // Port 0x7FFE
23    Space, SymShift, M, N, B,
24}
25
26#[cfg_attr(feature = "strum", derive(strum::EnumIter))]
27#[derive(Debug, Clone, Copy)]
28pub enum CompoundKey {
29    ArrowLeft,
30    ArrowRight,
31    ArrowUp,
32    ArrowDown,
33    CapsLock,
34    Delete,
35    Break,
36}
37
38impl CompoundKey {
39    /// This mask is required to implement logic to keep
40    /// modifier key pressed while one of the compound
41    /// keys were released, but one of them is still
42    /// pressed, therefore modifier should be unchanged
43    pub(crate) fn modifier_mask(self) -> u32 {
44        match self {
45            CompoundKey::ArrowLeft => 0x00000001,
46            CompoundKey::ArrowRight => 0x00000002,
47            CompoundKey::ArrowUp => 0x00000004,
48            CompoundKey::ArrowDown => 0x00000008,
49            CompoundKey::CapsLock => 0x00000010,
50            CompoundKey::Delete => 0x00000020,
51            CompoundKey::Break => 0x00000040,
52        }
53    }
54
55    pub(crate) fn modifier_key(self) -> ZXKey {
56        ZXKey::Shift
57    }
58
59    pub(crate) fn primary_key(self) -> ZXKey {
60        match self {
61            CompoundKey::ArrowLeft => ZXKey::N5,
62            CompoundKey::ArrowRight => ZXKey::N8,
63            CompoundKey::ArrowUp => ZXKey::N7,
64            CompoundKey::ArrowDown => ZXKey::N6,
65            CompoundKey::CapsLock => ZXKey::N2,
66            CompoundKey::Delete => ZXKey::N0,
67            CompoundKey::Break => ZXKey::Space,
68        }
69    }
70}
71
72impl ZXKey {
73    pub(crate) fn row_id(self) -> usize {
74        match self.half_port() {
75            0xFE => 0,
76            0xFD => 1,
77            0xFB => 2,
78            0xF7 => 3,
79            0xEF => 4,
80            0xDF => 5,
81            0xBF => 6,
82            0x7F => 7,
83            _ => unreachable!(),
84        }
85    }
86
87    pub(crate) fn mask(&self) -> u8 {
88        use ZXKey::*;
89        match self {
90            Shift | A | Q | N1 | N0 | P | Enter | Space => 0x01,
91            Z | S | W | N2 | N9 | O | L | SymShift => 0x02,
92            X | D | E | N3 | N8 | I | K | M => 0x04,
93            C | F | R | N4 | N7 | U | J | N => 0x08,
94            V | G | T | N5 | N6 | Y | H | B => 0x10,
95        }
96    }
97
98    fn half_port(self) -> u8 {
99        use ZXKey::*;
100        match self {
101            Shift | Z | X | C | V => 0xFE,
102            A | S | D | F | G => 0xFD,
103            Q | W | E | R | T => 0xFB,
104            N1 | N2 | N3 | N4 | N5 => 0xF7,
105            N0 | N9 | N8 | N7 | N6 => 0xEF,
106            P | O | I | U | Y => 0xDF,
107            Enter | L | K | J | H => 0xBF,
108            Space | SymShift | M | N | B => 0x7F,
109        }
110    }
111}