Lösungen in Hardware findest du oben.

Wenn es wirklich in Software sein soll, dann ist ein megaAVR schon Overkill, es sei denn, du brauchst eh einen µC.

Die Routine zur Auswertung ist super simpel und sollte so auch für BASIC-Progger verständlich sein. | ist ein oder und << sind Shifts.

Der Code ist Standard-C.

INT-Eingänge würd ich da nicht verschwenden. Es genügt, wenn du oft genug auf die Ports schaust in einer ISR, z.B. alle 1ms (hängt natürlich von der Drehgeschwindigkeit ab)

Code:
// ergibt die Drehrichtung für die beiden Quadratur-Eingänge a0 und a1
// ai =  0 --> Eingang ist nicht gesetzt
// ai != 0 --> Eingang ist gesetzt
// Return-Wert ist die Drehrichtung
// -1 Richtung x
//  1 dazu entgegengesetzt
// 0 keine Änderung
// DREH_INVALID ungültige Kombination
//
// bevor man die Rückgabewerte verwendet, sollte man die Funktion
// einmal zur Initialisierung mit gültigen Eingangswerten aufrufen,
// ohne den return-Wert zu benutzen.
//
// Die Drehrichtung ist natürlich anhängig davon,
// wie die Anschlüsse belegt sind.

#define DREH_INVALID -128

char drehgeber_step (unsigned char a0, unsigned char a1)
{
	static const char drehgeber_trainsitions[] = 
	{
		 0,                       1,           -1, DREH_INVALID,
		-1,                       0, DREH_INVALID,            1, 
		 1,            DREH_INVALID,            0,           -1, 
		 DREH_INVALID,           -1,            1,            0
	};
	
	static unsigned char a_alt;
	
	unsigned char a = a_alt;
	
	if (a0)	    a |= (1 << 2);
	if (a1)	    a |= (1 << 3);
	
	a_alt = a >> 2;
	
	return drehgeber_trainsitions[a];
}
Und hier in Assembler:
Code:
.section	.progmem.data,"a",@progbits

drehgeber_trainsitions:
	.byte	0
	.byte	1
	.byte	-1
	.byte	-128
	
	.byte	-1
	.byte	0
	.byte	-128
	.byte	1
	
	.byte	1
	.byte	-128
	.byte	0
	.byte	-1
	
	.byte	-128
	.byte	-1
	.byte	1
	.byte	0
	
.lcomm a_alt, 1
	
.text

; Eingabe: r24, r25
; Ausgabe: r24
; Verändert: r24, r30, r31

.global	drehgeber_step
drehgeber_step:
	clr r31
	lds r30, a_alt
	cpse r24, r31
	ori r30, 4
	cpse r25, r31
	ori r30, 8
	mov r24,r30
	lsr r24
	lsr r24
	sts a_alt, r24
	subi r30, lo8(-(drehgeber_trainsitions))
	sbci r31, hi8(-(drehgeber_trainsitions))
	lpm r24, Z
	ret