Files
DSA/dsa_resources/print.dsa
T

336 lines
5.8 KiB
Plaintext

// 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
push rg0
push rg1
push rg2
push rg3
ldw bpr, rg0, 8
ldw current, rg1
_print_loop:
ldb rg0, rg2
ieq rg2, zero, rg3
jnz rg3, _print_end
stb rg2, rg1
addi rg0, 1
addi rg1, 1
jmp _print_loop
_print_end:
stw rg1, current
pop rg3
pop rg2
pop rg1
pop rg0
return
// ------------------------------------------
// 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
push rg0
push rg1
ldw bpr, rg0, 8
ldw current, rg1
stb rg0, rg1
addi rg1, 1
pop rg1
pop rg0
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
newline:
push bpr
mov spr, bpr
ldw display, rg0
ldw current, rg1
sub rg1, rg0, rg2 // offset from base
lli 80, rg3
_newline_mod:
ilt rg2, rg3, rg4
jnz rg4, _newline_done
sub rg2, rg3, rg2
jmp _newline_mod
_newline_done:
// rg2 = offset % 80 (position within current line)
sub rg1, rg2, rg1 // go back to line start
addi rg1, 80, rg1 // advance to next line
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