ft(interpreter): expand interrupt functionality
Implement mess2 type, as well as return m_type for existing and new interrupts. TODO: save pointer to message data, as the current write is redundant.
This commit is contained in:
@@ -18,6 +18,8 @@ use super::{
|
|||||||
interrupt::InterruptMessage,
|
interrupt::InterruptMessage,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const EINVAL: Word = 22;
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum InterpreterError {
|
pub enum InterpreterError {
|
||||||
InvalidSyscall(Byte),
|
InvalidSyscall(Byte),
|
||||||
@@ -787,18 +789,23 @@ impl Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let msg = InterruptMessage::new(&data);
|
let msg = InterruptMessage::new(&data);
|
||||||
|
log::debug!("{msg}");
|
||||||
|
|
||||||
// simulate interrupt handler code of MINIX
|
// simulate interrupt handler code of MINIX
|
||||||
match id {
|
match id {
|
||||||
// sofware interrupts
|
// sofware interrupts
|
||||||
0x20 => {
|
0x20 => {
|
||||||
log::debug!("Software interrupt with raw data {:?}", data);
|
log::debug!(
|
||||||
|
"Software interrupt with raw data {:x?} of type {:#04x}",
|
||||||
|
data,
|
||||||
|
msg.m_type
|
||||||
|
);
|
||||||
match msg.m_type {
|
match msg.m_type {
|
||||||
// EXIT()
|
// EXIT()
|
||||||
0x01 => {
|
0x01 => {
|
||||||
let data = Mess1::new(&data);
|
let data = Mess1::new(&data);
|
||||||
let status = data.i1;
|
let status = data.i1;
|
||||||
log::info!("executing exit({})", status);
|
log::info!("<exit({})>", status);
|
||||||
exit(status.into())
|
exit(status.into())
|
||||||
}
|
}
|
||||||
// WRITE()
|
// WRITE()
|
||||||
@@ -807,7 +814,7 @@ impl Interpreter {
|
|||||||
let fd = data.i1;
|
let fd = data.i1;
|
||||||
let len = data.i2;
|
let len = data.i2;
|
||||||
let location = data.p1;
|
let location = data.p1;
|
||||||
log::info!("executing write({}, {}, {})", fd, location, len);
|
log::info!("<write({:#04x}, {:#04x}, {:#04x})>", fd, location, len);
|
||||||
for byte in &self.computer.memory.raw[location as usize..] {
|
for byte in &self.computer.memory.raw[location as usize..] {
|
||||||
if *byte == 0x00 {
|
if *byte == 0x00 {
|
||||||
break;
|
break;
|
||||||
@@ -815,6 +822,37 @@ impl Interpreter {
|
|||||||
print!("{}", *byte as char);
|
print!("{}", *byte as char);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m_type response
|
||||||
|
// TODO: save messages as pointer to remove this hack
|
||||||
|
self.computer.write(len.into(), (bx + 2).into())?;
|
||||||
|
}
|
||||||
|
// TODO: BRK
|
||||||
|
0x11 => {
|
||||||
|
let bx = self.computer.regs.bx.read();
|
||||||
|
let addr = self.computer.read((bx + 10).into())?;
|
||||||
|
log::info!("<brk({:#04x})>", addr);
|
||||||
|
|
||||||
|
// XXX add err handling?
|
||||||
|
self.computer.write(addr.into(), (bx + 18).into())?;
|
||||||
|
|
||||||
|
// m_type response
|
||||||
|
// TODO: save messages as pointer to remove this hack
|
||||||
|
self.computer
|
||||||
|
.write(ImmediateOperand::Word(0), (bx + 2).into())?;
|
||||||
|
}
|
||||||
|
// IOCTL()
|
||||||
|
0x36 => {
|
||||||
|
let data = Mess2::new(&data);
|
||||||
|
let tty = data.i1;
|
||||||
|
let count = data.i3;
|
||||||
|
let address = data.p1;
|
||||||
|
log::info!("<ioctl({}, {}, {})>", tty, count, address);
|
||||||
|
|
||||||
|
// m_type response
|
||||||
|
// TODO: save messages as pointer to remove this hack
|
||||||
|
let reply = (!EINVAL).wrapping_add(1);
|
||||||
|
self.computer.write(reply.into(), (bx + 2).into())?;
|
||||||
}
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
};
|
};
|
||||||
@@ -822,6 +860,11 @@ impl Interpreter {
|
|||||||
_ => return Err(InterpreterError::InvalidSyscall(id)),
|
_ => return Err(InterpreterError::InvalidSyscall(id)),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX return val in AX?
|
||||||
|
self.computer
|
||||||
|
.regs
|
||||||
|
.write(crate::register::Register::AX, ImmediateOperand::Word(0));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use core::fmt;
|
|||||||
use crate::operands::Word;
|
use crate::operands::Word;
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
// typedef struct {int m2i1, m2i2, m2i3; long m2l1, m2l2; char *m2p1;} mess_2;
|
|
||||||
// typedef struct {int m3i1, m3i2; char *m3p1; char m3ca1[M3_STRING];} mess_3;
|
// typedef struct {int m3i1, m3i2; char *m3p1; char m3ca1[M3_STRING];} mess_3;
|
||||||
// typedef struct {long m4l1, m4l2, m4l3, m4l4, m4l5;} mess_4;
|
// typedef struct {long m4l1, m4l2, m4l3, m4l4, m4l5;} mess_4;
|
||||||
// typedef struct {char m5c1, m5c2; int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5;
|
// typedef struct {char m5c1, m5c2; int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5;
|
||||||
@@ -22,7 +21,6 @@ pub struct Mess1 {
|
|||||||
|
|
||||||
impl Mess1 {
|
impl Mess1 {
|
||||||
pub fn new(data: &Vec<u8>) -> Self {
|
pub fn new(data: &Vec<u8>) -> Self {
|
||||||
log::debug!("Mess1 from data {data:?}");
|
|
||||||
Self {
|
Self {
|
||||||
i1: Word::from_le_bytes([data[4], data[5]]),
|
i1: Word::from_le_bytes([data[4], data[5]]),
|
||||||
i2: Word::from_le_bytes([data[6], data[7]]),
|
i2: Word::from_le_bytes([data[6], data[7]]),
|
||||||
@@ -43,6 +41,41 @@ impl fmt::Display for Mess1 {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
// typedef struct {int m2i1, m2i2, m2i3; long m2l1, m2l2; char *m2p1;} mess_2;
|
||||||
|
pub struct Mess2 {
|
||||||
|
pub i1: Word,
|
||||||
|
pub i2: Word,
|
||||||
|
pub i3: Word,
|
||||||
|
pub l1: Word,
|
||||||
|
pub l2: Word,
|
||||||
|
pub p1: Word,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mess2 {
|
||||||
|
pub fn new(data: &Vec<u8>) -> Self {
|
||||||
|
Self {
|
||||||
|
i1: Word::from_le_bytes([data[4], data[5]]),
|
||||||
|
i2: Word::from_le_bytes([data[6], data[7]]),
|
||||||
|
i3: Word::from_le_bytes([data[8], data[9]]),
|
||||||
|
l1: Word::from_le_bytes([data[10], data[11]]),
|
||||||
|
l2: Word::from_le_bytes([data[12], data[13]]),
|
||||||
|
p1: Word::from_le_bytes([data[14], data[15]]),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Mess2 {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(
|
||||||
|
f,
|
||||||
|
"Mess1({} {} {} {} {} {})",
|
||||||
|
self.i1, self.i2, self.i3, self.l1, self.l2, self.p1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
/// First part of: include/minix/type.h:struct message
|
/// First part of: include/minix/type.h:struct message
|
||||||
/// The union-type will be handled differently, where I the data of each
|
/// The union-type will be handled differently, where I the data of each
|
||||||
|
|||||||
Reference in New Issue
Block a user