use crate::sys::getchar::get_char;
use crate::sys::select::{self, FdSet};
use crate::sys::time::TimeVal;
use crate::sys::time::TimeValLike;
use libc::STDIN_FILENO;
pub const MEMORY_SIZE: usize = std::u16::MAX as usize;
#[derive(Copy)]
pub struct Memory {
pub cells: [u16; MEMORY_SIZE],
}
impl Memory {
pub fn new() -> Memory {
Memory {
cells: [0; MEMORY_SIZE],
}
}
pub fn write(&mut self, address: usize, value: u16) {
self.cells[(address as u16) as usize] = value;
}
pub fn read(&mut self, address: u16) -> u16 {
if address == MemoryMappedReg::Kbsr as u16 {
if check_key() {
self.cells[MemoryMappedReg::Kbsr as usize] = 1 << 15;
self.cells[MemoryMappedReg::Kbdr as usize] = get_char() as u16;
} else {
self.cells[MemoryMappedReg::Kbsr as usize] = 0;
}
}
self.cells[address as usize]
}
}
impl Clone for Memory {
fn clone(&self) -> Memory {
*self
}
}
pub enum MemoryMappedReg {
Kbsr = 0xFE00,
Kbdr = 0xFE02,
}
fn check_key() -> bool {
let mut fd = FdSet::new();
fd.insert(STDIN_FILENO);
let mut timeout = TimeVal::seconds(0);
match select::select(1, &mut fd, None, None, &mut timeout) {
Err(_) => false,
_ => true,
}
}