Ein paar einfache Assembler Routinen für die AVRs, die man immermalwieder gebrauchen kann. Geht sicherlich auch noch ein Stück kürzer, den einen oder anderen Takt könnte man auch noch sparen, aber es tut was es soll. Die aufgeführten Register sollten vor dem Anspringen der Routinen mit den Ausgangsdaten gefüttert werden, dann einfach mit CALL/ICALL/RCALL (jenachdem, was der verwendete AVR kann und grade sinnvoll erscheint)aufrufen.

Speicherbereich überschreiben (mit was steht im rgtmpbyte):
FFMem:
   ; Speicherbereich FF'en, 8 bit Zaehler
   ; rgi haelt den Zaehler, also wieviele bytes loeschen
   ; rgtmpbyte haelt das FF (oder was auch immer)
   ; X haelt die Startadresse im RAM
   
   LDI rgtmpbyte, 0xFF     ; tmpbyte = 0xff
   slffmem:
      ST X+, rgtmpbyte		; tmpbyte in Speicher kopiern
      SUBI rgi, 1 		; rgi--
      BRNE slffmem		; solange rgi>0 weiter in der Schleife
   RET

Einen Bereich vom RAM an eine andere Stelle des RAM kopieren:
CPMem2Mem:
   ; kopiert Speicherbereich in einen anderen, 8 bit Zaehler
   ; rgi haelt Zaehler, alse wiviele bytes kopieren
   ; rgtmpbyte byte zum Zwischenspeichern
   ; X haelt Adresse des 1. byte im RAM (Ziel)
   ; Y haelt Adresse des 1. byte im RAM (Quelle), Y->X

   sl028:
      LD rgtmpbyte, Y+		; 1 byte ausm Speicher lesen
      ST X+, rgtmpbyte		; -> in den Speicehr schreiben
      SUBI rgi, 1		; rgi--
      BRNE sl028;		; solange rgi>0 weiter in der Schleife
   RET

Einen Bereich aus dem Flash ins RAM kopieren:
CPFlash2Mem:
   ; kopiert Bereich ausm Flash ins RAM, 8 bit Zaehler
   ; rgi haelt Zaehler, alse wiviele bytes kopieren
   ; R0 byte zum Zwischenspeichern (LPM liest nur ins R0)
   ; X haelt Adresse des 1. byte im RAM (Ziel)
   ; Z haelt Adresse des 1. byte im Flash (Quelle), Z->X

   slcpflash2mem:
      LPM			; byte aus Progammspeicher lesen, landet im R0
      ST X+, R0			; byte aus flash ins RAM schreiben
      ADIW ZH:ZL, 1		; Addresspointer fuer Programmspeicher ++
      SUBI rgi, 1		; rgi--
      BRNE slcpflash2mem	; solange rgi>0 weiter in der Schleife
   RET

Einen Bereich aus dem internen EEProm ins RAM kopieren:
CPEe2Mem:
   ; kopiert Bereich ausm EEProm ins RAM, 8 bit Zaehler
   ; rgi haelt Zaehler, alse wiviele bytes kopieren
   ; X haelt Adresse des 1. byte im RAM (Ziel)
   ; Z haelt Adresse des 1. byte im EEProm (Quelle), Z->X

   ; eeprom startadresse setzen
   OUT EEARH,ZH		   ; high byte adresse eeprom schreiben
   OUT EEARL,ZL		   ; low byte adresse eeprom schreiben
   slcpee2mem:
      SBI EECR, EERE		; Lesevorgang triggern
      IN rgtmpbyte, EEDR	; byte aus eeprom ins tmpbyte schieben
      ST X+, rgtmpbyte		; byte aus tmpbyte ins RAM schreiben
      ADIW ZH:ZL, 1		; Addresspointer fuer EEProm++
      OUT EEARH,ZH		; -> high byte neue adresse eeprom schreiben
      OUT EEARL,ZL		; -> low byte neue adresse eeprom schreiben
      SUBI rgi, 1		; rgi--
      BRNE slcpee2mem		; solange rgi>0 weiter in der Schleife
   RET

Einen Bereich aus dem RAM ins interne EProm kopieren:
CPMem2Ee:
   ; kopiert Bereich ausm RAM ins EEProm, 8 bit Zaehler
   ; rgi haelt Zaehler, alse wiviele bytes kopieren
   ; Y haelt Adresse des 1. byte im RAM (Quelle)
   ; Z haelt Adresse des 1. byte im EEProm (Ziel), Y->Z

   ; eeprom startadresse setzen
   OUT EEARH,ZH		   ; high byte adresse eeprom schreiben
   OUT EEARL,ZL		   ; low byte adresse eeprom schreiben
   slcpmem2ee:
      LD rgtmpbyte,Y+		; byte ausm Speicehr ins rgtmpbyte lesen
      sleeready:		    ; eeprom fertig zum Schreiben?
         SBIC EECR,1 		    ; if bit1 clear -> den jump ueberspringen
         RJMP sleeready		    ; -> zuruck
      OUT EEDR,rgtmpbyte	; zu schreibendes byte ins datenregister tun
      SBI EECR,EEMWE		; Schaltet EEPROM Master Write Enable ein
      SBI EECR,EEWE		; Löst Schreibvorgang im EEPROM aus
      sleeready2:		    ; auf eeprom mit schreiben fertig warten
         SBIC EECR,1 		    ; if bit1 clear -> den jump ueberspringen
         RJMP sleeready2	    ; -> zuruck
      ADIW ZH:ZL, 1		; Addresspointer fuer EEProm++
      OUT EEARH,ZH		; -> high byte adresse eeprom schreiben
      OUT EEARL,ZL		; -> low byte adresse eeprom schreiben
      SUBI rgi, 1		; schleife, i--rgi--
      BRNE slcpmem2ee		; solange rgi>0 weiter in der Schleife
   RET