mirror of
https://github.com/guilhermewerner/machine
synced 2025-06-16 13:14:18 +00:00
Update machine methods
This commit is contained in:
Binary file not shown.
@ -1,326 +1,402 @@
|
|||||||
use crate::Machine;
|
use crate::Machine;
|
||||||
|
|
||||||
pub fn Nothing(vm: &mut Machine) -> bool {
|
pub fn Nothing(vm: &mut Machine) -> bool {
|
||||||
vm.program += 1;
|
vm.WalkAddress(1);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn LoadRegister(vm: &mut Machine) -> bool {
|
pub fn LoadRegister(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1];
|
let pc = vm.GetAddress();
|
||||||
let a = vm.memory[vm.program + 2];
|
|
||||||
|
|
||||||
vm.registers[r as usize] = vm.memory[a as usize];
|
let reg = vm.GetMemory(pc + 1);
|
||||||
|
let addr = vm.GetMemory(pc + 2);
|
||||||
|
|
||||||
vm.program += 3;
|
let val = vm.GetMemory(addr);
|
||||||
|
|
||||||
|
vm.SetRegister(reg, val);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SaveRegister(vm: &mut Machine) -> bool {
|
pub fn SaveRegister(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1];
|
let pc = vm.GetAddress();
|
||||||
let a = vm.memory[vm.program + 2];
|
|
||||||
|
|
||||||
vm.memory[a as usize] = vm.registers[r as usize];
|
let addr = vm.GetMemory(pc + 1);
|
||||||
|
let reg = vm.GetMemory(pc + 2);
|
||||||
|
|
||||||
vm.program += 3;
|
let val = vm.GetRegister(reg);
|
||||||
|
|
||||||
|
vm.SetMemory(addr, val);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Move(vm: &mut Machine) -> bool {
|
#[allow(dead_code)]
|
||||||
|
pub fn Move(_vm: &mut Machine) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Add(vm: &mut Machine) -> bool {
|
pub fn Add(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a + b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 + op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn AddAssign(vm: &mut Machine) -> bool {
|
pub fn AddAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] += a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 + op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Subtract(vm: &mut Machine) -> bool {
|
pub fn Subtract(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a - b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 - op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SubtractAssign(vm: &mut Machine) -> bool {
|
pub fn SubtractAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] -= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 - op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Multiply(vm: &mut Machine) -> bool {
|
pub fn Multiply(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a * b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 * op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn MultiplyAssign(vm: &mut Machine) -> bool {
|
pub fn MultiplyAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] *= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 * op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Divide(vm: &mut Machine) -> bool {
|
pub fn Divide(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a / b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 / op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn DivideAssign(vm: &mut Machine) -> bool {
|
pub fn DivideAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] /= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 / op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Remainder(vm: &mut Machine) -> bool {
|
pub fn Remainder(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a % b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 % op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn RemainderAssign(vm: &mut Machine) -> bool {
|
pub fn RemainderAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] %= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 % op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Neg(vm: &mut Machine) -> bool {
|
#[allow(dead_code)]
|
||||||
|
pub fn Neg(_vm: &mut Machine) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn And(vm: &mut Machine) -> bool {
|
pub fn And(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a & b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 & op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn AndAssign(vm: &mut Machine) -> bool {
|
pub fn AndAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] &= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 & op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Or(vm: &mut Machine) -> bool {
|
pub fn Or(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a | b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 | op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn OrAssign(vm: &mut Machine) -> bool {
|
pub fn OrAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] |= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 | op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Xor(vm: &mut Machine) -> bool {
|
pub fn Xor(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a ^ b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 ^ op2);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn XorAssign(vm: &mut Machine) -> bool {
|
pub fn XorAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] ^= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
|
||||||
|
let op1 = vm.GetRegister(reg);
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 ^ op2);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Not(vm: &mut Machine) -> bool {
|
pub fn Not(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = !a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, !op1);
|
||||||
|
vm.WalkAddress(3);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ShiftLeft(vm: &mut Machine) -> bool {
|
pub fn ShiftLeft(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a << b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 << 1);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ShiftLeftAssign(vm: &mut Machine) -> bool {
|
pub fn ShiftLeftAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] <<= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
let op1 = vm.GetRegister(reg);
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 << 1);
|
||||||
|
vm.WalkAddress(2);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ShiftRight(vm: &mut Machine) -> bool {
|
pub fn ShiftRight(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = a >> b;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 >> 1);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ShiftRightAssign(vm: &mut Machine) -> bool {
|
pub fn ShiftRightAssign(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] >>= a;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 3;
|
let op1 = vm.GetRegister(reg);
|
||||||
|
|
||||||
|
vm.SetRegister(reg, op1 >> 1);
|
||||||
|
vm.WalkAddress(2);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Equals(vm: &mut Machine) -> bool {
|
pub fn Equals(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = (a == b) as u8;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, (op1 == op2) as u8);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn NotEquals(vm: &mut Machine) -> bool {
|
pub fn NotEquals(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = (a != b) as u8;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, (op1 != op2) as u8);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn LessThan(vm: &mut Machine) -> bool {
|
pub fn LessThan(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = (a < b) as u8;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, (op1 < op2) as u8);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn LessEquals(vm: &mut Machine) -> bool {
|
pub fn LessEquals(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = (a <= b) as u8;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, (op1 <= op2) as u8);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn GreaterThan(vm: &mut Machine) -> bool {
|
pub fn GreaterThan(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = (a > b) as u8;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, (op1 > op2) as u8);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn GreaterEquals(vm: &mut Machine) -> bool {
|
pub fn GreaterEquals(vm: &mut Machine) -> bool {
|
||||||
let r = vm.memory[vm.program + 1] as usize;
|
let pc = vm.GetAddress();
|
||||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
|
||||||
let b = vm.registers[vm.memory[vm.program + 3] as usize];
|
|
||||||
|
|
||||||
vm.registers[r] = (a >= b) as u8;
|
let reg = vm.GetMemory(pc + 1);
|
||||||
vm.program += 4;
|
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
|
||||||
|
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
|
||||||
|
|
||||||
|
vm.SetRegister(reg, (op1 >= op2) as u8);
|
||||||
|
vm.WalkAddress(4);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn Halt(vm: &mut Machine) -> bool {
|
pub fn Halt(_: &mut Machine) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
155
Source/Machine.rs
Normal file
155
Source/Machine.rs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
use std::panic;
|
||||||
|
|
||||||
|
use crate::Instructions::*;
|
||||||
|
use crate::Operations::*;
|
||||||
|
|
||||||
|
pub const ADDRESS_COUNT: usize = 256;
|
||||||
|
pub const REGISTER_COUNT: usize = 16;
|
||||||
|
|
||||||
|
pub struct Machine {
|
||||||
|
program: usize,
|
||||||
|
registers: [u8; REGISTER_COUNT],
|
||||||
|
memory: [u8; ADDRESS_COUNT],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Machine {
|
||||||
|
/// Create a machine with program counter.
|
||||||
|
pub fn New(pc: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
program: pc as usize,
|
||||||
|
registers: [0; REGISTER_COUNT],
|
||||||
|
memory: [0; ADDRESS_COUNT],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn LoadProgram(&mut self, buffer: &[u8], offset: u8) {
|
||||||
|
let mut i = offset as usize;
|
||||||
|
|
||||||
|
for elem in buffer.to_vec().drain(..) {
|
||||||
|
self.memory[i] = elem;
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Execute(mut self) {
|
||||||
|
let mut running = true;
|
||||||
|
|
||||||
|
while running {
|
||||||
|
//self.PrintMemory();
|
||||||
|
self.PrintRegisters();
|
||||||
|
|
||||||
|
let opcode = self.memory[self.program];
|
||||||
|
|
||||||
|
running = match opcode {
|
||||||
|
NOP => Nothing(&mut self),
|
||||||
|
LDR => LoadRegister(&mut self),
|
||||||
|
SVR => SaveRegister(&mut self),
|
||||||
|
//MOV
|
||||||
|
ADD => Add(&mut self),
|
||||||
|
ADD_ASSIGN => AddAssign(&mut self),
|
||||||
|
SUB => Subtract(&mut self),
|
||||||
|
SUB_ASSIGN => SubtractAssign(&mut self),
|
||||||
|
MUL => Multiply(&mut self),
|
||||||
|
MUL_ASSIGN => MultiplyAssign(&mut self),
|
||||||
|
DIV => Divide(&mut self),
|
||||||
|
DIV_ASSIGN => DivideAssign(&mut self),
|
||||||
|
REM => Remainder(&mut self),
|
||||||
|
REM_ASSIGN => RemainderAssign(&mut self),
|
||||||
|
//NEG
|
||||||
|
AND => And(&mut self),
|
||||||
|
AND_ASSIGN => AndAssign(&mut self),
|
||||||
|
OR => Or(&mut self),
|
||||||
|
OR_ASSIGN => OrAssign(&mut self),
|
||||||
|
XOR => Xor(&mut self),
|
||||||
|
XOR_ASSIGN => XorAssign(&mut self),
|
||||||
|
NOT => Not(&mut self),
|
||||||
|
SHL => ShiftLeft(&mut self),
|
||||||
|
SHL_ASSIGN => ShiftLeftAssign(&mut self),
|
||||||
|
SHR => ShiftRight(&mut self),
|
||||||
|
SHR_ASSIGN => ShiftRightAssign(&mut self),
|
||||||
|
EQ => Equals(&mut self),
|
||||||
|
NEQ => NotEquals(&mut self),
|
||||||
|
LT => LessThan(&mut self),
|
||||||
|
LE => LessEquals(&mut self),
|
||||||
|
GT => GreaterThan(&mut self),
|
||||||
|
GE => GreaterEquals(&mut self),
|
||||||
|
HLT => Halt(&mut self),
|
||||||
|
_ => Nothing(&mut self),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn PrintRegisters(&self) {
|
||||||
|
for data in self.registers.iter() {
|
||||||
|
print!("{:02x} ", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn PrintMemory(&self) {
|
||||||
|
let mut address = 0;
|
||||||
|
|
||||||
|
for data in self.memory.iter() {
|
||||||
|
if address % 8 == 0 {
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
print!("{:02x} ", data);
|
||||||
|
|
||||||
|
address += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetMemory(&self, addr: u8) -> u8 {
|
||||||
|
let index = addr as usize;
|
||||||
|
|
||||||
|
if index < ADDRESS_COUNT {
|
||||||
|
self.memory[index]
|
||||||
|
} else {
|
||||||
|
panic!("Invalid Address!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn SetMemory(&mut self, addr: u8, val: u8) {
|
||||||
|
let index = addr as usize;
|
||||||
|
|
||||||
|
if index < ADDRESS_COUNT {
|
||||||
|
self.memory[index] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetRegister(&self, reg: u8) -> u8 {
|
||||||
|
let index = reg as usize;
|
||||||
|
|
||||||
|
if index < REGISTER_COUNT {
|
||||||
|
self.registers[index]
|
||||||
|
} else {
|
||||||
|
panic!("Invalid Register!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn SetRegister(&mut self, reg: u8, val: u8) {
|
||||||
|
let index = reg as usize;
|
||||||
|
|
||||||
|
if index < REGISTER_COUNT {
|
||||||
|
self.registers[index] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetAddress(&self) -> u8 {
|
||||||
|
self.program as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn WalkAddress(&mut self, bytes: i8) {
|
||||||
|
self.program += bytes as usize;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn SetAddress(&mut self, addr: u8) {
|
||||||
|
self.program = addr as usize;
|
||||||
|
}
|
||||||
|
}
|
@ -155,28 +155,28 @@ pub const NOT: u8 = 0x15;
|
|||||||
/// **0x16** - The left shift operator `<<`.
|
/// **0x16** - The left shift operator `<<`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shl r1 r2 r3 // r1 = r2 << r3
|
/// shl r1 r2 // r1 = r2 << 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHL: u8 = 0x16;
|
pub const SHL: u8 = 0x16;
|
||||||
|
|
||||||
/// **0x17** - The left shift assignment operator `<<=`.
|
/// **0x17** - The left shift assignment operator `<<=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shl r1 r2 // r1 <<= r2
|
/// shl r1 // r1 <<= 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHL_ASSIGN: u8 = 0x17;
|
pub const SHL_ASSIGN: u8 = 0x17;
|
||||||
|
|
||||||
/// **0x18** - The right shift operator `>>`.
|
/// **0x18** - The right shift operator `>>`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shr r1 r2 r3 // r1 = r2 >> r3
|
/// shr r1 r2 // r1 = r2 >> 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHR: u8 = 0x18;
|
pub const SHR: u8 = 0x18;
|
||||||
|
|
||||||
/// **0x19** - The right shift assignment operator `>>=`.
|
/// **0x19** - The right shift assignment operator `>>=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shr r1 r2 // r1 >>= r2
|
/// shr r1 // r1 >>= 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHR_ASSIGN: u8 = 0x19;
|
pub const SHR_ASSIGN: u8 = 0x19;
|
||||||
|
|
||||||
|
129
Source/lib.rs
129
Source/lib.rs
@ -1,130 +1,9 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
#![allow(unused_imports)]
|
|
||||||
#![allow(unused_variables)]
|
|
||||||
|
|
||||||
pub mod Instructions;
|
mod Instructions;
|
||||||
pub mod Operations;
|
pub mod Operations;
|
||||||
pub mod Registers;
|
pub mod Registers;
|
||||||
|
|
||||||
use Instructions::*;
|
#[path = "Machine.rs"]
|
||||||
use Operations::*;
|
mod _Machine;
|
||||||
use Registers::*;
|
pub use self::_Machine::*;
|
||||||
|
|
||||||
//#[path = "World.rs"]
|
|
||||||
//mod _World;
|
|
||||||
//pub use self::_World::*;
|
|
||||||
|
|
||||||
pub const ADDRESS_COUNT: usize = 256;
|
|
||||||
pub const REGISTER_COUNT: usize = 16;
|
|
||||||
|
|
||||||
pub struct Machine {
|
|
||||||
pub program: usize,
|
|
||||||
pub registers: [u8; REGISTER_COUNT],
|
|
||||||
pub memory: [u8; ADDRESS_COUNT],
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Machine {
|
|
||||||
/// Create a machine with program counter.
|
|
||||||
pub fn New(pc: u16) -> Self {
|
|
||||||
Self {
|
|
||||||
program: pc as usize,
|
|
||||||
registers: [0; REGISTER_COUNT],
|
|
||||||
memory: [0; ADDRESS_COUNT],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn LoadProgram(&mut self, buffer: &[u8], offset: u16) {
|
|
||||||
let mut i = offset as usize;
|
|
||||||
|
|
||||||
for elem in buffer.to_vec().drain(..) {
|
|
||||||
self.memory[i] = elem;
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
|
||||||
pub fn Execute(mut self) {
|
|
||||||
let mut running = true;
|
|
||||||
|
|
||||||
while running {
|
|
||||||
self.PrintMemory();
|
|
||||||
//self.PrintRegisters();
|
|
||||||
|
|
||||||
let opcode = self.memory[self.program];
|
|
||||||
|
|
||||||
running = match opcode {
|
|
||||||
NOP => Nothing(&mut self),
|
|
||||||
LDR => LoadRegister(&mut self),
|
|
||||||
SVR => SaveRegister(&mut self),
|
|
||||||
//MOV
|
|
||||||
ADD => Add(&mut self),
|
|
||||||
ADD_ASSIGN => AddAssign(&mut self),
|
|
||||||
SUB => Subtract(&mut self),
|
|
||||||
SUB_ASSIGN => SubtractAssign(&mut self),
|
|
||||||
MUL => Multiply(&mut self),
|
|
||||||
MUL_ASSIGN => MultiplyAssign(&mut self),
|
|
||||||
DIV => Divide(&mut self),
|
|
||||||
DIV_ASSIGN => DivideAssign(&mut self),
|
|
||||||
REM => Remainder(&mut self),
|
|
||||||
REM_ASSIGN => RemainderAssign(&mut self),
|
|
||||||
//NEG
|
|
||||||
AND => And(&mut self),
|
|
||||||
AND_ASSIGN => AndAssign(&mut self),
|
|
||||||
OR => Or(&mut self),
|
|
||||||
OR_ASSIGN => OrAssign(&mut self),
|
|
||||||
XOR => Xor(&mut self),
|
|
||||||
XOR_ASSIGN => XorAssign(&mut self),
|
|
||||||
NOT => Xor(&mut self),
|
|
||||||
SHL => ShiftLeft(&mut self),
|
|
||||||
SHL_ASSIGN => ShiftLeftAssign(&mut self),
|
|
||||||
SHR => ShiftRight(&mut self),
|
|
||||||
SHR_ASSIGN => ShiftRightAssign(&mut self),
|
|
||||||
EQ => Equals(&mut self),
|
|
||||||
NEQ => NotEquals(&mut self),
|
|
||||||
LT => LessThan(&mut self),
|
|
||||||
LE => LessEquals(&mut self),
|
|
||||||
GT => GreaterThan(&mut self),
|
|
||||||
GE => GreaterEquals(&mut self),
|
|
||||||
HLT => Halt(&mut self),
|
|
||||||
_ => Nothing(&mut self),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn PrintRegisters(&self) {
|
|
||||||
for data in self.registers.iter() {
|
|
||||||
print!("{:02x} ", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn PrintMemory(&self) {
|
|
||||||
let mut address = 0;
|
|
||||||
|
|
||||||
for data in self.memory.iter() {
|
|
||||||
if address % 8 == 0 {
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
print!("{:02x} ", data);
|
|
||||||
|
|
||||||
address += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
println!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetRegister(&self, register: usize) -> u8 {
|
|
||||||
self.registers[register]
|
|
||||||
}
|
|
||||||
|
|
||||||
fn GetProgramCounter(&self) -> u16 {
|
|
||||||
self.program as u16
|
|
||||||
}
|
|
||||||
|
|
||||||
fn SetProgramCounter(&mut self, pc: u16) {
|
|
||||||
self.program = pc as usize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user