Passing params in PASM
This example shows you how to pass a start address for a set of paramaters to your new Cog as the boot parameter. You can
then read each paramater, as a long or a byte, by incrementing the supplied Address and using the rdlong and rdbyte instructions
to retrieve them from the Hub.
This is a pretty standard way to bootstrap your Cog with all the information it needs to do its job, and is also a handy way to provide arrays or single memory locations where the Cog can deposit the result of its work.
For example, you could define a LENGTH var, followed by a LED_PATTERN var and produce code in PASM which reads each byte from
LED_PATTERN in turn and flashes the LEDs. We'll probably cover something like this later, but for now here's a simple example:
CON
_CLKMODE = xtal1 + pll16x
_XINFREQ = 6_000_000
VAR
long MY_PIN_1, MY_PIN_2 ' These will appear next to each other in memory
PUB main
MY_PIN_1 := |< 0 ' Set our first pin to a bitmask for A0
MY_PIN_2 := |< 1 ' And our second for A1
cognew(@blink, @MY_PIN_1) ' Supply the address of the first parameter
DAT
org 0
blink mov addr, par ' Load our address from the boot param
rdlong Pn, addr ' Read the first pin number
add addr, #4 ' Increment addr by 1 long ( 4 bytes )
rdlong Pn2, addr ' Read the second pin number
or dira, Pn ' Set up pins as outputs
or dira, Pn2 ' It's good to do stuff while we're waiting
' for the Hub to come back around, since we
' only just synced for a rdbyte!
rdlong Delay, #0 ' Prepare the delay
mov Time, cnt ' Prep the wait time
add Time, #9 ' Add the minimum wait time
:loop waitcnt Time, Delay ' Start blinking!
xor outa, Pn
xor outa, Pn2
jmp #:loop
Pn res 1 ' Store our first LED pin
Pn2 res 1 ' Store our second LED pin
Addr res 1 ' Store our parameter address
Delay res 1 ' Store the delay increment
Time res 1 ' Store the current time for wait
fit
Breaking it down
I'm going to assume you've read My First Pasm and skim over much of the basics.
long MY_PIN_1, MY_PIN_2
In our PASM code, we're declaring two variables next to each other. These will appear adjacent to each other in HUB memory as two sets of 4 bytes, or 2 longs. These are the longs we want to copy to our COG!
MY_PIN_1 := |< 0
MY_PIN_2 := |< 1
In our main method, we're setting the values of MY_PIN_1 and MY_PIN_2 to be bit masks, by using our old friend the bitwise decode operator |<. Practically speaking, this will convert 0 to %0 and 1 to %10 etc.
We use bit masks because these can be or'd against our output registers to flip those bits to 1. Or xord to toggle them.
It's worth noting that in SPIN and PASM you use % to denote a binary number, like %10101010 and $ to denote a hexadecimal number like $AA.
mov addr, par
The very first line of our PASM ( remember that "blink" in this case is a label, and not part of the instruction ) deals with
the par register. This register always starts off containing the parameter that's passed into it via cognew.
In this case we've passed it the Hub address of MY_PIN_1, and it can use this address to locate that value in the Hub when it
wants to read it.
rdlong Pn, addr
The second line executes what's known as a HUB instruction. The instruction rdlong waits for the HUB to come around, then reads a long ( 4 bytes ) into the target location. In this instance Pn is our memory location within the COG and is where we want to copy the value of MY_PIN_1.
add addr, #4
Now that we've read one long from HUB memory, we want to advance to the next one. Addresses are byte-aligned, which means we can read one byte at a time. Since we want the next 4 bytes, and not just the last 3 of the previous long plus the first of the next long, we'll increment our addr register by 4. 4 bytes = 1 long.
rdlong Pn2, addr
Now we've got a pointer to MY_PIN_2, which is a long in memory right next to MY_PIN_1 we can use the rdlong instruction to read it into Pn2.
Hooray. We've successfully copied two setting values from HUB memory into our COG!
or dira, Pn
In this next line we're simply oring the value of Pn against dira- this sets it as an output. The bit that's set in the Pn mask will flip to 1 in the output register. For example 0000 or 0100 = 0100.
Everything else you should remember from My First Pasm, we set up a loop using waitcnt and jmp and use xor ( 1 xor 1 = 0, 0 xor 1 = 1 ) to blink the LEDs.
Search above to find more great tutorials and guides.