summaryrefslogtreecommitdiff
path: root/src/cpu/fetch_thumb.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/fetch_thumb.rs')
-rw-r--r--src/cpu/fetch_thumb.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/cpu/fetch_thumb.rs b/src/cpu/fetch_thumb.rs
new file mode 100644
index 0000000..cee6ba7
--- /dev/null
+++ b/src/cpu/fetch_thumb.rs
@@ -0,0 +1,54 @@
+/*
+ Copyright 2021-2023 Gabriel Jensen.
+
+ This file is part of Luma.
+
+ Luma is free software: you can redistribute it
+ and/or modify it under the terms of the GNU
+ Affero General Public License as published by
+ the Free Software Foundation, either version 3
+ of the License, or (at your option) any later
+ version.
+
+ Luma is distributed in the hope that it will be
+ useful, but WITHOUT ANY WARRANTY; without even
+ the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Affero General Public License for more details.
+
+ You should have received a copy of the GNU
+ Affero General Public License along with Luma.
+ If not, see <https://www.gnu.org/licenses/>.
+*/
+
+use crate::{Error, log};
+use crate::cpu::{Cpu, take_state};
+use crate::instruction::Instruction;
+use crate::predicate::Predicate;
+
+impl Cpu {
+ pub(super) fn fetch_thumb(&mut self) -> (Instruction, Predicate, u32) {
+ take_state!(state, self);
+
+ let address = state.read_register(0xF).wrapping_sub(0x4);
+ let opcode = state.read_halfword(address);
+ let cpsr = state.read_cpsr();
+
+ drop(state);
+
+ log!();
+ log!(" \u{1B}[1m{opcode:016b}\u{1B}[0m @ \u{1B}[1m{address:08X}\u{1B}[0m - ({})", self.cycle);
+
+ let (instruction, predicate) = Instruction::decode_thumb(opcode);
+
+ match (instruction, predicate) {
+ | (Instruction::Undefined, _)
+ | (_, Predicate::Nv)
+ => Error::InvalidThumbOpcode(address, opcode).trap(),
+
+ _ => {},
+ };
+
+ return (instruction, predicate, cpsr);
+ }
+}