View Full Version : Global variables in assembler
07-13-2009, 07:41 PM
I have an assembly routine reading the 'a' and 'b' counters in a cog. How do I set up global vars that can be set by the assembler with the count values and read by spin which will then display the two counts.
I have it working with one counter using the 'par' as the var pointer, but I can not figure out how to transfere both counts.
07-13-2009, 08:07 PM
Several ways possible:
1. Instead of two vars a and b you could have an array a
Use 2 vars which are defined one behind the other. They have to be the same type!
So you still have to pass one adress. Please be aware that using PAR for passing adresses only works in case your adress is long alligned. Due to the fact that PAR will clear the 2 LSBs. Your PASM code then accesses the first variable as before and uses PAR+4 for the next long / PAR+2 for the next word or PAR+1 for the next byte.
2. If you one day have to pass vars of different types an array of pointers would do the job. The PAR then holds the adress of that array.
3. You can use SPIN to write the adresses into your PASM code before you start it. No need to use PAR at all.
07-13-2009, 10:56 PM
This is most of the code I have been testing. Commenting out the line marked <<<<<<--------- it works ok, displaying counter 'a' value, including this line and everything goes to pot. Adding 4 to the value in PAR so that it points to the 2nd element in freq1 array - Am I doing this correct.
PUB Main | tmDelay
tmDelay := cnt
waitcnt(tmDelay += clkfreq)
entry mov ctra, ctra_ 'set mode and start counter
mov frqa, #1 'increment for each incomming pos edge
mov ctrb, ctrb_ 'same for b
mov frqb, #1
mov cnt_, cnt 'setup time delay
add cnt_, cntadd
:loop waitcnt cnt_, cntadd 'wait for next sample
mov new_a, phsa 'record 'a' and 'b' couints
mov new_b, phsb
mov temp, new_a 'make second copy
sub new_a, old_a
mov old_a, temp
wrlong new_a, par 'save new 'a' count
mov temp, new_b 'do the same for 'b'
sub new_b, old_b
mov old_b, temp
'wrlong new_b, par+4 '<<<<<<<<<<<<<<<<<<<<<<<<<<<---------------------------
ctra_ long %01010 << 26 + 7 'mode + APIN
ctrb_ long %01010 << 26 + 8 'mode + APIN
cntadd long 16_384_000 + 85 'wait 1 second, apply xtal error compensation.
cnt_ res 1
new_a res 1
new_b res 1
old_a res 1
old_b res 1
temp res 1
07-14-2009, 01:31 AM
That does not work with PASM. Let's have a look what your line of code is doing
wrlong new_a, par
par is nothing else but a replacement of a memory adress in COG-RAM ( $49? - I forgot the right adress ;o).
The wrlong instruction fetches the data inside of that RAM-adress. That's the pointer to your variable.
If you tell the compiler to do this:
wrlong new_b, par+4
you add the 4 to the memory adress of PAR ( $49x+4) - which is then a completely different special purpose register - and read it's content. That's no longer the pointer to HUB-RAM.
You have to do:
add PAR, #4
wrlong new_b, PAR
sub PAR, #4 -> for the next loop
07-14-2009, 01:52 AM
That won't work either because PAR is a read-only register. You have to move the value to some other location to add to it like:
07-14-2009, 03:56 AM
I tend to save the address of my variables going in -- makes the code easier to read; like this:
entry mov fr1hub, par
mov fr2hub, par
add fr2hub, #4
:loop ' other code
wrlong newa, fr1hub
wrlong newb, fr2hub
This is identical to Mike's suggestion except that I'm only using par at the entry of the program; both strategies work.
07-14-2009, 04:15 AM
Time will come when I learn it! Thank you Mike!
07-14-2009, 06:43 AM
Works perfectly now - thank you both.
par+4 was an error on my part, and of course·I can't alter its value with being read only. Made a copy of par, used it for 'a' then added 4 and used it·for 'b', then sub 4.
All makes sense now - again thanks.