; *************************************************************************** ; copyright : (C) 2026 by Martin Preuss ; email : martin@libchipcard.de ; ; *************************************************************************** ; * This file is part of the project "AqHome". * ; * Please see toplevel file COPYING of that project for license details. * ; *************************************************************************** #ifndef AQH_AVR_COMMON_ITOA_ASM #define AQH_AVR_COMMON_ITOA_ASM ; *************************************************************************** ; defines .equ ITOA_BUFFER_SIZE = 8 ; *************************************************************************** ; global data .dseg itoa_buffer: ; max uint16 65535, 5 digits, plus komma, sign, ZERO .byte ITOA_BUFFER_SIZE ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine IntToAscii @global ; ; @param R21:R20 value to transform to ascii ; @param R24 number of digits after komma ; @return X pointer to result string (will be overwritten by next call!) ; @clobbers R16, R17, R18, R19, R20, R21, R22, R23 IntToAscii: ldi xl, LOW(itoa_buffer) ldi xh, HIGH(itoa_buffer) adiw xh:xl, ITOA_BUFFER_SIZE clr r16 st -X, r16 ldi r25, ITOA_BUFFER_SIZE-1 ; byte counter IntToAscii_loop: ; divide by 10 ldi r22, 10 clr r23 push r25 bigcall Utils_Divu16_16_16 ; R17:R16=result, R19:R18=remainder (R25) pop r25 ; move result for next loop mov r20, r16 mov r21, r17 ; store digit of remainder (can only be 0-9 when dividing by 10) ldi r19, '0' add r19, r18 st -X, r19 dec r25 breq IntToAscii_ret ; maybe insert komma tst r24 breq IntToAscii_next dec r24 brne IntToAscii_next ldi r19, ',' st -X, r19 dec r25 breq IntToAscii_ret IntToAscii_next: mov r16, r20 ; result == 0? or r16, r21 breq IntToAscii_ret ; yes, done rjmp IntToAscii_loop IntToAscii_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine HexWordToAscii @global ; ; Shares buffer with @ref IntToAscii ! ; ; @param R21:R20 value to transform to ascii ; @return X pointer to result string (will be overwritten by next call!) ; @clobbers R16, R17 HexWordToAscii: ldi xl, LOW(itoa_buffer) ldi xh, HIGH(itoa_buffer) mov r16, r21 rcall writeHexByteToBuffer ; write hi byte mov r16, r20 rcall writeHexByteToBuffer ; write low byte clr r16 st X+, r16 sbiw xh:xl, 5 ret ; @end ; --------------------------------------------------------------------------- ; @routine HexByteToAscii @global ; ; Shares buffer with @ref IntToAscii ! ; ; @param R16 value to transform to ascii ; @return X pointer to result string (will be overwritten by next call!) ; @clobbers R16, R17 HexByteToAscii: ldi xl, LOW(itoa_buffer) ldi xh, HIGH(itoa_buffer) rcall writeHexByteToBuffer clr r16 st X+, r16 sbiw xh:xl, 3 ret ; @end ; --------------------------------------------------------------------------- ; @routine writeHexByteToBuffer ; ; @param R16 value to transform to ascii ; @param X pointer to current pos in result buffer ; @clobbers R16, R17 writeHexByteToBuffer: push r16 swap r16 rcall hexNibbleToAscii ; transform high nibble (r16, r17) st X+, r16 pop r16 rcall hexNibbleToAscii ; transform low nibble (r16, r17) st X+, r16 ret ; @end ; --------------------------------------------------------------------------- ; @routine hexNibbleToAscii ; ; Convert a nibble to an ASCII char. ; @return R16 ASCII representation of that nibble (e.g. '0' for 0) ; @param R16 byte (in bits 0-3) ; @clobbers r16, r17 hexNibbleToAscii: andi r16, 0xf cpi r16, 10 brcs hexNibbleToAscii_l1 ldi r17, 7 add r16, r17 hexNibbleToAscii_l1: ldi r17, '0' add r16, r17 ret ; @end #endif