mirror of
https://github.com/guilhermewerner/machine
synced 2025-06-15 04:34:19 +00:00
Simple 8 bits operations
This commit is contained in:
@ -12,3 +12,6 @@ name = "Machine"
|
||||
crate-type = ["rlib"]
|
||||
path = "Source/lib.rs"
|
||||
|
||||
[[example]]
|
||||
name = "Simple"
|
||||
path = "Examples/Simple.rs"
|
||||
|
BIN
Examples/Simple.bin
Normal file
BIN
Examples/Simple.bin
Normal file
Binary file not shown.
14
Examples/Simple.rs
Normal file
14
Examples/Simple.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use ::Machine::*;
|
||||
use std::fs;
|
||||
|
||||
fn main() {
|
||||
let mut vm = Machine::New(0x00);
|
||||
|
||||
let bytecode = fs::read("Examples/Simple.bin").unwrap();
|
||||
|
||||
vm.LoadProgram(&bytecode, 0x00);
|
||||
|
||||
vm.Execute();
|
||||
}
|
326
Source/Instructions.rs
Normal file
326
Source/Instructions.rs
Normal file
@ -0,0 +1,326 @@
|
||||
use crate::Machine;
|
||||
|
||||
pub fn Nothing(vm: &mut Machine) -> bool {
|
||||
vm.program += 1;
|
||||
false
|
||||
}
|
||||
|
||||
pub fn LoadRegister(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1];
|
||||
let a = vm.memory[vm.program + 2];
|
||||
|
||||
vm.registers[r as usize] = vm.memory[a as usize];
|
||||
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn SaveRegister(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1];
|
||||
let a = vm.memory[vm.program + 2];
|
||||
|
||||
vm.memory[a as usize] = vm.registers[r as usize];
|
||||
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Move(vm: &mut Machine) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn Add(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn AddAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] += a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Subtract(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn SubtractAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] -= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Multiply(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn MultiplyAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] *= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Divide(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn DivideAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] /= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Remainder(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn RemainderAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] %= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Neg(vm: &mut Machine) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub fn And(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn AndAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] &= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Or(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn OrAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] |= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Xor(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn XorAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] ^= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Not(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] = !a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn ShiftLeft(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn ShiftLeftAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] <<= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn ShiftRight(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn ShiftRightAssign(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
let a = vm.registers[vm.memory[vm.program + 2] as usize];
|
||||
|
||||
vm.registers[r] >>= a;
|
||||
vm.program += 3;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Equals(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn NotEquals(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn LessThan(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn LessEquals(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn GreaterThan(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn GreaterEquals(vm: &mut Machine) -> bool {
|
||||
let r = vm.memory[vm.program + 1] as usize;
|
||||
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;
|
||||
vm.program += 4;
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
pub fn Halt(vm: &mut Machine) -> bool {
|
||||
false
|
||||
}
|
230
Source/Operations.rs
Normal file
230
Source/Operations.rs
Normal file
@ -0,0 +1,230 @@
|
||||
/// **0x00** - No operation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// nop
|
||||
/// ```
|
||||
pub const NOP: u8 = 0x00;
|
||||
|
||||
/// **0x01** - Load register from memory.
|
||||
///
|
||||
/// ```no_run
|
||||
/// ldr r1 0050 // r1 = mem[0050]
|
||||
/// ```
|
||||
pub const LDR: u8 = 0x01;
|
||||
|
||||
/// **0x02** - Save register in memory.
|
||||
///
|
||||
/// ```no_run
|
||||
/// svr 0050 r1 // mem[0050] = r1
|
||||
/// ```
|
||||
pub const SVR: u8 = 0x02;
|
||||
|
||||
/// **0x03** - Move register.
|
||||
///
|
||||
/// ```no_run
|
||||
/// mov r1 r2 // r1 = r2
|
||||
/// ```
|
||||
pub const MOV: u8 = 0x03;
|
||||
|
||||
/// **0x04** - The addition operator `+`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// add r1 r2 r3 // r1 = r2 + r3
|
||||
/// ```
|
||||
pub const ADD: u8 = 0x04;
|
||||
|
||||
/// **0x05** - The addition assignment operator `+=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// add r1 r2 // r1 += r2
|
||||
/// ```
|
||||
pub const ADD_ASSIGN: u8 = 0x05;
|
||||
|
||||
/// **0x06** - The subtraction operator `-`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// sub r1 r2 r3 // r1 = r2 - r3
|
||||
/// ```
|
||||
pub const SUB: u8 = 0x06;
|
||||
|
||||
/// **0x07** - The subtraction assignment operator `-=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// sub r1 r2 // r1 -= r2
|
||||
/// ```
|
||||
pub const SUB_ASSIGN: u8 = 0x07;
|
||||
|
||||
/// **0x08** - The multiplication operator `*`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// mul r1 r2 r3 // r1 = r2 * r3
|
||||
/// ```
|
||||
pub const MUL: u8 = 0x08;
|
||||
|
||||
/// **0x09** - The multiplication assignment operator `*=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// mul r1 r2 // r1 *= r2
|
||||
/// ```
|
||||
pub const MUL_ASSIGN: u8 = 0x09;
|
||||
|
||||
/// **0x0A** - The division operator `/`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// div r1 r2 r3 // r1 = r2 / r3
|
||||
/// ```
|
||||
pub const DIV: u8 = 0x0A;
|
||||
|
||||
/// **0x0B** - The division assignment operator `/=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// div r1 r2 // r1 /= r2
|
||||
/// ```
|
||||
pub const DIV_ASSIGN: u8 = 0x0B;
|
||||
|
||||
/// **0x0C** - The remainder operator `%`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// rem r1 r2 r3 // r1 = r2 % r3
|
||||
/// ```
|
||||
pub const REM: u8 = 0x0C;
|
||||
|
||||
/// **0x0D** - The remainder assignment operator `%=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// rem r1 r2 // r1 %= r2
|
||||
/// ```
|
||||
pub const REM_ASSIGN: u8 = 0x0D;
|
||||
|
||||
/// **0x0E** - Arithmetic negation `-`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// not r1 r2 // r1 = -r2
|
||||
/// ```
|
||||
pub const NEG: u8 = 0x0E;
|
||||
|
||||
/// **0x0F** -The bitwise AND operator `&`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// and r1 r2 r3 // r1 = r2 & r3
|
||||
/// ```
|
||||
pub const AND: u8 = 0x0F;
|
||||
|
||||
/// **0x10** - The bitwise AND assignment operator `&=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// and r1 r2 // r1 &= r2
|
||||
/// ```
|
||||
pub const AND_ASSIGN: u8 = 0x10;
|
||||
|
||||
/// **0x11** - The bitwise OR operator `|`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// or r1 r2 r3 // r1 = r2 | r3
|
||||
/// ```
|
||||
pub const OR: u8 = 0x11;
|
||||
|
||||
/// **0x12** - The bitwise OR assignment operator `|=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// or r1 r2 // r1 |= r2
|
||||
/// ```
|
||||
pub const OR_ASSIGN: u8 = 0x12;
|
||||
|
||||
/// **0x13** - The bitwise XOR operator `^`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// xor r1 r2 r3 // r1 = r2 ^ r3
|
||||
/// ```
|
||||
pub const XOR: u8 = 0x13;
|
||||
|
||||
/// **0x14** - The bitwise XOR assignment operator `^=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// xor r1 r2 // r1 ^= r2
|
||||
/// ```
|
||||
pub const XOR_ASSIGN: u8 = 0x14;
|
||||
|
||||
/// **0x15** - Logical negation `!`
|
||||
///
|
||||
/// ```no_run
|
||||
/// not r1 r2 // r1 = !r2
|
||||
/// ```
|
||||
pub const NOT: u8 = 0x15;
|
||||
|
||||
/// **0x16** - The left shift operator `<<`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// shl r1 r2 r3 // r1 = r2 << r3
|
||||
/// ```
|
||||
pub const SHL: u8 = 0x16;
|
||||
|
||||
/// **0x17** - The left shift assignment operator `<<=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// shl r1 r2 // r1 <<= r2
|
||||
/// ```
|
||||
pub const SHL_ASSIGN: u8 = 0x17;
|
||||
|
||||
/// **0x18** - The right shift operator `>>`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// shr r1 r2 r3 // r1 = r2 >> r3
|
||||
/// ```
|
||||
pub const SHR: u8 = 0x18;
|
||||
|
||||
/// **0x19** - The right shift assignment operator `>>=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// shr r1 r2 // r1 >>= r2
|
||||
/// ```
|
||||
pub const SHR_ASSIGN: u8 = 0x19;
|
||||
|
||||
/// **0x1A** - The equality operator `==`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// eq r1 r2 r3 // r1 = r2 == r3
|
||||
/// ```
|
||||
pub const EQ: u8 = 0x1A;
|
||||
|
||||
/// **0x1B** - The inequality operator `!=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// neq r1 r2 r3 // r1 = r2 != r3
|
||||
/// ```
|
||||
pub const NEQ: u8 = 0x1B;
|
||||
|
||||
/// **0x1C** - The less than operator `<`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// lt r1 r2 r3 // r1 = r2 < r3
|
||||
/// ```
|
||||
pub const LT: u8 = 0x1C;
|
||||
|
||||
/// **0x1D** - The less than or equal to operator `<=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// le r1 r2 r3 // r1 = r2 <= r3
|
||||
/// ```
|
||||
pub const LE: u8 = 0x1D;
|
||||
|
||||
/// **0x1E** - The greater than operator `>`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// gt r1 r2 r3 // r1 = r2 > r3
|
||||
/// ```
|
||||
pub const GT: u8 = 0x1E;
|
||||
|
||||
/// **0x1F** - The greater than or equal to operator `>=`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// ge r1 r2 r3 // r1 = r2 >= r3
|
||||
/// ```
|
||||
pub const GE: u8 = 0x1F;
|
||||
|
||||
/// **0xFF** - Halt execution.
|
||||
///
|
||||
/// ```no_run
|
||||
/// hlt
|
||||
/// ```
|
||||
pub const HLT: u8 = 0xFF;
|
47
Source/Registers.rs
Normal file
47
Source/Registers.rs
Normal file
@ -0,0 +1,47 @@
|
||||
/// **0x00** - r0
|
||||
pub const REGISTER_0: u8 = 0x00;
|
||||
|
||||
/// **0x01** - r1
|
||||
pub const REGISTER_1: u8 = 0x01;
|
||||
|
||||
/// **0x02** - r2
|
||||
pub const REGISTER_2: u8 = 0x02;
|
||||
|
||||
/// **0x03** - r3
|
||||
pub const REGISTER_3: u8 = 0x03;
|
||||
|
||||
/// **0x04** - r4
|
||||
pub const REGISTER_4: u8 = 0x04;
|
||||
|
||||
/// **0x05** - r5
|
||||
pub const REGISTER_5: u8 = 0x05;
|
||||
|
||||
/// **0x06** - r6
|
||||
pub const REGISTER_6: u8 = 0x06;
|
||||
|
||||
/// **0x07** - r7
|
||||
pub const REGISTER_7: u8 = 0x07;
|
||||
|
||||
/// **0x08** - r8
|
||||
pub const REGISTER_8: u8 = 0x08;
|
||||
|
||||
/// **0x09** - r9
|
||||
pub const REGISTER_9: u8 = 0x09;
|
||||
|
||||
/// **0x10** - r10
|
||||
pub const REGISTER_10: u8 = 0x10;
|
||||
|
||||
/// **0x11** - r11
|
||||
pub const REGISTER_11: u8 = 0x11;
|
||||
|
||||
/// **0x12** - r12
|
||||
pub const REGISTER_12: u8 = 0x12;
|
||||
|
||||
/// **0x13** - r13
|
||||
pub const REGISTER_13: u8 = 0x13;
|
||||
|
||||
/// **0x14** - r14
|
||||
pub const REGISTER_14: u8 = 0x14;
|
||||
|
||||
/// **0x15** - r15
|
||||
pub const REGISTER_15: u8 = 0x15;
|
317
Source/lib.rs
317
Source/lib.rs
@ -1,201 +1,130 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(unused_imports)]
|
||||
#![allow(unused_variables)]
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, TryFromPrimitive)]
|
||||
pub enum Instruction {
|
||||
/// **0x00** - No operation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// nop
|
||||
/// ```
|
||||
Nop = 0x00,
|
||||
pub mod Instructions;
|
||||
pub mod Operations;
|
||||
pub mod Registers;
|
||||
|
||||
/// **0x01** - Load register from memory.
|
||||
///
|
||||
/// ```no_run
|
||||
/// ldr r1 0050 // r1 = mem[0050]
|
||||
/// ```
|
||||
Ldr = 0x01,
|
||||
use Instructions::*;
|
||||
use Operations::*;
|
||||
use Registers::*;
|
||||
|
||||
/// **0x02** - Store register in memory.
|
||||
///
|
||||
/// ```no_run
|
||||
/// str 0050 r1 // mem[0050] = r1
|
||||
/// ```
|
||||
Str = 0x02,
|
||||
//#[path = "World.rs"]
|
||||
//mod _World;
|
||||
//pub use self::_World::*;
|
||||
|
||||
/// **0x03** - Move register.
|
||||
///
|
||||
/// ```no_run
|
||||
/// mov r1 r2 // r1 = r2
|
||||
/// ```
|
||||
Mov = 0x03,
|
||||
pub const ADDRESS_COUNT: usize = 256;
|
||||
pub const REGISTER_COUNT: usize = 16;
|
||||
|
||||
/// **0x04** - Arithmetic addition `+`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// add r1 r2 r3 // r1 = r2 + r3
|
||||
/// ```
|
||||
Add = 0x04,
|
||||
|
||||
/// **0x05** - Add with carry.
|
||||
///
|
||||
/// ```no_run
|
||||
/// adc r1 r2 r3 r4 // r1 = r2 + r3 + r4
|
||||
/// ```
|
||||
Adc = 0x05,
|
||||
|
||||
/// **0x06** - Arithmetic subtraction `-`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// sub r1 r2 r3 // r1 = r2 - r3
|
||||
/// ```
|
||||
Sub = 0x06,
|
||||
|
||||
/// **0x07** - Subtract with carry.
|
||||
///
|
||||
/// ```no_run
|
||||
/// sbc r1 r2 r3 r4 // r1 = r2 - r3 - 1 - r4
|
||||
/// ```
|
||||
Sbc = 0x07,
|
||||
|
||||
/// **0x08** - Arithmetic multiplication `*`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// mul r1 r2 r3 // r1 = r2 * r3
|
||||
/// ```
|
||||
Mul = 0x08,
|
||||
|
||||
/// **0x09** - Arithmetic division `/`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// div r1 r2 r3 // r1 = r2 / r3
|
||||
/// ```
|
||||
Div = 0x09,
|
||||
|
||||
/// **0x0A** - Arithmetic remainder `/`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// rem r1 r2 r3 // r1 = r2 % r3
|
||||
/// ```
|
||||
Rem = 0x0A,
|
||||
|
||||
/// **0x0B** - Arithmetic negation `-`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// not r1 r2 // r1 = -r2
|
||||
/// ```
|
||||
Neg = 0x0B,
|
||||
|
||||
/// **0x0C** - Bitwise AND `&`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// and r1 r2 r3 // r1 = r2 & r3
|
||||
/// ```
|
||||
And = 0x0C,
|
||||
|
||||
/// **0x0D** - Bitwise OR `|`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// or r1 r2 r3 // r1 = r2 | r3
|
||||
/// ```
|
||||
Or = 0x0D,
|
||||
|
||||
/// **0x0E** - Bitwise XOR `^`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// xor r1 r2 r3 // r1 = r2 ^ r3
|
||||
/// ```
|
||||
Xor = 0x0E,
|
||||
|
||||
/// **0x0F** - Logical negation `!`
|
||||
///
|
||||
/// ```no_run
|
||||
/// not r1 r2 // r1 = !r2
|
||||
/// ```
|
||||
Not = 0x0F,
|
||||
|
||||
/// **0x10** - Bitwise NAND.
|
||||
///
|
||||
/// ```no_run
|
||||
/// nand r1 r2 r3 // r1 = !(r2 & r3)
|
||||
/// ```
|
||||
Nand = 0x10,
|
||||
|
||||
/// **0x11** - Bitwise NOR.
|
||||
///
|
||||
/// ```no_run
|
||||
/// nor r1 r2 r3 // r1 = !(r2 | r3)
|
||||
/// ```
|
||||
Nor = 0x11,
|
||||
|
||||
/// **0x12** - Bitwise XNOR.
|
||||
///
|
||||
/// ```no_run
|
||||
/// xnor r1 r2 r3 // r1 = !(r2 ^ r3)
|
||||
/// ```
|
||||
Xnor = 0x12,
|
||||
|
||||
/// **0x13** - Shift left `<<`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// shl r1 r2 r3 // r1 = r2 << r3
|
||||
/// ```
|
||||
Shl = 0x13,
|
||||
|
||||
/// **0x14** - Shift right `>>`.
|
||||
///
|
||||
/// ```no_run
|
||||
/// shr r1 r2 r3 // r1 = r2 >> r3
|
||||
/// ```
|
||||
Shr = 0x14,
|
||||
|
||||
/// **0x15** - Equality comparation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// eq r1 r2 r3 // r1 = r2 == r3
|
||||
/// ```
|
||||
Eq = 0x15,
|
||||
|
||||
/// **0x16** - Inequality comparation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// neq r1 r2 r3 // r1 = r2 != r3
|
||||
/// ```
|
||||
Neq = 0x16,
|
||||
|
||||
/// **0x17** - Less comparation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// lt r1 r2 r3 // r1 = r2 < r3
|
||||
/// ```
|
||||
Lt = 0x17,
|
||||
|
||||
/// **0x18** - Less-equal comparation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// le r1 r2 r3 // r1 = r2 <= r3
|
||||
/// ```
|
||||
Le = 0x18,
|
||||
|
||||
/// **0x19** - Greater comparation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// gt r1 r2 r3 // r1 = r2 > r3
|
||||
/// ```
|
||||
Gt = 0x19,
|
||||
|
||||
/// **0x1A** - Greater-equal comparation.
|
||||
///
|
||||
/// ```no_run
|
||||
/// ge r1 r2 r3 // r1 = r2 >= r3
|
||||
/// ```
|
||||
Ge = 0x1A,
|
||||
|
||||
/// **0xFF** - Halt execution.
|
||||
///
|
||||
/// ```no_run
|
||||
/// hlt
|
||||
/// ```
|
||||
Hlt = 0xFF,
|
||||
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