This commit is contained in:
Werner
2021-11-19 17:55:40 -03:00
parent 8b7501fb91
commit ae70b9db3d
11 changed files with 409 additions and 324 deletions

View File

@ -1,34 +1,28 @@
use crate::Machine;
pub fn Nothing(vm: &mut Machine) -> bool {
vm.WalkAddress(1);
vm.Next();
true
}
pub fn LoadRegister(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let addr = vm.ReadWord(None);
let val = vm.ReadWord(Some(addr));
let reg = vm.GetMemory(pc + 1);
let addr = vm.GetMemory(pc + 2);
let val = vm.GetMemory(addr);
vm.SetRegister(reg, val);
vm.WalkAddress(3);
vm.registry.Set(reg, val);
vm.Walk(5);
true
}
pub fn SaveRegister(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let addr = vm.ReadWord(None);
let reg = vm.ReadByte(None);
let val = vm.registry.Get(reg);
let addr = vm.GetMemory(pc + 1);
let reg = vm.GetMemory(pc + 2);
let val = vm.GetRegister(reg);
vm.SetMemory(addr, val);
vm.WalkAddress(3);
vm.WriteWord(Some(addr), val);
vm.Walk(5);
true
}
@ -39,136 +33,131 @@ pub fn Move(_vm: &mut Machine) -> bool {
}
pub fn Add(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 + op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 + op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn AddAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 + op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 + op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Subtract(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 - op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 - op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn SubtractAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 - op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 - op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Multiply(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 * op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 * op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn MultiplyAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 * op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 * op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Divide(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 / op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 / op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn DivideAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 / op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 / op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Remainder(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 % op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 % op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn RemainderAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 % op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 % op2).to_be_bytes());
vm.Walk(2);
true
}
@ -179,220 +168,217 @@ pub fn Neg(_vm: &mut Machine) -> bool {
}
pub fn And(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 & op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 & op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn AndAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 & op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 & op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Or(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 | op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 | op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn OrAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 | op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 | op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Xor(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, op1 ^ op2);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 ^ op2).to_be_bytes());
vm.Walk(3);
true
}
pub fn XorAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
let op2 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, op1 ^ op2);
vm.WalkAddress(3);
vm.registry.Set(reg1, (op1 ^ op2).to_be_bytes());
vm.Walk(2);
true
}
pub fn Not(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let op = u32::from_be_bytes(vm.registry.Get(reg));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
vm.SetRegister(reg, !op1);
vm.WalkAddress(3);
vm.registry.Set(reg, (!op).to_be_bytes());
vm.Walk(2);
true
}
pub fn ShiftLeft(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
vm.SetRegister(reg, op1 << 1);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 << 1).to_be_bytes());
vm.Walk(3);
true
}
pub fn ShiftLeftAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
vm.SetRegister(reg, op1 << 1);
vm.WalkAddress(2);
vm.registry.Set(reg1, (op1 << 1).to_be_bytes());
vm.Walk(2);
true
}
pub fn ShiftRight(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
vm.SetRegister(reg, op1 >> 1);
vm.WalkAddress(4);
vm.registry.Set(reg, (op1 >> 1).to_be_bytes());
vm.Walk(3);
true
}
pub fn ShiftRightAssign(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(reg);
vm.SetRegister(reg, op1 >> 1);
vm.WalkAddress(2);
vm.registry.Set(reg1, (op1 >> 1).to_be_bytes());
vm.Walk(2);
true
}
pub fn Equals(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, (op1 == op2) as u8);
vm.WalkAddress(4);
vm.registry.Set(reg, ((op1 == op2) as u32).to_be_bytes());
vm.Walk(3);
true
}
pub fn NotEquals(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, (op1 != op2) as u8);
vm.WalkAddress(4);
vm.registry.Set(reg, ((op1 != op2) as u32).to_be_bytes());
vm.Walk(3);
true
}
pub fn LessThan(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, (op1 < op2) as u8);
vm.WalkAddress(4);
vm.registry.Set(reg, ((op1 < op2) as u32).to_be_bytes());
vm.Walk(3);
true
}
pub fn LessEquals(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, (op1 <= op2) as u8);
vm.WalkAddress(4);
vm.registry.Set(reg, ((op1 <= op2) as u32).to_be_bytes());
vm.Walk(3);
true
}
pub fn GreaterThan(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, (op1 > op2) as u8);
vm.WalkAddress(4);
vm.registry.Set(reg, ((op1 > op2) as u32).to_be_bytes());
vm.Walk(3);
true
}
pub fn GreaterEquals(vm: &mut Machine) -> bool {
let pc = vm.GetAddress();
let reg = vm.ReadByte(None);
let reg = vm.GetMemory(pc + 1);
let op1 = vm.GetRegister(vm.GetMemory(pc + 2));
let op2 = vm.GetRegister(vm.GetMemory(pc + 3));
let reg1 = vm.ReadByte(None);
let op1 = u32::from_be_bytes(vm.registry.Get(reg1));
let reg2 = vm.ReadByte(None);
let op2 = u32::from_be_bytes(vm.registry.Get(reg2));
vm.SetRegister(reg, (op1 >= op2) as u8);
vm.WalkAddress(4);
vm.registry.Set(reg, ((op1 >= op2) as u32).to_be_bytes());
vm.Walk(3);
true
}

5
Source/Limits.rs Normal file
View File

@ -0,0 +1,5 @@
pub const REGISTER_COUNT: usize = 16;
pub const STACK_SIZE: usize = 64;
pub const HEAP_LIMIT: usize = 256;

View File

@ -1,33 +1,36 @@
use std::panic;
use crate::Instructions::*;
use crate::Operations::*;
use crate::Types::*;
use crate::{Memory, Registry, Stack, HEAP_LIMIT, STACK_SIZE};
pub const ADDRESS_COUNT: usize = 256;
pub const REGISTER_COUNT: usize = 16;
#[allow(dead_code)]
pub struct Machine {
program: usize,
registers: [u8; REGISTER_COUNT],
memory: [u8; ADDRESS_COUNT],
pub(crate) program_counter: usize,
pub(crate) registry: Registry,
pub(crate) stack_pointer: usize,
pub(crate) link_register: usize,
pub(crate) stack: Stack,
pub(crate) memory_pointer: usize,
pub(crate) heap: Memory,
}
#[allow(dead_code)]
impl Machine {
/// Create a machine with program counter.
pub fn New(pc: u8) -> Self {
pub fn New(address: Word) -> Self {
Self {
program: pc as usize,
registers: [0; REGISTER_COUNT],
memory: [0; ADDRESS_COUNT],
program_counter: u32::from_be_bytes(address) as usize,
registry: Registry::default(),
stack_pointer: 0,
link_register: 0,
stack: Stack::New(STACK_SIZE),
memory_pointer: 0,
heap: Memory::New(HEAP_LIMIT),
}
}
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 LoadProgram(&mut self, buffer: &[u8]) {
for (addr, data) in buffer.to_vec().drain(..).enumerate() {
self.heap.WriteByte(addr as u32, data);
}
}
@ -35,10 +38,10 @@ impl Machine {
let mut running = true;
while running {
//self.PrintMemory();
self.PrintRegisters();
self.registry.Print();
let opcode = self.memory[self.program];
let opcode = self.heap.ReadByte(self.program_counter as u32);
self.memory_pointer = self.program_counter + 1;
running = match opcode {
NOP => Nothing(&mut self),
@ -79,77 +82,55 @@ impl Machine {
}
}
#[allow(dead_code)]
fn PrintRegisters(&self) {
for data in self.registers.iter() {
print!("{:02x} ", data);
pub(crate) fn ReadByte(&mut self, addr: Option<Word>) -> Byte {
let mut mp = self.memory_pointer as u32;
if let Some(addr) = addr {
mp = u32::from_be_bytes(addr);
}
println!();
self.memory_pointer = (mp + 1) as usize;
self.heap.ReadByte(mp)
}
#[allow(dead_code)]
fn PrintMemory(&self) {
let mut address = 0;
pub(crate) fn WriteByte(&mut self, addr: Option<Word>, value: Byte) {
let mut mp = self.memory_pointer as u32;
for data in self.memory.iter() {
if address % 8 == 0 {
println!();
}
if let Some(addr) = addr {
mp = u32::from_be_bytes(addr);
};
print!("{:02x} ", data);
self.memory_pointer = (mp + 1) as usize;
self.heap.WriteByte(mp, value);
}
address += 1;
pub(crate) fn ReadWord(&mut self, addr: Option<Word>) -> Word {
let mut mp = self.memory_pointer as u32;
if let Some(addr) = addr {
mp = u32::from_be_bytes(addr);
}
println!();
self.memory_pointer = (mp + 4) as usize;
self.heap.ReadWord(mp as u32)
}
pub fn GetMemory(&self, addr: u8) -> u8 {
let index = addr as usize;
pub(crate) fn WriteWord(&mut self, addr: Option<Word>, value: Word) {
let mut mp = self.memory_pointer as u32;
if index < ADDRESS_COUNT {
self.memory[index]
} else {
panic!("Invalid Address!")
if let Some(addr) = addr {
mp = u32::from_be_bytes(addr);
}
self.memory_pointer = (mp + 4) as usize;
self.heap.WriteWord(mp as u32, value);
}
pub fn SetMemory(&mut self, addr: u8, val: u8) {
let index = addr as usize;
if index < ADDRESS_COUNT {
self.memory[index] = val;
}
pub(crate) fn Next(&mut self) {
self.program_counter += 1;
}
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;
pub(crate) fn Walk(&mut self, bytes: Byte) {
self.program_counter += bytes as usize;
}
}

56
Source/Memory.rs Normal file
View File

@ -0,0 +1,56 @@
use crate::Types::*;
use std::mem;
pub struct Memory {
storage: Vec<u8>,
capacity: usize,
}
impl Memory {
pub fn New(limit: usize) -> Self {
Self {
storage: Vec::with_capacity(limit),
capacity: limit,
}
}
pub fn Flush(&mut self) {
self.storage.clear();
}
pub fn ReadByte(&mut self, addr: u32) -> Byte {
let index = addr as usize;
*self.storage.get(index).unwrap()
}
pub fn WriteByte(&mut self, addr: u32, value: Byte) {
let index = addr as usize;
if index < self.capacity {
self.storage.push(value);
}
}
pub fn ReadWord(&mut self, addr: u32) -> Word {
let mut index = addr as usize;
const BYTES: usize = mem::size_of::<Word>();
let mut buffer = [0; BYTES];
for i in 0..BYTES {
buffer[i] = *self.storage.get(index).unwrap_or(&0);
index += 1;
}
buffer
}
pub fn WriteWord(&mut self, addr: u32, value: Word) {
let index = addr as usize;
if index < self.capacity {
self.storage.extend(value);
}
}
}

View File

@ -1,47 +0,0 @@
/// **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;

35
Source/Registry.rs Normal file
View File

@ -0,0 +1,35 @@
use crate::Types::*;
use crate::REGISTER_COUNT;
#[derive(Default)]
pub struct Registry {
registers: [Word; REGISTER_COUNT],
}
impl Registry {
pub fn Get(&mut self, index: u8) -> Word {
let index = index as usize;
if index < REGISTER_COUNT {
self.registers[index]
} else {
panic!("Invalid Register!")
}
}
pub fn Set(&mut self, index: u8, value: Word) {
let index = index as usize;
if index < REGISTER_COUNT {
self.registers[index] = value;
}
}
pub(crate) fn Print(&self) {
for r in self.registers.iter() {
print!("{:02X}{:02X}{:02X}{:02X} ", r[0], r[1], r[2], r[3]);
}
println!();
}
}

50
Source/Stack.rs Normal file
View File

@ -0,0 +1,50 @@
use crate::Types::*;
use std::mem;
pub struct Stack {
storage: Vec<u8>,
capacity: usize,
}
impl Stack {
pub fn New(size: usize) -> Self {
Self {
storage: Vec::with_capacity(size),
capacity: size,
}
}
pub fn Flush(&mut self) {
self.storage.clear();
}
pub fn PushByte(&mut self, item: Byte) {
if self.storage.len() + 1 < self.capacity {
self.storage.push(item);
}
}
pub fn PopByte(&mut self) -> Byte {
self.storage.pop().unwrap_or(0)
}
pub fn PushWord(&mut self, item: Word) {
const BYTES: usize = mem::size_of::<Word>();
if self.storage.len() + BYTES < self.capacity {
self.storage.extend(item);
}
}
pub fn PopWord(&mut self) -> Word {
const BYTES: usize = mem::size_of::<Word>();
let mut buffer = [0; BYTES];
for i in 0..BYTES {
buffer[i] = self.storage.pop().unwrap_or(0);
}
buffer
}
}

5
Source/Types.rs Normal file
View File

@ -0,0 +1,5 @@
/// Canonical byte type.
pub type Byte = u8;
/// Canonical data and address type.
pub type Word = [u8; 4];

View File

@ -1,9 +1,26 @@
#![allow(non_snake_case)]
mod Instructions;
pub mod Operations;
pub mod Registers;
pub mod Types;
#[path = "Limits.rs"]
mod _Limits;
pub use self::_Limits::*;
#[path = "Machine.rs"]
mod _Machine;
pub use self::_Machine::*;
#[path = "Memory.rs"]
mod _Memory;
pub use self::_Memory::*;
#[path = "Registry.rs"]
mod _Registry;
pub use self::_Registry::*;
#[path = "Stack.rs"]
mod _Stack;
pub use self::_Stack::*;