@@ 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,
}
}