fix broken build system commit
This commit is contained in:
@@ -0,0 +1,589 @@
|
||||
pub trait Template {
|
||||
fn lib(project: &str) -> String;
|
||||
fn bin(project: &str) -> String;
|
||||
|
||||
fn create(project: &str, lib: bool) -> String {
|
||||
if lib {
|
||||
Self::lib(project)
|
||||
} else {
|
||||
Self::bin(project)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Dsa;
|
||||
pub struct Dsc;
|
||||
|
||||
impl Template for Dsa {
|
||||
fn lib(project: &str) -> String {
|
||||
format!(
|
||||
r#"//
|
||||
lib.dsa
|
||||
// usage:
|
||||
//
|
||||
// include {project} "<relative path>"
|
||||
//
|
||||
// usage for {project}_main:
|
||||
// push (arg1)
|
||||
// push (arg0)
|
||||
// call {project}::{project}_main
|
||||
// pop (arg0)
|
||||
// pop (arg1)
|
||||
|
||||
// Example data declarations
|
||||
// dw example_data: 0x0000
|
||||
|
||||
// Main function template
|
||||
{project}_main:
|
||||
// the correct way to start a function as defined by the calling convention
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
// explanation of how to access args
|
||||
ldw bpr, rg0, 8 // arg 0
|
||||
ldw bpr, rg0, 12 // arg 1
|
||||
|
||||
// your code goes here
|
||||
// Example: load example_data into rg1
|
||||
// ldw example_data, rg1
|
||||
|
||||
// the correct way to end a function as defined by the calling convention
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
"#,
|
||||
)
|
||||
}
|
||||
|
||||
fn bin(project: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
// GENERATED BY DSX-BUILD
|
||||
// Generated at: {timestamp}
|
||||
// Project name: {project}
|
||||
|
||||
// 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"#,
|
||||
timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Template for Dsc {
|
||||
fn lib(project: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
// GENERATED BY DSX-BUILD
|
||||
// Generated at: {timestamp}
|
||||
// Project name: {project}
|
||||
|
||||
// Imports
|
||||
include print: "./lib/print.dsa";
|
||||
|
||||
// Main Function
|
||||
fn {project}_main() -> u32 {{
|
||||
return 0;
|
||||
}}"#,
|
||||
timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string()
|
||||
)
|
||||
}
|
||||
|
||||
fn bin(project: &str) -> String {
|
||||
format!(
|
||||
r#"
|
||||
// GENERATED BY DSX-BUILD
|
||||
// Generated at: {timestamp}
|
||||
// Project name: {project}
|
||||
|
||||
// Imports
|
||||
include print: "./lib/print.dsa";
|
||||
|
||||
// Main Function
|
||||
fn main() -> u32 {{
|
||||
return 0;
|
||||
}}"#,
|
||||
timestamp = chrono::Utc::now().format("%Y-%m-%d %H:%M:%S").to_string()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_print_lib() -> String {
|
||||
format!(
|
||||
r#"
|
||||
// lib:
|
||||
// print.dsa
|
||||
|
||||
// usage:
|
||||
//
|
||||
// include print "<relative path>""
|
||||
//
|
||||
// usage for print:
|
||||
// push (register containing address of string)
|
||||
// push pcx
|
||||
// jmp print::print
|
||||
//
|
||||
// usage for reset:
|
||||
// push pcx
|
||||
// jmp print::reset
|
||||
//
|
||||
// usage for clear:
|
||||
// push pcx
|
||||
// jmp print::clear
|
||||
//
|
||||
// usage for print_byte:
|
||||
// push (register containing byte)
|
||||
// push pcx
|
||||
// jmp print::print_byte
|
||||
//
|
||||
// usage for print_word:
|
||||
// push (register containing word)
|
||||
// push pcx
|
||||
// jmp print::print_word
|
||||
//
|
||||
// usage for print_num:
|
||||
// push (register containing number to print in decimal)
|
||||
// push pcx
|
||||
// jmp print::print_num
|
||||
//
|
||||
|
||||
include maths "./maths.dsa"
|
||||
|
||||
dw display: 0x20000
|
||||
dw current: 0x20000
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the string at addr(arg[0]) to the screen. (no trailing whitespace unless explicitly provided)
|
||||
print:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
_print_loop:
|
||||
ldb rg0, acc
|
||||
cmp acc, zero
|
||||
jeq _end
|
||||
stb acc, rg1
|
||||
|
||||
addi rg0, 1
|
||||
addi rg1, 1
|
||||
|
||||
jmp _print_loop
|
||||
|
||||
// ------------------------------------------
|
||||
println:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
_println_loop:
|
||||
ldb rg0, acc
|
||||
cmp acc, zero
|
||||
jeq _println_end
|
||||
stb acc, rg1
|
||||
|
||||
addi rg0, 1
|
||||
addi rg1, 1
|
||||
|
||||
jmp _println_loop
|
||||
|
||||
_println_end:
|
||||
call print_newline
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the value of arg[0] to the screen.
|
||||
print_word:
|
||||
// initialise
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
// load byte into acc
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
addi rg1, 3
|
||||
|
||||
stb rg0, rg1
|
||||
subi rg1, 1
|
||||
shr rg0, 8
|
||||
stb rg0, rg1
|
||||
subi rg1, 1
|
||||
shr rg0, 8
|
||||
stb rg0, rg1
|
||||
subi rg1, 1
|
||||
shr rg0, 8
|
||||
stb rg0, rg1
|
||||
|
||||
addi rg1, 4
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the last byte of arg[0] to the screen.
|
||||
print_byte:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints the value of arg[0] to the screen in hex.
|
||||
print_hex_word:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw current, 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 screen in hex.
|
||||
print_hex_byte:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8
|
||||
ldw current, rg1
|
||||
|
||||
call _print_hex_byte
|
||||
jmp _end
|
||||
|
||||
// function body
|
||||
_print_hex_byte:
|
||||
// mask to get lower nibble
|
||||
lli 0xF, rg2
|
||||
// save rg0 state
|
||||
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
|
||||
addi rg1, 1
|
||||
return
|
||||
|
||||
// helper function.
|
||||
_print_hex_nibble_number:
|
||||
addi rg0, 0x30, rg0
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
return
|
||||
|
||||
// ------------------------------------------
|
||||
// print whitespace
|
||||
print_whitespace:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw current, rg1
|
||||
lli 0x20, rg0
|
||||
stb rg0, rg1
|
||||
addi rg1, 1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// print newline
|
||||
print_newline:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
// load variables into registers
|
||||
ldw display, rg0
|
||||
ldw current, rg1
|
||||
|
||||
// get the offset from the display base
|
||||
sub rg1, rg0, rg0
|
||||
|
||||
lwi 80, rg2
|
||||
pusha 3
|
||||
push rg0
|
||||
push rg2
|
||||
call maths::divmod
|
||||
pop zero // result
|
||||
pop rg3 // remainder
|
||||
popa 3
|
||||
|
||||
sub rg1, rg3, rg2
|
||||
addi rg2, 80, rg1
|
||||
|
||||
// _end saves the display state
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// prints arg[0] as a decimal number to the screen.
|
||||
print_num:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8 // load number to print
|
||||
lli 0, rg5 // rg5 = digit counter
|
||||
|
||||
// check if number is zero
|
||||
cmp rg0, zero
|
||||
jne _print_num_extract_digits
|
||||
|
||||
// special case: print '0' for zero
|
||||
lli 0x30, rg6
|
||||
push rg6 // push digit to stack buffer
|
||||
lli 1, rg5 // we have 1 digit
|
||||
jmp _print_num_output
|
||||
|
||||
_print_num_extract_digits:
|
||||
// divide by 10 repeatedly to get digits
|
||||
cmp rg0, zero
|
||||
jeq _print_num_output
|
||||
|
||||
// call divmod(rg0, 10)
|
||||
push rg0 // dividend
|
||||
lli 10, rg1
|
||||
push rg1 // divisor (10)
|
||||
call maths::divmod
|
||||
pop rg0 // quotient (continue dividing this)
|
||||
pop rg1 // remainder (the digit)
|
||||
|
||||
// convert digit to ASCII and push to stack buffer
|
||||
addi rg1, 0x30, rg6 // convert to ASCII
|
||||
push rg6 // push digit to stack
|
||||
inc rg5 // increment digit counter
|
||||
|
||||
jmp _print_num_extract_digits
|
||||
|
||||
_print_num_output:
|
||||
// now print digits (pop them off in reverse order)
|
||||
ldw current, rg1 // get display pointer
|
||||
|
||||
_print_num_output_loop:
|
||||
// check if we've printed all digits
|
||||
cmp rg5, zero
|
||||
jeq _print_num_done
|
||||
|
||||
// pop digit and print it
|
||||
pop rg6
|
||||
stb rg6, rg1
|
||||
addi rg1, 1
|
||||
dec rg5
|
||||
|
||||
jmp _print_num_output_loop
|
||||
|
||||
_print_num_done:
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// resets the cursor position on the screen to 0x20000. (0,0)
|
||||
reset:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
ldw display, rg1
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// clears the screen
|
||||
clear:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
// display size = 2000 bytes / 500 words
|
||||
lli 500 rg0
|
||||
ldw display, rg1
|
||||
|
||||
_clear_loop:
|
||||
dec rg0
|
||||
stw zero, rg1
|
||||
addi rg1, 4
|
||||
cmp rg0, zero
|
||||
jgt _clear_loop
|
||||
jmp _end
|
||||
|
||||
// ------------------------------------------
|
||||
// return
|
||||
_end:
|
||||
stw rg1, current
|
||||
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
||||
pub fn create_maths_lib() -> String {
|
||||
format!(
|
||||
r#"
|
||||
// multiply.dsa
|
||||
// usage:
|
||||
//
|
||||
// include multiply "<relative path>"
|
||||
//
|
||||
// usage for multiply:
|
||||
// push (arg1)
|
||||
// push (arg0)
|
||||
// call multiply::multiply
|
||||
// pop (arg0)
|
||||
// pop (arg1)
|
||||
|
||||
multiply:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8 // load op 2
|
||||
ldw bpr, rg1, 12 // load op 1
|
||||
lwi 0, rg2 // initialise rg2 to zero
|
||||
|
||||
_multiply_loop:
|
||||
add rg2, rg0, rg2
|
||||
dec rg1
|
||||
|
||||
cmp rg1, zero
|
||||
jgt _multiply_loop
|
||||
|
||||
_multiply_end:
|
||||
stw rg2, bpr, 8
|
||||
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
|
||||
divmod:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg1, 8 // load op 2
|
||||
ldw bpr, rg0, 12 // load op 1
|
||||
|
||||
lli 0, rg3
|
||||
|
||||
_divmod_loop:
|
||||
cmp rg0, rg1
|
||||
jlt _divmod_end
|
||||
|
||||
sub rg0, rg1, rg0
|
||||
inc rg3
|
||||
|
||||
jmp _divmod_loop
|
||||
|
||||
_divmod_end:
|
||||
// store div in first arg
|
||||
// store mod in second arg
|
||||
stw rg3, bpr, 8
|
||||
stw rg0, bpr, 12
|
||||
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
|
||||
// multiply.dsa - improved version
|
||||
// Multiplies two 32-bit numbers using shift-and-add
|
||||
//
|
||||
// Usage:
|
||||
// push operand2 (multiplier)
|
||||
// push operand1 (multiplicand)
|
||||
// call multiply::multiply
|
||||
// pop result
|
||||
// pop zero (discard second argument)
|
||||
|
||||
new_multiply:
|
||||
push bpr
|
||||
mov spr, bpr
|
||||
|
||||
ldw bpr, rg0, 8 // rg0 = multiplicand
|
||||
ldw bpr, rg1, 12 // rg1 = multiplier
|
||||
|
||||
lli 0, rg2 // rg2 = result (accumulator)
|
||||
lli 32, rg3 // rg3 = bit counter
|
||||
|
||||
mult_loop:
|
||||
// Check if lowest bit of multiplier is 1
|
||||
lli 1, acc
|
||||
and rg1, acc, acc // acc = rg1 & 1
|
||||
cmp acc, zero
|
||||
jeq skip_add // if (rg1 & 1) == 0, skip addition
|
||||
|
||||
// Add multiplicand to result
|
||||
add rg2, rg0, rg2
|
||||
|
||||
skip_add:
|
||||
shl rg0, 1 // shift multiplicand left
|
||||
shr rg1, 1 // shift multiplier right
|
||||
|
||||
dec rg3
|
||||
cmp rg3, zero
|
||||
jgt mult_loop
|
||||
|
||||
stw rg2, bpr, 8 // store result
|
||||
mov bpr, spr
|
||||
pop bpr
|
||||
return
|
||||
"#
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user