HI!
Ich möchte eine 0815-Bytevariable aus Bascom in ein Register (R0 - R31, bzw. von R16 - R28) laden, um sie mit ASM weiterverarbeiten zu können.
Das Laden sollte möglichst schnell gehen...
Gaht das überhaupt, oder...?
Danke schonmal!
VLG Tobi
Druckbare Version
HI!
Ich möchte eine 0815-Bytevariable aus Bascom in ein Register (R0 - R31, bzw. von R16 - R28) laden, um sie mit ASM weiterverarbeiten zu können.
Das Laden sollte möglichst schnell gehen...
Gaht das überhaupt, oder...?
Danke schonmal!
VLG Tobi
Das geht folgendermaßen:
lds r24, {Variablenname}
für z.B. für eine Byte-Variable in das Register r24.
Für Word könnte man verwenden
lds r24, {WordVariable}
lds r25, {WordVariable+1}
Für Long ist folgende Variante kürzer:
loadadr VariablenName, X ' Adresse in X laden
ld r20, X+
ld r21, X+
ld r22, X+
ld r23, X+
loadadr ist eine BASCOM-Funktion, welche benötigt wird, um die von BASCOM vergebene Adresse für eine Variable in ein Pointer-Registerpaar X (r26,r27) oder Z (r30,r31) zu laden. Y (r28,r29) darf nicht verwendet werden, da hier BASCOM den Soft-Stack verwaltet.
Wieso Du in Deinem Post r16 bis r28 noch einmal erwähnst, da diese ja schon in R0 - r31 enthalten sind, ist mir nicht klar?
Hi!
Danke!
Ich wollte eigentlich R16 bis R26 sasgen, weil ja Bascom damit die Speicher anspricht.
(Da wollte ich nicht stören... :D)
Die geschweiften Klammern muss man also auch setzen... da bin ich erst drauf reingefallen... :D
Danke!
VLG Tobi
Ganz gemeine Leute nehmen auch
INP adr, val oder
OUT adr, val
z.B.
OUT &h10 , 255 ' schreibt FF ins Register 16
byteval = INP( &h10 ) ' liest das dann.
Ähnlich wie Peek & Poke
Hi!
LDS ist genau das, was ich brauche.
Wen wir schon bei ASM sind.
Ich bräuchte eine Möglichkeit, wie ich möglichst schnell die Variable in R16 oder in welchem R auch immer an verschiedene Pins verteilen.
Also z.B. R16.0 -> Portd.4 ; R16.1 -> Portc.3 usw.
Lässt sich das halbwegs bewerkstelligen?
Ich galube, dass mein Bascom-Code dazu etwas langsam ist...
Das ganze sollte nach Möglichkeit auch rückwärts funktionieren...
Danke!
VLG Tobi
@TObi: kommt auch drauf an, wie du die tabelle dazu gedacht oder gegeben hast.
Das CPU-mäßig schnellste wäre ein stück assembler-spaghetti code, der gleichzeitig das Mapping bildet
Zyklenmäßich ist das recht flott. Bei jeder Schleifenkonstruktion brauchst du ein vielfachesCode:CBI PORTD, 4 ; outpin löschen
SBRC R16, 0 ; nächsten Befehl überspringen, wenn das bit = 0
SBI PORTD, 4 ; sonst outpin setzen
..
CBI PORTC, 3
SBRC R16, 1
SBI PORTC, 3
..
CBI PORTx, n
SBRC R16, 7
SBI PORTx, n
Ich weiß auch, daß das saumäßig auschaut
Hi!
Das hat mit dem RAM-Zugriff zu tun, das wird pro Durchlauf etwa 16000 mal aufgerufen. wenn das also schnell ist, dann ist schon Zeit gespart...
Hm. Nur zum codeverständnis:
Du löschst (=0) zuerst den Pin.
dann fragst du den Status des Bits ab.
Wenn der 1 ist, dann führst du die nächste anweisung aus,
wenn nicht, dann nicht, oder wie?
Danke!
VLG Tobi
Ja, genau so.
SBI u. CBI haben jeweils 2 Cycles,
SBRC hat 1 oder 2 (ohne skip / mit skip)
d.h Je Bit (also 8 mal)
ist das R16 bit = 0, brauchst du 4 Cyklen,
ist das R16 bit = 1, brauchst du 5 Cyklen
also minimal 32 Cyklen (alles Null)
maximal 40 Cyklen (alles Eins)
bei 8 MHZ also ca 4 - 5 uS
Schneller wird's nicht gehen, denk' ich. (Vorschläge werden aber gerne angenommen)
Edit: wer nicht schreiben kann, soll's bleiben lassen :oops:
Hi!
Sehr sehr schön!
Danke!
Habe 16MHz... :D
Werd' das demnächst mal einbauen.
Hm habe gerade einen chronischen Absturz (habe ihm glaub ich ne Wordvariable zu viel verpasst...)Naja, das ist das erst mal, dass ich nen AVR zum abstürzen gebracht habe... :D )
Sothen, Danke an alle Beteiligten, ihr habt mir sehr geholfen!
VLG Tobi
Hi!
Da gibts jetzt nur ein kleines Problem...:
Das gibt dann einenCode:$asm
lds R30, {value}
......
Error 5,..., No space for BIT [valaue]
Alle Register voll, oder wie...?? (wär nicht so gut...)
VLG Tobi