W projektach opartych o mikrokontrolery AVR, nieraz zachodzi potrzeba realizacji jakiejś funkcji logi-
cznej. Przy aplikacjach nie wymagających bramek o dużej szybkości reakcji, zamiast używać dodatko-
wych układów scalonych TTL można programowo emulować ich działanie. Poniżej znajdują się przy-
kładowe kody źródłowe asemblera, które służą do emulacji podstawowych bramek logicznych TTL.
Pierwsze linie kodu to instrukcje konfigurujące wyprowadzenia mikrokontrolera tak, aby pracowały jako
wejścia/wyjścia danej bramki. Mogą one być wykonane tylko raz, ale jak najwcześniej po włączeniu/re-
secie mikrokontrolera. Kolejne linie kodu to właściwe instrukcje emulujące zachowanie danej bramki.
Muszą one być wykonywane ciągle, dlatego należy je umieścić w głównej pętli programu lub w proce-
durze obsługi przerwania.
Oczywiście rozwiązanie takie ma pewne wady i nie w każdym projekcie da się zaimplementować. Głó-
wną wadą jest liniowe wykonywanie kodu programu, co skutkuje powstawaniem opóźnień czasowych
w obsłudze emulowanych bramek (czas reakcji na sygnały wejściowe i czas uzyskania odpowiedzi na
wyjściu bramki). W zależności od obciążenia mikrokontrolera (dużo wykonywanego kodu) oraz często-
tliwości jego taktowania (niskie zegary), opóźnienia te mogą być zbyt długie dla niektórych zastosowań.
Kolejną wadą jest zwiększanie obciążenia mikrokontrolera przez kod każdej emulowanej bramki oraz
zajmowanie kolejnych jego wyprowadzeń, których liczba jest ograniczona.
Na niepodłączonych wejściach emulowanych bramek panuje wysoki stan logiczny, wymuszony przez
włączenie wewnętrznych rezystorów podciągających (pull-up) mikrokontrolera. Bramki z wyjściem trój-
stanowym (three-state output) są aktywowane niskim stanem logicznym (negative/low enable) na wej-
ściu /OE. Aby były one aktywowane wysokim stanem logicznym (positive/high enable), należy zmienić
w kodzie linię "breq XXXXX ;skok, jeśli /OE=0" na "brne XXXXX ;skok, jeśli /OE=1".
Podana liczba linii i rozmiar dotyczy samego kodu emulującego daną bramkę (bez instrukcji konfiguru-
jących wyprowadzenia mikrokontrolera). Podana liczba cykli zegarowych potrzebna do wykonania tego
kodu, zależy od stanów logicznych na wejściach danej bramki, dlatego jest podana w zakresie od-do.
;Bufor (7407): A=PD0, Y=PD1
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$01 ;ustawienie pinu PD1 jako wyjścia z wysokim stanem
BUF1: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$01
brne BUF1a ;skok, jeśli A=1
cbi PORTD,$01 ;Y=0
rjmp BUF1b
BUF1a: sbi PORTD,$01 ;Y=1
BUF1b:
;Rozmiar: 12 B, linii kodu: 6, cykli: 6-7
;Inwerter (7404): A=PD0, Y=PD1
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$01 ;ustawienie pinu PD1 jako wyjścia z wysokim stanem
INV1: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$01
brne INV1a ;skok, jeśli A=1
sbi PORTD,$01 ;Y=1
rjmp INV1b
INV1a: cbi PORTD,$01 ;Y=0
INV1b:
;Rozmiar: 12 B, linii kodu: 6, cykli: 6-7
;Bramka AND 2-wejścia (7408): A=PD0, B=PD1, Y=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$02 ;ustawienie pinu PD2 jako wyjścia z wysokim stanem
AND2: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
cpi R16,$03
breq AND2a ;skok, jeśli A=B=1
cbi PORTD,$02 ;Y=0
rjmp AND2b
AND2a: sbi PORTD,$02 ;Y=1
AND2b:
;Rozmiar: 14 B, linii kodu: 7, cykli: 7-8
;Bramka AND 3-wejścia (7411): A=PD0, B=PD1, C=PD2, Y=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$03 ;ustawienie pinu PD3 jako wyjścia z wysokim stanem
AND3: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
cpi R16,$07
breq AND3a ;skok, jeśli A=B=C=1
cbi PORTD,$03 ;Y=0
rjmp AND3b
AND3a: sbi PORTD,$03 ;Y=1
AND3b:
;Rozmiar: 14 B, linii kodu: 7, cykli: 7-8
;Bramka NAND 2-wejścia (7400): A=PD0, B=PD1, Y=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$02 ;ustawienie pinu PD2 jako wyjścia z wysokim stanem
NAND2: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
cpi R16,$03
breq NAND2a ;skok, jeśli A=B=1
sbi PORTD,$02 ;Y=1
rjmp NAND2b
NAND2a: cbi PORTD,$02 ;Y=0
NAND2b:
;Rozmiar: 14 B, linii kodu: 7, cykli: 7-8
;Bramka NAND 3-wejścia (7410): A=PD0, B=PD1, C=PD2, Y=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$03 ;ustawienie pinu PD3 jako wyjścia z wysokim stanem
NAND3: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
cpi R16,$07
breq NAND3a ;skok, jeśli A=B=C=1
sbi PORTD,$03 ;Y=1
rjmp NAND3b
NAND3a: cbi PORTD,$03 ;Y=0
NAND3b:
;Rozmiar: 14 B, linii kodu: 7, cykli: 7-8
;Bramka OR 2-wejścia (7432): A=PD0, B=PD1, Y=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$02 ;ustawienie pinu PD2 jako wyjścia z wysokim stanem
OR2: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq OR2a ;skok, jeśli A=B=0
sbi PORTD,$02 ;Y=1
rjmp OR2b
OR2a: cbi PORTD,$02 ;Y=0
OR2b:
;Rozmiar: 12 B, linii kodu: 6, cykli: 6-7
;Bramka OR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$03 ;ustawienie pinu PD3 jako wyjścia z wysokim stanem
OR3: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq OR3a ;skok, jeśli A=B=C=0
sbi PORTD,$03 ;Y=1
rjmp OR3b
OR3a: cbi PORTD,$03 ;Y=0
OR3b:
;Rozmiar: 12 B, linii kodu: 6, cykli: 6-7
;Bramka NOR 2-wejścia (7402): A=PD0, B=PD1, Y=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$02 ;ustawienie pinu PD2 jako wyjścia z wysokim stanem
NOR2: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq NOR2a ;skok, jeśli A=B=0
cbi PORTD,$02 ;Y=0
rjmp NOR2b
NOR2a: sbi PORTD,$02 ;Y=1
NOR2b:
;Rozmiar: 12 B, linii kodu: 6, cykli: 6-7
;Bramka NOR 3-wejścia (7427): A=PD0, B=PD1, C=PD2, Y=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$03 ;ustawienie pinu PD3 jako wyjścia z wysokim stanem
NOR3: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq NOR3a ;skok, jeśli A=B=C=0
cbi PORTD,$03 ;Y=0
rjmp NOR3b
NOR3a: sbi PORTD,$03 ;Y=1
NOR3b:
;Rozmiar: 12 B, linii kodu: 6, cykli: 6-7
;Bramka XOR 2-wejścia (7486): A=PD0, B=PD1, Y=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$02 ;ustawienie pinu PD2 jako wyjścia z wysokim stanem
XOR2: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq XOR2a ;skok, jeśli A=B=0
cpi R16,$03
breq XOR2a ;skok, jeśli A=B=1
sbi PORTD,$02 ;Y=1
rjmp XOR2b
XOR2a: cbi PORTD,$02 ;Y=0
XOR2b:
;Rozmiar: 16 B, linii kodu: 8, cykli: 6-9
;Bramka XOR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$03 ;ustawienie pinu PD3 jako wyjścia z wysokim stanem
XOR3: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq XOR3a ;skok, jeśli A=B=C=0
cpi R16,$07
breq XOR3a ;skok, jeśli A=B=C=1
sbi PORTD,$03 ;Y=1
rjmp XOR3b
XOR3a: cbi PORTD,$03 ;Y=0
XOR3b:
;Rozmiar: 16 B, linii kodu: 8, cykli: 6-9
;Bramka XNOR 2-wejścia (74266): A=PD0, B=PD1, Y=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$02 ;ustawienie pinu PD2 jako wyjścia z wysokim stanem
XNOR2: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq XNOR2a ;skok, jeśli A=B=0
cpi R16,$03
breq XNOR2a ;skok, jeśli A=B=1
cbi PORTD,$02 ;Y=0
rjmp XNOR2b
XNOR2a: sbi PORTD,$02 ;Y=1
XNOR2b:
;Rozmiar: 16 B, linii kodu: 8, cykli: 6-9
;Bramka XNOR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
sbi DDRD,$03 ;ustawienie pinu PD3 jako wyjścia z wysokim stanem
XNOR3: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq XNOR3a ;skok, jeśli A=B=C=0
cpi R16,$07
breq XNOR3a ;skok, jeśli A=B=C=1
cbi PORTD,$03 ;Y=0
rjmp XNOR3b
XNOR3a: sbi PORTD,$03 ;Y=1
XNOR3b:
;Rozmiar: 16 B, linii kodu: 8, cykli: 6-9
;Bufor trójstanowy (74125): A=PD0, Y=PD1, /OE=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
BUF1T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$04
breq BUF1T0 ;skok, jeśli /OE=0
cbi DDRD,$01
cbi PORTD,$01 ;Y=Z (wysoka impedancja)
rjmp BUF1T2
BUF1T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$01
brne BUF1T1 ;skok, jeśli A=1
cbi PORTD,$01
sbi DDRD,$01 ;Y=0
rjmp BUF1T2
BUF1T1: sbi PORTD,$01
sbi DDRD,$01 ;Y=1
BUF1T2:
;Rozmiar: 28 B, linii kodu: 14, cykli: 9-13
;Inwerter trójstanowy (74240): A=PD0, Y=PD1, /OE=PD2
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
INV1T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$04
breq INV1T0 ;skok, jeśli /OE=0
cbi DDRD,$01
cbi PORTD,$01 ;Y=Z (wysoka impedancja)
rjmp INV1T2
INV1T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$01
brne INV1T1 ;skok, jeśli A=1
sbi PORTD,$01
sbi DDRD,$01 ;Y=1
rjmp INV1T2
INV1T1: cbi PORTD,$01
sbi DDRD,$01 ;Y=0
INV1T2:
;Rozmiar: 28 B, linii kodu: 14, cykli: 9-13
;Bramka trójstanowa AND 2-wejścia: A=PD0, B=PD1, Y=PD2, /OE=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
AND2T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$08
breq AND2T0 ;skok, jeśli /OE=0
cbi DDRD,$02
cbi PORTD,$02 ;Y=Z (wysoka impedancja)
rjmp AND2T2
AND2T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
cpi R16,$03
breq AND2T1 ;skok, jeśli A=B=1
cbi PORTD,$02
sbi DDRD,$02 ;Y=0
rjmp AND2T2
AND2T1: sbi PORTD,$02
sbi DDRD,$02 ;Y=1
AND2T2:
;Rozmiar: 30 B, linii kodu: 15, cykli: 9-14
;Bramka trójstanowa AND 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3, /OE=PD4
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$04 ;ustawienie pinu PD4 jako wejścia z wysokim stanem (pull-up)
AND3T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$10
breq AND3T0 ;skok, jeśli /OE=0
cbi DDRD,$03
cbi PORTD,$03 ;Y=Z (wysoka impedancja)
rjmp AND3T2
AND3T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
cpi R16,$07
breq AND3T1 ;skok, jeśli A=B=C=1
cbi PORTD,$03
sbi DDRD,$03 ;Y=0
rjmp AND3T2
AND3T1: sbi PORTD,$03
sbi DDRD,$03 ;Y=1
AND3T2:
;Rozmiar: 30 B, linii kodu: 15, cykli: 9-14
;Bramka trójstanowa NAND 2-wejścia: A=PD0, B=PD1, Y=PD2, /OE=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
NAND2T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$08
breq NAND2T0 ;skok, jeśli /OE=0
cbi DDRD,$02
cbi PORTD,$02 ;Y=Z (wysoka impedancja)
rjmp NAND2T2
NAND2T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
cpi R16,$03
breq NAND2T1 ;skok, jeśli A=B=1
sbi PORTD,$02
sbi DDRD,$02 ;Y=1
rjmp NAND2T2
NAND2T1: cbi PORTD,$02
sbi DDRD,$02 ;Y=0
NAND2T2:
;Rozmiar: 30 B, linii kodu: 15, cykli: 9-14
;Bramka trójstanowa NAND 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3, /OE=PD4
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$04 ;ustawienie pinu PD4 jako wejścia z wysokim stanem (pull-up)
NAND3T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$10
breq NAND3T0 ;skok, jeśli /OE=0
cbi DDRD,$03
cbi PORTD,$03 ;Y=Z (wysoka impedancja)
rjmp NAND3T2
NAND3T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
cpi R16,$07
breq NAND3T1 ;skok, jeśli A=B=C=1
sbi PORTD,$03
sbi DDRD,$03 ;Y=1
rjmp NAND3T2
NAND3T1: cbi PORTD,$03
sbi DDRD,$03 ;Y=0
NAND3T2:
;Rozmiar: 30 B, linii kodu: 15, cykli: 9-14
;Bramka trójstanowa OR 2-wejścia: A=PD0, B=PD1, Y=PD2, /OE=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
OR2T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$08
breq OR2T0 ;skok, jeśli /OE=0
cbi DDRD,$02
cbi PORTD,$02 ;Y=Z (wysoka impedancja)
rjmp OR2T2
OR2T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq OR2T1 ;skok, jeśli A=B=0
sbi PORTD,$02
sbi DDRD,$02 ;Y=1
rjmp OR2T2
OR2T1: cbi PORTD,$02
sbi DDRD,$02 ;Y=0
OR2T2:
;Rozmiar: 28 B, linii kodu: 14, cykli: 9-13
;Bramka trójstanowa OR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3, /OE=PD4
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$04 ;ustawienie pinu PD4 jako wejścia z wysokim stanem (pull-up)
OR3T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$10
breq OR3T0 ;skok, jeśli /OE=0
cbi DDRD,$03
cbi PORTD,$03 ;Y=Z (wysoka impedancja)
rjmp OR3T2
OR3T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq OR3T1 ;skok, jeśli A=B=C=0
sbi PORTD,$03
sbi DDRD,$03 ;Y=1
rjmp OR3T2
OR3T1: cbi PORTD,$03
sbi DDRD,$03 ;Y=0
OR3T2:
;Rozmiar: 28 B, linii kodu: 14, cykli: 9-13
;Bramka trójstanowa NOR 2-wejścia: A=PD0, B=PD1, Y=PD2, /OE=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
NOR2T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$08
breq NOR2T0 ;skok, jeśli /OE=0
cbi DDRD,$02
cbi PORTD,$02 ;Y=Z (wysoka impedancja)
rjmp NOR2T2
NOR2T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq NOR2T1 ;skok, jeśli A=B=0
cbi PORTD,$02
sbi DDRD,$02 ;Y=0
rjmp NOR2T2
NOR2T1: sbi PORTD,$02
sbi DDRD,$02 ;Y=1
NOR2T2:
;Rozmiar: 28 B, linii kodu: 14, cykli: 9-13
;Bramka trójstanowa NOR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3, /OE=PD4
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$04 ;ustawienie pinu PD4 jako wejścia z wysokim stanem (pull-up)
NOR3T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$10
breq NOR3T0 ;skok, jeśli /OE=0
cbi DDRD,$03
cbi PORTD,$03 ;Y=Z (wysoka impedancja)
rjmp NOR3T2
NOR3T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq NOR3T1 ;skok, jeśli A=B=C=0
cbi PORTD,$03
sbi DDRD,$03 ;Y=0
rjmp NOR3T2
NOR3T1: sbi PORTD,$03
sbi DDRD,$03 ;Y=1
NOR3T2:
;Rozmiar: 28 B, linii kodu: 14, cykli: 9-13
;Bramka trójstanowa XOR 2-wejścia: A=PD0, B=PD1, Y=PD2, /OE=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
XOR2T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$08
breq XOR2T0 ;skok, jeśli /OE=0
cbi DDRD,$02
cbi PORTD,$02 ;Y=Z (wysoka impedancja)
rjmp XOR2T2
XOR2T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq XOR2T1 ;skok, jeśli A=B=0
cpi R16,$03
breq XOR2T1 ;skok, jeśli A=B=1
sbi PORTD,$02
sbi DDRD,$02 ;Y=1
rjmp XOR2T2
XOR2T1: cbi PORTD,$02
sbi DDRD,$02 ;Y=0
XOR2T2:
;Rozmiar: 32 B, linii kodu: 16, cykli: 9-15
;Bramka trójstanowa XOR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3, /OE=PD4
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$04 ;ustawienie pinu PD4 jako wejścia z wysokim stanem (pull-up)
XOR3T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$10
breq XOR3T0 ;skok, jeśli /OE=0
cbi DDRD,$03
cbi PORTD,$03 ;Y=Z (wysoka impedancja)
rjmp XOR3T2
XOR3T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq XOR3T1 ;skok, jeśli A=B=C=0
cpi R16,$07
breq XOR3T1 ;skok, jeśli A=B=C=1
sbi PORTD,$03
sbi DDRD,$03 ;Y=1
rjmp XOR3T2
XOR3T1: cbi PORTD,$03
sbi DDRD,$03 ;Y=0
XOR3T2:
;Rozmiar: 32 B, linii kodu: 16, cykli: 9-15
;Bramka trójstanowa XNOR 2-wejścia: A=PD0, B=PD1, Y=PD2, /OE=PD3
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$03 ;ustawienie pinu PD3 jako wejścia z wysokim stanem (pull-up)
XNOR2T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$08
breq XNOR2T0 ;skok, jeśli /OE=0
cbi DDRD,$02
cbi PORTD,$02 ;Y=Z (wysoka impedancja)
rjmp XNOR2T2
XNOR2T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$03
breq XNOR2T1 ;skok, jeśli A=B=0
cpi R16,$03
breq XNOR2T1 ;skok, jeśli A=B=1
cbi PORTD,$02
sbi DDRD,$02 ;Y=0
rjmp XNOR2T2
XNOR2T1: sbi PORTD,$02
sbi DDRD,$02 ;Y=1
XNOR2T2:
;Rozmiar: 32 B, linii kodu: 16, cykli: 9-15
;Bramka trójstanowa XNOR 3-wejścia: A=PD0, B=PD1, C=PD2, Y=PD3, /OE=PD4
sbi PORTD,$00 ;ustawienie pinu PD0 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$01 ;ustawienie pinu PD1 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$02 ;ustawienie pinu PD2 jako wejścia z wysokim stanem (pull-up)
sbi PORTD,$04 ;ustawienie pinu PD4 jako wejścia z wysokim stanem (pull-up)
XNOR3T: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$10
breq XNOR3T0 ;skok, jeśli /OE=0
cbi DDRD,$03
cbi PORTD,$03 ;Y=Z (wysoka impedancja)
rjmp XNOR3T2
XNOR3T0: in R16,PIND ;odczyt stanu pinów PD0-PD7
andi R16,$07
breq XNOR3T1 ;skok, jeśli A=B=C=0
cpi R16,$07
breq XNOR3T1 ;skok, jeśli A=B=C=1
cbi PORTD,$03
sbi DDRD,$03 ;Y=0
rjmp XNOR3T2
XNOR3T1: sbi PORTD,$03
sbi DDRD,$03 ;Y=1
XNOR3T2:
;Rozmiar: 32 B, linii kodu: 16, cykli: 9-15