Dec braucht einen Taktzyklus
BRNE braucht einen Takt, wenn er nicht springt und zwei, wenn er es tut.
Die Wartezeit ist also:
(r16-1)*3 + 2 für den ersten Teil der Schleife(r16-1, weil bei r16=1 sofort nach dem dec gescipt wird. *3, weil ein DEC einen und ein BRNE mit Sprung zwei Takte dauert. +2, weil das letzte mal nicht gesprungen wird und DEC und BRNE dann jeweils einen Takt dauern)
dazu kommen dann
(r17-1)*(255*3+2)+2
255*3+2 , weil ab dem zweiten Durchlauf r16 auf 0 ist(und dann von 255 bis auf 1 'runterzählt. Dann kommen die 2 Takte für Dec auf 0 und BRNE ohne Sprung.).
+3 ,Weil das "Dec r17" und das BRNE danach 3 Takte dauern(mit Sprung). Die (r17-1) und das +2 am Ende kommen wieder daher, dass er beim letzten mal nicht springt und BRNE nur einen Takt dauert(+DEC macht dann 2).
Dann kommen noch
(r18-1)*(255*(255*3+2)+2)+2 Takte
Wenn das Ganze also 1Sekunde bei 12MHZ dauern soll, musst die Schleife 12*10^6 Takte dauern. Dabei ist zu berücksichtigen, dass der Aufruf der Schleife, wenn du sie in eine Subroutine packst, nochmal dauert.
Zum Berechnen nimmst du den größten Wert von r18, mit dem allein die Wartezeit noch zu gering ist und füllst dann auf:
(r16-1)*3+ (r17-1)*767 +(r18-1)*195587 +6
62 ist der Wert für r18
91 für r17
bei 53 für r16 ist die Schleife(ohne eventuellen Aufruf!) einen Takt zu kurz. Also schreibst du noch ein NOP dahinter(oder davor) oder "verschwendest" sonstwie noch einen Takt und die Zeit passt.
Lesezeichen