From ae70b9db3dd7b46e9845717a934008ab57693d84 Mon Sep 17 00:00:00 2001 From: Werner Date: Fri, 19 Nov 2021 17:55:40 -0300 Subject: [PATCH] 32 bits --- Examples/Simple.bin | Bin 256 -> 272 bytes Examples/Simple.rs | 9 +- Source/Instructions.rs | 372 ++++++++++++++++++++--------------------- Source/Limits.rs | 5 + Source/Machine.rs | 135 +++++++-------- Source/Memory.rs | 56 +++++++ Source/Registers.rs | 47 ------ Source/Registry.rs | 35 ++++ Source/Stack.rs | 50 ++++++ Source/Types.rs | 5 + Source/lib.rs | 19 ++- 11 files changed, 409 insertions(+), 324 deletions(-) create mode 100644 Source/Limits.rs create mode 100644 Source/Memory.rs delete mode 100644 Source/Registers.rs create mode 100644 Source/Registry.rs create mode 100644 Source/Stack.rs create mode 100644 Source/Types.rs diff --git a/Examples/Simple.bin b/Examples/Simple.bin index c5c118df323d1f36c99a3c250f63e53b52991c61..3c37ff3237f115ef5b8fc6a29db44dd695bce03c 100644 GIT binary patch literal 272 scmZQ%0D=G}AmPBk$PA=HSlAgrG?Cyxs=EJzw@d`rx~z3U6&^Y~0MK;?3IG5A literal 256 fcmZQ%NMK}4WMN`pWJ+TC&p>q`6i#&`scIkqUN-`o diff --git a/Examples/Simple.rs b/Examples/Simple.rs index 87be950..57d49b7 100644 --- a/Examples/Simple.rs +++ b/Examples/Simple.rs @@ -4,11 +4,8 @@ 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); - + let mut vm = Machine::New([0, 0, 0, 0]); + let code = fs::read("Examples/Simple.bin").unwrap(); + vm.LoadProgram(&code); vm.Execute(); } diff --git a/Source/Instructions.rs b/Source/Instructions.rs index 3d9afdb..c4ecb1a 100644 --- a/Source/Instructions.rs +++ b/Source/Instructions.rs @@ -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 } diff --git a/Source/Limits.rs b/Source/Limits.rs new file mode 100644 index 0000000..99f1412 --- /dev/null +++ b/Source/Limits.rs @@ -0,0 +1,5 @@ +pub const REGISTER_COUNT: usize = 16; + +pub const STACK_SIZE: usize = 64; + +pub const HEAP_LIMIT: usize = 256; diff --git a/Source/Machine.rs b/Source/Machine.rs index d55efd4..a489229 100644 --- a/Source/Machine.rs +++ b/Source/Machine.rs @@ -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) -> 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, 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 { + 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, 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; } } diff --git a/Source/Memory.rs b/Source/Memory.rs new file mode 100644 index 0000000..4440b6f --- /dev/null +++ b/Source/Memory.rs @@ -0,0 +1,56 @@ +use crate::Types::*; +use std::mem; + +pub struct Memory { + storage: Vec, + 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::(); + 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); + } + } +} + diff --git a/Source/Registers.rs b/Source/Registers.rs deleted file mode 100644 index d36a0b2..0000000 --- a/Source/Registers.rs +++ /dev/null @@ -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; diff --git a/Source/Registry.rs b/Source/Registry.rs new file mode 100644 index 0000000..0b37335 --- /dev/null +++ b/Source/Registry.rs @@ -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!(); + } +} diff --git a/Source/Stack.rs b/Source/Stack.rs new file mode 100644 index 0000000..546fdc0 --- /dev/null +++ b/Source/Stack.rs @@ -0,0 +1,50 @@ +use crate::Types::*; +use std::mem; + +pub struct Stack { + storage: Vec, + 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::(); + + if self.storage.len() + BYTES < self.capacity { + self.storage.extend(item); + } + } + + pub fn PopWord(&mut self) -> Word { + const BYTES: usize = mem::size_of::(); + let mut buffer = [0; BYTES]; + + for i in 0..BYTES { + buffer[i] = self.storage.pop().unwrap_or(0); + } + + buffer + } +} + diff --git a/Source/Types.rs b/Source/Types.rs new file mode 100644 index 0000000..c897660 --- /dev/null +++ b/Source/Types.rs @@ -0,0 +1,5 @@ +/// Canonical byte type. +pub type Byte = u8; + +/// Canonical data and address type. +pub type Word = [u8; 4]; diff --git a/Source/lib.rs b/Source/lib.rs index 5fcf39c..24490f0 100644 --- a/Source/lib.rs +++ b/Source/lib.rs @@ -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::*;