@@ 1,92 @@
+struct Processor {
+ stack_a: Vec<u16>,
+ stack_b: Vec<u16>,
+ pub memory: [u16;1024],
+ carry: bool,
+ pub pc: u16 //program counter
+}
+
+impl Processor {
+ pub fn run(&mut self) {
+ let instruction = self.memory[self.pc as usize];
+ let mut is_jump = false;
+ match instruction & 0x300 {
+ 0x000 => self.carry = calc(&mut self.stack_a, instruction, self.carry),
+ 0x100 => self.carry = calc(&mut self.stack_a, instruction, self.carry),
+ 0x200 => self.stack_a.push(instruction & 0xFF),
+ 0x300 => {
+ if (instruction & 0x80) != 0 {
+ let conditional = (instruction & 0x40) != 0;
+ let relative = (instruction & 0x20) != 0;
+ let save_pc = (instruction & 0x10) != 0;
+ if !conditional || self.carry {
+ let address = self.stack_a.pop().expect("End of stack");
+ if save_pc {self.stack_a.push(self.pc+1)};
+ if relative {self.pc += address}
+ else {self.pc = address};
+ is_jump = true;
+ }
+ }
+ else {
+ let toggle = (instruction & 0x40) != 0;
+ let mut stack;
+ if toggle {stack = &mut self.stack_b;}
+ else {stack = &mut self.stack_a;};
+ match instruction & 0x3F {
+ 0 => { //swap top 2
+ let a = stack.pop().expect("End of stack");
+ let b = stack.pop().expect("End of stack");
+ stack.push(a);
+ stack.push(b);
+ }
+ 1 => { //clone top
+ let a = stack.pop().expect("End of stack");
+ stack.push(a);
+ stack.push(a);
+ }
+ 2 => { //clone second
+ let a = stack.pop().expect("End of stack");
+ let b = stack.pop().expect("End of stack");
+ stack.push(b);
+ stack.push(a);
+ stack.push(b);
+ }
+ 3 => { //move between stacks
+ if toggle {self.stack_a.push(self.stack_b.pop().expect("End of stack"));}
+ else {self.stack_b.push(self.stack_a.pop().expect("End of stack"));};
+ }
+ 4 => { //push/pop
+ let addr = self.stack_a.pop().expect("End of stack") as usize;
+ if toggle {
+ let value = self.stack_a.pop().expect("End of stack");
+ self.memory[addr] = value;
+ }
+ else {self.stack_a.push(self.memory[addr]);};
+ }
+ 5 => { //set/clear carry
+ self.carry = toggle;
+ }
+ _ => ()
+ }
+ }
+ }
+ _ => unreachable!()
+ }
+ if !is_jump {self.pc += 1};
+ }
+}
+
+fn calc(stack: &mut Vec::<u16>, instruction: u16, carry_in: bool) -> bool {
+ let operand_a = stack.pop().expect("End of stack");
+ let operand_b = stack.pop().expect("End of stack");
+ let mut carry = carry_in;
+ let mut result = 0;
+ for i in 0..10 {
+ let bit = 1 << i;
+ let count = ((operand_a & bit) >> i) + ((operand_b & bit) >> i) + carry as u16;
+ result += ((instruction & (1<<(count+4))) >> count) << i;
+ carry = (instruction & (1<<count)) != 0;
+ }
+ stack.push(result);
+ carry
+}