progress
diff --git a/src/console.rs b/src/console.rs
new file mode 100644
index 0000000..96711e1
--- /dev/null
+++ b/src/console.rs
@@ -0,0 +1,61 @@
+use core::{fmt,mem};
+use core::cell::Cell;
+use core::result::Result;
+use syscalls::{self, allow, yieldk_for};
+
+use alloc::{String, VecDeque};
+
+pub struct Console {
+    queue: VecDeque<String>,
+    outstanding: bool
+}
+
+impl Console {
+    pub fn new() -> Console {
+        Console {
+            queue: VecDeque::new(),
+            outstanding: false
+        }
+    }
+
+    pub fn write(&mut self, string: String) {
+        if !self.outstanding {
+            self.outstanding = true;
+            unsafe {
+                putstr_async(string, Self::cb, self as *const _ as usize);
+            }
+        } else {
+            self.queue.push_back(string);
+        }
+    }
+
+    extern fn cb(_: usize, _: usize, _: usize, ptr: usize) {
+        let console: &mut Console = unsafe {
+            mem::transmute(ptr)
+        };
+        if let Some(next) = console.queue.pop_front() {
+            unsafe {
+                putstr_async(next, Self::cb, ptr);
+            }
+        } else {
+            console.outstanding = false;
+        }
+    }
+}
+
+impl fmt::Write for Console {
+    fn write_str(&mut self, string: &str) -> Result<(), fmt::Error> {
+        self.write(String::from(string));
+        Ok(())
+    }
+}
+
+unsafe fn putstr_async(string: String, cb: extern fn (usize, usize, usize, usize), ud: usize) -> isize {
+  let ret = allow(0, 1, string.as_bytes());
+  if ret < 0 {
+      return ret;
+  }
+
+  return syscalls::subscribe(0, 1, cb, ud);
+}
+
diff --git a/src/led.rs b/src/led.rs
index 9f589e5..6fcd12d 100644
--- a/src/led.rs
+++ b/src/led.rs
@@ -6,17 +6,25 @@
 const TOGGLE: u32 = 3;
 
 pub fn count() -> isize {
-    command(8, COUNT, 0)
+    unsafe {
+        command(8, COUNT, 0)
+    }
 }
 
 pub fn on(led_num: u32) {
-    command(8, ON, led_num as isize);
+    unsafe {
+        command(8, ON, led_num as isize);
+    }
 }
 
 pub fn off(led_num: u32) {
-    command(8, OFF, led_num as isize);
+    unsafe {
+        command(8, OFF, led_num as isize);
+    }
 }
 
 pub fn toggle(led_num: u32) {
-    command(8, TOGGLE, led_num as isize);
+    unsafe {
+        command(8, TOGGLE, led_num as isize);
+    }
 }
diff --git a/src/lib.rs b/src/lib.rs
index 57c4611..c77d666 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,17 +1,20 @@
-#![feature(asm,const_fn,global_allocator,lang_items,naked_functions)]
+#![feature(asm,alloc,compiler_builtins_lib,const_fn,global_allocator,lang_items,naked_functions)]
 #![no_std]
 
 pub mod syscalls;
+pub mod console;
 pub mod timer;
 pub mod led;
 
+extern crate alloc;
+extern crate compiler_builtins;
 extern crate linked_list_allocator;
 
 mod lang_items;
 
 use core::ptr;
 use core::mem::size_of;
-use linked_list_allocator::{Heap,BaseHeap};
+use linked_list_allocator::BaseHeap;
 
 #[global_allocator]
 static ALLOCATOR : BaseHeap = BaseHeap;
@@ -29,13 +32,15 @@
     }
 
     unsafe {
+        asm!("mov r9, $0" : : "r"(app_heap_break) : : "volatile");
+        syscalls::memop(0, mem_start + 2048);
+
         // Setup stack
-        let new_stack = mem_start + size_of::<Heap>();
+        let new_stack = mem_start + 1024;
         asm!("mov sp, $0" : : "r"(new_stack) : : "volatile");
 
-
         let heap_start = new_stack + size_of::<usize>();
-        let heap_size = app_heap_break - heap_start;
+        let heap_size = 1024;
         BaseHeap.init(heap_start, heap_size);
 
         // arguments are not used in Tock applications
diff --git a/src/syscalls.rs b/src/syscalls.rs
index a45e43d..65d57cc 100644
--- a/src/syscalls.rs
+++ b/src/syscalls.rs
@@ -11,7 +11,18 @@
     }
 }
 
-pub fn subscribe(major: u32, minor: u32, cb: extern fn(usize, usize, usize, usize), ud: usize) -> u32 {
+pub unsafe fn allow(major: u32, minor: u32, slice: &[u8]) -> isize {
+    let res;
+    unsafe {
+        asm!("svc 3" : "={r0}"(res)
+                     : "{r0}"(major) "{r1}"(minor) "{r2}"(slice.as_ptr()) "{r3}"(slice.len())
+                     : "memory"
+                     : "volatile");
+    }
+    res
+}
+
+pub unsafe fn subscribe(major: u32, minor: u32, cb: extern fn(usize, usize, usize, usize), ud: usize) -> isize {
     let res;
     unsafe {
         asm!("svc 1" : "={r0}"(res)
@@ -22,7 +33,7 @@
     res
 }
 
-pub fn command(major: u32, minor: u32, arg1: isize) -> isize {
+pub unsafe fn command(major: u32, minor: u32, arg1: isize) -> isize {
     let res;
     unsafe {
         asm!("svc 2" : "={r0}"(res)
@@ -33,3 +44,14 @@
     res
 }
 
+pub unsafe fn memop(major: u32, arg1: usize) -> isize {
+    let res;
+    unsafe {
+        asm!("svc 4" : "={r0}"(res)
+                     : "{r0}"(major) "{r1}"(arg1)
+                     : "memory"
+                     : "volatile");
+    }
+    res
+}
+
diff --git a/src/timer.rs b/src/timer.rs
index 538b292..2680694 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -2,20 +2,26 @@
 use core::cell::Cell;
 use syscalls::{self, command, yieldk_for};
 
-pub fn subscribe(cb: extern fn(usize, usize, usize, usize), ud: usize) {
+pub unsafe fn subscribe(cb: extern fn(usize, usize, usize, usize), ud: usize) {
     syscalls::subscribe(3, 0, cb, ud);
 }
 
 pub fn start_oneshot(ms: u32) {
-    command(3, 1, ms as isize);
+    unsafe {
+        command(3, 1, ms as isize);
+    }
 }
 
 pub fn start_repeating(ms: u32) {
-    command(3, 2, ms as isize);
+    unsafe {
+        command(3, 2, ms as isize);
+    }
 }
 
 pub fn stop(ms: u32) {
-    command(3, 3, ms as isize);
+    unsafe {
+        command(3, 3, ms as isize);
+    }
 }
 
 pub fn delay_ms(ms: u32) {
@@ -27,8 +33,10 @@
     }
 
     let expired = Cell::new(false);
-    subscribe(cb, &expired as *const _ as usize);
-    start_oneshot(ms);
-    yieldk_for(|| expired.get() );
+    unsafe {
+        subscribe(cb, &expired as *const _ as usize);
+        start_oneshot(ms);
+        yieldk_for(|| expired.get() );
+    }
 }