diff --git a/Cargo.lock b/Cargo.lock
index dd803bf8e375519a88c4447f7b9b7d699b36b66f..883b0b473b2c8c9ea5b50bb4312994b7752fbc68 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6,6 +6,7 @@ dependencies = [
  "orbfont 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "orbimage 0.1.1 (git+https://github.com/redox-os/orbimage.git)",
  "orbtk 0.1.2 (git+https://github.com/redox-os/orbtk.git)",
+ "ransid 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -218,6 +219,11 @@ dependencies = [
  "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "ransid"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "rustc-serialize"
 version = "0.3.19"
diff --git a/Cargo.toml b/Cargo.toml
index 303c222a77ca5a0e6702a773468e6aca09c7c22a..063098080a52970fd85bf56c910207ebdfc37b8d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -36,3 +36,4 @@ orbclient = "0.1"
 orbfont = "0.1"
 orbimage = { git = "https://github.com/redox-os/orbimage.git" }
 orbtk = { git = "https://github.com/redox-os/orbtk.git" }
+ransid = "0.1"
diff --git a/src/terminal/console.rs b/src/terminal/console.rs
index c268cdd6699e6d0c0538390a1ab697663306db47..d6d10a1230d339b54de819d4c09d5528a5c18f32 100644
--- a/src/terminal/console.rs
+++ b/src/terminal/console.rs
@@ -1,70 +1,19 @@
-extern crate system;
-
 extern crate orbfont;
-
-use self::system::graphics::{fast_copy, fast_set};
+extern crate ransid;
 
 use self::orbfont::Font;
 
-use std::{cmp, mem};
+use std::mem;
 
 use orbclient::{Color, Event, EventOption, Window};
 use orbclient::event;
 
-fn ansi_color(value: u8) -> Color {
-    match value {
-        0 => Color::rgb(0x00, 0x00, 0x00),
-        1 => Color::rgb(0x80, 0x00, 0x00),
-        2 => Color::rgb(0x00, 0x80, 0x00),
-        3 => Color::rgb(0x80, 0x80, 0x00),
-        4 => Color::rgb(0x00, 0x00, 0x80),
-        5 => Color::rgb(0x80, 0x00, 0x80),
-        6 => Color::rgb(0x00, 0x80, 0x80),
-        7 => Color::rgb(0xc0, 0xc0, 0xc0),
-        8 => Color::rgb(0x80, 0x80, 0x80),
-        9 => Color::rgb(0xff, 0x00, 0x00),
-        10 => Color::rgb(0x00, 0xff, 0x00),
-        11 => Color::rgb(0xff, 0xff, 0x00),
-        12 => Color::rgb(0x00, 0x00, 0xff),
-        13 => Color::rgb(0xff, 0x00, 0xff),
-        14 => Color::rgb(0x00, 0xff, 0xff),
-        15 => Color::rgb(0xff, 0xff, 0xff),
-        16 ... 231 => {
-            let convert = |value: u8| -> u8 {
-                match value {
-                    0 => 0,
-                    _ => value * 0x28 + 0x28
-                }
-            };
-
-            let r = convert((value - 16)/36 % 6);
-            let g = convert((value - 16)/6 % 6);
-            let b = convert((value - 16) % 6);
-            Color::rgb(r, g, b)
-        },
-        232 ... 255 => {
-            let gray = (value - 232) * 10 + 8;
-            Color::rgb(gray, gray, gray)
-        },
-        _ => Color::rgb(0, 0, 0)
-    }
-}
-
 pub struct Console {
     pub window: Window,
+    pub inner: ransid::Console,
     pub font: Font,
     pub font_bold: Font,
-    pub point_x: i32,
-    pub point_y: i32,
-    pub foreground: Color,
-    pub background: Color,
-    pub bold: bool,
-    pub redraw: bool,
     pub command: String,
-    pub escape: bool,
-    pub escape_sequence: bool,
-    pub sequence: Vec<String>,
-    pub raw_mode: bool,
 }
 
 impl Console {
@@ -73,239 +22,18 @@ impl Console {
         window.sync();
         Console {
             window: window,
+            inner: ransid::Console::new(width as usize/8, height as usize/16),
             font: Font::find(Some("Mono"), None, Some("Regular")).unwrap(),
             font_bold: Font::find(Some("Mono"), None, Some("Bold")).unwrap(),
-            point_x: 0,
-            point_y: 0,
-            foreground: ansi_color(7),
-            background: ansi_color(0),
-            bold: false,
-            redraw: true,
             command: String::new(),
-            escape: false,
-            escape_sequence: false,
-            sequence: Vec::new(),
-            raw_mode: false,
-        }
-    }
-
-    pub fn code(&mut self, c: char) {
-        if self.escape_sequence {
-            match c {
-                '0' ... '9' => {
-                    // Add a number to the sequence list
-                    if let Some(mut value) = self.sequence.last_mut() {
-                        value.push(c);
-                    }
-                },
-                ';' => {
-                    // Split sequence into list
-                    self.sequence.push(String::new());
-                },
-                'm' => {
-                    // Display attributes
-                    let mut value_iter = self.sequence.iter();
-                    while let Some(value_str) = value_iter.next() {
-                        let value = value_str.parse::<u8>().unwrap_or(0);
-                        match value {
-                            0 => {
-                                self.foreground = ansi_color(7);
-                                self.background = ansi_color(0);
-                                self.bold = false;
-                            },
-                            1 => {
-                                self.bold = true;
-                            },
-                            30 ... 37 => self.foreground = ansi_color(value - 30),
-                            38 => match value_iter.next().map_or("", |s| &s).parse::<usize>().unwrap_or(0) {
-                                2 => {
-                                    //True color
-                                    let r = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    let g = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    let b = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    self.foreground = Color::rgb(r, g, b);
-                                },
-                                5 => {
-                                    //256 color
-                                    let color_value = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    self.foreground = ansi_color(color_value);
-                                },
-                                _ => {}
-                            },
-                            40 ... 47 => self.background = ansi_color(value - 40),
-                            48 => match value_iter.next().map_or("", |s| &s).parse::<usize>().unwrap_or(0) {
-                                2 => {
-                                    //True color
-                                    let r = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    let g = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    let b = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    self.background = Color::rgb(r, g, b);
-                                },
-                                5 => {
-                                    //256 color
-                                    let color_value = value_iter.next().map_or("", |s| &s).parse::<u8>().unwrap_or(0);
-                                    self.background = ansi_color(color_value);
-                                },
-                                _ => {}
-                            },
-                            _ => {},
-                        }
-                    }
-
-                    self.escape_sequence = false;
-                },
-                'J' => {
-                    match self.sequence.get(0).map_or("", |p| &p).parse::<usize>().unwrap_or(0) {
-                        0 => {
-                            //TODO: Erase down
-                        },
-                        1 => {
-                            //TODO: Erase up
-                        },
-                        2 => {
-                            // Erase all
-                            self.point_x = 0;
-                            self.point_y = 0;
-                            self.window.set(self.background);
-                            self.redraw = true;
-                        },
-                        _ => {}
-                    }
-
-                    self.escape_sequence = false;
-                },
-                'H' | 'f' => {
-                    self.window.rect(self.point_x, self.point_y, 8, 16, self.background);
-
-                    let row = self.sequence.get(0).map_or("", |p| &p).parse::<isize>().unwrap_or(1);
-                    self.point_y = cmp::max(0, row - 1) as i32 * 16;
-
-                    let col = self.sequence.get(1).map_or("", |p| &p).parse::<isize>().unwrap_or(1);
-                    self.point_x = cmp::max(0, col - 1) as i32 * 8;
-
-                    self.window.rect(self.point_x, self.point_y, 8, 16, self.foreground);
-                    self.redraw = true;
-
-                    self.escape_sequence = false;
-                },
-/*
-@MANSTART{terminal-raw-mode}
-INTRODUCTION
-    Since Redox has no ioctl syscall, it uses escape codes for switching to raw mode.
-
-ENTERING AND EXITING RAW MODE
-    Entering raw mode is done using CSI-r (^[r). Unsetting raw mode is done by CSI-R (^[R).
-
-RAW MODE
-    Raw mode means that the stdin must be handled solely by the program itself. It will not automatically be printed nor will it be modified in any way (modulo escape codes).
-
-    This means that:
-        - stdin is not printed.
-        - newlines are interpreted as carriage returns in stdin.
-        - stdin is not buffered, meaning that the stream of bytes goes directly to the program, without the user having to press enter.
-@MANEND
-*/
-                'r' => {
-                    self.raw_mode = true;
-                    self.escape_sequence = false;
-                },
-                'R' => {
-                    self.raw_mode = false;
-                    self.escape_sequence = false;
-                },
-                _ => self.escape_sequence = false,
-
-            }
-
-            if !self.escape_sequence {
-                self.sequence.clear();
-                self.escape = false;
-            }
-        } else {
-            match c {
-                '[' => {
-                    // Control sequence initiator
-
-                    self.escape_sequence = true;
-                    self.sequence.push(String::new());
-                },
-                'c' => {
-                    // Reset
-                    self.point_x = 0;
-                    self.point_y = 0;
-                    self.raw_mode = false;
-                    self.foreground = ansi_color(7);
-                    self.background = ansi_color(0);
-                    self.bold = false;
-                    self.window.set(self.background);
-                    self.redraw = true;
-
-                    self.escape = false;
-                }
-                _ => self.escape = false,
-            }
-        }
-    }
-
-    pub fn scroll(&mut self, rows: usize) {
-        if rows > 0 && rows < self.window.height() as usize {
-            let offset = rows * self.window.width() as usize;
-            let data = self.window.data_mut();
-            unsafe {
-                fast_copy(data.as_mut_ptr() as *mut u32, data.as_ptr().offset(offset as isize) as *const u32, data.len() - offset);
-                fast_set(data.as_mut_ptr().offset((data.len() - offset) as isize) as *mut u32, self.background.data, offset);
-            }
         }
     }
 
-    pub fn character(&mut self, c: char) {
-        self.window.rect(self.point_x, self.point_y, 8, 16, self.background);
-
-        match c {
-            '\0' => {},
-            '\x1B' => self.escape = true,
-            '\n' => {
-                self.point_x = 0;
-                self.point_y += 16;
-            },
-            '\t' => self.point_x = ((self.point_x / 64) + 1) * 64,
-            '\r' => self.point_x = 0,
-            '\x08' => {
-                self.point_x -= 8;
-                if self.point_x < 0 {
-                    self.point_x = 0
-                }
-                self.window.rect(self.point_x, self.point_y, 8, 16, self.background);
-            },
-            _ => {
-                if self.bold {
-                    self.font_bold.render(&c.to_string(), 16.0).draw(&mut self.window, self.point_x, self.point_y, self.foreground);
-                } else {
-                    self.font.render(&c.to_string(), 16.0).draw(&mut self.window, self.point_x, self.point_y, self.foreground);
-                }
-                //self.window.char(self.point_x, self.point_y, c, self.foreground);
-                self.point_x += 8;
-            }
-        }
-
-        if self.point_x >= self.window.width() as i32 {
-            self.point_x = 0;
-            self.point_y += 16;
-        }
-
-        while self.point_y + 16 > self.window.height() as i32 {
-            self.scroll(16);
-            self.point_y -= 16;
-        }
-        self.window.rect(self.point_x, self.point_y, 8, 16, self.foreground);
-        self.redraw = true;
-    }
-
     pub fn event(&mut self, event: Event) -> Option<String> {
         match event.to_option() {
             EventOption::Key(key_event) => {
                 if key_event.pressed {
-                    if self.raw_mode {
+                    if self.inner.raw_mode {
                         match key_event.scancode {
                             event::K_BKSP => self.command.push_str("\x08"),
                             event::K_UP => self.command.push_str("\x1B[A"),
@@ -328,12 +56,16 @@ RAW MODE
                     } else {
                         match key_event.scancode {
                             event::K_BKSP => if ! self.command.is_empty() {
+                                self.inner.redraw = true;
+
                                 self.write(&[8]);
                                 self.command.pop();
                             },
                             _ => match key_event.character {
                                 '\0' => (),
                                 c => {
+                                    self.inner.redraw = true;
+
                                     self.write(&[c as u8]);
                                     self.command.push(c);
 
@@ -355,18 +87,41 @@ RAW MODE
     }
 
     pub fn write(&mut self, bytes: &[u8]) {
-        for byte in bytes.iter() {
-            let c = *byte as char;
-
-            if self.escape {
-                self.code(c);
-            } else {
-                self.character(c);
+        self.inner.write(bytes);
+        //TODO: if self.inner.redraw
+        {
+            self.inner.redraw = false;
+
+            self.window.set(Color {
+                data: self.inner.background.data
+            });
+            for y in 0..self.inner.h {
+                for x in 0..self.inner.w {
+                    let block = self.inner.display[y * self.inner.w + x];
+                    self.window.rect(x as i32 * 8, y as i32 * 16, 8, 16, Color {
+                        data: block.bg.data
+                    });
+                    if block.c != ' ' {
+                        match block.style {
+                            ransid::Style::Normal => {
+                                self.font.render(&block.c.to_string(), 16.0).draw(&mut self.window, x as i32 * 8, y as i32 * 16, Color {
+                                    data: block.fg.data
+                                });
+                            },
+                            ransid::Style::Bold => {
+                                self.font_bold.render(&block.c.to_string(), 16.0).draw(&mut self.window, x as i32 * 8, y as i32 * 16, Color {
+                                    data: block.fg.data
+                                });
+                            }
+                        }
+                    }
+                }
+            }
+            if self.inner.cursor {
+                self.window.rect(self.inner.x as i32 * 8, self.inner.y as i32 * 16, 8, 16, Color {
+                    data: self.inner.foreground.data
+                });
             }
-        }
-
-        if self.redraw {
-            self.redraw = false;
             self.window.sync();
         }
     }
diff --git a/src/terminal/main.rs b/src/terminal/main.rs
index 07ff35a4e085af6a3d06c3a438a261399f6fff2c..dab53e6189905014b1ff33843cd2cc8980342437 100644
--- a/src/terminal/main.rs
+++ b/src/terminal/main.rs
@@ -6,11 +6,12 @@ extern crate orbclient;
 use orbclient::event;
 
 use std::env;
+use std::error::Error;
 use std::io::{Read, Write, self};
 use std::process::{Command, Stdio};
 use std::sync::{Arc, Mutex};
+use std::time::Duration;
 use std::thread;
-use std::error::Error;
 
 use console::Console;
 
@@ -122,7 +123,7 @@ fn main() {
                     }
                 }
 
-                thread::sleep_ms(1);
+                thread::sleep(Duration::new(0, 1000000));
             }
         },
         Err(err) => {