; ==== symbols ====
; clear                    0x000001d0  TEXT global
; _loop                    0x00000018  TEXT global
; print_whitespace         0x00000150  TEXT global
; _print_hex_nibble_number 0x00000140  TEXT global
; _init                    0x00000000  TEXT global
; _print_loop              0x00000068  TEXT global
; print_hex_byte           0x000000e0  TEXT global
; _print_hex_byte          0x00000100  TEXT global
; _end                     0x00000200  TEXT global
; print_byte               0x000000ac  TEXT global
; _newline_mod             0x0000019c  TEXT global
; reset                    0x000001b8  TEXT global
; _newline_done            0x000001ac  TEXT global
; msg                      0x00000218  DATA global
; display                  0x00000228  DATA global
; current                  0x0000022c  DATA global
; _clear_loop              0x000001e8  TEXT global
; _print_hex_nibble        0x00000124  TEXT global
; print                    0x00000040  TEXT global
; stack                    0x00000224  DATA global
; _print_end               0x00000084  TEXT global
; newline                  0x00000174  TEXT global

; ==== data ====
    db "hello world"
    dw 0x00000000
    dw 0x00000010
    dw 0x00000000
    dw 0x00000002
    dw 0x00000002

; ==== text ====
_init:
    ldw stack, Bpr, 0x0000
    mov Bpr, Spr
    lwi 0x000f4240, Rg5
_loop:
    call reset
    lwi msg, Rg0
    push Rg0
    call print
    pop Zero
    subi Rg5, Rg5, 0x0001
    igt Rg5, Zero, Rg4
    jnz Rg4, _loop
    hlt
print:
    push Bpr
    mov Spr, Bpr
    push Rg0
    push Rg1
    push Rg2
    push Rg3
    ldw Bpr, Rg0, 0x0008
    ldw current, Rg1, 0x0000
_print_loop:
    ldb Rg0, Rg2, 0x0000
    ieq Rg2, Zero, Rg3
    jnz Rg3, _print_end
    stb Rg2, Rg1, 0x0000
    addi Rg0, Rg0, 0x0001
    addi Rg1, Rg1, 0x0001
    jmp _print_loop
_print_end:
    stw current, Rg1, 0x0000
    pop Rg3
    pop Rg2
    pop Rg1
    pop Rg0
    mov Bpr, Spr
    pop Bpr
    ret
print_byte:
    push Bpr
    mov Spr, Bpr
    push Rg0
    push Rg1
    ldw Bpr, Rg0, 0x0008
    ldw current, Rg1, 0x0000
    stb Rg0, Rg1, 0x0000
    addi Rg1, Rg1, 0x0001
    pop Rg1
    pop Rg0
    jmp _end
print_hex_byte:
    push Bpr
    mov Spr, Bpr
    ldw Bpr, Rg0, 0x0008
    ldw current, Rg1, 0x0000
    call _print_hex_byte
    jmp _end
_print_hex_byte:
    lli Rg2, 0x000f
    push Rg0
    shr Rg0, Rg0, Zero, 4
    and Rg0, Rg2, Rg0
    call _print_hex_nibble
    pop Rg0
    and Rg0, Rg2, Rg0
    call _print_hex_nibble
    ret
_print_hex_nibble:
    lli Rg3, 0x000a
    ilt Rg0, Rg3, Rg4
    jnz Rg4, _print_hex_nibble_number
    addi Rg0, Rg0, 0x0037
    stb Rg0, Rg1, 0x0000
    addi Rg1, Rg1, 0x0001
    ret
_print_hex_nibble_number:
    addi Rg0, Rg0, 0x0030
    stb Rg0, Rg1, 0x0000
    addi Rg1, Rg1, 0x0001
    ret
print_whitespace:
    push Bpr
    mov Spr, Bpr
    ldw current, Rg1, 0x0000
    lli Rg0, 0x0020
    stb Rg0, Rg1, 0x0000
    addi Rg1, Rg1, 0x0001
    jmp _end
newline:
    push Bpr
    mov Spr, Bpr
    ldw display, Rg0, 0x0000
    ldw current, Rg1, 0x0000
    sub Rg1, Rg0, Rg2
    lli Rg3, 0x0050
_newline_mod:
    ilt Rg2, Rg3, Rg4
    jnz Rg4, _newline_done
    sub Rg2, Rg3, Rg2
    jmp _newline_mod
_newline_done:
    sub Rg1, Rg2, Rg1
    addi Rg1, Rg1, 0x0050
    jmp _end
reset:
    push Bpr
    mov Spr, Bpr
    ldw display, Rg1, 0x0000
    jmp _end
clear:
    push Bpr
    mov Spr, Bpr
    lli Rg0, 0x01f4
    ldw display, Rg1, 0x0000
_clear_loop:
    subi Rg0, Rg0, 0x0001
    stw Zero, Rg1, 0x0000
    addi Rg1, Rg1, 0x0004
    igt Rg0, Zero, Rg4
    jnz Rg4, _clear_loop
    jmp _end
_end:
    stw current, Rg1, 0x0000
    mov Bpr, Spr
    pop Bpr
    ret
