pass address to assembler routine in another module
Cncjerry
Posts: 64
I have a main routine that calls a start routine in another module. The start routine (in a separate file) then does a cognew of an assembler routine. This is from bastardized quickstart demo code.
Basically I want the main routine to call the object module with a main memory address that the assembler can read & write. Please refer to the questions in the comments below. This is example code that wont run, but it gets the idea across.
So the main routine does this:
and in the buttons object file
Basically I want the main routine to call the object module with a main memory address that the assembler can read & write. Please refer to the questions in the comments below. This is example code that wont run, but it gets the idea across.
So the main routine does this:
VAR long results PUB Start buttons.start(@results) ' so this is passing the address of results to the following object file and it works
and in the buttons object file
PUB Start(ButRes) ' is the address of butres available and is it equal to the address of the long variable results from the caller above ??? cognew(@entry,@butres) ' so when I start the assembler routine below is it sending the address of butres defined in the pub statement or the address of results from the caller? ' I suspect it is the address of butres since the mov of #$02 into butin never gets to results. DAT org 0 entry mov butin, #$02 ' set to 2 for testing wrlong butin, par ' write to butres in the object file or to results in main memory?? ' par should be pointing to the address of butres which should be the address of results as well, no??? jmp #entry butin res 1
Comments
I think your code would write 2 to "results" if you got rid of the "@" symbol in you cognew statement.
You want the contents of butres not the location of butres passed to your PASM code.
If you could watch the vaule of "butres" after the cog has been started, you'd see it change from the address of "results" to the value of 2.
For example. If you changed the start method to:
The cog might launch too fast to catch the value of butres before it's changed, but if you add a delay to the beginning of you PASM code, you should be able to catch when "butres" gets written too.
PUB start(butres)
butres:=2 ' then you would think that the address would now be set to 2, but I am pretty sure butres as a long will be 2, no?
cognew(@entry,butres) ' would be inconsistent then
I am going to try moving all these assembler routines back to the main module. It will work then since I wont have to call a start routine in another module.
It does seem like it should work as suggested since the @results should be the address of the variable results put into butres which then cognew(@entry, ButRes) should send to the assembled routine. But the fact that you can assign a value directly to butres in the start routine means that it is being treated as a resolved litteral from the passed address.
There should be a technique to move addresses between spin modules but it eludes me.
Thinking about it again, though, I could reserve an upper block of memory with constants that point to the address of the variable in that block. Then by using the constant in the rdlong and wrlong each asm routine would get the variable. I am going to play with this idea. I just need to figure out the way spin does indirect addressing. I think I would also need the address aligned on a long block line.
This is done all the time.
Would you post your code where "2" isn't written back to "results"?
How do you know it's not being written there?
When I was trying to get my head around the way addresses were passed, I'd add a bunch of debug statements that printed both the location of a variable and its contents.
There are several past threads about this issue. I think there's demo code that illustrates address passing in those threads. I'll see if I can find them and add a link here.
Edit: I didn't find a thread specifically about passing address to a different object (not that it matters which object an address is passed to, it's still an address in hub RAM). I did find this thread about sharing variables between two PASM cogs.
What I have been able to do was create an address as below and move data in and out in spin:
So this code works.
I then did somewhat of the same in assembler:
So all this works and I skip all the address transfers. I am going to just allocate a block for data up in higher memory and work from there using constants for the addresses.
I can't figure out how to pass addresses to modules using a spin routine with parameters though I am sure it is possible. If I send a spin routine an address, it looks like the data from the address is loaded into a compiled long variable opposed to the address. I could be wrong but since the parameter variables are not declared in a DAT section, the spin interpreter might treat all parameter declared variables as addresses anyway and do the address to value translation. Can't confirm it without more work, but I played around with it and couldn't get it to work. I was using some code to just write the values to my LCD and was never able to get the modified variable from the assembler routine. Using constants to point to memory addresses will work and I can keep my code in modules and not worry about passing addresses around.
Making a data block in high memory is more to my liking anyway since I will have a number of variables that each of the ASM routines access.
Jerry
It would help if you posted the complete program so we could point out what you're doing wrong. I think you're making this harder than it needs to be.
I agree that it should work but for some reason, the address wasn't getting thru. Clearly I am new to the prop chip and asm.
I don't know, but I think my final solution of just using constants to hold the offsets in hub memory is pretty simple. I then can put each cog asm routine in its own module, start them with a small spin in the same module and read/write all day long without passing any parameters.
Jerry
Correct. That's the idea here.
One last ( read next ) question: is it possible to modify cog memory directly from another cog? Is there a faster way to move data between cogs?
Even after all this works, I think I am still architecting this code with the allocated high memory addresses. This method seems to fit more with my asm background.
Also you don't need to. You can always get the address of any data area you define in Spin or PASM and pass it around as required.