assembler
This commit is contained in:
parent
63f3139c75
commit
a7402461e8
5 changed files with 137 additions and 14 deletions
47
Cargo.lock
generated
47
Cargo.lock
generated
|
@ -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",
|
||||
]
|
||||
|
|
|
@ -4,3 +4,4 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
regex = "1.11.1"
|
||||
|
|
58
src/assembler.rs
Normal file
58
src/assembler.rs
Normal 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();
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
};
|
||||
}
|
21
src/main.rs
21
src/main.rs
|
@ -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();
|
||||
}
|
||||
|
|
Reference in a new issue