diff --git a/frontends/libretro/src/lib.rs b/frontends/libretro/src/lib.rs
index 202727ad383b0a06fcbf53bdec4fc43ba66627db..b081d5e969b96079f9ade5488f1a889048411ed6 100644
--- a/frontends/libretro/src/lib.rs
+++ b/frontends/libretro/src/lib.rs
@@ -11,7 +11,7 @@ use std::{
 use boytacean::{
     gb::{AudioProvider, GameBoy},
     pad::PadKey,
-    ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, RGB1555_SIZE},
+    ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH, FRAME_BUFFER_RGB155_SIZE, RGB1555_SIZE},
     rom::Cartridge,
 };
 
@@ -31,6 +31,7 @@ const RETRO_DEVICE_JOYPAD: usize = 1;
 
 static mut EMULATOR: Option<GameBoy> = None;
 static mut KEY_STATES: Option<HashMap<RetroJoypad, bool>> = None;
+static mut FRAME_BUFFER: [u8; FRAME_BUFFER_RGB155_SIZE] = [0x00; FRAME_BUFFER_RGB155_SIZE];
 
 static mut ENVIRONMENT_CALLBACK: Option<extern "C" fn(u32, *const c_void) -> bool> = None;
 static mut VIDEO_REFRESH_CALLBACK: Option<extern "C" fn(*const u8, c_uint, c_uint, usize)> = None;
@@ -176,6 +177,8 @@ pub extern "C" fn retro_deinit() {
 #[no_mangle]
 pub extern "C" fn retro_reset() {
     println!("retro_reset()");
+    let emulator = unsafe { EMULATOR.as_mut().unwrap() };
+    emulator.reload();
 }
 
 #[no_mangle]
@@ -348,8 +351,9 @@ pub extern "C" fn retro_run() {
 
     let frame_buffer = emulator.frame_buffer_rgb1555();
     unsafe {
+        FRAME_BUFFER.copy_from_slice(&frame_buffer);
         VIDEO_REFRESH_CALLBACK.unwrap()(
-            frame_buffer.as_ptr(),
+            FRAME_BUFFER.as_ptr(),
             DISPLAY_WIDTH as u32,
             DISPLAY_HEIGHT as u32,
             DISPLAY_WIDTH * RGB1555_SIZE,
diff --git a/src/gb.rs b/src/gb.rs
index b95a09996b0e936442d87a96ae87d4a30764c55b..dee5b7dfd7b090d316dfc7bf2fba8ccbf3b3aded 100644
--- a/src/gb.rs
+++ b/src/gb.rs
@@ -406,6 +406,13 @@ impl GameBoy {
         self.cpu.reset();
     }
 
+    pub fn reload(&mut self) {
+        let rom = self.rom().clone();
+        self.reset();
+        self.load(true);
+        self.load_cartridge(rom);
+    }
+
     pub fn clock(&mut self) -> u16 {
         let cycles = self.cpu_clock() as u16;
         let cycles_n = cycles / self.multiplier() as u16;
@@ -989,13 +996,17 @@ impl GameBoy {
         self.load_boot_file(BootRom::Cgb);
     }
 
+    pub fn load_cartridge(&mut self, rom: Cartridge) -> &mut Cartridge {
+        self.mmu().set_rom(rom);
+        self.mmu().rom()
+    }
+
     pub fn load_rom(&mut self, data: &[u8], ram_data: Option<&[u8]>) -> &mut Cartridge {
         let mut rom = Cartridge::from_data(data);
         if let Some(ram_data) = ram_data {
             rom.set_ram_data(ram_data)
         }
-        self.mmu().set_rom(rom);
-        self.mmu().rom()
+        self.load_cartridge(rom)
     }
 
     pub fn load_rom_file(&mut self, path: &str, ram_path: Option<&str>) -> &mut Cartridge {
diff --git a/src/rom.rs b/src/rom.rs
index c4cc53887f67335f166000d58462c5532f8e4a35..031285e469cf01b762420a28fab28af592b60825 100644
--- a/src/rom.rs
+++ b/src/rom.rs
@@ -599,6 +599,10 @@ impl Cartridge {
         self.ram_data = data.to_vec();
     }
 
+    pub fn clear_ram_data(&mut self) {
+        self.ram_data = vec![0u8; self.ram_data.len()];
+    }
+
     pub fn description(&self, column_length: usize) -> String {
         let name_l = format!("{:width$}", "Name", width = column_length);
         let type_l = format!("{:width$}", "Type", width = column_length);