2024-03-02 13:00:57 +05:30
|
|
|
use std::ops::SubAssign;
|
|
|
|
use std::sync::atomic::{AtomicU16, Ordering};
|
|
|
|
use std::sync::{Arc, Mutex, RwLock};
|
|
|
|
use std::thread::{JoinHandle, sleep};
|
|
|
|
use std::time::Duration;
|
|
|
|
use crate::device::timer::Timer;
|
|
|
|
|
|
|
|
|
|
|
|
pub struct Device {
|
|
|
|
pub registers: RegisterFile,
|
|
|
|
pub memory: Box<[u8; Self::DEVICE_MEMORY_SIZE]>,
|
|
|
|
pub timer: Timer,
|
|
|
|
pub stack: Vec<u16>
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Device {
|
|
|
|
pub const DEVICE_MEMORY_SIZE: usize = 2 << 12;
|
|
|
|
pub fn new(timer: Timer) -> Device {
|
|
|
|
let memory = vec![0u8; Self::DEVICE_MEMORY_SIZE].into_boxed_slice().try_into().unwrap();
|
|
|
|
log::trace!("Successfully initiated device memory");
|
|
|
|
Device {
|
|
|
|
registers: RegisterFile::new(),
|
|
|
|
memory,
|
|
|
|
stack:Vec::with_capacity(16),
|
|
|
|
timer,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
impl Device{
|
|
|
|
const DEFAULT_FONT:[u8;5*16] = [
|
|
|
|
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0
|
|
|
|
0x20, 0x60, 0x20, 0x20, 0x70, // 1
|
|
|
|
0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2
|
|
|
|
0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3
|
|
|
|
0x90, 0x90, 0xF0, 0x10, 0x10, // 4
|
|
|
|
0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5
|
|
|
|
0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6
|
|
|
|
0xF0, 0x10, 0x20, 0x40, 0x40, // 7
|
|
|
|
0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8
|
|
|
|
0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9
|
|
|
|
0xF0, 0x90, 0xF0, 0x90, 0x90, // A
|
|
|
|
0xE0, 0x90, 0xE0, 0x90, 0xE0, // B
|
|
|
|
0xF0, 0x80, 0x80, 0x80, 0xF0, // C
|
|
|
|
0xE0, 0x90, 0x90, 0x90, 0xE0, // D
|
|
|
|
0xF0, 0x80, 0xF0, 0x80, 0xF0, // E
|
|
|
|
0xF0, 0x80, 0xF0, 0x80, 0x80 // F
|
|
|
|
];
|
|
|
|
const FONT_DEFAULT_MEM_LOCATION_START:usize = 0x50;
|
|
|
|
const FONT_DEFAULT_MEM_LOCATION_END:usize = 0x9F;
|
2024-03-02 15:55:27 +05:30
|
|
|
const ROM_START:usize = 0x200;
|
2024-03-02 13:00:57 +05:30
|
|
|
pub fn cycle(&mut self){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn set_default_font(&mut self){
|
2024-03-02 15:55:27 +05:30
|
|
|
log::info!("Loaded default font from memory");
|
2024-03-02 13:00:57 +05:30
|
|
|
self.memory[Self::FONT_DEFAULT_MEM_LOCATION_START..=Self::FONT_DEFAULT_MEM_LOCATION_END].copy_from_slice(&Self::DEFAULT_FONT);
|
|
|
|
}
|
2024-03-02 15:55:27 +05:30
|
|
|
/// load a rom from bytes
|
|
|
|
pub fn load_rom(&mut self,rom: &[u8]){
|
|
|
|
log::info!("Loaded ROM from memory");
|
|
|
|
self.memory[Self::ROM_START..].copy_from_slice(rom);
|
|
|
|
}
|
2024-03-02 13:00:57 +05:30
|
|
|
|
|
|
|
}
|
|
|
|
impl Drop for Device{
|
|
|
|
fn drop(&mut self) {
|
|
|
|
self.timer.send_stop_signal()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct RegisterFile {
|
|
|
|
pub v: [u8; 0x10],
|
2024-03-02 15:55:27 +05:30
|
|
|
/// program counter - only u12 technically.
|
2024-03-02 13:00:57 +05:30
|
|
|
pub pc: u16,
|
|
|
|
/// stack pointer
|
|
|
|
pub i: u16,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl RegisterFile {
|
2024-03-02 15:55:27 +05:30
|
|
|
pub const DEFAULT_PC_VALUE:u16 = Device::ROM_START as u16;
|
2024-03-02 13:00:57 +05:30
|
|
|
pub fn new() -> RegisterFile {
|
|
|
|
RegisterFile {
|
|
|
|
v: [0; 0x10],
|
2024-03-02 15:55:27 +05:30
|
|
|
pc: Self::DEFAULT_PC_VALUE,
|
2024-03-02 13:00:57 +05:30
|
|
|
i: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|