; ***************************************************************************
; 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, r20
    adc r17, r21
    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

