diff --git a/src/devices/stdout.rs b/src/devices/stdout.rs
index a2f7528c0ba72eef722536923dc8f5c6651fe722..048a83f7a78e61df5245d8aa03cd04524d8c8ba0 100644
--- a/src/devices/stdout.rs
+++ b/src/devices/stdout.rs
@@ -4,11 +4,19 @@ use crate::serial::SerialDevice;
 
 pub struct StdoutDevice {
     flush: bool,
+    callback: fn(image_buffer: &Vec<u8>),
 }
 
 impl StdoutDevice {
     pub fn new(flush: bool) -> Self {
-        Self { flush }
+        Self {
+            flush,
+            callback: |_| {},
+        }
+    }
+
+    pub fn set_callback(&mut self, callback: fn(image_buffer: &Vec<u8>)) {
+        self.callback = callback;
     }
 }
 
@@ -22,6 +30,8 @@ impl SerialDevice for StdoutDevice {
         if self.flush {
             stdout().flush().unwrap();
         }
+        let data = vec![byte];
+        (self.callback)(&data);
     }
 
     fn allow_slave(&self) -> bool {
diff --git a/src/gb.rs b/src/gb.rs
index 08c28c58b078387b4a458b896351f457311ad581..ba55c2fef5978425c8002009e7afce5a039e8dc6 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -8,7 +8,7 @@ use crate::{
     pad::{Pad, PadKey},
     ppu::{Ppu, PpuMode, Tile, FRAME_BUFFER_SIZE},
     rom::Cartridge,
-    serial::{Serial, SerialDevice},
+    serial::{NullDevice, Serial, SerialDevice},
     timer::Timer,
     util::read_file,
 };
@@ -484,6 +484,19 @@ impl GameBoy {
         self.load_rom(data).clone()
     }
 
+    pub fn load_null_ws(&mut self) {
+        let null = Box::<NullDevice>::default();
+        self.attach_serial(null);
+    }
+
+    pub fn load_logger_ws(&mut self) {
+        let mut logger = Box::<StdoutDevice>::default();
+        logger.set_callback(|data| {
+            logger_callback(data.to_vec());
+        });
+        self.attach_serial(logger);
+    }
+
     pub fn load_printer_ws(&mut self) {
         let mut printer = Box::<PrinterDevice>::default();
         printer.set_callback(|image_buffer| {
@@ -534,6 +547,9 @@ extern "C" {
     #[wasm_bindgen(js_namespace = window)]
     fn panic(message: &str);
 
+    #[wasm_bindgen(js_namespace = window, js_name = loggerCallback)]
+    fn logger_callback(data: Vec<u8>);
+
     #[wasm_bindgen(js_namespace = window, js_name = printerCallback)]
     fn printer_callback(image_buffer: Vec<u8>);
 }