From 9303aa07fb512637391518873f206ef142ecca29 Mon Sep 17 00:00:00 2001 From: kn0000 Date: Fri, 30 May 2025 17:41:06 +0100 Subject: [PATCH] Rewrote lib.rs to fix numerous mistakes and tidy up with constants --- src/lib.rs | 195 +++++++++++++++++++++++++++++----------------------- src/main.rs | 29 +++++--- 2 files changed, 128 insertions(+), 96 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ec290a03764fdaee1e80c130d1843eefa6e5e3e5..c8647faf37c4fe883e32e8cfe9a90b66ab28c27c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,113 +1,138 @@ +const STACK_SIZE: usize = 1024; +pub const MEMORY_SIZE: usize = 1<<20; +pub const SCREEN_WIDTH: usize = 512; +pub const SCREEN_HEIGHT: usize = 512; +pub const SCREEN_UPDATE_ADDRESS: usize = 0x7FFFF + +#[derive(Debug)] +pub struct Stack { + buffer: [u16;STACK_SIZE], + index: usize +} + +impl Stack { + fn push(&mut self, value: u16) { + self.buffer[self.index] = value; + self.index = (self.index + 1) % STACK_SIZE; + } + + fn pop(&mut self) -> u16 { + self.index = (self.index + STACK_SIZE - 1) % STACK_SIZE; + self.buffer[self.index] + } +} + +pub fn new_stack() -> Stack { + Stack{ + buffer: [0u16;STACK_SIZE], + index: 0 + } +} + pub struct Processor { - pub stack_a: Vec, - pub stack_b: Vec, - pub memory: [u16;0xFFFFF], + pub stack_a: Stack, + pub stack_b: Stack, + pub memory: [u16;MEMORY_SIZE], pub carry: bool, - pub pc: u16 //program counter + pub pc: usize } impl Processor { pub fn run(&mut self) -> bool { - let instruction = self.memory[self.pc as usize]; + let instruction = self.memory[self.pc] & 0x3FF; + let (mut stack, off_stack) = { + if (instruction & 0x200) == 0 { + (&mut self.stack_a, &mut self.stack_b) + } + else {(&mut self.stack_b, &mut self.stack_a)} + }; 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; - let long_address = (instruction & 0x8) != 0; - if !conditional || self.carry { - let address; - if long_address {address = self.stack_a.pop().unwrap_or(0) | (self.stack_a.pop().unwrap_or(0) << 10)} //lower value on stack is high half of long address - else {address = self.stack_a.pop().unwrap_or(0)}; - if save_pc {self.stack_a.push(self.pc+1)}; - if relative {self.pc += address} - else {self.pc = address}; - is_jump = true; - } + + if instruction & 0x100 == 0 { //calculation + self.carry = calc(&mut stack, instruction, self.carry); + } + else if instruction & 0x80 == 0 { //jump + let push_pc = (instruction & 0x40) != 0; + let conditional = (instruction & 0x20) != 0; + if !conditional || self.carry { + let address = (stack.pop() as usize) | ((stack.pop() as usize) << 10); + is_jump = true; + if push_pc { + let a = self.pc + 1; + let upper = a & 0b11111111110000000000 >> 10; + let lower = a & 0b1111111111; + stack.push(upper as u16); + stack.push(lower as u16); + } + self.pc = address; + } + } + else { + match instruction & 0x7F { + 0 => { //immediate value + self.pc += 1; + stack.push(self.memory[self.pc] & 0x3FF); + } + 1 => { + let upper = self.pc & 0b11111111110000000000 >> 10; + let lower = self.pc & 0b1111111111; + stack.push(upper as u16); + stack.push(lower as u16); + } + 2 => { //swap + let a = stack.pop(); + let b = stack.pop(); + stack.push(a); + stack.push(b); + } + 3 => off_stack.push(stack.pop()), //move between stacks + 4 => { //push from memory + let address = (stack.pop() as usize) | ((stack.pop() as usize) << 10); + stack.push(self.memory[address]); + } + 5 => { //pop to memory + let address = (stack.pop() as usize) | ((stack.pop() as usize) << 10); + self.memory[address] = stack.pop(); + } + 6 => { //dup + let a = stack.pop(); + stack.push(a); + stack.push(a); } - else { - let toggle = (instruction & 0x40) != 0; - let 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().unwrap_or(0); - let b = stack.pop().unwrap_or(0); - stack.push(a); - stack.push(b); - } - 1 => { //clone top - let a = stack.pop().unwrap_or(0); - stack.push(a); - stack.push(a); - } - 2 => { //clone second - let a = stack.pop().unwrap_or(0); - let b = stack.pop().unwrap_or(0); - stack.push(b); - stack.push(a); - stack.push(b); - } - 3 => { //move between stacks - if toggle {self.stack_a.push(self.stack_b.pop().unwrap_or(0));} - else {self.stack_b.push(self.stack_a.pop().unwrap_or(0));}; - } - 4 => { //push/pop - let addr = self.stack_a.pop().unwrap_or(0) as usize; - if toggle { - let value = self.stack_a.pop().unwrap_or(0); - self.memory[addr] = value; - } - else {self.stack_a.push(self.memory[addr])}; - } - 5 => { //long addr push/pop - let addr = (self.stack_a.pop().unwrap_or(0) | (self.stack_a.pop().unwrap_or(0) << 10)) as usize; - if toggle { - let value = self.stack_a.pop().unwrap_or(0); - self.memory[addr] = value; - } - else {self.stack_a.push(self.memory[addr])}; - } - 6 => { //set/clear carry - self.carry = toggle; - } - 0x3F => return false, - _ => () - } + 7 => { //over + let a = stack.pop(); + let b = stack.pop(); + stack.push(b); + stack.push(a); + stack.push(b); } + 0x7F => return false, + _ => () } - _ => unreachable!() } if !is_jump {self.pc += 1}; true } } -fn calc(stack: &mut Vec::, instruction: u16, carry_in: bool) -> bool { - let operand_a = stack.pop().unwrap_or(0); - let operand_b = stack.pop().unwrap_or(0); +fn calc(stack: &mut Stack, instruction: u16, carry_in: bool) -> bool { + let operand_a = stack.pop(); + let operand_b = stack.pop(); 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<> i) & 1) + ((operand_b >> i) & 1) + (carry as u16); + result += ((instruction >> (count+4)) & 1) << i; + carry = ((instruction >> count) & 1) != 0; } stack.push(result); carry } -pub fn mem_to_buf(memory: &[u16]) -> [u32;(2<<14)-1] { - let mut result = [0u32;(2<<14)-1]; +pub fn mem_to_buf(memory: &[u16]) -> [u32;SCREEN_WIDTH*SCREEN_HEIGHT] { + let mut result = [0u32;SCREEN_WIDTH*SCREEN_HEIGHT]; let mut i = 0; - for byte in &memory[(2<<20)-(2<<14)..(2<<20)-1] { + for byte in &memory[(MEMORY_SIZE-SCREEN_WIDTH*SCREEN_HEIGHT)..MEMORY_SIZE] { result[i] = (((byte & 0b111000000) as u32) << 15) | (((byte & 0b111000) as u32) << 10) | (((byte & 0b111) as u32) << 5); //shifts 3 bits of each 10 bit value into the rgb channels of the buffer, from the last region of memory i += 1; } diff --git a/src/main.rs b/src/main.rs index d9489602c305bb336c80f27534415a858fdb3d7a..5f38a27af597569e1e7acec407a39705b720efb7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,17 +4,16 @@ use implementation::*; fn main() { let mut filename = String::new(); - print!("Enter filename of the program to load into memory"); + println!("Enter filename of the program to load into memory"); io::stdin().read_line(&mut filename).unwrap(); - let program = fs::read_to_string(filename).unwrap(); + let program = fs::read_to_string(filename.trim()).unwrap(); let mut i = 0; - let mut memory = [0u16;0xFFFFF]; + let mut memory = [0u16;MEMORY_SIZE]; for line in program.lines() { let mut byte = 0u16; let mut count = 0; for digit in line.chars() { - count += 1; match digit { '0' => { byte = byte << 1; @@ -26,25 +25,33 @@ fn main() { } _ => () } - if count > 10 {panic!("10 bits only :)")}; + if count > 10 {panic!("10 bits only :)\nFailed at line {i}")}; } memory[i] = byte; i += 1; } let mut processor = Processor { - stack_a: Vec::new(), - stack_b: Vec::new(), + stack_a: new_stack(), + stack_b: new_stack(), memory, carry: false, pc: 0 }; - let mut window = Window::new("STT Display", 128, 128, WindowOptions::default()).unwrap(); + let mut window = Window::new("STT Display", SCREEN_WIDTH, SCREEN_HEIGHT, WindowOptions::default()).unwrap(); + window.update_with_buffer(&[0;(1<<14)],128,128).unwrap(); + let mut instructions_run = 0; while window.is_open() && processor.run() { - if processor.memory[(2<<20)-(2<<14)-1] != 0 { - processor.memory[(2<<20)-(2<<14)-1] = 0; - window.update_with_buffer(&mem_to_buf(&processor.memory), 128, 128).unwrap(); + if processor.memory[SCREEN_UPDATE_ADDRESS] != 0 { + processor.memory[SCREEN_UPDATE_ADDRESS] = 0; + window.update_with_buffer(&mem_to_buf(&processor.memory), SCREEN_WIDTH, SCREEN_HEIGHT).unwrap(); + } + instructions_run += 1; + if instructions_run%1000 == 0 { + println!("Program running"); } } + + println!("Stack A: {0:?}\nStack B: {1:?}", processor.stack_a, processor.stack_b); }