diff --git a/examples/sdl/Cargo.toml b/examples/sdl/Cargo.toml
index 6a029adafa561be3e8c6030827a2f0e05e01886f..203f0936cfaf7a2d99af449a7926c8b7a245e240 100644
--- a/examples/sdl/Cargo.toml
+++ b/examples/sdl/Cargo.toml
@@ -9,7 +9,6 @@ edition = "2018"
 
 [dependencies.boytacean]
 path = "../.."
-features = ["debug"]
 
 [dependencies.sdl2]
 version = "0.35"
diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs
index 2fbc7a1cc0c6e9174d6b7e562b2de88ff4bd891c..f7a1ec4043fab4d37071f131b5581940c16c07e4 100644
--- a/examples/sdl/src/main.rs
+++ b/examples/sdl/src/main.rs
@@ -1,111 +1,167 @@
 pub mod data;
+pub mod util;
 
 use boytacean::{
     gb::GameBoy,
     pad::PadKey,
     ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH},
 };
-use sdl2::{
-    event::Event, keyboard::Keycode, pixels::PixelFormatEnum, rwops::RWops, surface::Surface,
-    sys::image, video::Window, AudioSubsystem, EventPump, TimerSubsystem, VideoSubsystem,
-};
+use sdl2::{event::Event, keyboard::Keycode, pixels::PixelFormatEnum};
+use util::Graphics;
+
+use crate::util::surface_from_bytes;
+
+const VISUAL_HZ: u32 = 60;
+const SCREEN_SCALE: f32 = 2.0;
 
 /// The base title to be used in the window.
 static TITLE: &'static str = "Boytacean";
 
-pub struct Graphics {
-    window: Window,
-    video_subsystem: VideoSubsystem,
-    timer_subsystem: TimerSubsystem,
-    audio_subsystem: AudioSubsystem,
-    event_pump: EventPump,
-}
-
-fn start_sdl() -> Graphics {
-    // initializes the SDL sub-system, making it ready to be
-    // used for display of graphics and audio
-    let sdl = sdl2::init().unwrap();
-    let video_subsystem = sdl.video().unwrap();
-    let timer_subsystem = sdl.timer().unwrap();
-    let audio_subsystem = sdl.audio().unwrap();
-    let event_pump = sdl.event_pump().unwrap();
-
-    // initialized the fonts context to be used
-    // in the loading of fonts
-    let ttf_context = sdl2::ttf::init().unwrap();
-
-    // creates the system window that is going to be used to
-    // show the emulator and sets it to the central are o screen
-    let window = video_subsystem
-        .window(
-            TITLE,
-            2 as u32 * DISPLAY_WIDTH as u32, //@todo check screen scale
-            2 as u32 * DISPLAY_HEIGHT as u32, //@todo check screen scale
-        )
-        .resizable()
-        .position_centered()
-        .opengl()
-        .build()
-        .unwrap();
-
-    Graphics {
-        window: window,
-        video_subsystem: video_subsystem,
-        timer_subsystem: timer_subsystem,
-        audio_subsystem: audio_subsystem,
-        event_pump: event_pump,
-    }
+pub struct Emulator {
+    system: GameBoy,
+    graphics: Graphics,
+    visual_frequency: u32,
+    next_tick_time: f32,
+    next_tick_time_i: u32,
 }
 
-pub fn surface_from_bytes(bytes: &[u8]) -> Surface {
-    unsafe {
-        let rw_ops = RWops::from_bytes(bytes).unwrap();
-        let raw_surface = image::IMG_Load_RW(rw_ops.raw(), 0);
-        Surface::from_ll(raw_surface)
+impl Emulator {
+    pub fn new(system: GameBoy, screen_scale: f32) -> Self {
+        Self {
+            system: system,
+            graphics: Graphics::new(
+                TITLE,
+                DISPLAY_WIDTH as u32,
+                DISPLAY_HEIGHT as u32,
+                screen_scale,
+            ),
+            visual_frequency: VISUAL_HZ,
+            next_tick_time: 0.0,
+            next_tick_time_i: 0,
+        }
     }
-}
 
-fn main() {
-    let mut graphics = start_sdl();
-
-    // updates the icon of the window to reflect the image
-    // and style of the emulator
-    let surface = surface_from_bytes(&data::ICON);
-    graphics.window.set_icon(&surface);
+    pub fn run(&mut self) {
+        // updates the icon of the window to reflect the image
+        // and style of the emulator
+        let surface = surface_from_bytes(&data::ICON);
+        self.graphics.window_mut().set_icon(&surface);
+
+        // creates an accelerated canvas to be used in the drawing
+        // then clears it and presents it
+        self.graphics.canvas.present();
+
+        // creates a texture creator for the current canvas, required
+        // for the creation of dynamic and static textures
+        let texture_creator = self.graphics.canvas.texture_creator();
+
+        // creates the texture streaming that is going to be used
+        // as the target for the pixel buffer
+        let mut texture = texture_creator
+            .create_texture_streaming(
+                PixelFormatEnum::RGB24,
+                DISPLAY_WIDTH as u32,
+                DISPLAY_HEIGHT as u32,
+            )
+            .unwrap();
 
-    let mut canvas = graphics.window.into_canvas().accelerated().build().unwrap();
-    canvas.clear();
-    canvas.present();
+        // allocates space for the loop ticks counter to be used in each
+        // iteration cycle
+        let mut counter = 0u32;
+
+        // the main loop to execute the multiple machine clocks
+        'main: loop {
+            // increments the counter that will keep track
+            // on the number of visual ticks since beginning
+            counter = counter.wrapping_add(1);
+
+            // obtains an event from the SDL sub-system to be
+            // processed under the current emulation context
+            while let Some(event) = self.graphics.event_pump.poll_event() {
+                match event {
+                    Event::Quit { .. } => break 'main,
+
+                    Event::KeyDown {
+                        keycode: Some(keycode),
+                        ..
+                    } => match key_to_pad(keycode) {
+                        Some(key) => self.system.key_press(key),
+                        None => (),
+                    },
+
+                    Event::KeyUp {
+                        keycode: Some(keycode),
+                        ..
+                    } => match key_to_pad(keycode) {
+                        Some(key) => self.system.key_lift(key),
+                        None => (),
+                    },
+
+                    _ => (),
+                }
+            }
 
-    let texture_creator = canvas.texture_creator();
+            let current_time = self.graphics.timer_subsystem.ticks();
+
+            let mut counter_ticks = 0u32;
+
+            if current_time >= self.next_tick_time_i {
+                loop {
+                    // limits the number of ticks to the typical number
+                    // of ticks required to do a complete PPU draw
+                    if counter_ticks >= 70224 {
+                        break;
+                    }
+
+                    // runs the Game Boy clock, this operations should
+                    // include the advance of both the CPU and the PPU
+                    counter_ticks += self.system.clock() as u32;
+                }
+
+                // obtains the frame buffer of the Game Boy PPU and uses it
+                // to update the stream texture, copying it then to the canvas
+                let frame_buffer = self.system.frame_buffer().as_ref();
+                texture
+                    .update(None, frame_buffer, DISPLAY_WIDTH as usize * 3)
+                    .unwrap();
+                self.graphics.canvas.copy(&texture, None, None).unwrap();
+
+                // presents the canvas effectively updating the screen
+                // information presented to the user
+                self.graphics.canvas.present();
+
+                // updates the next update time reference to the current
+                // time so that it can be used from game loop control
+                self.next_tick_time += 1000.0 / self.visual_frequency as f32;
+                self.next_tick_time_i = self.next_tick_time.ceil() as u32;
+            }
 
-    // creates the texture streaming that is going to be used
-    // as the target for the pixel buffer
-    let mut texture = texture_creator
-        .create_texture_streaming(
-            PixelFormatEnum::RGB24,
-            DISPLAY_WIDTH as u32,
-            DISPLAY_HEIGHT as u32,
-        )
-        .unwrap();
+            let current_time = self.graphics.timer_subsystem.ticks();
+            let pending_time = self.next_tick_time_i.saturating_sub(current_time);
+            self.graphics.timer_subsystem.delay(pending_time);
+        }
+    }
+}
 
+fn main() {
     // creates a new Game Boy instance and loads both the boot ROM
     // and the initial game ROM to "start the engine"
     let mut game_boy = GameBoy::new();
     game_boy.load_boot_default();
 
-    //game_boy.load_rom_file("../../res/roms.prop/tetris.gb");
-    //game_boy.load_rom_file("../../res/roms.prop/dr_mario.gb");
-    //game_boy.load_rom_file("../../res/roms.prop/alleyway.gb");
-    //game_boy.load_rom_file("../../res/roms.prop/super_mario.gb");
+    //let rom = game_boy.load_rom_file("../../res/roms.prop/tetris.gb");
+    //let rom = game_boy.load_rom_file("../../res/roms.prop/dr_mario.gb");
+    //let rom = game_boy.load_rom_file("../../res/roms.prop/alleyway.gb");
+    let rom = game_boy.load_rom_file("../../res/roms.prop/super_mario.gb");
     //let rom = game_boy.load_rom_file("../../res/roms.prop/super_mario_2.gb");
 
-    //game_boy.load_rom_file("../../res/roms/firstwhite.gb");
-    //game_boy.load_rom_file("../../res/roms/opus5.gb");
+    //let rom = game_boy.load_rom_file("../../res/roms/firstwhite.gb");
+    //let rom = game_boy.load_rom_file("../../res/roms/opus5.gb");
 
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/cpu_instrs.gb"); // CRASHED
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/interrupt_time/interrupt_time.gb"); // FAILED
-    let rom = game_boy.load_rom_file("../../res/roms/paradius/instr_timing/instr_timing.gb"); // FAILED
+    //let rom = game_boy.load_rom_file("../../res/roms/paradius/instr_timing/instr_timing.gb"); // FAILED
+    //let rom = game_boy.load_rom_file("../../res/roms/paradius/mem_timing/mem_timing.gb"); // NO FINISH
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/01-special.gb"); // PASSED
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/02-interrupts.gb"); // PASSED
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/03-op sp,hl.gb"); // PASSED
@@ -115,73 +171,12 @@ fn main() {
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/07-jr,jp,call,ret,rst.gb"); // PASSED
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/08-misc instrs.gb");  // PASSED
     //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/09-op r,r.gb"); // PASSED
-    //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/10-bit ops.gb"); //
-    //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/11-op a,(hl).gb"); //let rom  PASSED
-
+    //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/10-bit ops.gb"); // PASSED
+    //let rom = game_boy.load_rom_file("../../res/roms/paradius/cpu/11-op a,(hl).gb"); // PASSED
     println!("==== Cartridge ====\n{}\n===================", rom);
 
-    let mut counter = 0u32;
-
-    'main: loop {
-        // increments the counter that will keep track
-        // on the number of visual ticks since beginning
-        counter = counter.wrapping_add(1);
-
-        // obtains an event from the SDL sub-system to be
-        // processed under the current emulation context
-        while let Some(event) = graphics.event_pump.poll_event() {
-            match event {
-                Event::Quit { .. } => break 'main,
-
-                Event::KeyDown {
-                    keycode: Some(keycode),
-                    ..
-                } => match key_to_pad(keycode) {
-                    Some(key) => game_boy.key_press(key),
-                    None => (),
-                },
-
-                Event::KeyUp {
-                    keycode: Some(keycode),
-                    ..
-                } => match key_to_pad(keycode) {
-                    Some(key) => game_boy.key_lift(key),
-                    None => (),
-                },
-
-                _ => (),
-            }
-        }
-
-        let mut counter_ticks = 0u32;
-
-        loop {
-            // limits the number of ticks to the typical number
-            // of ticks required to do a complete PPU draw
-            if counter_ticks >= 70224 {
-                break;
-            }
-
-            // runs the Game Boy clock, this operations should
-            // include the advance of both the CPU and the PPU
-            counter_ticks += game_boy.clock() as u32;
-        }
-
-        // obtains the frame buffer of the Game Boy PPU and uses it
-        // to update the stream texture, copying it then to the canvas
-        let frame_buffer = game_boy.frame_buffer().as_ref();
-        texture
-            .update(None, frame_buffer, DISPLAY_WIDTH as usize * 3)
-            .unwrap();
-        canvas.copy(&texture, None, None).unwrap();
-
-        // presents the canvas effectively updating the screen
-        // information presented to the user
-        canvas.present();
-
-        // @todo this must be improved with proper timestamps
-        graphics.timer_subsystem.delay(17);
-    }
+    let mut emulator = Emulator::new(game_boy, SCREEN_SCALE);
+    emulator.run();
 }
 
 fn key_to_pad(keycode: Keycode) -> Option<PadKey> {
diff --git a/examples/sdl/src/util.rs b/examples/sdl/src/util.rs
new file mode 100644
index 0000000000000000000000000000000000000000..2f613a9def6b695b28513f082ddb3c58318333ad
--- /dev/null
+++ b/examples/sdl/src/util.rs
@@ -0,0 +1,72 @@
+use sdl2::{
+    render::Canvas, rwops::RWops, surface::Surface, sys::image, ttf::Sdl2TtfContext, video::Window,
+    AudioSubsystem, EventPump, TimerSubsystem, VideoSubsystem,
+};
+
+pub struct Graphics {
+    pub canvas: Canvas<Window>,
+    pub video_subsystem: VideoSubsystem,
+    pub timer_subsystem: TimerSubsystem,
+    pub audio_subsystem: AudioSubsystem,
+    pub event_pump: EventPump,
+    pub ttf_context: Sdl2TtfContext,
+}
+
+impl Graphics {
+    /// Start the SDL sub-system and all of its structure and returns
+    /// a structure with all the needed stuff to handle SDL graphics
+    /// and sound.
+    pub fn new(title: &str, width: u32, height: u32, scale: f32) -> Self {
+        // initializes the SDL sub-system, making it ready to be
+        // used for display of graphics and audio
+        let sdl = sdl2::init().unwrap();
+        let video_subsystem = sdl.video().unwrap();
+        let timer_subsystem = sdl.timer().unwrap();
+        let audio_subsystem = sdl.audio().unwrap();
+        let event_pump = sdl.event_pump().unwrap();
+
+        // initialized the fonts context to be used
+        // in the loading of fonts
+        let ttf_context = sdl2::ttf::init().unwrap();
+
+        // creates the system window that is going to be used to
+        // show the emulator and sets it to the central are o screen
+        let window = video_subsystem
+            .window(title, scale as u32 * width, scale as u32 * height)
+            .resizable()
+            .position_centered()
+            .opengl()
+            .build()
+            .unwrap();
+
+        // creates an accelerated canvas to be used in the drawing
+        // then clears it so that is can be presented empty initially
+        let mut canvas = window.into_canvas().accelerated().build().unwrap();
+        canvas.clear();
+
+        Self {
+            canvas: canvas,
+            video_subsystem: video_subsystem,
+            timer_subsystem: timer_subsystem,
+            audio_subsystem: audio_subsystem,
+            event_pump: event_pump,
+            ttf_context: ttf_context,
+        }
+    }
+
+    pub fn window(&self) -> &Window {
+        self.canvas.window()
+    }
+
+    pub fn window_mut(&mut self) -> &mut Window {
+        self.canvas.window_mut()
+    }
+}
+
+pub fn surface_from_bytes(bytes: &[u8]) -> Surface {
+    unsafe {
+        let rw_ops = RWops::from_bytes(bytes).unwrap();
+        let raw_surface = image::IMG_Load_RW(rw_ops.raw(), 0);
+        Surface::from_ll(raw_surface)
+    }
+}
diff --git a/res/roms/paradius/mem_timing/mem_timing.gb b/res/roms/paradius/mem_timing/mem_timing.gb
new file mode 100644
index 0000000000000000000000000000000000000000..78766b579f74433332c546c9cf06f8b972a4c2d8
Binary files /dev/null and b/res/roms/paradius/mem_timing/mem_timing.gb differ
diff --git a/src/rom.rs b/src/rom.rs
index 4eef24f6cd6395633b6e3126b5ed9d395c84d815..86c89671ef7239668a184b87a5a19aa4794b83c0 100644
--- a/src/rom.rs
+++ b/src/rom.rs
@@ -349,10 +349,12 @@ pub static MBC1: Mbc = Mbc {
                 rom.set_rom_bank(rom_bank);
             }
             0x4000 | 0x5000 => {
-                println!("SETTING UPPER BITS {}", value);
+                let ram_bank = value & 0x03;
+                rom.set_ram_bank(ram_bank);
             }
+            // ROM mode selection
             0x6000 | 0x7000 => {
-                println!("SETTING MODE {}", value);
+                debugln!("SETTING MODE {}", value);
             }
             _ => panic!("Writing to unknown Cartridge ROM location 0x{:04x}", addr),
         }