Bin gerade weiter dabei einige Fehler zu killen, welche aufgrund des unterschiedlichen Befehlssatzes AVR5(1) und AVR25 zustande kommen.
Der längere Weg ist dieser...
Code: Alles auswählen
{$if defined (ATMega328p)}
procedure TNeoPixel.show; assembler; nostackframe;
label wait, NextBit, NextByte, nop1, nop2, nop3;
asm
   push r29      // verwendete Register sichern
   push r28      // Y = r28/r29 fnumBytes
   push r27      // X = r26/r27 zeigt auf Pixels
   push r26      //
   push r18      // hi PinMask
   push r19      // lo PinMask
   push r20      // Bit Zähler
   push r21      // aktuell ausgegebenes Byte
   push r22      // next
   push r30      // Z = r30/r31 zeigt (vorerst) auf self
   push r31      // wird nach dem initialisieren gesichert und dann auf die Portadresse umgestellt
   push r24      // Das Ergebnis von canShow wird in r24 zurückgegeben
   push r25      // canShow verändert r24 und r25, benötigt aber den Zeiger auf self darin
wait:
   pop  r25
   pop  r24
   push r24
   push r25
   call canShow
   tst  r24
   breq wait
   pop  r25
   pop  r24
   movw  r30,r24                  // self in Z register laden
   ldd  r28,Z+TNeoPixel.fnumBytes   // fnumBytes in r28/r29 = Y Register laden
   ldd  r29,Z+TNeoPixel.fNumBytes+1
   ldd  r26,Z+TNeoPixel.fPixels  // Zeiger auf fPixels in X Register laden
   ldd  r27,Z+TNeoPixel.fPixels+1
   ldd  r22,Z+TNeoPixel.fPinMask
   ldd  r24,Z+TNeoPixel.fPin     // Arduino Pin
   ldd  r25,Z+TNeoPixel.fPin+1
   push r30                      // Z Register sichern. Wird von digitalReadPort überschrieben
   push r31
   call digitalReadPort          // Den aktuellen Zustand des Ports auslesen (wird in r24 zurückgeliefert)
   pop  r31
   pop  r30
   ldd  r18,Z+TNeoPixel.fPort    // Portadresse zwischenspeichern
   ldd  r19,Z+TNeoPixel.fPort+1
   push r30                      // Da wir nach dem senden der Sequenz 300us warten müssen,
   push r31                      // speichern wir den Inhalt des Z Registers auf dem Stack zwischen
   movw r30,r18                  // Portadresse in das Z Register laden.
                                 // ab hier kann nicht mehr auf self zugegriffen werden
   mov  r18,r24                  // Aktuellen Portzustand in r18 schreiben
   mov  r19,r18                  // und diesen auch nach lo schreiben
   or   r18,r22                  // Pin Bit setzen (hi)
   com  r22                      // Alle Bits ausser unserem setzen
   and  r19,r22                  // Pin Bit löschen, alles andere so lassen wie es ist
   com  r22                      // unser Bit wieder setzen, alles andere löschen
   ldi  r20,8                    // Bit Zähler
   ld   r21,X+                   // erstes Byte laden und X Register erhöhen
   mov  r22,r19                  // next := lo
   cli             // Interrupts sperren
NextBit:
   st   Z,r18      // PORT := hi                             (T =  0)
   sbrc r21,7      // if (Byte and 128) then                 (T =  2)
   mov  r22,r18    //   next := hi                           (T =  4)
   dec  r20        // Bit := Bit - 1                         (T =  5)
   st   Z,r22      // Port := next                           (T =  7)
   mov  r22,r19    // next := lo                             (T =  8)
   breq NextByte   // if Bit = 0 then NextByte               (from dec above)
   rol  r21        // Rotate Left on Byte                    (T = 10)
   rjmp nop1       // 3 Takte Pause                          (T = 11)
nop1:
   nop             //                                        (T = 13)
   st   Z,r19      // Port := lo                             (T = 15)
   rjmp nop2       // 3 Takte Pause machen
nop2:
   nop             //
   rjmp NextBit    // Nächstes Bit ausgeben
NextByte:
   ldi  r20,8      // Bit := 8
   ld   r21,X+     // Nächstes Byte von fPixels laden
   st   Z,r19      // Port := lo
   rjmp nop3       // 1 Takt warten
nop3:
   sbiw r28,1      // Bytezähler decrementieren
   brne NextBit    // Nicht Null? nächstes Byte ausgeben
   pop  r31        // die Adresse von self wieder zurück
   pop  r30        // holen
   sei             // Interrupts wieder zulassen
   call micros     // Aktuellen Microsekundenzählerstand in fEndTime speichern
   std  Z+TNeoPixel.fEndTime,r22
   std  Z+TNeoPixel.fEndTime+1,r23
   std  Z+TNeoPixel.fEndTime+2,r24
   std  Z+TNeoPixel.fEndTime+3,r25
   pop  r31        // gesicherte Register wieder herstellen.
   pop  r30
   pop  r22
   pop  r21
   pop  r20
   pop  r19
   pop  r18
   pop  r26
   pop  r27
   pop  r28
   pop  r29
end;
{$endif}
{$if defined (ATtiny45) of defined (ATtiny85)}
procedure TNeoPixel.show; assembler; nostackframe;
label wait, NextBit, NextByte, nop1, nop2, nop3;
asm
   push r29      // verwendete Register sichern
   push r28      // Y = r28/r29 fnumBytes
   push r27      // X = r26/r27 zeigt auf Pixels
   push r26      //
   push r18      // hi PinMask
   push r19      // lo PinMask
   push r20      // Bit Zähler
   push r21      // aktuell ausgegebenes Byte
   push r22      // next
   push r30      // Z = r30/r31 zeigt (vorerst) auf self
   push r31      // wird nach dem initialisieren gesichert und dann auf die Portadresse umgestellt
   push r24      // Das Ergebnis von canShow wird in r24 zurückgegeben
   push r25      // canShow verändert r24 und r25, benötigt aber den Zeiger auf self darin
wait:
   pop  r25
   pop  r24
   push r24
   push r25
   rcall canShow
   tst  r24
   breq wait
   pop  r25
   pop  r24
   movw  r30,r24                  // self in Z register laden
   ldd  r28,Z+TNeoPixel.fnumBytes   // fnumBytes in r28/r29 = Y Register laden
   ldd  r29,Z+TNeoPixel.fNumBytes+1
   ldd  r26,Z+TNeoPixel.fPixels  // Zeiger auf fPixels in X Register laden
   ldd  r27,Z+TNeoPixel.fPixels+1
   ldd  r22,Z+TNeoPixel.fPinMask
   ldd  r24,Z+TNeoPixel.fPin     // Arduino Pin
   ldd  r25,Z+TNeoPixel.fPin+1
   push r30                      // Z Register sichern. Wird von digitalReadPort überschrieben
   push r31
   rcall digitalReadPort          // Den aktuellen Zustand des Ports auslesen (wird in r24 zurückgeliefert)
   pop  r31
   pop  r30
   ldd  r18,Z+TNeoPixel.fPort    // Portadresse zwischenspeichern
   ldd  r19,Z+TNeoPixel.fPort+1
   push r30                      // Da wir nach dem senden der Sequenz 300us warten müssen,
   push r31                      // speichern wir den Inhalt des Z Registers auf dem Stack zwischen
   movw r30,r18                  // Portadresse in das Z Register laden.
                                 // ab hier kann nicht mehr auf self zugegriffen werden
   mov  r18,r24                  // Aktuellen Portzustand in r18 schreiben
   mov  r19,r18                  // und diesen auch nach lo schreiben
   or   r18,r22                  // Pin Bit setzen (hi)
   com  r22                      // Alle Bits ausser unserem setzen
   and  r19,r22                  // Pin Bit löschen, alles andere so lassen wie es ist
   com  r22                      // unser Bit wieder setzen, alles andere löschen
   ldi  r20,8                    // Bit Zähler
   ld   r21,X+                   // erstes Byte laden und X Register erhöhen
   mov  r22,r19                  // next := lo
   cli             // Interrupts sperren
NextBit:
   st   Z,r18      // PORT := hi                             (T =  0)
   sbrc r21,7      // if (Byte and 128) then                 (T =  2)
   mov  r22,r18    //   next := hi                           (T =  4)
   dec  r20        // Bit := Bit - 1                         (T =  5)
   st   Z,r22      // Port := next                           (T =  7)
   mov  r22,r19    // next := lo                             (T =  8)
   breq NextByte   // if Bit = 0 then NextByte               (from dec above)
   rol  r21        // Rotate Left on Byte                    (T = 10)
   rjmp nop1       // 3 Takte Pause                          (T = 11)
nop1:
   nop             //                                        (T = 13)
   st   Z,r19      // Port := lo                             (T = 15)
   rjmp nop2       // 3 Takte Pause machen
nop2:
   nop             //
   rjmp NextBit    // Nächstes Bit ausgeben
NextByte:
   ldi  r20,8      // Bit := 8
   ld   r21,X+     // Nächstes Byte von fPixels laden
   st   Z,r19      // Port := lo
   rjmp nop3       // 1 Takt warten
nop3:
   sbiw r28,1      // Bytezähler decrementieren
   brne NextBit    // Nicht Null? nächstes Byte ausgeben
   pop  r31        // die Adresse von self wieder zurück
   pop  r30        // holen
   sei             // Interrupts wieder zulassen
   rcall micros     // Aktuellen Microsekundenzählerstand in fEndTime speichern
   std  Z+TNeoPixel.fEndTime,r22
   std  Z+TNeoPixel.fEndTime+1,r23
   std  Z+TNeoPixel.fEndTime+2,r24
   std  Z+TNeoPixel.fEndTime+3,r25
   pop  r31        // gesicherte Register wieder herstellen.
   pop  r30
   pop  r22
   pop  r21
   pop  r20
   pop  r19
   pop  r18
   pop  r26
   pop  r27
   pop  r28
   pop  r29
end;
{$endif}
Ausschlag gebend für diesen Umständlichen Weg ist leider der Aspekt 
und da scheue ich mich auch nicht dies zuzugeben das ich nicht weiß, wie ich den Compilerschalter (MCU-Auswahl) in ASM hinbekomme.
mir persönlich wäre auch unter ASM folgender Weg angenehm.
Code: Alles auswählen
{$if defined (ATMega328p)}
   call canShow
{$endif}
{$if defined (ATtiny45) of defined (ATtiny85)}
  rcall canshow
{$endif}
Lediglich nachstehden Meldungen muß ich noch anfassen.
ATTiny85
/usr/bin/avr-ld: region `data' overflowed by 762 bytes
ATTiny45
/usr/bin/avr-ld: region `text' overflowed by 2540 bytes
/usr/bin/avr-ld: region `data' overflowed by 1018 bytes
Wenn dies vom Tisch ist, einmal Toasten und Testlauf, Änderungen Dokumentieren, bevor ich es in's git werfe.