my first schip rom works in my schip emulator.
BUGFIX: Corrects runaway after drawing in my first schip rom scroll down, left, right all test with test rom assembler now assembles to the expected output it seems fixes incorrect loading of schip font to memory replaces schip font from new chatgpt feedback
This commit is contained in:
@@ -12,7 +12,7 @@ use super::{
|
||||
system_memory::Chip8SystemMemory, video::Chip8Video,
|
||||
};
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct Chip8Computer {
|
||||
pub num_cycles: i32,
|
||||
pub memory: Chip8SystemMemory,
|
||||
@@ -43,15 +43,15 @@ impl Default for Chip8Computer {
|
||||
}
|
||||
|
||||
impl Chip8Computer {
|
||||
pub fn reset(&mut self) {
|
||||
pub fn reset(&mut self, quirk_mode: QuirkMode) {
|
||||
self.video_memory.reset();
|
||||
self.num_cycles = 0;
|
||||
self.registers.reset();
|
||||
self.delay_timer.reset();
|
||||
self.sound_timer.reset();
|
||||
self.stack.reset();
|
||||
self.memory.reset();
|
||||
self.quirk_mode = QuirkMode::Chip8;
|
||||
self.memory.reset(quirk_mode);
|
||||
self.quirk_mode = quirk_mode;
|
||||
}
|
||||
|
||||
pub fn dump_keypad_to_string(&self) -> String {
|
||||
@@ -108,7 +108,7 @@ impl Chip8Computer {
|
||||
|
||||
match self.state {
|
||||
Chip8CpuStates::WaitingForInstruction => {
|
||||
println!("Ticking sound, delay, video");
|
||||
// println!("Ticking sound, delay, video");
|
||||
self.sound_timer.tick();
|
||||
self.delay_timer.tick();
|
||||
self.video_memory.tick();
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
use std::thread;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use crate::chip8::computer::Chip8Computer;
|
||||
use crate::chip8::cpu_states::Chip8CpuStates;
|
||||
use crate::chip8::cpu_states::Chip8CpuStates::WaitingForInstruction;
|
||||
use crate::chip8::quirk_modes::QuirkMode;
|
||||
use std::thread;
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub enum ManagerDumpables {
|
||||
Video,
|
||||
Registers,
|
||||
Keyboard
|
||||
Keyboard,
|
||||
}
|
||||
|
||||
pub struct Chip8ComputerManager {
|
||||
core_should_run: bool,
|
||||
one_step: bool,
|
||||
core_cycle_timer: bool,
|
||||
core_last_cycle_start: Instant,
|
||||
computer: Chip8Computer
|
||||
computer: Chip8Computer,
|
||||
}
|
||||
|
||||
impl Default for Chip8ComputerManager {
|
||||
@@ -23,26 +24,27 @@ impl Default for Chip8ComputerManager {
|
||||
Chip8ComputerManager {
|
||||
core_should_run: false,
|
||||
one_step: false,
|
||||
core_cycle_timer: false,
|
||||
core_last_cycle_start: Instant::now() ,
|
||||
computer: Chip8Computer::new()
|
||||
core_last_cycle_start: Instant::now(),
|
||||
computer: Chip8Computer::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Chip8ComputerManager {
|
||||
pub fn reset(&mut self) {
|
||||
pub fn quirks_mode(&self) -> QuirkMode {
|
||||
self.computer.quirk_mode.clone()
|
||||
}
|
||||
|
||||
pub fn reset(&mut self, mode: QuirkMode) {
|
||||
self.one_step = false;
|
||||
self.core_should_run = false;
|
||||
self.computer.reset();
|
||||
self.computer.reset(mode);
|
||||
}
|
||||
pub fn new() -> Chip8ComputerManager {
|
||||
let core_handle = thread::spawn(move || {
|
||||
loop {
|
||||
let start_time = Instant::now();
|
||||
let sleep_time = Instant::now().duration_since(start_time).as_millis();
|
||||
sleep(Duration::from_millis((16 - sleep_time) as u64));
|
||||
}
|
||||
let _ = thread::spawn(move || loop {
|
||||
let start_time = Instant::now();
|
||||
let sleep_time = Instant::now().duration_since(start_time).as_millis();
|
||||
sleep(Duration::from_millis((16 - sleep_time) as u64));
|
||||
});
|
||||
|
||||
Chip8ComputerManager::default()
|
||||
@@ -64,15 +66,15 @@ impl Chip8ComputerManager {
|
||||
&self.computer
|
||||
}
|
||||
|
||||
pub fn tick( &mut self) -> bool {
|
||||
// println!("STARTING TICK");
|
||||
pub fn tick(&mut self) -> bool {
|
||||
// println!("STARTING TICK");
|
||||
let mut did_tick: bool = false;
|
||||
if self.one_step | self.core_should_run {
|
||||
if self.one_step | self.core_should_run {
|
||||
if let WaitingForInstruction = self.computer.state {
|
||||
self.core_last_cycle_start = Instant::now();
|
||||
self.computer.step_system();
|
||||
did_tick = true
|
||||
// println!("SYSTEM STEP");
|
||||
// println!("SYSTEM STEP");
|
||||
}
|
||||
};
|
||||
if self.one_step {
|
||||
@@ -112,21 +114,15 @@ impl Chip8ComputerManager {
|
||||
}
|
||||
|
||||
pub fn load_new_program_to_system_memory(&mut self, bytes_to_load: Vec<u8>) {
|
||||
self.reset();
|
||||
self.reset(self.computer.quirk_mode.clone());
|
||||
self.computer.load_bytes_to_memory(0x200, &bytes_to_load);
|
||||
}
|
||||
|
||||
pub fn dump_to_string(&self, dump_type: ManagerDumpables) -> String {
|
||||
match dump_type {
|
||||
ManagerDumpables::Video => {
|
||||
self.computer.video_memory.format_as_string()
|
||||
}
|
||||
ManagerDumpables::Registers => {
|
||||
self.computer.registers.format_as_string()
|
||||
}
|
||||
ManagerDumpables::Keyboard => {
|
||||
self.computer.keypad.format_as_string()
|
||||
}
|
||||
ManagerDumpables::Video => self.computer.video_memory.format_as_string(),
|
||||
ManagerDumpables::Registers => self.computer.registers.format_as_string(),
|
||||
ManagerDumpables::Keyboard => self.computer.keypad.format_as_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Default, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Default, Serialize, Deserialize, Debug)]
|
||||
pub enum Chip8CpuStates {
|
||||
#[default]
|
||||
WaitingForInstruction,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
||||
pub struct DelayTimer {
|
||||
counter: u8,
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use crate::constants::*;
|
||||
use log::debug;
|
||||
use rand::Rng;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ascii::AsciiExt;
|
||||
use std::fmt::{Debug, Display, Formatter};
|
||||
use std::ops::BitAnd;
|
||||
use std::time::Instant;
|
||||
@@ -270,6 +271,11 @@ pub enum Chip8CpuInstructions {
|
||||
/// scroll screen content down N pixel, in XO-CHIP only selected bit
|
||||
/// planes are scrolled (Quirks are HP48 specific)
|
||||
SCU(u8),
|
||||
/// 0xNNNN
|
||||
///
|
||||
/// data word
|
||||
/// used for specifying data to be used in system memory
|
||||
DW(u16),
|
||||
}
|
||||
|
||||
impl Chip8CpuInstructions {
|
||||
@@ -322,6 +328,7 @@ impl Chip8CpuInstructions {
|
||||
JPX(_, _) => INST_JPX,
|
||||
XXXXERRORINSTRUCTION => "XX ERROR XX",
|
||||
SCU(_) => INST_SCU,
|
||||
DW(_) => INST_DW,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,7 +338,8 @@ impl Chip8CpuInstructions {
|
||||
let addr_for_display = (*x as u16) << 8 | *addr;
|
||||
format!("0x{x:02x}, 0x{addr_for_display:04x}")
|
||||
}
|
||||
Chip8CpuInstructions::SYS(addr)
|
||||
Chip8CpuInstructions::DW(addr)
|
||||
| Chip8CpuInstructions::SYS(addr)
|
||||
| Chip8CpuInstructions::JPI(addr)
|
||||
| Chip8CpuInstructions::JPA(addr)
|
||||
| Chip8CpuInstructions::LDIA(addr)
|
||||
@@ -406,7 +414,7 @@ impl Chip8CpuInstructions {
|
||||
pub fn from_str(input: &str) -> Chip8CpuInstructions {
|
||||
let mut parts = input.split(" ");
|
||||
// print!("THERE ARE {} PARTS", parts.clone().count());
|
||||
let first_part = parts.next().unwrap_or("");
|
||||
let first_part = parts.next().unwrap_or("").to_ascii_uppercase();
|
||||
// take the next value...
|
||||
// ...strip off the extra...
|
||||
// ...convert it to an integer from base 16
|
||||
@@ -414,6 +422,7 @@ impl Chip8CpuInstructions {
|
||||
parts
|
||||
.next()
|
||||
.unwrap_or("0")
|
||||
.to_ascii_lowercase()
|
||||
.trim_start_matches("0x")
|
||||
.trim_end_matches(","),
|
||||
16,
|
||||
@@ -423,6 +432,7 @@ impl Chip8CpuInstructions {
|
||||
parts
|
||||
.next()
|
||||
.unwrap_or("0")
|
||||
.to_ascii_lowercase()
|
||||
.trim_start_matches("0x")
|
||||
.trim_end_matches(","),
|
||||
16,
|
||||
@@ -432,13 +442,17 @@ impl Chip8CpuInstructions {
|
||||
parts
|
||||
.next()
|
||||
.unwrap_or("0")
|
||||
.to_ascii_lowercase()
|
||||
.trim_start_matches("0x")
|
||||
.trim_end_matches(","),
|
||||
16,
|
||||
)
|
||||
.unwrap_or(0);
|
||||
// println!("\tFirst part is {:?} / {:?} / {:?} / {:?}", first_part, param1 ,param2 ,param3);
|
||||
match first_part {
|
||||
println!(
|
||||
"\tFirst part is {:?} / {:?} / {:?} / {:?}",
|
||||
first_part, param1, param2, param3
|
||||
);
|
||||
match first_part.as_str() {
|
||||
INST_ADDI => ADDI(param1 as u8),
|
||||
INST_ADD => ADD(param1 as u8, param2 as u8),
|
||||
INST_CLS => CLS,
|
||||
@@ -483,6 +497,7 @@ impl Chip8CpuInstructions {
|
||||
INST_LDIS => LDIS(param1 as u8),
|
||||
INST_LDD => LDD(param1 as u8),
|
||||
INST_JPX => JPX(param1 as u8, param2),
|
||||
INST_DW => DW(param1 as u16),
|
||||
_ => XXXXERRORINSTRUCTION,
|
||||
}
|
||||
}
|
||||
@@ -571,8 +586,9 @@ impl Chip8CpuInstructions {
|
||||
Chip8CpuInstructions::LDF2(x_register) => 0xF030 | ((*x_register as u16) << 8),
|
||||
Chip8CpuInstructions::STR(x_register) => 0xF075 | ((*x_register as u16) << 8),
|
||||
Chip8CpuInstructions::LIDR(x_register) => 0xF085 | ((*x_register as u16) << 8),
|
||||
XXXXERRORINSTRUCTION => 0xFFFF,
|
||||
SCU(x_register) => 0x00D0 | (*x_register as u16),
|
||||
DW(address) => *address as u16,
|
||||
XXXXERRORINSTRUCTION => 0x0000,
|
||||
}
|
||||
}
|
||||
pub fn decode(input: u16, quirk_mode: &QuirkMode) -> Chip8CpuInstructions {
|
||||
@@ -661,7 +677,7 @@ impl Chip8CpuInstructions {
|
||||
0x85 => Chip8CpuInstructions::LIDR(ubln),
|
||||
_ => XXXXERRORINSTRUCTION,
|
||||
},
|
||||
_ => XXXXERRORINSTRUCTION,
|
||||
_ => DW(addr_param),
|
||||
}
|
||||
}
|
||||
pub fn execute(&self, input: &mut Chip8Computer) -> Chip8Computer {
|
||||
@@ -1084,6 +1100,7 @@ impl Chip8CpuInstructions {
|
||||
input.registers.poke_i(offset + 1);
|
||||
}
|
||||
Chip8CpuInstructions::XXXXERRORINSTRUCTION => {}
|
||||
// SCHIP1.1
|
||||
Chip8CpuInstructions::SCD(x) => match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
debug!("Attempt to execute SCD in Chip8 Mode");
|
||||
@@ -1092,6 +1109,7 @@ impl Chip8CpuInstructions {
|
||||
input.video_memory.scroll_down(*x as i32);
|
||||
}
|
||||
},
|
||||
// SCHIP 1.1
|
||||
Chip8CpuInstructions::SCR => match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
debug!("Attempt to execute SCR in Chip8 Mode");
|
||||
@@ -1100,6 +1118,7 @@ impl Chip8CpuInstructions {
|
||||
input.video_memory.scroll_right();
|
||||
}
|
||||
},
|
||||
// SCHIP 1.1
|
||||
Chip8CpuInstructions::SCL => match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
debug!("Attempt to execute SCL in Chip8 Mode");
|
||||
@@ -1108,6 +1127,7 @@ impl Chip8CpuInstructions {
|
||||
input.video_memory.scroll_left();
|
||||
}
|
||||
},
|
||||
// SCHIP 1.0
|
||||
Chip8CpuInstructions::LOW => match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
debug!("ATTEMPT TO SET LOWRES IN CHIP8MODE");
|
||||
@@ -1116,6 +1136,7 @@ impl Chip8CpuInstructions {
|
||||
input.video_memory.set_lowres();
|
||||
}
|
||||
},
|
||||
// SCHIP 1.0
|
||||
Chip8CpuInstructions::HIGH => match input.quirk_mode {
|
||||
QuirkMode::Chip8 => {
|
||||
debug!("ATTEMPT TO SET HIGHRES IN CHIP8MODE");
|
||||
@@ -1171,6 +1192,9 @@ impl Chip8CpuInstructions {
|
||||
}
|
||||
}
|
||||
}
|
||||
DW(addr) => {
|
||||
println!("DATA WORD FOUND...");
|
||||
}
|
||||
};
|
||||
let cycle_time = Instant::now().duration_since(start_time).as_nanos();
|
||||
// println!("\t\tTook {cycle_time}ms");
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::constants::CHIP8_KEYBOARD;
|
||||
|
||||
#[derive(Clone, Copy, Default, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Default, Serialize, Deserialize, Debug)]
|
||||
pub struct Keypad {
|
||||
keys: [bool; 0x10],
|
||||
}
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Default, Clone, Serialize, Deserialize)]
|
||||
#[derive(Default, Clone, Serialize, Deserialize, Copy, Debug)]
|
||||
pub enum QuirkMode {
|
||||
#[default]
|
||||
Chip8,
|
||||
XOChip,
|
||||
#[default]
|
||||
SChipModern,
|
||||
}
|
||||
|
||||
impl Display for QuirkMode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let variant = match &self {
|
||||
QuirkMode::Chip8 => "Chip8".to_string(),
|
||||
QuirkMode::XOChip => "XO Chip".to_string(),
|
||||
QuirkMode::SChipModern => "SChip-Modern".to_string(),
|
||||
};
|
||||
write!(f, "{}", variant)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Registers. numbered 1-16 publicly.
|
||||
/// Privately using zero base array so -1 to shift from pub to priv.
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
||||
pub struct Chip8Registers {
|
||||
pub registers: [u8; 16],
|
||||
pub i_register: u16,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use log::trace;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
||||
pub struct SoundTimer {
|
||||
counter: i32,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Default, Serialize, Deserialize)]
|
||||
#[derive(Clone, Default, Serialize, Deserialize, Debug)]
|
||||
pub struct Chip8Stack {
|
||||
items: Vec<u16>,
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ use crate::constants::*;
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
use super::quirk_modes;
|
||||
use super::quirk_modes::QuirkMode;
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct Chip8SystemMemory {
|
||||
memory: Vec<u8>,
|
||||
}
|
||||
@@ -18,6 +21,7 @@ impl Default for Chip8SystemMemory {
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
impl Chip8SystemMemory {
|
||||
fn empty_memory() -> Vec<u8> {
|
||||
let mut working_memory = vec![];
|
||||
@@ -28,10 +32,19 @@ impl Chip8SystemMemory {
|
||||
working_memory
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
pub fn reset(&mut self, quirk_modes: QuirkMode) {
|
||||
self.memory = Chip8SystemMemory::empty_memory();
|
||||
self.load_fonts_to_memory();
|
||||
self.load_schip_fonts_to_memory();
|
||||
match quirk_modes {
|
||||
QuirkMode::Chip8 => {
|
||||
self.load_fonts_to_memory();
|
||||
}
|
||||
QuirkMode::XOChip => {
|
||||
println!("NO XO FONT LOADING DONE YET");
|
||||
}
|
||||
QuirkMode::SChipModern => {
|
||||
self.load_schip_fonts_to_memory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
@@ -114,10 +127,10 @@ impl Chip8SystemMemory {
|
||||
SCHIPFONT_F,
|
||||
];
|
||||
for (font_index, current_font) in all_font_characters.iter().enumerate() {
|
||||
let base_offset = 0x100;
|
||||
for font_mem_offset in 0..=4 {
|
||||
let real_offset = base_offset + font_index * 0x10 + font_mem_offset;
|
||||
self.poke(real_offset as u16, current_font[font_mem_offset]);
|
||||
let base_offset = SCHIPFONT_OFFSET;
|
||||
for font_mem_offset in 0..=9 {
|
||||
let real_offset = base_offset + (font_index * 0x0a) as u32 + font_mem_offset;
|
||||
self.poke(real_offset as u16, current_font[font_mem_offset as usize]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,13 +6,13 @@ use crate::constants::{
|
||||
use log::debug;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Clone, Copy, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
|
||||
pub enum Chip8VideoModes {
|
||||
LowRes,
|
||||
HighRes,
|
||||
}
|
||||
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct Chip8Video {
|
||||
memory: Vec<bool>,
|
||||
pub has_frame_changed: bool,
|
||||
@@ -172,14 +172,16 @@ impl Chip8Video {
|
||||
}
|
||||
|
||||
pub fn scroll_left(&mut self) {
|
||||
println!("SCROLLLEFTPRE:::[{}]", self.format_as_string());
|
||||
let (width, height) = self.get_resolution();
|
||||
|
||||
for current_row in 0..height {
|
||||
let row_offset = current_row * width;
|
||||
for current_column in 0..width - 4 {
|
||||
let source: usize = (row_offset + current_column) as usize;
|
||||
let target: usize = source + 4;
|
||||
for current_column in (0..width - 4) {
|
||||
let target: usize = (row_offset + current_column) as usize;
|
||||
let source: usize = target + 4;
|
||||
self.memory[target] = self.memory[source];
|
||||
println!("Moving from {source} to {target}");
|
||||
}
|
||||
|
||||
let clear_start: usize = (row_offset + width - 4) as usize;
|
||||
@@ -187,6 +189,7 @@ impl Chip8Video {
|
||||
|
||||
self.memory[clear_start..clear_end].fill(false);
|
||||
}
|
||||
println!("SCROLLLEFTPOST:::[{}]", self.format_as_string());
|
||||
}
|
||||
|
||||
pub fn scroll_up(&mut self, how_far: &u8) {
|
||||
|
||||
+22
-88
@@ -12,7 +12,7 @@ pub const CHIP8_KEYBOARD: [[u8; 4]; 4] = [
|
||||
[0x01, 0x02, 0x03, 0x0C],
|
||||
[0x04, 0x05, 0x06, 0x0D],
|
||||
[0x07, 0x08, 0x09, 0x0E],
|
||||
[0x0A, 0x00, 0x0B, 0x0F]
|
||||
[0x0A, 0x00, 0x0B, 0x0F],
|
||||
];
|
||||
|
||||
pub const SCHIP_VIDEO_HEIGHT: i32 = 64;
|
||||
@@ -65,6 +65,10 @@ pub const INST_LOW: &str = "LOW";
|
||||
pub const INST_HIGH: &str = "HIGH";
|
||||
pub const INST_ORY: &str = "ORY";
|
||||
pub const INST_SCU: &str = "SCU";
|
||||
/// Data Word
|
||||
/// Data to be loaded to memory for application use
|
||||
pub const INST_DW: &str = "DW";
|
||||
|
||||
pub const CHIP8_PROGRAM_LOAD_OFFSET: i32 = 0x200;
|
||||
pub const CHIP8FONT_0: [u8; 5] = [0xF0, 0x90, 0x90, 0x90, 0xF0];
|
||||
pub const CHIP8FONT_1: [u8; 5] = [0x20, 0x60, 0x20, 0x20, 0x70];
|
||||
@@ -83,90 +87,20 @@ pub const CHIP8FONT_D: [u8; 5] = [0xE0, 0x90, 0x90, 0x90, 0xE0];
|
||||
pub const CHIP8FONT_E: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0xF0];
|
||||
pub const CHIP8FONT_F: [u8; 5] = [0xF0, 0x80, 0xF0, 0x80, 0x80];
|
||||
|
||||
pub const SCHIPFONT_0: [u8; 0x20] = [
|
||||
0x00, 0x00,
|
||||
0x01, 0x80,
|
||||
0x03, 0xc0,
|
||||
0x06, 0x60,
|
||||
0x0c, 0x30,
|
||||
0x0c, 0x30,
|
||||
0x18, 0x18,
|
||||
0x18, 0x18,
|
||||
0x18, 0x18,
|
||||
0x18, 0x18,
|
||||
0x0c, 0x30,
|
||||
0x0c, 0x30,
|
||||
0x06, 0x60,
|
||||
0x03, 0xc0, // 0b0000001111000000
|
||||
0x01, 0x80, // 0b0000000110000000
|
||||
0x00, 0x00 // 0b0000000000000000
|
||||
];
|
||||
pub const SCHIPFONT_1: [u8; 0x20] = [
|
||||
0x00, 0x00,
|
||||
0x03, 0xc0,
|
||||
0x02, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x00, 0xc0,
|
||||
0x03, 0xf0,
|
||||
0x00, 0x00
|
||||
];
|
||||
pub const SCHIPFONT_2: [u8; 0x20] = [0x7C, 0xFE, 0xFF, 0xFF, 0xC7, 0xC3, 0xC0, 0xE0,
|
||||
0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xFF, 0xFF,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78];
|
||||
pub const SCHIPFONT_3: [u8; 0x20] = [0x7C, 0xFE, 0xFF, 0xFF, 0xC7, 0xC3, 0xC0, 0xE0,
|
||||
0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0xFF, 0xFF,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78];
|
||||
pub const SCHIPFONT_4: [u8; 0x20] = [0xE0, 0xF0, 0xF8, 0xFC, 0xFE, 0xF7, 0xF3, 0xF1,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78];
|
||||
pub const SCHIPFONT_5: [u8; 0x20] = [0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x3F, 0x7F, 0x7F,
|
||||
0x01, 0x01, 0xC1, 0xE3, 0xFF, 0xFE, 0xFC, 0x78,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78];
|
||||
pub const SCHIPFONT_6: [u8; 0x20] = [0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_7: [u8; 0x20] = [0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0x78, 0x3C,
|
||||
0x1E, 0x0F, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_8: [u8; 0x20] = [0x7C, 0xFE, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xFF,
|
||||
0x7E, 0xFE, 0xC3, 0xC3, 0xFF, 0xFF, 0xFE, 0x7C,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_9: [u8; 0x20] = [0x7C, 0xFE, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xFF,
|
||||
0xFF, 0x7F, 0x03, 0x03, 0xC7, 0xFF, 0xFE, 0x7C,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_A: [u8; 0x20] = [0x7C, 0xFE, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_B: [u8; 0x20] = [0xFE, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xFE, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xFE,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_C: [u8; 0x20] = [0x7C, 0xFE, 0xFF, 0xFF, 0xC3, 0xC3, 0x01, 0x01,
|
||||
0x01, 0x01, 0xC3, 0xC3, 0xFF, 0xFE, 0xFC, 0x78,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_D: [u8; 0x20] = [0xFE, 0xFF, 0xFF, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3,
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xFF, 0xFE, 0x7C, 0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_E: [u8; 0x20] = [0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0x03, 0xFF, 0xFF, 0xFF, 0xFF,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78
|
||||
];
|
||||
pub const SCHIPFONT_F: [u8; 0x20] = [0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0xFF,
|
||||
0xFF, 0xFF, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,0x78, 0xFE, 0xFF, 0xFF, 0x83, 0x01, 0x01, 0xFF,
|
||||
0xFF, 0xFF, 0xC3, 0xE3, 0xFF, 0xFE, 0xFC, 0x78];
|
||||
pub const SCHIPFONT_OFFSET: u32 = 0x81;
|
||||
pub const SCHIPFONT_0: [u8; 0x0A] = [0xF0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xF0];
|
||||
pub const SCHIPFONT_1: [u8; 0x0A] = [0x20, 0x60, 0xA0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70];
|
||||
pub const SCHIPFONT_2: [u8; 0x0A] = [0xF0, 0x10, 0x10, 0x10, 0xF0, 0x80, 0x80, 0x80, 0x80, 0xF0];
|
||||
pub const SCHIPFONT_3: [u8; 0x0A] = [0xF0, 0x10, 0x10, 0x10, 0xF0, 0x10, 0x10, 0x10, 0x10, 0xF0];
|
||||
pub const SCHIPFONT_4: [u8; 0x0A] = [0x90, 0x90, 0x90, 0x90, 0xF0, 0x10, 0x10, 0x10, 0x10, 0x10];
|
||||
pub const SCHIPFONT_5: [u8; 0x0A] = [0xF0, 0x80, 0x80, 0x80, 0xF0, 0x10, 0x10, 0x10, 0x10, 0xF0];
|
||||
pub const SCHIPFONT_6: [u8; 0x0A] = [0xF0, 0x80, 0x80, 0x80, 0xF0, 0x90, 0x90, 0x90, 0x90, 0xF0];
|
||||
pub const SCHIPFONT_7: [u8; 0x0A] = [0xF0, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10];
|
||||
pub const SCHIPFONT_8: [u8; 0x0A] = [0xF0, 0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x90, 0xF0];
|
||||
pub const SCHIPFONT_9: [u8; 0x0A] = [0xF0, 0x90, 0x90, 0x90, 0xF0, 0x10, 0x10, 0x10, 0x10, 0xF0];
|
||||
pub const SCHIPFONT_A: [u8; 0x0A] = [0xF0, 0x90, 0x90, 0x90, 0xF0, 0x90, 0x90, 0x90, 0x90, 0x90];
|
||||
pub const SCHIPFONT_B: [u8; 0x0A] = [0xE0, 0x90, 0x90, 0x90, 0xE0, 0x90, 0x90, 0x90, 0x90, 0xE0];
|
||||
pub const SCHIPFONT_C: [u8; 0x0A] = [0xF0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xF0];
|
||||
pub const SCHIPFONT_D: [u8; 0x0A] = [0xE0, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0xE0];
|
||||
pub const SCHIPFONT_E: [u8; 0x0A] = [0xF0, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x80, 0xF0];
|
||||
pub const SCHIPFONT_F: [u8; 0x0A] = [0xF0, 0x80, 0x80, 0x80, 0xF0, 0x80, 0x80, 0x80, 0x80, 0x80];
|
||||
|
||||
Reference in New Issue
Block a user