Source file: /~heha/Mikrocontroller/Sprache/sprich.zip/tinyhelp.S

// Binärdatei im Flash einbinden
	.section .progmem.data,"a",@progbits
	.global spDINER
	.type   spDINER,@object
spDINER:
	.incbin "TomsDiner.lpc"

// Sonstige Hilfsroutinen
	.section .text
	.global	getBits,ptrBit,ptrAddr
getBits:
	clr	r0
	lds	r25,ptrBit
1:	cpi	r25,2
	brcc	2f
	lds	r30,ptrAddr
	lds	r31,ptrAddr+1
	lpm	r25,Z+
	sts	ptrAddr+1,r31
	sts	ptrAddr,r30
2:	ror	r25
	rol	r0
	dec	r24
	brne	1b
	sts	ptrBit,r25
	mov	r24,r0
	ret

// Ausgerollte Multiplikation mit Addierbefehlen (ATtiny-kompatibel)
	.global fmul8x16
/*
mulI10xI16Shr9:
// R25:R24 muss im Bereich -511 .. 511 liegen
	sbrs	r25,7
	 rjmp	0f
	com	r25
	neg	r24
	sbci	r25,-1
	com	r23
	neg	r22
	sbci	r23,-1
0:	movw	r0,r24
	clr	r24
	clr	r25
	asr	r23
	ror	r22
	sbrs	r1,0
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	asr	r23
	ror	r22
	clr	r1
	sbrs	r0,7
	 rjmp	7f
	add	r24,r22
	adc	r25,r23
	rjmp	7f
*/
fmul8x16:	// R25:R24 = (R24 × R23:R22) >> 7, beide vzb.
// R24 darf nie 0x80 sein!! Min. 48 Takte, max. 63 Takte (ohne CALL, mit RET).
#if 1	// ATmega
	clr	r20
	mov	r21,r24
	fmuls	r21,r23		// (signed)a * (signed)bh << 1, ignore C
	movw	r24,r0
	fmulsu	r21,r22		// (signed)a * bl << 1
	sbc	r25,r20		// Der Trick mit dem C-Flag
	add	r24,r1		// R0 ignorieren
	adc	r25,r20
	clr	r1
	ret
#else	// ATtiny
	sbrs	r24,7
	 rjmp	0f
	neg	r24		// R24 positiv
	com	r23
	neg	r22
	sbci	r23,-1		// R23:R22 negieren
0:	mov	r0,r24
	clr	r24
	clr	r25		// Akku leeren
7:	asr	r23
	ror	r22		// 1 Bit weg
	sbrs	r0,6
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	asr	r23
	ror	r22		// 2 Bit weg
	sbrs	r0,5
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	asr	r23
	ror	r22		// 3 Bit weg
	sbrs	r0,4
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	asr	r23
	ror	r22		// 4 Bit weg
	sbrs	r0,3
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	asr	r23
	ror	r22		// 5 Bit weg
	sbrs	r0,2
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	asr	r23
	ror	r22		// 6 Bit weg
	sbrs	r0,1
	 rjmp	0f
	add	r24,r22
	adc	r25,r23
0:	sbrs	r0,0
	 rjmp	0f
	asr	r23
	ror	r22		// 7 Bit weg
	add	r24,r22
	adc	r25,r23
0:	ret
#endif
/*
	.global fmuls16x16_32,mpy16s,mpy16u
fmuls16x16_32:	// fmul geht nur mit Quellregistern r16..r23!!
	movw	r18,r24
	clr	r20
	fmuls	r19,r23		; ( (signed)ah * (signed)bh ) << 1
	movw	r24,r0
	fmul	r18,r22		; ( al * bl ) << 1
	adc	r24,r20		; Das Bit 0 von R24 muss nach fmuls =0 sein
	movw	r30,r0		; ZH:ZL ist Low-Teil des Multiplikationsergebnisses
	fmulsu	r19,r22		; ( (signed)ah * bl ) << 1
	sbc	r25,r20		; DAS ist wirklich ein rätselhafter Trick!
	add	r31,r0
	adc	r24,r1
	adc	r25,r20
	fmulsu	r23,r18		; ( (signed)bh * al ) << 1
	sbc	r25,r20		; NOCH MAL der Griff in die Trickkiste!
	add	r31,r0
	adc	r24,r1
	adc	r25,r20
	movw	r22,r30
	clr	r1
	ret

mpy16s:		// R25:R24 x R23:R22 = R25:R24:R23:R22	210~226
	movw	r0,r24
	clr	r25		;clear result byte 3
	sub	r24,r24		;clear result byte 2 and carry
	ldi	r20,16	;init loop counter
1:	brcc	2f		;if carry (previous bit) set
	add	r24,r0	;    add multiplicand Low to result byte 2
	adc	r25,r1	;    add multiplicand High to result byte 3
2:	sbrs	r22,0	;if current bit set
	 rjmp	3f
	sub	r24,r0	;    sub multiplicand Low from result byte 2
	sbc	r25,r1	;    sub multiplicand High from result byte 3
3:	asr	r25		;shift right result and multiplier
	ror	r24
	ror	r23
	ror	r22
	dec	r20	;decrement counter
	brne	1b		;if not done, loop more	
	clr	r1
	ret

mpy16u:		// R25:R24 x R23:R22 = R25:R24:R23:R22	140~153
	movw	r0,r24
	clr	r25		;clear 2 highest bytes of result
	clr	r24
	ldi	r20,16	;init loop counter
	lsr	r23
	ror	r22
1:	brcc	2f		;if bit 0 of multiplier set
	add	r24,r0	;add multiplicand Low to byte 2 of res
	adc	r25,r1	;add multiplicand high to byte 3 of res
2:	ror	r25		;shift right result byte 3
	ror	r24	;rotate right result byte 2
	ror	r23	;rotate result byte 1 and multiplier High
	ror	r22	;rotate result byte 0 and multiplier Low
	dec	r20		;decrement loop counter
	brne	1b		;if not done, loop more
	clr	r1
	ret
*/
Detected encoding: UTF-80