-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
135 lines (114 loc) · 3.12 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use core::panic;
use std::{fmt::Display, mem::size_of};
use serde::{Deserialize, Serialize};
pub const START_ADDRESS: RawOperand = 0x10;
// index to length conversion
pub const MEMORY_SIZE: usize = RawAddress::MAX as usize + 1;
pub const MEMORY_DATA_CELL_SIZE: usize = size_of::<MemoryDataType>();
pub type MemoryDataType = u32;
pub type RawOperand = u16;
pub type RawAddress = RawOperand;
pub type RawPort = u8;
#[derive(Deserialize, Serialize, Clone, Copy, Debug)]
pub struct Operand {
pub operand: RawOperand,
pub operand_type: OperandType,
}
// address
// label, (label), !label, same with number
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
pub enum Opcode {
IN, // port
OUT, // port
LOAD, // address
STORE, // address
ADD, // address
INC, // none
AND, // address
CMP, // address
SHIFT_LEFT, // immediate
SHIFT_RIGHT, // immediate
JZC, // address
JZS, // address
JCS, // address
JCC, // address
JUMP, // address
NOP, // none
HALT, // none
}
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
pub enum OperandType {
None,
Indirect,
Absolute,
Relative,
Immediate,
}
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
pub struct CompiledCommand {
pub opcode: Opcode,
#[serde(flatten)]
pub operand: Operand,
}
impl Display for CompiledCommand {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Opcode: {:?}, operand: {}, mode: {:?}",
self.opcode, self.operand.operand, self.operand.operand_type
)
}
}
#[derive(Serialize, Deserialize)]
pub struct CompiledSection {
pub start_address: RawAddress,
pub items: Vec<MemoryItem>,
}
impl CompiledSection {
pub fn with_address(address: RawAddress) -> Self {
Self {
start_address: address,
items: Vec::new(),
}
}
}
#[derive(Serialize, Deserialize)]
pub struct CompiledProgram {
pub sections: Vec<CompiledSection>,
}
#[derive(Clone, Copy, Serialize, Deserialize, Debug)]
#[serde(untagged)]
pub enum MemoryItem {
Data(MemoryDataType),
Command(CompiledCommand),
}
impl Display for MemoryItem {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MemoryItem::Data(data) => write!(f, "Data({})", data),
MemoryItem::Command(command) => write!(f, "Command: {}", command),
}
}
}
impl MemoryItem {
pub fn unwrap_data(self) -> u32 {
match self {
MemoryItem::Data(payload) => payload,
MemoryItem::Command(_) => {
panic!("Instruction accessed! Instructions does not have binary representation!")
}
}
}
pub fn unwrap_command(self) -> CompiledCommand {
match self {
MemoryItem::Data(_) => panic!("Data accessed! Instruction expected!"),
MemoryItem::Command(command) => command,
}
}
}
impl From<MemoryItem> for u32 {
fn from(value: MemoryItem) -> Self {
value.unwrap_data()
}
}