Skip to content
This repository was archived by the owner on Aug 30, 2024. It is now read-only.

Commit 95c03ab

Browse files
committed
feat: flag sets + opcodes
1 parent e170080 commit 95c03ab

File tree

5 files changed

+279
-27
lines changed

5 files changed

+279
-27
lines changed

src/interpreter/flag_set.rs

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use log::trace;
2+
use std::collections::HashMap;
3+
4+
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Hash)]
5+
pub enum Flag {
6+
Zero,
7+
Sign,
8+
Parity,
9+
Carry,
10+
Overflow,
11+
Direction,
12+
Interrupt,
13+
Trap,
14+
}
15+
16+
impl Flag {
17+
pub fn iter() -> impl Iterator<Item = Flag> {
18+
[
19+
Flag::Zero,
20+
Flag::Sign,
21+
Flag::Parity,
22+
Flag::Carry,
23+
Flag::Overflow,
24+
Flag::Direction,
25+
Flag::Interrupt,
26+
Flag::Trap,
27+
]
28+
.iter()
29+
.copied()
30+
}
31+
}
32+
33+
#[derive(Debug)]
34+
pub struct FlagSet {
35+
flags: HashMap<Flag, bool>,
36+
}
37+
38+
impl FlagSet {
39+
pub fn new() -> Self {
40+
let mut flags = HashMap::new();
41+
for flag in Flag::iter() {
42+
flags.insert(flag, false);
43+
}
44+
Self { flags }
45+
}
46+
47+
pub fn get(&self, flag: Flag) -> bool {
48+
*self.flags.get(&flag).expect("Unknown flag")
49+
}
50+
51+
pub fn set(&mut self, flag: Flag, value: bool) {
52+
if let Some(val) = self.flags.get_mut(&flag) {
53+
trace!("Set {:?}: {} (previous: {})", flag, value, *val);
54+
*val = value;
55+
}
56+
}
57+
}
58+
59+
impl std::fmt::Display for FlagSet {
60+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
61+
for flag in Flag::iter() {
62+
write!(f, "{:?}: {}\n", flag, self.get(flag))?;
63+
}
64+
Ok(())
65+
}
66+
}

src/interpreter/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod flag_set;
12
mod memory;
23
mod register_set;
34
mod vm;

src/interpreter/vm.rs

Lines changed: 75 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use super::flag_set::FlagSet;
12
use super::memory::Memory;
23
use super::register_set::RegisterSet;
4+
use crate::interpreter::flag_set::Flag;
35
use crate::utils::{min, HexdumpFormatter};
4-
use crate::x86::{Address, Displacement, Register};
6+
use crate::x86::{Address, Displacement, Operand, Register};
57
use crate::{minix::Program, x86::IR};
68

79
use log::trace;
@@ -10,23 +12,29 @@ use log::trace;
1012
mod opcodes;
1113
use opcodes::OpcodeExecutable;
1214

15+
#[allow(dead_code)]
1316
struct VM {
1417
// cpu
1518
pub ip: u16,
1619
// memory
1720
pub text: Memory,
1821
pub data: Memory,
19-
// registers
22+
// registers, flags
2023
pub regs: RegisterSet,
21-
pub flags: u16,
24+
pub flags: FlagSet,
2225
}
2326

2427
impl From<Program> for VM {
2528
fn from(program: Program) -> Self {
2629
let text = Memory::from(program.text_segment.data);
27-
let data = Memory::from(program.data_segment.data);
28-
let regs = RegisterSet::new();
29-
let flags = 0;
30+
31+
let size = 0x1000;
32+
let mut data = Memory::new(size);
33+
data.write_bytes(0, &program.data_segment.data);
34+
35+
let mut regs = RegisterSet::new();
36+
regs.set(Register::SP, (data.len() - 2) as i16);
37+
let flags = FlagSet::new();
3038
let ip = 0;
3139
VM {
3240
ip,
@@ -83,21 +91,56 @@ impl VmIrExecutable for VM {
8391
IR::Add { dest, src } => {
8492
self.add(dest, src);
8593
}
86-
// pop, push, ...
87-
_ => panic!("Not implemented"),
94+
IR::Xor { dest, src } => {
95+
self.xor(dest, src);
96+
}
97+
IR::Lea { dest, src } => {
98+
self.lea(dest, src);
99+
}
100+
IR::Cmp { dest, src, byte: _ } => {
101+
self.cmp(dest, src);
102+
}
103+
IR::Jnb { dest } => {
104+
self.jnb(dest);
105+
}
106+
IR::Jne { dest } => {
107+
self.jne(dest);
108+
}
109+
IR::Je { dest } => {
110+
self.je(dest);
111+
}
112+
IR::Test { dest, src, byte: _ } => {
113+
self.test(dest, src);
114+
}
115+
IR::Push { src } => {
116+
self.push(src);
117+
}
118+
IR::Call { dest } => {
119+
self.call(dest);
120+
}
121+
IR::In { dest, src } => {
122+
self.in_(dest, src);
123+
}
124+
IR::Loopnz { dest } => {
125+
self.loopnz(dest);
126+
}
127+
IR::Or { dest, src } => {
128+
self.or(dest, src);
129+
}
130+
_ => panic!("{}: Not implemented", ir),
88131
}
89132
}
90133

91134
fn run(&mut self) {
92-
trace!(" AX BX CX DX SP BP SI DI FLAGS IP");
135+
trace!(" AX BX CX DX SP BP SI DI IP");
93136
while let Some(ir) = self.fetch() {
94137
let (decoded_ir, ir_len) = self.decode(ir);
95138

96139
// Trace with format:
97140
// AX BX CX DX SP BP SI DI FLAGS IP
98141
// 0000 0000 0000 0000 0000 0000 0000 0000 ---- 0000:bb0000 mov bx, 000
99142
trace!(
100-
"{} \t{}",
143+
"{} \t{}",
101144
{
102145
let mut regs = String::new();
103146
for reg in vec![
@@ -112,10 +155,14 @@ impl VmIrExecutable for VM {
112155
] {
113156
regs.push_str(&format!("{:04x} ", self.regs.get(reg)));
114157
}
158+
let mut flags = String::new();
159+
for flag in Flag::iter() {
160+
flags.push_str(&format!("{}", self.flags.get(flag) as u8));
161+
}
115162
format!(
116-
"{} {:04x} {:04x}:{}",
163+
"{} {} {:04x}:{}",
117164
regs,
118-
self.flags,
165+
flags,
119166
self.ip,
120167
&ir[..ir_len]
121168
.iter()
@@ -131,7 +178,7 @@ impl VmIrExecutable for VM {
131178
// Increment the instruction pointer (ip) appropriately
132179
self.ip += ir_len as u16;
133180
}
134-
trace!("Execution finished:\n{}", self);
181+
// trace!("Execution finished:\n{}", self);
135182
}
136183
}
137184

@@ -165,12 +212,26 @@ impl VM {
165212

166213
base.wrapping_add(index).wrapping_add(disp) as u16
167214
}
215+
216+
fn into_value(&self, operand: Operand) -> i16 {
217+
match operand {
218+
Operand::Register(reg) => self.regs.get(reg),
219+
Operand::Immediate(value) => value as i16,
220+
Operand::LongImmediate(value) => value as i16,
221+
Operand::SignExtendedImmediate(value) => value as i16,
222+
Operand::MemoryAddress(address) => {
223+
let ea = self.get_effective_address(address);
224+
self.data.read_word(ea) as i16
225+
}
226+
Operand::Displacement(value) => self.ip.wrapping_add(value.into()) as i16,
227+
}
228+
}
168229
}
169230

170231
impl std::fmt::Display for VM {
171232
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
172233
writeln!(f, "IP: {:04x}", self.ip)?;
173-
writeln!(f, "FLAGS: {:04x}", self.flags)?;
234+
writeln!(f, "FLAGS: {}", self.flags)?;
174235
writeln!(f, "TEXT:")?;
175236
write!(f, "{:?}", HexdumpFormatter(&self.text.data))?;
176237
writeln!(f, "DATA:")?;

0 commit comments

Comments
 (0)