progress on serial and added editor
This commit is contained in:
@@ -15,6 +15,7 @@ pub enum Interrupt {
|
||||
|
||||
// IRQ's (32-63)
|
||||
Hardware(u8),
|
||||
SerialIn = 32,
|
||||
|
||||
// Syscalls (64-255)
|
||||
// OS defined, program uses INT 64-127
|
||||
@@ -33,6 +34,7 @@ impl Interrupt {
|
||||
Interrupt::WriteToReadOnly => 6,
|
||||
Interrupt::ReadFromWriteOnly => 7,
|
||||
Interrupt::UnmappedIo => 8,
|
||||
Interrupt::SerialIn => 32,
|
||||
Interrupt::Hardware(x) => {
|
||||
if *x < 32 || *x > 63 {
|
||||
0
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct Emulator {
|
||||
shared_state: Arc<SharedState>,
|
||||
|
||||
// Interrupts
|
||||
interrupts: mpsc::Receiver<u8>,
|
||||
interrupts: mpsc::Receiver<Interrupt>,
|
||||
pending_fault: Option<Interrupt>,
|
||||
|
||||
// memory
|
||||
@@ -45,7 +45,7 @@ pub struct Emulator {
|
||||
unsafe impl Send for Emulator {}
|
||||
impl Emulator {
|
||||
pub fn new() -> Self {
|
||||
let (sender, receiver) = mpsc::channel::<u8>();
|
||||
let (sender, receiver) = mpsc::channel::<Interrupt>();
|
||||
|
||||
Self {
|
||||
interrupts: receiver,
|
||||
@@ -163,6 +163,8 @@ impl Emulator {
|
||||
while self.shared_state.reseting.load(Ordering::Relaxed) {
|
||||
thread::sleep(Duration::from_millis(100));
|
||||
}
|
||||
|
||||
self.internal_state.halted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,19 +184,19 @@ impl Emulator {
|
||||
self.check_update();
|
||||
}
|
||||
|
||||
// if the cpu didn't halt on it's own then it's ready to run again.
|
||||
if !self.internal_state.halted {
|
||||
return;
|
||||
}
|
||||
|
||||
loop {
|
||||
// Check for interrupts.
|
||||
if let Ok(code) = self.interrupts.recv_timeout(Duration::from_millis(100)) {
|
||||
if let Ok(int) = self.interrupts.recv_timeout(Duration::from_millis(100)) {
|
||||
self.internal_state.halted = false;
|
||||
self.interrupt(Interrupt::Software(code));
|
||||
self.interrupt(int);
|
||||
break;
|
||||
}
|
||||
|
||||
// if the cpu didn't halt on it's own then it's ready to run again.
|
||||
if !self.internal_state.halted {
|
||||
return;
|
||||
}
|
||||
|
||||
// UI is resetting the emulator
|
||||
self.check_update();
|
||||
}
|
||||
@@ -230,7 +232,7 @@ impl Emulator {
|
||||
}
|
||||
|
||||
match self.interrupts.try_recv() {
|
||||
Ok(code) => self.interrupt(Interrupt::Software(code)),
|
||||
Ok(int) => self.interrupt(int),
|
||||
Err(TryRecvError::Disconnected) => break 'emu,
|
||||
Err(TryRecvError::Empty) => {}
|
||||
}
|
||||
@@ -270,14 +272,21 @@ impl Emulator {
|
||||
|
||||
#[inline]
|
||||
fn interrupt(&mut self, int: Interrupt) {
|
||||
let idt = self.reg(Register::Idr);
|
||||
self.push(Register::Pcx);
|
||||
*self.mut_reg(Register::Pcx) =
|
||||
self.mem_read_word(self.reg(Register::Idr) + int.code() as u32 * 4)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn push(&mut self, reg: Register) {
|
||||
*self.mut_reg(Register::Spr) -= 4;
|
||||
let spr = self.reg(Register::Spr);
|
||||
let pcx = self.reg(Register::Pcx);
|
||||
self.mem_write_word(spr, pcx);
|
||||
self.mem_write_word(self.reg(Register::Spr), self.reg(reg));
|
||||
}
|
||||
|
||||
*self.mut_reg(Register::Pcx) = self.mem_read_word(idt + int.code() as u32 * 4)
|
||||
#[inline]
|
||||
fn pop(&mut self, reg: Register) {
|
||||
*self.mut_reg(reg) = self.mem_read_word(self.reg(Register::Spr));
|
||||
*self.mut_reg(Register::Spr) += 4;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -477,24 +486,15 @@ impl Emulator {
|
||||
self.interrupt(Interrupt::Software(word.imm16() as u8));
|
||||
}
|
||||
Some(Opcode::Hlt) => self.halt(),
|
||||
Some(Opcode::IRet) => todo!(),
|
||||
Some(Opcode::IRet) => {
|
||||
self.pop(Register::Ret);
|
||||
*self.mut_reg(Register::Pcx) = self.reg(Register::Ret);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn push(&mut self, reg: Register) {
|
||||
*self.mut_reg(Register::Spr) -= 4;
|
||||
self.mem_write_word(self.reg(Register::Spr), self.reg(reg));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn pop(&mut self, reg: Register) {
|
||||
*self.mut_reg(reg) = self.mem_read_word(self.reg(Register::Spr));
|
||||
*self.mut_reg(Register::Spr) += 4;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn mem_read_byte(&mut self, addr: u32) -> u8 {
|
||||
self.mainstore.read_byte(addr)
|
||||
|
||||
@@ -4,6 +4,8 @@ use arc_swap::ArcSwap;
|
||||
|
||||
use crate::backend::processor::processor::ProcessorSnapshot;
|
||||
|
||||
use super::interrupts::Interrupt;
|
||||
|
||||
pub struct SharedState {
|
||||
pub proc: ArcSwap<ProcessorSnapshot>,
|
||||
|
||||
@@ -11,11 +13,11 @@ pub struct SharedState {
|
||||
pub paused: AtomicBool,
|
||||
pub update_req: AtomicBool,
|
||||
|
||||
interrupt_queue: mpsc::Sender<u8>,
|
||||
pub interrupt_queue: mpsc::Sender<Interrupt>,
|
||||
}
|
||||
|
||||
impl SharedState {
|
||||
pub fn new(sender: mpsc::Sender<u8>) -> Self {
|
||||
pub fn new(sender: mpsc::Sender<Interrupt>) -> Self {
|
||||
Self {
|
||||
reseting: AtomicBool::new(false),
|
||||
proc: ArcSwap::new(Arc::new(ProcessorSnapshot::default())),
|
||||
|
||||
Reference in New Issue
Block a user