continuing with serial driver in dsa.
This commit is contained in:
@@ -272,9 +272,16 @@ impl Emulator {
|
||||
|
||||
#[inline]
|
||||
fn interrupt(&mut self, int: Interrupt) {
|
||||
println!("Interrupt while at address {}", 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)
|
||||
self.mem_read_word(self.reg(Register::Idr) + int.code() as u32 * 4);
|
||||
|
||||
println!(
|
||||
"Jumping to interrupt at address {}",
|
||||
self.reg(Register::Pcx)
|
||||
);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -489,6 +496,11 @@ impl Emulator {
|
||||
Some(Opcode::IRet) => {
|
||||
self.pop(Register::Ret);
|
||||
*self.mut_reg(Register::Pcx) = self.reg(Register::Ret);
|
||||
|
||||
println!(
|
||||
"Returning from interrupt to address {}",
|
||||
self.reg(Register::Pcx)
|
||||
);
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
@@ -502,8 +514,12 @@ impl Emulator {
|
||||
|
||||
#[inline]
|
||||
fn mem_write_byte(&mut self, addr: u32, val: u8) {
|
||||
if addr == 0x40000 {
|
||||
eprintln!("emulator wrote 0x{:08x} to uart", val);
|
||||
if addr == 0x40000 || addr == 0x40001 || addr == 0x40002 || addr == 0x40003 {
|
||||
eprintln!("emulator wrote 0x{:08x} to uart + {}", val, addr - 0x40000);
|
||||
|
||||
if addr == 0x40001 || addr == 0x40003 {
|
||||
eprintln!("writing char {} to uart + {}", val as char, addr - 0x40000);
|
||||
}
|
||||
}
|
||||
self.mainstore.write_byte(addr, val);
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ use crate::{
|
||||
};
|
||||
|
||||
/// ## SERIAL LAYOUT: (from the perspective of code inside the emulator)
|
||||
/// - [base+0x00]: write valid flag - set by kernel after writing a byte to serial
|
||||
/// - [base+0x01]: write byte - data payload for emulator to read
|
||||
/// - [base+0x02]: read valid flag - set by emulator after writing a byte to serial
|
||||
/// - [base+0x03]: read byte - data payload for kernel to read
|
||||
/// - [base+0x00]: ser_out valid flag - set by kernel after writing a byte to serial
|
||||
/// - [base+0x01]: ser_out byte - data payload for emulator to read
|
||||
/// - [base+0x02]: ser_in valid flag - set by emulator after writing a byte to serial
|
||||
/// - [base+0x03]: ser_in byte - data payload for kernel to read
|
||||
pub struct Serial {
|
||||
pub read_rx: Receiver<u8>,
|
||||
pub write_tx: Sender<u8>,
|
||||
@@ -33,20 +33,19 @@ impl Serial {
|
||||
rx: Receiver<u8>,
|
||||
) {
|
||||
loop {
|
||||
let word = mem.read_word(uart_base);
|
||||
|
||||
// Kernel → emulator: valid flag in bits 31:24, data in bits 23:16
|
||||
if (word >> 24) as u8 == 0x01 {
|
||||
let byte = (word >> 16) as u8;
|
||||
let _ = tx.send(byte);
|
||||
mem.write_word(uart_base, 0x00); // clear the whole word
|
||||
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 {
|
||||
let ser_out = mem.read_byte(uart_base + 1);
|
||||
let _ = tx.send(ser_out);
|
||||
mem.write_byte(uart_base, 0x00); // clear the whole word
|
||||
}
|
||||
|
||||
// Emulator → kernel: your existing rx path
|
||||
if (word >> 8) as u8 == 0x00 {
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#![feature(likely_unlikely)]
|
||||
#![feature(inherent_associated_types)]
|
||||
#![feature(str_as_str)]
|
||||
|
||||
pub mod args;
|
||||
pub mod backend;
|
||||
|
||||
Reference in New Issue
Block a user