                    .setcpu "6502"
                    .include "macros.inc65"
                    .include "zeropage.inc65"

                    .export fmt_hex_char
                    .export fmt_bin_string
                    .export fmt_hex_string
                    .export scan_hex_char
                    .export scan_hex
                    .export scan_hex16

                    .code

; Format the value of the accu as a binary string
; The string is written into (R0)..(R0)+8 (9 bytes)
fmt_bin_string:     sta TMP0
                    phay
                    ldy #8
                    lda #0
                    sta (R0),y
                    dey
@next_bit:          lsr TMP0
                    bcs @bit_is_1
@bit_is_0:          lda #'0'
                    jmp @store_char
@bit_is_1:          lda #'1'
@store_char:        sta (R0),y
                    dey
                    bpl @next_bit
                    play
                    rts

; Convert the 4-bit value of the accu into it's hex ascii character
; The hex ascii character is returned in the accu
fmt_hex_char:       cmp #10
                    bcc @less_then_10
@greater_then_10:   sec
                    sbc #10
                    clc
                    adc #'A'
                    rts
@less_then_10:      clc
                    adc #'0'
                    rts

; Format the value of the accu as a hex string
; The string is written into (R0)..(R0)+2 (3 bytes)
fmt_hex_string:     sta TMP0
                    phay
                    ldy #0
                    lda TMP0
                    lsr
                    lsr
                    lsr
                    lsr
                    jsr fmt_hex_char
                    sta (R0),y
                    iny
                    lda TMP0
                    and #$0f
                    jsr fmt_hex_char
                    sta (R0),y
                    iny
                    lda #0
                    sta (R0),y
                    play
                    rts

; Convert the hex character in the accu to its integer value
; The integer value is returned in the accu
scan_hex_char:      cmp #'0'
                    bcc @invalid
                    cmp #('9' + 1)
                    bcs @no_digit
                    sec
                    sbc #'0'
                    rts
@no_digit:          cmp #'A'
                    bcc @invalid
                    cmp #('F' + 1)
                    bcs @no_upper_hex
                    sec
                    sbc #('A' - 10)
                    rts
@no_upper_hex:      cmp #'a'
                    bcc @invalid
                    cmp #('f' + 1)
                    bcs @invalid
                    sec
                    sbc #('a' - 10)
                    rts
@invalid:           lda #0
                    rts

; Convert two hex characters starting at (R0) into an integer value
; The integer value is returned in the accu
scan_hex:           tya
                    pha
                    ldy #0
                    lda (R0),y
                    jsr scan_hex_char
                    asl
                    asl
                    asl
                    asl
                    sta TMP0
                    iny
                    lda (R0),y
                    jsr scan_hex_char
                    ora TMP0
                    sta TMP0
                    pla
                    tay
                    lda TMP0
                    rts

; Convert four hex characters starting at (R0) into an integer value
; The integer value is returned in RES..RES+1
scan_hex16:         phay
                    ldy #0
                    lda (R0),y
                    jsr scan_hex_char
                    asl
                    asl
                    asl
                    asl
                    sta RES + 1
                    iny
                    lda (R0),y
                    jsr scan_hex_char
                    ora RES + 1
                    sta RES + 1
                    iny
                    lda (R0),y
                    jsr scan_hex_char
                    asl
                    asl
                    asl
                    asl
                    sta RES
                    iny
                    lda (R0),y
                    jsr scan_hex_char
                    ora RES
                    sta RES
                    play
                    rts
