~maddie/custom-processor-simulator

425f054548c5cd678a74f4d5e099ec130e6d9246 — Madeline Cronin 3 months ago 4fb5ee1
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.
1 files changed, 62 insertions(+), 7 deletions(-)

M src/processor.rs
M src/processor.rs => src/processor.rs +62 -7
@@ 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,
        }
    }