Skip to content

Commit

Permalink
Implement Thumb: * mov Rd, Rm; * movs Rd, immediate_8; * movs Rd, Rm;…
Browse files Browse the repository at this point in the history
… Update readme; Rename condition method to check_condition;
  • Loading branch information
bjoernager committed Jul 2, 2023
1 parent 52d65e5 commit f5cc136
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 16 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.txt
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "luma"
version = "0.40.0"
version = "0.41.0"
authors = ["Gabriel Jensen"]
edition = "2021"
description = "AGB emulator."
Expand Down
4 changes: 4 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion src/luma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 6 additions & 1 deletion src/luma/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -52,6 +52,11 @@ pub enum Branch {
Register(u8),
}

pub enum Move {
Immediate(u8),
Register( u8),
}

pub struct Device {
pub decode: fn(&mut Device),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
14 changes: 7 additions & 7 deletions src/luma/device/decode_arm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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;
Expand All @@ -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();
}

Expand Down
32 changes: 31 additions & 1 deletion src/luma/device/decode_thumb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
Expand Down
15 changes: 11 additions & 4 deletions src/luma/device/move.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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})"),
});
}
}

0 comments on commit f5cc136

Please sign in to comment.