summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/luma.rs30
-rw-r--r--src/luma/app.rs15
-rw-r--r--src/luma/app/emu.rs64
-rw-r--r--src/luma/app/end.rs21
-rw-r--r--src/luma/app/ini.rs16
-rw-r--r--src/luma/app/new.rs17
-rw-r--r--src/luma/app/prspar.rs26
-rw-r--r--src/luma/app/run.rs44
-rw-r--r--src/luma/app/trp.rs29
-rw-r--r--src/main.rs10
10 files changed, 272 insertions, 0 deletions
diff --git a/src/luma.rs b/src/luma.rs
new file mode 100644
index 0000000..57c2768
--- /dev/null
+++ b/src/luma.rs
@@ -0,0 +1,30 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+pub mod app;
+
+pub const VER: u32 = 0x1E;
+
+pub const MEMSIZ: usize = 0x0E010000;
+
+pub const BTLSIZ: usize = 0x00004000;
+pub const IMGSIZ: usize = 0x06000000;
+
+pub struct Reg {
+ r0: u32,
+ r1: u32,
+ r2: u32,
+ r3: u32,
+ r4: u32,
+ r5: u32,
+ r6: u32,
+ r7: u32,
+ r8: u32,
+ r9: u32,
+ r10: u32,
+ r11: u32,
+ r12: u32,
+ sp: u32,
+ lr: u32,
+ pc: u32,
+ cpsr: u32,
+}
diff --git a/src/luma/app.rs b/src/luma/app.rs
new file mode 100644
index 0000000..d12dbfa
--- /dev/null
+++ b/src/luma/app.rs
@@ -0,0 +1,15 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+pub mod emu;
+pub mod end;
+pub mod ini;
+pub mod new;
+pub mod prspar;
+pub mod run;
+pub mod trp;
+
+pub struct App {
+ btl: String,
+ img: String,
+ mem: *mut u8,
+}
diff --git a/src/luma/app/emu.rs b/src/luma/app/emu.rs
new file mode 100644
index 0000000..3dad048
--- /dev/null
+++ b/src/luma/app/emu.rs
@@ -0,0 +1,64 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::{MEMSIZ, Reg};
+use crate::luma::app::App;
+
+impl App {
+ pub fn emu(&mut self) {
+ eprintln!("starting emulation");
+
+ // Initialise registers:
+ let mut reg = Reg {
+ r0: 0x00000000,
+ r1: 0x00000000,
+ r2: 0x00000000,
+ r3: 0x00000000,
+ r4: 0x00000000,
+ r5: 0x00000000,
+ r6: 0x00000000,
+ r7: 0x00000000,
+ r8: 0x00000000,
+ r9: 0x00000000,
+ r10: 0x00000000,
+ r11: 0x00000000,
+ r12: 0x00000000,
+ sp: 0x00000000,
+ lr: 0x00000000,
+ pc: 0x08000008,
+ cpsr: 0b00000000000000000000000000001111,
+ };
+
+ //let mem = self.mem; // For convenience.
+
+ eprintln!("starting at 0x{:08X}",reg.pc - 0x8);
+
+ loop {
+ // Check the current address:
+ if reg.pc >= MEMSIZ as u32 {
+ self.end(0x1, Some(format!("out-of-bounds address {:X}",reg.pc).as_str()));
+ }
+
+ // Decode opcode:
+ let opc = unsafe { *(self.mem.add((reg.pc - 0x8) as usize) as *mut u32) };
+
+ // Currently, we only support the bal.w instruction.
+ if opc & 0b11111111000000000000000000000000 == 0b11101010000000000000000000000000 {
+ let off: u32 = opc & 0b00000000111111111111111111111111;
+ let abs: u32 = !(opc - 0x1) & 0b00000000111111111111111111111111;
+
+ reg.pc = match (off & 0b00000000100000000000000000000000) != 0x0 { // If negative...
+ false => reg.pc + off * 0x4 + 0x8,
+ true => reg.pc - abs * 0x4 + 0x8,
+ };
+ eprintln!("branch {off:X} => {:X}",reg.pc);
+
+ continue;
+ } else {
+ self.trp(&reg, opc);
+ }
+
+ // Continue:
+ reg.pc += 0x4;
+ }
+ }
+}
diff --git a/src/luma/app/end.rs b/src/luma/app/end.rs
new file mode 100644
index 0000000..db2c842
--- /dev/null
+++ b/src/luma/app/end.rs
@@ -0,0 +1,21 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::MEMSIZ;
+use crate::luma::app::App;
+
+use std::alloc::{dealloc, Layout};
+use std::process::exit;
+
+impl App {
+ pub fn end(&mut self, cod: u8, msg: Option<&str>) {
+ if cod != 0x0 {
+ eprintln!("error: {}", msg.unwrap());
+ }
+
+ eprintln!("ending");
+
+ unsafe { dealloc(self.mem, Layout::new::<[u32; MEMSIZ/0x20usize]>()) };
+
+ exit(cod as i32);
+ }
+}
diff --git a/src/luma/app/ini.rs b/src/luma/app/ini.rs
new file mode 100644
index 0000000..f4ee5e7
--- /dev/null
+++ b/src/luma/app/ini.rs
@@ -0,0 +1,16 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::MEMSIZ;
+use crate::luma::app::App;
+
+use std::alloc::{alloc_zeroed, Layout};
+
+impl App {
+ pub fn ini(&mut self) {
+ eprintln!("initialising");
+
+ self.mem = unsafe { alloc_zeroed(Layout::new::<[u32; MEMSIZ]>()) };
+
+ eprintln!("allocated memory buffer at 0x{:0X}", self.mem as usize);
+ }
+}
diff --git a/src/luma/app/new.rs b/src/luma/app/new.rs
new file mode 100644
index 0000000..1b30f3e
--- /dev/null
+++ b/src/luma/app/new.rs
@@ -0,0 +1,17 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::app::App;
+
+use std::ptr::null;
+
+impl App {
+ pub fn new() -> App {
+ let app = App {
+ btl: "bootloader.bin".to_string(),
+ img: "image.agb".to_string(),
+ mem: null::<u8>() as *mut u8,
+ };
+
+ return app;
+ }
+}
diff --git a/src/luma/app/prspar.rs b/src/luma/app/prspar.rs
new file mode 100644
index 0000000..2353787
--- /dev/null
+++ b/src/luma/app/prspar.rs
@@ -0,0 +1,26 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::app::App;
+
+use std::env::args;
+
+impl App {
+ pub fn prspar(&mut self) {
+ eprintln!("parsing parameters");
+
+ let arg: Vec<String> = args().collect();
+ let num = arg.len();
+
+ if num >= 0x2 {
+ self.img = arg[0x1].clone();
+ }
+
+ if num >= 0x3 {
+ self.btl = arg[0x2].clone();
+ }
+
+ if num > 0x3 {
+ self.end(0x1,Some(format!("invalid number of parameters ({num})").as_str()));
+ }
+ }
+}
diff --git a/src/luma/app/run.rs b/src/luma/app/run.rs
new file mode 100644
index 0000000..3abbc0a
--- /dev/null
+++ b/src/luma/app/run.rs
@@ -0,0 +1,44 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::{BTLSIZ, IMGSIZ, VER};
+use crate::luma::app::App;
+
+use std::fs::File;
+use std::io::Read;
+use std::slice;
+
+impl App {
+ pub fn run(&mut self) {
+ eprintln!("luma {VER}");
+
+ self.prspar();
+
+ self.ini();
+
+ {
+ eprintln!("loading booatloader \"{}\"",self.btl);
+
+ // Open bootloader:
+ let mut btl = File::open(self.btl.clone()).expect("unable to open bootloader");
+
+ // Read bootloader:
+ let slc = unsafe { slice::from_raw_parts_mut(self.mem.offset(0x00000000), BTLSIZ) };
+ btl.read(slc).expect("unable to read bootloader");
+ }
+
+ {
+ eprintln!("loading image \"{}\"",self.img);
+
+ // Open image:
+ let mut img = File::open(self.img.clone()).expect("unable to open image");
+
+ // Read image:
+ let slc = unsafe { slice::from_raw_parts_mut(self.mem.offset(0x08000000), IMGSIZ) };
+ img.read(slc).expect("unable to read image");
+ }
+
+ self.emu();
+
+ self.end(0x0,None);
+ }
+}
diff --git a/src/luma/app/trp.rs b/src/luma/app/trp.rs
new file mode 100644
index 0000000..7ec4cec
--- /dev/null
+++ b/src/luma/app/trp.rs
@@ -0,0 +1,29 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+use crate::luma::Reg;
+use crate::luma::app::App;
+
+impl App {
+ pub fn trp(&mut self, reg: &Reg, opc: u32) {
+ eprintln!("trap - register dump:");
+ eprintln!("\tr0: {:08X}", reg.r0);
+ eprintln!("\tr1: {:08X}", reg.r1);
+ eprintln!("\tr2: {:08X}", reg.r2);
+ eprintln!("\tr3: {:08X}", reg.r3);
+ eprintln!("\tr4: {:08X}", reg.r4);
+ eprintln!("\tr5: {:08X}", reg.r5);
+ eprintln!("\tr6: {:08X}", reg.r6);
+ eprintln!("\tr7: {:08X}", reg.r7);
+ eprintln!("\tr8: {:08X}", reg.r8);
+ eprintln!("\tr9: {:08X}", reg.r9);
+ eprintln!("\tr10: {:08X}", reg.r10);
+ eprintln!("\tr11: {:08X}", reg.r11);
+ eprintln!("\tr12: {:08X}", reg.r12);
+ eprintln!("\tsp: {:08X}", reg.sp);
+ eprintln!("\tlr: {:08X}", reg.lr);
+ eprintln!("\tpc: {:08X}", reg.pc);
+ eprintln!("\tcpsr: {:032b}", reg.cpsr);
+
+ self.end(0x1, Some(format!("invalid opcode 0x{opc:08X} at 0x{:08X}",reg.pc-0x8).as_str()));
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..aaa0e2b
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,10 @@
+// Copyright 2021-2023 Gabriel Jensen.
+
+mod luma;
+
+use crate::luma::app::App;
+
+fn main() {
+ let mut app = App::new();
+ app.run();
+}