diff options
Diffstat (limited to '')
| -rw-r--r-- | rsnix/src/tty.rs | 28 |
1 files changed, 23 insertions, 5 deletions
diff --git a/rsnix/src/tty.rs b/rsnix/src/tty.rs index 7304925..0783521 100644 --- a/rsnix/src/tty.rs +++ b/rsnix/src/tty.rs | |||
| @@ -1,4 +1,8 @@ | |||
| 1 | //! Line discipline over the PS/2 keyboard — the kernel's tty layer. | 1 | //! Line discipline over the keyboard — the kernel's tty layer. |
| 2 | //! | ||
| 3 | //! Keys come from either the PS/2 controller (IRQ-fed scancode ring) or the | ||
| 4 | //! USB HID boot keyboard (polled UHCI driver). Both are translated to the | ||
| 5 | //! same `KeyEvent` space, so the shell is input-source agnostic. | ||
| 2 | //! | 6 | //! |
| 3 | //! Two modes, like a real UNIX terminal: | 7 | //! Two modes, like a real UNIX terminal: |
| 4 | //! - **canonical** (`read_line`): input is echoed, buffered until Enter, | 8 | //! - **canonical** (`read_line`): input is echoed, buffered until Enter, |
| @@ -34,6 +38,20 @@ pub enum LineInput { | |||
| 34 | static mut RAW_QUEUE: [u8; 8] = [0; 8]; | 38 | static mut RAW_QUEUE: [u8; 8] = [0; 8]; |
| 35 | static mut RAW_LEN: usize = 0; | 39 | static mut RAW_LEN: usize = 0; |
| 36 | 40 | ||
| 41 | /// Combined blocking key poll: USB HID keyboard first (polled UHCI), then | ||
| 42 | /// the PS/2 path (which parks via `hlt` until an IRQ-fed scancode lands). | ||
| 43 | fn poll_key() -> KeyEvent { | ||
| 44 | if let Some(ev) = crate::uhci::try_poll_key() { | ||
| 45 | return ev; | ||
| 46 | } | ||
| 47 | ps2::poll_key() | ||
| 48 | } | ||
| 49 | |||
| 50 | /// Combined non-blocking key poll (USB first, then PS/2). | ||
| 51 | fn try_poll_key() -> Option<KeyEvent> { | ||
| 52 | crate::uhci::try_poll_key().or_else(ps2::try_poll_key) | ||
| 53 | } | ||
| 54 | |||
| 37 | // --------------------------------------------------------------------------- | 55 | // --------------------------------------------------------------------------- |
| 38 | // canonical mode | 56 | // canonical mode |
| 39 | // --------------------------------------------------------------------------- | 57 | // --------------------------------------------------------------------------- |
| @@ -46,7 +64,7 @@ pub fn read_line() -> LineInput { | |||
| 46 | crate::vt::sync_scroll(); | 64 | crate::vt::sync_scroll(); |
| 47 | let mut buf = strbuf::String::<LINE_BUF_SIZE>::new(); | 65 | let mut buf = strbuf::String::<LINE_BUF_SIZE>::new(); |
| 48 | loop { | 66 | loop { |
| 49 | match ps2::poll_key() { | 67 | match poll_key() { |
| 50 | KeyEvent::Enter => { | 68 | KeyEvent::Enter => { |
| 51 | gop::put_char('\n'); | 69 | gop::put_char('\n'); |
| 52 | serial::write_str("\r\n"); | 70 | serial::write_str("\r\n"); |
| @@ -104,7 +122,7 @@ pub fn read_line() -> LineInput { | |||
| 104 | /// streaming commands (cat/hexdump) so a long dump can be interrupted. | 122 | /// streaming commands (cat/hexdump) so a long dump can be interrupted. |
| 105 | pub fn interrupt_pressed() -> bool { | 123 | pub fn interrupt_pressed() -> bool { |
| 106 | let mut pressed = false; | 124 | let mut pressed = false; |
| 107 | while let Some(ev) = ps2::try_poll_key() { | 125 | while let Some(ev) = try_poll_key() { |
| 108 | if matches!(ev, KeyEvent::Ctrl('c')) { | 126 | if matches!(ev, KeyEvent::Ctrl('c')) { |
| 109 | pressed = true; | 127 | pressed = true; |
| 110 | } | 128 | } |
| @@ -126,7 +144,7 @@ pub fn read_byte() -> u8 { | |||
| 126 | if let Some(b) = pop_raw() { | 144 | if let Some(b) = pop_raw() { |
| 127 | return b; | 145 | return b; |
| 128 | } | 146 | } |
| 129 | let ev = ps2::poll_key(); | 147 | let ev = poll_key(); |
| 130 | enqueue_key(ev); | 148 | enqueue_key(ev); |
| 131 | } | 149 | } |
| 132 | } | 150 | } |
| @@ -136,7 +154,7 @@ pub fn try_read_byte() -> Option<u8> { | |||
| 136 | if let Some(b) = pop_raw() { | 154 | if let Some(b) = pop_raw() { |
| 137 | return Some(b); | 155 | return Some(b); |
| 138 | } | 156 | } |
| 139 | match ps2::try_poll_key() { | 157 | match try_poll_key() { |
| 140 | Some(ev) => { | 158 | Some(ev) => { |
| 141 | enqueue_key(ev); | 159 | enqueue_key(ev); |
| 142 | pop_raw() | 160 | pop_raw() |
