.global btohex
.global tohex

.section .rodata

hexchars:
  .ascii "0123456789ABCDEF"

.text

# Write hex representation of word into buffer
#    arguments:
#       a0: value to format
#       a1: address of buffer to write to
#   temporaries used:
#       t0
#    return:
#       none
tohex:
    addi sp, sp, -20  # allocate stack space
    sw s0, 16(sp)     # save contents of s0
    sw s1, 12(sp)      # save contents of s1
    li s0, 0          # set up loop variables
    li s1, 4
    addi a1, a1, 6    # offset output address to end chars
tohex_loop:
    sw ra, 8(sp)      # save contents of ra
    sw a0, 4(sp)      # save contents of ra
    sw a1, 0(sp)      # save contents of ra
    jal btohex
    lw a1, 0(sp)      # restore contents of a1
    sh a0, 0(a1)      # write the two bytes to the output buffer
    lw a0, 4(sp)      # restore contents of a0
    lw ra, 8(sp)      # restore contents of ra
    srli a0, a0, 8    # shift the next byte to format down
    addi a1, a1, -2   # decrement output buffer address
    addi s0, s0, 1    # increment loop counter
    blt s0, s1, tohex_loop # TODO: we don't need the loop counter and output addr
    lw s0, 16(sp)     # restore s0 & s1
    lw s1, 12(sp)
    addi sp, sp, 20   # deallocate stack space
    ret

# Convert byte to ASCII hex
#    arguments:
#       a0: value to format
#   temporaries used:
#       t0, t1
#    return:
#       a0: value in ASCII hex
btohex:
    la   a1, hexchars     # load address of hexchars
    andi t0, a0, 0xF      # Mask off lower nybble
    add  a2, a1, t0       # a2 = offset to nybble hex char
    lbu  t0, 0(a2)        # load hex char for lower nybble into t0
    srli t1, a0, 4        # shift upper nybble down
    andi t1, t1, 0xF      # mask off upper nybble
    add  a2, a1, t1       # offset to nybble
    lbu  a0, 0(a2)        # load hex char for upper nybble into a0
    slli t0, t0, 8        # shift lower char up (little endian)
    or   a0, a0, t0       # OR the lower char into a0
    ret