diff --git a/.vscode/settings.json b/.vscode/settings.json
index e0c3d05..8937728 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,6 @@
 {
+   "editor.insertSpaces": false,
+   "editor.detectIndentation": false,
    "rust-analyzer.checkOnSave.allTargets": false,
    "rust-analyzer.showUnlinkedFileNotification": false,
    "C_Cpp.errorSquiggles": "disabled"
diff --git a/STYLE_GUIDE.md b/STYLE_GUIDE.md
new file mode 100644
index 0000000..6298d0e
--- /dev/null
+++ b/STYLE_GUIDE.md
@@ -0,0 +1,77 @@
+# Style Guide
+This style guide has two modes that a guideline may be.
+
+`strict` means that prs will be rejected if they do not follow the guideline.
+
+`loose` means that a pr would be accepted but should later be fixed.
+
+## Empty Functions | loose
+Empty functions are typically a sign of an unfinished program or driver.
+
+In cases where there is a clear reason to have an empty function it will be allowed.
+For example FakeAlloc is only empty functions because it is a example of an the allocator api.
+
+### Allowed
+```rust
+/// in example.hb
+a := fn(): void {}
+```
+### Not Allowed
+```rust
+/// in fat32.hb
+a := fn(): void {}
+```
+## Magic Functions | loose
+'Magic functions' are what I am calling small helper functions that do one or two things.
+### Example
+```rust
+a := null
+magic_a := fn(){
+	a = 10
+}
+```
+The exact policy I want to have here is a bit fuzzy. I think that functions like this are nice in certain situations and not in others.
+Regardless of if you use them or not, put a comment above the function explaining rational.
+
+
+## Magic Numbers | loose
+The policy on magic numbers is make them const and have a comment above them. Typically linking to a source of information about the magic number.
+
+This helps cut down on magic numbers while making acceptable names and atleast half assed documentation. 
+
+Constants are inlined anyways, so its the same thing in the binary.
+
+```rust
+// The standard vga port is mapped at 0xB8000
+$VGA_PTR := 0xB8000
+```
+
+## Tabs Vs Spaces | strict
+I prefer for hblang code to use hard tabs.
+
+The rational behind this is that a tab is `1 Indent` which some developers might want to be various different sizes when displayed
+
+Soft tabs do not allow this user/editor specific as soft tabs always become spaces.
+
+Bottom line is this is an accessibility feature.
+
+There are some samples below.
+```
+\t means hard tab
+\n means new line
+\0x20 means space
+```
+
+### Allowed
+```rust
+if x == y {\n
+\tlog(z)\n
+}\n
+```
+
+### Not Allowed
+```rust
+if x == y {\n
+\0x20\0x20\0x20\0x20log(z)\n
+}\n
+```
\ No newline at end of file
diff --git a/kernel/ktest_macro/src/lib.rs b/kernel/ktest_macro/src/lib.rs
index c1c3a8a..ebff040 100644
--- a/kernel/ktest_macro/src/lib.rs
+++ b/kernel/ktest_macro/src/lib.rs
@@ -1,28 +1,85 @@
 extern crate proc_macro;
 extern crate quote;
 extern crate syn;
+
 use {
     proc_macro::TokenStream,
     quote::quote,
-    syn::{parse_macro_input, ItemFn}
+    syn::{parse::Parse, parse_macro_input, Expr, ItemFn, Token}
 };
 
+struct KtestInput {
+    lhs: Expr,
+    _comma: Token![,],
+    rhs: Expr,
+}
+
+impl Parse for KtestInput {
+    fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+        Ok(Self {
+            lhs: input.parse()?,
+            _comma: input.parse()?,
+            rhs: input.parse()?,
+        })
+    }
+}
+
+#[proc_macro]
+pub fn ktest_eq(item: TokenStream) -> TokenStream {
+    let input = parse_macro_input!(item as KtestInput);
+
+    let lhs = input.lhs;
+    let rhs = input.rhs;
+
+    let out = quote! {
+        if #lhs != #rhs {
+            return Err(name);
+        }
+    };
+    TokenStream::from(out)
+}
+
+#[proc_macro]
+pub fn ktest_neq(item: TokenStream) -> TokenStream {
+    let input = parse_macro_input!(item as KtestInput);
+
+    let lhs = input.lhs;
+    let rhs = input.rhs;
+
+    let out = quote! {
+        if #lhs == #rhs {
+            return Err(name);
+        }
+    };
+    TokenStream::from(out)
+}
+
 #[proc_macro_attribute]
 pub fn ktest(_attr: TokenStream, item: TokenStream) -> TokenStream {
     let input = parse_macro_input!(item as ItemFn);
     let test_name = &input.sig.ident;
+    let test_string = test_name.to_string();
     let static_var_name = syn::Ident::new(
-        &format!("__ktest_{}", test_name),
+        &format!("__ktest_{}", test_name).to_uppercase(),
         test_name.span(),
     );
-    let out = quote! {
-        // #[cfg(feature = "ktest")]
-        #input
 
-        // #[cfg(feature = "ktest")]
+    let block = &input.block;
+    let out = quote! {
+        #[cfg(feature = "ktest")]
+        fn #test_name() -> Result<String, String> {
+            use crate::alloc::string::ToString;
+            let name = #test_string.to_string();
+
+            #block
+
+            return Ok(name);
+        }
+
+        #[cfg(feature = "ktest")]
         #[unsafe(link_section = ".note.ktest")]
         #[used]
-        pub static #static_var_name: fn() = #test_name;
+        pub static #static_var_name: fn() -> Result<String, String> = #test_name;
     };
 
     TokenStream::from(out)
diff --git a/kernel/lds/aarch64-qemu.ld b/kernel/lds/aarch64-qemu.ld
index dbcbacf..adf13fb 100644
--- a/kernel/lds/aarch64-qemu.ld
+++ b/kernel/lds/aarch64-qemu.ld
@@ -6,6 +6,11 @@ SECTIONS
     .text.boot : { *(.text.boot) }
     .text : { *(.text) }
     .data : { *(.data) }
+    .note.ktest : {
+		__ktest_start = .;
+    	*(.note.ktest)
+    	__ktest_end = .;
+	}
     .rodata : { *(.rodata) }
     .bss : {
         *(COMMON)
diff --git a/kernel/src/arch/x86_64/interrupts.rs b/kernel/src/arch/x86_64/interrupts.rs
index 4bd3c8a..336f0c8 100644
--- a/kernel/src/arch/x86_64/interrupts.rs
+++ b/kernel/src/arch/x86_64/interrupts.rs
@@ -62,7 +62,7 @@ extern "x86-interrupt" fn page_fault(
 }
 
 extern "x86-interrupt" fn timer(_isf: InterruptStackFrame) {
-    // interrupt(Interrupt::Timer);
+    interrupt(Interrupt::Timer);
 
     unsafe {
         LAPIC.end_of_interrupt();
@@ -83,28 +83,31 @@ extern "x86-interrupt" fn spurious(_: InterruptStackFrame) {
     }
 }
 
+#[allow(unused_imports)]
 fn interrupt(interrupt_type: Interrupt) {
-    use crate::arch::INTERRUPT_LIST;
-    let il = INTERRUPT_LIST.lock();
-    let val = il.list.get(&interrupt_type).unwrap();
+    use crate::{arch::INTERRUPT_LIST, kmain::EXECUTOR};
+    // let il = INTERRUPT_LIST.lock();
+    // let val = il.list.get(&interrupt_type).unwrap();
 
-    use crate::holeybytes::kernel_services::service_definition_service::sds_search_service;
-    let buffer = sds_search_service(val);
-    if buffer != 0 {
-        use {crate::kmain::IPC_BUFFERS, alloc::vec::Vec};
-        let mut buffs = IPC_BUFFERS.lock();
-        match buffs.get_mut(&buffer) {
-            Some(buff) => {
-                let mut msg_vec = Vec::new();
-                msg_vec.push(0xFF);
-                buff.push(msg_vec.to_vec());
-                log::debug!("Sent Message {:?} to Buffer({})", msg_vec, buffer);
-            }
-            None => {
-                log::error!("Access of non-existent buffer {}", buffer)
-            }
-        }
+    // use crate::holeybytes::kernel_services::service_definition_service::sds_search_service;
+    // let buffer = sds_search_service(val);
+    // if buffer != 0 {
+    //     use {crate::kmain::IPC_BUFFERS, alloc::vec::Vec};
+    //     let mut buffs = IPC_BUFFERS.lock();
+    //     match buffs.get_mut(&buffer) {
+    //         Some(buff) => {
+    //             let mut msg_vec = Vec::new();
+    //             msg_vec.push(0xFF);
+    //             buff.push(msg_vec.to_vec());
+    //             log::debug!("Sent Message {:?} to Buffer({})", msg_vec, buffer);
+    //         }
+    //         None => {
+    //             log::error!("Access of non-existent buffer {}", buffer)
+    //         }
+    //     }
+    // }
 
-        // log::info!("{}", buffer);
+    unsafe {
+        EXECUTOR.send_interrupt(interrupt_type as u8);
     }
 }
diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs
index 67576f4..ab540d6 100644
--- a/kernel/src/holeybytes/ecah.rs
+++ b/kernel/src/holeybytes/ecah.rs
@@ -33,7 +33,7 @@ unsafe fn x86_in<T: x86_64::instructions::port::PortRead>(address: u16) -> T {
 }
 
 #[inline(always)]
-pub fn handler(vm: &mut Vm) {
+pub fn handler(vm: &mut Vm, pid: &usize) {
     let ecall_number = vm.registers[2].cast::<u64>();
 
     match ecall_number {
@@ -80,6 +80,10 @@ pub fn handler(vm: &mut Vm) {
             let length = vm.registers[5].cast::<u64>() as usize;
             trace!("IPC address: {:?}", mem_addr);
 
+            unsafe { LazyCell::<Executor>::get_mut(&mut EXECUTOR) }
+                .unwrap()
+                .send_buffer(buffer_id as usize);
+
             match buffer_id {
                 0 => match sds_msg_handler(vm, mem_addr, length) {
                     Ok(()) => {}
@@ -209,7 +213,6 @@ pub fn handler(vm: &mut Vm) {
             let buffer_id = vm.registers[3].cast::<u64>();
             let map_ptr = vm.registers[4].cast::<u64>();
             let max_length = vm.registers[5].cast::<u64>();
-
             let mut buffs = IPC_BUFFERS.lock();
             let buff: &mut IpcBuffer = match buffs.get_mut(&buffer_id) {
                 Some(buff) => buff,
@@ -243,6 +246,28 @@ pub fn handler(vm: &mut Vm) {
                 vm.registers[3] = x
             }
         }
+        6 => {
+            // Wait till interrupt
+            use crate::kmain::EXECUTOR;
+            let interrupt_type = vm.registers[3].cast::<u8>();
+            debug!("Interrupt subscribed: {}", interrupt_type);
+            unsafe {
+                LazyCell::<Executor>::get_mut(&mut EXECUTOR)
+                    .unwrap()
+                    .interrupt_subscribe(*pid, interrupt_type);
+            }
+        }
+        7 => {
+            // Wait till buffer
+            use crate::kmain::EXECUTOR;
+            let buffer_id = vm.registers[3].cast::<u64>() as usize;
+            debug!("Buffer subscribed: {}", buffer_id);
+            unsafe {
+                LazyCell::<Executor>::get_mut(&mut EXECUTOR)
+                    .unwrap()
+                    .buffer_subscribe(*pid, buffer_id);
+            }
+        }
         _ => {
             log::error!("Syscall unknown {:?}{:?}", ecall_number, vm.registers);
         }
diff --git a/kernel/src/holeybytes/mod.rs b/kernel/src/holeybytes/mod.rs
index 2c4dbab..ab68d04 100644
--- a/kernel/src/holeybytes/mod.rs
+++ b/kernel/src/holeybytes/mod.rs
@@ -65,7 +65,12 @@ impl<'p> Future for ExecThread {
                 return Poll::Ready(Err(err));
             }
             Ok(VmRunOk::End) => return Poll::Ready(Ok(())),
-            Ok(VmRunOk::Ecall) => ecah::handler(&mut self.vm),
+            Ok(VmRunOk::Ecall) => ecah::handler(
+                &mut self.vm,
+                cx.ext()
+                    .downcast_ref()
+                    .expect("PID did not exist in Context"),
+            ),
             Ok(VmRunOk::Timer) => (),
             Ok(VmRunOk::Breakpoint) => {
                 log::error!(
diff --git a/kernel/src/kmain.rs b/kernel/src/kmain.rs
index 625b9cd..8d9d398 100644
--- a/kernel/src/kmain.rs
+++ b/kernel/src/kmain.rs
@@ -22,12 +22,16 @@ use {
 pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
     debug!("Entered kmain");
 
-    #[cfg(feature = "ktest")] {
-        use crate::ktest;
-        debug!("TESTING");
+    #[cfg(feature = "ktest")]
+    {
+        use {
+			crate::ktest,
+			log::info,
+		};
+        info!("Running tests");
         ktest::test_main();
 
-        loop {};
+        loop {}
     }
 
     // let kcmd = build_cmd("Kernel Command Line", cmdline);
@@ -75,6 +79,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
         "Graphics front ptr {:?}",
         fb1.address.as_ptr().unwrap() as *const u8
     );
+    log::info!("Started AbleOS");
 
     unsafe {
         let executor = LazyCell::<Executor>::force_mut(&mut EXECUTOR);
@@ -120,7 +125,7 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
             if cmd_len > 0 {
                 thr.set_arguments(cmd.as_ptr() as u64, cmd_len);
             }
-            executor.spawn(Box::pin(async move {
+            executor.spawn(Box::pin(async {
                 if let Err(e) = thr.await {
                     log::error!("{e:?}");
                 }
@@ -131,7 +136,6 @@ pub fn kmain(_cmdline: &str, boot_modules: BootModules) -> ! {
 
         executor.run();
     };
-
     crate::arch::spin_loop()
 }
 
diff --git a/kernel/src/ktest.rs b/kernel/src/ktest.rs
index 43a2a11..c194445 100644
--- a/kernel/src/ktest.rs
+++ b/kernel/src/ktest.rs
@@ -1,38 +1,51 @@
-pub use ktest_macro::ktest;
-use log::debug;
+pub use ktest_macro::*;
+
+use {
+	alloc::string::String,
+	log::{error, info},
+};
 
 extern "C" {
-    static __ktest_start: fn();
-    static __ktest_end: fn();
+    static __ktest_start: fn() -> Result<String, String>;
+    static __ktest_end: fn() -> Result<String, String>;
 }
 
-// TODO: Get test_fn linker name (may require no_mangle in macro)
-//       More info on tests (run the rest even if panic)
-//       Implement ktest for arm and riscv (Later problems, see below)
+// TODO: Implement ktest for arm and riscv (Later problems, see below)
 //       Allow for arch specific tests (Leave for now)
-//       Allow for ktest test name attr
-//       Usefull message at the end of testing
+//       Should panic tests
+//       Test specific panic handler
 pub fn test_main() {
     unsafe {
-        let mut current_test = &__ktest_start as *const fn();
-        let mut current = 1;
-        let test_end = &__ktest_end as *const fn();        
+        let mut current_test = &__ktest_start as *const fn() -> Result<String, String>;
+        let test_end = &__ktest_end as *const fn() -> Result<String, String>;
+
+		let mut pass = 0;
+		let mut fail = 0;
 
         while current_test < test_end {
             let test_fn = *current_test;
 
-            debug!("Running test {}", current);
-            
-            test_fn();
-            debug!("Test {} passed", current);
+            let test_name = test_fn();
+            match test_name {
+                Ok(name) => {
+                    info!("Test: {} passed", name);
+                    pass += 1;
+                },
+                Err(name) => {
+                    error!("Test: {} failed", name);
+                    fail += 1;
+                }
+            }
 
             current_test = current_test.add(1);
-            current += 1;
         }
+
+        info!("{}/{} tests passed", pass, pass + fail);
     }
 }
 
 #[ktest]
 pub fn trivial_assertion() {
-    assert_eq!(1, 1);
-}
\ No newline at end of file
+    ktest_eq!(1, 1);
+	ktest_neq!(0, 1);
+}
diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs
index 52956ec..b0005d8 100644
--- a/kernel/src/lib.rs
+++ b/kernel/src/lib.rs
@@ -10,9 +10,11 @@
     abi_x86_interrupt,
     lazy_get,
     alloc_error_handler,
+    local_waker,
+    context_ext,
     ptr_sub_ptr,
     naked_functions,
-    pointer_is_aligned_to,
+    pointer_is_aligned_to
 )]
 #![allow(dead_code, internal_features, static_mut_refs)]
 extern crate alloc;
@@ -32,10 +34,9 @@ mod memory;
 mod task;
 mod utils;
 
-// #[cfg(feature = "tests")]
+#[allow(improper_ctypes, non_upper_case_globals)]
 mod ktest;
 
-use alloc::string::ToString;
 use versioning::Version;
 
 /// Kernel's version
@@ -48,6 +49,7 @@ pub const VERSION: Version = Version {
 #[panic_handler]
 #[cfg(target_os = "none")]
 fn panic(info: &core::panic::PanicInfo) -> ! {
+    use alloc::string::ToString;
     arch::register_dump();
 
     if let Some(loc) = info.location() {
diff --git a/kernel/src/task.rs b/kernel/src/task.rs
index 3326871..8807505 100644
--- a/kernel/src/task.rs
+++ b/kernel/src/task.rs
@@ -1,9 +1,14 @@
 use {
-    alloc::{boxed::Box, sync::Arc},
+    alloc::{
+        boxed::Box,
+        collections::{BTreeMap, BTreeSet},
+        sync::Arc,
+    },
     core::{
         future::Future,
         pin::Pin,
-        task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
+        sync::atomic::{AtomicBool, Ordering},
+        task::{Context, ContextBuilder, Poll, RawWaker, RawWakerVTable, Waker},
     },
     crossbeam_queue::SegQueue,
     slab::Slab,
@@ -14,7 +19,6 @@ pub fn yield_now() -> impl Future<Output = ()> {
     impl Future for YieldNow {
         type Output = ();
 
-        #[inline(always)]
         fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
             if self.0 {
                 Poll::Ready(())
@@ -29,150 +33,184 @@ pub fn yield_now() -> impl Future<Output = ()> {
     YieldNow(false)
 }
 
+pub trait Process: Future<Output = ()> + Send {}
+impl<T: Future<Output = ()> + Send> Process for T {}
+
 pub struct Executor {
-    tasks:      Slab<Task>,
-    task_queue: Arc<TaskQueue>,
+    tasks: Slab<Task>,
+    task_queue: Arc<SegQueue<usize>>,
+    interrupt_lookup: [Option<usize>; u8::MAX as usize],
+    buffer_lookup: BTreeMap<usize, BTreeSet<usize>>,
 }
 
 impl Executor {
     pub fn new() -> Self {
         Self {
-            tasks:      Slab::new(),
-            task_queue: Arc::new(TaskQueue::new()),
+            tasks: Slab::new(),
+            task_queue: Arc::new(SegQueue::new()),
+            interrupt_lookup: [None; u8::MAX as usize],
+            buffer_lookup: BTreeMap::new(),
         }
     }
 
-    #[inline]
-    pub fn spawn(&mut self, future: Pin<Box<dyn Future<Output = ()> + Send>>) -> usize {
+    pub fn spawn(&mut self, future: Pin<Box<dyn Process>>) -> usize {
         let id = self.tasks.insert(Task::new(future));
-        self.task_queue.queue.push(id);
+        self.task_queue.push(id);
+
         id
     }
 
+    pub fn pause(&self, id: usize) {
+        if let Some(task) = self.tasks.get(id) {
+            task.set_paused(true);
+        }
+    }
+
+    pub fn unpause(&self, id: usize) {
+        if let Some(task) = self.tasks.get(id) {
+            task.set_paused(false);
+            self.task_queue.push(id);
+        }
+    }
+
+    pub fn interrupt_subscribe(&mut self, pid: usize, interrupt_type: u8) {
+        self.pause(pid);
+        self.interrupt_lookup[interrupt_type as usize] = Some(pid);
+    }
+
+    pub fn buffer_subscribe(&mut self, pid: usize, buffer_id: usize) {
+        self.pause(pid);
+        if let Some(buf) = self.buffer_lookup.get_mut(&buffer_id) {
+            buf.insert(pid);
+        } else {
+            self.buffer_lookup.insert(buffer_id, BTreeSet::from([pid]));
+        }
+    }
+
     pub fn run(&mut self) {
         let mut task_batch = [0; 32];
-        let mut batch_len = 0;
-
         loop {
-            self.task_queue.batch_pop(&mut task_batch, &mut batch_len);
+            let mut batch_len = 0;
 
-            if batch_len == 0 {
-                if self.task_queue.is_empty() {
+            while let Some(id) = self.task_queue.pop() {
+                task_batch[batch_len] = id;
+                batch_len += 1;
+                if batch_len == task_batch.len() {
                     break;
-                } else {
-                    continue;
                 }
             }
 
-            for &id in &task_batch[..batch_len] {
-                if let Some(task) = self.tasks.get_mut(id) {
-                    let waker = task
-                        .waker
-                        .get_or_insert_with(|| TaskWaker::new(id, Arc::clone(&self.task_queue)));
+            if batch_len == 0 {
+                // break;
+                continue;
+            }
 
-                    let waker = unsafe { Waker::from_raw(TaskWaker::into_raw_waker(waker)) };
-                    let mut cx = Context::from_waker(&waker);
+            for &(mut id) in &task_batch[..batch_len] {
+                if let Some(task) = self.tasks.get_mut(id) {
+                    if task.is_paused() {
+                        continue;
+                    }
+
+                    let waker = create_waker(id, Arc::clone(&self.task_queue));
+                    let mut cx = ContextBuilder::from_waker(&waker).ext(&mut id).build();
 
                     if let Poll::Ready(()) = task.poll(&mut cx) {
                         self.tasks.remove(id);
-                        self.task_queue.free_tasks.push(id);
+                        self.interrupt_lookup.map(|pid| {
+                            if let Some(pid) = pid {
+                                if pid == id {
+                                    return None;
+                                }
+                            }
+                            return pid;
+                        });
+                        self.buffer_lookup.iter_mut().for_each(|(_, pid_set)| {
+                            pid_set.remove(&id);
+                        });
                     }
                 }
             }
         }
     }
+
+    pub fn send_interrupt(&self, interrupt: u8) {
+        let id = self.interrupt_lookup[interrupt as usize];
+        if let Some(id) = id {
+            self.unpause(id);
+        }
+    }
+    pub fn send_buffer(&self, id: usize) {
+        if let Some(buf) = self.buffer_lookup.get(&id) {
+            buf.iter().for_each(|pid| self.unpause(*pid));
+        }
+    }
 }
 
 struct Task {
-    future: Pin<Box<dyn Future<Output = ()> + Send>>,
-    waker:  Option<TaskWaker>,
+    future: Pin<Box<dyn Process>>,
+    paused: AtomicBool,
 }
 
 impl Task {
-    #[inline(always)]
-    pub fn new(future: Pin<Box<dyn Future<Output = ()> + Send>>) -> Self {
+    fn new(future: Pin<Box<dyn Process>>) -> Self {
         Self {
             future,
-            waker: None,
+            paused: AtomicBool::new(false),
         }
     }
 
-    #[inline(always)]
     fn poll(&mut self, cx: &mut Context) -> Poll<()> {
         self.future.as_mut().poll(cx)
     }
+
+    fn is_paused(&self) -> bool {
+        self.paused.load(Ordering::Acquire)
+    }
+
+    fn set_paused(&self, paused: bool) {
+        self.paused.store(paused, Ordering::Release)
+    }
 }
 
+fn create_waker(task_id: usize, task_queue: Arc<SegQueue<usize>>) -> Waker {
+    let data = Box::new(TaskWaker {
+        task_id,
+        task_queue,
+    });
+    let raw_waker = RawWaker::new(Box::into_raw(data) as *const (), &VTABLE);
+    unsafe { Waker::from_raw(raw_waker) }
+}
+
+#[derive(Clone)]
 struct TaskWaker {
-    id: usize,
-    task_queue: Arc<TaskQueue>,
+    task_id:    usize,
+    task_queue: Arc<SegQueue<usize>>,
 }
 
 impl TaskWaker {
-    #[inline(always)]
-    fn new(id: usize, task_queue: Arc<TaskQueue>) -> Self {
-        Self { id, task_queue }
-    }
-
-    #[inline(always)]
     fn wake(&self) {
-        self.task_queue.queue.push(self.id);
-    }
-
-    fn into_raw_waker(waker: &TaskWaker) -> RawWaker {
-        let ptr = waker as *const TaskWaker;
-        RawWaker::new(ptr.cast(), &VTABLE)
+        self.task_queue.push(self.task_id);
     }
 }
 
 const VTABLE: RawWakerVTable = RawWakerVTable::new(clone_raw, wake_raw, wake_by_ref_raw, drop_raw);
 
 unsafe fn clone_raw(ptr: *const ()) -> RawWaker {
-    let waker = &*(ptr as *const TaskWaker);
-    TaskWaker::into_raw_waker(waker)
+    let task_waker = Box::from_raw(ptr as *mut TaskWaker);
+    let raw_waker = RawWaker::new(Box::into_raw(task_waker.clone()) as *const (), &VTABLE);
+    raw_waker
 }
 
 unsafe fn wake_raw(ptr: *const ()) {
-    let waker = &*(ptr as *const TaskWaker);
-    waker.wake();
+    let task_waker = Box::from_raw(ptr as *mut TaskWaker);
+    task_waker.wake();
 }
 
 unsafe fn wake_by_ref_raw(ptr: *const ()) {
-    let waker = &*(ptr as *const TaskWaker);
-    waker.wake();
+    let task_waker = &*(ptr as *const TaskWaker);
+    task_waker.wake();
 }
 
-unsafe fn drop_raw(_: *const ()) {}
-
-struct TaskQueue {
-    queue:      SegQueue<usize>,
-    next_task:  usize,
-    free_tasks: SegQueue<usize>,
-}
-
-impl TaskQueue {
-    fn new() -> Self {
-        Self {
-            queue:      SegQueue::new(),
-            next_task:  0,
-            free_tasks: SegQueue::new(),
-        }
-    }
-
-    #[inline(always)]
-    fn batch_pop(&self, output: &mut [usize], len: &mut usize) {
-        *len = 0;
-        while let Some(id) = self.queue.pop() {
-            output[*len] = id;
-            *len += 1;
-            if *len == output.len() {
-                break;
-            }
-        }
-    }
-
-    #[inline(always)]
-    fn is_empty(&self) -> bool {
-        self.queue.is_empty()
-    }
+unsafe fn drop_raw(ptr: *const ()) {
+    drop(Box::from_raw(ptr as *mut TaskWaker));
 }
diff --git a/repbuild/src/dev.rs b/repbuild/src/dev.rs
index 48f90e0..2f0a95a 100644
--- a/repbuild/src/dev.rs
+++ b/repbuild/src/dev.rs
@@ -83,7 +83,8 @@ impl Package {
                 &path,
                 Options {
                     fmt: true,
-                    in_house_regalloc: true,
+                    resolver: Some(hblang::ABLEOS_PATH_RESOLVER),
+
                     ..Default::default()
                 },
                 out,
@@ -99,7 +100,7 @@ impl Package {
             hblang::run_compiler(
                 &path,
                 Options {
-                    in_house_regalloc: true,
+                    resolver: Some(hblang::ABLEOS_PATH_RESOLVER),
                     ..Default::default()
                 },
                 out,
@@ -111,8 +112,9 @@ impl Package {
             hblang::run_compiler(
                 &path,
                 Options {
+                    resolver: Some(hblang::ABLEOS_PATH_RESOLVER),
                     dump_asm: true,
-                    in_house_regalloc: true,
+
                     ..Default::default()
                 },
                 out,
diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs
index 5a80bf4..d361cbc 100644
--- a/repbuild/src/main.rs
+++ b/repbuild/src/main.rs
@@ -460,6 +460,10 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
                 // "-serial", "stdio",
                 "-m", "2G",
                 "-smp", "1",
+																"-audiodev",
+																"pa,id=speaker",
+																"-machine",
+																"pcspk-audiodev=speaker",
                 "-parallel", "none",
                 "-monitor", "none",
                 "-machine", accel,
@@ -485,7 +489,7 @@ fn run(release: bool, target: Target, do_accel: bool) -> Result<(), Error> {
             #[rustfmt::skip]
             com.args([
                 "-M", "virt",
-                "-cpu", "neoverse-n2",
+                "-cpu", "max",
                 "-device", "ramfb",
                 "-device", "qemu-xhci",
                 "-device", "usb-kbd",
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index a0db7f5..b37e5aa 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,5 +1,7 @@
 [toolchain]
 # old toolchain
 # channel = "nightly-2024-07-27"
-channel = "nightly-2024-11-20"
+# last stable
+# channel = "nightly-2024-11-20"
+channel = "nightly"
 components = ["rust-src", "llvm-tools"]
diff --git a/sysdata/libraries/horizon_api/src/lib.hb b/sysdata/libraries/horizon_api/src/lib.hb
index 112bbac..bae1ba6 100644
--- a/sysdata/libraries/horizon_api/src/lib.hb
+++ b/sysdata/libraries/horizon_api/src/lib.hb
@@ -26,12 +26,6 @@ create_window := fn(channel: int): ^render.Surface {
 	if windowing_system_buffer == 0 {
 		return @as(^render.Surface, idk)
 	} else {
-		// ! bad able, stop using string messages :ragey:
-		// msg := "\{01}\0"
-		// msg_length := 2
-
-		// @as(void, @eca(3, windowing_system_buffer, msg, msg_length))
-
 		x := 0
 		loop if x > 1000 break else x += 1
 
diff --git a/sysdata/libraries/horizon_api/src/widgets/label.hb b/sysdata/libraries/horizon_api/src/widgets/label.hb
index 5d1fb19..ce7e030 100644
--- a/sysdata/libraries/horizon_api/src/widgets/label.hb
+++ b/sysdata/libraries/horizon_api/src/widgets/label.hb
@@ -14,14 +14,27 @@ Label := struct {
 	text_length: uint,
 	bg: Color,
 	fg: Color,
-}
 
-set_label_text := fn(label: Label, text: ^u8): void {
-	text_length := string.length(text)
+	new_label := fn(text: ^u8): Self {
+		text_surface := render.new_surface(1024, 20)
+		text_length := string.length(text)
+		label := Self.(3, true, text_surface, text, text_length, render.black, render.white)
+		return label
+	}
 
-	label.is_dirty = true
-	label.text = text
-	label.text_length = text_length
+	set_label_text := fn(self: Self, text: ^u8): void {
+		text_length := string.length(text)
+
+		self.is_dirty = true
+		self.text = text
+		self.text_length = text_length
+	}
+
+	$set_color := fn(self: Self, bg: Color, fg: Color): void {
+		self.bg = bg
+		self.fg = fg
+		self.is_dirty = true
+	}
 }
 
 render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: Vec2(uint)): void {
@@ -30,17 +43,4 @@ render_label_to_surface := fn(surface: Surface, label: Label, font: Font, pos: V
 		render.put_text(label.surface, font, .(0, 0), label.fg, label.text)
 	}
 	render.put_surface(surface, label.surface, pos, false)
-}
-
-new_label := fn(text: ^u8): Label {
-	text_surface := render.new_surface(1024, 20)
-	text_length := string.length(text)
-	label := Label.(3, true, text_surface, text, text_length, render.black, render.white)
-	return label
-}
-
-$set_color := fn(label: Label, bg: Color, fg: Color): void {
-	label.bg = bg
-	label.fg = fg
-	label.is_dirty = true
 }
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/alloc/alloc_return.hb b/sysdata/libraries/stn/src/alloc/alloc_return.hb
new file mode 100644
index 0000000..bdc61f5
--- /dev/null
+++ b/sysdata/libraries/stn/src/alloc/alloc_return.hb
@@ -0,0 +1,4 @@
+AllocReturn := struct {
+	byte_count: uint,
+	ptr: ?^u8,
+}
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/alloc/block_alloc.hb b/sysdata/libraries/stn/src/alloc/block_alloc.hb
new file mode 100644
index 0000000..7cca606
--- /dev/null
+++ b/sysdata/libraries/stn/src/alloc/block_alloc.hb
@@ -0,0 +1,90 @@
+.{log, panic, memory} := @use("../lib.hb")
+alloc_return := @use("alloc_return.hb")
+
+/* the block size is 64 bytes, 64 blocks of 64 bytes.
+   this will very quickly lead to exhaustion of free blocks.
+*/
+BlockAlloc := struct {
+	// hi
+	state: uint,
+	ptr: ?^u8,
+
+	$init := fn(): Self {
+		alloc_page_ptr := memory.request_page(1)
+		state := 0xFFFFFFFFFFFFFFFF
+		return .(state, alloc_page_ptr)
+	}
+
+	alloc := fn(self: Self, alloc_type: type, count: uint): alloc_return.AllocReturn {
+		offset := 0
+		state_2 := 0
+		loop {
+			xyz := self.state & 1
+			abc := if xyz == 1 {
+				true
+			} else {
+				false
+			}
+			// check if the `offset` bit is 1, if it is move to the next offset
+			if abc {
+				offset += 1
+				return .(0, null)
+			} else {
+				log.info("Already Allocated\0")
+			}
+
+			// else {
+			// 	// self it to 1 and return the ptr to the allocation
+			// 	self.state |= a
+			// 	// return ptr + offset * 64
+			// 	if self.ptr != null {
+			// 		return .(64, self.ptr + offset * 64)
+			// 	} else {
+			// 		// panic.panic("Allocator is not inited.\0")
+			// 		// return .(0, null)
+			// 	}
+			// }
+			// there are only 64 blocks
+			if offset >= 64 {
+				return .(0, null)
+			}
+		}
+	}
+
+	dealloc := fn(self: Self, ptr: ^u8, alloc_type: type, count: uint): void {
+		// size := size_of(alloc_type)*count
+		size := 64
+		// get the size alligned to the nearest block
+		// rounded_size := nearest_block_size_rounded_up(size)
+		rounded_size := 64
+
+		state_bit_start := {
+			// Do math here to figure out what starting ptr corresponds to what bit
+			3
+		}
+
+		offset := 0
+
+		loop {
+			if rounded_size > 0 {
+				// set state_bit_start+offset to 0
+
+				// at the end move to the next one
+				offset += 1
+			} else {
+				break
+			}
+
+			rounded_size -= 64
+		}
+		return void
+	}
+
+	$deinit := fn(self: Self): void {
+		self.state = 0
+		self.ptr = null
+	}
+}
+
+// request a kernel page
+// ptr := memory.alloc(1)
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/alloc/fake_alloc.hb b/sysdata/libraries/stn/src/alloc/fake_alloc.hb
new file mode 100644
index 0000000..82c422a
--- /dev/null
+++ b/sysdata/libraries/stn/src/alloc/fake_alloc.hb
@@ -0,0 +1,19 @@
+alloc_return := @use("alloc_return.hb")
+
+FakeAlloc := struct {
+	$init := fn(): Self {
+		return .()
+	}
+
+	$alloc := fn(self: Self, alloc_type: type, count: uint): alloc_return.AllocReturn {
+		return .(0, null)
+	}
+
+	$dealloc := fn(self: Self, ptr: ^u8, alloc_type: type, count: uint): void {
+		return void
+	}
+	// Nothing to clean up here
+	$deinit := fn(self: Self): void {
+		return void
+	}
+}
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/alloc/lib.hb b/sysdata/libraries/stn/src/alloc/lib.hb
new file mode 100644
index 0000000..f80a361
--- /dev/null
+++ b/sysdata/libraries/stn/src/alloc/lib.hb
@@ -0,0 +1,2 @@
+.{BlockAlloc} := @use("block_alloc.hb");
+.{FakeAlloc} := @use("fake_alloc.hb")
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/alloc/main.hb b/sysdata/libraries/stn/src/alloc/main.hb
new file mode 100644
index 0000000..138d53c
--- /dev/null
+++ b/sysdata/libraries/stn/src/alloc/main.hb
@@ -0,0 +1,25 @@
+allocators := @use("alloc/alloc.hb")
+
+AStruct := struct {
+    a_field: u8,
+}
+
+main := fn():void{
+    alloc := allocators.FakeAlloc.init()
+    astruct := alloc.alloc(AStruct, 2)
+    if astruct.ptr != null{
+        panic("FakeAlloc actually allocated.")
+    }
+    alloc.dealloc(astruct_ptr, AStruct, 2)
+    alloc.deinit()
+
+    balloc := allocators.BlockAlloc.init()
+    bstruct_ptr := balloc.alloc(AStruct, 2)
+    if bstruct_ptr == null {
+        panic("BlockAlloc actually didn't allocate.")
+    }
+    balloc.dealloc(bstruct_ptr, AStruct, 2)
+    balloc.deinit()
+
+
+}
diff --git a/sysdata/libraries/stn/src/buffer.hb b/sysdata/libraries/stn/src/buffer.hb
index 17f5a3f..495f53a 100644
--- a/sysdata/libraries/stn/src/buffer.hb
+++ b/sysdata/libraries/stn/src/buffer.hb
@@ -1,5 +1,9 @@
 string := @use("string.hb")
 
+$await := fn(buffer_id: uint): void {
+	return @eca(7, buffer_id)
+}
+
 $recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void {
 	return @eca(4, buffer_id, memory_map_location, @sizeof(Expr))
 }
diff --git a/sysdata/libraries/stn/src/hash/foldhash.hb b/sysdata/libraries/stn/src/hash/foldhash.hb
new file mode 100644
index 0000000..2aa9e1b
--- /dev/null
+++ b/sysdata/libraries/stn/src/hash/foldhash.hb
@@ -0,0 +1,189 @@
+/*
+* This code is an implementation of the FoldHash algorithm from https://github.com/orlp/foldhash,
+* originally written by Orson Peters under the zlib license.
+*
+* Changes to the original code were made to meet the simplicity requirements of this implementation.
+* Behaviour aims to be equivalent but not identical to the original code.
+*
+* Copyright (c) 2024 Orson Peters
+* 
+* This software is provided 'as-is', without any express or implied warranty. In
+* no event will the authors be held liable for any damages arising from the use of
+* this software.
+* 
+* Permission is granted to anyone to use this software for any purpose, including
+* commercial applications, and to alter it and redistribute it freely, subject to
+* the following restrictions:
+* 
+* 1. The origin of this software must not be misrepresented; you must not claim
+*     that you wrote the original software. If you use this software in a product,
+*     an acknowledgment in the product documentation would be appreciated but is
+*     not required.
+* 
+* 2. Altered source versions must be plainly marked as such, and must not be
+*     misrepresented as being the original software.
+* 
+* 3. This notice may not be removed or altered from any source distribution.
+*/;
+
+.{math, random} := @use("../lib.hb")
+
+$ARBITRARY0 := 0x243F6A8885A308D3
+$ARBITRARY1 := 0x13198A2E03707344
+$ARBITRARY2 := 0xA4093822299F31D0
+$ARBITRARY3 := 0x82EFA98EC4E6C89
+$ARBITRARY4 := 0x452821E638D01377
+$ARBITRARY5 := 0xBE5466CF34E90C6C
+$ARBITRARY6 := 0xC0AC29B7C97C50DD
+$ARBITRARY7 := 0x3F84D5B5B5470917
+$ARBITRARY8 := 0x9216D5D98979FB1B
+$ARBITRARY9 := 0xD1310BA698DFB5AC
+$FIXED_GLOBAL_SEED := [uint].(ARBITRARY4, ARBITRARY5, ARBITRARY6, ARBITRARY7)
+
+global_seed := 0
+
+u128 := packed struct {a: uint, b: uint}
+
+$folded_multiply := fn(x: uint, y: uint): uint {
+	lx := @as(u32, @intcast(x))
+	ly := @as(u32, @intcast(y))
+	hx := x >> 32
+	hy := y >> 32
+	afull := lx * hy
+	bfull := hx * ly
+	return afull ^ (bfull << 32 | bfull >> 32)
+}
+
+hash_bytes_medium := fn(bytes: ^u8, len: uint, s0: uint, s1: uint, fold_seed: uint): uint {
+	lo := bytes
+	end := bytes + len
+	hi := end - 16
+
+	loop if lo >= hi break else {
+		a := *@as(^uint, @bitcast(lo))
+		b := *@as(^uint, @bitcast(lo + 8))
+		c := *@as(^uint, @bitcast(hi))
+		d := *@as(^uint, @bitcast(hi + 8))
+		s0 = folded_multiply(a ^ s0, c ^ fold_seed)
+		s1 = folded_multiply(b ^ s1, d ^ fold_seed)
+		hi -= 16
+		lo += 16
+	}
+	return s0 ^ s1
+}
+
+hash_bytes_long := fn(bytes: ^u8, len: uint, s0: uint, s1: uint, s2: uint, s3: uint, fold_seed: uint): uint {
+	$chunk_size := 64
+	chunks := len / chunk_size
+	remainder := len % chunk_size
+
+	ptr := bytes
+	i := 0
+	loop if i >= chunks break else {
+		a := *@as(^uint, @bitcast(ptr))
+		b := *@as(^uint, @bitcast(ptr + 8))
+		c := *@as(^uint, @bitcast(ptr + 16))
+		d := *@as(^uint, @bitcast(ptr + 24))
+		e := *@as(^uint, @bitcast(ptr + 32))
+		f := *@as(^uint, @bitcast(ptr + 40))
+		g := *@as(^uint, @bitcast(ptr + 48))
+		h := *@as(^uint, @bitcast(ptr + 56))
+
+		s0 = folded_multiply(a ^ s0, e ^ fold_seed)
+		s1 = folded_multiply(b ^ s1, f ^ fold_seed)
+		s2 = folded_multiply(c ^ s2, g ^ fold_seed)
+		s3 = folded_multiply(d ^ s3, h ^ fold_seed)
+
+		ptr += chunk_size
+		i += 1
+	}
+
+	s0 ^= s2
+	s1 ^= s3
+
+	if remainder > 0 {
+		remainder_start := bytes + len - math.max(uint, remainder, 16)
+		return hash_bytes_medium(remainder_start, math.max(uint, remainder, 16), s0, s1, fold_seed)
+	}
+
+	return s0 ^ s1
+}
+
+FoldHasher := struct {
+	accumulator: uint,
+	original_seed: uint,
+	sponge: u128,
+	sponge_len: u8,
+	fold_seed: uint,
+	expand_seed: uint,
+	expand_seed2: uint,
+	expand_seed3: uint,
+
+	$new := fn(seed: uint): Self {
+		return .(
+			seed,
+			seed,
+			.(0, 0),
+			0,
+			FIXED_GLOBAL_SEED[0],
+			FIXED_GLOBAL_SEED[1],
+			FIXED_GLOBAL_SEED[2],
+			FIXED_GLOBAL_SEED[3],
+		)
+	}
+
+	default := fn(): Self {
+		if global_seed == 0 {
+			// ! consider this "secure enough" for now
+			global_seed = random.any(uint)
+		}
+		return Self.new(global_seed)
+	}
+
+	write := fn(self: ^Self, bytes: ^u8, len: uint): void {
+		s0 := self.accumulator
+		s1 := self.expand_seed
+		if len <= 16 {
+			if len >= 8 {
+				s0 ^= *@bitcast(bytes)
+				s1 ^= *@bitcast(bytes + len - 8)
+			} else if len >= 4 {
+				s0 ^= *@as(^u32, @bitcast(bytes))
+				s1 ^= *@as(^u32, @bitcast(bytes + len - 4))
+			} else if len > 0 {
+				lo := *bytes
+				mid := *(bytes + len / 2)
+				hi := *(bytes + len - 1)
+				s0 ^= lo
+				s1 ^= @as(uint, hi) << 8 | mid
+			}
+			self.accumulator = folded_multiply(s0, s1)
+		} else if len < 256 {
+			self.accumulator = hash_bytes_medium(bytes, len, s0, s1, self.fold_seed)
+		} else {
+			self.accumulator = hash_bytes_long(
+				bytes,
+				len,
+				s0,
+				s1,
+				self.expand_seed2,
+				self.expand_seed3,
+				self.fold_seed,
+			)
+		}
+	}
+
+	finish := fn(self: ^Self): uint {
+		if self.sponge_len > 0 {
+			return folded_multiply(self.sponge.b ^ self.accumulator, self.sponge.a ^ self.fold_seed)
+		} else {
+			return self.accumulator
+		}
+	}
+
+	reset := fn(self: ^Self): void {
+		self.accumulator = self.original_seed
+		self.sponge = .(0, 0)
+		self.sponge_len = 0
+	}
+}
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/hash/lib.hb b/sysdata/libraries/stn/src/hash/lib.hb
new file mode 100644
index 0000000..da97bfd
--- /dev/null
+++ b/sysdata/libraries/stn/src/hash/lib.hb
@@ -0,0 +1,2 @@
+//! NON CRYPTOGRAPHIC HASHER
+foldhash := @use("foldhash.hb")
\ No newline at end of file
diff --git a/sysdata/libraries/stn/src/lib.hb b/sysdata/libraries/stn/src/lib.hb
index 961037c..9391917 100644
--- a/sysdata/libraries/stn/src/lib.hb
+++ b/sysdata/libraries/stn/src/lib.hb
@@ -1,4 +1,6 @@
 acs := @use("acs.hb")
+allocators := @use("alloc/lib.hb")
+hashers := @use("hash/lib.hb")
 string := @use("string.hb")
 log := @use("log.hb")
 memory := @use("memory.hb")
@@ -8,6 +10,7 @@ random := @use("random.hb")
 file := @use("file_io.hb")
 dt := @use("dt.hb")
 process := @use("process.hb")
+sleep := @use("sleep.hb")
 
 panic := fn(message: ?^u8): never {
 	log.error("Error: Panic Called, Message:\0")
diff --git a/sysdata/libraries/stn/src/sleep.hb b/sysdata/libraries/stn/src/sleep.hb
index d323267..5aeaf14 100644
--- a/sysdata/libraries/stn/src/sleep.hb
+++ b/sysdata/libraries/stn/src/sleep.hb
@@ -3,4 +3,5 @@ subscribe_to_interrupt := fn(interrupt_number: u8): bool {
 }
 // Pauses execution until the interrupt occures
 sleep_until_interrupt := fn(interrupt_number: u8): void {
+	@eca(6, interrupt_number)
 }
\ No newline at end of file
diff --git a/sysdata/libraries/sunset_proto/src/lib.hb b/sysdata/libraries/sunset_proto/src/lib.hb
index f75dfb2..9be50d8 100644
--- a/sysdata/libraries/sunset_proto/src/lib.hb
+++ b/sysdata/libraries/sunset_proto/src/lib.hb
@@ -1,4 +1,4 @@
-.{math: .{Vec2}, buffer, memory} := @use("../../stn/src/lib.hb");
+.{math: .{Vec2}, buffer, memory} := @use("stn");
 .{Surface} := @use("../../render/src/lib.hb")
 
 $BUFFER_SERVER := "sunset_server\0"
@@ -48,6 +48,8 @@ await_channel := fn(): Channel {
 await_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
 	response := @as(?Message(Expr), null)
 	loop {
+		// awaiting here causes flickering... idk why
+		buffer.await(buffer_id)
 		buffer.recv(?Message(Expr), buffer_id, &response)
 		if response != null {
 			return @as(Message(Expr), response)
@@ -58,9 +60,11 @@ await_message := fn($Expr: type, buffer_id: uint): Message(Expr) {
 await_header := fn(buffer_id: uint): MessageHeader {
 	response := @as(?MessageHeader, null)
 	loop {
+		// awaiting here causes flickering... idk why
+		buffer.await(buffer_id)
 		buffer.recv(?MessageHeader, buffer_id, &response)
 		if response != null {
-			return @as(?MessageHeader, response)
+			return @as(MessageHeader, response)
 		}
 	}
 }
diff --git a/sysdata/libraries/sunset_proto/src/server.hb b/sysdata/libraries/sunset_proto/src/server.hb
index 4850ce6..4dd16d9 100644
--- a/sysdata/libraries/sunset_proto/src/server.hb
+++ b/sysdata/libraries/sunset_proto/src/server.hb
@@ -1,6 +1,6 @@
-.{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb");
-.{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text, clear, white, black} := @use("../../render/src/lib.hb");
-.{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("./lib.hb")
+.{math, log, string, random, buffer, memory} := @use("stn");
+.{Color, Surface, new_surface, put_surface, sync, put_rect, put_filled_rect, text, put_text, clear, white, black} := @use("lib:render");
+.{Channel, Window, WindowProps, WindowData, MessageHeader, BUFFER_SERVER, BUFFER_CLIENT, message, permissions, recv_header, recv_message, send_message, send_header, await_message} := @use("lib:sunset_proto")
 
 WindowServer := struct {
 	window_count: uint,
diff --git a/sysdata/programs/dt_buffer_test/README.md b/sysdata/programs/dt_buffer_test/README.md
deleted file mode 100644
index c01a7c5..0000000
--- a/sysdata/programs/dt_buffer_test/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# dt_buffer_test
\ No newline at end of file
diff --git a/sysdata/programs/dt_buffer_test/src/main.hb b/sysdata/programs/dt_buffer_test/src/main.hb
deleted file mode 100644
index 7d37f6a..0000000
--- a/sysdata/programs/dt_buffer_test/src/main.hb
+++ /dev/null
@@ -1,13 +0,0 @@
-.{dt} := @use("../../../libraries/stn/src/lib.hb")
-
-main := fn(): void {
-	dt.get(void, "framebuffer/fb0/width\0")
-	dt.get(void, "cpu/cpu0/architecture\0")
-
-	// Checking if the first detected serial port is memory mapped or port mapped
-	// 0 -> memory mapped
-	// 1 -> port mapped
-	dt.get(void, "serial_ports/sp0/mapping\0")
-
-	return
-}
\ No newline at end of file
diff --git a/sysdata/programs/pcspkr/README.md b/sysdata/programs/pcspkr/README.md
new file mode 100644
index 0000000..5a5f4b9
--- /dev/null
+++ b/sysdata/programs/pcspkr/README.md
@@ -0,0 +1 @@
+# pcspkr
\ No newline at end of file
diff --git a/sysdata/programs/processes/meta.toml b/sysdata/programs/pcspkr/meta.toml
similarity index 74%
rename from sysdata/programs/processes/meta.toml
rename to sysdata/programs/pcspkr/meta.toml
index 86a4869..d71a5f2 100644
--- a/sysdata/programs/processes/meta.toml
+++ b/sysdata/programs/pcspkr/meta.toml
@@ -1,6 +1,6 @@
 [package]
-name = "processes"
-authors = ["koniifer"]
+name = "pcspkr"
+authors = [""]
 
 [dependants.libraries]
 
diff --git a/sysdata/programs/pcspkr/src/main.hb b/sysdata/programs/pcspkr/src/main.hb
new file mode 100644
index 0000000..5c5055c
--- /dev/null
+++ b/sysdata/programs/pcspkr/src/main.hb
@@ -0,0 +1,45 @@
+stn := @use("../../../libraries/stn/src/lib.hb");
+.{memory, buffer, log, string, math} := stn;
+.{inb, outb} := memory
+
+$PIT_CLOCK := 1193180
+
+play_sound := fn(frequency: u32): void {
+	div := 0
+
+	div = PIT_CLOCK / frequency
+	memory.outb(0x43, 0xB6)
+	memory.outb(0x42, @intcast(div))
+	memory.outb(0x42, @intcast(div >> 8))
+
+	tmp := inb(0x61)
+	if tmp != (tmp | 3) {
+		outb(0x61, tmp | 3)
+	}
+}
+
+no_sound := fn(): void {
+	tmp := memory.inb(0x61) & 0xFC
+
+	memory.outb(0x61, tmp)
+}
+
+beep := fn(): void {
+	play_sound(1000)
+	idx := 0
+	loop {
+		if idx >= 1000000 {
+			idx += 1
+		} else {
+			break
+		}
+	}
+
+	no_sound()
+}
+
+main := fn(): int {
+	no_sound()
+	beep()
+	return 0
+}
\ No newline at end of file
diff --git a/sysdata/programs/render_example/src/main.hb b/sysdata/programs/render_example/src/main.hb
index 77cb04c..ab66cfa 100644
--- a/sysdata/programs/render_example/src/main.hb
+++ b/sysdata/programs/render_example/src/main.hb
@@ -1 +1 @@
-.{example: main} := @use("./examples/text.hb")
\ No newline at end of file
+.{example: main} := @use("./examples/orbit.hb")
\ No newline at end of file
diff --git a/sysdata/programs/sdoom/README.md b/sysdata/programs/sdoom/README.md
new file mode 100644
index 0000000..e752f1f
--- /dev/null
+++ b/sysdata/programs/sdoom/README.md
@@ -0,0 +1,4 @@
+# sdoom
+SDoom stands for simple doom.
+
+This is not a full implementation of doom and is instead a doom style renderer.
\ No newline at end of file
diff --git a/sysdata/programs/dt_buffer_test/meta.toml b/sysdata/programs/sdoom/meta.toml
similarity index 73%
rename from sysdata/programs/dt_buffer_test/meta.toml
rename to sysdata/programs/sdoom/meta.toml
index f25002e..b6e9cbd 100644
--- a/sysdata/programs/dt_buffer_test/meta.toml
+++ b/sysdata/programs/sdoom/meta.toml
@@ -1,6 +1,6 @@
 [package]
-name = "dt_buffer_test"
-authors = ["able"]
+name = "sdoom"
+authors = [""]
 
 [dependants.libraries]
 
diff --git a/sysdata/programs/sdoom/src/main.hb b/sysdata/programs/sdoom/src/main.hb
new file mode 100644
index 0000000..22aebc7
--- /dev/null
+++ b/sysdata/programs/sdoom/src/main.hb
@@ -0,0 +1,53 @@
+sunset := @use("../../../libraries/sunset_proto/src/lib.hb")
+render := @use("../../../libraries/render/src/lib.hb")
+
+stn := @use("../../../libraries/stn/src/lib.hb");
+.{log} := stn;
+.{Vec2} := stn.math
+
+Player := struct {
+	x: i8,
+	y: i8,
+
+	$new := fn(x: i8, y: i8): Self {
+		return Self.(x, y)
+	}
+}
+
+GameState := struct {
+	player: Player,
+
+	$new := fn(): Self {
+		p := Player.new(0, 0)
+		return Self.(p)
+	}
+}
+
+main := fn(): void {
+	sunset.client.find_server()
+
+	window := sunset.client.new(.(.(600, 400), .(200, 200), "SDoom\0"))
+
+	if window == null {
+		log.error("got no window\0")
+		return
+	}
+
+	game_state := GameState.new()
+
+	loop {
+		render.clear(window.surface, render.black)
+		width := 100
+		idx := 1
+
+		loop {
+			if idx >= width {
+				break
+			}
+			render.put_vline(window.surface, idx, 10, 100, render.white)
+			idx += 1
+		}
+
+		_ = sunset.client.send_frame(window)
+	}
+}
\ No newline at end of file
diff --git a/sysdata/programs/sdoom/src/player.hb b/sysdata/programs/sdoom/src/player.hb
new file mode 100644
index 0000000..e69de29
diff --git a/sysdata/programs/serial_driver_test/src/main.hb b/sysdata/programs/serial_driver_test/src/main.hb
deleted file mode 100644
index 19ad6c1..0000000
--- a/sysdata/programs/serial_driver_test/src/main.hb
+++ /dev/null
@@ -1,20 +0,0 @@
-.{string, buffer} := @use("../../../libraries/stn/src/lib.hb")
-
-log_info := fn(): void {
-	a := buffer.search("XNumber\0")
-	if a == 0 {
-	} else {
-		msg := "XABC\0"
-		// inline is broked
-		// msg_length := @inline(string.length, msg)
-		msg_length := 5
-		@as(void, @eca(3, a, msg, msg_length))
-	}
-
-	return
-}
-
-main := fn(): int {
-	log_info()
-	return 0
-}
\ No newline at end of file
diff --git a/sysdata/programs/sunset_client_2/src/main.hb b/sysdata/programs/sunset_client_2/src/main.hb
index 3fcf1c1..2e54759 100644
--- a/sysdata/programs/sunset_client_2/src/main.hb
+++ b/sysdata/programs/sunset_client_2/src/main.hb
@@ -13,7 +13,7 @@ main := fn(): void {
 		return
 	}
 
-	window := sunset.client.new(.(.(400, 300), .(400, 240), "Sunset!\0"))
+	window := sunset.client.new(.(.(400, 100), .(400, 240), "Sunset!\0"))
 
 	if window == null {
 		log.error("got no window\0")
diff --git a/sysdata/programs/sunset_server/src/main.hb b/sysdata/programs/sunset_server/src/main.hb
index 4329586..9f438d7 100644
--- a/sysdata/programs/sunset_server/src/main.hb
+++ b/sysdata/programs/sunset_server/src/main.hb
@@ -3,7 +3,7 @@ render := @use("../../../libraries/render/src/lib.hb")
 intouch := @use("../../../libraries/intouch/src/lib.hb")
 
 horizon_api := @use("../../../libraries/horizon_api/src/lib.hb");
-.{new_label, render_label_to_surface, set_label_text, set_color} := horizon_api.widgets.label
+.{set_color, render_label_to_surface, Label} := horizon_api.widgets.label
 
 stn := @use("../../../libraries/stn/src/lib.hb");
 .{Vec2} := stn.math
@@ -13,6 +13,9 @@ img := @embed("../../../assets/wallpaper.qoi")
 
 main := fn(): int {
 	sunset.server.start()
+	defer {
+		stn.log.info("Sunset Server Exit\0")
+	}
 
 	screen := render.init(true)
 	render.clear(screen, render.black)
@@ -28,8 +31,8 @@ main := fn(): int {
 	mouse_x := 100
 	mouse_y := 100
 
-	text_label := new_label("Hi\0")
-	set_color(text_label, sunset.server.DECO_COLOUR, render.black)
+	text_label := Label.new_label("Hi\0")
+	text_label.set_color(sunset.server.DECO_COLOUR, render.black)
 
 	loop {
 		mouse_event := intouch.recieve_mouse_event()
@@ -59,13 +62,13 @@ main := fn(): int {
 			}
 
 			if mouse_event.left {
-				set_label_text(text_label, "LEFT CLICK\0")
+				text_label.set_label_text("LEFT CLICK\0")
 			}
 			if mouse_event.middle {
-				set_label_text(text_label, "MIDDLE CLICK\0")
+				text_label.set_label_text("MIDDLE CLICK\0")
 			}
 			if mouse_event.right {
-				set_label_text(text_label, "RIGHT CLICK\0")
+				text_label.set_label_text("RIGHT CLICK\0")
 			}
 		}
 		{
@@ -88,8 +91,8 @@ main := fn(): int {
 
 		// Mouse cursor
 		{
-			render.put_filled_rect(screen, .(mouse_x, mouse_y), .(20, 20), sunset.server.DECO_COLOUR_DARKER)
-			render.put_rect(screen, .(mouse_x, mouse_y), .(20, 20), sunset.server.DECO_COLOUR)
+			render.put_filled_circle(screen, .(mouse_x, mouse_y), 10, sunset.server.DECO_COLOUR_DARKER)
+			render.put_circle(screen, .(mouse_x, mouse_y), 10, sunset.server.DECO_COLOUR)
 		}
 
 		render.sync(screen)
diff --git a/sysdata/programs/serial_driver_test/meta.toml b/sysdata/programs/test/meta.toml
similarity index 72%
rename from sysdata/programs/serial_driver_test/meta.toml
rename to sysdata/programs/test/meta.toml
index f8f995c..93c3dd7 100644
--- a/sysdata/programs/serial_driver_test/meta.toml
+++ b/sysdata/programs/test/meta.toml
@@ -1,6 +1,6 @@
 [package]
-name = "serial_driver_test"
-authors = ["able"]
+name = "test"
+authors = ["koniifer", "able"]
 
 [dependants.libraries]
 
diff --git a/sysdata/programs/test/src/main.hb b/sysdata/programs/test/src/main.hb
new file mode 100644
index 0000000..debec4e
--- /dev/null
+++ b/sysdata/programs/test/src/main.hb
@@ -0,0 +1,7 @@
+stn := @use("./tests/stn/lib.hb")
+serial_driver := @use("./tests/serial_driver.hb")
+
+main := fn(): uint {
+	// return serial_driver.test()
+	return stn.sleep.test()
+}
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/serial_driver.hb b/sysdata/programs/test/src/tests/serial_driver.hb
new file mode 100644
index 0000000..8e27b11
--- /dev/null
+++ b/sysdata/programs/test/src/tests/serial_driver.hb
@@ -0,0 +1,18 @@
+.{string, buffer} := @use("../../../../libraries/stn/src/lib.hb")
+
+log_info := fn(): void {
+	a := buffer.search("XNumber\0")
+	if a == 0 {
+	} else {
+		msg := "XABC\0"
+		msg_length := string.length(msg)
+		@eca(3, a, msg, msg_length)
+	}
+
+	return
+}
+
+test := fn(): uint {
+	log_info()
+	return 0
+}
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/stn/allocators.hb b/sysdata/programs/test/src/tests/stn/allocators.hb
new file mode 100644
index 0000000..8b194b7
--- /dev/null
+++ b/sysdata/programs/test/src/tests/stn/allocators.hb
@@ -0,0 +1,30 @@
+stn := @use("../../../../../libraries/stn/src/lib.hb");
+.{allocators, panic, log} := stn
+
+AStruct := struct {
+	a_field: u8,
+}
+
+test := fn(): uint {
+	// alloc := allocators.FakeAlloc.init()
+	// astruct := alloc.alloc(AStruct, 2)
+	// if astruct.ptr != null{
+	// panic.panic("FakeAlloc actually allocated.")
+	// }
+	// alloc.dealloc(&astruct.ptr, AStruct, 2)
+	// alloc.deinit()
+
+	balloc := allocators.BlockAlloc.init()
+	// defer {
+	// 	balloc.deinit()
+	// }
+	bstruct := balloc.alloc(AStruct, 2)
+	// if bstruct.ptr == null {
+	// 	log.info("Hi\0")
+	// 	// panic.panic("BlockAlloc actually didn't allocate.")
+	// } else {
+	// 	log.info("Allocator functioned.\0")
+	// }
+	// balloc.dealloc(bstruct_ptr, AStruct, 2)
+	return 0
+}
\ No newline at end of file
diff --git a/sysdata/programs/processes/src/hello_world_and_spin.hb b/sysdata/programs/test/src/tests/stn/assets/hello_world_and_spin.hb
similarity index 100%
rename from sysdata/programs/processes/src/hello_world_and_spin.hb
rename to sysdata/programs/test/src/tests/stn/assets/hello_world_and_spin.hb
diff --git a/sysdata/programs/processes/src/hello_world_and_spin.hbf b/sysdata/programs/test/src/tests/stn/assets/hello_world_and_spin.hbf
similarity index 100%
rename from sysdata/programs/processes/src/hello_world_and_spin.hbf
rename to sysdata/programs/test/src/tests/stn/assets/hello_world_and_spin.hbf
diff --git a/sysdata/programs/test/src/tests/stn/dt.hb b/sysdata/programs/test/src/tests/stn/dt.hb
new file mode 100644
index 0000000..e331f33
--- /dev/null
+++ b/sysdata/programs/test/src/tests/stn/dt.hb
@@ -0,0 +1,18 @@
+.{dt, memory, string, log} := @use("../../../../../libraries/stn/src/lib.hb")
+
+test := fn(): uint {
+	buffer := memory.request_page(1)
+
+	log.info(string.display_int(dt.get(int, "framebuffer/fb0/width\0"), buffer, 10))
+	string.clear(buffer)
+
+	log.info(string.display_int(dt.get(int, "cpu/cpu0/architecture\0"), buffer, 10))
+	string.clear(buffer)
+
+	// 0 -> memory mapped
+	// 1 -> port mapped
+
+	log.info(string.display_int(dt.get(int, "serial_ports/sp0/mapping\0"), buffer, 10))
+
+	return 0
+}
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/stn/hashers.hb b/sysdata/programs/test/src/tests/stn/hashers.hb
new file mode 100644
index 0000000..a1052d6
--- /dev/null
+++ b/sysdata/programs/test/src/tests/stn/hashers.hb
@@ -0,0 +1,32 @@
+.{hashers, log, memory, string} := @use("../../../../../libraries/stn/src/lib.hb")
+
+test := fn(): uint {
+	buffer := memory.request_page(1)
+	target := "abcdefghijklmnop\0"
+	strings := [^u8].("abcdefshijklmnop\0", "abcdefghijklnnop\0", "abcdefshijklmnop\0", "abcdefghijklmnop\0", "abcdefghijflmnop\0", "dbcdefghijklmnop\0", "abcdefghijklmnop\0")
+	len := @sizeof(@TypeOf(strings)) / @sizeof(^u8)
+	strlen := string.length(target)
+
+	// hasher := hashers.foldhash.FoldHasher.new(1)
+	hasher := hashers.foldhash.FoldHasher.default()
+	hasher.write(target, strlen)
+	correct := hasher.finish()
+
+	log.warn("target:\0")
+	log.warn(target)
+
+	i := 0
+	loop if i == len break else {
+		defer i += 1
+		hasher.reset()
+		hasher.write(strings[i], strlen)
+		d := hasher.finish()
+		if d == correct {
+			log.warn("match found\0")
+		}
+		log.info(strings[i])
+		log.debug(string.display_int(@bitcast(d), buffer, 16))
+		string.clear(buffer)
+	}
+	return 0
+}
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/stn/lib.hb b/sysdata/programs/test/src/tests/stn/lib.hb
new file mode 100644
index 0000000..da08b77
--- /dev/null
+++ b/sysdata/programs/test/src/tests/stn/lib.hb
@@ -0,0 +1,5 @@
+hashers := @use("./hashers.hb")
+allocators := @use("./allocators.hb")
+sleep := @use("./sleep.hb")
+dt := @use("./dt.hb")
+process := @use("./process.hb")
\ No newline at end of file
diff --git a/sysdata/programs/processes/src/main.hb b/sysdata/programs/test/src/tests/stn/process.hb
similarity index 61%
rename from sysdata/programs/processes/src/main.hb
rename to sysdata/programs/test/src/tests/stn/process.hb
index 06b4ade..493e36a 100644
--- a/sysdata/programs/processes/src/main.hb
+++ b/sysdata/programs/test/src/tests/stn/process.hb
@@ -1,8 +1,8 @@
-.{process, log, string, memory} := @use("../../../libraries/stn/src/lib.hb")
+.{process, log, string, memory} := @use("../../../../../libraries/stn/src/lib.hb")
 
-exe := @embed("./hello_world_and_spin.hbf")
+exe := @embed("./assets/hello_world_and_spin.hbf")
 
-main := fn(): void {
+test := fn(): uint {
 	buf := "\0\0\0\0\0\0\0"
 	loop {
 		log.info(
@@ -16,4 +16,5 @@ main := fn(): void {
 		i := 0
 		loop if i == 1000000 break else i += 1
 	}
+	return 0
 }
\ No newline at end of file
diff --git a/sysdata/programs/test/src/tests/stn/sleep.hb b/sysdata/programs/test/src/tests/stn/sleep.hb
new file mode 100644
index 0000000..9eaeb31
--- /dev/null
+++ b/sysdata/programs/test/src/tests/stn/sleep.hb
@@ -0,0 +1,8 @@
+.{sleep, log} := @use("../../../../../libraries/stn/src/lib.hb")
+
+test := fn(): uint {
+	log.info("BEFORE\0")
+	sleep.sleep_until_interrupt(32)
+	log.info("AFTER\0")
+	return 0
+}
\ No newline at end of file