Am einfachsten dürfte das mit indizierten Lese und Schreibbefehlen mit Auto Inkrement gehen.
Code:
LDI XL,low (Startadresse) ;X Register mit Startadresse füttern
LDI XH,high (Startadresse)
....
LDI R16,konstante
CALL Schreibloop
.....
Schreibloop:
ST X+,R16 ; Den Wert von R16 im Speicherplatz ablegen und X um 1 erhöhen
LDI R17,low (maxAdress) ; R17 und R18 auf das Ende des Ringpuffers einstellen
LDI R18,high(maxAdress)
CP R17,XL ; Vergleichen ob das Ende des Ringpuffers erreicht ist
CPC R18,XH
BRCC ENDE ; Das Ende ist nicht erreicht -> nächster Wert
LDI XL,low (Startadresse) ; Das Ende ist erreicht -> wieder am Anfang beginnen
LDI XL,high (Startadresse)
ENDE:
Return ; Wieder in die aufrufende Routine zurück gehen.
Die Ausleseroutine kann analog z.B. mit dem Y Register erfolgen.
In die Schreibroutine müsste noch eine Überwachung, das der Schreibzeiger, den Lesezeiger nicht überholt. -> Nach dem Schreiben darf der Schreibzeiger nicht gleich dem Lesezeiger sein.
Das würde Datenverlust zur Folge haben ( Buffer Overflow )
Wenn der Lesezeiger den Schreibzeiger erreicht hat ist der Ringpuffer wieder geleert.
Du kannst natürlich auch die aktuellen Schreib- und Leseadressen in einem RAM Speicherplatz ablegen, damit die Routine zerteilen und bei Bedarf den Schreib- bzw. Lesebegfehl ausführen.
Wenn Du das X und Y Register exklusiv für die Indizierung der Adressen nutzen kannst (wie im Beispiel oben), bleibt Dir das Laden und Abspeichern der Adressen in das RAM erspart.
Ich hoffe ich hab das einigermassen Verständlich rübergebracht, wenn nicht poste mal wo es hakt.
Lesezeichen