commented out debug print statements and removed some commented out code that's no longer needed
This commit is contained in:
@@ -2,107 +2,38 @@
|
|||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
use std::{fmt, sync::mpsc::Sender};
|
use std::{fmt, sync::mpsc::Sender};
|
||||||
|
|
||||||
// pub struct Logger {}
|
// pub struct Entry {
|
||||||
|
// etype: EntryType,
|
||||||
|
// pub message: String,
|
||||||
|
// }
|
||||||
|
|
||||||
// impl Logger {
|
// #[derive(Copy, Clone, Eq, PartialEq)]
|
||||||
// pub const fn new() -> Self {
|
// enum EntryType {
|
||||||
// Self {}
|
// Debug,
|
||||||
// }
|
// Info,
|
||||||
|
// Warn,
|
||||||
|
// Error,
|
||||||
|
// Fatal,
|
||||||
|
// }
|
||||||
|
|
||||||
// pub fn log(&self, message: &str) {
|
// impl fmt::Display for EntryType {
|
||||||
// _ = self;
|
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
// println!("\x1b[32mINFO:\x1b[0m {message}");
|
// write!(
|
||||||
|
// f,
|
||||||
|
// "{:<5}",
|
||||||
|
// match self {
|
||||||
|
// Self::Debug => "DEBUG",
|
||||||
|
// Self::Info => "INFO",
|
||||||
|
// Self::Warn => "WARN",
|
||||||
|
// Self::Error => "ERROR",
|
||||||
|
// Self::Fatal => "FATAL",
|
||||||
|
// }
|
||||||
|
// )
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// #[derive(Debug)]=
|
// impl fmt::Display for Entry {
|
||||||
// pub struct Logger {
|
// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
// pub sender: Sender<Entry>,
|
// write!(f, "{}: {}", self.etype, self.message)
|
||||||
// }
|
|
||||||
|
|
||||||
// impl Logger {
|
|
||||||
// pub fn new(sender: Sender<Entry>) -> Self {
|
|
||||||
// Self { sender }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn debug<T: fmt::Display>(&self, message: T) {
|
|
||||||
// self.sender
|
|
||||||
// .send(Entry {
|
|
||||||
// etype: EntryType::Debug,
|
|
||||||
// message: message.to_string(),
|
|
||||||
// })
|
|
||||||
// .unwrap();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn info<T: fmt::Display>(&self, message: T) {
|
|
||||||
// self.sender
|
|
||||||
// .send(Entry {
|
|
||||||
// etype: EntryType::Info,
|
|
||||||
// message: message.to_string(),
|
|
||||||
// })
|
|
||||||
// .unwrap();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn warn<T: fmt::Display>(&self, message: T) {
|
|
||||||
// self.sender
|
|
||||||
// .send(Entry {
|
|
||||||
// etype: EntryType::Warn,
|
|
||||||
// message: message.to_string(),
|
|
||||||
// })
|
|
||||||
// .unwrap();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn error<T: fmt::Display>(&self, message: T) {
|
|
||||||
// self.sender
|
|
||||||
// .send(Entry {
|
|
||||||
// etype: EntryType::Error,
|
|
||||||
// message: message.to_string(),
|
|
||||||
// })
|
|
||||||
// .unwrap();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// pub fn fatal<T: fmt::Display>(&self, message: T) {
|
|
||||||
// self.sender
|
|
||||||
// .send(Entry {
|
|
||||||
// etype: EntryType::Fatal,
|
|
||||||
// message: message.to_string(),
|
|
||||||
// })
|
|
||||||
// .unwrap();
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
pub struct Entry {
|
|
||||||
etype: EntryType,
|
|
||||||
pub message: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
|
||||||
enum EntryType {
|
|
||||||
Debug,
|
|
||||||
Info,
|
|
||||||
Warn,
|
|
||||||
Error,
|
|
||||||
Fatal,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for EntryType {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{:<5}",
|
|
||||||
match self {
|
|
||||||
Self::Debug => "DEBUG",
|
|
||||||
Self::Info => "INFO",
|
|
||||||
Self::Warn => "WARN",
|
|
||||||
Self::Error => "ERROR",
|
|
||||||
Self::Fatal => "FATAL",
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for Entry {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "{}: {}", self.etype, self.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ pub fn generate_ast(input: &str, logger: &Logger) -> Result<Program, CompilerErr
|
|||||||
|
|
||||||
let lexer = lexer::Lexer::new(&input);
|
let lexer = lexer::Lexer::new(&input);
|
||||||
let tokens = lexer.collect::<Vec<_>>();
|
let tokens = lexer.collect::<Vec<_>>();
|
||||||
println!("{tokens:#?}");
|
|
||||||
|
// println!("{tokens:#?}");
|
||||||
|
|
||||||
logger.info(&format!("Parsing {} Tokens...", tokens.len()));
|
logger.info(&format!("Parsing {} Tokens...", tokens.len()));
|
||||||
|
|
||||||
|
|||||||
@@ -800,8 +800,6 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_type(&mut self) -> ParseResult<TypeId, CompilerError> {
|
fn parse_type(&mut self) -> ParseResult<TypeId, CompilerError> {
|
||||||
println!("yes {:?}", self.peek_next()?);
|
|
||||||
|
|
||||||
// parse primitive or named type
|
// parse primitive or named type
|
||||||
if expect_tt!(self.peek_next()?, Identifier).accepted() {
|
if expect_tt!(self.peek_next()?, Identifier).accepted() {
|
||||||
return self.parse_type_identifier();
|
return self.parse_type_identifier();
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
name = "test"
|
|
||||||
binaries = []
|
|
||||||
Binary file not shown.
@@ -1,105 +0,0 @@
|
|||||||
|
|
||||||
// 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
|
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
|
|
||||||
// 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
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
// 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_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
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
// 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
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
// GENERATED BY DSC COMPILER
|
|
||||||
// Generated at 2026-02-23 18:58:53
|
|
||||||
|
|
||||||
// Imports
|
|
||||||
include print: "./lib/print.dsa"
|
|
||||||
|
|
||||||
// Globals & Reserved Memory
|
|
||||||
|
|
||||||
// Entry Point
|
|
||||||
dw stack: 0x010000
|
|
||||||
db message: "Process Exited with code:"
|
|
||||||
_init:
|
|
||||||
ldw stack, bpr, 0
|
|
||||||
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
|
|
||||||
|
|
||||||
// Return
|
|
||||||
_ret:
|
|
||||||
mov bpr, spr
|
|
||||||
pop bpr
|
|
||||||
return
|
|
||||||
|
|
||||||
db str_1: "Hello, World!"
|
|
||||||
// fn main() -> void
|
|
||||||
main:
|
|
||||||
push bpr
|
|
||||||
mov spr, bpr
|
|
||||||
lwi str_1, rg0
|
|
||||||
// push arg 0
|
|
||||||
push rg0
|
|
||||||
call print::print
|
|
||||||
pop zero
|
|
||||||
jmp _ret
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
include print: "./lib/print.dsa";
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
print::print("Hello, World!");
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
|
|
||||||
// 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
|
|
||||||
@@ -1,332 +0,0 @@
|
|||||||
|
|
||||||
// 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
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
// 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_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
|
|
||||||
|
|
||||||
// ------------------------------------------
|
|
||||||
// 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
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
include print: "./lib/print.dsa";
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
print::print("Hello, World!");
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user