Chip, is the scope of local variables still the same? With it being only between global variables as now, it makes it impossible to use common names (me, delay, pins, etc) within a COG image. These all become global variables so you end up with me, me2, me3 and so on as you build COG images in your program. Scoping within an org section might be a useful feature.
Thanks again for putting up with us and giving new toys to try!
Chip, is the scope of local variables still the same? With it being only between global variables as now, it makes it impossible to use common names (me, delay, pins, etc) within a COG image. These all become global variables so you end up with me, me2, me3 and so on as you build COG images in your program. Scoping within an org section might be a useful feature.
Thanks again for putting up with us and giving new toys to try!
Every time you declare a normal symbol, you've made a new scope for local variables. Maybe I'm not understanding you.
Initial debug ISR's have been moved up to $FFFC0..$FFFFF.
Event-triggering LONGs have been moved up to $FFF80..$FFFBF.
(No more complications at the bottom of hub RAM - everything starts at $00000)
PNut doesn't download to the last 16 longs in hub RAM, anymore, so that you don't have to worry about putting those initial debug ISR's in your code.
Shouldn't that be the last 32 longs in hub RAM? Preloading data the event-triggering LONGs doesn't seem very useful.
Chip, is the scope of local variables still the same? With it being only between global variables as now, it makes it impossible to use common names (me, delay, pins, etc) within a COG image. These all become global variables so you end up with me, me2, me3 and so on as you build COG images in your program. Scoping within an org section might be a useful feature.
Thanks again for putting up with us and giving new toys to try!
Every time you declare a normal symbol, you've made a new scope for local variables. Maybe I'm not understanding you.
Exactly, that is the problem I am having the scope is too small for local variables.
I think it would be useful to be able to:
orgh $1000
.me long 0
hubentry cogid .me ' this .me would resolve to the one defined in the orgh
.
.
org 0
.me long 0
.
cog1entry cogid .me ' this .me would resolve to the one above
.
.
org 0
.
cog2entry cogid .me ' this .me would resolve to the address of the one below
.
.me long 0
the variable .me would have scope between orgs. That is, a reference to .me would refer to the .me most recently defined back to the previous org.
This way PASM code written for a COG would be source portable as long as you used local variables. If I wanted to use code you wrote for a COG as long as I took it from the org to the code, any local variables you used on your code snippet would not conflict with local variables I used in my code snippets. They would be in scope for that org section but nothing else.
It would be like module scoping if you consider everything between orgs to be a COG module or function scoping if you considered the chunks of code between orgs to be "functions".
Initial debug ISR's have been moved up to $FFFC0..$FFFFF.
Event-triggering LONGs have been moved up to $FFF80..$FFFBF.
(No more complications at the bottom of hub RAM - everything starts at $00000)
PNut doesn't download to the last 16 longs in hub RAM, anymore, so that you don't have to worry about putting those initial debug ISR's in your code.
Shouldn't that be the last 32 longs in hub RAM? Preloading data the event-triggering LONGs doesn't seem very useful.
No, Chip's description is correct. The event longs ($FFF80-$FFFBF) are immediately followed by the DEBUG ISRs ($FFFC0-$FFFFF). The ROM booter preloads the last 16 longs with IRET0 and you need to change them in your code if you want to intercept them - PNUT never loads these. PNUT *WILL* load the Event longs for you if you define them in your code.
When I played with the last version of PNUT however, it did not like addresses above $7FFFF, so you still might need to manually load the event vectors once you are loaded and running your code.
No, Chip's description is correct. The event longs ($FFF80-$FFFBF) are immediately followed by the DEBUG ISRs ($FFFC0-$FFFFF). The ROM booter preloads the last 16 longs with IRET0 and you need to change them in your code if you want to intercept them - PNUT never loads these. PNUT *WILL* load the Event longs for you if you define them in your code.
When I played with the last version of PNUT however, it did not like addresses above $7FFFF, so you still might need to manually load the event vectors once you are loaded and running your code.
Wait! That's right! PNUT can't reasonably load anything above $7FFFF, so my comment is moot.
Coley wrote:
IMHO Hub exec mode is the icing on the cake and shouldn't be the driving force.
I use all sorts of micros depending on the task at hand, the Propeller is by far the easiest and most fun to use.
I really hope P2 can continue that tradition.
+1
David Betz wrote:
I was under the impression that it was relatively uncommon for most Propeller users to use PASM other than what is included in drivers that they download from OBEX.
It is FAR FAR FAR more likely for a Propeller user to use ASM than it is for an ARM user to use ASM. I will resist any effort to make the Propeller another ARM chip. At least 75% of all Propeller code I write is PASM because of the Propeller's irreplaceable and almost unique facility to allow a user to create precise custom high-speed signalling easily.
+1
The precise high speed signalling the cogs and pasm make possible is my main reason for using the propeller.
Coley wrote:
IMHO Hub exec mode is the icing on the cake and shouldn't be the driving force.
I use all sorts of micros depending on the task at hand, the Propeller is by far the easiest and most fun to use.
I really hope P2 can continue that tradition.
+1
David Betz wrote:
I was under the impression that it was relatively uncommon for most Propeller users to use PASM other than what is included in drivers that they download from OBEX.
It is FAR FAR FAR more likely for a Propeller user to use ASM than it is for an ARM user to use ASM. I will resist any effort to make the Propeller another ARM chip. At least 75% of all Propeller code I write is PASM because of the Propeller's irreplaceable and almost unique facility to allow a user to create precise custom high-speed signalling easily.
+1
The precise high speed signalling the cogs and pasm make possible is my main reason for using the propeller.
I agree but I still wonder what percentage of Propeller users write that PASM code themselves vs. using an off-the-shelf object that contains PASM code someone else wrote.
[register] usually means indirect through the register, so that works. Although, I would prefer it be consistent, and be used everywhere, not just on branches. In fact, I think we could lose the # to mean immediate, and instead have it be no symbol = immediate, and [] means through register, then the @ can stay as it was beforee you made it the ` (which is awful).
C/C++ uses & to mean address of when it prepends an identifier (e.g. &routine = address of routine), maybe an option?
+1, particularly for no symbol meaning immediate. Forgetting the # is the most common mistake I still make fairly often.
Well, we need something to denote relative, as opposed to absolute branching.
I'm unclear on why this is needed ?
Can the assembler not choose the smallest, most portable form, when using a generic CALL or JMP, and if you want an explicit non-relative form for some reason, use a AJMP or LJMP or RJMP - that avoids yet another special character... ?
Ah, make new mnemonics for the different types. Interesting.
That might work well. JMP would be the generic case that would follow some contextual rule, while AJMP/RJMP would force absolute/relative. I wonder if that would just clutter things up on the instruction side, though. It would get rid of both "#" and "@" for branches, which is nice.
It might be better to put the letter on the end. No, that's not going to work.
That gets kind of busy. Maybe we could use ":" to mean relative and "#" to mean absolute. That is a lot tidier. I think someone suggested using ":" for relative. If we did that, "@" could mean address-of.
Why mnemonics? The compiler should be able to select between direct and relative based on distance from the current location. Then indirect is the only choice that needs to be specified, and it may need to be specified to take advantage of jump tables in any case.
On the P1, I've experienced a problem where I've needed to refer to what should be a local label from the other side of a global label. Currently, the only solution to this is to make the local label global, further cluttering the global namespace. To alleviate this, could you add globallabel.locallabel syntax to refer to possibly out-of-scope local labels, where .locallabel is a local label that comes after globallabel and before the next global label after globallabel?
I remember coming to the P1 without any useful background at all. What I really loved is that I could start using both SPIN and PASM without reading anything:) As long as I stuck to the patterns, I was fine. This latest incantation does exactly that for me.
Yep. All part of the beauty. I appreciated it too. Back in the day, when I saw P1 and ordered up a Demo Board, I was able to read through and start working in a day. And that's some tweaking of PASM too. You follow the patterns, and there are only a few variations, so worst case, plug a couple in, until it works. Better understanding comes quickly, but it also comes in the context of doing stuff too.
@label is the address of label, as on the P1. #@ means use that address as a 9-bit immediate value.. ##@ means use the address as a 32-bit immediate value, using AUGS to make the address fit.
[register] usually means indirect through the register, so that works. Although, I would prefer it be consistent, and be used everywhere, not just on branches. In fact, I think we could lose the # to mean immediate, and instead have it be no symbol = immediate, and [] means through register
+1, particularly for no symbol meaning immediate. Forgetting the # is the most common mistake I still make fairly often.
I agree, many users will be using more than one MCU assembler, and certainly all new users will have been exposed to some other Assembler
That introduces a wrinkle into the standard Propeller thinking, though. I could go either way.
I think there is a solution that covers all of this :
Support JMP [reg] '@register branches use [reg]
as that is a safe superset. ie nothing breaks if you do this.
(and the code is already done.. )
Support the legacy, but deprecated JMP #LabelName
nothing breaks if you do that, which only leaves..
Have a simple switch that directs the ambiguous and nonstandard JMP LabelName
to be treated as either of JMP [LabelName] ' Indirect jump
or JMP LabelName ' Standard direct Jump
Prop users who have never used any other assembler, and expect they never will, can use the legacy form.
New users, and those using multiple assemblers, can use the switch set the other way.(default?)
Ah, make new mnemonics for the different types. Interesting.
That might work well. JMP would be the generic case that would follow some contextual rule, while AJMP/RJMP would force absolute/relative. I wonder if that would just clutter things up on the instruction side, though. It would get rid of both "#" and "@" for branches, which is nice.
The compiler should be able to select between direct and relative based on distance from the current location. Then indirect is the only choice that needs to be specified, and it may need to be specified to take advantage of jump tables in any case.
Yup, agreed, however some Assemblers are better at this than others.
IIRC Chip has said PNUT is 2 pass and does not forward resolve.
Also, gas docs suggest it is worse than yasm, and may need some user-help until it gets as good as yasm
using mnemonics allow everyone to code now, while the tools get aligned to the ideal.
IIRC Chip has said PNUT is 2 pass and does not forward resolve.
Yes. If we keep this stage simple, the on chip tools will work reasonably well. For those that care, this discussion matters. For everyone, it's a baseline set of functionality that is necessary to bootstrap higher level things.
Once it's a lock, and we've got bigger and better things going on, the tools one layer up, gcc, OpenSpin, etc... can add a lot of the nice bits people are wanting / needing.
the variable .me would have scope between orgs. That is, a reference to .me would refer to the .me most recently defined back to the previous org.
It would be like module scoping if you consider everything between orgs to be a COG module or function scoping if you considered the chunks of code between orgs to be "functions".
Understood, but that sounds like a problem that needs more than a local change.
On the P1, I've experienced a problem where I've needed to refer to what should be a local label from the other side of a global label. Currently, the only solution to this is to make the local label global, further cluttering the global namespace. To alleviate this, could you add globallabel.locallabel syntax to refer to possibly out-of-scope local labels, where .locallabel is a local label that comes after globallabel and before the next global label after globallabel?
Reading the gas / nasm docs, I think they do this.( I've not tried it)
ie you can use globallabel.locallabel, which I think is one reason they chose the period.
No idea how easy/hard that is to add to PNUT, but the idea has precedence.
Question: aren't there still enough bits in coginit D field to pass a long-aligned address?
Since there's now an alignment compiler directive, is this easy to add?
Maybe upper bits of D could be sent to PARA?
Question: aren't there still enough bits in coginit D field to pass a long-aligned address?
Since there's now an alignment compiler directive, is this easy to add?
Maybe upper bits of D could be sent to PARA?
There are only 9 bits in D for an immediate value:
Ok. Still, isn't that the perfect size for mapping to the <$400 HUB RAM area?
Those nine bits would only reach to $1FF. Remember that we are not forcing long alignment for instructions, like some would prefer, so that we could reduce the PC's by two bits. Those 9 bits count bytes, not longs.
Comments
At the top of the thread, I've loaded a new file, with some explanation.
Thanks again for putting up with us and giving new toys to try!
Every time you declare a normal symbol, you've made a new scope for local variables. Maybe I'm not understanding you.
BTW: I hope you get a chance to update the documentation with something about the LUT streamer...
Shouldn't that be the last 32 longs in hub RAM? Preloading data the event-triggering LONGs doesn't seem very useful.
Exactly, that is the problem I am having the scope is too small for local variables.
I think it would be useful to be able to:
the variable .me would have scope between orgs. That is, a reference to .me would refer to the .me most recently defined back to the previous org.
This way PASM code written for a COG would be source portable as long as you used local variables. If I wanted to use code you wrote for a COG as long as I took it from the org to the code, any local variables you used on your code snippet would not conflict with local variables I used in my code snippets. They would be in scope for that org section but nothing else.
It would be like module scoping if you consider everything between orgs to be a COG module or function scoping if you considered the chunks of code between orgs to be "functions".
No, Chip's description is correct. The event longs ($FFF80-$FFFBF) are immediately followed by the DEBUG ISRs ($FFFC0-$FFFFF). The ROM booter preloads the last 16 longs with IRET0 and you need to change them in your code if you want to intercept them - PNUT never loads these. PNUT *WILL* load the Event longs for you if you define them in your code.
When I played with the last version of PNUT however, it did not like addresses above $7FFFF, so you still might need to manually load the event vectors once you are loaded and running your code.
Wait! That's right! PNUT can't reasonably load anything above $7FFFF, so my comment is moot.
+1
The precise high speed signalling the cogs and pasm make possible is my main reason for using the propeller.
+1, particularly for no symbol meaning immediate. Forgetting the # is the most common mistake I still make fairly often.
Why mnemonics? The compiler should be able to select between direct and relative based on distance from the current location. Then indirect is the only choice that needs to be specified, and it may need to be specified to take advantage of jump tables in any case.
Also, I love the new addressing syntax!
I remember coming to the P1 without any useful background at all. What I really loved is that I could start using both SPIN and PASM without reading anything:) As long as I stuck to the patterns, I was fine. This latest incantation does exactly that for me.
Well done guys!!!!
Rich
It is all incredible.
Rich
I agree, many users will be using more than one MCU assembler, and certainly all new users will have been exposed to some other Assembler
Yup that makes sense, plus it is the widely understood/expected syntax, however....
this also makes sense :
I think there is a solution that covers all of this :
Support
JMP [reg] '@register branches use [reg]
as that is a safe superset. ie nothing breaks if you do this.
(and the code is already done.. )
Support the legacy, but deprecated
JMP #LabelName
nothing breaks if you do that, which only leaves..
Have a simple switch that directs the ambiguous and nonstandard
JMP LabelName
to be treated as either of
JMP [LabelName] ' Indirect jump
or
JMP LabelName ' Standard direct Jump
Prop users who have never used any other assembler, and expect they never will, can use the legacy form.
New users, and those using multiple assemblers, can use the switch set the other way.(default?)
Yup, agreed, however some Assemblers are better at this than others.
IIRC Chip has said PNUT is 2 pass and does not forward resolve.
Also, gas docs suggest it is worse than yasm, and may need some user-help until it gets as good as yasm
using mnemonics allow everyone to code now, while the tools get aligned to the ideal.
Yes. If we keep this stage simple, the on chip tools will work reasonably well. For those that care, this discussion matters. For everyone, it's a baseline set of functionality that is necessary to bootstrap higher level things.
Once it's a lock, and we've got bigger and better things going on, the tools one layer up, gcc, OpenSpin, etc... can add a lot of the nice bits people are wanting / needing.
Understood, but that sounds like a problem that needs more than a local change.
Can you use the form below ?
Reading the gas / nasm docs, I think they do this.( I've not tried it)
ie you can use globallabel.locallabel, which I think is one reason they chose the period.
No idea how easy/hard that is to add to PNUT, but the idea has precedence.
Question: aren't there still enough bits in coginit D field to pass a long-aligned address?
Since there's now an alignment compiler directive, is this easy to add?
Maybe upper bits of D could be sent to PARA?
There are only 9 bits in D for an immediate value:
CCCC 1100111 CLI DDDDDDDDD SSSSSSSSS COGINIT D/#,S/# {WC}
Those nine bits would only reach to $1FF. Remember that we are not forcing long alignment for instructions, like some would prefer, so that we could reduce the PC's by two bits. Those 9 bits count bytes, not longs.
Can you answer this question:
"@" means the-address-of-in-hub.
"#@" means the-address-of-in-hub, in an immediate 9-bit constant. It had better fit!
"##@" means the-address-of-in-hub, in an immediate 32-bit constant (20-bit, really). It will always fit!
I think someone accurately answered this earlier.
Possibly, but with the latest changes, I've lost track. Taking this a bit further, what is the difference between:
# and #@
## and ##@
edit: And where would you use @ instead of #@ or ##@?