From cb66c07a5f4c239db070a9830a8f97a6993ba81e Mon Sep 17 00:00:00 2001
From: Jcodefox <jcodefox@gmail.com>
Date: Fri, 1 Dec 2023 09:48:57 -0500
Subject: [PATCH 1/3] Add check for non-existent buffer

---
 kernel/src/holeybytes/ecah.rs   | 27 +++++++++++++++------------
 sysdata/test-programs/main.rhai |  3 ++-
 2 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs
index b3f82a2..c43226b 100644
--- a/kernel/src/holeybytes/ecah.rs
+++ b/kernel/src/holeybytes/ecah.rs
@@ -77,20 +77,23 @@ pub fn handler(vm: &mut Vm) {
                 buffer_id => {
                     let mut buffs = IPC_BUFFERS.lock();
 
-                    let mut buff = buffs.get_mut(&buffer_id).unwrap();
+                    match buffs.get_mut(&buffer_id) {
+                        Some(buff) => {
+                            let mut msg_vec = vec![];
 
-                    let mut msg_vec = vec![];
-
-                    for x in 0..(length as isize) {
-                        let xyz = mem_addr as *const u8;
-                        let value = unsafe { xyz.offset(x).read() };
-                        msg_vec.push(value);
+                            for x in 0..(length as isize) {
+                                let xyz = mem_addr as *const u8;
+                                let value = unsafe { xyz.offset(x).read() };
+                                msg_vec.push(value);
+                            }
+                            buff.push(msg_vec.clone());
+                            info!(
+                                "Message {:?} has been sent to Buffer({})",
+                                msg_vec, buffer_id
+                            );
+                        }
+                        None => log::error!("Access of non-existent buffer")
                     }
-                    buff.push(msg_vec.clone());
-                    info!(
-                        "Message {:?} has been sent to Buffer({})",
-                        msg_vec, buffer_id
-                    );
                     drop(buffs);
                 }
             }
diff --git a/sysdata/test-programs/main.rhai b/sysdata/test-programs/main.rhai
index 63a2f22..1875f36 100644
--- a/sysdata/test-programs/main.rhai
+++ b/sysdata/test-programs/main.rhai
@@ -8,8 +8,9 @@ fn main(){
     std::Trace("Trace Deez");
     
     std::ipc_send(2, 0, 0);
+    std::ipc_send(3, 0, 0);
 
     tx();
 }
 
-main();
\ No newline at end of file
+main();

From 6f061153e690d39829b516788e9dfb623ed38e97 Mon Sep 17 00:00:00 2001
From: Jcodefox <jcodefox@gmail.com>
Date: Fri, 1 Dec 2023 10:02:56 -0500
Subject: [PATCH 2/3] Log number with buffer error

---
 kernel/src/holeybytes/ecah.rs   | 4 +++-
 sysdata/test-programs/main.rhai | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs
index c43226b..8b6fb94 100644
--- a/kernel/src/holeybytes/ecah.rs
+++ b/kernel/src/holeybytes/ecah.rs
@@ -92,7 +92,9 @@ pub fn handler(vm: &mut Vm) {
                                 msg_vec, buffer_id
                             );
                         }
-                        None => log::error!("Access of non-existent buffer")
+                        None => {
+                            log::error!("Access of non-existent buffer {}", buffer_id)
+                        }
                     }
                     drop(buffs);
                 }
diff --git a/sysdata/test-programs/main.rhai b/sysdata/test-programs/main.rhai
index 1875f36..d95eb92 100644
--- a/sysdata/test-programs/main.rhai
+++ b/sysdata/test-programs/main.rhai
@@ -8,6 +8,9 @@ fn main(){
     std::Trace("Trace Deez");
     
     std::ipc_send(2, 0, 0);
+
+    std::ipc_make_bound_buffer(64);
+
     std::ipc_send(3, 0, 0);
 
     tx();

From 0a6085061ac7433af9a02f3d36c9f5e9a56b1926 Mon Sep 17 00:00:00 2001
From: Jcodefox <jcodefox@gmail.com>
Date: Tue, 5 Dec 2023 00:56:23 -0500
Subject: [PATCH 3/3] ECAH: Add a simple keyboard driver

---
 kernel/src/holeybytes/ecah.rs              |  40 +++--
 repbuild/src/main.rs                       |   1 +
 sysdata/limine.cfg                         |   3 +
 sysdata/test-programs/keyboard_driver.rhai | 199 +++++++++++++++++++++
 sysdata/test-programs/main.rhai            |   4 -
 5 files changed, 231 insertions(+), 16 deletions(-)
 create mode 100644 sysdata/test-programs/keyboard_driver.rhai

diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs
index 8b6fb94..7f3be72 100644
--- a/kernel/src/holeybytes/ecah.rs
+++ b/kernel/src/holeybytes/ecah.rs
@@ -108,6 +108,10 @@ pub fn handler(vm: &mut Vm) {
             let msg = buff.pop();
             info!("Recieve {:?} from Buffer({})", msg, r2);
         }
+        5 => {
+            let r2 = vm.registers[2].cast::<u64>();
+            vm.registers[3] = hbvm::value::Value( unsafe { x86_in(r2 as u16) } as u64);
+        }
         // 5
         _ => {
             log::error!("Syscall unknown {:?}{:?}", r1, vm.registers);
@@ -115,6 +119,13 @@ pub fn handler(vm: &mut Vm) {
     }
 }
 
+unsafe fn x86_in(address: u16) -> u32{
+    x86_64::instructions::port::Port::new(address).read()
+}
+unsafe fn x86_out(address: u16, value: u32){
+    x86_64::instructions::port::Port::new(address).write(value);
+}
+
 fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogError> {
     // let message_length = 8 + 8 + 8;
     // log::info!("Mem Addr 0x{:x?} length {}", mem_addr, length);
@@ -127,19 +138,24 @@ fn log_msg_handler(vm: &mut Vm, mem_addr: u64, length: usize) -> Result<(), LogE
         msg_vec.push(value);
     }
     let log_level = msg_vec.pop().unwrap();
-    let strr = String::from_utf8(msg_vec).unwrap();
-
-    // use LogLevel::*;
-    let ll = match log_level {
-        0 | 48 => error!("{}", strr),
-        1 | 49 => warn!("{}", strr),
-        2 | 50 => info!("{}", strr),
-        3 | 51 => debug!("{}", strr),
-        4 | 52 => trace!("{}", strr),
-        _ => {
-            return Err(LogError::InvalidLogFormat);
+    match String::from_utf8(msg_vec) {
+        Ok (strr) => {
+            // use LogLevel::*;
+            let ll = match log_level {
+                0 | 48 => error!("{}", strr),
+                1 | 49 => warn!("{}", strr),
+                2 | 50 => info!("{}", strr),
+                3 | 51 => debug!("{}", strr),
+                4 | 52 => trace!("{}", strr),
+                _ => {
+                    return Err(LogError::InvalidLogFormat);
+                }
+            };
         }
-    };
+        Err(e) => {
+            error!("{:?}", e);
+        }
+    }
 
     Ok(())
 }
diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs
index e2cc634..f8871b8 100644
--- a/repbuild/src/main.rs
+++ b/repbuild/src/main.rs
@@ -152,6 +152,7 @@ fn get_fs() -> Result<FileSystem<impl ReadWriteSeek>, io::Error> {
         "target/test-programs/serial_driver.hbf",
         "target/test-programs/vfs_test.hbf",
         "target/test-programs/limine_framebuffer_driver.hbf",
+        "target/test-programs/keyboard_driver.hbf",
     ] {
         let path = Path::new(fpath);
         io::copy(
diff --git a/sysdata/limine.cfg b/sysdata/limine.cfg
index c082f68..65f7457 100644
--- a/sysdata/limine.cfg
+++ b/sysdata/limine.cfg
@@ -27,6 +27,9 @@ TERM_BACKDROP=008080
     MODULE_PATH=boot:///main.hbf
     MODULE_CMDLINE=""
 
+    MODULE_PATH=boot:///keyboard_driver.hbf
+    MODULE_CMDLINE=""
+
     MODULE_PATH=boot:///vfs_test.hbf
     MODULE_CMDLINE=""
 
diff --git a/sysdata/test-programs/keyboard_driver.rhai b/sysdata/test-programs/keyboard_driver.rhai
new file mode 100644
index 0000000..cae710a
--- /dev/null
+++ b/sysdata/test-programs/keyboard_driver.rhai
@@ -0,0 +1,199 @@
+import "sysdata/test-programs/hblib/std" as std;
+
+fn print_register(reg){
+    std::Debug("-----------------");
+    let c0 = declabel();
+    let c1 = declabel();
+    let c2 = declabel();
+    let c3 = declabel();
+    let c4 = declabel();
+    let c5 = declabel();
+    let c6 = declabel();
+    let c7 = declabel();
+    let c8 = declabel();
+    let c9 = declabel();
+    let ca = declabel();
+    let cb = declabel();
+    let cc = declabel();
+    let cd = declabel();
+    let ce = declabel();
+    let cf = declabel();
+    let end = declabel();
+
+    cp(r32, reg);
+    li64(r35, 16);
+
+    let next_loop = label();
+
+    addi64(r35, r35, -1);
+    li64(r37, 4);
+    mul64(r36, r35, r37);
+    sru64(r34, r32, r36);
+
+    andi(r34, r34, 0xf);
+    li64(r33, 0);
+
+    jeq(r34, r33, c0);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c1);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c2);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c3);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c4);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c5);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c6);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c7);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c8);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, c9);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, ca);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, cb);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, cc);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, cd);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, ce);
+    addi64(r33, r33, 1);
+    jeq(r34, r33, cf);
+
+    std::Error("This should be an invalid state");
+
+    let next = label();
+    jne(r0, r35, next_loop);
+    jeq(r0, r0, end);
+
+    here(c0);
+    std::Debug("0");
+    jeq(r0, r0, next);
+    here(c1);
+    std::Debug("1");
+    jeq(r0, r0, next);
+    here(c2);
+    std::Debug("2");
+    jeq(r0, r0, next);
+    here(c3);
+    std::Debug("3");
+    jeq(r0, r0, next);
+    here(c4);
+    std::Debug("4");
+    jeq(r0, r0, next);
+    here(c5);
+    std::Debug("5");
+    jeq(r0, r0, next);
+    here(c6);
+    std::Debug("6");
+    jeq(r0, r0, next);
+    here(c7);
+    std::Debug("7");
+    jeq(r0, r0, next);
+    here(c8);
+    std::Debug("8");
+    jeq(r0, r0, next);
+    here(c9);
+    std::Debug("9");
+    jeq(r0, r0, next);
+    here(ca);
+    std::Debug("A");
+    jeq(r0, r0, next);
+    here(cb);
+    std::Debug("B");
+    jeq(r0, r0, next);
+    here(cc);
+    std::Debug("C");
+    jeq(r0, r0, next);
+    here(cd);
+    std::Debug("D");
+    jeq(r0, r0, next);
+    here(ce);
+    std::Debug("E");
+    jeq(r0, r0, next);
+    here(cf);
+    std::Debug("F");
+    jeq(r0, r0, next);
+
+    here(end);
+    std::Debug("-----------------");
+}
+
+fn get_keyboard_status(){
+    li64(r1, 5);
+    li64(r2, 0x64);
+    eca();
+}
+
+fn get_keyboard_input(){
+    li64(r1, 5);
+    li64(r2, 0x60);
+    eca();
+}
+
+fn is_keyup(rb, ra){
+    li64(rb, 15);
+    sru64(rb, ra, rb);
+    andi(rb, rb, 1);
+}
+
+fn dump_registers(){
+    li64(r1, 0xff);
+    eca();
+}
+
+fn to_ascii(rb, ra){
+    let str = data::str(
+        "  1234567890-=  " +
+        "qwertyuiop[]  " +
+        "asdfghjkl;'` \\" +
+        "zxcvbnm,./ " +
+        "*               " +
+        "789-456+1230.     "
+    );
+    andi(r33, ra, 0x00ff);
+    lra(rb, r0, str);
+    add64(rb, rb, r33);
+    ld(rb, rb, 0, 1);
+}
+
+fn display_key(ra){
+    andi(r33, ra, 0x00ff);
+    ori(r33, r33, 0x0200);
+    let location = 0x20000;
+    li64(r32, location);
+    st(r33, r32, 0, 2);
+
+    li64(r1, 3);
+    li64(r2, 1);
+    li64(r3, location);
+    li64(r4, 2);
+    eca();
+}
+
+fn main(){
+    let key_up = declabel();
+    let main_loop = label();
+    get_keyboard_status();
+    andi(r12, r3, 1);
+    li64(r13, 0x1);
+    jne(r13, r12, main_loop);
+    get_keyboard_input();
+    cp(r12, r3);
+    is_keyup(r14, r12);
+    jne(r0, r14, key_up);
+    to_ascii(r15, r12);
+    display_key(r15);
+    jeq(r0, r0, main_loop);
+    here(key_up);
+    jeq(r0, r0, main_loop);
+
+    tx();
+}
+
+main();
diff --git a/sysdata/test-programs/main.rhai b/sysdata/test-programs/main.rhai
index d95eb92..ccfc70f 100644
--- a/sysdata/test-programs/main.rhai
+++ b/sysdata/test-programs/main.rhai
@@ -9,10 +9,6 @@ fn main(){
     
     std::ipc_send(2, 0, 0);
 
-    std::ipc_make_bound_buffer(64);
-
-    std::ipc_send(3, 0, 0);
-
     tx();
 }