summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.txt9
-rw-r--r--Cargo.toml2
-rw-r--r--README.txt4
-rw-r--r--src/luma.rs2
-rw-r--r--src/luma/device.rs7
-rw-r--r--src/luma/device/check_condition.rs (renamed from src/luma/device/condition.rs)2
-rw-r--r--src/luma/device/decode_arm.rs14
-rw-r--r--src/luma/device/decode_thumb.rs32
-rw-r--r--src/luma/device/move.rs15
9 files changed, 71 insertions, 16 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
index e1d5fa3..962e13d 100644
--- a/CHANGELOG.txt
+++ b/CHANGELOG.txt
@@ -1,3 +1,12 @@
+# 0.29
+
+* Implement Thumb:
+ * mov Rd, Rm;
+ * movs Rd, immediate_8;
+ * movs Rd, Rm;
+* Update readme;
+* Rename condition method to check_condition;
+
# 0.28
* Fix wrong license in readme;
diff --git a/Cargo.toml b/Cargo.toml
index 7b57df9..a074240 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "luma"
-version = "0.40.0"
+version = "0.41.0"
authors = ["Gabriel Jensen"]
edition = "2021"
description = "AGB emulator."
diff --git a/README.txt b/README.txt
index 4525988..d95258d 100644
--- a/README.txt
+++ b/README.txt
@@ -51,6 +51,7 @@ will be skipped.
* bx Rm
* ldr{cond} Rn, +/-offset_12
* mov{cond} Rd, Rn
+ * mov{cond} Rd, immediate_8
* mov{cons}s r15, Rn
* str{cond} Rn, +/-offset_12
@@ -59,6 +60,9 @@ Moreover, the following Thumb instructions are supported:
* b +/-offset_11
* b{cond} +/-offset_8
* bx Rm
+ * mov Rd, Rn
+ * movs Rd, immediate_8
+ * movs Rd, Rn
When the virtual processor boots, the default mode is the sys mode. As no
supported instruction can change this mode, this is also the only mode for now.
diff --git a/src/luma.rs b/src/luma.rs
index 2d52699..16c1941 100644
--- a/src/luma.rs
+++ b/src/luma.rs
@@ -32,7 +32,7 @@ pub struct VersionType<T> {
pub const VERSION: VersionType::<u32> = VersionType::<u32> {
major: 0x0,
- minor: 0x28,
+ minor: 0x29,
};
pub const CONFIGURATION_VERSION: u32 = 0x0;
diff --git a/src/luma/device.rs b/src/luma/device.rs
index 21a68c5..c3d5092 100644
--- a/src/luma/device.rs
+++ b/src/luma/device.rs
@@ -23,7 +23,7 @@
pub mod bootloader;
pub mod branch;
-pub mod condition;
+pub mod check_condition;
pub mod r#continue;
pub mod decode_arm;
pub mod decode_thumb;
@@ -52,6 +52,11 @@ pub enum Branch {
Register(u8),
}
+pub enum Move {
+ Immediate(u8),
+ Register( u8),
+}
+
pub struct Device {
pub decode: fn(&mut Device),
diff --git a/src/luma/device/condition.rs b/src/luma/device/check_condition.rs
index d72993c..b202448 100644
--- a/src/luma/device/condition.rs
+++ b/src/luma/device/check_condition.rs
@@ -24,7 +24,7 @@
use crate::luma::device::Device;
impl Device {
- pub fn condition(&self, condition: u8) -> bool {
+ pub fn check_condition(&self, condition: u8) -> bool {
return match condition {
0x0 => self.cpsr & 0b01000000000000000000000000000000 != 0x00,
0x1 => self.cpsr & 0b01000000000000000000000000000000 == 0x00,
diff --git a/src/luma/device/decode_arm.rs b/src/luma/device/decode_arm.rs
index e8a6e43..4aa3216 100644
--- a/src/luma/device/decode_arm.rs
+++ b/src/luma/device/decode_arm.rs
@@ -21,7 +21,7 @@
see <https://www.gnu.org/licenses/>.
*/
-use crate::luma::device::{Branch, Device, Trap};
+use crate::luma::device::{Branch, Device, Move, Trap};
impl Device {
pub fn decode_arm(&mut self) {
@@ -33,9 +33,9 @@ impl Device {
if cfg!(debug_assertions) { eprintln!("{opcode:#034b} @ {address:#010X}") }
let condition = ((opcode & 0b11110000000000000000000000000000) >> 0x1C) as u8;
- if !self.condition(condition) { return self.r#continue() }
+ if !self.check_condition(condition) { return self.r#continue() }
- // b{cond}{l}
+ // b{cond}{l} +/-offset_24
if opcode & 0b00001110000000000000000000000000 == 0b00001010000000000000000000000000 {
let link = opcode & 0b00000001000000000000000000000000 != 0x0;
@@ -52,14 +52,14 @@ impl Device {
return self.branch(Branch::Offset(offset, link));
}
- // bx
+ // bx{cond} Rm
if opcode & 0b00001111111111111111111111110000 == 0b00000001001011111111111100010000 {
let register = (opcode & 0b00000000000000000000000000001111) as u8;
return self.branch(Branch::Register(register));
}
- // ldr|str{cond}{b}
+ // ldr|str{cond}{b} Rn, +/-offset_12
if opcode & 0b00001111001000000000000000000000 == 0b00000101000000000000000000000000 {
let register = ((opcode & 0b00000000000000001111000000000000) >> 0xC) as u8;
@@ -75,7 +75,7 @@ impl Device {
return self.r#continue();
}
- // mov{cond}{s}
+ // mov{cond}{s} Rd, Rn
if opcode & 0b00001101111111100000111111110000 == 0b00000001101000000000000000000000 {
let destination = ((opcode & 0b00000000000000001111000000000000) >> 0xC) as u8;
let source = (opcode & 0b00000000000000000000000000001111) as u8;
@@ -85,7 +85,7 @@ impl Device {
let s = opcode & 0b00000000000100000000000000000000 != 0x0;
- self.r#move(destination, source, s);
+ self.r#move(destination, Move::Register(source), s);
return self.r#continue();
}
diff --git a/src/luma/device/decode_thumb.rs b/src/luma/device/decode_thumb.rs
index 1e57659..5ccd9ee 100644
--- a/src/luma/device/decode_thumb.rs
+++ b/src/luma/device/decode_thumb.rs
@@ -21,7 +21,7 @@
see <https://www.gnu.org/licenses/>.
*/
-use crate::luma::device::{Branch, Device, Trap};
+use crate::luma::device::{Branch, Device, Move, Trap};
impl Device {
pub fn decode_thumb(&mut self) {
@@ -69,6 +69,36 @@ impl Device {
return self.branch(Branch::Register(register));
}
+ // mov Rd, Rm
+ if opcode & 0b1111111100000000 == 0b0100011000000000 {
+ let destination = ((opcode & 0b0000000000000111) | (opcode & 0b0000000010000000) >> 0x4) as u8;
+
+ let source = ((opcode & 0b0000000001111000) >> 0x3) as u8;
+
+ self.r#move(destination, Move::Register(source), false);
+ return self.r#continue();
+ }
+
+ // movs Rd, immediate_8
+ if opcode & 0b1111100000000000 == 0b0010000000000000 {
+ let destination = ((opcode & 0b0000011100000000) >> 0x8) as u8;
+
+ let immediate = (opcode & 0b0000000011111111) as u8;
+
+ self.r#move(destination, Move::Immediate(immediate), true);
+ return self.r#continue();
+ }
+
+ // movs Rd, Rn
+ if opcode & 0b1111111111000000 == 0b0001110000000000 {
+ let destination = ((opcode & 0b0000000000000111) >> 0x3) as u8;
+
+ let source = ((opcode & 0b0000000000111000) >> 0x3) as u8;
+
+ self.r#move(destination, Move::Register(source), true);
+ return self.r#continue();
+ }
+
self.trap(Trap::InvalidThumbOpcode(address, opcode));
self.r#continue();
diff --git a/src/luma/device/move.rs b/src/luma/device/move.rs
index 6cc7dab..9818f68 100644
--- a/src/luma/device/move.rs
+++ b/src/luma/device/move.rs
@@ -21,11 +21,15 @@
see <https://www.gnu.org/licenses/>.
*/
-use crate::luma::device::Device;
+use crate::luma::device::{Device, Move};
impl Device {
- pub fn r#move(&mut self, destination: u8, source: u8, s: bool) {
- let value = self.registers[source as usize];
+ pub fn r#move(&mut self, destination: u8, kind: Move, s: bool) {
+ let value = match kind {
+ Move::Immediate(immediate) => immediate as u32,
+ Move::Register( source) => self.registers[source as usize],
+ };
+
self.registers[destination as usize] = value;
if s { // Check the s flag.
@@ -36,6 +40,9 @@ impl Device {
}
}
- self.log("move", format!("r{destination} => r{source} ({value:#010X})"));
+ self.log("move", match kind {
+ Move::Immediate(..) => format!("r{destination} => {value:#04X}"),
+ Move::Register( source) => format!("r{destination} => r{source} ({value:#010X})"),
+ });
}
} \ No newline at end of file