I think I have confirmed this "bug" (or feature) by moving the code from hubexec to the cog. In the cog, it works with or without the backslash.
But, in hubexec, the backslash is required.
Note: This is for Spin+ASM. It was all working in pure ASM...
Eric,
I have written an Asm object that will run in its own cog. It’s an SD Driver and communicates via a hub mailbox.
To test it I have another asm file. It starts the above file with coginit. There is no spin in either - they are straight P2 assembly.
I have two problems.
First I cannot include the second file as an object...
OBJ
sd: “file2.spin2”
Second, I cannot reference the entry address in this object.
I had to place this file at the end after an
ORGH $2000
so I could use a fixed address to start it with
COGINIT #%01_0000,
and include the following in the calling file...
xyz long $2000
This was the only way I could get the coginit address.
And, the compiler did not include the file in the binary output.
I have had to resort to making one big file.
The P1 spin conversion to P2 asm is a separate issue. I am trying to convert Kyes spin P1 SD FAT driver to P2 asm. My asm Driver above will replace the asm section of Kyes driver.
Eric,
I have written an Asm object that will run in its own cog. It’s an SD Driver and communicates via a hub mailbox.
To test it I have another asm file. It starts the above file with coginit. There is no spin in either - they are straight P2 assembly.
First I cannot include the second file as an object...
OBJ
sd: “file2.spin2”
Ah, I think I see where you're coming from. But OBJ is a Spin language feature, not PASM, so it's not going to work with pure PASM code. This isn't just a fastspin restriction, it's the same in original Spin too.
Second, I cannot reference the entry address in this object.
Probably you'll want to use #include to include the source file, something like:
file2_start
#include "file2.spin2"
Now the label @file2_start will refer to the start of the file2.spin2 code.
The P1 spin conversion to P2 asm is a separate issue. I am trying to convert Kyes spin P1 SD FAT driver to P2 asm. My asm Driver above will replace the asm section of Kyes driver.
You can keep the Spin code as Spin, and just replace the assembly code. In fact you could even keep the assembly code and #ifdef it so that it can be compiled for P1 or for P2.
I think I have confirmed this "bug" (or feature) by moving the code from hubexec to the cog. In the cog, it works with or without the backslash.
But, in hubexec, the backslash is required.
Note: This is for Spin+ASM. It was all working in pure ASM...
In the next release of fastspin the loc should work without slash. I've just given up and in mixed Spin + PASM all constant references in LOC will be absolute. References to labels will still be relative, and references in pure PASM will still be relative, it'll only be in mixed code that the rules will be a little different. This should be transparent to the programmer.
Thanks. I’m just being greedy here and using loc to save an instruction...
I suppose you could also make loc to a constant illegal...
A constant for loc is perfectly legal, as long as the constant fits in 20 bits. There is a case to be made that you should always use "\" with a constant, because otherwise the code will be position dependent, but for programs that don't move code around it shouldn't matter. In some sense Spin objects are always potentially moved, so loc in Spin objects should use "\" for constants. As I mentioned, that will happen automatically in the final version of fastspin 3.9.32 (so if you leave the "\" off it'll still be absolute with a constant, just as it would when referring to HUB variables from COG and vice-versa).
Thanks for your help Eric.
I’ll try include. This should be easier than OBJ anyways.
BTW we did use objects with PASM, just that they were always wrapped with spin. And we didn’t have include in proptool although we did in best and homespun.
Thanks for your help Eric.
I’ll try include. This should be easier than OBJ anyways.
BTW we did use objects with PASM, just that they were always wrapped with spin. And we didn’t have include in proptool although we did in best and homespun.
I don't think it's ever been possible to refer to an object from PASM though. Having PASM inside of objects is fine (and will work in fastspin) but to actually use the objects you need to write some Spin code. Or am I missing something?
I've posted new versions of fastspin and the GUI for it. That gui is now called "FlexGUI" instead of "spin2gui" to better reflect the multi-language nature of it.
The current versions of both are 3.9.32, and they are available at:
The "flexgui.zip" file contains everything you'll need for development on Windows, including fastspin.
This new release supports the new silicon via a "-2b" flag. The old silicon is still available as "-2a". Just plain "-2" selects the most common P2 variant, which is still "2a" but eventually will become "2b". FlexGUI has a button to switch between these.
Other changes are some more editor configuration options in FlexGUI, better handling of loc and jmps in PASM within Spin objects, and some C library fixes.
Thanks for your help Eric.
I’ll try include. This should be easier than OBJ anyways.
BTW we did use objects with PASM, just that they were always wrapped with spin. And we didn’t have include in proptool although we did in best and homespun.
I don't think it's ever been possible to refer to an object from PASM though. Having PASM inside of objects is fine (and will work in fastspin) but to actually use the objects you need to write some Spin code. Or am I missing something?
Yes, you're missing something here
The pasm in my case is a complete object that gets loaded into another cog. The interface is via a 4 long mailbox, used as a command + parameters and a status reply in response. So there is no interaction between objects except via the mailbox. When the COGINIT is launched, it is preceeded by a SETQ mailbox that passes the address of the mailbox into PTRA of the started cog. Works easy, save for the include
DAT
org 0
.....
SETQ ptrmailbox ' set to pass addr of hub mailbox
COGINIT #%01_0000, sd_run ' start the SD Driver Cog
.....
sd_run long @sd_entry ' hub start address to load/run the SD Driver code
DAT
orgh
org 0
#include "SD202a.spin"
This is currently how I am getting the start entry point hub address and starting the cog passing the hub address of the mailbox into PTRA of the called cog.
Thanks for your help Eric.
I’ll try include. This should be easier than OBJ anyways.
BTW we did use objects with PASM, just that they were always wrapped with spin. And we didn’t have include in proptool although we did in best and homespun.
I don't think it's ever been possible to refer to an object from PASM though. Having PASM inside of objects is fine (and will work in fastspin) but to actually use the objects you need to write some Spin code. Or am I missing something?
Yes, you're missing something here
The pasm in my case is a complete object that gets loaded into another cog. The interface is via a 4 long mailbox, used as a command + parameters and a status reply in response. So there is no interaction between objects except via the mailbox.
Ah, I see. Yes, that's a good way to use objects from PASM. You'll still need some Spin to set the objects up though. Is there some way in regular Spin for PASM code to get the address of an object? As far as I can see it would have to be passed to the PASM code from some Spin initialization code.
Sorry, something is really wrong with this new fastspin…
My old pure ASM version of this code doesn't work with it either...
The attached was working perfectly in pure ASM with the two Spin lines commented out.
With the Spin in, it almost worked, except for something just a bit wrong with the very top graphics line...
Graphics are all messed up. I think it might be getting the offset to the palette wrong...
Looks like it might be an issue with the palette anyway...
Serial output looks right, so the code is running...
Eric,
I have found a problem. Attached is the source together with listings for fastspin 3.9.31 & 3.9.32
The listing so not match due to incorrect relative jmp forward compilation.
3.9.31 is definately wrong.
The jmp #@_fail at $19C 067 is an example. Currently not sure about 3.9.32 yet.
Spent days trying to get this working with weird results. Now I know why
Anyone have the link to the definitive use of @ and \ ?
There is no definitive answer in Chips reference for cog to cog in cog for the #@. Without @ it will use relative and with #\ it will use absolute.
Sorry, something is really wrong with this new fastspin…
My old pure ASM version of this code doesn't work with it either...
Yes, there's a bug in the encoding of the rdlut and wrlut instructions . It'll actually work correctly if you tell it to compile for the rev 2b silicon (give it the "-2b" flag instead of "-2" or "-2a"). I changed rdlut and wrlut to handle the new PTRA++ addressing modes for the new silicon, but in the process managed to break encoding of the original silicon (it's just a silly typo in the source code, but it's enough to get a bit wrong in the output).
Code compiled for "-2b" will actually work fine on your original 2a silicon as long as you're not using any of the new features.
Eric,
I have found a problem. Attached is the source together with listings for fastspin 3.9.31 & 3.9.32
The listing so not match due to incorrect relative jmp forward compilation.
3.9.31 is definately wrong.
The jmp #@_fail at $19C 067 is an example. Currently not sure about 3.9.32 yet.
Spent days trying to get this working with weird results. Now I know why
I think this is a bug in your code... the label _fail is located at hub address $238, so I don't think you can run code from there in hubexec mode. Which by definition a "jmp #@_fail" is doing ("@" says to always use the HUB address).
Anyone have the link to the definitive use of @ and \ ?
There is no definitive answer in Chips reference for cog to cog in cog for the #@. Without @ it will use relative and with #\ it will use absolute.
By definition anything involving @ is a HUB access, not cog to cog.
"@" says to use the HUB address of the following label
"\" says to use absolute rather than relative addressing
Eric,
I have found a problem. Attached is the source together with listings for fastspin 3.9.31 & 3.9.32
The listing so not match due to incorrect relative jmp forward compilation.
3.9.31 is definately wrong.
The jmp #@_fail at $19C 067 is an example. Currently not sure about 3.9.32 yet.
Spent days trying to get this working with weird results. Now I know why
I think this is a bug in your code... the label _fail is located at hub address $238, so I don't think you can run code from there in hubexec mode. Which by definition a "jmp #@_fail" is doing ("@" says to always use the HUB address).
Anyone have the link to the definitive use of @ and \ ?
There is no definitive answer in Chips reference for cog to cog in cog for the #@. Without @ it will use relative and with #\ it will use absolute.
By definition anything involving @ is a HUB access, not cog to cog.
"@" says to use the HUB address of the following label
"\" says to use absolute rather than relative addressing
Chips latest reference definitely says @ is usable in cog to cog jumps. Page 21. I don’t have it to hand.
I did remove all the @ and the code still doesn’t get past go so I still think there’s a problem but it’s too late for me to test and likely no time for a few days
I was trying to debug two cogs communicating via hub, and they were each variously going off the rails. In the end I counted the nesting levels thinking there was a stack issue. I ended up separating them and trying to debug one of them when I struck the problem. The JMP #@_fail just before the .command8 label has a relative offset of IIRC 470 where the actual offset would have only been around 200 if the compiler was treating both as hub so I think something is still amiss.
We desperately need to sort this addressing mess out. The source should be able to be compiled for either cog or hub by a simple org statement. It would be nicer if the same compiled code could run in either but I’m not sure how relative works between the two modes. Is the relative bytes or longs.
Please don’t take this the wrong way Eric. You’re done a fantastic job!!!
Chips latest reference definitely says @ is usable in cog to cog jumps. Page 21. I don’t have it to hand.
I think there's some misunderstanding there. @ means "use the hub value of the label". Now, theoretically, if you compile some code in orgh that's using @ and relative jumps, and then load it into COG, then the jumps should still work, so in that sense it "works" for cog to cog jumps. But @ definitely means "this is a hub address", so using it when you're intending that the code run in a COG is something that needs a really hard look.
"\" on the other hand means "use absolute addressing no matter what". Without it the assembler will try to use relative addressing if it can (for jumps that stay inside the same space -- COG, LUT, or HUB).
We desperately need to sort this addressing mess out. The source should be able to be compiled for either cog or hub by a simple org statement. It would be nicer if the same compiled code could run in either but I’m not sure how relative works between the two modes. Is the relative bytes or longs.
The rules for addressing are a little complicated, but I think they're clear:
(1) Labels have two values, a hub address (where the code is physically loaded by the loader into HUB memory at boot time) and a default address. The default address may be the same as the hub address (for code after orgh) or may be different (for code after org).
(2) Putting "@" in front of a label says to use its hub address. Otherwise its default address (the one established by org, if any) is used.
(3) If you put a "\" after the immediate symbol in a jmp or loc instruction, you're requesting that absolute addressing be used. This overrides any other consideration for relative vs. absolute addressing.
(4) If there is no "\", then the choice of relative vs absolute addressing is:
- if both addresses are in COG (between $0 and $1ff inclusive), use relative
- if both addresses are in LUT (between $200 and $3ff inclusive) use relative
- if both addresses are in HUB (above $400) use relative
- otherwise use absolute (as if "\" had been specified)
The only ambiguity I can think of is for the case where you try to jump to a HUB address below $400, for example by specifying @ on such a label or if it comes after an orgh without an org. In that case the various assemblers may differ in what they do -- some may treat it as a COG/LUT address, some may notice that it's really HUB and try to use that, etc. The hardware will always treat absolute jumps to below $400 as being into COG or LUT memory. So it's probably a very bad idea to try to hubexec code below $400. Maybe, possibly, a relative jump could be made to hub code in that space (@cgracey, please correct me if I'm wrong). But there are so many potential problems that I would *strongly* recommend not doing this. For example, if code that's in HUB below $400 does a subroutine call, any RET will end up jumping into COG/LUT rather than back to HUB.
Eric isn't saying it would work under any circumstance, just that an attempt to code it in source would likely produce differing machine code from the different assemblers.
Comments
But, in hubexec, the backslash is required.
Note: This is for Spin+ASM. It was all working in pure ASM...
I have written an Asm object that will run in its own cog. It’s an SD Driver and communicates via a hub mailbox.
To test it I have another asm file. It starts the above file with coginit. There is no spin in either - they are straight P2 assembly.
I have two problems.
First I cannot include the second file as an object...
OBJ
sd: “file2.spin2”
Second, I cannot reference the entry address in this object.
I had to place this file at the end after an
ORGH $2000
so I could use a fixed address to start it with
COGINIT #%01_0000,
and include the following in the calling file...
xyz long $2000
This was the only way I could get the coginit address.
And, the compiler did not include the file in the binary output.
I have had to resort to making one big file.
The P1 spin conversion to P2 asm is a separate issue. I am trying to convert Kyes spin P1 SD FAT driver to P2 asm. My asm Driver above will replace the asm section of Kyes driver.
Ah, I think I see where you're coming from. But OBJ is a Spin language feature, not PASM, so it's not going to work with pure PASM code. This isn't just a fastspin restriction, it's the same in original Spin too.
Probably you'll want to use #include to include the source file, something like:
Now the label @file2_start will refer to the start of the file2.spin2 code.
You can keep the Spin code as Spin, and just replace the assembly code. In fact you could even keep the assembly code and #ifdef it so that it can be compiled for P1 or for P2.
In the next release of fastspin the loc should work without slash. I've just given up and in mixed Spin + PASM all constant references in LOC will be absolute. References to labels will still be relative, and references in pure PASM will still be relative, it'll only be in mixed code that the rules will be a little different. This should be transparent to the programmer.
I suppose you could also make loc to a constant illegal...
A constant for loc is perfectly legal, as long as the constant fits in 20 bits. There is a case to be made that you should always use "\" with a constant, because otherwise the code will be position dependent, but for programs that don't move code around it shouldn't matter. In some sense Spin objects are always potentially moved, so loc in Spin objects should use "\" for constants. As I mentioned, that will happen automatically in the final version of fastspin 3.9.32 (so if you leave the "\" off it'll still be absolute with a constant, just as it would when referring to HUB variables from COG and vice-versa).
I’ll try include. This should be easier than OBJ anyways.
BTW we did use objects with PASM, just that they were always wrapped with spin. And we didn’t have include in proptool although we did in best and homespun.
I don't think it's ever been possible to refer to an object from PASM though. Having PASM inside of objects is fine (and will work in fastspin) but to actually use the objects you need to write some Spin code. Or am I missing something?
The current versions of both are 3.9.32, and they are available at:
https://www.patreon.com/totalspectrum
https://www.github.com/totalspectrum/flexgui/releases
https://www.github.com/totalspectrum/spin2cpp/releases
The "flexgui.zip" file contains everything you'll need for development on Windows, including fastspin.
This new release supports the new silicon via a "-2b" flag. The old silicon is still available as "-2a". Just plain "-2" selects the most common P2 variant, which is still "2a" but eventually will become "2b". FlexGUI has a button to switch between these.
Other changes are some more editor configuration options in FlexGUI, better handling of loc and jmps in PASM within Spin objects, and some C library fixes.
Yes, you're missing something here
The pasm in my case is a complete object that gets loaded into another cog. The interface is via a 4 long mailbox, used as a command + parameters and a status reply in response. So there is no interaction between objects except via the mailbox. When the COGINIT is launched, it is preceeded by a SETQ mailbox that passes the address of the mailbox into PTRA of the started cog. Works easy, save for the include
Found it
This is currently how I am getting the start entry point hub address and starting the cog passing the hub address of the mailbox into PTRA of the called cog.
Is there something I need to change in my code for this version to work?
My old pure ASM version of this code doesn't work with it either...
The attached was working perfectly in pure ASM with the two Spin lines commented out.
With the Spin in, it almost worked, except for something just a bit wrong with the very top graphics line...
Graphics are all messed up. I think it might be getting the offset to the palette wrong...
Looks like it might be an issue with the palette anyway...
Serial output looks right, so the code is running...
This is how that bitmap is specified:
I have found a problem. Attached is the source together with listings for fastspin 3.9.31 & 3.9.32
The listing so not match due to incorrect relative jmp forward compilation.
3.9.31 is definately wrong.
The jmp #@_fail at $19C 067 is an example. Currently not sure about 3.9.32 yet.
Spent days trying to get this working with weird results. Now I know why
Anyone have the link to the definitive use of @ and \ ?
There is no definitive answer in Chips reference for cog to cog in cog for the #@. Without @ it will use relative and with #\ it will use absolute.
Meanwhile off to try 3.9.32
Yes, there's a bug in the encoding of the rdlut and wrlut instructions . It'll actually work correctly if you tell it to compile for the rev 2b silicon (give it the "-2b" flag instead of "-2" or "-2a"). I changed rdlut and wrlut to handle the new PTRA++ addressing modes for the new silicon, but in the process managed to break encoding of the original silicon (it's just a silly typo in the source code, but it's enough to get a bit wrong in the output).
Code compiled for "-2b" will actually work fine on your original 2a silicon as long as you're not using any of the new features.
By definition anything involving @ is a HUB access, not cog to cog.
"@" says to use the HUB address of the following label
"\" says to use absolute rather than relative addressing
I did remove all the @ and the code still doesn’t get past go so I still think there’s a problem but it’s too late for me to test and likely no time for a few days
I was trying to debug two cogs communicating via hub, and they were each variously going off the rails. In the end I counted the nesting levels thinking there was a stack issue. I ended up separating them and trying to debug one of them when I struck the problem. The JMP #@_fail just before the .command8 label has a relative offset of IIRC 470 where the actual offset would have only been around 200 if the compiler was treating both as hub so I think something is still amiss.
We desperately need to sort this addressing mess out. The source should be able to be compiled for either cog or hub by a simple org statement. It would be nicer if the same compiled code could run in either but I’m not sure how relative works between the two modes. Is the relative bytes or longs.
Please don’t take this the wrong way Eric. You’re done a fantastic job!!!
"\" on the other hand means "use absolute addressing no matter what". Without it the assembler will try to use relative addressing if it can (for jumps that stay inside the same space -- COG, LUT, or HUB).
The rules for addressing are a little complicated, but I think they're clear:
(1) Labels have two values, a hub address (where the code is physically loaded by the loader into HUB memory at boot time) and a default address. The default address may be the same as the hub address (for code after orgh) or may be different (for code after org).
(2) Putting "@" in front of a label says to use its hub address. Otherwise its default address (the one established by org, if any) is used.
(3) If you put a "\" after the immediate symbol in a jmp or loc instruction, you're requesting that absolute addressing be used. This overrides any other consideration for relative vs. absolute addressing.
(4) If there is no "\", then the choice of relative vs absolute addressing is:
- if both addresses are in COG (between $0 and $1ff inclusive), use relative
- if both addresses are in LUT (between $200 and $3ff inclusive) use relative
- if both addresses are in HUB (above $400) use relative
- otherwise use absolute (as if "\" had been specified)
The only ambiguity I can think of is for the case where you try to jump to a HUB address below $400, for example by specifying @ on such a label or if it comes after an orgh without an org. In that case the various assemblers may differ in what they do -- some may treat it as a COG/LUT address, some may notice that it's really HUB and try to use that, etc. The hardware will always treat absolute jumps to below $400 as being into COG or LUT memory. So it's probably a very bad idea to try to hubexec code below $400. Maybe, possibly, a relative jump could be made to hub code in that space (@cgracey, please correct me if I'm wrong). But there are so many potential problems that I would *strongly* recommend not doing this. For example, if code that's in HUB below $400 does a subroutine call, any RET will end up jumping into COG/LUT rather than back to HUB.
If your definitions are correct, then Chip needs to change his document as it disagrees.
I'm working with the "test.spin2" I think ersmith posted here earlier...
It could be the serial coms that are broke, not sure...
Nope, doesn't appear to be just the serial coms. I rigged it to toggle P56 led on keypress and it doesn't do it with new fastspin...