// 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-8 | 0
|