continuing with serial driver in dsa.

This commit is contained in:
2026-03-16 23:18:53 +00:00
parent 6061e1701e
commit ffdd392003
7 changed files with 186 additions and 94 deletions
@@ -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);
}
+13 -14
View File
@@ -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
View File
@@ -1,5 +1,6 @@
#![feature(likely_unlikely)]
#![feature(inherent_associated_types)]
#![feature(str_as_str)]
pub mod args;
pub mod backend;