where : ibrtses embedded

AVR math

ASM

signed16 multiplied with unsigned8 - limited

assumed the CPU supports the required commands
all in CSEG :
; multiply S16:=S16*U8 with overflow protection both ways
;
; result:= Z^, S16:=Y^, U8:=u1	 16 bit as little endian
;
; there is no overflow bigger than 0x7FFF or smaller 0x8000
MulS16U8:
	push	temp
	push	u2
	push	u3
	push	u4
	push	u5

	clr	u2	; low result
	clr	u3	; high result
	ld	u4,Y	; low S16
	ldd	u5,Y+1	; high S16
	ldd	temp,Y+1	; get sign of S16
	andi	temp,0x80	
	brne	ms16u8_1
; positive
ms16u8_0:
	lsr	u1
	brcc	ms16u8_3	; skip
	add	u2,u4
	adc	u3,u5
	mov	temp,u3
	andi	temp,0x80
	brne	ms16u8_2	; positive overflow
ms16u8_3:
	tst	u1
	breq	ms16u8_end	; end
	lsl	u4		; shift left
	rol	u5
	brmi	ms16u8_6	; goes negative
	rjmp	ms16u8_0	;again
ms16u8_2:			;positive overflow
	ldi	u2,0xFF		; set max number 0x7FFF
	ldi	u3,0x7F
	rjmp	ms16u8_end	; end
ms16u8_6:			; shift goes negative
	tst	u1		;  set overflow if more to add
	brne	ms16u8_2
	rjmp	ms16u8_end	;  or terminate if end
; negative
ms16u8_1:
	lsr	u1
	brcc	ms16u8_4	;skip
	add	u2,u4
	adc	u3,u5
	mov	temp,u3
	andi	temp,0x80
	breq	ms16u8_5	;negative overflow
ms16u8_4:
	tst	u1
	breq	ms16u8_end	;end;
	lsl	u4
	rol	u5
	brpl	ms16u8_7	; goes positive
	rjmp	ms16u8_1	;again
ms16u8_5:			;negative overflow
	ldi	u2,0x00		; set min number=0x8000
	ldi	u3,0x80
	rjmp	ms16u8_end	; end
ms16u8_7:			;shift goes positive
	tst	u1		; set overflow if more to add
	brne	ms16u8_5
ms16u8_end:
	st	Z,u2
	std	Z+1,u3

	pop	u5
	pop	u4
	pop	u3
	pop	u2
	pop	temp
	ret

add 2 signed 16 bit - limited

 assume U1..U3 as R16..R31
;addition of 2 signed 16 bit with overflow protection ; add into 24 bit then test ; ; result:= Z^, S16:=Y^, Z^:=Z^+Y^ 16 bit as little endian ; ; there is no overflow bigger than 0x7FFF or smaller 0x8000 addS16: push temp push u1 push u2 push u3 push u4 push u5 ld u2,Z ; low result ldd u3,Z+1 ; high result ld u4,Y ; low S16 ldd u5,Y+1 ; high S16 tst u3 brpl as16_1 ; neg Z tst u5 brpl as16_2 ; neg + neg add u2,u4 adc u3,u5 brmi as16_end ; neg + neg overflow ldi u2,0x00 ldi u3,0x80 ; ok rjmp as16_end ; neg + pos as16_2: add u2,u4 adc u3,u5 rjmp as16_end ; pos + neg as16_3: add u2,u4 adc u3,u5 rjmp as16_end ; pos Z as16_1: tst u5 brmi as16_3 ; pos + pos ldi temp,0 ldi u1,0 add u2,u4 adc u3,u5 brpl as16_end ; pos + pos overflow ldi u2,0xFF ldi u3,0x7F as16_end: st Z,u2 std Z+1,u3 pop u5 pop u4 pop u3 pop u2 pop u1 pop temp ret



Questions ?
Suggestions?
Feedback ?






sponsored links




disclaimer


AVR index
embedded software pages
home

last updated: 18.sept.00



Copyright (99,2001) Ing.Büro R.Tschaggelar