mega refactor:

essentially completely reorganised the project.
previous contents of the dsa folder have now been split into emulator/ tooling/ and libraries/
libraries is for common functionality across crates, tooling is for core binaries needed for building and debugging DSA projects, including dsx client/server/build
emulator contains the dsa_emulator crate that implements the core DSA emulator, the dsa_gui crate that implements the graphical user interface for the emulator & all future tooling under a unified application, and finally the dsa_cli crate which will eventually provide lightweight wrapper for the core emulator, simply providing a tool for running DSA binaries without the overhead of a heavy GUI.
This commit is contained in:
2026-08-01 01:28:11 +01:00
parent 8c19497bc7
commit 27d38eaf89
120 changed files with 84 additions and 90 deletions
+13 -12
View File
@@ -3,18 +3,19 @@
<component name="NewModuleRootManager"> <component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$"> <content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/dsa/assembler_old/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/dsa/assembler_old/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/common/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/emulator/dsa_cli/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/compiler/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/emulator/dsa_emulator/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/linker/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/emulator/dsa_gui/benches" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/dsa/assembler/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/emulator/dsa_gui/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/disassembler/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/libraries/common/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/emulator/emulator_core/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/libraries/dsa_formats/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/emulator/emulator_ui/benches" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/tooling/assembler/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/emulator/emulator_ui/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/tooling/compiler/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsx/dsx_client/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/tooling/disassembler/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsx/dsx_common/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/tooling/dsx_build/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsx/dsx_server/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/tooling/dsx_client/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/dsa/dsa_formats/src" isTestSource="false" /> <sourceFolder url="file://$MODULE_DIR$/tooling/dsx_server/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tooling/linker/src" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.idea/caches" /> <excludeFolder url="file://$MODULE_DIR$/.idea/caches" />
<excludeFolder url="file://$MODULE_DIR$/doc/.obsidian" /> <excludeFolder url="file://$MODULE_DIR$/doc/.obsidian" />
<excludeFolder url="file://$MODULE_DIR$/target" /> <excludeFolder url="file://$MODULE_DIR$/target" />
+6 -1
View File
@@ -1,5 +1,10 @@
[workspace] [workspace]
members = ["dsa/common", "dsa/assembler", "dsa/emulator/emulator_ui", "dsa/linker", "dsa/compiler", "dsa/emulator/emulator_core", "dsx/dsx_common", "dsx/dsx_server", "dsx/dsx_client", "dsa/disassembler", "dsa/dsa_formats"] members = [
"emulator/dsa_emulator", "emulator/dsa_gui", "emulator/dsa_cli",
"libraries/common", "libraries/dsa_formats",
"tooling/assembler", "tooling/disassembler", "tooling/linker", "tooling/compiler",
"tooling/dsx_build", "tooling/dsx_server", "tooling/dsx_client"]
resolver = "3" resolver = "3"
[workspace.package] [workspace.package]
-17
View File
@@ -1,17 +0,0 @@
The DSA libraries form the foundation of the entire project, acting as a bridge between high‑level software and the specialized DSA hardware. Their primary responsibilities are:
1. **Instruction Set Core Library**
- Encapsulates all architectural primitives: opcodes, operand formats, and execution semantics.
- Supplies utility functions to build, validate, and serialize instruction streams.
2. **Assembler Support**
- Translates DSA assembly language into binary instruction packets that the hardware can execute.
- Implements directives for sectioning, alignment, and relocation handling.
3. **High‑Level Language Compiler (DSC) Runtime**
- Generates DSA bytecode from DSC source files, leveraging the core library for instruction encoding.
- Offers debugging hooks, profiling counters, and exception handling mechanisms.
4. **Testing & Verification Utilities**
- Contains unit tests that run against both emulated and real hardware to ensure correctness.
- Provides logging facilities for low‑level bus transactions and performance metrics.
@@ -1,2 +0,0 @@
pub const DEFAULT_MEMORY_MAP: &'static str = include_str!("./dsa.mmap.ron");
pub const DEFAULT_IO_MAP: &'static str = include_str!("./dsa.iomap.ron");
-8
View File
@@ -1,8 +0,0 @@
DSX is a collection of higher‑level tools that orchestrate the DSA ecosystem.
While **DSA** supplies the core emulator, compiler, assembler and runtime, DSX provides:
* **dsx-client** – A package manager that interacts with servers, managing packages and DSA repositories on the local machine
* **dsx-server** – A lightweight package repository server that hosts DSX packages, enabling sharing and version control across teams, with CI/CD configured out‑of‑the‑box.
* **dsx-common** - A set of common utilities between dsx-client and dsx-server, including the build system itself
Together, these tools streamline development workflows, automate builds, and manage the distribution of DSA components within an organization.
@@ -1,5 +1,5 @@
[package] [package]
name = "dsx_common" name = "dsa_cli"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true
authors.workspace = true authors.workspace = true
@@ -1,15 +1,15 @@
[package] [package]
name = "emulator_core" name = "dsa_emulator"
edition.workspace = true edition.workspace = true
version.workspace = true version.workspace = true
authors.workspace = true authors.workspace = true
[lib] [lib]
name = "emulator_core" name = "dsa_emulator"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
arc-swap = "1.9.2" arc-swap = "1.9.2"
common = { version = "0.1.0", path = "../../common" } common = { version = "0.1.0", path = "../../libraries/common" }
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
ron = "0.12.2" ron = "0.12.2"
@@ -0,0 +1,2 @@
pub const DEFAULT_MEMORY_MAP: &'static str = include_str!("dsa.mmap.ron");
pub const DEFAULT_IO_MAP: &'static str = include_str!("dsa.iomap.ron");
@@ -53,7 +53,7 @@ impl Serial {
handle.write_byte(uart_base + 2, 0x01); handle.write_byte(uart_base + 2, 0x01);
} }
// Presumably emulator thread has shut down by this point. // Presumably dsa_emulator thread has shut down by this point.
if handle.interrupt(Interrupt::SerialIn).is_err() { if handle.interrupt(Interrupt::SerialIn).is_err() {
return; return;
} }
@@ -24,10 +24,10 @@ pub enum DsaError {
CriticalException(String), CriticalException(String),
} }
/// This trait should be implemented for any type that can act as a fully functional DSA emulator with the ability to share state /// This trait should be implemented for any type that can act as a fully functional DSA dsa_emulator with the ability to share state
pub trait DsaImplementation: Send { pub trait DsaImplementation: Send {
/// may be modified in future with extra args like config /// may be modified in future with extra args like config
/// having direct control over the emulator's POST/boot state can be useful for /// having direct control over the dsa_emulator's POST/boot state can be useful for
/// integration testing. /// integration testing.
fn boot(&mut self) -> Result<(), DsaError>; fn boot(&mut self) -> Result<(), DsaError>;
@@ -36,7 +36,7 @@ pub trait DsaImplementation: Send {
/// main run method. the main-loop of the program execution /// main run method. the main-loop of the program execution
fn run(&mut self) -> Result<(), DsaError>; fn run(&mut self) -> Result<(), DsaError>;
/// memory mapping is required for emulator memory sections /// memory mapping is required for dsa_emulator memory sections
fn apply_memory_map(&mut self, map: MemoryMap); fn apply_memory_map(&mut self, map: MemoryMap);
/// IO mapping also /// IO mapping also
@@ -46,10 +46,10 @@ pub trait DsaImplementation: Send {
/// returns a copy of the IOmap (cannot be a reference since across-threads) /// returns a copy of the IOmap (cannot be a reference since across-threads)
fn get_io_map(&self) -> IoMap; fn get_io_map(&self) -> IoMap;
/// returns a wrapper around the physical memory used by the emulator /// returns a wrapper around the physical memory used by the dsa_emulator
fn get_memory_handle(&mut self) -> &mut MemoryBank; fn get_memory_handle(&mut self) -> &mut MemoryBank;
/// returns a wrapper around the shared state of the emulator /// returns a wrapper around the shared state of the dsa_emulator
fn get_state_handle(&mut self) -> Arc<SharedState>; fn get_state_handle(&mut self) -> Arc<SharedState>;
} }
@@ -98,12 +98,12 @@ impl EmulatorHandle {
} }
/// Request that the emulator backend provide an updated copy of its current internal state to `state.proc` /// Request that the dsa_emulator backend provide an updated copy of its current internal state to `state.proc`
pub fn request_update(&mut self) { pub fn request_update(&mut self) {
self.state.update_requested.store(true, Ordering::Relaxed); self.state.update_requested.store(true, Ordering::Relaxed);
} }
/// Request that the emulator backend pauses it's current execution /// Request that the dsa_emulator backend pauses it's current execution
/// no-op if in the `Paused` state /// no-op if in the `Paused` state
pub fn request_pause(&mut self) { pub fn request_pause(&mut self) {
self.state.pause_requested.store(true, Ordering::Relaxed); self.state.pause_requested.store(true, Ordering::Relaxed);
@@ -119,13 +119,13 @@ impl EmulatorHandle {
f(self); f(self);
} }
/// Request that the emulator backend resumes it's current execution /// Request that the dsa_emulator backend resumes it's current execution
/// no-op if not in the `Paused` state /// no-op if not in the `Paused` state
pub fn request_resume(&mut self) { pub fn request_resume(&mut self) {
self.state.pause_requested.store(false, Ordering::Relaxed); self.state.pause_requested.store(false, Ordering::Relaxed);
} }
/// Request that the emulator backend performs a full reset, clearing all memory, registers and other internal state. /// Request that the dsa_emulator backend performs a full reset, clearing all memory, registers and other internal state.
pub fn reset(&mut self) { pub fn reset(&mut self) {
self.state.reset_requested.store(true, Ordering::Relaxed); self.state.reset_requested.store(true, Ordering::Relaxed);
@@ -150,7 +150,7 @@ enum InternalImplementation {
} }
pub struct EmulatorController { pub struct EmulatorController {
// the emulator itself // the dsa_emulator itself
internal: Option<InternalImplementation>, internal: Option<InternalImplementation>,
handle: EmulatorHandle, handle: EmulatorHandle,
} }
@@ -177,7 +177,7 @@ impl EmulatorController {
const STACK_SIZE: usize = 1024 * 1024 * 16; const STACK_SIZE: usize = 1024 * 1024 * 16;
let Some(Owned(mut handle)) = self.internal.take() else { let Some(Owned(mut handle)) = self.internal.take() else {
return Err(DsaError::CriticalException(String::from("owned emulator returned none!"))) return Err(DsaError::CriticalException(String::from("owned dsa_emulator returned none!")))
}; };
self.internal = Some(Handle( self.internal = Some(Handle(
@@ -386,7 +386,7 @@ impl DsaProcessor {
impl Drop for DsaProcessor { impl Drop for DsaProcessor {
fn drop(&mut self) { fn drop(&mut self) {
// drop is only ever called once on an emulator instance, so we can be sure a double free will not happen. // drop is only ever called once on an dsa_emulator instance, so we can be sure a double free will not happen.
unsafe { self.mainstore.dealloc() } unsafe { self.mainstore.dealloc() }
} }
} }
@@ -1,5 +1,5 @@
[package] [package]
name = "emulator_ui" name = "dsa_gui"
version.workspace = true version.workspace = true
edition.workspace = true edition.workspace = true
authors.workspace = true authors.workspace = true
@@ -13,11 +13,11 @@ name = "dsa"
path = "src/lib.rs" path = "src/lib.rs"
[dependencies] [dependencies]
common = { path = "../../common" } common = { path = "../../libraries/common" }
dsa_formats = { path = "../../dsa_formats" } dsa_formats = { path = "../../libraries/dsa_formats" }
assembler = { path = "../../assembler" } assembler = { path = "../../tooling/assembler" }
emulator_core = { version = "0.3.0", path = "../emulator_core" } dsa_emulator = { version = "0.3.0", path = "../dsa_emulator" }
disassembler = { version = "0.3.0", path = "../../disassembler" } disassembler = { version = "0.3.0", path = "../../tooling/disassembler" }
clap = { version = "4.5.60", features = ["derive"] } clap = { version = "4.5.60", features = ["derive"] }
ron = "0.12.0" ron = "0.12.0"
@@ -2,7 +2,7 @@ use std::{fs, path::PathBuf};
use clap::Parser; use clap::Parser;
use emulator_core::config::{IoMap, MemoryMap}; use dsa_emulator::config::{IoMap, MemoryMap};
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
#[command(version, about, long_about = None)] #[command(version, about, long_about = None)]
@@ -1,13 +1,13 @@
use crate::ui::DamnSimpleUI; use crate::ui::DamnSimpleUI;
use eframe::NativeOptions; use eframe::NativeOptions;
use emulator_core::EmulatorController; use dsa_emulator::EmulatorController;
pub mod ui; pub mod ui;
pub mod args; pub mod args;
pub mod state; pub mod state;
pub fn run_app(mut controller: EmulatorController) -> eframe::Result<()> { pub fn run_app(mut controller: EmulatorController) -> eframe::Result<()> {
// initialise emulator // initialise dsa_emulator
controller.run().unwrap(); controller.run().unwrap();
eframe::run_native( eframe::run_native(
@@ -2,7 +2,7 @@ use clap::Parser;
use dsa::args::DsaArgs; use dsa::args::DsaArgs;
use dsa::run_app; use dsa::run_app;
use emulator_core::{DsaImplementation, EmulatorController, processor::Emulator}; use dsa_emulator::{DsaImplementation, EmulatorController, processor::Emulator};
fn main() { fn main() {
let args = DsaArgs::parse(); let args = DsaArgs::parse();
@@ -1,7 +1,7 @@
use eframe::epaint::Color32; use eframe::epaint::Color32;
use common::prelude::Register; use common::prelude::Register;
use emulator_core::EmulatorHandle; use dsa_emulator::EmulatorHandle;
use emulator_core::processor::RunningState; use dsa_emulator::processor::RunningState;
use crate::ui::ui_helpers::PaddedWidget; use crate::ui::ui_helpers::PaddedWidget;
pub struct Controller { pub struct Controller {
@@ -11,9 +11,9 @@ use dialogs::file_dialog::DsaFileDialog;
use dsa_formats::binary_dse::DseExecutable; use dsa_formats::binary_dse::DseExecutable;
use egui::{CentralPanel, Panel, Ui}; use egui::{CentralPanel, Panel, Ui};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::EmulatorController; use dsa_emulator::EmulatorController;
use emulator_core::devices::display::Display; use dsa_emulator::devices::display::Display;
use emulator_core::devices::serial::Serial; use dsa_emulator::devices::serial::Serial;
use tiles::PanelFactory; use tiles::PanelFactory;
use tiles::documentation::Documentation; use tiles::documentation::Documentation;
use tiles::editor::Editor; use tiles::editor::Editor;
@@ -3,7 +3,7 @@ use crate::ui::tiles::TilePane;
use eframe::epaint::Direction; use eframe::epaint::Direction;
use egui::{Ui, WidgetText}; use egui::{Ui, WidgetText};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::config::VERSION; use dsa_emulator::config::VERSION;
use std::any::Any; use std::any::Any;
pub struct AboutScreen; pub struct AboutScreen;
@@ -2,7 +2,7 @@ use crate::state::Action;
use crate::ui::tiles::TilePane; use crate::ui::tiles::TilePane;
use egui::{Color32, FontId, Ui, Vec2, WidgetText}; use egui::{Color32, FontId, Ui, Vec2, WidgetText};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::devices::display::Display; use dsa_emulator::devices::display::Display;
use std::any::Any; use std::any::Any;
impl TilePane for Display { impl TilePane for Display {
@@ -2,9 +2,9 @@ use crate::state::Action;
use crate::ui::tiles::TilePane; use crate::ui::tiles::TilePane;
use egui::{Ui, Vec2, WidgetText}; use egui::{Ui, Vec2, WidgetText};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::EmulatorHandle; use dsa_emulator::EmulatorHandle;
use emulator_core::devices::framebuffer::FrameBuffer; use dsa_emulator::devices::framebuffer::FrameBuffer;
use emulator_core::memory::PhysAddr; use dsa_emulator::memory::PhysAddr;
use std::any::Any; use std::any::Any;
pub struct FrameBufferUi { pub struct FrameBufferUi {
@@ -2,7 +2,7 @@ use crate::state::Action;
use crate::ui::tiles::TilePane; use crate::ui::tiles::TilePane;
use egui::{Ui, WidgetText}; use egui::{Ui, WidgetText};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::devices::serial::Serial; use dsa_emulator::devices::serial::Serial;
use std::any::Any; use std::any::Any;
impl TilePane for Serial { impl TilePane for Serial {
@@ -27,7 +27,7 @@ impl TilePane for Serial {
if ui.button("Clear").clicked() { if ui.button("Clear").clicked() {
self.read_buff.clear(); self.read_buff.clear();
} }
None None
} }
@@ -4,7 +4,7 @@ use common::prelude::Instruction;
use egui::{Ui, WidgetText}; use egui::{Ui, WidgetText};
use egui_extras::{Column, TableBuilder}; use egui_extras::{Column, TableBuilder};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::EmulatorHandle; use dsa_emulator::EmulatorHandle;
use std::any::Any; use std::any::Any;
use std::num::ParseIntError; use std::num::ParseIntError;
@@ -3,7 +3,7 @@ use crate::ui::tiles::TilePane;
use common::prelude::Register; use common::prelude::Register;
use egui::{Ui, WidgetText}; use egui::{Ui, WidgetText};
use egui_tiles::TileId; use egui_tiles::TileId;
use emulator_core::EmulatorHandle; use dsa_emulator::EmulatorHandle;
use std::any::Any; use std::any::Any;
use std::f32; use std::f32;
@@ -1,9 +1,8 @@
pub mod text; pub mod text;
use eframe::emath::Vec2; use eframe::emath::Vec2;
use egui::{Color32, Frame, Stroke}; use egui::{Color32};
use egui::widget_style::{Classes, WidgetState}; use dsa_emulator::processor::RunningState;
use emulator_core::processor::RunningState;
pub struct PaddedWidget { pub struct PaddedWidget {
text: String, text: String,
@@ -70,7 +70,7 @@ impl DseExecutable {
Ok(DseExecutable { header, symbols, string_table, data, text }) Ok(DseExecutable { header, symbols, string_table, data, text })
} }
pub fn write<W: Write + Seek>(&self, writer: &mut W) -> binrw::BinResult<()> { pub fn write<W: Write + Seek>(&self, writer: &mut W) -> binrw::BinResult<()> {
self.header.write(writer)?; self.header.write(writer)?;
@@ -155,7 +155,7 @@ impl DseExecutable {
/// matching the exact layout `resolve_address` assumed when the assembler /// matching the exact layout `resolve_address` assumed when the assembler
/// resolved symbol addresses. This is NOT the same as the on-disk file /// resolved symbol addresses. This is NOT the same as the on-disk file
/// layout (header/symtab/strtab/data/text) — this is what actually needs /// layout (header/symtab/strtab/data/text) — this is what actually needs
/// to end up in emulator memory. /// to end up in dsa_emulator memory.
pub fn to_memory_image(&self) -> Vec<u8> { pub fn to_memory_image(&self) -> Vec<u8> {
let mut image = Vec::with_capacity(self.text.len() * 4 + self.data.len()); let mut image = Vec::with_capacity(self.text.len() * 4 + self.data.len());
@@ -14,8 +14,8 @@ path = "src/lib.rs"
[dependencies] [dependencies]
clap = { version = "4.6.0", features = ["derive"] } clap = { version = "4.6.0", features = ["derive"] }
common = { path = "../common" } common = { path = "../../libraries/common" }
dsa_formats = { path = "../dsa_formats" } dsa_formats = { path = "../../libraries/dsa_formats" }
num_cpus = "1.17.0" num_cpus = "1.17.0"
strum = { version = "0.28.0", features = ["derive"] } strum = { version = "0.28.0", features = ["derive"] }

Some files were not shown because too many files have changed in this diff Show More