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 }