Passing multiple variables to asm
James Long
Posts: 1,181
Ok, someone else's turn. Mike has had enough for a week or two.
Say I want to pass three variables to asm. One of those variables is a very long byte array. How is this done?
I have read the tutorials about passing one variable, but can't find anything about passing a byte array.
Also with this much data, I'm worried about getting it all mixed up.
Any help would be appreciated.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Say I want to pass three variables to asm. One of those variables is a very long byte array. How is this done?
I have read the tutorials about passing one variable, but can't find anything about passing a byte array.
Also with this much data, I'm worried about getting it all mixed up.
Any help would be appreciated.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Comments
Ziggy,
How do I know if the Variables are in successive order?
This is where I am confused.
Will they come in the order of how the cognew statement is configured?
One variable seems pretty easy, but I don't understand how a person knows how every other variable is ordered.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Longs are laid into memory in the order you define them, so if you stick with longs your PASM code can pick them up by knowing the address of the first. Let's say you have two longs and an array of longs that you want to share with PASM.
You PASM code might look something like this:
To start the Assembly section you pass pointers to the Assembly code and the param1 variable:
One the address of the first (param1) is known the others are easily calculated.
Ah, I see. What if the variables are bytes.
If I declare them all in order, they should be in memory in order as well I'm assuming. I can't remember off the top of my head if they are all bytes. I believe they are.
I don't remember reading that anywhere.
I'll give that a shot.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
long param1
word param2[noparse][[/noparse]10]
byte param2[noparse][[/noparse]10]
Effectively you can access all the above using rdbyte/wrbyte by getting par and adding #1. Just remember the ordering is not as you might expect "little endian".
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, SixBladeProp, website (Multiple propeller pcbs)
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
See the attached demo: it uses two longs and an array of bytes and demonstrates the Spin/Asm interface.
The PASM code figures out a CNT value which all the cogs will wait on and then stores that value into cogwait. As long as cogwait is part of the 498 LONGs which are copied to the COG, then the value is accessible to the COG code. Note: the 60_000 values is sufficient for this example but is not optimized.
Don't forget that PAR is designed to be an address of a LONG in HUB RAM as it is only 14 bits.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: http://forums.parallax.com/showthread.php?p=800114
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
That is, if you have:
LONG myLong1
LONG myLong2
BYTE myByte1
WORD myWord1
LONG myLong3
BYTE myByte2
WORD myWord2
.... you will have in memory:
myLong1, myLong2, myLong3, myWord1, myWord2, myByte1, myByte2...
... in that order. Kind of annoying since I don't think any of this is plainly stated in any official (or even unofficial) documentation...
... so you can't reference myByte1 by offsetting the base address of myLong1 by 8, because there are other LONGs and WORDs that are magically sandwiched in there with absolutely no hint of where they are... unless you keep track of it yourself and/or are careful when you declare the variables and know where they are. Because of this memory re-ordering magic, you can't have quasi data structures in memory that hold different data types in a particular order that is continuous in memory (unless you are tricky about it). So you'll just have to take note or care of your variable declarations!
Hope this helps and keeps you away from a day's worth of headaches!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Links to other interesting threads:
· Home of the MultiBladeProps: TriBladeProp, SixBladeProp, website (Multiple propeller pcbs)
· Single Board Computer:·3 Propeller ICs·and a·TriBladeProp board (ZiCog Z80 Emulator)
· Prop Tools under Development or Completed (Index)
· Emulators: Micros eg Altair, and Terminals eg VT100 (Index)
· Search the Propeller forums (via Google)
My cruising website is: ·www.bluemagic.biz·· MultiBladeProp is: www.bluemagic.biz/cluso.htm
*** Produces :
Otherwise pointers to the different parameter types can be used.
Note: HUB addresses can only be resolved at run time. So don't try to embed "ptr WORD @data" 'cause it won't work.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Composite NTSC sprite driver: http://forums.parallax.com/showthread.php?p=800114
Ah, Now there is an answer that is useful.
I wanted to ask about this, but didn't know how to go about asking the question.
So I can take the known address, and make a pointer to the first location. That will suffice to what I need to do.
I need to compare 2 variables (check equality) and when they are equal, I need to perform one of two possible instructions based on the third variable.
With the pointers addressed as above, this procedure will be much easier.
Thanks Mag,
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
but keep in mind, what I wrote is only necessary if you have different types of variables. If you only have one type it's enough to pass the adress of the first variable. SPIN compiler is only reordering typewise. The order of the variables within the same type is not changed.
I want criticism of the code. Please tell me any problems you guys see with this.
This code is designed for a 128 byte array.
The passing of parameters and addresses is still a uneasy task for me to perform. I'm not sure if I'll ever get to understand it.
Edit, had to add in some code on increment through the byte array.
2nd Edit. changed "test" to "andn". I think it will work this way.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Post Edited (James Long) : 4/21/2009 8:27:15 PM GMT
Hmmmm,
Well back to the drawing (programming) board.
I have changed the above listed code to andn for the testing of the variables
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Post Edited (James Long) : 4/21/2009 8:25:44 PM GMT
start( 10, @somevar ) is used in whatever SPIN program. 10 is put on the stack, the adress of somevar is put on the adress and start is executed. Now start can access the 10 by using the parameter name note and the adress of somevar by parameter name cuelist_addr.
You then pass the adress of note to a PASM program. But the PASM program needs some time to load while the COG running your start returns and cleans up the stack. Usually an interpreter would not remove the values on the stack by overwriting with zeros, but it's very likely that you call another function which also has parameters. So, at the time you access the note in PASM it's real content is not necessarily the 10.
But I think you meant:
But please be aware, you pass the adress of note1 to the PASM. Incrementing this by 1 it'll point to cuelist_addr and not to the cuelist! By the way ... cuelist_addr at least should be word size, since HUB RAM adresses have 16 bit. Then we again have the problem of reorder.
So, you could pack both values in one 32 bit variable.
So the variables in the PASM must be:
"whatever" long 0
I get it.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Mag,
I'm going to need to read that a few times. I'm not sure that makes sense.
I'll post back, when I actually decide how to ask the question I have.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Mag,
I definitely do not know what I'm doing.
I have this hang up with passing parameters in Spin, so passing them into PASM will definitely be a problem.
The top object collects all the data I'm using for a result. This is where I always have my pitfall.
I am trying to learn, but the hang ups still occur when I try to pass parameters.
For example, the last post you made would be a problem. I do not see how you would do action on the items, if the top object is constantly changing them. The timing is specific, so there would need to be a call (Pub method) to initiate the comparison.
With a Pub having parameters, does the initial command to start that Pub need to have the same? Ah, the basis for my hang up.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
I now see your point about the pointer. Because it is a pointer (or address) I can not read what I need from it, only it's value, which I do not want. Passing the addresses from a previous Spin method is something I'll just need to work out.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
I think now I understand the process.
If someone would, please critique the latest revision.
Just as a note: the other bracket is there in the code(for note_cuelist_addr), it just doesn't show on the forum.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Have fun digesting this ;o)
By the way ... what you do here looks like implementing the lookdownz in PASM. Do you expect it to be so much faster?
Post Edited (MagIO2) : 4/22/2009 7:17:10 AM GMT
You are right, it will take me some time to get all that through my head.
Your right of course. i used to being able to "call" a method when I want a result, and with a cog running all the time, the results can be rubbish.
You are right about the purpose. I was trying to make a lookdown event in pasm. I thought it was a good first project. Not sure if it would be much faster, but it is a good learning experiment.
You are definitely a patient person, because dealing with all of this is annoying, but I'll get it. You may have to beat it into my skull with the manual, but I will get it.
Ok, so the first words (notice words) of the variables addressed with be the address of the material (yet again I missed that). I must use that information to move the pointer to the respective address.
Could I do " andn list,note_val wz
if_nz jmp #wherever
I wanted the values to match perfectly, but may have used the wrong "z".
Ok, I read your list, and will try again to write this. I think this is a good exercise, even if you want to beat me after looking at it.
James L
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
cmp list, note_val WZ
if_z jmp #value_match
Ok, lesson 1 learned ;o) :
A driver does not work like a function call in SPIN. The cognew does not wait until the PASM code is done with it's job. And it even does not wait until the PASM code has been loaded into COG RAM. That's why you should never (for newbies [noparse]:o[/noparse]) pass parameter adresses to the PASM because parameters are located on the stack and that might be used otherwise meanwhile. If you need the result in your 'calling' method, you have to synchronize. For drivers you reserve some memory in HUB RAM - for example a variable, some variables, an array .. - which is then used as communication buffer. Both, the PASM and the SPIN code need to know the structure of this buffer. For example: 1 long for passing a command, 1 long for returning a value, several longs for data.
Simple communication protocol is (as already scetched in the code comments of my previous post):
1. PASM waits until command <>0
2. So, as long as SPIN does not write a command into that part of the buffer, nothing happens
3. Depending on the value in command it can do different things ( in your case you might switch between lookdown and lookdownz )
4. When PASM is done, it copys the result to the return-part of the buffer and sets the command buffer to zero again.
This prevents PASM code running again immediately and it can be used to synchronize the SPIN code ( repeat while command )
Yet again, I haven't given up.
I have yet again totally changed the structure. I know you love that.
Try this and see if it is any better:
I edited for the return value pointer, it was wrong, maybe I fixed it this time.
James
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
James L
Partner/Designer
Lil Brother SMT Assembly Services
Post Edited (James Long) : 4/22/2009 8:07:34 PM GMT