summaryrefslogtreecommitdiff
path: root/src/luma/application/decode.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/luma/application/decode.rs')
-rw-r--r--src/luma/application/decode.rs45
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!();
+ }
+}