@cgracey said:
What preprocessing commands should reasonably be implemented? I don't want to spend too much time on this, but what could be done that would solve most of the problem?
I think INCLUDE is the hardest to implement.
I use #INCLUDE all the time with FlexSpin to handle auto-generated skip patterns. I've written a program that scans the source file for skip patterns and outputs SKIPF and EXECF bit string constants to file xxxx.SKP, with a #INCLUDE "xxxx.SKP" line immediately after CON in source file.
Supporting #include "filename" is really useful for partitioning code and building up libraries from smaller source files rather than keeping everything in one big monolithic file.
Also when combining #include with #ifdef etc this is very powerful because it then lets your data and code be build time configurable as well without otherwise duplicating lots of lines in different source files. I could really use this feature in my various memory drivers. You could just setup one #define (or a const perhaps if these can be shared) and it would pull in the needed pieces to build a driver object for you.
+1000 for #include...I use it a lot with flexspin, for basically all the reasons Roger mentions. Great for re-use of existing code without having to manually copy and paste. Lots of code that's common to several different drivers? Put it in an external file and #include it in all of them instead. That way any changes that need to be made to it can be made once, in one place, instead of changing it in a zillion places, possibly making mistakes along the way and ending up with a zillion different versions.
@JonnyMac said:
Am I missing something, Jeff? I downloaded the ZIP from the link in your post.
I did in fact extract to a folder -- there are only those two files in it.
Yes, apparently the archive didn't get uploaded. I've fixed it. It's the top zip file in the Assets on that page. Thank you so much for reporting.
Jeff,
I just tried the 2.8 beta on Wine and it now IDs and downloads/runs on Prop2. First time comms has worked in Proptool's history.
Debug had problems though. It spat out a bunch of errors as a series of pop-ups. I'll report more later.
@evanh said:
I just tried the 2.8 beta on Wine and it now IDs and downloads/runs on Prop2. First time comms has worked in Proptool's history.
Debug had problems though. It spat out a bunch of errors as a series of pop-ups. I'll report more later.
Thanks! That's encouraging. I'm working on a debugging issue, trying to get it to work under my VM. If I can get it to work there, it may work across more machines (and maybe under Wine). Looking forward to the details.
Ah, the errors this morning occurred with "debugger_clock_frequency_change.spin2". That might be a regression in Proptool ... Possibly no longer handling dynamic runtime changes of the Prop2 clock frequency? Or did Proptool not get that feature yet?
@evanh said:
Ah, the errors this morning occurred with "debugger_clock_frequency_change.spin2". That might be a regression in Proptool ... Possibly no longer handling dynamic runtime changes of the Prop2 clock frequency? Or did Proptool not get that feature yet?
Thanks. PropTool did get the clock frequency change feature for PASM2-only code, but maybe I missed something. I'll check into it.
@variable used to only work with hub variables and it returned a 20-bit address with potentially unknown data in the top 12 bits.
Now, @variable works with all variables (both hub and register), including any bit fields. It uses the top 12 bits of the return value to store the additional setup information for register/byte/word/long, base bit, and number of additional bits, in addition to the original 20 bits of address in the LSBs.
@variable outputs these patterns now:
@reg --> 00_11111_00000_00000000000rrrrrrrrr
@reg.[bbbbb addbits sssss] --> 00_sssss_bbbbb_00000000000rrrrrrrrr
@byte --> 01_00111_00000_aaaaaaaaaaaaaaaaaaaa
@byte.[bbbbb addbits sssss] --> 01_sssss_bbbbb_aaaaaaaaaaaaaaaaaaaa
@word --> 10_01111_00000_aaaaaaaaaaaaaaaaaaaa
@word.[bbbbb addbits sssss] --> 10_sssss_bbbbb_aaaaaaaaaaaaaaaaaaaa
@long --> 11_11111_00000_aaaaaaaaaaaaaaaaaaaa
@long.[bbbbb addbits sssss] --> 11_sssss_bbbbb_aaaaaaaaaaaaaaaaaaaa
bbbbb = base bit of field within reg/byte/word/long
sssss = number of additional bits in field
To go with this, there is a new FIELD[] keyword which allows you to operate on the variable pointed to by the @variable operation.
You can now do things like this:
PUB Go() | p
dira~~
p := @outa.[7..4]
repeat
Increment(p)
PRI Increment(somebits)
field[somebits]++
I was noticing that in the code I was writing for the flash file system, there were getting to be many repetitive and ugly variables with bit fields. They had to be typed over and over. Now, they can be typed once and the runtime code will be smaller and faster.
The net effect on execution time is that @variable statements now take 19 PASM instructions, instead of 2, and the routine is in hub RAM, so it takes some extra clocks to branch to it and restart XBYTE.
and it would operate on those same field bits in successive variables/registers?
Yes, and you could add offsets, too, since the address is in the 20 LSBs.
Increment(p + 1)
In case someone supposes that this breaks the current language, bits 31..20 were previously undefined from @variable. Now, we give them meaning and offer an extra keyword FIELD[] with which you can operate on ANY variable pointed to by @variable. It was providence that we had exactly the twelve more bits needed to accomplish this in a 32-bit variable.
@cgracey said:
In case someone supposes that this breaks the current language, bits 31..20 were previously undefined from @variable. Now, we give them meaning and offer an extra keyword FIELD[] with which you can operate on ANY variable pointed to by @variable. It was providence that we had exactly the twelve more bits needed to accomplish this in a 32-bit variable.
Were they really undefined? I remember Spin1 explicitly clears out high bits when computing an address.
Though this passively occurring on every address-of is perhaps a bit obnoxious. Should rather be a separate operator to maintain speed/simplicity of the regualar addrof operation (IOW flexspin backends go owie owie)
@cgracey said:
In case someone supposes that this breaks the current language, bits 31..20 were previously undefined from @variable. Now, we give them meaning and offer an extra keyword FIELD[] with which you can operate on ANY variable pointed to by @variable. It was providence that we had exactly the twelve more bits needed to accomplish this in a 32-bit variable.
Well, it certainly breaks any program which uses the word "field" as a variable or constant, and breaks any program that compares addresses (@variable used to clear the upper bits, and I don't recall any official declaration that those bits were undefined).
I suppose it doesn't really matter. Parallax has made it abundantly clear that FlexSpin and other third party languages/implementations aren't of interest to them, and that's their perogative.
@ersmith said:
I suppose it doesn't really matter. Parallax has made it abundantly clear that FlexSpin and other third party languages/implementations aren't of interest to them, and that's their perogative.
For what its worth, I dont know Spin, I never intend to learn or use Spin, and without @ersmith excellent Flex suite (C, BASIC, PASM) I’d have moved on to something else long ago. Parallax needs to understand that I am not alone and probably in the majority here.
Third-party language support is essential to keeping the P2 relevent. Few new users are going to say “sure, no problem, I’ll spend a few weeks learning a new language just so I can then learn about this thing called a P2… so I can then see if it works for me”. No. The “hook” for new users is leveraging their knowledge of existing, mainstream languages so they can immediately start wiggling bits and have that “wow!!!” moment. That moment then becomes a contagion and results in flying purchase orders and new products.
PARALLAX: Guys like Eric, Ross, and all the other “wing and a prayer” third party implementors need your support. The user-base needs these tools. Ignore them at your own peril.
EVERYONE: consider spending a minute (and a buck) to make a donation to any of the excellent third-party developers that give us the FREE tools to make more neat stuff.
Chip, why are you designing your own, incompatible Flash FS when there are already things like LittleFS and SpifFS? Some of them have quite elegant designs. If you just reimplemented one of those in Spin, you'd have something that's already proven to work reliably, something that already has tools that run on a PC, and one less thing that's likely to scare away new users.
This new operator is nice, but please make it something different than plain @, for the reasons Ada described, and because it's so much slower. And why is it so much slower, anyway? Doesn't it just need to add PBASE to an immediate value? Wouldn't it still be the same, just with a bigger immediate, except in the REG case, where it'd just be a 32-bit immediate load without the + PBASE?
@cgracey said:
In case someone supposes that this breaks the current language, bits 31..20 were previously undefined from @variable. Now, we give them meaning and offer an extra keyword FIELD[] with which you can operate on ANY variable pointed to by @variable. It was providence that we had exactly the twelve more bits needed to accomplish this in a 32-bit variable.
Well, it certainly breaks any program which uses the word "field" as a variable or constant, and breaks any program that compares addresses (@variable used to clear the upper bits, and I don't recall any official declaration that those bits were undefined).
Good spot. Didn't even think of that. Though the comparsion issue would only arise when comparing addresses of different-width elements, which is a nice footgun. i.e. repeat ptr from @some_long to @some_byte will bring you a cool surprise (I forget the specifics of how the compiler decides access width for DAT symbols, but something tells me it's easy to make this scenario happen.) Same issue when calculating relative offsets. It really should be a different operator. Since @@ and @@@ are taken, how about @!
I suppose it doesn't really matter. Parallax has made it abundantly clear that FlexSpin and other third party languages/implementations aren't of interest to them, and that's their perogative.
Yea
I think we need to come up with a policy on what constitues "FlexSpin2" then.
I suppose it doesn't really matter. Parallax has made it abundantly clear that FlexSpin and other third party languages/implementations aren't of interest to them, and that's their perogative.
That's bad.
Having only a Proptool/Spin will greatly reduce interest in this microcontroller.
I work at a technical university. When I show P2 to my colleagues, the first question they ask me is - "can it be programmed in C?"
Yes, it can, because of Flexprop. If Flexprop was not there, we would not have bought >40 Edges and several Evals for our project.
Parallax should support Flexprop too. While Propeller Tool is good, it is spin only tool and there is limited count of microcontroller programmers who want to learn yet another language when they can simply buy something else, C programmable instead.
I think I am going to put @variable back to quickly returning the 20-bit hub address, but with the top 12 bits cleared using 'zerox x,#11'. That will add one instruction to what we used to have.
Then, I am going to put the newer functionality into ^@variable. Also, I will get rid of FIELD[ptr] and use ^[ptr] instead.
Thank you all for working in the sausage factory.
We do appreciate Eric's Flexprop tool, by the way.
@Electrodude said:
Chip, why are you designing your own, incompatible Flash FS when there are already things like LittleFS and SpifFS? Some of them have quite elegant designs. If you just reimplemented one of those in Spin, you'd have something that's already proven to work reliably, something that already has tools that run on a PC, and one less thing that's likely to scare away new users.
This new operator is nice, but please make it something different than plain @, for the reasons Ada described, and because it's so much slower. And why is it so much slower, anyway? Doesn't it just need to add PBASE to an immediate value? Wouldn't it still be the same, just with a bigger immediate, except in the REG case, where it'd just be a 32-bit immediate load without the + PBASE?
I looked into these existing file systems for micro controllers and they were just way too complicated. I've got the critical issues all ironed out and our file system will be very compact and simple.
@cgracey said:
I think I am going to put @variable back to quickly returning the 20-bit hub address, but with the top 12 bits cleared using 'zerox x,#11'. That will add one instruction to what we used to have.
Wouldn't they already be clear if VBASE/PBASE have cleared top bits? Are there any situations where they wouldn't be? Method pointers? It'd probably be more efficient to make sure the base pointers are in range in any situation where they might not be.
@cgracey said:
I think I am going to put @variable back to quickly returning the 20-bit hub address, but with the top 12 bits cleared using 'zerox x,#11'. That will add one instruction to what we used to have.
Wouldn't they already be clear if VBASE/PBASE have cleared top bits? Are there any situations where they wouldn't be? Method pointers? It'd probably be more efficient to make sure the base pointers are in range in any situation where they might not be.
I need to check, but there could at least be roll over effects from indexing.
@cgracey said:
I think I am going to put @variable back to quickly returning the 20-bit hub address, but with the top 12 bits cleared using 'zerox x,#11'. That will add one instruction to what we used to have.
Wouldn't they already be clear if VBASE/PBASE have cleared top bits? Are there any situations where they wouldn't be? Method pointers? It'd probably be more efficient to make sure the base pointers are in range in any situation where they might not be.
I need to check, but there could at least be roll over effects from indexing.
Hmm, if you're indexing out of bounds (@something[1_000_000]), I think that's programmer's fault and returning an overflown address is the result i'd expect. Then again, Spin1 clears it (and flexspin (P1 bytecode backend aside) doesn't, now that I think about it. That difference is currently documented for @@ operator only... PR submitted)
I think I am going to put @variable back to quickly returning the 20-bit hub address, but with the top 12 bits cleared using 'zerox x,#11'. That will add one instruction to what we used to have.
Thanks Chip, I was thinking about this thread yesterday but didn't want to complicate it more by responding with my opinions, yet this was the actual change I was hoping for. Prior to reading this I didn't realize that doing @variable could potentially leave garbage in the top 12 bits. For address comparisons to be able to find differences in addresses between variables it is important that these top bits remain fixed so ensuring they are zero is ideal.
When you have new features to put into SPIN, then using additional operators is probably going to more amenable than changing the behavior of existing code. Doing that would upset the apple cart too much. It's tricky to redefine a language that is already released.
@cgracey said:
To go with this, there is a new FIELD[] keyword which allows you to operate on the variable pointed to by the @variable operation.
You can now do things like this:
PUB Go() | p
dira~~
p := @outa.[7..4]
repeat
Increment(p)
PRI Increment(somebits)
field[somebits]++
I'm probably not the only one who was still thinking about this after the Zoom discussion yesterday, As I understand the enhancement, it's an index-able pointer to some arbitrary, predefined, number of bits in a packed array of these bit fields.
I decided that, given a choice, I'd prefer the keyword "ptrp[]" - which can be read as "pointer to packed".
@brianh said:
I decided that, given a choice, I'd prefer the keyword "ptrp[]" - which can be read as "pointer to packed".
Thanks for suggesting that. I like that because it's very short and relatable to its function, as you suggested. At the same time, I'm also hesitant about it because it appears to represent a specific existing entity, like the PTRA and PTRB registers. PTRP may also seem to refer to a register for someone learning and browsing the reserved word list or an alphabetical list of features of sorts.
Maybe pptr[] instead? Meaning "packed pointer."
Also, it doesn't have to be an array of arbitrary-sized bit fields... this symbol[] could also be used just to conveniently reference a unique arbitrary-sized bit field at a specific address. So on that note, and considering Chip naturally thought "FIELD"... maybe a combination of his and your ideas: fptr[] to mean "field pointer."
@"Jeff Martin" said:
Thanks for suggesting that. I like that because it's very short and relatable to its function, as you suggested. At the same time, I'm also hesitant about it because it appears to represent a specific existing entity, like the PTRA and PTRB registers. PTRP may also seem to refer to a register for someone learning and browsing the reserved word list or an alphabetical list of features of sorts.
Maybe pptr[] instead? Meaning "packed pointer."
Good point. Using "pptr[]" and reading it as "packed pointer" makes just as much sense to me.
Part of the discussion was that "[single letter]ptr" is something more likely to be used as a user symbol, whereas "ptr[single letter]" is already used for the register symbols.
Hmm, That just happens to break my bitmap driver code I'm currently writing, there it means "pixel pointer". But as it's not released yet I can easily fix that.
Comments
Getting just the same two files Jon got.
Supporting #include "filename" is really useful for partitioning code and building up libraries from smaller source files rather than keeping everything in one big monolithic file.
Also when combining #include with #ifdef etc this is very powerful because it then lets your data and code be build time configurable as well without otherwise duplicating lots of lines in different source files. I could really use this feature in my various memory drivers. You could just setup one #define (or a const perhaps if these can be shared) and it would pull in the needed pieces to build a driver object for you.
+1000 for #include...I use it a lot with flexspin, for basically all the reasons Roger mentions. Great for re-use of existing code without having to manually copy and paste. Lots of code that's common to several different drivers? Put it in an external file and #include it in all of them instead. That way any changes that need to be made to it can be made once, in one place, instead of changing it in a zillion places, possibly making mistakes along the way and ending up with a zillion different versions.
Yes, apparently the archive didn't get uploaded. I've fixed it. It's the top zip file in the Assets on that page. Thank you so much for reporting.
https://github.com/parallaxinc/Propeller-Tool/releases/tag/v2.8.0_beta
Jeff,
I just tried the 2.8 beta on Wine and it now IDs and downloads/runs on Prop2. First time comms has worked in Proptool's history.
Debug had problems though. It spat out a bunch of errors as a series of pop-ups. I'll report more later.
Thanks! That's encouraging. I'm working on a debugging issue, trying to get it to work under my VM. If I can get it to work there, it may work across more machines (and maybe under Wine). Looking forward to the details.
Oddly, the errors I got this morning aren't happening now. Debug works.
I am getting an error 120 when stopping debug though:
Ah, the errors this morning occurred with "debugger_clock_frequency_change.spin2". That might be a regression in Proptool ... Possibly no longer handling dynamic runtime changes of the Prop2 clock frequency? Or did Proptool not get that feature yet?
Thanks. PropTool did get the clock frequency change feature for PASM2-only code, but maybe I missed something. I'll check into it.
I made an enhancement to the @variable operator.
@variable used to only work with hub variables and it returned a 20-bit address with potentially unknown data in the top 12 bits.
Now, @variable works with all variables (both hub and register), including any bit fields. It uses the top 12 bits of the return value to store the additional setup information for register/byte/word/long, base bit, and number of additional bits, in addition to the original 20 bits of address in the LSBs.
@variable outputs these patterns now:
To go with this, there is a new FIELD[] keyword which allows you to operate on the variable pointed to by the @variable operation.
You can now do things like this:
The FIELD[] variable alias works like this:
I was noticing that in the code I was writing for the flash file system, there were getting to be many repetitive and ugly variables with bit fields. They had to be typed over and over. Now, they can be typed once and the runtime code will be smaller and faster.
The net effect on execution time is that @variable statements now take 19 PASM instructions, instead of 2, and the routine is in hub RAM, so it takes some extra clocks to branch to it and restart XBYTE.
Wow Chip, that's great!
By the looks of it, we can also do something like
and it would operate on those same field bits in successive variables/registers?
Yes, and you could add offsets, too, since the address is in the 20 LSBs.
Increment(p + 1)
In case someone supposes that this breaks the current language, bits 31..20 were previously undefined from @variable. Now, we give them meaning and offer an extra keyword FIELD[] with which you can operate on ANY variable pointed to by @variable. It was providence that we had exactly the twelve more bits needed to accomplish this in a 32-bit variable.
Were they really undefined? I remember Spin1 explicitly clears out high bits when computing an address.
Though this passively occurring on every address-of is perhaps a bit obnoxious. Should rather be a separate operator to maintain speed/simplicity of the regualar addrof operation (IOW flexspin backends go owie owie)
Well, it certainly breaks any program which uses the word "field" as a variable or constant, and breaks any program that compares addresses (@variable used to clear the upper bits, and I don't recall any official declaration that those bits were undefined).
I suppose it doesn't really matter. Parallax has made it abundantly clear that FlexSpin and other third party languages/implementations aren't of interest to them, and that's their perogative.
For what its worth, I dont know Spin, I never intend to learn or use Spin, and without @ersmith excellent Flex suite (C, BASIC, PASM) I’d have moved on to something else long ago. Parallax needs to understand that I am not alone and probably in the majority here.
Third-party language support is essential to keeping the P2 relevent. Few new users are going to say “sure, no problem, I’ll spend a few weeks learning a new language just so I can then learn about this thing called a P2… so I can then see if it works for me”. No. The “hook” for new users is leveraging their knowledge of existing, mainstream languages so they can immediately start wiggling bits and have that “wow!!!” moment. That moment then becomes a contagion and results in flying purchase orders and new products.
PARALLAX: Guys like Eric, Ross, and all the other “wing and a prayer” third party implementors need your support. The user-base needs these tools. Ignore them at your own peril.
EVERYONE: consider spending a minute (and a buck) to make a donation to any of the excellent third-party developers that give us the FREE tools to make more neat stuff.
Chip, why are you designing your own, incompatible Flash FS when there are already things like LittleFS and SpifFS? Some of them have quite elegant designs. If you just reimplemented one of those in Spin, you'd have something that's already proven to work reliably, something that already has tools that run on a PC, and one less thing that's likely to scare away new users.
This new operator is nice, but please make it something different than plain
@
, for the reasons Ada described, and because it's so much slower. And why is it so much slower, anyway? Doesn't it just need to add PBASE to an immediate value? Wouldn't it still be the same, just with a bigger immediate, except in the REG case, where it'd just be a 32-bit immediate load without the + PBASE?Good spot. Didn't even think of that. Though the comparsion issue would only arise when comparing addresses of different-width elements, which is a nice footgun. i.e.
repeat ptr from @some_long to @some_byte
will bring you a cool surprise (I forget the specifics of how the compiler decides access width for DAT symbols, but something tells me it's easy to make this scenario happen.) Same issue when calculating relative offsets. It really should be a different operator. Since@@
and@@@
are taken, how about@!
Yea
I think we need to come up with a policy on what constitues "FlexSpin2" then.
That's bad.
Having only a Proptool/Spin will greatly reduce interest in this microcontroller.
I work at a technical university. When I show P2 to my colleagues, the first question they ask me is - "can it be programmed in C?"
Yes, it can, because of Flexprop. If Flexprop was not there, we would not have bought >40 Edges and several Evals for our project.
Parallax should support Flexprop too. While Propeller Tool is good, it is spin only tool and there is limited count of microcontroller programmers who want to learn yet another language when they can simply buy something else, C programmable instead.
Thanks for the feedback, Everyone.
I think I am going to put @variable back to quickly returning the 20-bit hub address, but with the top 12 bits cleared using 'zerox x,#11'. That will add one instruction to what we used to have.
Then, I am going to put the newer functionality into ^@variable. Also, I will get rid of FIELD[ptr] and use ^[ptr] instead.
Thank you all for working in the sausage factory.
We do appreciate Eric's Flexprop tool, by the way.
I looked into these existing file systems for micro controllers and they were just way too complicated. I've got the critical issues all ironed out and our file system will be very compact and simple.
Wouldn't they already be clear if VBASE/PBASE have cleared top bits? Are there any situations where they wouldn't be? Method pointers? It'd probably be more efficient to make sure the base pointers are in range in any situation where they might not be.
I need to check, but there could at least be roll over effects from indexing.
Hmm, if you're indexing out of bounds (
@something[1_000_000]
), I think that's programmer's fault and returning an overflown address is the result i'd expect. Then again, Spin1 clears it (and flexspin (P1 bytecode backend aside) doesn't, now that I think about it. That difference is currently documented for @@ operator only... PR submitted)Thanks Chip, I was thinking about this thread yesterday but didn't want to complicate it more by responding with my opinions, yet this was the actual change I was hoping for. Prior to reading this I didn't realize that doing @variable could potentially leave garbage in the top 12 bits. For address comparisons to be able to find differences in addresses between variables it is important that these top bits remain fixed so ensuring they are zero is ideal.
When you have new features to put into SPIN, then using additional operators is probably going to more amenable than changing the behavior of existing code. Doing that would upset the apple cart too much. It's tricky to redefine a language that is already released.
I'm probably not the only one who was still thinking about this after the Zoom discussion yesterday, As I understand the enhancement, it's an index-able pointer to some arbitrary, predefined, number of bits in a packed array of these bit fields.
I decided that, given a choice, I'd prefer the keyword "ptrp[]" - which can be read as "pointer to packed".
Thanks for suggesting that. I like that because it's very short and relatable to its function, as you suggested. At the same time, I'm also hesitant about it because it appears to represent a specific existing entity, like the PTRA and PTRB registers. PTRP may also seem to refer to a register for someone learning and browsing the reserved word list or an alphabetical list of features of sorts.
Maybe pptr[] instead? Meaning "packed pointer."
Also, it doesn't have to be an array of arbitrary-sized bit fields... this symbol[] could also be used just to conveniently reference a unique arbitrary-sized bit field at a specific address. So on that note, and considering Chip naturally thought "FIELD"... maybe a combination of his and your ideas: fptr[] to mean "field pointer."
Good point. Using "pptr[]" and reading it as "packed pointer" makes just as much sense to me.
Part of the discussion was that "[single letter]ptr" is something more likely to be used as a user symbol, whereas "ptr[single letter]" is already used for the register symbols.
Of course the patrician option is carrot[]
+1
Hmm, That just happens to break my bitmap driver code I'm currently writing, there it means "pixel pointer". But as it's not released yet I can easily fix that.