dsx/dsx_server repo system first implementation

This commit is contained in:
2026-02-25 14:52:04 +00:00
parent ba4ced6433
commit 0d54b319f1
28 changed files with 1196 additions and 378 deletions
@@ -1 +0,0 @@
id="example"
@@ -1 +0,0 @@
name = "example"
@@ -1,39 +0,0 @@
// GENERATED BY DSX-BUILD
// Generated at: 2026-02-21 02:50:14
// Project name: example
// Imports
include print: "./lib/print.dsa"
// Globals & Reserved Memory
dw stack: 0x10000
db message: "Process Exited with code:"
// Entry Point
_init:
ldw stack, bpr
mov bpr, spr
push zero
call main
call print::print_newline
lwi message, rg0
push rg0
call print::print
pop zero
call print::print_hex_word
pop zero
hlt
main:
push bpr
mov spr, bpr
// Your code goes here
// Return zero
stw zero, bpr, 8
mov bpr, spr
pop bpr
return
@@ -0,0 +1,4 @@
id = "test"
latest_build_date = "2026-02-25 14:39:49"
latest_build_status = "success"
latest_build_id = "test"
@@ -0,0 +1,3 @@
name = "test"
binaries = []
remote = "http://localhost:8000/api/pkg/test"
@@ -0,0 +1,77 @@
// Arena Allocator
// Supports multiple arenas that can be destroyed independently
// Much more practical than a simple bump allocator
// Global heap management
static heap_start: u32 = 0x30000;
static heap_end: u32 = 0x40000;
static heap_current: u32 = 0x30000;
// Arena structure (stored at the start of each arena):
// [0-3]: start_address (u32)
// [4-7]: current_position (u32)
// [8-11]: end_address (u32)
// Total header size: 12 bytes
// Create a new arena with given size
// Returns pointer to arena handle (or 0 if failed)
fn new(size: u32) -> u32 {
let total_size: u32 = size + 12;
let arena_ptr: u32 = heap_current;
let new_current: u32 = arena_ptr + total_size;
// Check if we have space
if new_current > heap_end {
return 0;
}
// Calculate arena data region
let data_start: u32 = arena_ptr + 12;
let data_end: u32 = arena_ptr + total_size;
// Initialize arena header
// Note: In real implementation, you'd use pointer writes here
// For now, using placeholder comments:
*arena_ptr = data_start; // start_address
*(arena_ptr + 4) = data_start; // current_position
*(arena_ptr + 8) = data_end; // end_address
heap_current = new_current;
return arena_ptr;
}
// Allocate from an arena
// Returns pointer to allocated memory (or 0 if failed)
fn alloc(arena: u32, size: u32) -> u32 {
// Read current position from arena
let current: u32 = *(arena + 4);
let end: u32 = *(arena + 8);
let new_current: u32 = current + size;
// Check if arena has space
if new_current > end {
return 0;
}
// Update current position in arena
*(arena + 4) = new_current;
return current;
}
// Destroy an arena (in bump allocator, this is a no-op)
// In a real allocator, you'd mark the memory as free
fn destroy(arena: u32) {
// In a true allocator, mark memory as reusable
// For bump allocator, we can't reclaim memory
// unless we destroy ALL arenas and reset
return 0;
}
// Reset entire heap (destroys ALL arenas)
fn reset_all() {
heap_current = heap_start;
return 0;
}
@@ -0,0 +1,274 @@
// lib:
// print_serial.dsa
// usage:
//
// include print_serial "<relative path>"
//
// usage for print:
// push (register containing address of string)
// push pcx
// jmp print_serial::print
//
// usage for print_byte:
// push (register containing byte)
// push pcx
// jmp print_serial::print_byte
//
// usage for print_word:
// push (register containing word)
// push pcx
// jmp print_serial::print_word
//
// usage for print_hex_byte:
// push (register containing byte)
// push pcx
// jmp print_serial::print_hex_byte
//
// usage for print_hex_word:
// push (register containing word)
// push pcx
// jmp print_serial::print_hex_word
//
// usage for print_whitespace:
// push pcx
// jmp print_serial::print_whitespace
//
// usage for print_newline:
// push pcx
// jmp print_serial::print_newline
//
// usage for print_num:
// push (register containing number to print in decimal)
// push pcx
// jmp print_serial::print_num
//
// usage for println:
// push (register containing address of string)
// push pcx
// jmp print_serial::println
//
include maths "./maths.dsa"
dw serial: 0x207D0 // 0x20000 + 2000
// ------------------------------------------
// prints the string at addr(arg[0]) to the serial port.
print:
push bpr
mov spr, bpr
ldw bpr, rg0, 8
lwi 0x207D0, rg1
_print_loop:
ldb rg0, acc
cmp acc, zero
jeq _end
stb acc, rg1
addi rg0, 1
jmp _print_loop
// ------------------------------------------
// prints the string at addr(arg[0]) followed by a newline to the serial port.
println:
push bpr
mov spr, bpr
ldw bpr, rg0, 8
lwi 0x207D0, rg1
_println_loop:
ldb rg0, acc
cmp acc, zero
jeq _println_end
stb acc, rg1
addi rg0, 1
jmp _println_loop
_println_end:
lli 0x0A, rg2 // newline character
stb rg2, rg1
jmp _end
// ------------------------------------------
// prints the word in arg[0] as 4 raw bytes to the serial port.
print_word:
push bpr
mov spr, bpr
ldw bpr, rg0, 8
lwi 0x207D0, rg1
stb rg0, rg1
shr rg0, 8
stb rg0, rg1
shr rg0, 8
stb rg0, rg1
shr rg0, 8
stb rg0, rg1
jmp _end
// ------------------------------------------
// prints the last byte of arg[0] to the serial port.
print_byte:
push bpr
mov spr, bpr
ldw bpr, rg0, 8
lwi 0x207D0, rg1
stb rg0, rg1
jmp _end
// ------------------------------------------
// prints the value of arg[0] to the serial port in hex.
print_hex_word:
push bpr
mov spr, bpr
lwi 0x207D0, rg1
ldb bpr, rg0, 8
push rg0
call _print_hex_byte
addi spr, 4
ldb bpr, rg0, 9
push rg0
call _print_hex_byte
addi spr, 4
ldb bpr, rg0, 10
push rg0
call _print_hex_byte
addi spr, 4
ldb bpr, rg0, 11
push rg0
call _print_hex_byte
addi spr, 4
jmp _end
// ------------------------------------------
// prints the last byte of arg[0] to the serial port in hex.
print_hex_byte:
push bpr
mov spr, bpr
ldw bpr, rg0, 8
lwi 0x207D0, rg1
call _print_hex_byte
jmp _end
// function body
_print_hex_byte:
lli 0xF, rg2
push rg0
shr rg0, 4
and rg0, rg2, rg0
call _print_hex_nibble
pop rg0
and rg0, rg2, rg0
call _print_hex_nibble
return
// print a hex digit
_print_hex_nibble:
lli 10, rg3
cmp rg0, rg3
jlt _print_hex_nibble_number
addi rg0, 0x37, rg0
stb rg0, rg1
return
_print_hex_nibble_number:
addi rg0, 0x30, rg0
stb rg0, rg1
return
// print a single space
print_whitespace:
push bpr
mov spr, bpr
lli 0x20, rg0
ldw serial, rg1
stb rg0, rg1
jmp _end
// print a single space
print_newline:
push bpr
mov spr, bpr
lli 0x0A, rg0
ldw serial, rg1
stb rg0, rg1
jmp _end
// ------------------------------------------
// prints arg[0] as a decimal number to the serial port.
print_num:
push bpr
mov spr, bpr
ldw bpr, rg0, 8
lli 0, rg5
cmp rg0, zero
jne _print_num_extract_digits
lli 0x30, rg6
push rg6
lli 1, rg5
jmp _print_num_output
_print_num_extract_digits:
cmp rg0, zero
jeq _print_num_output
push rg0
lli 10, rg1
push rg1
call maths::divmod
pop rg0
pop rg1
addi rg1, 0x30, rg6
push rg6
inc rg5
jmp _print_num_extract_digits
_print_num_output:
lwi 0x207D0, rg1
_print_num_output_loop:
cmp rg5, zero
jeq _print_num_done
pop rg6
stb rg6, rg1
dec rg5
jmp _print_num_output_loop
_print_num_done:
jmp _end
// ------------------------------------------
// return
_end:
mov bpr, spr
pop bpr
return
@@ -0,0 +1,30 @@
include serial: "./lib/serial.dsa";
include print: "./lib/print.dsa";
include arena: "./lib/arena_alloc.dsc";
fn main() {
let x: u32 = 0;
let y: u32 = &x;
let alloc: u32 = arena::new(512);
let ptr1: u32 = arena::alloc(alloc, 32);
let ptr2: u32 = arena::alloc(alloc, 32);
serial::print_hex_word(alloc);
serial::print_newline();
serial::print_hex_word(ptr1);
serial::print_newline();
serial::print_hex_word(ptr2);
serial::print_newline();
serial::print_num(*ptr2);
serial::print_newline();
*ptr2 = 42;
serial::print_hex_word(ptr2);
serial::print_whitespace();
serial::print_num(*ptr2);
serial::print_newline();
serial::println("end");
return 0;
}