Commit Diff


commit - e4b3bdecac0878c575ac410513582983b59f82eb
commit + 00098d83918691e91c4ecd0f18bd9e542c5ce9a1
blob - 4b055bbd7b017259a2000c802efb1f80797b9570
blob + 11a1422a4ad5b4db09bfa55ee568cb7b7a36c4d9
--- src/chip8.rs
+++ src/chip8.rs
@@ -1,40 +1,76 @@
+use crate::drivers::VideoDriver;
+
 #[derive(Debug)]
 /// Represents a Chip8 machine
 pub struct Chip8 {
     /// Memory of 4096 8 bit wide locations
     /// 0x000 - 0x1FF is usually reserved for the interpreter
     /// 0x200 is where most Chip8 programs start
-    mem: [u8; 4096],
-    /// 16 registers, commonly named V0-VF
-    regs: [u8; 16],
-    /// 12 bit wide address register
+    mem: Vec<u8>,
+    /// 16 registers, commonly named V0-VF.
+    regs: Vec<u8>,
+    /// 12 bit wide address register.
     i_reg: u16,
-    /// 16-bit Program Counter
+    /// 16-bit Program Counter.
     pc: u16,
-    /// Call stack with a maximum size of 16
-    stack: [u16; 16],
-    /// Stack pointer, pointing to the topmost level of the stack
+    /// Call stack with a maximum size of 16.
+    stack: Vec<u16>,
+    /// Stack pointer, pointing to the topmost level of the stack.
     stack_pointer: u8,
     /// Delay timer
-    /// The value of timer is being decremented at a rate of 60Hz
+    /// The value of timer is being decremented at a rate of 60Hz.
     delay_timer: u8,
     /// Sound timer
-    /// The value of this timer is being decremented at a rate of 60Hz
+    /// The value of this timer is being decremented at a rate of 60Hz.
     sound_timer: u8,
+    /// Video Driver
+    video_driver: VideoDriver,
 }
 
-// should be implemented ourselves since Default is not implemented for array with sizes > 32
-impl Default for Chip8 {
-    fn default() -> Self {
+/// Instructions of the Chip8.
+pub enum Instruction {
+    /// Clears the screen.
+    CLS,
+}
+
+impl Chip8 {
+    pub fn new() -> Self {
         Self {
-            mem: [0; 4096],
-            regs: [0; 16],
+            mem: vec![0; 4096],
+            regs: vec![0; 16],
             i_reg: 0,
             pc: 0,
-            stack: [0; 16],
+            stack: vec![0; 16],
             stack_pointer: 0,
             delay_timer: 0,
             sound_timer: 0,
+            video_driver: VideoDriver::new(),
         }
     }
+
+    /// Execute a given instruction.
+    pub fn execute(&mut self, instruction: Instruction) -> Result<(), String> {
+        match instruction {
+            // CLS
+            Instruction::CLS => {
+                self.video_driver.clear();
+            },
+        };
+
+        Ok(())
+    }
 }
+
+// this makes the code easier to read
+/// Convert a raw u16 instruction to an Instruction enum.
+pub fn raw_to_instruction(instruction: u16) -> Result<Instruction, String> {
+    match instruction {
+        // CLS
+        0x00E0 => {
+            return Ok(Instruction::CLS)
+        },
+        _ => {
+            return Err(format!("{:x}: not an instruction", instruction));
+        }
+    }
+}
blob - 80942aa10242e5df4a275e3fbee886492b0beb37
blob + 4a0bc3f1f549d1db39b1c9566156cd08f79de702
--- src/drivers/video_driver.rs
+++ src/drivers/video_driver.rs
@@ -1,39 +1,22 @@
-use minifb::{Window, WindowOptions};
-
 // TODO: cli arg
 const STRETCH_FACTOR: usize = 2;
 const WINDOW_WIDTH: usize = 64 * STRETCH_FACTOR;
 const WINDOW_HEIGHT: usize = 32 * STRETCH_FACTOR;
 
-/// Contains the window to draw to.
+#[derive(Debug)]
+/// Contains the buffer that will be used to draw to the window.
 pub struct VideoDriver {
-    window: Window,
+    buffer: Vec<u32>,
 }
 
 impl VideoDriver {
-    /// Create a new window.
+    /// Create a new buffer.
     pub fn new() -> Self {
-        let mut w = Window::new("yac8e", 64, 32, WindowOptions::default())
-            .expect("Unable to open a window");
-
-        Self { window: w }
+        Self { buffer: vec![0; WINDOW_WIDTH * WINDOW_HEIGHT] }
     }
 
-    /// Draw the given array to the window.
-    pub fn draw(&mut self, pixels: &[u32; WINDOW_WIDTH * WINDOW_HEIGHT]) {
-        self.window
-            .update_with_buffer(pixels, WINDOW_WIDTH, WINDOW_HEIGHT)
-            .expect("Wrong buffer size");
-    }
-
-    /// Clears the window.
+    /// Clears the buffer.
     pub fn clear(&mut self) {
-        todo!();
+        self.buffer.clear();
     }
 }
-
-pub fn from_u8_rgb(r: u8, g: u8, b: u8) -> u32 {
-    let (r, g, b) = (r as u32, g as u32, b as u32);
-
-    (r << 16) | (g << 8) | b
-}
blob - 66927a6fa454baaa4883edc86a7461e617fb3f8c
blob + b2d6b056b7cfc8cc73a88825087bab39f390f2a8
--- src/main.rs
+++ src/main.rs
@@ -1,11 +1,16 @@
 mod chip8;
 mod drivers;
 
-use drivers::VideoDriver;
+use chip8::Chip8;
 
+use minifb::{Window, WindowOptions};
+
 fn main() -> Result<(), String> {
-    let v = VideoDriver::new();
+    let mut w = Window::new("yac8e", 64, 32, WindowOptions::default())
+        .expect("Unable to open a window");
 
+    let chip8 = Chip8::new();
+
     std::thread::sleep(std::time::Duration::from_secs(1));
 
     Ok(())