diff options
-rw-r--r-- | CHANGELOG.txt | 7 | ||||
-rw-r--r-- | Cargo.toml | 3 | ||||
-rw-r--r-- | README.html | 2 | ||||
-rw-r--r-- | src/luma.rs | 11 | ||||
-rw-r--r-- | src/luma/application.rs | 25 | ||||
-rw-r--r-- | src/luma/application/bootloader.rs (renamed from src/luma/emulator/bootloader.rs) | 4 | ||||
-rw-r--r-- | src/luma/application/decode.rs (renamed from src/luma/emulator/opcode.rs) | 6 | ||||
-rw-r--r-- | src/luma/application/drop.rs | 6 | ||||
-rw-r--r-- | src/luma/application/image.rs (renamed from src/luma/emulator/image.rs) | 6 | ||||
-rw-r--r-- | src/luma/application/initialise.rs | 45 | ||||
-rw-r--r-- | src/luma/application/load.rs | 26 | ||||
-rw-r--r-- | src/luma/application/new.rs | 12 | ||||
-rw-r--r-- | src/luma/application/read.rs (renamed from src/luma/emulator/read.rs) | 4 | ||||
-rw-r--r-- | src/luma/application/run.rs | 46 | ||||
-rw-r--r-- | src/luma/application/trap.rs (renamed from src/luma/emulator/trap.rs) | 6 | ||||
-rw-r--r-- | src/luma/emulator.rs | 22 | ||||
-rw-r--r-- | src/luma/emulator/drop.rs | 13 | ||||
-rw-r--r-- | src/luma/emulator/new.rs | 39 | ||||
-rw-r--r-- | src/luma/emulator/run.rs | 29 | ||||
-rw-r--r-- | src/main.rs | 2 |
20 files changed, 156 insertions, 158 deletions
diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1639ad2..cc25adf 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,10 @@ +# 0.29 + +* Update version constant to include minor versions; +* Use SDL2 for windowing; +* Combine Application and Emulator structures; +* Rename opcode method to decode; + # 0.28 * Support bl; @@ -1,6 +1,6 @@ [package] name = "luma" -version = "0.32.0" +version = "0.33.0" edition = "2021" [[bin]] @@ -15,3 +15,4 @@ lto = true [dependencies] libc = "0.2.146" +sdl2 = "0.35.2" diff --git a/README.html b/README.html index d7d25d8..71d88b3 100644 --- a/README.html +++ b/README.html @@ -2,7 +2,7 @@ <html> <body> <h1>luma</h1> - <p><a href="https://mandelbrot.dk/luma">luma</a> is a free, open-source, and portable emulator for the luma platform.</p> + <p><a href="https://mandelbrot.dk/luma">luma</a> is a free, open-source, and portable application for the luma platform.</p> <p>This project serves as the reference implementation for the luma platform.</p> <h2 id="copyright-license">Copyright & License</h2> <p>Copyright 2021, 2022 Gabriel Jensen.</p> diff --git a/src/luma.rs b/src/luma.rs index e4a9395..af45480 100644 --- a/src/luma.rs +++ b/src/luma.rs @@ -1,9 +1,16 @@ // Copyright 2021-2023 Gabriel Jensen. pub mod application; -pub mod emulator; -pub const VERSION: u32 = 0x20; +pub struct VersionType<T> { + major: T, + minor: T, +} + +pub const VERSION: VersionType::<u32> = VersionType::<u32> { + major: 0x0, + minor: 0x21, +}; pub const MEMORY_SIZE: usize = 0x0E010000; diff --git a/src/luma/application.rs b/src/luma/application.rs index 4f095c2..63f7d92 100644 --- a/src/luma/application.rs +++ b/src/luma/application.rs @@ -1,17 +1,38 @@ // Copyright 2021-2023 Gabriel Jensen. +extern crate sdl2; + +use sdl2::{Sdl, VideoSubsystem}; +use sdl2::video::Window; use std::sync::atomic::AtomicBool; +pub mod bootloader; +pub mod decode; pub mod drop; pub mod end; +pub mod image; pub mod initialise; -pub mod new; +pub mod load; pub mod parse_parameters; +pub mod read; pub mod run; +pub mod trap; + +pub enum TrapKind { + BadAlignment, + InvalidOpcode, + OutOfBounds, +} pub struct Application { bootloader: String, - image: String, + image: String, + sdl: Sdl, + sdl_video: VideoSubsystem, + window: Window, + memory: *mut u8, + registers: [u32; 0x10], + psr: u32, } pub static mut GOT_SIGNAL: AtomicBool = AtomicBool::new(false); diff --git a/src/luma/emulator/bootloader.rs b/src/luma/application/bootloader.rs index 9aca8eb..2a69447 100644 --- a/src/luma/emulator/bootloader.rs +++ b/src/luma/application/bootloader.rs @@ -1,11 +1,11 @@ // Copyright 2021-2023 Gabriel Jensen. +use crate::luma::application::Application; use crate::luma::BOOTLOADER_SIZE; -use crate::luma::emulator::Emulator; use std::slice; -impl Emulator { +impl Application { pub fn bootloader<'a>(&mut self) -> &'a mut [u8] { return unsafe { slice::from_raw_parts_mut(self.memory.offset(0x00000000), BOOTLOADER_SIZE) }; } diff --git a/src/luma/emulator/opcode.rs b/src/luma/application/decode.rs index b074aa7..feca794 100644 --- a/src/luma/emulator/opcode.rs +++ b/src/luma/application/decode.rs @@ -1,9 +1,9 @@ // Copyright 2021-2023 Gabriel Jensen. -use crate::luma::emulator::{Emulator, TrapKind}; +use crate::luma::application::{Application, TrapKind}; -impl Emulator { - pub fn opcode(&mut self, opcode: u32) { +impl Application { + pub fn decode(&mut self, opcode: u32) { let condition = match opcode & 0b11110000000000000000000000000 { 0b00000000000000000000000000000 => self.psr & 0b01000000000000000000000000000000 != 0x00, 0b00010000000000000000000000000 => self.psr & 0b01000000000000000000000000000000 == 0x00, diff --git a/src/luma/application/drop.rs b/src/luma/application/drop.rs index 8fb7cf1..711e994 100644 --- a/src/luma/application/drop.rs +++ b/src/luma/application/drop.rs @@ -1,9 +1,15 @@ // Copyright 2021-2023 Gabriel Jensen. use crate::luma::application::Application; +use crate::luma::MEMORY_SIZE; + +use std::alloc::{dealloc, Layout}; +use std::mem::size_of; impl Drop for Application { fn drop(&mut self) { + unsafe { dealloc(self.memory, Layout::new::<[u32; MEMORY_SIZE / size_of::<u32>()]>()) }; + self.end(0x0,None); } } diff --git a/src/luma/emulator/image.rs b/src/luma/application/image.rs index d62dc9a..9f2aeae 100644 --- a/src/luma/emulator/image.rs +++ b/src/luma/application/image.rs @@ -1,12 +1,12 @@ // Copyright 2021-2023 Gabriel Jensen. +use crate::luma::application::Application; use crate::luma::IMAGE_SIZE; -use crate::luma::emulator::Emulator; use std::slice; -impl Emulator { +impl Application { pub fn image<'a>(&mut self) -> &'a mut [u8] { return unsafe { slice::from_raw_parts_mut(self.memory.offset(0x08000000), IMAGE_SIZE) }; } -} +}
\ No newline at end of file diff --git a/src/luma/application/initialise.rs b/src/luma/application/initialise.rs index 9b6848b..e9bf0ef 100644 --- a/src/luma/application/initialise.rs +++ b/src/luma/application/initialise.rs @@ -1,11 +1,14 @@ // Copyright 2021-2023 Gabriel Jensen. use crate::luma::application::{Application, GOT_SIGNAL}; +use crate::luma::MEMORY_SIZE; extern crate libc; +extern crate sdl2; use libc::{c_int, sighandler_t, SIGINT, signal, SIGTERM}; -use std::mem::transmute; +use std::alloc::{alloc_zeroed, Layout}; +use std::mem::{size_of, transmute}; use std::sync::atomic::Ordering; fn signal_handler(sig: c_int) { @@ -17,12 +20,50 @@ fn signal_handler(sig: c_int) { } impl Application { - pub fn initialise(&mut self) { + pub fn initialise() -> Application { eprintln!("initialising"); unsafe { signal(SIGINT, transmute::<fn(c_int), sighandler_t>(signal_handler)); signal(SIGTERM, transmute::<fn(c_int), sighandler_t>(signal_handler)); } + + let sdl = sdl2::init().expect("unable to initialise sdl2"); + let sdl_video = sdl.video().expect("unable to initialise sdl2"); + + let window = sdl_video.window("luma", 0xF0, 0xA0).position_centered().build().unwrap(); + + let memory = unsafe { alloc_zeroed(Layout::new::<[u32; MEMORY_SIZE / size_of::<u32>()]>()) }; + if memory.is_null() { panic!("unable to allocate memory buffer") } + + eprintln!("allocated memory buffer at 0x{:0X}", memory as usize); + + return Application { + bootloader: "bootloader.bin".to_string(), + image: "image.agb".to_string(), + sdl: sdl, + sdl_video: sdl_video, + window: window, + memory: memory, + registers: [ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x08000008, + ], + psr: 0b00000000000000000000000000001111, + }; } } diff --git a/src/luma/application/load.rs b/src/luma/application/load.rs new file mode 100644 index 0000000..58491d7 --- /dev/null +++ b/src/luma/application/load.rs @@ -0,0 +1,26 @@ +// Copyright 2021-2023 Gabriel Jensen. + +use crate::luma::application::Application; + +use std::fs::File; +use std::io::Read; + +impl Application { + pub fn load(&mut self) { + eprintln!("loading booatloader \"{}\"", self.bootloader); + + // Open bootloader: + let mut bootloader = File::open(self.bootloader.clone()).expect("unable to open bootloader"); + + // Read bootloader: + bootloader.read(self.bootloader()).expect("unable to read bootloader"); + + eprintln!("loading image \"{}\"", self.image); + + // Open image: + let mut image = File::open(self.image.clone()).expect("unable to open image"); + + // Read image: + image.read(self.image()).expect("unable to read image"); + } +} diff --git a/src/luma/application/new.rs b/src/luma/application/new.rs deleted file mode 100644 index 41d25a7..0000000 --- a/src/luma/application/new.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright 2021-2023 Gabriel Jensen. - -use crate::luma::application::Application; - -impl Application { - pub fn new() -> Application { - return Application { - bootloader: "bootloader.bin".to_string(), - image: "image.agb".to_string(), - }; - } -} diff --git a/src/luma/emulator/read.rs b/src/luma/application/read.rs index f374e4d..40604a9 100644 --- a/src/luma/emulator/read.rs +++ b/src/luma/application/read.rs @@ -1,9 +1,9 @@ // Copyright 2021-2023 Gabriel Jensen. +use crate::luma::application::{Application, TrapKind}; use crate::luma::MEMORY_SIZE; -use crate::luma::emulator::{Emulator, TrapKind}; -impl Emulator { +impl Application { #[allow(dead_code)] pub fn read_byte(&mut self, address: u32) -> u8 { if address >= MEMORY_SIZE as u32 { self.trap(TrapKind::OutOfBounds, Some(address), None, None) }; diff --git a/src/luma/application/run.rs b/src/luma/application/run.rs index 23419be..a0a3f83 100644 --- a/src/luma/application/run.rs +++ b/src/luma/application/run.rs @@ -1,38 +1,42 @@ // Copyright 2021-2023 Gabriel Jensen. +use crate::luma::application::{Application, GOT_SIGNAL}; use crate::luma::VERSION; -use crate::luma::application::Application; -use crate::luma::emulator::Emulator; -use std::fs::File; -use std::io::Read; +use sdl2::event::Event; +use std::sync::atomic::Ordering; impl Application { pub fn run(&mut self) { - eprintln!("luma {VERSION}"); + eprintln!("luma {}.{}", VERSION.major, VERSION.minor); self.parse_parameters(); + self.load(); - self.initialise(); + let mut event_pump = self.sdl.event_pump().expect("unable to get event pump"); - let mut emulator = Emulator::new(); + eprintln!("starting emulation at 0x{:08X}",self.registers[0xF] - 0x8); - eprintln!("loading booatloader \"{}\"",self.bootloader); + 'main_loop: loop { + // Check if we have recieved a signal: + if unsafe { GOT_SIGNAL.load(Ordering::Relaxed) } { + eprintln!("got interrupt"); + break; + } - // Open bootloader: - let mut bootloader = File::open(self.bootloader.clone()).expect("unable to open bootloader"); + for event in event_pump.poll_iter() { + match event { + Event::Quit {..} => break 'main_loop, + _ => {}, + } + } - // Read bootloader: - bootloader.read(emulator.bootloader()).expect("unable to read bootloader"); + // Decode opcode: + let opcode = self.read_word(self.registers[0xF] - 0x8); + self.decode(opcode); - eprintln!("loading image \"{}\"",self.image); - - // Open image: - let mut image = File::open(self.image.clone()).expect("unable to open image"); - - // Read image: - image.read(emulator.image()).expect("unable to read image"); - - emulator.run(); + // Continue: + self.registers[0xF] += 0x4; + } } } diff --git a/src/luma/emulator/trap.rs b/src/luma/application/trap.rs index fa833e5..7f484ba 100644 --- a/src/luma/emulator/trap.rs +++ b/src/luma/application/trap.rs @@ -1,9 +1,9 @@ // Copyright 2021-2023 Gabriel Jensen. +use crate::luma::application::{Application, TrapKind}; use crate::luma::MEMORY_SIZE; -use crate::luma::emulator::{Emulator, TrapKind}; -impl Emulator { +impl Application { pub fn trap(&mut self, kind: TrapKind, address: Option<u32>, opcode: Option<u32>, alignment: Option<u32>) { let message = match kind { TrapKind::BadAlignment => format!("bad alignment of address 0x{:08X} (should be {}-byte aligned)", address.unwrap(), alignment.unwrap()), @@ -29,7 +29,7 @@ impl Emulator { eprintln!("\tsp: {:08X}", self.registers[0xD]); eprintln!("\tlr: {:08X}", self.registers[0xE]); eprintln!("\tpc: {:08X}", self.registers[0xF]); - eprintln!("\topsr: {:032b}", self.psr); + eprintln!("\tcpsr: {:032b}", self.psr); panic!("{message}"); } diff --git a/src/luma/emulator.rs b/src/luma/emulator.rs deleted file mode 100644 index 2a108eb..0000000 --- a/src/luma/emulator.rs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2021-2023 Gabriel Jensen. - -pub mod bootloader; -pub mod drop; -pub mod read; -pub mod image; -pub mod new; -pub mod opcode; -pub mod run; -pub mod trap; - -pub enum TrapKind { - BadAlignment, - InvalidOpcode, - OutOfBounds, -} - -pub struct Emulator { - memory: *mut u8, - registers: [u32; 0x10], - psr: u32, -} diff --git a/src/luma/emulator/drop.rs b/src/luma/emulator/drop.rs deleted file mode 100644 index 6f87867..0000000 --- a/src/luma/emulator/drop.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2021-2023 Gabriel Jensen. - -use crate::luma::MEMORY_SIZE; -use crate::luma::emulator::Emulator; - -use std::alloc::{dealloc, Layout}; -use std::mem::size_of; - -impl Drop for Emulator { - fn drop(&mut self) { - unsafe { dealloc(self.memory, Layout::new::<[u32; MEMORY_SIZE / size_of::<u32>()]>()) }; - } -} diff --git a/src/luma/emulator/new.rs b/src/luma/emulator/new.rs deleted file mode 100644 index e3ab7ef..0000000 --- a/src/luma/emulator/new.rs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2021-2023 Gabriel Jensen. - -use crate::luma::MEMORY_SIZE; -use crate::luma::emulator::Emulator; - -use std::alloc::{alloc_zeroed, Layout}; -use std::mem::size_of; - -impl Emulator { - pub fn new() -> Emulator { - let memory = unsafe { alloc_zeroed(Layout::new::<[u32; MEMORY_SIZE / size_of::<u32>()]>()) }; - if memory.is_null() { panic!("unable to allocate memory buffer") } - - eprintln!("allocated memory buffer at 0x{:0X}", memory as usize); - - return Emulator { - memory: memory, - registers: [ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x08000008, - ], - psr: 0b00000000000000000000000000001111, - }; - } -} diff --git a/src/luma/emulator/run.rs b/src/luma/emulator/run.rs deleted file mode 100644 index 001bbe4..0000000 --- a/src/luma/emulator/run.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2021-2023 Gabriel Jensen. - -use crate::luma::application::GOT_SIGNAL; -use crate::luma::emulator::Emulator; - -use std::sync::atomic::Ordering; - -impl Emulator { - pub fn run(&mut self) { - eprintln!("starting emulation"); - - eprintln!("starting at 0x{:08X}",self.registers[0xF] - 0x8); - - loop { - // Check if we have recieved a signal: - if unsafe { GOT_SIGNAL.load(Ordering::Relaxed) } { - eprintln!("got interrupt"); - break; - } - - // Decode opcode: - let opcode = self.read_word(self.registers[0xF] - 0x8); - self.opcode(opcode); - - // Continue: - self.registers[0xF] += 0x4; - } - } -} diff --git a/src/main.rs b/src/main.rs index 82d3609..92e5dcc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,6 @@ mod luma; use crate::luma::application::Application; fn main() { - let mut application = Application::new(); + let mut application = Application::initialise(); application.run(); } |