changes uwu

This commit is contained in:
5225225 2020-06-06 15:10:12 +01:00
parent 6cbdb42dbf
commit d394c95c02
3 changed files with 102 additions and 17 deletions

BIN
challenge

Binary file not shown.

Binary file not shown.

View File

@ -18,7 +18,49 @@ struct Machine {
IP: u16, 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 { enum Register {
RX, RX,
RY, RY,
@ -192,14 +234,6 @@ bitfield::bitfield! {
into AFLG, aflg0, set_aflg0: 15, 14; 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)] #[derive(Debug)]
struct Instruction { struct Instruction {
def: DefinitionWord, def: DefinitionWord,
@ -216,9 +250,9 @@ impl Default for Machine {
RSTAT: Flags::FSE, RSTAT: Flags::FSE,
IP: 1, IP: 0,
RCALL: 0, RCALL: 0,
RSK: 0, RSK: 0xffff,
RSR: 0, RSR: 0,
RTRGT: 0, RTRGT: 0,
RX: 0, RX: 0,
@ -324,8 +358,6 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) {
let mut args = Vec::new(); let mut args = Vec::new();
let mut registers_found = 0;
let mut register_count = 0; let mut register_count = 0;
if ac > 0 && def.aflg0() == AFLG::Register { if ac > 0 && def.aflg0() == AFLG::Register {
@ -341,6 +373,7 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) {
let mut registers = Vec::new(); let mut registers = Vec::new();
if register_count > 0 { if register_count > 0 {
let mut aw = bytes[0]; let mut aw = bytes[0];
dbg!(aw);
bytes = &bytes[1..]; bytes = &bytes[1..];
consumed += 1; consumed += 1;
@ -380,23 +413,73 @@ fn parse_instruction(mut bytes: &[u16]) -> (Instruction, usize) {
(Instruction { def, args }, consumed) (Instruction { def, args }, consumed)
} }
#[derive(Debug)] #[derive(Debug, Copy, Clone)]
enum Arg { enum Arg {
Register(Register), Register(Register),
SIN(u16), SIN(u16),
SMAIN(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 { impl Machine {
fn step(&mut self) -> bool { fn step(&mut self) -> bool {
let (cur_instruction, inc_by) = parse_instruction(&self.SCODE[(self.IP as usize)..]); let (cur_instruction, inc_by) = parse_instruction(&self.SCODE[(self.IP as usize)..]);
dbg!(&cur_instruction);
let oc = cur_instruction.def.opcode(); let oc = cur_instruction.def.opcode();
match oc { match oc {
OP::HALT => return false, OP::HALT => return false,
OP::NOOP => {}, 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; self.IP += inc_by as u16;
@ -406,7 +489,7 @@ impl Machine {
} }
fn dump_instructions(mut x: &[u16]) { fn dump_instructions(mut x: &[u16]) {
loop { while !x.is_empty() {
let (i, inc) = parse_instruction(x); let (i, inc) = parse_instruction(x);
x = &x[inc..]; x = &x[inc..];
println!("{:?}", i); println!("{:?}", i);
@ -429,5 +512,7 @@ fn main() {
m.SIN = sin.inner().to_vec(); m.SIN = sin.inner().to_vec();
m.SCODE = code.inner().to_vec(); m.SCODE = code.inner().to_vec();
dump_instructions(&m.SCODE); dump_instructions(&m.SCODE[1..]);
// while m.step() {}
} }