commit - e4b3bdecac0878c575ac410513582983b59f82eb
commit + 00098d83918691e91c4ecd0f18bd9e542c5ce9a1
blob - 4b055bbd7b017259a2000c802efb1f80797b9570
blob + 11a1422a4ad5b4db09bfa55ee568cb7b7a36c4d9
--- src/chip8.rs
+++ src/chip8.rs
+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
-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
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(())