1use std::cell::{Ref, RefCell, RefMut};
2use std::ops::Add;
3use std::rc::Rc;
4use std::time::{Duration, Instant};
5
6use osiris_data::data::atomic::Word;
7use osiris_data::data::composite::ProduceConsume;
8use osiris_data::data::identification::{Address, Identifier};
9use osiris_data::memory::{Memory, MemoryError, MemoryResult};
10use crate::communication::MessageQueue;
11
12use crate::operation;
13use crate::operation::{Instruction, Operation, OperationSet};
14use crate::operation::error::{OperationError, OperationResult};
15use crate::register::{RegisterBank, RegisterId, RegisterRange};
16use crate::register::floating_point::{Number, VectorApplication};
17use crate::register::integral::BankApplication;
18use crate::register::state::{CpuState, TickState};
19
20#[derive(Copy, Clone, Debug)]
21pub struct CpuConfiguration {
22 pub frequency: usize,
23}
24
25impl CpuConfiguration {
26 pub const DEFAULT_FREQUENCY: usize = 64;
27}
28
29impl Default for CpuConfiguration {
30 fn default() -> Self {
32 CpuConfiguration {
33 frequency: Self::DEFAULT_FREQUENCY,
34 }
35 }
36}
37
38#[derive(Clone, Debug, Default)]
40pub struct Cpu {
41 pub parent: Option<Rc<Cpu>>,
42 pub config: CpuConfiguration,
43 pub state: CpuState,
44 pub output: MessageQueue,
45 operations: Rc<OperationSet>,
46 ram: RefCell<Memory>,
47}
48
49impl Cpu {
50 pub fn new(memory: RefCell<Memory>, operation_set: Rc<OperationSet>) -> Self {
51 Self {
52 parent: None,
53 config: CpuConfiguration::default(),
54 state: CpuState::new(),
55 output: MessageQueue::default(),
56 operations: operation_set,
57 ram: memory,
58 }
59 }
60
61 pub fn fork(self, fork_target: Address) -> (Self, Rc<Self>) {
62 let config = self.config;
63 let mut state = self.state.clone();
64 state.current = fork_target;
65 let operations = self.operations.clone();
66 let ram = self.memory();
67 let rc = Rc::from(self);
68
69 (Self {
70 parent: Some(rc.clone()),
71 config,
72 state,
73 output: MessageQueue::default(),
74 operations,
75 ram,
76 }, rc)
77 }
78
79 pub fn debug(&self, label: &str, value: String, symbol: String) {
80 if self.state.flag_debug {
81 println!("\u{2ba1} {:15} {:} \x1b[1;38m{}\x1b[0m", label, symbol, value);
82 }
83 }
84
85 pub fn memory(&self) -> RefCell<Memory> { self.ram.clone() }
88 pub fn ram(&self) -> Ref<Memory> { self.ram.borrow() }
89 pub fn ram_mut(&self) -> RefMut<Memory> { self.ram.borrow_mut() }
90
91 pub fn stack_push(&mut self, word: Word) {
94 self.debug("push", format!("{:016x}", word.to_u64()), "🔽".to_string());
95 self.state.stack.produce(word);
96 }
97 pub fn stack_pop(&mut self) -> Option<Word> {
98 let pop = self.state.stack.consume();
99 self.debug("pop", match &pop {
100 None => "".to_string(),
101 Some(w) => format!("{:016x}", w.to_u64()),
102 }, "🔼".to_string());
103 pop
104 }
105 pub fn bank_get(&self, register_id: RegisterId) -> Word {
106 let v = self.state.bank.get(register_id);
107 self.debug(format!("get r{:04x}", register_id.to_u16()).as_str(), format!("{:016x}", v.to_u64()), "▶️".to_string());
108 v
109 }
110 pub fn bank_set(&mut self, register_id: RegisterId, word: Word) {
111 self.state.bank.set(register_id, word);
112 self.debug(format!("set r{:04x}", register_id.to_u16()).as_str(), format!("{:016x}", self.state.bank.get(register_id).to_u64()), "◀️".to_string());
113 }
114
115 pub fn bank_store(&mut self, register_id: RegisterId, address: Address) -> MemoryResult<()> {
116 let word = self.state.bank.get(register_id);
117 self.ram_mut().store(address, word)?;
118 self.debug("store", format!("{:016x} {:016x}", address.to_u64(), word.to_u64()), "⏬".to_string());
119 Ok(())
120 }
121
122 pub fn bank_load(&mut self, register_id: RegisterId, address: Address) -> MemoryResult<()> {
123 let word = self.ram().load(address)?;
124 self.state.bank.set(register_id, word);
125 self.debug("load", format!("{:016x} {:016x}", address.to_u64(), word.to_u64()), "⏫".to_string());
126 Ok(())
127 }
128
129 pub fn bank_apply(&mut self, target: RegisterId, range: RegisterRange, application: BankApplication) {
130 self.debug("apply unsigned", format!("{:04x}:{:04x}", range.start.to_u16(), range.end.to_u16()), "⚙️".to_string());
131 self.state.operation.result = self.state.bank.apply(range, application);
132 self.bank_set(target, self.state.operation.result);
133 }
134
135 pub fn bank_push(&mut self, register_id: RegisterId) {
136 self.stack_push(self.bank_get(register_id));
137 }
138
139 pub fn bank_pop(&mut self, register_id: RegisterId) {
140 if self.state.stack.is_empty() { return; }
141 let popped = self.stack_pop().unwrap_or(self.state.bank.get(register_id));
142 self.bank_set(register_id, popped);
143 }
144
145 pub fn vector_get(&self, register_id: RegisterId) -> Number {
146 let v = self.state.vector.get(register_id);
147 self.debug(format!("get f{:04x}", register_id.to_u16()).as_str(), format!("{}", v.to_f64()), "▶️".to_string());
148 v
149 }
150 pub fn vector_set(&mut self, register_id: RegisterId, number: Number) {
151 self.state.vector.set(register_id, number);
152 self.debug(format!("set f{:04x}", register_id.to_u16()).as_str(), format!("{}", self.state.vector.get(register_id).to_f64()), "◀️".to_string());
153 }
154
155 pub fn vector_store(&mut self, register_id: RegisterId, address: Address) -> MemoryResult<()> {
156 let number = self.state.vector.get(register_id);
157 self.ram_mut().store(address, Word::new(number.to_u64()))?;
158 self.debug("store", format!("{:016x} {}", address.to_u64(), number.to_f64()), "⏬".to_string());
159 Ok(())
160 }
161
162 pub fn vector_load(&mut self, register_id: RegisterId, address: Address) -> MemoryResult<()> {
163 let number = self.ram().load(address)?;
164 let number = Number::from_u64(number.to_u64());
165 self.state.vector.set(register_id, number);
166 self.debug("load", format!("{:016x} {}", address.to_u64(), number.to_f64()), "⏬".to_string());
167 Ok(())
168 }
169
170 pub fn vector_apply(&mut self, target: RegisterId, range: RegisterRange, application: VectorApplication) {
171 self.debug("apply float", format!("{:04x}:{:04x}", range.start.to_u16(), range.end.to_u16()), "⚙️".to_string());
172 self.state.vector.set(target, self.state.vector.apply(range, application));
173 }
174
175 pub fn vector_push(&mut self, register_id: RegisterId) { self.stack_push(Word::new(self.vector_get(register_id).to_u64())); }
176
177 pub fn vector_pop(&mut self, register_id: RegisterId) {
178 if self.state.stack.is_empty() { return; }
179 let value = self.stack_pop()
180 .unwrap_or(Word::new(self.vector_get(register_id).to_u64())).to_u64();
181 self.vector_set(register_id, Number::from_u64(value))
182 }
183
184 pub fn next_instruction(&mut self) {
185 self.state.current.increment();
186 }
187
188 pub fn stack_size(&self) -> usize { self.state.stack.len() }
189 pub fn memory_size(&self) -> usize { self.ram().len() }
190
191 pub fn current_instruction(&self) -> Instruction { Instruction::new(self.ram().load(self.state.current).unwrap_or_default().to_u64()) }
192
193 pub fn point_instruction(&mut self, new_address: Address) -> MemoryResult<()> {
194 if new_address.to_usize() > self.memory_size() {
195 return Err(MemoryError::OutOfBounds { requested: new_address.to_usize(), memory_len: self.memory_size() });
196 }
197 self.state.current = new_address;
198 self.debug("point", format!("{:016x}", self.state.current.to_u64()), "📌".to_string());
199 Ok(())
200 }
201
202 pub fn decrease_loop_counter(&mut self) {
203 let counter = self.state.operation.counter.to_u64();
204 if counter > 0 {
205 self.state.operation.counter = Word::new(counter - 1);
206 self.debug("loop--", format!("{}", counter), "♾️".to_string());
207 } else {
208 self.debug("no loop", format!("{}", counter), "♾️".to_string());
209 }
210 }
211
212 pub fn halt(&mut self) {
213 self.debug("halt cpu", "".to_string(), "🛑".to_string());
214 self.state.flag_halt = true;
215 }
216
217 pub fn tick(&mut self) -> OperationResult<TickState> {
220 let instruction = self.current_instruction();
221 match operation::match_operation(&self.operations, instruction) {
222 None => Err(OperationError::MismatchedInstruction(instruction)),
223 Some(operation) => self.execute_or_skip(instruction, operation)
224 }
225 }
226
227 fn execute_or_skip(&mut self, instruction: Instruction, operation: Operation<()>) -> OperationResult<TickState> {
228 let scheme = instruction.operation_to_instruction(&operation);
229 if self.state.flag_skip {
230 self.state.flag_skip = false;
231 Ok(TickState::Skipped)
232 } else {
233 let old_current = self.state.current;
234 if self.state.flag_debug {
235 let [addr_top, addr_bottom] = Word::new(self.state.current.to_u64()).split();
236 print!("\x1b[37m{:08x}\x1b[0m{:08x}: ", addr_top.to_u32(), addr_bottom.to_u32());
237 operation.call_debug(self, scheme)?;
238 } else {
239 operation.call(self, scheme)?;
240 }
241 if self.state.current != old_current {
242 Ok(TickState::Jumped)
243 } else {
244 Ok(TickState::Executed)
245 }
246 }
247 }
248
249 pub fn next_instant(&self) -> Instant {
250 Instant::now().add(Duration::from_nanos(((1024 * 1024 * 1024) as f64 / self.config.frequency as f64) as u64))
252 }
253
254 pub fn advance(&mut self) {
255 let state = match self.tick() {
256 Ok(s) => s,
257 Err(err) => panic!("⚠️ \x1b[31mOperation error\x1b[0m : {:#?}", err)
258 };
259 if state != TickState::Jumped {
260 self.next_instruction();
261 }
262 }
263
264 pub fn until_halt(&mut self) {
265 loop {
266 self.advance();
267 if self.state.flag_halt {
268 break;
269 }
270 }
271 }
272
273}