diff --git a/src/main.rs b/src/main.rs index 31f75d5..18f23c5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -361,7 +361,7 @@ OP::RCPF => 2, } fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) { - println!("{:#02x?}", &bytes[0..8]); + //println!("{:#02x?}", &bytes[0..8]); let mut consumed = 0; let def = DefinitionWord(bytes[0]); @@ -387,11 +387,11 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) { let mut registers = Vec::new(); if register_count > 0 { let mut aw = bytes[0]; - dbg!(aw); + //dbg!(aw); bytes = &bytes[1..]; consumed += 1; - println!("{:016b}", aw); + //println!("{:016b}", aw); aw >>= 4; for i in 0..register_count { registers.insert(0_usize, Register::into_register(aw & 0b1111)); @@ -444,14 +444,22 @@ impl Arg { Arg::SMAIN(x) => x, } } + + fn offset(self, by: i32) -> Self { + match self { + Arg::Register(_) => panic!("offset must be memory space address"), + Arg::SIN(x) => Arg::SIN((x as i32 + by) as u16), + Arg::SMAIN(x) => Arg::SMAIN((x as i32 + by) as u16), + } + } } impl Machine { fn step(&mut self) -> bool { - let (cur_instruction, inc_by) = parse_instruction(&self.SCODE[(self.IP as usize)..]); - dbg!(&cur_instruction); + let (ci, inc_by) = parse_instruction(&self.SCODE[(self.IP as usize)..]); + //dbg!(&ci); - let oc = cur_instruction.def.opcode(); + let oc = ci.def.opcode(); let mut should_inc_ip = true; @@ -459,10 +467,10 @@ impl Machine { OP::HALT => return false, OP::NOOP => {}, OP::XOR => { - let arg0 = self.read(cur_instruction.args[0]); - let arg1 = self.read(cur_instruction.args[1]); + let arg0 = self.read(ci.args[0]); + let arg1 = self.read(ci.args[1]); let xored = arg0 ^ arg1; - self.write(cur_instruction.args[0], xored); + self.write(ci.args[0], xored); self.RSTAT.set(Flags::FZERO, xored == 0); } OP::CALL => { @@ -475,9 +483,9 @@ impl Machine { self.push_stack(self.RZ); self.push_stack(u16::try_from(inc_by).unwrap()); self.RSR = self.RSK; - self.RX = self.read(cur_instruction.args[0]); - self.RY = self.read(cur_instruction.args[1]); - self.RZ = self.read(cur_instruction.args[2]); + self.RX = self.read(ci.args[0]); + self.RY = self.read(ci.args[1]); + self.RZ = self.read(ci.args[2]); self.RCALL = self.IP; self.IP = self.RTRGT; should_inc_ip = false; @@ -486,21 +494,26 @@ impl Machine { } } OP::POP => { - if self.RSK == 0xffff { - - } else { - unimplemented!(); - } + let val = self.pop_stack(); + self.write(ci.args[0], val); + self.RSTAT.set(Flags::FZERO, val == 0); + self.RSTAT.set(Flags::FSE, self.RSK == 0xffff); + } + OP::PUSH => { + let val = self.read(ci.args[0]); + self.push_stack(val); + self.RSTAT.set(Flags::FZERO, val == 0); + self.RSTAT.set(Flags::FSF, self.RSK == 0); } OP::ICPY => { - let arg0 = cur_instruction.args[0].as_immediate(); - self.write(cur_instruction.args[1], arg0); + let arg0 = ci.args[0].as_immediate(); + self.write(ci.args[1], arg0); self.RSTAT.set(Flags::FZERO, arg0 == 0); - eprintln!("copying {} to {:?}", arg0, cur_instruction.args[1]); + //eprintln!("copying {} to {:?}", arg0, ci.args[1]); } OP::CMP => { - let a = self.read(cur_instruction.args[0]); - let b = self.read(cur_instruction.args[0]); + let a = self.read(ci.args[0]); + let b = self.read(ci.args[0]); self.RSTAT.set(Flags::FZERO, a == 0 || b == 0); self.RSTAT.set(Flags::FEQUL, a == b); @@ -514,17 +527,74 @@ impl Machine { } } OP::INC => { - let mut val = self.read(cur_instruction.args[0]); + let mut val = self.read(ci.args[0]); val += 1; - self.write(cur_instruction.args[0], val); + self.write(ci.args[0], val); self.RSTAT.set(Flags::FZERO, val == 0); } OP::READ => { - let input = 50; + let input = 0; - self.write(cur_instruction.args[0], input); + self.write(ci.args[0], input); self.RSTAT.set(Flags::FZERO, input == 0); } + OP::CPY => { + let val = self.read(ci.args[0]); + self.write(ci.args[1], val); + self.RSTAT.set(Flags::FZERO, val == 0); + } + OP::RTRN => { + self.RSK = self.RSR; + self.RX = self.pop_stack(); + self.IP = self.RCALL + self.RX; + should_inc_ip = false; + + self.RZ = self.pop_stack(); + self.RY = self.pop_stack(); + self.RX = self.pop_stack(); + self.RSTAT = Flags::from_bits(self.pop_stack()).unwrap(); + self.RCALL = self.pop_stack(); + + self.push_stack(self.RTRGT); + self.RTRGT = 0; + } + OP::RCPF => { + let by: i32 = if ci.def.sign() == 1 { + self.RTRGT as i32 + } else { + -(self.RTRGT as i32) + }; + + let from = ci.args[0].offset(by); + let from_val = self.read(from); + self.RSTAT.set(Flags::FZERO, from_val == 0); + + self.write(ci.args[1], from_val); + } + OP::CMPL => { + let mut val = self.read(ci.args[0]); + val = !val; + self.write(ci.args[0], val); + self.RSTAT.set(Flags::FZERO, val == 0); + } + OP::AND => { + let arg0 = self.read(ci.args[0]); + let arg1 = self.read(ci.args[1]); + let anded = arg0 & arg1; + self.write(ci.args[0], anded); + self.RSTAT.set(Flags::FZERO, anded == 0); + } + OP::OR => { + let arg0 = self.read(ci.args[0]); + let arg1 = self.read(ci.args[1]); + let ored = arg0 | arg1; + self.write(ci.args[0], ored); + self.RSTAT.set(Flags::FZERO, ored == 0); + } + OP::WRIT => { + let arg = self.read(ci.args[0]); + println!("ch: `{}`", arg); + } _ => { eprintln!("unsupported opcode {:?}, continuing", oc); return false; } } @@ -540,7 +610,7 @@ fn dump_instructions(mut x: &[u16]) { while !x.is_empty() { let (i, inc) = parse_instruction(x); x = &x[inc..]; - println!("{:?}", i); + //println!("{:?}", i); } }