97 lines
2.7 KiB
Rust
97 lines
2.7 KiB
Rust
use clap::Parser;
|
|
use common::{instructions::Instruction, register::Register};
|
|
use dsa::{
|
|
BulkAllocStore, Emulator, Page, RandomAccessMemory, SharedState,
|
|
args::DsaArgs,
|
|
io::display::{DisplayDevice, DisplayHandle},
|
|
};
|
|
use std::{
|
|
os::unix::thread::JoinHandleExt,
|
|
process::exit,
|
|
sync::{Arc, atomic::Ordering},
|
|
thread,
|
|
time::Duration,
|
|
};
|
|
|
|
fn main() {
|
|
let args = DsaArgs::parse();
|
|
|
|
let mmap = args.get_memory_map();
|
|
let iomap = args.get_io_map();
|
|
|
|
let store = BulkAllocStore::new();
|
|
let (display, handle) = DisplayDevice::new(80, 25);
|
|
|
|
let mut emulator = Emulator::new(store)
|
|
.with_device(display)
|
|
.apply_memory_map(mmap)
|
|
.apply_io_map(iomap)
|
|
.unwrap();
|
|
|
|
if let Some(bin) = args.get_binary() {
|
|
for (i, ch) in bin.chunks(4).enumerate() {
|
|
let instruction = Instruction(u32::from_le_bytes(ch.try_into().unwrap()));
|
|
let hex = ch
|
|
.iter()
|
|
.map(|b| format!("{:02X}", b))
|
|
.collect::<Vec<_>>()
|
|
.join(" ");
|
|
let chars = ch
|
|
.iter()
|
|
.map(|b| {
|
|
if b.is_ascii_graphic() {
|
|
*b as char
|
|
} else {
|
|
'.'
|
|
}
|
|
})
|
|
.collect::<String>();
|
|
println!("{:04X}: {:<12} {:4} {:?}", i * 4, hex, chars, instruction);
|
|
}
|
|
|
|
let program: Vec<Page> = Page::paginate(&bin).collect();
|
|
|
|
for (i, page) in program.iter().enumerate() {
|
|
emulator.memory_mut().write_page(i as u32 * 4096, &page);
|
|
}
|
|
}
|
|
|
|
let state = emulator.state_handle();
|
|
|
|
const STACK_SIZE: usize = 1024 * 1024 * 16;
|
|
let runner = thread::Builder::new()
|
|
.stack_size(STACK_SIZE)
|
|
.spawn(move || emulator.run().unwrap())
|
|
.unwrap();
|
|
|
|
let observer = thread::spawn(|| observe(state, handle));
|
|
|
|
runner.join().unwrap();
|
|
thread::sleep(Duration::from_millis(100));
|
|
|
|
// yeah we don't need this tbh.
|
|
// observer.join().unwrap();
|
|
}
|
|
|
|
/// todo: remove this!
|
|
fn observe(state: Arc<SharedState>, handle: DisplayHandle) {
|
|
loop {
|
|
state.update_req.store(true, Ordering::Relaxed);
|
|
thread::sleep(std::time::Duration::from_millis(20));
|
|
let state = state.proc.load();
|
|
// println!(
|
|
// "clock: {}, GP Registers: {:?}",
|
|
// state.clock, state.registers
|
|
// );
|
|
|
|
if handle.is_dirty() {
|
|
for line in handle.read_all().chunks(80) {
|
|
for (i, byte) in line.iter().enumerate() {
|
|
print!("{}", *byte as char);
|
|
}
|
|
println!();
|
|
}
|
|
}
|
|
}
|
|
}
|