diff --git a/ableos/Cargo.toml b/ableos/Cargo.toml
index aafb66b..194afcc 100644
--- a/ableos/Cargo.toml
+++ b/ableos/Cargo.toml
@@ -52,7 +52,6 @@ bitflags = "1.2.1"
 linked_list_allocator = "0.9.0"
 lliw = "0.2.0"
 spin = "0.9"
-log = "0.4.17"
 pretty-hex = "0.2.1"
 unicode-width = "0.1.7"
 picorand = "0.1.0"
@@ -64,6 +63,12 @@ axel = { git = "https://git.ablecorp.us/able/aos_userland" }
 versioning = { git = "https://git.ablecorp.us/able/aos_userland" }
 # embedded-graphics = "*"
 pc-keyboard = "0.5"
+# mini-backtrace = "0.1"
+
+[dependencies.log]
+version = "0.4.17"
+default-features = false
+
 
 [dependencies.logos]
 version = "0.12"
diff --git a/ableos/debug.log b/ableos/debug.log
new file mode 100644
index 0000000..e69de29
diff --git a/ableos/src/arch/x86_64/drivers/serial.rs b/ableos/src/arch/x86_64/drivers/serial.rs
index fb5eb18..64eee68 100644
--- a/ableos/src/arch/x86_64/drivers/serial.rs
+++ b/ableos/src/arch/x86_64/drivers/serial.rs
@@ -10,10 +10,12 @@ pub static SERIAL1: Lazy<Mutex<SerialPort>> = Lazy::new(|| {
 #[doc(hidden)]
 pub fn _print(args: ::core::fmt::Arguments) {
     use core::fmt::Write;
+    // /*
     SERIAL1
         .lock()
         .write_fmt(args)
         .expect("Printing to serial failed");
+    // */
 }
 
 /// Prints to the host through the serial interface.
diff --git a/ableos/src/arch/x86_64/drivers/vga.rs b/ableos/src/arch/x86_64/drivers/vga.rs
index 3fcde93..8b13789 100644
--- a/ableos/src/arch/x86_64/drivers/vga.rs
+++ b/ableos/src/arch/x86_64/drivers/vga.rs
@@ -1,162 +1 @@
-use core::fmt;
-use spin::{Lazy, Mutex};
-use volatile::Volatile;
 
-const BUFFER_HEIGHT: usize = 25;
-const BUFFER_WIDTH: usize = 80;
-
-#[allow(dead_code)]
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[repr(u8)]
-pub enum Color {
-    Black = 0,
-    Blue = 1,
-    Green = 2,
-    Cyan = 3,
-    Red = 4,
-    Magenta = 5,
-    Brown = 6,
-    LightGray = 7,
-    DarkGray = 8,
-    LightBlue = 9,
-    LightGreen = 10,
-    LightCyan = 11,
-    LightRed = 12,
-    Pink = 13,
-    Yellow = 14,
-    White = 15,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[repr(transparent)]
-struct ColorCode(u8);
-impl ColorCode {
-    const fn new(foreground: Color, background: Color) -> ColorCode {
-        ColorCode((background as u8) << 4 | (foreground as u8))
-    }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-#[repr(C)]
-struct ScreenChar {
-    ascii_character: u8,
-    color_code: ColorCode,
-}
-
-#[repr(transparent)]
-struct Buffer {
-    chars: [[Volatile<ScreenChar>; BUFFER_WIDTH]; BUFFER_HEIGHT],
-}
-
-pub struct Writer {
-    column_position: usize,
-    color_code: ColorCode,
-    buffer: &'static mut Buffer,
-}
-
-impl Writer {
-    pub fn write_byte(&mut self, byte: u8) {
-        match byte {
-            b'\n' => self.new_line(),
-            byte => {
-                if self.column_position >= BUFFER_WIDTH {
-                    self.new_line();
-                }
-                let row = BUFFER_HEIGHT - 1;
-                let col = self.column_position;
-                let color_code = self.color_code;
-                self.buffer.chars[row][col].write(ScreenChar {
-                    ascii_character: byte,
-                    color_code,
-                });
-                self.column_position += 1;
-            }
-        }
-    }
-
-    pub fn write_string(&mut self, s: &str) {
-        for byte in s.bytes() {
-            match byte {
-                // printable ASCII byte or newline
-                0x20..=0x7e | b'\n' => self.write_byte(byte),
-                // not part of printable ASCII range
-                _ => self.write_byte(0xfe),
-            }
-        }
-    }
-
-    fn new_line(&mut self) {
-        for row in 1..BUFFER_HEIGHT {
-            for col in 0..BUFFER_WIDTH {
-                let character = self.buffer.chars[row][col].read();
-                self.buffer.chars[row - 1][col].write(character);
-            }
-        }
-        self.clear_row(BUFFER_HEIGHT - 1);
-        self.column_position = 0;
-    }
-
-    fn clear_row(&mut self, row: usize) {
-        let blank = ScreenChar {
-            ascii_character: b' ',
-            color_code: self.color_code,
-        };
-        for col in 0..BUFFER_WIDTH {
-            self.buffer.chars[row][col].write(blank);
-        }
-    }
-
-    pub fn backspace(&mut self) {
-        let col_pos = self.column_position;
-        if col_pos == 0 {
-        } else {
-            self.column_position -= 1;
-
-            let blank = ScreenChar {
-                ascii_character: b' ',
-                color_code: self.color_code,
-            };
-
-            self.buffer.chars[BUFFER_HEIGHT - 1][col_pos - 1].write(blank);
-        }
-    }
-}
-
-impl fmt::Write for Writer {
-    fn write_str(&mut self, s: &str) -> fmt::Result {
-        self.write_string(s);
-        Ok(())
-    }
-}
-
-pub static WRITER: Lazy<Mutex<Writer>> = Lazy::new(|| {
-    Mutex::new(Writer {
-        column_position: 0,
-        color_code: ColorCode::new(Color::White, Color::Black),
-        buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
-    })
-});
-
-#[macro_export]
-macro_rules! kprint {
-    ($($arg:tt)*) => ($crate::arch::drivers::vga::_kprint(format_args!($($arg)*)));
-}
-
-#[macro_export]
-macro_rules! kprintln {
-    () => ($crate::kprint!("\n"));
-    ($($arg:tt)*) => ($crate::kprint!("{}\n", format_args!($($arg)*)));
-}
-
-#[doc(hidden)]
-pub fn _kprint(args: fmt::Arguments) {
-    use core::fmt::Write;
-    use x86_64::instructions::interrupts;
-    interrupts::without_interrupts(|| {
-        WRITER.lock().write_fmt(args).unwrap();
-    });
-}
-
-pub fn set_vga_color(fg: Color, bg: Color) {
-    WRITER.lock().color_code = ColorCode::new(fg, bg);
-}
diff --git a/ableos/src/arch/x86_64/init.rs b/ableos/src/arch/x86_64/init.rs
index f8df89e..8ecb29b 100644
--- a/ableos/src/arch/x86_64/init.rs
+++ b/ableos/src/arch/x86_64/init.rs
@@ -1,6 +1,6 @@
 // #![allow(clippy::print_literal)]
 use super::{drivers::serial, gdt, interrupts};
-use crate::{logger, serial_println};
+use crate::{logger, serial_println, TERM};
 
 /// x86_64 initialization
 pub fn init() {
@@ -17,8 +17,12 @@ pub fn init() {
         Err(err) => serial_println!("{}", err),
     }
 
-    /*
-     */
+    let mut term = TERM.lock();
+    // term.initialize();
+    term.set_dirty(true);
+    term.draw_term();
+    drop(term);
+
     gdt::init();
 
     interrupts::init_idt();
diff --git a/ableos/src/arch/x86_64/interrupts.rs b/ableos/src/arch/x86_64/interrupts.rs
index 5c5328d..2f5d389 100644
--- a/ableos/src/arch/x86_64/interrupts.rs
+++ b/ableos/src/arch/x86_64/interrupts.rs
@@ -1,12 +1,8 @@
 use core::panic::PanicInfo;
 
 use crate::{
-    arch::{drivers::vga::WRITER, gdt},
-    image::mono_bitmap::bruh,
-    kernel_state::KERNEL_STATE,
-    print, println,
-    rhai_shell::KEYBUFF,
-    VgaBuffer, SCREEN_BUFFER,
+    arch::gdt, image::mono_bitmap::bruh, kernel_state::KERNEL_STATE, print, println,
+    rhai_shell::KEYBUFF, VgaBuffer, SCREEN_BUFFER,
 };
 use cpuio::outb;
 use pic8259::ChainedPics;
@@ -133,8 +129,9 @@ extern "x86-interrupt" fn keyboard_interrupt_handler(_stack_frame: InterruptStac
                 // Backspace
                 '\u{8}' => {
                     // TODO: Fix this and apply to new term
-                    // WRITER.lock().backspace();
+
                     KEYBUFF.lock().push(8.into());
+                    print!("\u{8}");
                 }
                 // '^' => KERNEL_STATE.lock().shutdown(),
                 chr => {
diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs
index fb78a46..4b609ac 100644
--- a/ableos/src/kmain.rs
+++ b/ableos/src/kmain.rs
@@ -30,16 +30,18 @@ pub static KERNEL_CONF: Lazy<KernelConfig> = Lazy::new(KernelConfig::new);
 pub fn kernel_main() -> ! {
     init::init();
 
+    // /*
     if KERNEL_CONF.logging.enabled {
         log::set_max_level(KERNEL_CONF.log_level());
     } else {
         log::set_max_level(log::LevelFilter::Off);
     }
-    let mut term = TERM.lock();
-    term.initialize();
-    term.set_dirty(true);
-    term.draw_term();
-    drop(term);
+    // */
+    // let mut term = TERM.lock();
+    // term.initialize();
+    // term.set_dirty(true);
+    // term.draw_term();
+    // drop(term);
 
     /*
     x86_64::instructions::interrupts::without_interrupts(|| {
@@ -71,15 +73,19 @@ pub fn kernel_main() -> ! {
     // for abc in list() {
     //     trace!("{:?}", abc);
     // }
+    /*
     log_version_data();
     x86_64::instructions::interrupts::without_interrupts(|| {
         let mut scheduler = SCHEDULER.lock();
         // comment this out to resume normal use
         // scheduler.enqueue_spawn(traceloop);
 
-        scheduler.enqueue_spawn(scratchpad);
+        // scheduler.enqueue_spawn(scratchpad);
     });
 
+    // */
+    scratchpad();
+
     sloop()
 }
 
@@ -141,8 +147,6 @@ pub static TICK: AtomicU64 = AtomicU64::new(0);
 
 pub fn tick() {
     x86_64::instructions::interrupts::without_interrupts(|| {
-        trace!("ticking time");
-
         let mut term = TERM.lock();
 
         term.draw_term();
@@ -152,6 +156,5 @@ pub fn tick() {
         data = data.wrapping_add(1);
 
         TICK.store(data, Relaxed);
-        trace!("time ticked");
     });
 }
diff --git a/ableos/src/print.rs b/ableos/src/print.rs
index 3687ee0..04cac19 100644
--- a/ableos/src/print.rs
+++ b/ableos/src/print.rs
@@ -21,8 +21,23 @@ impl core::fmt::Write for Stdout {
     }
     #[cfg(target_arch = "x86_64")]
     fn write_str(&mut self, s: &str) -> Result<(), Error> {
+        // use mini_backtrace::Backtrace;
+
         use crate::TERM;
 
+        // Capture up to 16 frames. This is returned using an ArrayVec that doesn't
+        // perform any dynamic memory allocation.
+        /*
+        let bt = Backtrace::<16>::capture();
+        trace!("Backtrace:");
+        for frame in bt.frames {
+            trace!("  {:#x}", frame);
+        }
+        if bt.frames_omitted {
+            trace!(" ... <frames omitted>");
+        }
+        */
+
         trace!("printing");
         // x86_64::instructions::interrupts::without_interrupts(|| {
         let mut term = TERM.lock();
diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs
index cf65c57..818e0b3 100644
--- a/ableos/src/scratchpad.rs
+++ b/ableos/src/scratchpad.rs
@@ -10,6 +10,7 @@ use crate::handle::Handle;
 use crate::ipc::IPC;
 use crate::rhai_shell::shell;
 use crate::rhai_shell::KEYBUFF;
+use crate::unicode_utils::LAMBDA;
 use crate::vterm::Term;
 use crate::wasm_jumploader::run_program;
 use crate::{vgai, SCREEN_BUFFER};
@@ -93,11 +94,13 @@ pub fn acpi() {
 }
 
 pub fn real_shell() {
+    let prompt = "-> ";
+
     let _current_dir = "/".to_string();
     let current_user = "able".to_string();
 
     let mut buf = String::new();
-    print!("> ");
+    print!("{}", prompt);
 
     loop {
         match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
@@ -112,7 +115,7 @@ pub fn real_shell() {
                 }
 
                 buf.clear();
-                print!("> ");
+                print!("{}", prompt);
             }
             Some('\u{0008}') => {
                 buf.pop();
diff --git a/ableos/src/vterm.rs b/ableos/src/vterm.rs
index 4b93172..d955456 100644
--- a/ableos/src/vterm.rs
+++ b/ableos/src/vterm.rs
@@ -11,10 +11,14 @@ const CURSOR_COLOR: Color16 = Color16::Cyan;
 pub struct Term {
     dirty: bool,
     term: [char; 80 * 60],
-    x: usize,
+    x: u8,
 }
 impl Term {
     pub fn new() -> Self {
+        let mode = VGAE.lock();
+        mode.set_mode();
+        drop(mode);
+
         Self {
             dirty: false,
             x: 0,
@@ -31,12 +35,30 @@ impl Term {
 
     pub fn print(&mut self, data: String) {
         for c in data.chars() {
-            if self.x == 79 || c == '\n' {
+            if self.x == 79 {
                 self.move_up();
-                self.x = 0;
-            } else {
-                self.term[TERM_MINUS_ONE_LINE + self.x] = c;
-                self.x += 1;
+                return;
+            }
+
+            match c {
+                '\u{08}' => {
+                    if self.x == 0 {
+                        warn!("IMPOSSIBLE BACKSPACE");
+                    } else {
+                        trace!("BACKSPACE");
+                        self.x -= 1;
+                        self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = '\0';
+                    }
+                }
+                '\n' => {
+                    self.move_up();
+                    self.x = 0;
+                }
+
+                c => {
+                    self.term[TERM_MINUS_ONE_LINE + (self.x as usize)] = c;
+                    self.x += 1;
+                }
             }
         }
     }
@@ -45,12 +67,13 @@ impl Term {
         for x in 0..80 {
             self.term[TERM_MINUS_ONE_LINE + x] = '\0';
         }
+        self.x = 0;
     }
-    pub fn initialize(&self) {
-        let mode = VGAE.lock();
-        mode.set_mode();
-        drop(mode);
-    }
+    // pub fn initialize(&self) {
+    // let mode = VGAE.lock();
+    // mode.set_mode();
+    // drop(mode);
+    // }
 
     pub fn draw_term(&mut self) {
         if self.is_dirty() {
@@ -85,7 +108,6 @@ impl Term {
 
             for c in self.term {
                 mode.draw_character(x * 8, y * 8, c, Color16::White);
-
                 if x == 79 {
                     y += 1;
                     x = 0;
diff --git a/repbuild/src/main.rs b/repbuild/src/main.rs
index 895e016..e816ba3 100644
--- a/repbuild/src/main.rs
+++ b/repbuild/src/main.rs
@@ -54,13 +54,14 @@ fn main() -> anyhow::Result<()> {
         } => {
             let _dir = xshell::pushd("./ableos");
 
-            let _debug_log: &[&str] = match debug {
+            let debug_log: &[&str] = match debug {
                 true => &["-D", "debug.log"],
                 false => &[],
             };
             match machine.unwrap_or(MachineType::X86) {
                 MachineType::X86 => {
-                    xshell::cmd!("cargo run --release").run()?;
+                    // export RUSTFLAGS=\"-Cforce-unwind-tables -Clink-arg=-Wl,eh_frame.ld\" &&
+                    xshell::cmd!("cargo run --release -- -D debug.log").run()?;
                     if profile {
                         xshell::cmd!("python qprofiler.py --path=qmp-sock --filename=target/x86_64-ableos/release/ableos").run()?;
                     }