336 lines
5.8 KiB
Plaintext
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
|