I'm really sorry that I didn't put a stop to it. This thread is about xbasic. Maybe the off topic posts can be removed?
I think almost all of the "off topic" posts were at least related to some form of Basic so they weren't all that far off. I don't see any need to remove them although I wasn't the originater of this thread.
Sorry to hear that but I'm curious as to what you mean by "the way the VM executes". Can you explain?
That there are many machine cycles between NATIVE instructions. Perhaps this will change with what you mentioned investigating. I guess that running from hub RAM means that we really don't get the full benefit of inline assembly.
And -- this is just me -- I want to be able to create libraries to help others, but it's not easy in xBasic, other than using high-level xBasic code. This is getting back to a point you made early on: Spin can do what I want and I don't need any special tools or techniques to write specialty drivers (e.g., my WS28xx objects). Like many, I started with BASIC (was a TS-1000 for me). I was an early adopter of the BASIC Stamp 1 which is still in use in the EFX-TEK Prop-1 controller (that we sell a lot of, so I still use PBASIC1 on a near daily basis).
I like computer languages, and I like BASIC. I will keep abreast of xBasic developments so that I can help share code that I've previously developed in Spin/PASM with future xBasic coders.
That there are many machine cycles between NATIVE instructions. Perhaps this will change with what you mentioned investigating. I guess that running from hub RAM means that we really don't get the full benefit of inline assembly.
And -- this is just me -- I want to be able to create libraries to help others, but it's not easy in xBasic, other than using high-level xBasic code. This is getting back to a point you made early on: Spin can do what I want and I don't need any special tools or techniques to write specialty drivers (e.g., my WS28xx objects). Like many, I started with BASIC (was a TS-1000 for me). I was an early adapter of the BASIC Stamp 1 which is still in use in the EFX-TEK Prop-1 controller (that we sell a lot of, so I still use PBASIC1 on a near daily basis).
I like computer languages, and I like BASIC. I will keep abreast of xBasic developments so that I can help share code that I've previously developed in Spin/PASM with future xBasic coders.
Thanks for explaining. Yes, the way the xbasic VM executes NATIVE instructions is far from efficient. You have to remember though that the reason the NATIVE instruction is there at all is to make it possible to had simple low-level functions that access Propeller hardware. I never intended it to be a way to write fast code. Like with Spin, the best way to write code that runs fast is to write it entirely in PASM and load it into another COG. Of course, Spin makes it much easier to do this than xbasic so I'm not surprised that you would choose to use it. It is a nice language especially for the Propeller.
I think the fact that Steve finds xbasic useful makes a strong statement which is why I will continue to to watch developments.
I won't be one of those demanding more libraries, I'm wanting to help others by creating them. At the moment, you could take my WS2812 code and create an xbasic library for it; I cannot.
I think the fact that Steve finds xbasic useful makes a strong statement which is why I will continue to to watch developments.
I won't be one of those demanding more libraries, I'm wanting to help others by creating them. At the moment, you could take my WS2812 code and create an xbasic library for it; I cannot.
That is probably true although I wouldn't do it using the NATIVE bytecode. I'd make a binary blob from your PASM code the way I did when I used it for my Christmas ornament last month. The instructions for how to do that would be pretty easy to write. If my simple little PASM assembler was more complete I guess I could do something simliar to what Spin does and allow you to create that blob from code inside of an xbasic program. Unfortunately, my little assembler is missing lots of features that are in Spin.
That is probably true although I wouldn't do it using the NATIVE bytecode. I'd make a binary blob from your PASM code the way I did when I used it for my Christmas ornament last month. The instructions for how to do that would be pretty easy to write. If my simple little PASM assembler was more complete I guess I could do something simliar to what Spin does and allow you to create that blob from code inside of an xbasic program. Unfortunately, my little assembler is missing lots of features that are in Spin.
I don't think using OpenSpin (or something else) to create the binary blob from SPIN/PASM would be an issue. I think just the instruction you mentioned for hooking a BLOB into xbasic would be a good start. Just like folks have done with PropGCC, an example or two to follow and then anyone wanting to convert a mostly PASM OBEX item to be used with xbasic wouldn't be too painful.
As I said (in one of my deleted posts), the Prop languages are going to live and die based on the quality of items in their libraries (OBEX equivalents) and the ease with which existing OBEX (or other) BLOBs can be passed around. This opens up another can of worms discussed in other threads.
Before I comment further, I probably should play a bit with xbasic.
The instructions for how to do that would be pretty easy to write.
If you do, I will take advantage of them by porting my Spin/PASM libraries. Again, I have EFX-TEK customers that would enjoy xbasic and I want to be able to support them should they choose to "hack" (something we encourage) one of our products.
Sadly, this thread devolved from its topic to the merits of other languages.
I'll second that.
Re XBasic. Like JonnyMac, I'd like to think about porting libraries. Looking at typical obex code, there always seems to be a pasm blob somewhere, and I guess that is just the nature of the propeller - there are lots of cogs so there are lots of pasm blobs to run in those cogs.
But for me, writing in hex is not fun. Sure, it is possible to take a VGA object, turn the pasm into a hex array and paste it back into xBasic. But that doesn't work so well when you want to modify the pasm, or if you are working on the high level language and the pasm at the same time.
Re XBasic. Like JonnyMac, I'd like to think about porting libraries. Looking at typical obex code, there always seems to be a pasm blob somewhere, and I guess that is just the nature of the propeller - there are lots of cogs so there are lots of pasm blobs to run in those cogs.
But for me, writing in hex is not fun. Sure, it is possible to take a VGA object, turn the pasm into a hex array and paste it back into xBasic. But that doesn't work so well when you want to modify the pasm, or if you are working on the high level language and the pasm at the same time.
I'm not sure about the answer to this.
There is a combination of two programs that you can use to automate this process. OpenSpin can compile PASM source code to a binary blob. Then a simple program that I've written called bin2xbasic will convert that binary blob into a .bas file that you can include in your xbasic program. This is essentially the same as one of the ways to make use of PASM code in PropGCC except that there is not currently a tool like SimpleIDE that automates the process for you. You don't have to construct the hex file by hand.
By the way, this is totally independent of the NATIVE bytecode that you can use in an ASM statement. The NATIVE bytecode at least currently is just a simple hack for inserting a few PASM instructions in an otherwise bytecode function.
There is a combination of two programs that you can use to automate this process. OpenSpin can compile PASM source code to a binary blob. Then a simple program that I've written called bin2xbasic will convert that binary blob into a .bas file that you can include in your xbasic program.
That makes things easier.
Ok, can you take it a step further, and leave the pasm code as it was. Just paste the pasm code into the xBasic program. Now (and bear with me here, I'm about to suggest a syntax change), you mark the beginning and end of that code. Given pasm usually starts with DAT, how about the beginning is marked with DAT, and at the end it finishes with DAT END
That makes it pretty easy to search for.
Compiliation now includes a search through the program one line at a time, if DAT is found, open a text file, start saving until DAT end is found, then shell your openspin program and then the bin2xbasic program, then paste the array back into the code.
I'm trying to think of a way of doing this for language purists.
Ok, DAT is not part of the BASIC language. But REM DAT is. So is REM DAT END. So is all the pasm blob if you put REM at the beginning of each line. Now it is fully BASIC compliant.
And, are we allowed to bend a few rules? I'd like to think so I see you are using a C type of of syntax for an array
dim TV_array() = {
0x00b71b00
The BASIC syntax would be to use a DATA statement, but the C syntax is better because it also defines the name of the array to store the data. If we can take the bits of C that are better than Basic, then can we also borrow the multiline block comment syntax of /* .... */
If so then all the pasm blob can be inside a block comment.
So then, the only syntax change you might need to add is block comments.
So - maybe this can be done with two simple changes:
1) add block comments to the xBasic syntax
2) Add an option in the IDE to allow a preprocessor program to run prior to compilation.
If you noticed some of the samplers, that is already being done. What's missing is some integration.
Here's what I propose. In some .bas file you should be able to add something like below.
Then the IDE will look for somecode.spin because of ' include "somecode_spin.bas". Then the IDE will convert PASM found into an array using openspin and bin2xbasic. The compile will fail if somecode_spin.bas is not found. This also means that openspin and bin2xbasic must be in the install package in the same folder as the xbasic compiler.
include "propeller.bas"
include "print.bas"
include "somecode_spin.bas"
def startSomecode
// add start code
end def
I still think it would be useful for David to add the pasm interpreter for generating in-line asm native code for us, but I know David is very busy, and his time of course is his.
If you noticed some of the samplers, that is already being done. What's missing is some integration.
Here's what I propose. In some .bas file you should be able to add something like below.
Then the IDE will look for somecode.spin because of ' include "somecode_spin.bas". Then the IDE will convert PASM found into an array using openspin and bin2xbasic. The compile will fail if somecode_spin.bas is not found. This also means that openspin and bin2xbasic must be in the install package in the same folder as the xbasic compiler.
include "propeller.bas"
include "print.bas"
include "somecode_spin.bas"
def startSomecode
// add start code
end def
I still think it would be useful for David to add the pasm interpreter for generating in-line asm native code for us, but I know David is very busy, and his time of course is his.
David has other ideas too
Hi Steve,
Your idea sounds good. I will look at adding the pasm.c code to xbasic but I'm afraid that this is just the tip of the iceberg. Once the simple PASM assembler is in there people will want it to have all of the features of the Spin PASM assembler and I'm not sure that is worth it for tiny snippets of PASM code. My guess is that the largest sequence of code that I could support is about 16 longs. Beyond that I'd have to go to some sort of LMM execution loop and that won't allow easy porting of stuff from OBEX. I find it funny that people want this inline assembler because Spin has nothing like this. The only way to run PASM is to load it into its own COG. This pretty much like what you're proposing.
By the way, I guess it wouldn't be too hard to make the compiler look for embedded PASM code and push that off to openspin if that would be more convenient than having to put it in a separate "include" file.
If you want to talk about it more, please start a new thread topic. Not trying to be rude of course, we just have a little trouble staying on topic around here. Hope you understand. Thanks.
I just want to work through the steps for the xxx.spin file too a byte array, as it stands right now. I can take a .spin file, like fsrw.spin, do the openspin on it to convert it to fsrw.bin file. Then I would take bin2xbasic and run that to get fsrw.bas. Then I would take the contents of the fsrw.bas file and place them into an array. A couple of questions, any size limit on the spin file that is getting converted? Can I just take the name fsrw.bas and place that in the array as opposed to the contents? Once this is running in a cog how do I get access to the commands to make this thing work within an xBasic program? The only draw back that I see is that if you have to modify a command, then you basically have to go back and rework the code in the spin file, and then do the process all over.
Since I have been just working with the QuickStart board with HUB and HUB settings, would the above conversion work on a C3 with FLASH and RAM settings? What are some of the other drawbacks to this that I am not anticipating? Since speed was mentioned in one of the other posts, would there be any problems with converting FDS.spin and have that work with 115200 BAUD and and above?
Here's what I propose. In some .bas file you should be able to add something like below.
Then the IDE will look for somecode.spin because of ' include "somecode_spin.bas". Then the IDE will convert PASM found into an array using openspin and bin2xbasic. The compile will fail if somecode_spin.bas is not found. This also means that openspin and bin2xbasic must be in the install package in the same folder as the xbasic compiler.
That sounds perfect! A neat and simple solution
So - take a typical Obex object, say a VGA driver, split off the pasm cog code and save it as a new file, put the include for that file at the top of the xbasic program and it now appears as an array. Now, translate the Spin to xBasic (manually, hopefully get quicker as we go). Do a cognew and move that array out to the cog. Talk to the cog in the same way as Spin does, via a block of data where you pass the address of the start of that block when the cog is started.
The cool bit - if the program is run from external memory, each pasm blob saves up to 2k of hub space. With a program running all 8 cogs, this could free up nearly half the Hub ram, compared with the same program running in Spin. (I know C can do that too, but it would be really nifty for Basic to do this as well).
Once this is running in a cog how do I get access to the commands to make this thing work within an xBasic program?
What you need to do is somehow set up whatever PAR parameters that binary blob uses and then when it is running communicate with it via share HUB memory in the same way as the original Spin code does.
This is where we see that it would be very useful if all such PASM code blobs used a common form of PAR parameters and memory sharing. Perhaps using a common "mailbox" layout and signalling protocol. Basically we need a standard "COG Binary Interface" (CBI) definition that all PASM code and high level language implementations could work to. Thus making any binary blob usable in any high level language.
Such a standard does not exist. This idea has been discussed at length on the forum many time times. RossH started a thread about it where he presented a a proposed standard that address all the issues.
Sadly all that effort fell on deaf ears and no such CGI conforming objects exist. (except in Ross's Catalina compiler system).
The problem is that unless one has travelled the long road that you just have to get, to the point where you have this problem, then one does not see the need for such a standard or why one should do the extra work required to adhere to it.
@heater, I've also thought long and hard about the need for a standard, but I came to the opposite conclusion - I don't think you need a standard.
The problem is that objects are so different. Object 1 might only need to send one PAR parameter - a single long is more than enough. Object 2, on the other hand, might send a PAR that points to a memory block that is most of the hub, eg a graphics buffer. How do you write a standard that encompasses these two extremes?
The 'standard', as I see it, exists within each object. So we take an object, say a VGA driver, and it might communicate via 10 longs. The number of longs, and the order they are in, that is the standard. So if that object gets translated to C, or to Basic or to any other language, there is a very good incentive to keep that order the same because then the PASM part doesn't need changing.
That is how I've approached the problem when I've been translating Spin objects.
I think there is also an argument for grouping high level cog interface code together - eg in Spin, put all the routines that talk to the cog in a group just above the DAT section, and don't scatter them in random positions through the code. But that isn't really a standard - it is just writing code in a neater way.
I guess my experience is that I like the abstract idea of a common cog interface, but such a concept doesn't seem to help in a practical sense when I am translating an object line by line to another language. I'd be very interested to see an example of where it would make things simpler.
I just want to work through the steps for the xxx.spin file too a byte array, as it stands right now. I can take a .spin file, like fsrw.spin, do the openspin on it to convert it to fsrw.bin file. Then I would take bin2xbasic and run that to get fsrw.bas. Then I would take the contents of the fsrw.bas file and place them into an array. A couple of questions, any size limit on the spin file that is getting converted? Can I just take the name fsrw.bas and place that in the array as opposed to the contents? Once this is running in a cog how do I get access to the commands to make this thing work within an xBasic program? The only draw back that I see is that if you have to modify a command, then you basically have to go back and rework the code in the spin file, and then do the process all over.
Since I have been just working with the QuickStart board with HUB and HUB settings, would the above conversion work on a C3 with FLASH and RAM settings? What are some of the other drawbacks to this that I am not anticipating? Since speed was mentioned in one of the other posts, would there be any problems with converting FDS.spin and have that work with 115200 BAUD and and above?
Ray
You don't need to take the contents of fsrw.bas and put them into any array. If you look at the file generated by bin2xbasic you'll find that it is already an array. All you need to do is include it in your xbasic program with a standard include statement:
include "fsrw.bas"
After that you can use the symbol fsrw_array as an argument to cognew.
How do you write a standard that encompasses these two extremes?
Similar things have been done many times.
Consider the problem of calling Pascal functions from C functions in the same program. Or vice versa. Or calling C from Python. In these cases we might have a variable number of parameters, they might have different types, they may be values or pointers to values, or pointers to memory areas, or arrays. Or strings, And so on.
To handle this kind of problem people have defined "Application Binary Interfaces", ABI's, that specify what parameters can be and how they are passed in to function, on the stack, in registers, a bit of both perhaps. They also do the same for how return values are returned.
The point of the ABI is that if your language conforms to it then modules compiled with it can be used from other conforming languages.
Of course the programmer has to define how many and what his parameters are and how to use them for each function in his source code, which may all be different, but the underlying mechanism is the same.
Conceptually using PASM code in COGs from some other language is the same problem and could have a similar ABI solution. The ACI, Application Cog Interface spec.
I just downloaded and installed xbasic 0_2_2 on my laptop. After it came up, I plugged in my PropBOE and while windows went through the USB setup, xbasic patiently waited. When Windows was done, I refreshed the ports and my PropBOE showed up on COM8. Fibo loaded and ran just fine.
Cudos to Steve. It's really nice to be able to code in C, Spin and now basic all from a consistent IDE! Thanks for all your work on that!
Now I need to play and see what's to like or not like about xbasic! (Jeez, I can't remember the last time I programmed in any form of BASIC!)
@mindrobots. Glad it works. You should be able to connect/disconnect the USB serial port (Quickstart, etc....) and the serial port box will update automatically.
I'll be adding something like the USB port detection to SimpleIDE - Jeff has mentioned some of the caveats of this to me already. For example, if you are using the terminal or loading, there may be some issues if you disconnect the port.
@Heater & @Dr_Acula .... A standard must must service all users and uses. In the case of PASM, it must be simple and flexible for embedded programs.
The only standard required for using PASM blobs is that the PASM must stand alone without being manipulated from the Spin code. That may require a mailbox for passing information between the language user code doing cognew and the COG code. The only mailbox standard is that a pointer is given to PAR. The rest is up to the PASM module and user code. There is no need for a registry of services unless you are considering some kind of an operating system - which is not required for an embedded program.
I am putting the tools together to do my first conversion of a spin file to build something xBasic likes. I downloaded openspin, and I went looking for bin2xbasic, the only thing that I found was bin2xbasic.c, so, I am supposed to compile that to get an .exe file? If so, what C compiler should I use too get the best results?
The first spin program that I am going to try is Extended_FDS.spin only because, if I remember correctly, it handles strings. Now I know that I have to have FDS.spin also, hopefully I will not run into any problems with openspin compiling it down to a bin file.
I was looking at the coginit example and it has "cognew(@blink_array, @count)". Since I am probably going to end up with a name like Efds.bas, and if all I have to work with is - include "Efds.bas", what does the cognew(@xxxx, @xxxx) supposed to look like, what is the naming convention? This is a very involved procedure to get that spin file to run in xBasic.
I checked the build size and it seems that adding propeller.bas to another include file that exists in a project using propeller.bas does not bloat the code. Good; I'm moving my essential IO control code out of propeller.bas to prevent losing that code on a future update.
I may have found a "gotcha" in PASM.EXE. Here's the code I attempt to compile:
mov t4, #1
shl t4, tos
andn dira, t4
test t4, ina wc
mov tos, #0
muxc tos, #1
It doesn't like the code -- which is odd as this code can be found in a few of the functions in propeller.bas. Here's the complaint:
error: expecting effects
line 6
muxc tos, #1
^
If I add the if_c condition at the start of the line it works, and gives me the same native opcode as I found in some functions in propeller.bas.
def read_pin(pin)
asm
dup // make space for the return value
lref 0 // pin --> tos
native 0xa0fc0801 // mov t4, #1
native 0x2cbc0805 // shl t4, tos
native 0x64bfec04 // andn dira, t4
native 0x613c09f2 // test t4, ina wc
native 0xa0fc0a01 // mov tos, #0
native 0x70fc0a01 // if_c muxc tos, #1
returnx
end asm
end def
Isn't the idea of muxc that one doesn't have to use a condition with it?
I am putting the tools together to do my first conversion of a spin file to build something xBasic likes. I downloaded openspin, and I went looking for bin2xbasic, the only thing that I found was bin2xbasic.c, so, I am supposed to compile that to get an .exe file? If so, what C compiler should I use too get the best results?
The first spin program that I am going to try is Extended_FDS.spin only because, if I remember correctly, it handles strings. Now I know that I have to have FDS.spin also, hopefully I will not run into any problems with openspin compiling it down to a bin file.
I was looking at the coginit example and it has "cognew(@blink_array, @count)". Since I am probably going to end up with a name like Efds.bas, and if all I have to work with is - include "Efds.bas", what does the cognew(@xxxx, @xxxx) supposed to look like, what is the naming convention? This is a very involved procedure to get that spin file to run in xBasic.
So I tried the conversion thing and I am not having any luck. Below I did the Extended_FDS.spin, I named it Efds.bas. As everybody knows FDS has a Start(xx,xx,xx,xxx) command and that is the first thing that I tried, it comes back with an error. I also had a tools.spin program which basically contains high(),low(),wait(),waitMS() commands, and I get the same error as I do with the Efds call out. Now I am not even sure where the debugging process should start for this. Any ideas?
Ray
error:Expecting '<EOL>',found "("
line 9
Efds_Start(31,30,0,115200)
^
REM ===========
REM efdsT1.bas
REM ===========
include "propeller.bas"
include "print.bas"
include "tools.bas"
include "Efds.bas"
Efds_Start(31,30,0,115200)
print "Hello"
tools_high(17)
So I tried the conversion thing and I am not having any luck. Below I did the Extended_FDS.spin, I named it Efds.bas. As everybody knows FDS has a Start(xx,xx,xx,xxx) command and that is the first thing that I tried, it comes back with an error. I also had a tools.spin program which basically contains high(),low(),wait(),waitMS() commands, and I get the same error as I do with the Efds call out. Now I am not even sure where the debugging process should start for this. Any ideas?
Ray
REM ===========
REM efdsT1.bas
REM ===========
include "propeller.bas"
include "print.bas"
include "tools.bas"
include "Efds.bas"
Efds_Start(31,30,0,115200)
print "Hello"
tools_high(17)
What is in "Efds.bas"? Is it the output from bin2xbasic? If so, it won't work. That will only contain the PASM blob from the spin code. You'll have to recode all of the functions that were written in Spin in xbasic before you'll be able to call any of them. Take a look at samples/TvDemo in the xbasic directory.
Yup, samples/TvDemo is what I am looking at for an example. Below is a snippet from TvDemo.bas, in there it contains " TvText_start(12)" which is similar to what you would need for the Efds.bas. I am not sure as to what you are trying to point me too. I looked at the accompanying TvText.spin, which I assume you
used the same method to convert, and the file looks straight forward to me. And the Extended_FDSerial.spin looks just as straight forward, again I am not sure where it is that I am going wrong.
Ray
REM ==================================================================
REM xbasic TvDemo.bas
REM ==================================================================
include "math.bas"
include "print.bas"
include "propeller.bas"
include "TvText.bas"
REM ------------------------------------------------------------------
REM startup program
main
REM ------------------------------------------------------------------
REM main function
REM
def main
TvText_start(12)
do
test
loop
end def
Comments
I'm really sorry that I didn't try to put a stop to it. This thread is about xbasic. Maybe the off topic posts can be removed?
That there are many machine cycles between NATIVE instructions. Perhaps this will change with what you mentioned investigating. I guess that running from hub RAM means that we really don't get the full benefit of inline assembly.
And -- this is just me -- I want to be able to create libraries to help others, but it's not easy in xBasic, other than using high-level xBasic code. This is getting back to a point you made early on: Spin can do what I want and I don't need any special tools or techniques to write specialty drivers (e.g., my WS28xx objects). Like many, I started with BASIC (was a TS-1000 for me). I was an early adopter of the BASIC Stamp 1 which is still in use in the EFX-TEK Prop-1 controller (that we sell a lot of, so I still use PBASIC1 on a near daily basis).
I like computer languages, and I like BASIC. I will keep abreast of xBasic developments so that I can help share code that I've previously developed in Spin/PASM with future xBasic coders.
I won't be one of those demanding more libraries, I'm wanting to help others by creating them. At the moment, you could take my WS2812 code and create an xbasic library for it; I cannot.
I don't think using OpenSpin (or something else) to create the binary blob from SPIN/PASM would be an issue. I think just the instruction you mentioned for hooking a BLOB into xbasic would be a good start. Just like folks have done with PropGCC, an example or two to follow and then anyone wanting to convert a mostly PASM OBEX item to be used with xbasic wouldn't be too painful.
As I said (in one of my deleted posts), the Prop languages are going to live and die based on the quality of items in their libraries (OBEX equivalents) and the ease with which existing OBEX (or other) BLOBs can be passed around. This opens up another can of worms discussed in other threads.
Before I comment further, I probably should play a bit with xbasic.
If you do, I will take advantage of them by porting my Spin/PASM libraries. Again, I have EFX-TEK customers that would enjoy xbasic and I want to be able to support them should they choose to "hack" (something we encourage) one of our products.
I'll second that.
Re XBasic. Like JonnyMac, I'd like to think about porting libraries. Looking at typical obex code, there always seems to be a pasm blob somewhere, and I guess that is just the nature of the propeller - there are lots of cogs so there are lots of pasm blobs to run in those cogs.
But for me, writing in hex is not fun. Sure, it is possible to take a VGA object, turn the pasm into a hex array and paste it back into xBasic. But that doesn't work so well when you want to modify the pasm, or if you are working on the high level language and the pasm at the same time.
I'm not sure about the answer to this.
By the way, this is totally independent of the NATIVE bytecode that you can use in an ASM statement. The NATIVE bytecode at least currently is just a simple hack for inserting a few PASM instructions in an otherwise bytecode function.
Here are the steps required: The file TV.bas will begin like this: You can include this in your xbasic program and then pass TV_array to cognew to load it into a COG and start it running.
That makes things easier.
Ok, can you take it a step further, and leave the pasm code as it was. Just paste the pasm code into the xBasic program. Now (and bear with me here, I'm about to suggest a syntax change), you mark the beginning and end of that code. Given pasm usually starts with DAT, how about the beginning is marked with DAT, and at the end it finishes with DAT END
That makes it pretty easy to search for.
Compiliation now includes a search through the program one line at a time, if DAT is found, open a text file, start saving until DAT end is found, then shell your openspin program and then the bin2xbasic program, then paste the array back into the code.
I'm trying to think of a way of doing this for language purists.
Ok, DAT is not part of the BASIC language. But REM DAT is. So is REM DAT END. So is all the pasm blob if you put REM at the beginning of each line. Now it is fully BASIC compliant.
And, are we allowed to bend a few rules? I'd like to think so I see you are using a C type of of syntax for an array
The BASIC syntax would be to use a DATA statement, but the C syntax is better because it also defines the name of the array to store the data. If we can take the bits of C that are better than Basic, then can we also borrow the multiline block comment syntax of /* .... */
If so then all the pasm blob can be inside a block comment.
So then, the only syntax change you might need to add is block comments.
So - maybe this can be done with two simple changes:
1) add block comments to the xBasic syntax
2) Add an option in the IDE to allow a preprocessor program to run prior to compilation.
If you noticed some of the samplers, that is already being done. What's missing is some integration.
Here's what I propose. In some .bas file you should be able to add something like below.
Then the IDE will look for somecode.spin because of ' include "somecode_spin.bas". Then the IDE will convert PASM found into an array using openspin and bin2xbasic. The compile will fail if somecode_spin.bas is not found. This also means that openspin and bin2xbasic must be in the install package in the same folder as the xbasic compiler.
David has other ideas too
Your idea sounds good. I will look at adding the pasm.c code to xbasic but I'm afraid that this is just the tip of the iceberg. Once the simple PASM assembler is in there people will want it to have all of the features of the Spin PASM assembler and I'm not sure that is worth it for tiny snippets of PASM code. My guess is that the largest sequence of code that I could support is about 16 longs. Beyond that I'd have to go to some sort of LMM execution loop and that won't allow easy porting of stuff from OBEX. I find it funny that people want this inline assembler because Spin has nothing like this. The only way to run PASM is to load it into its own COG. This pretty much like what you're proposing.
By the way, I guess it wouldn't be too hard to make the compiler look for embedded PASM code and push that off to openspin if that would be more convenient than having to put it in a separate "include" file.
Went to PropellerC Arduino Code : http://code.google.com/p/lib-propelleruino , seems to be empty project.
Would love to run my AVR on the prop.
You'll have to use the git tool to grab the code. Check this link to see what's there: https://code.google.com/p/lib-propelleruino/source/browse/#git%2FlibPropelleruino
If you want to talk about it more, please start a new thread topic. Not trying to be rude of course, we just have a little trouble staying on topic around here. Hope you understand. Thanks.
Since I have been just working with the QuickStart board with HUB and HUB settings, would the above conversion work on a C3 with FLASH and RAM settings? What are some of the other drawbacks to this that I am not anticipating? Since speed was mentioned in one of the other posts, would there be any problems with converting FDS.spin and have that work with 115200 BAUD and and above?
Ray
That sounds perfect! A neat and simple solution
So - take a typical Obex object, say a VGA driver, split off the pasm cog code and save it as a new file, put the include for that file at the top of the xbasic program and it now appears as an array. Now, translate the Spin to xBasic (manually, hopefully get quicker as we go). Do a cognew and move that array out to the cog. Talk to the cog in the same way as Spin does, via a block of data where you pass the address of the start of that block when the cog is started.
The cool bit - if the program is run from external memory, each pasm blob saves up to 2k of hub space. With a program running all 8 cogs, this could free up nearly half the Hub ram, compared with the same program running in Spin. (I know C can do that too, but it would be really nifty for Basic to do this as well).
Neat solution - thanks jazzed.
What you need to do is somehow set up whatever PAR parameters that binary blob uses and then when it is running communicate with it via share HUB memory in the same way as the original Spin code does.
This is where we see that it would be very useful if all such PASM code blobs used a common form of PAR parameters and memory sharing. Perhaps using a common "mailbox" layout and signalling protocol. Basically we need a standard "COG Binary Interface" (CBI) definition that all PASM code and high level language implementations could work to. Thus making any binary blob usable in any high level language.
Such a standard does not exist. This idea has been discussed at length on the forum many time times. RossH started a thread about it where he presented a a proposed standard that address all the issues.
Sadly all that effort fell on deaf ears and no such CGI conforming objects exist. (except in Ross's Catalina compiler system).
The problem is that unless one has travelled the long road that you just have to get, to the point where you have this problem, then one does not see the need for such a standard or why one should do the extra work required to adhere to it.
The problem is that objects are so different. Object 1 might only need to send one PAR parameter - a single long is more than enough. Object 2, on the other hand, might send a PAR that points to a memory block that is most of the hub, eg a graphics buffer. How do you write a standard that encompasses these two extremes?
The 'standard', as I see it, exists within each object. So we take an object, say a VGA driver, and it might communicate via 10 longs. The number of longs, and the order they are in, that is the standard. So if that object gets translated to C, or to Basic or to any other language, there is a very good incentive to keep that order the same because then the PASM part doesn't need changing.
That is how I've approached the problem when I've been translating Spin objects.
I think there is also an argument for grouping high level cog interface code together - eg in Spin, put all the routines that talk to the cog in a group just above the DAT section, and don't scatter them in random positions through the code. But that isn't really a standard - it is just writing code in a neater way.
I guess my experience is that I like the abstract idea of a common cog interface, but such a concept doesn't seem to help in a practical sense when I am translating an object line by line to another language. I'd be very interested to see an example of where it would make things simpler.
Similar things have been done many times.
Consider the problem of calling Pascal functions from C functions in the same program. Or vice versa. Or calling C from Python. In these cases we might have a variable number of parameters, they might have different types, they may be values or pointers to values, or pointers to memory areas, or arrays. Or strings, And so on.
To handle this kind of problem people have defined "Application Binary Interfaces", ABI's, that specify what parameters can be and how they are passed in to function, on the stack, in registers, a bit of both perhaps. They also do the same for how return values are returned.
The point of the ABI is that if your language conforms to it then modules compiled with it can be used from other conforming languages.
Of course the programmer has to define how many and what his parameters are and how to use them for each function in his source code, which may all be different, but the underlying mechanism is the same.
Conceptually using PASM code in COGs from some other language is the same problem and could have a similar ABI solution. The ACI, Application Cog Interface spec.
Cudos to Steve. It's really nice to be able to code in C, Spin and now basic all from a consistent IDE! Thanks for all your work on that!
Now I need to play and see what's to like or not like about xbasic! (Jeez, I can't remember the last time I programmed in any form of BASIC!)
I'll be adding something like the USB port detection to SimpleIDE - Jeff has mentioned some of the caveats of this to me already. For example, if you are using the terminal or loading, there may be some issues if you disconnect the port.
@Heater & @Dr_Acula .... A standard must must service all users and uses. In the case of PASM, it must be simple and flexible for embedded programs.
The only standard required for using PASM blobs is that the PASM must stand alone without being manipulated from the Spin code. That may require a mailbox for passing information between the language user code doing cognew and the COG code. The only mailbox standard is that a pointer is given to PAR. The rest is up to the PASM module and user code. There is no need for a registry of services unless you are considering some kind of an operating system - which is not required for an embedded program.
The first spin program that I am going to try is Extended_FDS.spin only because, if I remember correctly, it handles strings. Now I know that I have to have FDS.spin also, hopefully I will not run into any problems with openspin compiling it down to a bin file.
I was looking at the coginit example and it has "cognew(@blink_array, @count)". Since I am probably going to end up with a name like Efds.bas, and if all I have to work with is - include "Efds.bas", what does the cognew(@xxxx, @xxxx) supposed to look like, what is the naming convention? This is a very involved procedure to get that spin file to run in xBasic.
Ray
I may have found a "gotcha" in PASM.EXE. Here's the code I attempt to compile:
It doesn't like the code -- which is odd as this code can be found in a few of the functions in propeller.bas. Here's the complaint:
If I add the if_c condition at the start of the line it works, and gives me the same native opcode as I found in some functions in propeller.bas.
Isn't the idea of muxc that one doesn't have to use a condition with it?
As for cognew (not in external memory mode), blink_array is the output of bin2xbasic.exe, and count should just be a dim variable.
Ray
What is in "Efds.bas"? Is it the output from bin2xbasic? If so, it won't work. That will only contain the PASM blob from the spin code. You'll have to recode all of the functions that were written in Spin in xbasic before you'll be able to call any of them. Take a look at samples/TvDemo in the xbasic directory.
used the same method to convert, and the file looks straight forward to me. And the Extended_FDSerial.spin looks just as straight forward, again I am not sure where it is that I am going wrong.
Ray