; *************************************************************************** ; copyright : (C) 2025 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 COMMON_MULTIPLY_H #define COMMON_MULTIPLY_H ; --------------------------------------------------------------------------- ; @routine Utils_Mulu16x16_32 ; ; Multiplies two unsigned 16 bit values resulting in one 32 bit value. ; This is a rather simple but reasonable fast routine working just like you would ; when doing multiplications with pen and paper. ; ; R19:R18:R17:R16 = R21:R20 * R23:R22 ; ; TODO: adapt for signed values ; ; @param R21:R20 16 bit value A ; @param R23:R22 16 bit value B ; @return R19:R18:R17:R16 32 bit result ; @clobbers R16, R17, R18, R19, R20, R21, R22, R23, R24, R25, R26 Utils_Mulu16x16_32: clr r19 clr r18 clr r17 clr r16 clr r25 clr r24 ldi r26, 16 ; 16 bit multiplicator Utils_Mulu16x16_32_loop: lsr r23 ror r22 brcc Utils_Mulu16x16_32_noadd ; current digit in B is 0, don't add shifted A to result add r16, r22 adc r17, r23 adc r18, r24 adc r19, r25 ; brcs Utils_Mulu16x16_32_overflow ; can't happen Utils_Mulu16x16_32_noadd: dec r26 breq Utils_Mulu16x16_32_done lsl r20 rol r21 rol r24 rol r25 ; brcs Utils_Mulu16x16_32_overflow ; can't happen rjmp Utils_Mulu16x16_32_loop Utils_Mulu16x16_32_done: clc ret ;Utils_Mulu16x16_32_overflow: ; never reached. Multiplying 2 16 bit values can't overflow 32 bit ; sec ; ret ; @end #endif ; COMMON_MULTIPLY_H