diff options
Diffstat (limited to 'src/luma/application/decode.rs')
-rw-r--r-- | src/luma/application/decode.rs | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/src/luma/application/decode.rs b/src/luma/application/decode.rs new file mode 100644 index 0000000..feca794 --- /dev/null +++ b/src/luma/application/decode.rs @@ -0,0 +1,45 @@ +// Copyright 2021-2023 Gabriel Jensen. + +use crate::luma::application::{Application, TrapKind}; + +impl Application { + pub fn decode(&mut self, opcode: u32) { + let condition = match opcode & 0b11110000000000000000000000000 { + 0b00000000000000000000000000000 => self.psr & 0b01000000000000000000000000000000 != 0x00, + 0b00010000000000000000000000000 => self.psr & 0b01000000000000000000000000000000 == 0x00, + 0b00100000000000000000000000000 => self.psr & 0b00100000000000000000000000000000 != 0x00, + 0b00110000000000000000000000000 => self.psr & 0b00100000000000000000000000000000 == 0x00, + 0b01000000000000000000000000000 => self.psr & 0b10000000000000000000000000000000 != 0x00, + 0b01010000000000000000000000000 => self.psr & 0b10000000000000000000000000000000 == 0x00, + 0b01100000000000000000000000000 => self.psr & 0b00010000000000000000000000000000 != 0x00, + 0b01110000000000000000000000000 => self.psr & 0b00010000000000000000000000000000 == 0x00, + 0b10000000000000000000000000000 => self.psr & 0b00100000000000000000000000000000 != 0x00 && self.psr & 0b01000000000000000000000000000000 == 0x00, + 0b10010000000000000000000000000 => self.psr & 0b00100000000000000000000000000000 == 0x00 && self.psr & 0b01000000000000000000000000000000 != 0x00, + 0b10100000000000000000000000000 => self.psr & 0b00010000000000000000000000000000 >> 0x1C == self.psr & 0b10000000000000000000000000000000 >> 0x1F, + 0b10110000000000000000000000000 => self.psr & 0b00010000000000000000000000000000 >> 0x1C != self.psr & 0b10000000000000000000000000000000 >> 0x1F, + 0b11000000000000000000000000000 => self.psr & 0b01000000000000000000000000000000 == 0x00 && self.psr & 0b00010000000000000000000000000000 >> 0x1C == self.psr & 0b10000000000000000000000000000000 >> 0x1F, + 0b11010000000000000000000000000 => self.psr & 0b01000000000000000000000000000000 != 0x00 || self.psr & 0b00010000000000000000000000000000 >> 0x1C != self.psr & 0b10000000000000000000000000000000 >> 0x1F, + 0b11100000000000000000000000000 => true, + _ => { self.trap(TrapKind::InvalidOpcode, Some(self.registers[0xF] - 0x8), Some(opcode), None); unreachable!(); }, + }; + if !condition { return }; + + if opcode & 0b00001110000000000000000000000000 == 0b00001010000000000000000000000000 { + let off = opcode & 0b00000000111111111111111111111111; // Offset from pc. + let inv = !(opcode - 0x1) & 0b00000000111111111111111111111111; // Inverted offset. + + if opcode & 0b00000001000000000000000000000000 != 0x0 { self.registers[0xE] = self.registers[0xF] - 0x4; } + + self.registers[0xF] = match (off & 0b00000000100000000000000000000000) != 0x0 { // If negative... + false => self.registers[0xF] + off * 0x4 + 0x8, + true => self.registers[0xF] - inv * 0x4 + 0x8, + }; + + eprintln!("branch: {:024b} => {:08X}", off, self.registers[0xF] - 0x8); + return; + } + + self.trap(TrapKind::InvalidOpcode, Some(self.registers[0xF] - 0x8), Some(opcode), None); + unreachable!(); + } +} |