changes uwu
This commit is contained in:
parent
6cbdb42dbf
commit
d394c95c02
BIN
challenge.zst
BIN
challenge.zst
Binary file not shown.
119
src/main.rs
119
src/main.rs
|
@ -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() {}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue