assembler

This commit is contained in:
Patrick 2024-11-24 22:03:13 +01:00
parent 63f3139c75
commit a7402461e8
5 changed files with 137 additions and 14 deletions

47
Cargo.lock generated
View file

@ -2,6 +2,53 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "regex"
version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "sysforge"
version = "0.1.0"
dependencies = [
"regex",
]

View file

@ -4,3 +4,4 @@ version = "0.1.0"
edition = "2021"
[dependencies]
regex = "1.11.1"

58
src/assembler.rs Normal file
View file

@ -0,0 +1,58 @@
use regex::Regex;
use std::{collections::HashMap, str::FromStr};
pub struct Opcode<T: Clone + ToString + FromStr> {
pub key: String,
pub value: T,
}
impl<T: Clone + ToString + FromStr> Opcode<T> {
pub fn create(key: &str, value: T) -> Opcode<T> {
return Opcode {
key: key.to_string(),
value: value,
};
}
}
pub struct Assembler<T: Clone + ToString + FromStr> {
opcodes: Vec<Opcode<T>>,
}
impl<T: Clone + ToString + FromStr> Assembler<T> {
pub fn create(opcodes: Vec<Opcode<T>>) -> Assembler<T> {
return Assembler { opcodes: opcodes };
}
pub fn assemble(&mut self, source: &mut String) -> Vec<T> {
let mut map: HashMap<String, T> = HashMap::new();
for opcode in &self.opcodes {
map.insert(opcode.key.clone(), opcode.value.clone());
}
return Regex::new(r"[\s]+") // create regex
.unwrap()
.split(source) // split by regex
.filter(|s: &&str| !s.is_empty()) // remove empty entries
.map(|s| match map.get(&s.to_lowercase()) {
Some(opcode) => opcode.to_string(),
None => s.to_string(),
}) // converts opcode strings to numbers
.filter_map(|s| {
if s.starts_with("0x") {
// converts hexadecimals to decimal, then parses them
u128::from_str_radix(&s[2..], 16)
.ok()
.unwrap()
.to_string()
.parse::<T>()
.ok()
} else {
// parses all other decimals
s.parse::<T>().ok()
}
})
.collect();
}
}

View file

@ -12,7 +12,7 @@ pub struct ExampleCPU {
impl ExampleCPU {
// Here is where you can create your own CPU Instance.
pub fn create_instance(debug: bool, initial_state: [u8; 256]) -> ExampleCPU {
pub fn create(debug: bool, initial_state: [u8; 256]) -> ExampleCPU {
return ExampleCPU {
debug: debug,
execution_pointer: 0,
@ -22,8 +22,14 @@ impl ExampleCPU {
};
}
pub fn start(&mut self) {
loop {
self.fetch_and_decode()
}
}
// This fetches the operands, based on the position of the execution_pointer, then runs the selected instruction.
pub fn fetch_and_decode(&mut self) {
fn fetch_and_decode(&mut self) {
self.operands[0] = self.ram[self.execution_pointer as usize];
self.operands[1] = self.ram[(self.execution_pointer + 1) as usize];
self.operands[2] = self.ram[(self.execution_pointer + 2) as usize];
@ -34,13 +40,13 @@ impl ExampleCPU {
);
}
match self.operands[0] {
0x00 => self.nop(),
0x01 => self.load(),
0x02 => self.store(),
0x03 => self.add(),
0x04 => self.sub(),
0x05 => self.jump(),
0x06 => self.jpiz(),
0 => self.nop(),
1 => self.load(),
2 => self.store(),
3 => self.add(),
4 => self.sub(),
5 => self.jump(),
6 => self.jpiz(),
_ => self.nop(),
};
}

View file

@ -1,12 +1,23 @@
// SPDX-License-Identifier: LGPL-3.0-or-later
// Copyright (c) 2024 Patrick_Pluto
mod devices;
mod assembler;
mod cpu;
fn main() {
let mut instance: devices::ExampleCPU = devices::ExampleCPU::create_instance(true, [0; 256]);
let mut assembler: assembler::Assembler<u8> = assembler::Assembler::create(vec![
assembler::Opcode::create("nop", 0),
assembler::Opcode::create("load", 1),
assembler::Opcode::create("store", 2),
assembler::Opcode::create("add", 3),
assembler::Opcode::create("sub", 4),
assembler::Opcode::create("jump", 5),
assembler::Opcode::create("jpiz", 6),
]);
let final_result: Vec<u8> = assembler.assemble(&mut "nop 0x00 0x22".to_string());
dbg!(final_result);
// let mut instance: cpu::ExampleCPU = cpu::ExampleCPU::create_instance(true, [0; 256]);
// change the instructions here
loop {
instance.fetch_and_decode();
}
// instance.start_emulation();
}