summaryrefslogtreecommitdiffstats
path: root/rsnix/src/tty.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/tty.rs')
-rw-r--r--rsnix/src/tty.rs28
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 {
34static mut RAW_QUEUE: [u8; 8] = [0; 8]; 38static mut RAW_QUEUE: [u8; 8] = [0; 8];
35static mut RAW_LEN: usize = 0; 39static 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).
43fn 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).
51fn 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.
105pub fn interrupt_pressed() -> bool { 123pub 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()