64 lines
1.6 KiB
Plaintext
64 lines
1.6 KiB
Plaintext
// lib:
|
|
// serial.dsa
|
|
//
|
|
// usage:
|
|
// include serial "<relative path>"
|
|
//
|
|
// push (register containing address of string)
|
|
// call serial::print
|
|
//
|
|
// push (register containing byte)
|
|
// call serial::print_byte
|
|
|
|
dw uart: 0x40000
|
|
|
|
// ------------------------------------------
|
|
// transmit a single byte via sentinel protocol
|
|
// expects: byte in rg0, trashes rg2, rg3, rg4, rg5
|
|
_serial_send:
|
|
shl rg0, 16, rg2 // shift byte to bits [23:16]
|
|
lli 0x01, rg0
|
|
shl rg0, 24, rg0 // valid flag in bits [31:24]
|
|
or rg0, rg2, rg2 // rg2 = 0x01_XX_0000
|
|
|
|
ldw uart, rg5 // rg5 = 0x40000 (uart address, held for store)
|
|
|
|
_serial_wait:
|
|
ldw rg5, rg0 // poll mem[0x40000]
|
|
shr rg0, 24, rg0
|
|
lli 0x01, rg3
|
|
ieq rg0, rg3, rg4
|
|
jnz rg4, _serial_wait // loop while valid == 1
|
|
|
|
stw rg2, rg5 // mem[0x40000] = sentinel word
|
|
ret
|
|
|
|
// ------------------------------------------
|
|
// prints the null-terminated string at addr(arg[0])
|
|
print: func
|
|
ldw bpr, rg0, 8 // load string address from arg
|
|
|
|
_serial_print_loop:
|
|
ldb rg0, rg2 // load byte
|
|
ieq rg2, zero, rg4 // null terminator?
|
|
jnz rg4, _serial_end
|
|
|
|
push rg0 // save string pointer
|
|
mov rg2, rg0
|
|
call _serial_send
|
|
pop rg0
|
|
|
|
addi rg0, 1
|
|
jmp _serial_print_loop
|
|
|
|
// ------------------------------------------
|
|
// prints the last byte of arg[0]
|
|
print_byte: func
|
|
ldw bpr, rg0, 8
|
|
call _serial_send
|
|
jmp _serial_end
|
|
|
|
// ------------------------------------------
|
|
_serial_end:
|
|
return
|