commit e565a98e6d4f0d59e08eca57a6ced8fe655f5c1b Author: rick Date: Mon Feb 7 01:24:11 2022 +0100 first files: code skeleton diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e23b384 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "chip8-emulator" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +sdl2 = "0.35.1" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..f5a7238 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,198 @@ +extern crate sdl2; + +use sdl2::pixels::Color; +use sdl2::event::Event; +use sdl2::keyboard::Keycode; +use sdl2::video::Window; + +use std::fs::File; +use std::path::Path; +use std::io; +use std::io::Read; + +const font: [u8; 80] = [ + 0xF0, 0x90, 0x90, 0x90, 0xF0, + 0x20, 0x60, 0x20, 0x20, 0x70, + 0xF0, 0x10, 0xF0, 0x80, 0xF0, + 0xF0, 0x10, 0xF0, 0x10, 0xF0, + 0x90, 0x90, 0xF0, 0x10, 0x10, + 0xF0, 0x80, 0xF0, 0x10, 0xF0, + 0xF0, 0x80, 0xF0, 0x90, 0xF0, + 0xF0, 0x10, 0x20, 0x40, 0x40, + 0xF0, 0x90, 0xF0, 0x90, 0xF0, + 0xF0, 0x90, 0xF0, 0x10, 0xF0, + 0xF0, 0x90, 0xF0, 0x90, 0x90, + 0xE0, 0x90, 0xE0, 0x90, 0xE0, + 0xF0, 0x80, 0x80, 0x80, 0xF0, + 0xE0, 0x90, 0x90, 0x90, 0xE0, + 0xF0, 0x80, 0xF0, 0x80, 0xF0, + 0xF0, 0x80, 0xF0, 0x80, 0x80 +]; + +struct Machine { + memory: [u8; 4096], + key_inputs: [i32; 16], + display_buffer: [[i32; 64]; 32], + gpio: [i8; 16], + index: i16, + opcode: u16, + pc: usize, + stack: Vec +} + +fn decodeOp(op1: u8, op2: u8) -> u16 { + let ret: u16 = u16::from(op1) << 2; + ret + u16::from(op2) >> 2 +} + +impl Machine { + /// Initialise une machine en mettant tout à 0 (RAM, PC...) + pub fn new() -> Self { + Machine { + memory: [0; 4096], + key_inputs: [0; 16], + display_buffer: [[0; 64]; 32], + gpio: [0; 16], + index: 0, + opcode: 0, + pc: 0, + stack: Vec::new(), + } + } + + pub fn init(&mut self) { + for i in 0..font.len() { + self.memory[i] = font[i]; + } + + self.pc = 0x200; + } + + /// charge une ROM en mémoire + pub fn loadRom(&mut self, p: &Path) -> io::Result<()> { + let mut buffer = Vec::new(); + let mut f = File::open(p)?; + f.read_to_end(&mut buffer)?; + + for i in 0..buffer.len() { + self.memory[i + 0x200] = buffer[i]; + } + + Ok(()) + } + + pub fn cycle(&mut self, screen: &mut sdl2::render::Canvas) { + self.opcode = ((self.memory[self.pc] as u16) << 8) + + (self.memory[self.pc + 1] as u16); + + self.pc += 2; + //let o = self.opcode & 0xf000; + + match (self.opcode & 0xf000) >> 12 { + 0 => match self.opcode { + 0x00E0 => screen.clear(), + 0x00EE => println!("RET"), + _ => println!("SYS"), + } + 1 => println!("JP"), + 2 => println!("CALL"), + 3 => println!("SE"), + 4 => println!("SNE"), + 5 => println!("SE 5"), + 6 => println!("LD"), + 7 => println!("ADD"), + 8 => { + let x = (self.opcode & 0x0f00) >> 8; + let y = (self.opcode & 0x00f0) >> 4; + match self.opcode & 0x000f { + 0 => println!("LD 8"), + 1 => println!("OR"), + 2 => println!("AND"), + 3 => println!("XOR"), + 4 => println!("ADD"), + 5 => println!("SUB"), + 6 => println!("SHR"), + 7 => println!("SUBN"), + 0xE => println!("SHL"), + _ => println!("error 8") + } + } + 9 => println!("SNE 9"), + 0xA => println!("LD A"), + 0xB => println!("JP B"), + 0xC => println!("RND "), + 0xD => println!("DRW"), + 0xE => { + let x = (self.opcode & 0x0f00) >> 8; + match self.opcode & 0x00ff { + 0x9E => println!("SKP"), + 0xA1 => println!("SKNP"), + _ => println!("error E") + } + } + 0xF => { + let x = (self.opcode & 0x0f00) >> 8; + match self.opcode & 0x00ff { + 0x07 => println!("LD F 7"), + 0x0A => println!("LD F A"), + 0x15 => println!("LD F 15"), + 0x18 => println!("LD F 18"), + 0x1E => println!("ADD F 1E"), + 0x29 => println!("LD F 2"), // self.index = self.gpio[x] * 5) & 0x0fff + 0x33 => println!("LD F 3"), + 0x55 => println!("LD F 5"), + 0x65 => println!("LD F 6"), + _ => println!("error F") + } + } + _ => println!("error") + } + } +} + + +fn main() { + let mut t : Machine = Machine::new(); + println!("{:?}", t.memory); + t.init(); + t.loadRom(Path::new("15PUZZLE")); + println!("\n\n{:?}", t.memory); + //t.cycle(); + + let sdl_context = sdl2::init().unwrap(); + let video_subsystem = sdl_context.video().unwrap(); + let window = video_subsystem.window("Chip8 Emulator", 900, 700) + .position_centered() + .build() + .unwrap(); + + let mut canvas = window.into_canvas().build().unwrap(); + canvas.set_draw_color(Color::RGB(0, 255, 255)); + canvas.clear(); + canvas.present(); + + let mut event_pump = sdl_context.event_pump().unwrap(); + let mut i = 0; + + 'running: loop { + /* + i = (i + 1) % 255; + canvas.set_draw_color(Color::RGB(i, 64, 255 - i)); + canvas.clear(); + */ + t.cycle(&mut canvas); + + /* + for event in event_pump.poll_iter() { + match event { + Event::KeyDown { keycode: Some(Keycode::Escape), ..} => { + break 'running + }, + _ => {} + } + } + */ + + canvas.present(); + } +}