From 425f054548c5cd678a74f4d5e099ec130e6d9246 Mon Sep 17 00:00:00 2001 From: Madeline Cronin Date: Wed, 4 Sep 2024 20:43:50 +0100 Subject: [PATCH] Implement memory access instructions and fix small errors. The small errors were because this one is a dumbass that forgot to run cargo check before making the last commit. Read from serial port is unimplemented as handling of stdin is planned to be handled in the main program loop. --- src/processor.rs | 69 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/src/processor.rs b/src/processor.rs index e50816a..c7cd3f5 100644 --- a/src/processor.rs +++ b/src/processor.rs @@ -3,16 +3,18 @@ pub struct Processor<'a> { flags: [bool;2], //Flag A, then B itr_toggle: bool, //Interrupt toggle pub memory: &'a mut [u16], //Public since memory should be modifiable by the system. - pub disk: &'a mut [u16], + pub disk: &'a mut [u16], + pub vram: &'a mut [u16], } -pub fn new<'a>(memory: &'a mut [u16], disk: &'a mut [u16]) -> Processor<'a> { +pub fn new<'a>(memory: &'a mut [u16], disk: &'a mut [u16], vram: &'a mut [u16]) -> Processor<'a> { Processor { reg: [0;32], flags: [false;2], itr_toggle: false, memory, - disk + disk, + vram, } } @@ -115,7 +117,7 @@ impl <'a> Processor<'a> { } } _ => return true - } +} if toggles.3 {self.reg[operands.2] = !self.reg[operands.2]}; if let Some(addr) = pc_overwrite {self.reg[31] = addr}; self.reg[31] += 2; @@ -218,17 +220,17 @@ impl <'a> Processor<'a> { self.memory[self.reg[30] as usize] } else { //Use a register value - let operand: usize = (instruction.1 & 0xF800) >> 11 as usize; + let operand: usize = ((instruction.1 & 0xF800) >> 11) as usize; self.reg[operand] } - } + }; if toggles.1 { //Push to stack self.memory[self.reg[30] as usize] = self.reg[31] + 2; self.reg[30] -= 1; } if toggles.0 { //Relative jump - self.reg[31].wrapping_add(address); + self.reg[31] = self.reg[31].wrapping_add(address); } else { //Static jump self.reg[31] = address; @@ -239,6 +241,59 @@ impl <'a> Processor<'a> { } return false } + 0x0500 => { //Memory Access + let rw_toggle: bool = (instruction.0 & 0x0080) != 0; //False for read, true for + //write + let access_type: u16 = (instruction.0 & 0x0070) >> 4; + + let operands: (usize, usize) = ( + ((instruction.1 & 0xF800) >> 11) as usize, + ((instruction.1 & 0x07C0) >> 6) as usize, + ); + if rw_toggle { + match access_type { + 0 => { //Stack + self.memory[self.reg[30] as usize] = self.reg[operands.0]; + self.reg[30] -= 1; + } + 1 => { //Main Memory + self.memory[self.reg[operands.1] as usize] = self.reg[operands.0]; + } + 2 => { //Disk + self.disk[self.reg[operands.1] as usize] = self.reg[operands.0]; + } + 3 => { //VRAM + self.vram[self.reg[operands.1] as usize] = self.reg[operands.0]; + } + 4 => { //Serial port + print!("{}", self.reg[operands.0] as u8 as char); + } + _ => return true + } + } + else { + if operands.0 == 31 { //Skip the operation if writing to program counter, as + //program counter is inaccessible for non-control flow + //instructions + self.reg[31] += 2; + return false + } + match access_type { + 0 => { //Stack + self.reg[30] += 1; + self.reg[operands.0] = self.memory[self.reg[30] as usize]; + } + 1 => self.reg[operands.0] = self.memory[self.reg[operands.1] as usize], //Main memory + 2 => self.reg[operands.0] = self.disk[self.reg[operands.1] as usize], //Disk + 3 => self.reg[operands.0] = self.vram[self.reg[operands.1] as usize], //VRAM + 4 => todo!(), //Serial port, todo as stdin handling would be preferably + //dealt with as part of the main program loop + _ => return true + } + } + self.reg[31] += 2; + return false + } _ => return true, } } -- 2.43.4