george-emu/src/main.rs

111 lines
2.7 KiB
Rust

mod cli;
mod cpu;
mod error;
mod instructions;
mod keyboard;
mod memory;
mod types;
mod video;
use crate::cpu::Cpu;
use crate::keyboard::Keyboard;
use crate::memory::Mem;
use crate::video::{Screen, TerminalRenderer};
use cli::get_input;
use crossterm::execute;
use crossterm::terminal::{size, Clear, ClearType, SetSize};
// use cpu::CpuController;
use memory::MemHandle;
// use minifb::{Scale, ScaleMode, Window, WindowOptions};
use std::io::{stdout, Result};
use std::thread::{self, sleep};
use std::time::Duration;
use crossterm::{
cursor,
event::{self, KeyCode, KeyEventKind},
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
// For when we want to leave the terminal again :sigh:
//
// thread::spawn(move || {
// let mut screen = Crtc::new(
// screen_memory,
// config.char_rom.as_ref(),
// CpuController::new(screen_cpu_tx),
// window_tx,
// );
// screen.run();
// });
// let mut window = Window::new(
// "ʕ·ᴥ·ʔ-☆",
// 512,
// 380,
// WindowOptions {
// resize: true,
// borderless: true,
// title: true,
// transparency: false,
// scale: Scale::X2,
// scale_mode: ScaleMode::AspectRatioStretch,
// topmost: false,
// none: true,
// },
// )
// .unwrap();
fn main() -> Result<()> {
let mut stdout = stdout();
let (cols, rows) = size()?;
let mut memory = Mem::new();
get_input(&mut memory);
execute!(stdout, SetSize(64, 29), cursor::Hide, EnterAlternateScreen)?;
enable_raw_mode()?;
let shared_memory = MemHandle::new(memory);
let screen_memory = shared_memory.clone();
let cpu_memory = shared_memory.clone();
let keyboard_memory = shared_memory.clone();
let keyboard = Keyboard::new(keyboard_memory);
let (mut cpu, cpu_controller) = Cpu::new_with_control(cpu_memory);
let _ = cpu.reset();
thread::spawn(move || loop {
cpu.cycle();
});
let stdout_lock = stdout.lock();
let renderer = TerminalRenderer::new(screen_memory, stdout_lock);
let mut screen = Screen::new(renderer, cpu_controller);
loop {
sleep(Duration::from_millis(16));
screen.draw();
if event::poll(std::time::Duration::from_millis(16))? {
if let event::Event::Key(key) = event::read()? {
keyboard.read_keys(key);
if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
break;
}
}
}
}
execute!(
stdout,
LeaveAlternateScreen,
SetSize(cols, rows),
Clear(ClearType::Purge)
)?;
disable_raw_mode()?;
Ok(())
}