first files: code skeleton
This commit is contained in:
commit
e565a98e6d
2 changed files with 208 additions and 0 deletions
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
|
@ -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"
|
198
src/main.rs
Normal file
198
src/main.rs
Normal file
|
@ -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<i32>
|
||||
}
|
||||
|
||||
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<Window>) {
|
||||
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();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue