aboutsummaryrefslogtreecommitdiff
path: root/src/machine
diff options
context:
space:
mode:
Diffstat (limited to 'src/machine')
-rw-r--r--src/machine/kbd_defs.rs78
-rw-r--r--src/machine/key.rs167
-rw-r--r--src/machine/keyctrl.rs53
-rw-r--r--src/machine/mod.rs3
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;