Asembler mikrokontrolerów AVR     Różne procedury      Kompilacja


Aby sprawdzić działanie wszystkich poniższych procedur, były one odpowiednio implementowane
w kodzie programu, który służy do obsługi wyświetlacza LCD. Polegało to na: umieszczeniu kodu
danej procedury za główną pętlą programu, ustawieniu dowolnych wartości argumentów wejściowych
oraz wykonaniu rozgałęzienia do danej procedury. Następnie sprawdza się, czy dane wyjściowe
z procedury zgadzają się z oczekiwanym rezultatem.

Konwersja danych:
NAZWA
OPIS
ARGUMENTY
WEJŚCIOWE
WYJŚCIE
DANYCH
UŻYWANIE
STOSU
ConBDKonwersja bajtu do systemu DEC-ASCIIZR16sbuf-
ConBDs Konwersja bajtu do systemu DEC-ASCIIZ (szybka) R16sbuf-
Con8DKonwersja 8-bitów do systemu DEC-ASCIIZR22sbuf-
Con16DKonwersja 16-bitów do systemu DEC-ASCIIZ[R22:R23]sbuf-
Con24DKonwersja 24-bitów do systemu DEC-ASCIIZ[R22:R23:R24]sbuf-
Con32DKonwersja 32-bitów do systemu DEC-ASCIIZ[R22:R23:R24:R25] sbuf-
ConBOKonwersja bajtu do systemu OCT-ASCIIZR16sbuf-
ConBOsKonwersja bajtu do systemu OCT-ASCIIZ (szybka)R16sbuf-
Con8OKonwersja 8-bitów do systemu OCT-ASCIIZR22sbuf-
Con16OKonwersja 16-bitów do systemu OCT-ASCIIZ[R22:R23]sbuf-
Con24OKonwersja 24-bitów do systemu OCT-ASCIIZ[R22:R23:R24]sbuf-
Con32OKonwersja 32-bitów do systemu OCT-ASCIIZ[R22:R23:R24:R25]sbuf-
ConBHKonwersja bajtu do systemu HEX-ASCIIZR16sbuf-
ConBBKonwersja bajtu do systemu BIN-ASCIIZR16sbuf-

Operacje matematyczne:
NAZWA
OPIS
ARGUMENTY
WEJŚCIOWE
WYJŚCIE
DANYCH
UŻYWANIE
STOSU
Add168Dodawanie bajtu NN do słowa:
[16] + [8] = [16]
[R22:R23] + R18[R22:R23]-
Add1616Dodawanie 2 słów: [16] + [16] = [16][R22:R23] + [R18:R19] [R22:R23]-
Add248Dodawanie bajtu NN do wartości
24-bitowej: [24] + [8] = [24]
[R22:R23:R24] + R18[R22:R23:R24]-
Add2416Dodawanie słowa do wartości
24-bitowej: [24] + [16] = [24]
[R22:R23:R24]
+ [R18:R19]
[R22:R23:R24]-
Add2424Dodawanie 2 wartości 24-bitowych:
[24] + [24] = [24]
[R22:R23:R24]
+ [R18:R19:R20]
[R22:R23:R24]-
Add328Dodawanie bajtu NN do wartości
32-bitowej: [32] + [8] = [32]
[R22:R23:R24:R25]
+ R18
[R22:R23:R24:R25]-
Add3216Dodawanie słowa do wartości
32-bitowej: [32] + [16] = [32]
[R22:R23:R24:R25]
+ [R18:R19]
[R22:R23:R24:R25]-
Add3224Dodawanie wartości 24-bitowej do
wartości 32-bitowej: [32] + [24] = [32]
[R22:R23:R24:R25]
+ [R18:R19:R20]
[R22:R23:R24:R25]-
Add3232Dodawanie 2 wartości 32-bitowych:
[32] + [32] = [32]
[R22:R23:R24:R25]
+ [R18:R19:R20:R21]
[R22:R23:R24:R25]-
Sub168Odejmowanie bajtu NN od słowa:
[16] - [8] = [16]
[R22:R23] - R18[R22:R23]-
Sub1616Odejmowanie 2 słów: [16] - [16] = [16][R22:R23] - [R18:R19][R22:R23]-
Sub248Odejmowanie bajtu NN od wartości
24-bitowej: [24] - [8] = [24]
[R22:R23:R24] - R18[R22:R23:R24]-
Sub2416Odejmowanie słowa od wartości
24-bitowej: [24] - [16] = [24]
[R22:R23:R24]
- [R18:R19]
[R22:R23:R24]-
Sub2424Odejmowanie 2 wartości 24-bitowych:
[24] - [24] = [24]
[R22:R23:R24]
- [R18:R19:R20]
[R22:R23:R24]-
Sub328Odejmowanie bajtu NN od wartości
32-bitowej: [32] - [8] = [32]
[R22:R23:R24:R25]
- R18
[R22:R23:R24:R25]-
Sub3216Odejmowanie słowa od wartości
32-bitowej: [32] - [16] = [32]
[R22:R23:R24:R25]
- [R18:R19]
[R22:R23:R24:R25]-
Sub3224Odejmowanie wartości 24-bitowej od
wartości 32-bitowej: [32] - [24] = [32]
[R22:R23:R24:R25]
- [R18:R19:R20]
[R22:R23:R24:R25]-
Sub3232Odejmowanie 2 wartości 32-bitowych:
[32] - [32] = [32]
[R22:R23:R24:R25]
- [R18:R19:R20:R21]
[R22:R23:R24:R25]-
Mul88Mnożenie 2 bajtów: [8] * [8] = [16]R18 * R23[R22:R23]-
Mul88sMnożenie 2 bajtów: [8] * [8] = [16]
(szybka)
R18 * R23[R22:R23]-
Mul168sMnożenie słowa przez bajt NN:
[16] * [8] = [24] (szybka)
[R18:R19] * R20[R22:R23:R24]-
Mul1616Mnożenie 2 słów: [16] * [16] = [32][R18:R19] * [R24:R25][R22:R23:R24:R25]-
Mul1616s Mnożenie 2 słów: [16] * [16] = [32]
(szybka)
[R18:R19] * [R20:R21][R22:R23:R24:R25]-
Div88Dzielenie 2 bajtów: [8] / [8] = [8] + [8]R22 / R18R22 + R2-
Div1616Dzielenie 2 słów: [16] / [16] = [16] + [16] [R22:R23] / [R18:R19][R22:R23] + [R2:R3] -

Pętle opóźniające:
NAZWA
OPIS
ARGUMENTY
WEJŚCIOWE
WYJŚCIE
DANYCH
UŻYWANIE
STOSU
L8Pętla opóźniająca o 3-768 cykli zegarowych:
X = A*3, A=0: X=768
R16--
L16Pętla opóźniająca o 5-262145 cykli zegarowych:
X = A*4+1, A=0: X=262145
[XH:XL]--
L88Pętla opóźniająca o 6-197376 cykli zegarowych:
X = A*(B*6-(B-1)*3), A=0/B=0: X=197376
R16, R17--
L816Pętla opóźniająca o 8-67109888 cykli zegarowych:
X = A*(B*8-(B-1)*4), A=0/B=0: X=67109888
R16, [XH:XL]--
L168Pętla opóźniająca o 8-50593793 cykli zegarowych:
X = A*(B*8-(B-1)*5)-(A-1), A=0/B=0: X=50593793
[XH:XL], R16--
L1616    Pętla opóźniająca o 10-17180196865 cykli zegarowych:
X = A*(B*10-(B-1)*5)-(A*B-1), A=0/B=0: X=17180196865 
[XH:XL], [YH:YL] --
WaitPętla opóźniająca o zadany czas: 100us - 25.5msR15, R16--
WaitMPętla opóźniająca o zadany czas: 10ms - 2.55sR15, R16--

Inne:
NAZWA
OPIS
ARGUMENTY
WEJŚCIOWE
WYJŚCIE
DANYCH
UŻYWANIE
STOSU
LenStrLiczenie znaków w ciągu ASCIIZ z pamięci SRAMsbufR16-
LenStfLiczenie znaków w ciągu ASCIIZ z pamięci FLASHfbufR16-
DelZeroUsuwanie zbędnych zer z wartości ASCIIZsbufsbuf-
ClrZeroZamienianie zbędnych zer w wartości ASCIIZ na spacjesbufsbuf-
FuseBitGenerowanie ciągu ASCIIZ z szesnastkowymi wartościami
fuse/lock bitów: "FL:LB:FE:FH"
-sbuf-
RegSREG Generowanie ciągu ASCIIZ z wartościami flag rejestru SREG SREGsbuf-
ScalXYPodwajanie wymiarów bitmapy 8x8 pikseli z pamięci FLASHfbufsbuf-

Objaśnienia:
SREG - rejestr stanu (Status REGister)
Rx - rejestr 8-bitowy ogólnego przeznaczenia
[R22:R23] - wartość 16-bitowa: R22/R23 - starszy/młodszy bajt
[R22:R23:R24:R25] - wartość 32-bitowa: R22/R25 - najstarszy/najmłodszy bajt
[RxH:RxL] - wartość 16-bitowa tworzona przez parę rejestrów (starszy:młodszy bajt). W pętlach opóźniających
można używać tylko tych par, które są obsługiwane przez instrukcję odejmowania SBIW: [R25:R24],
[R27:R26] (XH:XL), [R29:R28] (YH:YL), [R31:R30] (ZH:ZL).
sbuf - pamięć dla danych wejściowych/wyjściowych (SRAM)
fbuf - pamięć dla danych wejściowych (FLASH)


 ConBD: ldi     R16,$00       ;bajt do konwersji
        ldi     ZL,LOW(sbuf)
        ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
        ldi     R17,$64
ConBD0: ldi     R18,$2F
ConBD1: inc     R18
        sub     R16,R17
        brcc    ConBD1
        add     R16,R17
        st      Z+,R18
        lsr     R17
        lsr     R17
        lsr     R17
        breq    ConBD2
        brcc    ConBD0
        subi    R17,$02
        rjmp    ConBD0
ConBD2: st      Z,R17
        ret

;Maksymalna wartość liczby wyjściowej: "255" ($FF)
;Rozmiar: 38 B, linii kodu: 19
 ConBDs: ldi     R16,$00       ;bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         ldi     R17,$3A
         ldi     R18,$2F
ConBDs0: inc     R18
         subi    R16,$64
         brcc    ConBDs0
ConBDs1: dec     R17
         subi    R16,$F6
         brmi    ConBDs1
         subi    R16,$D0
         st      Z+,R18
         st      Z+,R17
         st      Z+,R16
         clr     R16
         st      Z,R16
         ret

;Maksymalna wartość liczby wyjściowej: "255" ($FF)
;Rozmiar: 36 B, linii kodu: 18
 Con8D: ldi     R22,$00       ;bajt do konwersji
        ldi     ZL,LOW(sbuf)
        ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
        clr     R16
        adiw    ZL,$03
        st      Z,R16
        ldi     R17,$03       ;maksymalna liczba cyfr
Con8D0: ldi     R18,$08       ;liczba bitów do konwersji
        sub     R16,R16
Con8D1: rol     R16
        cpi     R16,$0A
        brcs    Con8D2
        subi    R16,$0A
        sec
        rjmp    Con8D3
Con8D2: clc
Con8D3: rol     R22
        dec     R18
        brpl    Con8D1
        subi    R16,$D0
        st      -Z,R16
        dec     R17
        brne    Con8D0
        ret

;Maksymalna wartość liczby wyjściowej: "255" ($FF)
;Rozmiar: 48 B, linii kodu: 24
 Con16D: ldi     R22,$00       ;starszy bajt do konwersji
         ldi     R23,$00       ;młodszy bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         clr     R16
         adiw    ZL,$05
         st      Z,R16
         ldi     R17,$05       ;maksymalna liczba cyfr
Con16D0: ldi     R18,$10       ;liczba bitów do konwersji
         sub     R16,R16
Con16D1: rol     R16
         cpi     R16,$0A
         brcs    Con16D2
         subi    R16,$0A
         sec
         rjmp    Con16D3
Con16D2: clc
Con16D3: rol     R23
         rol     R22
         dec     R18
         brpl    Con16D1
         subi    R16,$D0
         st      -Z,R16
         dec     R17
         brne    Con16D0
         ret

;Maksymalna wartość liczby wyjściowej: "65535" ($FFFF)
;Rozmiar: 52 B, linii kodu: 26
 Con24D: ldi     R22,$00       ;najstarszy bajt do konwersji
         ldi     R23,$00
         ldi     R24,$00       ;najmłodszy bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         clr     R16
         adiw    ZL,$08
         st      Z,R16
         ldi     R17,$08       ;maksymalna liczba cyfr
Con24D0: ldi     R18,$18       ;liczba bitów do konwersji
         sub     R16,R16
Con24D1: rol     R16
         cpi     R16,$0A
         brcs    Con24D2
         subi    R16,$0A
         sec
         rjmp    Con24D3
Con24D2: clc
Con24D3: rol     R24
         rol     R23
         rol     R22
         dec     R18
         brpl    Con24D1
         subi    R16,$D0
         st      -Z,R16
         dec     R17
         brne    Con24D0
         ret

;Maksymalna wartość liczby wyjściowej: "16777215" ($FFFFFF)
;Rozmiar: 56 B, linii kodu: 28
 Con32D: ldi     R22,$00       ;najstarszy bajt do konwersji
         ldi     R23,$00
         ldi     R24,$00
         ldi     R25,$00       ;najmłodszy bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         clr     R16
         adiw    ZL,$0A
         st      Z,R16
         ldi     R17,$0A       ;maksymalna liczba cyfr
Con32D0: ldi     R18,$20       ;liczba bitów do konwersji
         sub     R16,R16
Con32D1: rol     R16
         cpi     R16,$0A
         brcs    Con32D2
         subi    R16,$0A
         sec
         rjmp    Con32D3
Con32D2: clc
Con32D3: rol     R25
         rol     R24
         rol     R23
         rol     R22
         dec     R18
         brpl    Con32D1
         subi    R16,$D0
         st      -Z,R16
         dec     R17
         brne    Con32D0
         ret

;Maksymalna wartość liczby wyjściowej: "4294967295" ($FFFFFFFF)
;Rozmiar: 60 B, linii kodu: 30
 ConBO: ldi     R16,$00       ;bajt do konwersji
        ldi     ZL,LOW(sbuf)
        ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
        ldi     R17,$40
ConBO0: ldi     R18,$2F
ConBO1: inc     R18
        sub     R16,R17
        brcc    ConBO1
        add     R16,R17
        st      Z+,R18
        lsr     R17
        lsr     R17
        lsr     R17
        brne    ConBO0
        st      Z,R17
        ret

;Maksymalna wartość liczby wyjściowej: "377" ($FF)
;Rozmiar: 32 B, linii kodu: 16
 ConBOs: ldi     R16,$00       ;bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         ldi     R17,$38
         ldi     R18,$2F
ConBOs0: inc     R18
         subi    R16,$40
         brcc    ConBOs0
ConBOs1: dec     R17
         subi    R16,$F8
         brmi    ConBOs1
         subi    R16,$D0
         st      Z+,R18
         st      Z+,R17
         st      Z+,R16
         clr     R16
         st      Z,R16
         ret

;Maksymalna wartość liczby wyjściowej: "377" ($FF)
;Rozmiar: 36 B, linii kodu: 18
 Con8O: ldi     R22,$00       ;bajt do konwersji
        ldi     ZL,LOW(sbuf)
        ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
        clr     R16
        adiw    ZL,$03
        st      Z,R16
        ldi     R17,$03       ;maksymalna liczba cyfr
Con8O0: ldi     R18,$08       ;liczba bitów do konwersji
        sub     R16,R16
Con8O1: rol     R16
        cpi     R16,$08
        brcs    Con8O2
        subi    R16,$08
        sec
        rjmp    Con8O3
Con8O2: clc
Con8O3: rol     R22
        dec     R18
        brpl    Con8O1
        subi    R16,$D0
        st      -Z,R16
        dec     R17
        brne    Con8O0
        ret

;Maksymalna wartość liczby wyjściowej: "377" ($FF)
;Rozmiar: 48 B, linii kodu: 24
 Con16O: ldi     R22,$00       ;starszy bajt do konwersji
         ldi     R23,$00       ;młodszy bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         clr     R16
         adiw    ZL,$06
         st      Z,R16
         ldi     R17,$06       ;maksymalna liczba cyfr
Con16O0: ldi     R18,$10       ;liczba bitów do konwersji
         sub     R16,R16
Con16O1: rol     R16
         cpi     R16,$08
         brcs    Con16O2
         subi    R16,$08
         sec
         rjmp    Con16O3
Con16O2: clc
Con16O3: rol     R23
         rol     R22
         dec     R18
         brpl    Con16O1
         subi    R16,$D0
         st      -Z,R16
         dec     R17
         brne    Con16O0
         ret

;Maksymalna wartość liczby wyjściowej: "177777" ($FFFF)
;Rozmiar: 52 B, linii kodu: 26
 Con24O: ldi     R22,$00       ;najstarszy bajt do konwersji
         ldi     R23,$00
         ldi     R24,$00       ;najmłodszy bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         clr     R16
         adiw    ZL,$08
         st      Z,R16
         ldi     R17,$08       ;maksymalna liczba cyfr
Con24O0: ldi     R18,$18       ;liczba bitów do konwersji
         sub     R16,R16
Con24O1: rol     R16
         cpi     R16,$08
         brcs    Con24O2
         subi    R16,$08
         sec
         rjmp    Con24O3
Con24O2: clc
Con24O3: rol     R24
         rol     R23
         rol     R22
         dec     R18
         brpl    Con24O1
         subi    R16,$D0
         st      -Z,R16
         dec     R17
         brne    Con24O0
         ret

;Maksymalna wartość liczby wyjściowej: "77777777" ($FFFFFF)
;Rozmiar: 56 B, linii kodu: 28
 Con32O: ldi     R22,$00       ;najstarszy bajt do konwersji
         ldi     R23,$00
         ldi     R24,$00
         ldi     R25,$00       ;najmłodszy bajt do konwersji
         ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
         clr     R16
         adiw    ZL,$0B
         st      Z,R16
         ldi     R17,$0B       ;maksymalna liczba cyfr
Con32O0: ldi     R18,$20       ;liczba bitów do konwersji
         sub     R16,R16
Con32O1: rol     R16
         cpi     R16,$08
         brcs    Con32O2
         subi    R16,$08
         sec
         rjmp    Con32O3
Con32O2: clc
Con32O3: rol     R25
         rol     R24
         rol     R23
         rol     R22
         dec     R18
         brpl    Con32O1
         subi    R16,$D0
         st      -Z,R16
         dec     R17
         brne    Con32O0
         ret

;Maksymalna wartość liczby wyjściowej: "37777777777" ($FFFFFFFF)
;Rozmiar: 60 B, linii kodu: 30
 ConBH: ldi     R16,$00       ;bajt do konwersji
        ldi     ZL,LOW(sbuf)
        ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
        ldi     R17,$02
ConBH0: swap    R16
        mov     R18,R16
        andi    R18,$0F
        subi    R18,$D0
        cpi     R18,$3A
        brlt    ConBH1
        subi    R18,$F9       ;subi R18,$D9 - małe litery (a-f)
ConBH1: st      Z+,R18
        dec     R17
        brne    ConBH0
        st      Z,R17
        ret

;Maksymalna wartość liczby wyjściowej: "FF" ($FF)
;Procedura generuje duże lub małe litery (a-f)
;Rozmiar: 32 B, linii kodu: 16
 ConBB: ldi     R16,$00       ;bajt do konwersji
        ldi     ZL,LOW(sbuf)
        ldi     ZH,HIGH(sbuf) ;adres wyjścia danych
        ldi     R17,$08       ;liczba bitów do konwersji
ConBB0: ldi     R18,$30
        lsl     R16
        brcc    ConBB1
        inc     R18
ConBB1: st      Z+,R18
        dec     R17
        brne    ConBB0
        st      Z,R17
        ret

;Maksymalna wartość liczby wyjściowej: "11111111" ($FF)
;Rozmiar: 26 B, linii kodu: 13
Add168: clr     R2
        add     R23,R18 ;młodszy bajt słowa/wyniku, bajt NN
        adc     R22,R2  ;starszy bajt słowa/wyniku
        ret             ;C=1 jeśli wynik >65535

;Rozmiar: 8 B, linii kodu: 4
Add1616: add     R23,R19 ;młodszy bajt 1 słowa/wyniku, młodszy bajt 2 słowa
         adc     R22,R18 ;starszy bajt 1 słowa/wyniku, starszy bajt 2 słowa
         ret             ;C=1 jeśli wynik >65535

;Rozmiar: 6 B, linii kodu: 3
Add248: clr     R2
        add     R24,R18 ;najmłodszy bajt wartości/wyniku, bajt NN
        adc     R23,R2
        adc     R22,R2  ;najstarszy bajt wartości/wyniku
        ret             ;C=1 jeśli wynik >16777215

;Rozmiar: 10 B, linii kodu: 5
Add2416: clr     R2
         add     R24,R19 ;najmłodszy bajt wartości/wyniku, młodszy bajt słowa
         adc     R23,R18 ;starszy bajt słowa
         adc     R22,R2  ;najstarszy bajt wartości/wyniku
         ret             ;C=1 jeśli wynik >16777215

;Rozmiar: 10 B, linii kodu: 5
Add2424: add     R24,R20 ;najmłodszy bajt 1 wartości/wyniku, najmłodszy bajt 2 wartości
         adc     R23,R19
         adc     R22,R18 ;najstarszy bajt 1 wartości/wyniku, najstarszy bajt 2 wartości
         ret             ;C=1 jeśli wynik >16777215

;Rozmiar: 8 B, linii kodu: 4
Add328: clr     R2
        add     R25,R18 ;najmłodszy bajt wartości/wyniku, bajt NN
        adc     R24,R2
        adc     R23,R2
        adc     R22,R2  ;najstarszy bajt wartości/wyniku
        ret             ;C=1 jeśli wynik >4294967295

;Rozmiar: 12 B, linii kodu: 6
Add3216: clr     R2
         add     R25,R19 ;najmłodszy bajt wartości/wyniku, młodszy bajt słowa
         adc     R24,R18 ;starszy bajt słowa
         adc     R23,R2
         adc     R22,R2  ;najstarszy bajt wartości/wyniku
         ret             ;C=1 jeśli wynik >4294967295

;Rozmiar: 12 B, linii kodu: 6
Add3224: clr     R2
         add     R25,R20 ;najmłodszy bajt 1 wartości/wyniku, najmłodszy bajt 2 wartości
         adc     R24,R19
         adc     R23,R18 ;najstarszy bajt 2 wartości
         adc     R22,R2  ;najstarszy bajt 1 wartości/wyniku
         ret             ;C=1 jeśli wynik >4294967295

;Rozmiar: 12 B, linii kodu: 6
Add3232: add     R25,R21 ;najmłodszy bajt 1 wartości/wyniku, najmłodszy bajt 2 wartości
         adc     R24,R20
         adc     R23,R19
         adc     R22,R18 ;najstarszy bajt 1 wartości/wyniku, najstarszy bajt 2 wartości
         ret             ;C=1 jeśli wynik >4294967295

;Rozmiar: 10 B, linii kodu: 5
Sub168: clr     R2
        sub     R23,R18 ;młodszy bajt słowa/wyniku, bajt NN
        sbc     R22,R2  ;starszy bajt słowa/wyniku
        ret             ;C=1 jeśli wynik <0

;Rozmiar: 8 B, linii kodu: 4
Sub1616: sub     R23,R19 ;młodszy bajt 1 słowa/wyniku, młodszy bajt 2 słowa
         sbc     R22,R18 ;starszy bajt 1 słowa/wyniku, starszy bajt 2 słowa
         ret             ;C=1 jeśli wynik <0

;Rozmiar: 6 B, linii kodu: 3
Sub248: clr     R2
        sub     R24,R18 ;najmłodszy bajt wartości/wyniku, bajt NN
        sbc     R23,R2
        sbc     R22,R2  ;najstarszy bajt wartości/wyniku
        ret             ;C=1 jeśli wynik <0

;Rozmiar: 10 B, linii kodu: 5
Sub2416: clr     R2
         sub     R24,R19 ;najmłodszy bajt wartości/wyniku, młodszy bajt słowa
         sbc     R23,R18 ;starszy bajt słowa
         sbc     R22,R2  ;najstarszy bajt wartości/wyniku
         ret             ;C=1 jeśli wynik <0

;Rozmiar: 10 B, linii kodu: 5
Sub2424: sub     R24,R20 ;najmłodszy bajt 1 wartości/wyniku, najmłodszy bajt 2 wartości
         sbc     R23,R19
         sbc     R22,R18 ;najstarszy bajt 1 wartości/wyniku, najstarszy bajt 2 wartości
         ret             ;C=1 jeśli wynik <0

;Rozmiar: 8 B, linii kodu: 4
Sub328: clr     R2
        sub     R25,R18 ;najmłodszy bajt wartości/wyniku, bajt NN
        sbc     R24,R2
        sbc     R23,R2
        sbc     R22,R2  ;najstarszy bajt wartości/wyniku
        ret             ;C=1 jeśli wynik <0

;Rozmiar: 12 B, linii kodu: 6
Sub3216: clr     R2
         sub     R25,R19 ;najmłodszy bajt wartości/wyniku, młodszy bajt słowa
         sbc     R24,R18 ;starszy bajt słowa
         sbc     R23,R2
         sbc     R22,R2  ;najstarszy bajt wartości/wyniku
         ret             ;C=1 jeśli wynik <0

;Rozmiar: 12 B, linii kodu: 6
Sub3224: clr     R2
         sub     R25,R20 ;najmłodszy bajt 1 wartości/wyniku, najmłodszy bajt 2 wartości
         sbc     R24,R19
         sbc     R23,R18 ;najstarszy bajt 2 wartości
         sbc     R22,R2  ;najstarszy bajt 1 wartości/wyniku
         ret             ;C=1 jeśli wynik <0

;Rozmiar: 12 B, linii kodu: 6
Sub3232: sub     R25,R21 ;najmłodszy bajt 1 wartości/wyniku, najmłodszy bajt 2 wartości
         sbc     R24,R20
         sbc     R23,R19
         sbc     R22,R18 ;najstarszy bajt 1 wartości/wyniku, najstarszy bajt 2 wartości
         ret             ;C=1 jeśli wynik <0

;Rozmiar: 10 B, linii kodu: 5
 Mul88: sub     R22,R22
        ldi     R16,$08
Mul88a: brcc    Mul88b
        add     R22,R18 ;bajt 1
Mul88b: ror     R22     ;starszy bajt wyniku
        ror     R23     ;bajt 2, młodszy bajt wyniku
        dec     R16
        brpl    Mul88a
        ret

;Rozmiar: 18 B, linii kodu: 9
Mul88s: mul     R18,R23 ;bajt 1, bajt 2
        mov     R23,R0  ;młodszy bajt wyniku
        mov     R22,R1  ;starszy bajt wyniku
        ret

;Rozmiar: 8 B, linii kodu: 4
Mul168s: mul     R19,R20 ;młodszy bajt słowa, bajt NN
         mov     R24,R0  ;najmłodszy bajt wyniku
         mov     R23,R1
         mul     R18,R20 ;starszy bajt słowa
         add     R23,R0
         adc     R22,R1  ;najstarszy bajt wyniku
         ret

;Rozmiar: 14 B, linii kodu: 7
 Mul1616: clr     R22
          sub     R23,R23
          ldi     R16,$10
Mul1616a: brcc    Mul1616b
          add     R23,R19  ;młodszy bajt 1 słowa
          adc     R22,R18  ;starszy bajt 1 słowa
Mul1616b: ror     R22      ;najstarszy bajt wyniku
          ror     R23
          ror     R24      ;starszy bajt 2 słowa
          ror     R25      ;młodszy bajt 2 słowa, najmłodszy bajt wyniku
          dec     R16
          brpl    Mul1616a
          ret

;Rozmiar: 26 B, linii kodu: 13
Mul1616s: clr     R2
          mul     R19,R21
          mov     R25,R0  ;najmłodszy bajt wyniku
          mov     R24,R1
          mul     R18,R20
          mov     R23,R0
          mov     R22,R1
          mul     R19,R20 ;młodszy bajt 1 słowa, starszy bajt 2 słowa
          add     R24,R0
          adc     R23,R1
          adc     R22,R2
          mul     R18,R21 ;starszy bajt 1 słowa, młodszy bajt 2 słowa
          add     R24,R0
          adc     R23,R1
          adc     R22,R2  ;najstarszy bajt wyniku
          ret

;Rozmiar: 32 B, linii kodu: 16
 Div88: clr     R2
        ldi     R16,$08
Div88a: lsl     R22     ;bajt 1, bajt wyniku
        rol     R2      ;bajt z niepodzieloną resztą
        cp      R2,R18  ;bajt 2
        brcs    Div88b
        inc     R22
        sub     R2,R18
Div88b: dec     R16
        brne    Div88a
        ret

;Jeśli R18 (bajt 2) > R22 (bajt 1): wynik = $00, reszta = R22 (bajt 1).
;Po dzieleniu przez 0: wynik = $FF, reszta = R22 (bajt 1) (0/0 i 255/1 dają taki sam rezultat).

;Rozmiar: 22 B, linii kodu: 11
 Div1616: clr     R2
          clr     R3
          ldi     R16,$10
Div1616a: lsl     R23      ;młodszy bajt 1 słowa/wyniku
          rol     R22      ;starszy bajt 1 słowa/wyniku
          rol     R3       ;młodszy bajt słowa z niepodzieloną resztą
          rol     R2       ;starszy bajt słowa z niepodzieloną resztą
          cp      R3,R19   ;młodszy bajt 2 słowa
          cpc     R2,R18   ;starszy bajt 2 słowa
          brcs    Div1616b
          inc     R23
          sub     R3,R19
          sbc     R2,R18
Div1616b: dec     R16
          brne    Div1616a
          ret

;Jeśli [R18:R19] (słowo 2) > [R22:R23] (słowo 1): wynik = $0000, reszta = [R22:R23] (słowo 1).
;Po dzieleniu przez 0: wynik = $FFFF, reszta = [R22:R23] (słowo 1) (0/0 i 65535/1 dają taki sam
;rezultat).

;Rozmiar: 32 B, linii kodu: 16
 L8: ldi     R16,$01 ;liczba A
L8a: dec     R16
     brne    L8a

;Rozmiar: 6 B, linii kodu: 3
 L16: ldi     XH,$00 ;starszy bajt liczby A
      ldi     XL,$01 ;młodszy bajt liczby A
L16a: sbiw    XL,$01
      brne    L16a

;Rozmiar: 8 B, linii kodu: 4
 L88: ldi     R16,$01 ;liczba A
L88a: ldi     R17,$01 ;liczba B
L88b: dec     R17
      brne    L88b
      dec     R16
      brne    L88a

;Rozmiar: 12 B, linii kodu: 6
 L816: ldi     R16,$01 ;liczba A
L816a: ldi     XH,$00  ;starszy bajt liczby B
       ldi     XL,$01  ;młodszy bajt liczby B
L816b: sbiw    XL,$01
       brne    L816b
       dec     R16
       brne    L816a

;Rozmiar: 14 B, linii kodu: 7
 L168: ldi     XH,$00  ;starszy bajt liczby A
       ldi     XL,$01  ;młodszy bajt liczby A
L168a: ldi     R16,$01 ;liczba B
L168b: dec     R16
       brne    L168b
       sbiw    XL,$01
       brne    L168a

;Rozmiar: 14 B, linii kodu: 7
 L1616: ldi     XH,$00 ;starszy bajt liczby A
        ldi     XL,$01 ;młodszy bajt liczby A
L1616a: ldi     YH,$00 ;starszy bajt liczby B
        ldi     YL,$01 ;młodszy bajt liczby B
L1616b: sbiw    YL,$01
        brne    L1616b
        sbiw    XL,$01
        brne    L1616a

;Rozmiar: 16 B, linii kodu: 8
 Wait: ldi     R17,$19
       mul     R16,R17 ;wartość opóźnienia: $01-$FF (100us-25.5ms)
Wait0: movw    R24,R0
Wait1: sbiw    R24,$01
       brne    Wait1
       dec     R15     ;częstotliwość pracy mikrokontrolera: $01-$14 (1-20 MHz)
       brne    Wait0
       ret

;Rozmiar: 16 B, linii kodu: 8
 WaitM: ldi     R17,$19
        mul     R16,R17 ;wartość opóźnienia: $01-$FF (10ms-2.55s)
WaitM0: ldi     R18,$64
WaitM1: movw    R24,R0
WaitM2: sbiw    R24,$01
        brne    WaitM2
        dec     R18
        brne    WaitM1
        dec     R15     ;częstotliwość pracy mikrokontrolera: $01-$14 (1-20 MHz)
        brne    WaitM0
        ret

;Rozmiar: 22 B, linii kodu: 11
 LenStr: ldi     ZL,LOW(sbuf)
         ldi     ZH,HIGH(sbuf) ;adres wejścia danych
         ser     R16
LenStr0: inc     R16           ;liczba znaków (maks. 255)
         ld      R17,Z+        ;odczyt znaku z pamięci SRAM
         tst     R17
         brne    LenStr0
         ret

;Rozmiar: 16 B, linii kodu: 8
 LenStf: ldi     ZL,LOW(fbuf<<1)
         ldi     ZH,HIGH(fbuf<<1) ;adres wejścia danych
         ser     R16
LenStf0: inc     R16              ;liczba znaków (maks. 255)
         lpm     R17,Z+           ;odczyt znaku z pamięci FLASH
         tst     R17
         brne    LenStf0
         ret

;Rozmiar: 16 B, linii kodu: 8
 DelZero: ldi     ZL,LOW(sbuf)
          ldi     ZH,HIGH(sbuf) ;adres wejścia/wyjścia danych
          movw    YL,ZL
DelZero0: ld      R16,Y+
          tst     R16
          breq    DelZero3
          cpi     R16,$30
          breq    DelZero0
          sbiw    YL,$01
          cp      YL,ZL
          cpc     YH,ZH
          breq    DelZero2
DelZero1: ld      R16,Y+
          st      Z+,R16
          tst     R16
          brne    DelZero1
DelZero2: ret
DelZero3: std     Z+1,R16
          ret

;Rozmiar: 38 B, linii kodu: 19
 ClrZero: ldi     ZL,LOW(sbuf)
          ldi     ZH,HIGH(sbuf) ;adres wejścia/wyjścia danych
          ldi     R17,$20       ;znak spacji
          ld      R16,Z
ClrZero0: cpi     R16,$30
          breq    ClrZero1
          ret
ClrZero1: st      Z+,R17
          ld      R16,Z
          tst     R16
          brne    ClrZero0
          ldi     R16,$30
          st      -Z,R16
          ret

;Rozmiar: 28 B, linii kodu: 14
 FuseBit: ldi     YL,LOW(sbuf)
          ldi     YH,HIGH(sbuf) ;adres wyjścia danych
          clr     ZL
          clr     ZH
          ldi     R18,$3A
FuseBit0: lds     R16,$57       ;odczyt rejestru SPMCSR
          ori     R16,$09       ;ustawienie bitów BLBSET i SELFPRGEN
          sts     $57,R16       ;zapis rejestru SPMCSR
          lpm     R2,Z+         ;odczyt fuse/lock bitów
;W zależności od wartości adresu [ZH:ZL] są odczytywane:
; $0000 - Fuse bits Low byte (FL)
; $0001 - Lock Bits (LB)
; $0002 - Fuse bits Extended byte (FE)
; $0003 - Fuse bits High byte (FH)
          ldi     R16,$02
FuseBit1: swap    R2
          mov     R17,R2
          andi    R17,$0F
          subi    R17,$D0
          cpi     R17,$3A
          brlt    FuseBit2
          subi    R17,$F9
FuseBit2: st      Y+,R17
          dec     R16
          brne    FuseBit1
          st      Y+,R18
          cpi     ZL,$04
          brne    FuseBit0
          st      -Y,R16
          ret

;Rozmiar: 54 B, linii kodu: 25
 RegSREG: lds     R16,$5F              ;odczyt rejestru SREG
          ldi     YL,LOW(sbuf)
          ldi     YH,HIGH(sbuf)        ;adres wyjścia danych
          ldi     ZL,LOW(RegSREG2<<1)
          ldi     ZH,HIGH(RegSREG2<<1)
          ldi     R17,$08
          ldi     R18,$20
          ldi     R19,$3A
RegSREG0: lpm     R20,Z+
          st      Y+,R20
          st      Y+,R19
          ldi     R20,$30
          lsl     R16
          brcc    RegSREG1
          inc     R20
RegSREG1: st      Y+,R20
          st      Y+,R18
          dec     R17
          brne    RegSREG0
          st      -Y,R17
          ret
RegSREG2: .db     "ITHSVNZC"

;Rozmiar: 52 B, linii kodu: 22
 ScalXY: ldi     XL,LOW(fbuf<<1)
         ldi     XH,HIGH(fbuf<<1)    ;adres wejścia danych (bitmapa 8x8 = 8 bajtów)
         ldi     YL,LOW(sbuf)
         ldi     YH,HIGH(sbuf)       ;adres wyjścia danych (bitmapa 16x16 = 32 bajty)
         clr     R2
         ldi     R17,$08
ScalXY0: movw    ZL,XL
         lpm     R16,Z+              ;odczyt kolejnego bajtu bitmapy z pamięci FLASH
         movw    XL,ZL
         ldi     R18,$02
ScalXY1: mov     R19,R16
         andi    R19,$0F             ;pionowe podwajanie 4 pikseli (najpierw młodsze bity)
         swap    R16
         ldi     ZL,LOW(ScalXY2<<1)
         ldi     ZH,HIGH(ScalXY2<<1) ;adres tablicy do pionowego podwajania 4 pikseli
         add     ZL,R19
         adc     ZH,R2
         lpm     R19,Z
         st      Y+,R19         ;zapis bajtu z pionowo podwojonymi 4 pikselami (najpierw górne piksele)
         st      Y,R19          ;zapis drugiej identycznej kolumny pikseli - podwajanie poziome
         adiw    YL,$0F         ;przejście do drugiego wiersza obrazu (dolne kolumny pikseli)
         dec     R18
         brne    ScalXY1
         sbiw    YL,$1E         ;powrót do pierwszego wiersza obrazu (górne kolumny pikseli)
         dec     R17
         brne    ScalXY0
         ret
ScalXY2: .db     $00,$03,$0C,$0F,$30,$33,$3C,$3F,$C0,$C3,$CC,$CF,$F0,$F3,$FC,$FF

;Rozmiar: 70 B, linii kodu: 28

;Monochromatyczna bitmapa 8x8 pikseli, której każdy bajt to kolejna pionowa kolumna 8 pikseli obrazu
;(najmłodszy bit LSB to górny piksel kolumny). Taki format zapisu jest używany przez wyświetlacze OLED
;ze sterownikiem SSD1306.

   fbuf: .db     $00,$7C,$7E,$13,$13,$7E,$7C,$00  ;litera "A"