serial working
This commit is contained in:
@@ -272,14 +272,14 @@ impl Emulator {
|
||||
|
||||
#[inline]
|
||||
fn interrupt(&mut self, int: Interrupt) {
|
||||
println!("Interrupt while at address {}", self.reg(Register::Pcx));
|
||||
println!("Interrupt while at address {:04X}", self.reg(Register::Pcx));
|
||||
|
||||
self.push(Register::Pcx);
|
||||
*self.mut_reg(Register::Pcx) =
|
||||
self.mem_read_word(self.reg(Register::Idr) + int.code() as u32 * 4);
|
||||
|
||||
println!(
|
||||
"Jumping to interrupt at address {}",
|
||||
"Jumping to interrupt at address {:04X}",
|
||||
self.reg(Register::Pcx)
|
||||
);
|
||||
}
|
||||
@@ -498,7 +498,7 @@ impl Emulator {
|
||||
*self.mut_reg(Register::Pcx) = self.reg(Register::Ret);
|
||||
|
||||
println!(
|
||||
"Returning from interrupt to address {}",
|
||||
"Returning from interrupt to address {:04X}",
|
||||
self.reg(Register::Pcx)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ pub struct SharedState {
|
||||
pub reseting: AtomicBool,
|
||||
pub paused: AtomicBool,
|
||||
pub update_req: AtomicBool,
|
||||
|
||||
pub interrupt_queue: mpsc::Sender<Interrupt>,
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,12 @@ impl Component for Controller {
|
||||
let pcx = state.registers[Register::Pcx as usize];
|
||||
let clock = state.clock;
|
||||
let time = state.time.as_micros();
|
||||
let mips = state.clock as u128 / time;
|
||||
|
||||
let mips = if time != 0 {
|
||||
state.clock as u128 / time
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
ui.label(format!("Clock: {clock}"));
|
||||
ui.label(format!("Pcx: 0x{pcx:08X}"));
|
||||
|
||||
@@ -101,11 +101,11 @@ impl Component for MemoryInspector {
|
||||
ui.end_row();
|
||||
|
||||
// Memory data (8 bytes per row)
|
||||
for (row, word) in (0..self.view_size / 4)
|
||||
for (offset, word) in (0..self.view_size / 4)
|
||||
.map(|i| i * 4)
|
||||
.map(|i| (i, self.memory.read_word(self.view_addr + i)))
|
||||
{
|
||||
let row_address = self.view_addr + (row * 4);
|
||||
let row_address = self.view_addr + offset;
|
||||
ui.monospace(format!("0x{row_address:08X} ({row_address})"));
|
||||
for byte in word.to_le_bytes() {
|
||||
ui.monospace(format!("{byte:02X}"));
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use std::sync::{
|
||||
Arc,
|
||||
atomic::Ordering,
|
||||
mpsc::{Receiver, Sender},
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::Ordering,
|
||||
mpsc::{Receiver, Sender},
|
||||
},
|
||||
};
|
||||
|
||||
use super::Component;
|
||||
@@ -32,7 +35,13 @@ impl Serial {
|
||||
tx: Sender<u8>,
|
||||
rx: Receiver<u8>,
|
||||
) {
|
||||
let mut write_buffer: VecDeque<u8> = VecDeque::new();
|
||||
|
||||
loop {
|
||||
while let Ok(byte) = rx.try_recv() {
|
||||
write_buffer.push_back(byte);
|
||||
}
|
||||
|
||||
let ser_out_valid = mem.read_byte(uart_base + 0);
|
||||
// Kernel => emulator: valid flag in byte 0, data in byte 1
|
||||
if ser_out_valid == 0x01 {
|
||||
@@ -41,14 +50,19 @@ impl Serial {
|
||||
mem.write_byte(uart_base, 0x00); // clear the whole word
|
||||
}
|
||||
|
||||
// Emulator => kernel: valid flag in byte 2, data in byte 3
|
||||
let ser_in_valid = mem.read_byte(uart_base + 2);
|
||||
if ser_in_valid == 0x00 {
|
||||
if let Ok(byte) = rx.try_recv() {
|
||||
state.interrupt_queue.send(Interrupt::SerialIn).unwrap();
|
||||
mem.write_byte(uart_base + 3, byte);
|
||||
mem.write_byte(uart_base + 2, 0x01);
|
||||
if !write_buffer.is_empty() {
|
||||
// Emulator => kernel: valid flag in byte 2, data in byte 3
|
||||
let ser_in_valid = mem.read_byte(uart_base + 2);
|
||||
if ser_in_valid == 0x00 {
|
||||
if let Some(byte) = write_buffer.pop_front() {
|
||||
mem.write_byte(uart_base + 3, byte);
|
||||
mem.write_byte(uart_base + 2, 0x01);
|
||||
}
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(2));
|
||||
|
||||
state.interrupt_queue.send(Interrupt::SerialIn).unwrap();
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(1));
|
||||
|
||||
Reference in New Issue
Block a user