View Full Version : Global variables in assembler

07-13-2009, 06: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, 07: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, 09: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.

long freq1

PUB Main | tmDelay

cognew(@entry, @freq1)

tmDelay := cnt
waitcnt(tmDelay += clkfreq)
DispFreqs(freq1[0], freq1)


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 '<<<<<<<<<<<<<<<<<<<<<<<<<<<---------------------------
jmp #:loop

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, 12: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

Mike Green
07-14-2009, 12: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:

mov temp,PAR
add temp,#4
wrlong new_b,temp

07-14-2009, 02:56 AM
I tend to save the address of my variables going in -- makes the code easier to read; like this:


org 0

entry mov fr1hub, par
mov fr2hub, par
add fr2hub, #4

:loop ' other code

wrlong newa, fr1hub
wrlong newb, fr2hub
jmp #:loop

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, 03:15 AM
Time will come when I learn it! Thank you Mike!

07-14-2009, 05:43 AM
Works perfectly now - thank you both.

par+4 was an error on my part, and of courseI can't alter its value with being read only. Made a copy of par, used it for 'a' then added 4 and used itfor 'b', then sub 4.

All makes sense now - again thanks.