osiris_set_std/
registers.rs1use std::collections::HashMap;
15use osiris_data::converters::Words;
16
17use osiris_data::data::atomic::{HalfWord, Word};
18use osiris_process::operation::error::{OperationError, OperationResult};
19use osiris_process::operation::{Operation, OperationSet};
20use osiris_process::operation::scheme::{ArgumentType, InstructionScheme, OperationId};
21use osiris_process::processor::Cpu;
22use osiris_process::register::floating_point::Number;
23use osiris_process::register::RegisterId;
24
25pub const SET_MASK: u16 = 0x0200;
26pub const SET_TOP: OperationId = OperationId::new(SET_MASK | 0x01);
27pub const SET_BOTTOM: OperationId = OperationId::new(SET_MASK | 0x02);
28pub const CLEAR_RANGE: OperationId = OperationId::new(SET_MASK | 0x03);
29pub const MOVE_TO_FLOAT: OperationId = OperationId::new(SET_MASK | 0x04);
30pub const MOVE_FROM_FLOAT: OperationId = OperationId::new(SET_MASK | 0x05);
31pub const PUSH: OperationId = OperationId::new(SET_MASK | 0x10);
32pub const POP: OperationId = OperationId::new(SET_MASK | 0x11);
33pub const GET_COMPARE: OperationId = OperationId::new(SET_MASK | 0x20);
34
35pub fn set_top(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
49 let value = scheme.argument.get_one_u32()?;
50 let bottom = cpu.bank_get(scheme.target).bottom();
51 cpu.debug("merge", format!("{:08x}:{:08x}", value, bottom.to_u32()), "⚙️".to_string());
52 cpu.bank_set(scheme.target, Word::merge(HalfWord::new(value), bottom));
53 Ok(())
54}
55
56pub fn set_bottom(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
70 let value = scheme.argument.get_one_u32()?;
71 let top = cpu.bank_get(scheme.target).top();
72 cpu.debug("merge", format!("{:08x}:{:08x}", top.to_u32(), value), "⚙️".to_string());
73 cpu.bank_set(scheme.target, Word::merge(top, HalfWord::new(value)));
74 Ok(())
75}
76
77pub fn clear_range(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
91 for id in scheme.argument.get_range()?.to_usize_range() {
92 let rid = RegisterId::new(id as u16);
93 cpu.bank_set(rid, Word::default());
94 }
95 Ok(())
96}
97
98pub fn move_to_float(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
113 let (_, bank_id) = scheme.argument.get_two_u16()?;
114 let word = cpu.bank_get(RegisterId::new(bank_id));
115 cpu.vector_set(scheme.target, Number::from_word(word));
116 Ok(())
117}
118
119pub fn move_from_float(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
134 let (_, bank_id) = scheme.argument.get_two_u16()?;
135 let number = cpu.vector_get(RegisterId::new(bank_id));
136 cpu.bank_set(scheme.target, number.to_word());
137 Ok(())
138}
139
140pub fn push(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
154 scheme.argument.get_no_argument()?;
155 cpu.bank_push(scheme.target);
156 Ok(())
157}
158
159pub fn pop(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
173 scheme.argument.get_no_argument()?;
174 cpu.bank_pop(scheme.target);
175 Ok(())
176}
177
178pub fn get_compare(cpu: &mut Cpu, scheme: InstructionScheme) -> OperationResult<()> {
192 scheme.argument.get_no_argument()?;
193 cpu.bank_set(scheme.target, Words::from_i64(cpu.state.operation.compare));
194 Ok(())
195}
196
197pub fn operation_set() -> OperationSet {
210 let mut set: OperationSet = HashMap::new();
211 set.insert(SET_TOP, Operation::new(SET_TOP, "set-top".to_string(), true, ArgumentType::OneU32, set_top));
212 set.insert(SET_BOTTOM, Operation::new(SET_BOTTOM, "set-bottom".to_string(), true, ArgumentType::OneU32, set_bottom));
213 set.insert(CLEAR_RANGE, Operation::new(CLEAR_RANGE, "clear-range".to_string(), false, ArgumentType::Range, clear_range));
214 set.insert(MOVE_TO_FLOAT, Operation::new(MOVE_TO_FLOAT, "move-to-float".to_string(), true, ArgumentType::TwoU16, move_to_float));
215 set.insert(MOVE_FROM_FLOAT, Operation::new(MOVE_FROM_FLOAT, "move-from-float".to_string(), true, ArgumentType::TwoU16, move_from_float));
216 set.insert(PUSH, Operation::new(PUSH, "push".to_string(), true, ArgumentType::NoArgument, push));
217 set.insert(POP, Operation::new(POP, "pop".to_string(), true, ArgumentType::NoArgument, pop));
218 set.insert(GET_COMPARE, Operation::new(GET_COMPARE, "get-compare".to_string(), true, ArgumentType::NoArgument, get_compare));
219 set
220}