mirror of
https://github.com/guilhermewerner/machine
synced 2025-06-16 13:14:18 +00:00
Update heap, stack and opcodes
This commit is contained in:
70
Source/Frame.rs
Normal file
70
Source/Frame.rs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
use crate::Types::*;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
pub enum Frame {
|
||||||
|
Byte(Byte),
|
||||||
|
Half(Half),
|
||||||
|
Word(Word),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Frame {
|
||||||
|
pub fn Null() -> Self {
|
||||||
|
Self::Byte(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetSize(&self) -> usize {
|
||||||
|
match self {
|
||||||
|
Self::Byte(_) => mem::size_of::<Byte>(),
|
||||||
|
Self::Half(_) => mem::size_of::<Half>(),
|
||||||
|
Self::Word(_) => mem::size_of::<Word>(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn IsByte(&self) -> bool {
|
||||||
|
if let Self::Byte(_) = self {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetByte(&self) -> Option<Byte> {
|
||||||
|
if let Self::Byte(data) = *self {
|
||||||
|
Some(data)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn IsHalf(&self) -> bool {
|
||||||
|
if let Self::Half(_) = self {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetHalf(&self) -> Option<Half> {
|
||||||
|
if let Self::Half(data) = *self {
|
||||||
|
Some(data)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn IsWord(&self) -> bool {
|
||||||
|
if let Self::Word(_) = self {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn GetWord(&self) -> Option<Word> {
|
||||||
|
if let Self::Word(data) = *self {
|
||||||
|
Some(data)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
81
Source/Heap.rs
Normal file
81
Source/Heap.rs
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
use crate::Types::*;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
pub struct Heap {
|
||||||
|
buffer: Vec<Byte>,
|
||||||
|
lenght: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Heap {
|
||||||
|
pub fn New(size: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
buffer: Vec::with_capacity(size),
|
||||||
|
lenght: size,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn IsEmpty(&self) -> bool {
|
||||||
|
self.buffer.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn Flush(&mut self) {
|
||||||
|
self.buffer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ReadByte(&mut self, addr: u32) -> Byte {
|
||||||
|
let index = addr as usize;
|
||||||
|
*self.buffer.get(index).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn WriteByte(&mut self, addr: u32, value: Byte) {
|
||||||
|
let index = addr as usize;
|
||||||
|
|
||||||
|
if index < self.lenght {
|
||||||
|
self.buffer.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ReadHalf(&mut self, addr: u32) -> Half {
|
||||||
|
let mut index = addr as usize;
|
||||||
|
|
||||||
|
const BYTES: usize = mem::size_of::<Half>();
|
||||||
|
let mut buffer = [0; BYTES];
|
||||||
|
|
||||||
|
for i in 0..BYTES {
|
||||||
|
buffer[i] = *self.buffer.get(index).unwrap_or(&0);
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn WriteHalf(&mut self, addr: u32, value: Half) {
|
||||||
|
let index = addr as usize;
|
||||||
|
|
||||||
|
if index < self.lenght {
|
||||||
|
self.buffer.extend(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.buffer.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.lenght {
|
||||||
|
self.buffer.extend(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,7 @@ pub fn LoadRegister(vm: &mut Machine) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SaveRegister(vm: &mut Machine) -> bool {
|
pub fn StoreRegister(vm: &mut Machine) -> bool {
|
||||||
let (addr, reg) = Payload::GetAddressRegister(vm);
|
let (addr, reg) = Payload::GetAddressRegister(vm);
|
||||||
|
|
||||||
let data = vm.registry.Get(reg);
|
let data = vm.registry.Get(reg);
|
||||||
@ -28,6 +28,28 @@ pub fn SaveRegister(vm: &mut Machine) -> bool {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn IncrementRegister(vm: &mut Machine) -> bool {
|
||||||
|
let r0 = Payload::GetRegister(vm);
|
||||||
|
|
||||||
|
let a = u32::from_be_bytes(vm.registry.Get(r0));
|
||||||
|
|
||||||
|
vm.registry.Set(r0, (a + 1).to_be_bytes());
|
||||||
|
vm.Walk(2);
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn DecrementRegister(vm: &mut Machine) -> bool {
|
||||||
|
let r0 = Payload::GetRegister(vm);
|
||||||
|
|
||||||
|
let a = u32::from_be_bytes(vm.registry.Get(r0));
|
||||||
|
|
||||||
|
vm.registry.Set(r0, (a - 1).to_be_bytes());
|
||||||
|
vm.Walk(2);
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn Move(_vm: &mut Machine) -> bool {
|
pub fn Move(_vm: &mut Machine) -> bool {
|
||||||
false
|
false
|
||||||
|
@ -1,30 +1,39 @@
|
|||||||
use crate::Instructions::*;
|
use crate::Instructions::*;
|
||||||
use crate::Operations::*;
|
use crate::Operations::*;
|
||||||
use crate::Types::*;
|
use crate::Types::*;
|
||||||
use crate::{Memory, Registry, Stack, HEAP_LIMIT, STACK_SIZE};
|
use crate::{Heap, Registry, Stack, HEAP_LIMIT, STACK_SIZE};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Machine {
|
pub struct Machine {
|
||||||
pub(crate) program_counter: usize,
|
/// Program Counter.
|
||||||
|
pub(crate) pc: usize,
|
||||||
|
|
||||||
|
/// General-purpose registers.
|
||||||
pub(crate) registry: Registry,
|
pub(crate) registry: Registry,
|
||||||
pub(crate) stack_pointer: usize,
|
|
||||||
pub(crate) link_register: usize,
|
/// Stack Pointer.
|
||||||
|
pub(crate) sp: usize,
|
||||||
|
|
||||||
|
/// Stack Memory.
|
||||||
pub(crate) stack: Stack,
|
pub(crate) stack: Stack,
|
||||||
pub(crate) memory_pointer: usize,
|
|
||||||
pub(crate) heap: Memory,
|
/// Memory Pointer.
|
||||||
|
pub(crate) mp: usize,
|
||||||
|
|
||||||
|
/// Heap Memory.
|
||||||
|
pub(crate) heap: Heap,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl Machine {
|
impl Machine {
|
||||||
pub fn New(address: Word) -> Self {
|
pub fn New(address: Word) -> Self {
|
||||||
Self {
|
Self {
|
||||||
program_counter: u32::from_be_bytes(address) as usize,
|
pc: u32::from_be_bytes(address) as usize,
|
||||||
registry: Registry::default(),
|
registry: Registry::default(),
|
||||||
stack_pointer: 0,
|
sp: 0,
|
||||||
link_register: 0,
|
|
||||||
stack: Stack::New(STACK_SIZE),
|
stack: Stack::New(STACK_SIZE),
|
||||||
memory_pointer: 0,
|
mp: 0,
|
||||||
heap: Memory::New(HEAP_LIMIT),
|
heap: Heap::New(HEAP_LIMIT),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,14 +49,15 @@ impl Machine {
|
|||||||
while running {
|
while running {
|
||||||
self.registry.Print();
|
self.registry.Print();
|
||||||
|
|
||||||
let opcode = self.heap.ReadByte(self.program_counter as u32);
|
let opcode = self.heap.ReadByte(self.pc as u32);
|
||||||
self.memory_pointer = self.program_counter + 1;
|
self.mp = self.pc + 1;
|
||||||
|
|
||||||
running = match opcode {
|
running = match opcode {
|
||||||
NOP => Nothing(&mut self),
|
NOP => Nothing(&mut self),
|
||||||
LDR => LoadRegister(&mut self),
|
LDR => LoadRegister(&mut self),
|
||||||
SVR => SaveRegister(&mut self),
|
STR => StoreRegister(&mut self),
|
||||||
//MOV
|
INC => IncrementRegister(&mut self),
|
||||||
|
DEC => DecrementRegister(&mut self),
|
||||||
ADD => Add(&mut self),
|
ADD => Add(&mut self),
|
||||||
ADD_ASSIGN => AddAssign(&mut self),
|
ADD_ASSIGN => AddAssign(&mut self),
|
||||||
SUB => Subtract(&mut self),
|
SUB => Subtract(&mut self),
|
||||||
@ -83,54 +93,76 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ReadByte(&mut self, addr: Option<Word>) -> Byte {
|
pub(crate) fn ReadByte(&mut self, addr: Option<Word>) -> Byte {
|
||||||
let mut mp = self.memory_pointer as u32;
|
let mut mp = self.mp as u32;
|
||||||
|
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
mp = u32::from_be_bytes(addr);
|
mp = u32::from_be_bytes(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.memory_pointer = (mp + 1) as usize;
|
self.mp = (mp + 1) as usize;
|
||||||
self.heap.ReadByte(mp)
|
self.heap.ReadByte(mp)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn WriteByte(&mut self, addr: Option<Word>, value: Byte) {
|
pub(crate) fn WriteByte(&mut self, addr: Option<Word>, value: Byte) {
|
||||||
let mut mp = self.memory_pointer as u32;
|
let mut mp = self.mp as u32;
|
||||||
|
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
mp = u32::from_be_bytes(addr);
|
mp = u32::from_be_bytes(addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
self.memory_pointer = (mp + 1) as usize;
|
self.mp = (mp + 1) as usize;
|
||||||
self.heap.WriteByte(mp, value);
|
self.heap.WriteByte(mp, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn ReadWord(&mut self, addr: Option<Word>) -> Word {
|
pub(crate) fn ReadHalf(&mut self, addr: Option<Word>) -> Half {
|
||||||
let mut mp = self.memory_pointer as u32;
|
let mut mp = self.mp as u32;
|
||||||
|
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
mp = u32::from_be_bytes(addr);
|
mp = u32::from_be_bytes(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.memory_pointer = (mp + 4) as usize;
|
self.mp = (mp + 4) as usize;
|
||||||
|
self.heap.ReadHalf(mp as u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn WriteHalf(&mut self, addr: Option<Word>, value: Half) {
|
||||||
|
let mut mp = self.mp as u32;
|
||||||
|
|
||||||
|
if let Some(addr) = addr {
|
||||||
|
mp = u32::from_be_bytes(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mp = (mp + 4) as usize;
|
||||||
|
self.heap.WriteHalf(mp as u32, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn ReadWord(&mut self, addr: Option<Word>) -> Word {
|
||||||
|
let mut mp = self.mp as u32;
|
||||||
|
|
||||||
|
if let Some(addr) = addr {
|
||||||
|
mp = u32::from_be_bytes(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.mp = (mp + 4) as usize;
|
||||||
self.heap.ReadWord(mp as u32)
|
self.heap.ReadWord(mp as u32)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn WriteWord(&mut self, addr: Option<Word>, value: Word) {
|
pub(crate) fn WriteWord(&mut self, addr: Option<Word>, value: Word) {
|
||||||
let mut mp = self.memory_pointer as u32;
|
let mut mp = self.mp as u32;
|
||||||
|
|
||||||
if let Some(addr) = addr {
|
if let Some(addr) = addr {
|
||||||
mp = u32::from_be_bytes(addr);
|
mp = u32::from_be_bytes(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.memory_pointer = (mp + 4) as usize;
|
self.mp = (mp + 4) as usize;
|
||||||
self.heap.WriteWord(mp as u32, value);
|
self.heap.WriteWord(mp as u32, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn Next(&mut self) {
|
pub(crate) fn Next(&mut self) {
|
||||||
self.program_counter += 1;
|
self.pc += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn Walk(&mut self, bytes: Byte) {
|
pub(crate) fn Walk(&mut self, bytes: Byte) {
|
||||||
self.program_counter += bytes as usize;
|
self.pc += bytes as usize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -12,215 +12,278 @@ pub const NOP: u8 = 0x00;
|
|||||||
/// ```
|
/// ```
|
||||||
pub const LDR: u8 = 0x01;
|
pub const LDR: u8 = 0x01;
|
||||||
|
|
||||||
/// **0x02** - Save register in memory.
|
/// **0x02** - Load register from imediate value.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// svr 0050 r1 // mem[0050] = r1
|
/// ldi r1 1 // r1 = 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SVR: u8 = 0x02;
|
pub const LDI: u8 = 0x02;
|
||||||
|
|
||||||
/// **0x03** - Move register.
|
/// **0x03** - Store register in memory.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// str 0050 r1 // mem[0050] = r1
|
||||||
|
/// ```
|
||||||
|
pub const STR: u8 = 0x03;
|
||||||
|
|
||||||
|
/// **0x04** - Store imediate value in memory.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// sti 0050 1 // mem[0050] = 1
|
||||||
|
/// ```
|
||||||
|
pub const STI: u8 = 0x04;
|
||||||
|
|
||||||
|
/// **0x05** - Move register.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// mov r1 r2 // r1 = r2
|
/// mov r1 r2 // r1 = r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const MOV: u8 = 0x03;
|
pub const MOV: u8 = 0x05;
|
||||||
|
|
||||||
/// **0x04** - The addition operator `+`.
|
/// **0x06** - Push register value on stack.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// push r1 // sp = r1
|
||||||
|
/// ```
|
||||||
|
pub const PUSH: u8 = 0x06;
|
||||||
|
|
||||||
|
/// **0x07** - Pop stack and save in register.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// pop r1 // r1 = sp
|
||||||
|
/// ```
|
||||||
|
pub const POP: u8 = 0x07;
|
||||||
|
|
||||||
|
/// **0x08** - Increment register.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// inc r1 // r1 += 1
|
||||||
|
/// ```
|
||||||
|
pub const INC: u8 = 0x08;
|
||||||
|
|
||||||
|
/// **0x09** - Decrement register.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// dec r1 // r1 -= 1
|
||||||
|
/// ```
|
||||||
|
pub const DEC: u8 = 0x09;
|
||||||
|
|
||||||
|
/// **0x0A** - Jump to address.
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// jmp 0050
|
||||||
|
/// ```
|
||||||
|
pub const JMP: u8 = 0x0A;
|
||||||
|
|
||||||
|
/// **0x0B** - The addition operator `+`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// add r1 r2 r3 // r1 = r2 + r3
|
/// add r1 r2 r3 // r1 = r2 + r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const ADD: u8 = 0x04;
|
pub const ADD: u8 = 0x0B;
|
||||||
|
|
||||||
/// **0x05** - The addition assignment operator `+=`.
|
/// **0x0C** - The addition operator `+`, with carry;
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// adc r1 r2 r3 r4 // r1 = r2 + r3 + r4
|
||||||
|
/// ```
|
||||||
|
pub const ADC: u8 = 0x0C;
|
||||||
|
|
||||||
|
/// **0x0D** - The addition assignment operator `+=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// add r1 r2 // r1 += r2
|
/// add r1 r2 // r1 += r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const ADD_ASSIGN: u8 = 0x05;
|
pub const ADD_ASSIGN: u8 = 0x0D;
|
||||||
|
|
||||||
/// **0x06** - The subtraction operator `-`.
|
/// **0x0E** - The subtraction operator `-`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// sub r1 r2 r3 // r1 = r2 - r3
|
/// sub r1 r2 r3 // r1 = r2 - r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const SUB: u8 = 0x06;
|
pub const SUB: u8 = 0x0E;
|
||||||
|
|
||||||
/// **0x07** - The subtraction assignment operator `-=`.
|
//// *0x0F0x06** - The subtraction operator `-`, with carry;
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// suc r1 r2 r3 r4 // r1 = r2 - r3 + r4
|
||||||
|
/// ```
|
||||||
|
pub const SBC: u8 = 0x0F;
|
||||||
|
|
||||||
|
/// **0x10** - The subtraction assignment operator `-=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// sub r1 r2 // r1 -= r2
|
/// sub r1 r2 // r1 -= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const SUB_ASSIGN: u8 = 0x07;
|
pub const SUB_ASSIGN: u8 = 0x10;
|
||||||
|
|
||||||
/// **0x08** - The multiplication operator `*`.
|
/// **0x11** - The multiplication operator `*`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// mul r1 r2 r3 // r1 = r2 * r3
|
/// mul r1 r2 r3 // r1 = r2 * r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const MUL: u8 = 0x08;
|
pub const MUL: u8 = 0x11;
|
||||||
|
|
||||||
/// **0x09** - The multiplication assignment operator `*=`.
|
/// **0x12** - The multiplication assignment operator `*=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// mul r1 r2 // r1 *= r2
|
/// mul r1 r2 // r1 *= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const MUL_ASSIGN: u8 = 0x09;
|
pub const MUL_ASSIGN: u8 = 0x12;
|
||||||
|
|
||||||
/// **0x0A** - The division operator `/`.
|
/// **0x13** - The division operator `/`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// div r1 r2 r3 // r1 = r2 / r3
|
/// div r1 r2 r3 // r1 = r2 / r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const DIV: u8 = 0x0A;
|
pub const DIV: u8 = 0x13;
|
||||||
|
|
||||||
/// **0x0B** - The division assignment operator `/=`.
|
/// **0x14** - The division assignment operator `/=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// div r1 r2 // r1 /= r2
|
/// div r1 r2 // r1 /= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const DIV_ASSIGN: u8 = 0x0B;
|
pub const DIV_ASSIGN: u8 = 0x14;
|
||||||
|
|
||||||
/// **0x0C** - The remainder operator `%`.
|
/// **0x15** - The remainder operator `%`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// rem r1 r2 r3 // r1 = r2 % r3
|
/// rem r1 r2 r3 // r1 = r2 % r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const REM: u8 = 0x0C;
|
pub const REM: u8 = 0x15;
|
||||||
|
|
||||||
/// **0x0D** - The remainder assignment operator `%=`.
|
/// **0x16** - The remainder assignment operator `%=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// rem r1 r2 // r1 %= r2
|
/// rem r1 r2 // r1 %= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const REM_ASSIGN: u8 = 0x0D;
|
pub const REM_ASSIGN: u8 = 0x16;
|
||||||
|
|
||||||
/// **0x0E** - Arithmetic negation `-`.
|
/// **0x17** - Arithmetic negation `-`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// not r1 r2 // r1 = -r2
|
/// not r1 r2 // r1 = -r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const NEG: u8 = 0x0E;
|
pub const NEG: u8 = 0x17;
|
||||||
|
|
||||||
/// **0x0F** -The bitwise AND operator `&`.
|
/// **0x18** -The bitwise AND operator `&`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// and r1 r2 r3 // r1 = r2 & r3
|
/// and r1 r2 r3 // r1 = r2 & r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const AND: u8 = 0x0F;
|
pub const AND: u8 = 0x18;
|
||||||
|
|
||||||
/// **0x10** - The bitwise AND assignment operator `&=`.
|
/// **0x19** - The bitwise AND assignment operator `&=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// and r1 r2 // r1 &= r2
|
/// and r1 r2 // r1 &= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const AND_ASSIGN: u8 = 0x10;
|
pub const AND_ASSIGN: u8 = 0x19;
|
||||||
|
|
||||||
/// **0x11** - The bitwise OR operator `|`.
|
/// **0x1A** - The bitwise OR operator `|`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// or r1 r2 r3 // r1 = r2 | r3
|
/// or r1 r2 r3 // r1 = r2 | r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const OR: u8 = 0x11;
|
pub const OR: u8 = 0x1A;
|
||||||
|
|
||||||
/// **0x12** - The bitwise OR assignment operator `|=`.
|
/// **0x1B** - The bitwise OR assignment operator `|=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// or r1 r2 // r1 |= r2
|
/// or r1 r2 // r1 |= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const OR_ASSIGN: u8 = 0x12;
|
pub const OR_ASSIGN: u8 = 0x1B;
|
||||||
|
|
||||||
/// **0x13** - The bitwise XOR operator `^`.
|
/// **0x1C** - The bitwise XOR operator `^`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// xor r1 r2 r3 // r1 = r2 ^ r3
|
/// xor r1 r2 r3 // r1 = r2 ^ r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const XOR: u8 = 0x13;
|
pub const XOR: u8 = 0x1C;
|
||||||
|
|
||||||
/// **0x14** - The bitwise XOR assignment operator `^=`.
|
/// **0x1D** - The bitwise XOR assignment operator `^=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// xor r1 r2 // r1 ^= r2
|
/// xor r1 r2 // r1 ^= r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const XOR_ASSIGN: u8 = 0x14;
|
pub const XOR_ASSIGN: u8 = 0x1D;
|
||||||
|
|
||||||
/// **0x15** - Logical negation `!`
|
/// **0x1E** - Logical negation `!`
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// not r1 r2 // r1 = !r2
|
/// not r1 r2 // r1 = !r2
|
||||||
/// ```
|
/// ```
|
||||||
pub const NOT: u8 = 0x15;
|
pub const NOT: u8 = 0x1E;
|
||||||
|
|
||||||
/// **0x16** - The left shift operator `<<`.
|
/// **0x1F** - The left shift operator `<<`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shl r1 r2 // r1 = r2 << 1
|
/// shl r1 r2 // r1 = r2 << 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHL: u8 = 0x16;
|
pub const SHL: u8 = 0x1F;
|
||||||
|
|
||||||
/// **0x17** - The left shift assignment operator `<<=`.
|
/// **0x20** - The left shift assignment operator `<<=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shl r1 // r1 <<= 1
|
/// shl r1 // r1 <<= 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHL_ASSIGN: u8 = 0x17;
|
pub const SHL_ASSIGN: u8 = 0x20;
|
||||||
|
|
||||||
/// **0x18** - The right shift operator `>>`.
|
/// **0x21** - The right shift operator `>>`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shr r1 r2 // r1 = r2 >> 1
|
/// shr r1 r2 // r1 = r2 >> 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHR: u8 = 0x18;
|
pub const SHR: u8 = 0x21;
|
||||||
|
|
||||||
/// **0x19** - The right shift assignment operator `>>=`.
|
/// **0x22** - The right shift assignment operator `>>=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// shr r1 // r1 >>= 1
|
/// shr r1 // r1 >>= 1
|
||||||
/// ```
|
/// ```
|
||||||
pub const SHR_ASSIGN: u8 = 0x19;
|
pub const SHR_ASSIGN: u8 = 0x22;
|
||||||
|
|
||||||
/// **0x1A** - The equality operator `==`.
|
/// **0x23** - The equality operator `==`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// eq r1 r2 r3 // r1 = r2 == r3
|
/// eq r1 r2 r3 // r1 = r2 == r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const EQ: u8 = 0x1A;
|
pub const EQ: u8 = 0x23;
|
||||||
|
|
||||||
/// **0x1B** - The inequality operator `!=`.
|
/// **0x24** - The inequality operator `!=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// neq r1 r2 r3 // r1 = r2 != r3
|
/// neq r1 r2 r3 // r1 = r2 != r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const NEQ: u8 = 0x1B;
|
pub const NEQ: u8 = 0x24;
|
||||||
|
|
||||||
/// **0x1C** - The less than operator `<`.
|
/// **0x25** - The less than operator `<`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// lt r1 r2 r3 // r1 = r2 < r3
|
/// lt r1 r2 r3 // r1 = r2 < r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const LT: u8 = 0x1C;
|
pub const LT: u8 = 0x25;
|
||||||
|
|
||||||
/// **0x1D** - The less than or equal to operator `<=`.
|
/// **0x26** - The less than or equal to operator `<=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// le r1 r2 r3 // r1 = r2 <= r3
|
/// le r1 r2 r3 // r1 = r2 <= r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const LE: u8 = 0x1D;
|
pub const LE: u8 = 0x26;
|
||||||
|
|
||||||
/// **0x1E** - The greater than operator `>`.
|
/// **0x27** - The greater than operator `>`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// gt r1 r2 r3 // r1 = r2 > r3
|
/// gt r1 r2 r3 // r1 = r2 > r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const GT: u8 = 0x1E;
|
pub const GT: u8 = 0x27;
|
||||||
|
|
||||||
/// **0x1F** - The greater than or equal to operator `>=`.
|
/// **0x28** - The greater than or equal to operator `>=`.
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// ge r1 r2 r3 // r1 = r2 >= r3
|
/// ge r1 r2 r3 // r1 = r2 >= r3
|
||||||
/// ```
|
/// ```
|
||||||
pub const GE: u8 = 0x1F;
|
pub const GE: u8 = 0x28;
|
||||||
|
|
||||||
/// **0xFF** - Halt execution.
|
/// **0xFF** - Halt execution.
|
||||||
///
|
///
|
||||||
|
@ -6,6 +6,7 @@ pub type AddressRegister = (Word, Byte);
|
|||||||
pub type Register = Byte;
|
pub type Register = Byte;
|
||||||
pub type TwoRegisters = (Byte, Byte);
|
pub type TwoRegisters = (Byte, Byte);
|
||||||
pub type ThreeRegisters = (Byte, Byte, Byte);
|
pub type ThreeRegisters = (Byte, Byte, Byte);
|
||||||
|
pub type FourRegisters = (Byte, Byte, Byte, Byte);
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn GetRegisterAddress(vm: &mut Machine) -> RegisterAddress {
|
pub fn GetRegisterAddress(vm: &mut Machine) -> RegisterAddress {
|
||||||
@ -31,3 +32,13 @@ pub fn GetTwoRegisters(vm: &mut Machine) -> TwoRegisters {
|
|||||||
pub fn GetThreeRegisters(vm: &mut Machine) -> ThreeRegisters {
|
pub fn GetThreeRegisters(vm: &mut Machine) -> ThreeRegisters {
|
||||||
(vm.ReadByte(None), vm.ReadByte(None), vm.ReadByte(None))
|
(vm.ReadByte(None), vm.ReadByte(None), vm.ReadByte(None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn GetFourRegisters(vm: &mut Machine) -> FourRegisters {
|
||||||
|
(
|
||||||
|
vm.ReadByte(None),
|
||||||
|
vm.ReadByte(None),
|
||||||
|
vm.ReadByte(None),
|
||||||
|
vm.ReadByte(None),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -1,50 +1,33 @@
|
|||||||
use crate::Types::*;
|
use crate::Frame;
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
pub struct Stack {
|
pub struct Stack {
|
||||||
storage: Vec<u8>,
|
frames: Vec<Frame>,
|
||||||
capacity: usize,
|
lenght: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stack {
|
impl Stack {
|
||||||
pub fn New(size: usize) -> Self {
|
pub fn New(size: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
storage: Vec::with_capacity(size),
|
frames: Vec::with_capacity(size),
|
||||||
capacity: size,
|
lenght: size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn IsEmpty(&self) -> bool {
|
||||||
|
self.frames.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn Flush(&mut self) {
|
pub fn Flush(&mut self) {
|
||||||
self.storage.clear();
|
self.frames.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn PushByte(&mut self, item: Byte) {
|
pub fn Push(&mut self, frame: Frame) {
|
||||||
if self.storage.len() + 1 < self.capacity {
|
if self.frames.len() + frame.GetSize() < self.lenght {
|
||||||
self.storage.push(item);
|
self.frames.push(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn PopByte(&mut self) -> Byte {
|
pub fn Pop(&mut self) -> Frame {
|
||||||
self.storage.pop().unwrap_or(0)
|
self.frames.pop().unwrap_or(Frame::Null())
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub type Byte = u8;
|
pub type Byte = u8;
|
||||||
|
pub type Half = [Byte; 2];
|
||||||
pub type Word = [Byte; 4];
|
pub type Word = [Byte; 4];
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#![allow(dead_code)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
mod Instructions;
|
mod Instructions;
|
||||||
@ -6,6 +7,18 @@ pub mod Operations;
|
|||||||
pub mod Payload;
|
pub mod Payload;
|
||||||
pub mod Types;
|
pub mod Types;
|
||||||
|
|
||||||
|
#[path = "Assembly.rs"]
|
||||||
|
mod _Assembly;
|
||||||
|
pub use self::_Assembly::*;
|
||||||
|
|
||||||
|
#[path = "Frame.rs"]
|
||||||
|
mod _Frame;
|
||||||
|
pub use self::_Frame::*;
|
||||||
|
|
||||||
|
#[path = "Heap.rs"]
|
||||||
|
mod _Heap;
|
||||||
|
pub use self::_Heap::*;
|
||||||
|
|
||||||
#[path = "Limits.rs"]
|
#[path = "Limits.rs"]
|
||||||
mod _Limits;
|
mod _Limits;
|
||||||
pub use self::_Limits::*;
|
pub use self::_Limits::*;
|
||||||
@ -14,10 +27,6 @@ pub use self::_Limits::*;
|
|||||||
mod _Machine;
|
mod _Machine;
|
||||||
pub use self::_Machine::*;
|
pub use self::_Machine::*;
|
||||||
|
|
||||||
#[path = "Memory.rs"]
|
|
||||||
mod _Memory;
|
|
||||||
pub use self::_Memory::*;
|
|
||||||
|
|
||||||
#[path = "Registry.rs"]
|
#[path = "Registry.rs"]
|
||||||
mod _Registry;
|
mod _Registry;
|
||||||
pub use self::_Registry::*;
|
pub use self::_Registry::*;
|
||||||
|
Reference in New Issue
Block a user