diff --git a/src/chip8/fonts.rs b/src/chip8/fonts.rs index 3c56660..d52895a 100644 --- a/src/chip8/fonts.rs +++ b/src/chip8/fonts.rs @@ -1,4 +1,4 @@ -pub const CHIP8_FONT: [u8; 16 * 5] = [ +pub const CHIP48_FONT: [u8; 16 * 5] = [ // 0 0xF0, 0x90, 0x90, 0x90, 0xF0, // 1 @@ -32,3 +32,143 @@ pub const CHIP8_FONT: [u8; 16 * 5] = [ // F 0xF0, 0x80, 0xF0, 0x80, 0x80, ]; + +pub const COSMAC_VIP_FONT: [u8; 16 * 5] = [ + // 0 + 0xF0, 0x90, 0x90, 0x90, 0xF0, + // 1 + 0x60, 0x20, 0x20, 0x20, 0x70, + // 2 + 0xF0, 0x10, 0xF0, 0x80, 0xF0, + // 3 + 0xF0, 0x10, 0xF0, 0x10, 0xF0, + // 4 + 0xA0, 0xA0, 0xF0, 0x20, 0x20, + // 5 + 0xF0, 0x80, 0xF0, 0x10, 0xF0, + // 6 + 0xF0, 0x80, 0xF0, 0x90, 0xF0, + // 7 + 0xF0, 0x10, 0x10, 0x10, 0x10, + // 8 + 0xF0, 0x90, 0xF0, 0x90, 0xF0, + // 9 + 0xF0, 0x90, 0xF0, 0x10, 0xF0, + // A + 0xF0, 0x90, 0xF0, 0x90, 0x90, + // B + 0xF0, 0x50, 0x70, 0x50, 0xF0, + // C + 0xF0, 0x80, 0x80, 0x80, 0xF0, + // D + 0xF0, 0x50, 0x50, 0x50, 0xF0, + // E + 0xF0, 0x80, 0xF0, 0x80, 0xF0, + // F + 0xF0, 0x80, 0xF0, 0x80, 0x80, + ]; + +pub const DREAM6800_FONT: [u8; 16 * 5] = [ + // 0 + 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, + // 1 + 0x40, 0x40, 0x40, 0x40, 0x40, + // 2 + 0xE0, 0x20, 0xE0, 0x80, 0xE0, + // 3 + 0xE0, 0x20, 0xE0, 0x20, 0xE0, + // 4 + 0xA0, 0xA0, 0xE0, 0x20, 0x20, + // 5 + 0xE0, 0x80, 0xE0, 0x20, 0xE0, + // 6 + 0xE0, 0x80, 0xE0, 0xA0, 0xE0, + // 7 + 0xE0, 0x20, 0x20, 0x20, 0x20, + // 8 + 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, + // 9 + 0xE0, 0xA0, 0xE0, 0x20, 0xE0, + // A + 0xE0, 0xA0, 0xE0, 0xA0, 0xA0, + // B + 0x80, 0x80, 0xE0, 0xA0, 0xE0, + // C + 0xE0, 0x80, 0x80, 0x80, 0xE0, + // D + 0x20, 0x20, 0xE0, 0xA0, 0xE0, + // E + 0xE0, 0x80, 0xE0, 0x80, 0xE0, + // F + 0xE0, 0x80, 0xE0, 0x80, 0x80, + ]; + +pub const ETI660_FONT: [u8; 16 * 5] = [ + // 0 + 0xE0, 0xA0, 0xA0, 0xA0, 0xE0, + // 1 + 0x20, 0x20, 0x20, 0x20, 0x20, + // 2 + 0xE0, 0x20, 0xE0, 0x80, 0xE0, + // 3 + 0xE0, 0x20, 0xE0, 0x20, 0xE0, + // 4 + 0xA0, 0xA0, 0xE0, 0x20, 0x20, + // 5 + 0xE0, 0x80, 0xE0, 0x20, 0xE0, + // 6 + 0xE0, 0x80, 0xE0, 0xA0, 0xE0, + // 7 + 0xE0, 0x20, 0x20, 0x20, 0x20, + // 8 + 0xE0, 0xA0, 0xE0, 0xA0, 0xE0, + // 9 + 0xE0, 0xA0, 0xE0, 0x20, 0xE0, + // A + 0xE0, 0xA0, 0xE0, 0xA0, 0xA0, + // B + 0x80, 0x80, 0xE0, 0xA0, 0xE0, + // C + 0xE0, 0x80, 0x80, 0x80, 0xE0, + // D + 0x20, 0x20, 0xE0, 0xA0, 0xE0, + // E + 0xE0, 0x80, 0xE0, 0x80, 0xE0, + // F + 0xE0, 0x80, 0xE0, 0x80, 0x80, + ]; + +pub const FISH_N_CHIPS_FONT: [u8; 16 * 5] = [ + // 0 + 0x60, 0xA0, 0xA0, 0xA0, 0xC0, + // 1 + 0x40, 0xC0, 0x40, 0x40, 0xE0, + // 2 + 0xC0, 0x20, 0x40, 0x80, 0xE0, + // 3 + 0xC0, 0x20, 0x40, 0x20, 0xC0, + // 4 + 0x20, 0xA0, 0xE0, 0x20, 0x20, + // 5 + 0xE0, 0x80, 0xC0, 0x20, 0xC0, + // 6 + 0x40, 0x80, 0xC0, 0xA0, 0x40, + // 7 + 0xE0, 0x20, 0x60, 0x40, 0x40, + // 8 + 0x40, 0xA0, 0x40, 0xA0, 0x40, + // 9 + 0x40, 0xA0, 0x60, 0x20, 0x40, + // A + 0x40, 0xA0, 0xE0, 0xA0, 0xA0, + // B + 0xC0, 0xA0, 0xC0, 0xA0, 0xC0, + // C + 0x60, 0x80, 0x80, 0x80, 0x60, + // D + 0xC0, 0xA0, 0xA0, 0xA0, 0xC0, + // E + 0xE0, 0x80, 0xC0, 0x80, 0xE0, + // F + 0xE0, 0x80, 0xC0, 0x80, 0x80, + ]; diff --git a/src/chip8/memory.rs b/src/chip8/memory.rs index 1bae38f..10b0805 100644 --- a/src/chip8/memory.rs +++ b/src/chip8/memory.rs @@ -3,7 +3,7 @@ use std::io::Read; use std::fs::File; use std::ops::{Index, IndexMut}; -use super::fonts::CHIP8_FONT; +use super::fonts::CHIP48_FONT; const FONT_OFFSET: usize = 0x50; @@ -11,14 +11,12 @@ pub struct Memory([u8; 4096]); impl Default for Memory { fn default() -> Self { - let mut memory = [0u8; 4096]; - memory[FONT_OFFSET..FONT_OFFSET + 16 * 5].copy_from_slice(&CHIP8_FONT); - Self(memory) + Self::with_font(&CHIP48_FONT) } } impl Memory { - fn with_font(font: &[u8; 16 * 5]) -> Self { + pub fn with_font(font: &[u8; 16 * 5]) -> Self { let mut memory = [0u8; 4096]; memory[FONT_OFFSET..FONT_OFFSET + 16 * 5].copy_from_slice(font); Self(memory) diff --git a/src/chip8/mod.rs b/src/chip8/mod.rs index a7a1384..92d4211 100644 --- a/src/chip8/mod.rs +++ b/src/chip8/mod.rs @@ -22,14 +22,30 @@ impl Chip8 { "64x128", //< HI-RES CHIP-8 ]; - pub fn new(display_size: &str) -> Self { + pub const AVAILABLE_FONTS: [&'static str; 5] = [ + "chip48", + "cosmacvip", + "dream6800", + "eti660", + "fishnchips", + ]; + + pub fn new(display_size: &str, font: &str) -> Self { let (width, height) = match display_size { "64x32" => (64, 32), "128x64" => (128, 64), "64x128" => (64, 128), - _ => panic!("Unexpected Chip8 display size: {}", display_size), + _ => panic!("Unexpected CHIP-8 display size: {}", display_size), + }; + let font = match font { + "chip48" => &fonts::CHIP48_FONT, + "cosmacvip" => &fonts::COSMAC_VIP_FONT, + "dream6800" => &fonts::DREAM6800_FONT, + "eti660" => &fonts::ETI660_FONT, + "fishnchips" => &fonts::FISH_N_CHIPS_FONT, + _ => panic!("Unknown CHIP-8 font: {}", font), }; - let memory = memory::Memory::default(); + let memory = memory::Memory::with_font(font); let display = display::Display::new(width, height, FRAMERATE); Self { cpu: cpu::CPU::default(), diff --git a/src/main.rs b/src/main.rs index 4c60156..389fdd7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,14 @@ fn main() { .long("display") .default_value("64x32") .possible_values(&chip8::Chip8::AVAILABLE_DISPLAY_SIZES) + ) + .arg( + Arg::new("font") + .about("font") + .takes_value(true) + .long("font") + .default_value("chip48") + .possible_values(&chip8::Chip8::AVAILABLE_FONTS) ), ) .get_matches(); @@ -32,7 +40,8 @@ fn main() { Some("chip8") => { let subcommand = matches.subcommand_matches("chip8").unwrap(); let display = subcommand.value_of("display").unwrap(); - let mut chip8 = chip8::Chip8::new(display); + let font = subcommand.value_of("font").unwrap(); + let mut chip8 = chip8::Chip8::new(display, font); let filename = subcommand.value_of("rom-file").unwrap(); println!("loading {}", filename); let f = File::open(filename).unwrap();