diff options
| author | Tianhao Wang <shrik3@riseup.net> | 2023-03-24 15:25:13 +0100 |
|---|---|---|
| committer | Tianhao Wang <shrik3@riseup.net> | 2023-03-24 15:25:13 +0100 |
| commit | d295be457035b42c4451610c50e520c2fecead54 (patch) | |
| tree | 164f80e7c1ff9e7c9ad8d658743ae38bd4eac05e | |
| parent | 625c9652007111ba4bfbc2787ebe579727eefdd2 (diff) | |
minimal support for keyctrl, not complete
| -rw-r--r-- | src/machine/kbd_defs.rs | 78 | ||||
| -rw-r--r-- | src/machine/key.rs | 167 | ||||
| -rw-r--r-- | src/machine/keyctrl.rs | 53 | ||||
| -rw-r--r-- | src/machine/mod.rs | 3 |
4 files changed, 301 insertions, 0 deletions
diff --git a/src/machine/kbd_defs.rs b/src/machine/kbd_defs.rs new file mode 100644 index 0000000..94026e6 --- /dev/null +++ b/src/machine/kbd_defs.rs @@ -0,0 +1,78 @@ +use core::ffi::c_uchar; + +// bit masks for modifier keys +pub enum Mbit { + Shift = 0b00000001, + AltLeft = 0b00000010, + AltRight = 0b00000100, + CtrlLeft = 0b00001000, + CtrlRight = 0b00010000, + CapsLock = 0b00100000, + NumLock = 0b01000000, + ScrollLock = 0b10000000, +} + +// scan codes of a few specific keys +pub enum Scan { + F1 = 0x3b, + Del = 0x53, + Up = 72, + Down = 80, + Left = 75, + Right = 77, + Div = 8, +} + +// Decoding tables ... this shit is so ugly, thanks to rust's strong typing system!!! +// Also, this is a german layout keyboard +// oh btw, the code translation is done by ChatGPT if it's wrong complain to the AI! +const NORMAL_TAB: [c_uchar; 89] = [ + 0, 0, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 225, 39, 8, 0, 113, 119, 101, 114, 116, 122, 117, + 105, 111, 112, 129, 43, 10, 0, 97, 115, 100, 102, 103, 104, 106, 107, 108, 148, 132, 94, 0, 35, + 121, 120, 99, 118, 98, 110, 109, 44, 46, 45, 0, 42, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 45, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 60, 0, 0, +]; + +const SHIFT_TAB: [c_uchar; 89] = [ + 0, 0, 33, 34, 21, 36, 37, 38, 47, 40, 41, 61, 63, 96, 0, 0, 81, 87, 69, 82, 84, 90, 85, 73, 79, + 80, 154, 42, 0, 0, 65, 83, 68, 70, 71, 72, 74, 75, 76, 153, 142, 248, 0, 39, 89, 88, 67, 86, + 66, 78, 77, 59, 58, 95, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 62, 0, 0, +]; + +const ALT_TAB: [c_uchar; 89] = [ + 0, 0, 0, 253, 0, 0, 0, 0, 123, 91, 93, 125, 92, 0, 0, 0, 64, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 124, 0, 0 +]; + +const ASC_NUM_TAB: [c_uchar; 13] = [55, 56, 57, 45, 52, 53, 54, 43, 49, 50, 51, 48, 44]; +const SCAN_NUM_TAB: [c_uchar; 13] = [8, 9, 10, 53, 5, 6, 7, 27, 2, 3, 4, 11, 51]; + +// I think constants are more handy than enum for these... +// Keyboard controller commands +pub const KC_CMD_SET_LED: u8 = 0xed; +pub const KC_CMD_SET_SPEED: u8 = 0xf3; + +// CPU reset .. (reboot) +pub const KC_CPU_RESET: u8 = 0xfe; + +// Status register bits +pub const KC_SR_OUTB: u8 = 0x01; +pub const KC_SR_INPB: u8 = 0x02; +pub const KC_SR_AUXB: u8 = 0x20; + +// Keyboard Controller LED bits +pub const KC_LED_CAPS_LOCK: u8 = 4; +pub const KC_LED_NUM_LOCK: u8 = 2; +pub const KC_LED_SCROLL_LOCK: u8 = 1; + +// ACK +pub const KC_REPLY_ACK: u8 = 0xfa; + +// some stuffs for decoding +pub const BREAK_BIT: u8 = 0x80; +pub const PREFIX1: u8 = 0xe0; +pub const PREFIX2: u8 = 0xe1; diff --git a/src/machine/key.rs b/src/machine/key.rs new file mode 100644 index 0000000..3464d83 --- /dev/null +++ b/src/machine/key.rs @@ -0,0 +1,167 @@ +use self::super::kbd_defs::*; +use core::convert; + +pub struct Key { + asc: u8, + scan: u8, + modi: u8, + rawcode: u8, // this field not necessary, remove after testing +} + +// Not implementing +// +operator char() +// + +impl convert::Into<char> for Key{ + fn into(self) -> char { + self.asc as char + } +} + +impl convert::Into<u8> for Key{ + fn into(self) -> u8 { + self.asc + } +} + +#[allow(dead_code)] +impl Key { + pub fn new() -> Self { + Self { + asc: 0, + scan: 0, + modi: 0, + rawcode: 0, + } + } + + pub fn valid(self) -> bool { + self.scan != 0 + } + + pub fn invalidate(&mut self) { + self.scan = 0; + } + + pub fn set_raw(&mut self, code:u8) { + self.rawcode = code; + } + + pub fn get_raw(self) -> u8 { + self.rawcode + } + + // setter and getter for ascii and scancode + pub fn set_ascii(&mut self, ascii: u8) { + self.asc = ascii; + } + pub fn get_ascii(self) -> u8 { + self.asc + } + pub fn set_scancode(&mut self, scancode: u8) { + self.scan = scancode; + } + pub fn get_scancode(self) -> u8 { + self.scan + } + + // reading the state of SHIFT, ALT, CTRL etc. + pub fn shift(&self) -> bool { + self.modi & (Mbit::Shift as u8) != 0 + } + pub fn alt_left(&self) -> bool { + self.modi & (Mbit::AltLeft as u8) != 0 + } + pub fn alt_right(&self) -> bool { + self.modi & (Mbit::AltRight as u8) != 0 + } + pub fn ctrl_left(&self) -> bool { + self.modi & (Mbit::CtrlLeft as u8) != 0 + } + pub fn ctrl_right(&self) -> bool { + self.modi & (Mbit::CtrlRight as u8) != 0 + } + pub fn caps_lock(&self) -> bool { + self.modi & (Mbit::CapsLock as u8) != 0 + } + pub fn num_lock(&self) -> bool { + self.modi & (Mbit::NumLock as u8) != 0 + } + pub fn scroll_lock(&self) -> bool { + self.modi & (Mbit::ScrollLock as u8) != 0 + } + pub fn alt(&self) -> bool { + self.alt_left() | self.alt_right() + } + pub fn ctrl(&self) -> bool { + self.ctrl_left() | self.ctrl_right() + } + + // setting/clearing states of SHIFT, ALT, CTRL etc. + pub fn set_shift(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::Shift as u8 + } else { + self.modi & !(Mbit::Shift as u8) + } + } + + pub fn set_alt_left(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::AltLeft as u8 + } else { + self.modi & !(Mbit::AltLeft as u8) + } + } + + + pub fn set_alt_right(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::AltRight as u8 + } else { + self.modi & !(Mbit::AltRight as u8) + } + } + + pub fn set_ctrl_left(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::CtrlLeft as u8 + } else { + self.modi & !(Mbit::CtrlLeft as u8) + } + } + + pub fn set_ctrl_right(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::CtrlRight as u8 + } else { + self.modi & !(Mbit::CtrlRight as u8) + } + } + + + pub fn set_caps_lock(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::CapsLock as u8 + } else { + self.modi & !(Mbit::CapsLock as u8) + } + } + + + pub fn set_num_lock(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::NumLock as u8 + } else { + self.modi & !(Mbit::NumLock as u8) + } + } + + pub fn set_scroll_lock(&mut self, pressed: bool) { + self.modi = if pressed { + self.modi | Mbit::ScrollLock as u8 + } else { + self.modi & !(Mbit::ScrollLock as u8) + } + } +} diff --git a/src/machine/keyctrl.rs b/src/machine/keyctrl.rs new file mode 100644 index 0000000..49ac486 --- /dev/null +++ b/src/machine/keyctrl.rs @@ -0,0 +1,53 @@ +use self::super::kbd_defs::*; +use self::super::key::*; +use crate::arch::x86_64::io_port::*; + +// this is the driver for keyboard controller +// not to confuse with the keyboard module. +// The later is an abstraction +// This one serves a the HW driver + +// TODO +// [functions] +// Keyboard_Controller() +// get_ascii_code() +// key_decoded() +// key_hit() +// reboot() +// set_led(char led,bool on) +// set_repeat_rate(int speed,int delay) +pub struct KeyboardController { + code: u8, + prefix: u8, + gather: Key, + leds: u8, + + // two ports for keyboard controller + ctrl_port: u16, + data_port: u16, + // status register bits +} + +impl KeyboardController { + + pub fn new() -> Self { + Self { + code: 0, + prefix: 9, + gather: Key::new(), + leds: 0, + ctrl_port: 0x64, + data_port: 0x60, + } + } + + pub fn key_hit(&mut self) -> Key { + // for debugging only + let mut invalid:Key = Key::new(); + invalid.set_raw(0xff); + + let status = inb(self.ctrl_port); + + // TODO here + } +} diff --git a/src/machine/mod.rs b/src/machine/mod.rs index 19adb3a..f272509 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -1,2 +1,5 @@ pub mod cgascr; pub mod mem; +pub mod keyctrl; +pub mod key; +mod kbd_defs; |
