progress: new assembler works, instruction set fully implemented with call/ret and push/pop, bf.dsa works which means the dsa assembly language works reliably. still a few bugs to fix. might be able to squeeze out a tiny bit more performance

This commit is contained in:
2026-03-09 03:24:20 +00:00
parent fc972b9b7b
commit e01a9f2808
63 changed files with 4975 additions and 1579 deletions
+292
View File
@@ -0,0 +1,292 @@
// lib:
// print.dsa
// usage:
//
// include print "<relative path>"
//
// usage for print:
// push (register containing address of string)
// call print::print
//
// usage for reset:
// call print::reset
//
// usage for clear:
// call print::clear
//
// usage for print_byte:
// push (register containing byte)
// call print::print_byte
//
// usage for print_word:
// push (register containing word)
// call print::print_word
//
// usage for print_num:
// push (register containing number to print in decimal)
// call print::print_num
//
dw display: 0x20000
dw current: 0x20000
// ------------------------------------------
// prints the string at addr(arg[0]) to the screen.
print: func
ldw bpr, rg0, 8
ldw current, rg1
_print_loop:
ldb rg0, rg2
ieq rg2, zero, rg4
jnz rg4, _end
stb rg2, 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
// ieq acc, zero, rg4
// jnz rg4, _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:
// push bpr
// mov spr, bpr
// 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: func
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: func
ldw bpr, rg0, 8
ldw current, 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
ret
// print a hex digit
_print_hex_nibble:
lli 10, rg3
ilt rg0, rg3, rg4
jnz rg4, _print_hex_nibble_number
addi rg0, 0x37, rg0
stb rg0, rg1
addi rg1, 1
ret
// helper function.
_print_hex_nibble_number:
addi rg0, 0x30, rg0
stb rg0, rg1
addi rg1, 1
ret
// ------------------------------------------
// print whitespace
print_whitespace: func
ldw current, rg1
lli 0x20, rg0
stb rg0, rg1
addi rg1, 1
jmp _end
// // ------------------------------------------
// // print newline
// print_newline:
// push bpr
// mov spr, bpr
// ldw display, rg0
// ldw current, rg1
// sub rg1, rg0, rg0
// lwi 80, rg2
// push rg0
// push rg1
// push rg2
// push rg0
// push rg2
// call maths::divmod
// pop zero // result
// pop rg3 // remainder
// pop rg0
// pop rg1
// pop rg2
// sub rg1, rg3, rg2
// addi rg2, 80, rg1
// jmp _end
// ------------------------------------------
// prints arg[0] as a decimal number to the screen.
// print_num:
// push bpr
// mov spr, bpr
// ldw bpr, rg0, 8
// lli 0, rg5
// ieq rg0, zero, rg4
// jez rg4, _print_num_extract_digits
// lli 0x30, rg6
// push rg6
// lli 1, rg5
// jmp _print_num_output
// _print_num_extract_digits:
// ieq rg0, zero, rg4
// jnz rg4, _print_num_output
// push rg0
// lli 10, rg1
// push rg1
// call maths::divmod
// pop rg0 // quotient
// pop rg1 // remainder
// addi rg1, 0x30, rg6
// push rg6
// inc rg5
// jmp _print_num_extract_digits
// _print_num_output:
// ldw current, rg1
// _print_num_output_loop:
// ieq rg5, zero, rg4
// jnz rg4, _print_num_done
// pop rg6
// stb rg6, rg1
// addi rg1, 1
// dec rg5
// jmp _print_num_output_loop
// _print_num_done:
// jmp _end
// ------------------------------------------
// resets the cursor position to 0x20000 (0,0)
reset: func
ldw display, rg1
jmp _end
// ------------------------------------------
// clears the screen
clear: func
lli 500, rg0
ldw display, rg1
_clear_loop:
subi rg0, 1, rg0
stw zero, rg1
addi rg1, 4
igt rg0, zero, rg4
jnz rg4, _clear_loop
jmp _end
// ------------------------------------------
// return — saves current, restores frame, returns
_end:
stw rg1, current
return