~maddie/STT-implementation

ed510872ace66b1987b86b79ed2b1dcafab7a8f4 — kn0000 27 days ago
Initial commit, baseline implementation.
5 files changed, 109 insertions(+), 0 deletions(-)

A .gitignore
A Cargo.lock
A Cargo.toml
A src/lib.rs
A src/main.rs
A  => .gitignore +1 -0
@@ 1,1 @@
/target

A  => Cargo.lock +7 -0
@@ 1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4

[[package]]
name = "implementation"
version = "0.1.0"

A  => Cargo.toml +6 -0
@@ 1,6 @@
[package]
name = "implementation"
version = "0.1.0"
edition = "2024"

[dependencies]

A  => src/lib.rs +92 -0
@@ 1,92 @@
struct Processor {
    stack_a: Vec<u16>,
    stack_b: Vec<u16>,
    pub memory: [u16;1024],
    carry: bool,
    pub pc: u16 //program counter
}

impl Processor {
    pub fn run(&mut self) {
        let instruction = self.memory[self.pc as usize];
        let mut is_jump = false;
        match instruction & 0x300 {
            0x000 => self.carry = calc(&mut self.stack_a, instruction, self.carry),
            0x100 => self.carry = calc(&mut self.stack_a, instruction, self.carry),
            0x200 => self.stack_a.push(instruction & 0xFF),
            0x300 => {
                if (instruction & 0x80) != 0 {
                    let conditional = (instruction & 0x40) != 0;
                    let relative = (instruction & 0x20) != 0;
                    let save_pc = (instruction & 0x10) != 0;
                    if !conditional || self.carry {
                        let address = self.stack_a.pop().expect("End of stack");
                        if save_pc {self.stack_a.push(self.pc+1)};
                        if relative {self.pc += address}
                        else {self.pc = address};
                        is_jump = true;
                    }
                }
                else {
                    let toggle = (instruction & 0x40) != 0;
                    let mut stack;
                    if toggle {stack = &mut self.stack_b;}
                    else {stack = &mut self.stack_a;};
                    match instruction & 0x3F {
                        0 => { //swap top 2
                            let a = stack.pop().expect("End of stack");
                            let b = stack.pop().expect("End of stack");
                            stack.push(a);
                            stack.push(b);
                        }
                        1 => { //clone top
                            let a = stack.pop().expect("End of stack");
                            stack.push(a);
                            stack.push(a);
                        }
                        2 => { //clone second
                            let a = stack.pop().expect("End of stack");
                            let b = stack.pop().expect("End of stack");
                            stack.push(b);
                            stack.push(a);
                            stack.push(b);
                        }
                        3 => { //move between stacks
                            if toggle {self.stack_a.push(self.stack_b.pop().expect("End of stack"));}
                            else {self.stack_b.push(self.stack_a.pop().expect("End of stack"));};
                        }
                        4 => { //push/pop
                            let addr = self.stack_a.pop().expect("End of stack") as usize;
                            if toggle {
                                let value = self.stack_a.pop().expect("End of stack");
                                self.memory[addr] = value;
                            }
                            else {self.stack_a.push(self.memory[addr]);};
                        }
                        5 => { //set/clear carry
                            self.carry = toggle;
                        }
                        _ => ()
                    }
                }
            }
            _ => unreachable!()
        }
        if !is_jump {self.pc += 1};
    }
}

fn calc(stack: &mut Vec::<u16>, instruction: u16, carry_in: bool) -> bool {
    let operand_a = stack.pop().expect("End of stack");
    let operand_b = stack.pop().expect("End of stack");
    let mut carry = carry_in;
    let mut result = 0;
    for i in 0..10 {
        let bit = 1 << i;
        let count = ((operand_a & bit) >> i) + ((operand_b & bit) >> i) + carry as u16;
        result += ((instruction & (1<<(count+4))) >> count) << i;
        carry = (instruction & (1<<count)) != 0;
    }
    stack.push(result);
    carry
}

A  => src/main.rs +3 -0
@@ 1,3 @@
fn main() {
    println!("Hello, world!");
}