diff --git a/challenge b/challenge deleted file mode 100644 index 5096c31..0000000 Binary files a/challenge and /dev/null differ diff --git a/challenge.zst b/challenge.zst deleted file mode 100644 index dc04cd0..0000000 Binary files a/challenge.zst and /dev/null differ diff --git a/src/main.rs b/src/main.rs index 5d94a19..6316f2d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,7 +18,49 @@ struct Machine { IP: u16, } -#[derive(Debug, Eq, PartialEq)] +impl Machine { + fn write_reg(&mut self, reg: Register, val: u16) { + match reg { + Register::RX => self.RX = val, + Register::RY => self.RY = val, + Register::RZ => self.RZ = val, + Register::RTRGT => self.RTRGT = val, + Register::RSTAT => {}, // writes have no effect + Register::RCALL => {}, + Register::NULL => {}, + } + } + + fn read_reg(&mut self, reg: Register) -> u16 { + match reg { + Register::RX => self.RX, + Register::RY => self.RY, + Register::RZ => self.RZ, + Register::RTRGT => 0, + Register::RSTAT => self.RSTAT.bits(), + Register::RCALL => self.RCALL, + Register::NULL => 0, + } + } + + fn read(&mut self, a: Arg) -> u16 { + match a { + Arg::Register(r) => self.read_reg(r), + Arg::SIN(v) => self.SIN[v as usize], + Arg::SMAIN(v) => self.SMAIN[v as usize], + } + } + + fn write(&mut self, a: Arg, val: u16) { + match a { + Arg::Register(r) => self.write_reg(r, val), + Arg::SIN(v) => self.SIN[v as usize] = val, + Arg::SMAIN(v) => self.SMAIN[v as usize] = val, + } + } +} + +#[derive(Debug, Eq, PartialEq, Copy, Clone)] enum Register { RX, RY, @@ -192,14 +234,6 @@ bitfield::bitfield! { into AFLG, aflg0, set_aflg0: 15, 14; } -bitfield::bitfield! { - struct ArgumentWord(u16); - impl Debug; - reg2, set_reg2: 3, 0; - reg1, set_reg1: 7, 4; - reg0, set_reg0: 11, 8; -} - #[derive(Debug)] struct Instruction { def: DefinitionWord, @@ -216,9 +250,9 @@ impl Default for Machine { RSTAT: Flags::FSE, - IP: 1, + IP: 0, RCALL: 0, - RSK: 0, + RSK: 0xffff, RSR: 0, RTRGT: 0, RX: 0, @@ -324,8 +358,6 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) { let mut args = Vec::new(); - let mut registers_found = 0; - let mut register_count = 0; if ac > 0 && def.aflg0() == AFLG::Register { @@ -341,6 +373,7 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) { let mut registers = Vec::new(); if register_count > 0 { let mut aw = bytes[0]; + dbg!(aw); bytes = &bytes[1..]; consumed += 1; @@ -380,23 +413,73 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) { (Instruction { def, args }, consumed) } -#[derive(Debug)] +#[derive(Debug, Copy, Clone)] enum Arg { Register(Register), SIN(u16), SMAIN(u16), } +impl Arg { + fn as_immediate(self) -> u16 { + match self { + Arg::Register(_) => panic!("a register is not an immediate"), + Arg::SIN(x) => x, + Arg::SMAIN(x) => x, + } + } +} + impl Machine { fn step(&mut self) -> bool { let (cur_instruction, inc_by) = parse_instruction(&self.SCODE[(self.IP as usize)..]); + dbg!(&cur_instruction); let oc = cur_instruction.def.opcode(); match oc { OP::HALT => return false, OP::NOOP => {}, - _ => eprintln!("unsupported opcode {:?}, continuing", oc), + OP::XOR => { + let arg0 = self.read(cur_instruction.args[0]); + let arg1 = self.read(cur_instruction.args[1]); + let xored = arg0 ^ arg1; + self.write(cur_instruction.args[0], xored); + self.RSTAT.set(Flags::FZERO, xored == 0); + } + OP::CALL => { + if self.RTRGT == 0 { + } else { + unimplemented!("calling not implemented"); + } + } + OP::POP => { + if self.RSK == 0xffff { + + } else { + unimplemented!(); + } + } + OP::ICPY => { + let arg0 = cur_instruction.args[0].as_immediate(); + self.write(cur_instruction.args[1], arg0); + self.RSTAT.set(Flags::FZERO, arg0 == 0); + } + OP::CMP => { + let a = self.read(cur_instruction.args[0]); + let b = self.read(cur_instruction.args[0]); + + self.RSTAT.set(Flags::FZERO, a == 0 || b == 0); + self.RSTAT.set(Flags::FEQUL, a == b); + self.RSTAT.set(Flags::FLT, a < b); + self.RSTAT.set(Flags::FGT, a > b); + } + OP::JEQU => { + if self.RSTAT.contains(Flags::FEQUL) { + unimplemented!("{:?}", self.RTRGT); + } + } + _ => { eprintln!("unsupported opcode {:?}, continuing", oc); return false; } } self.IP += inc_by as u16; @@ -406,7 +489,7 @@ impl Machine { } fn dump_instructions(mut x: &[u16]) { - loop { + while !x.is_empty() { let (i, inc) = parse_instruction(x); x = &x[inc..]; println!("{:?}", i); @@ -429,5 +512,7 @@ fn main() { m.SIN = sin.inner().to_vec(); m.SCODE = code.inner().to_vec(); - dump_instructions(&m.SCODE); + dump_instructions(&m.SCODE[1..]); + +// while m.step() {} }