Out of curiosity I ran the rand program three times and got the results below. Comparing the print out, it seems like it keeps producing the same set of random numbers, so does it really need to have some kind of random seed number every time the rand is run? It also looks like there is a lot of negative values that are produced, which would maybe present an unusual problem down the road?
Ray
Am I getting anything.
-1714832263
-368852369
653136079
-1337015847
-162232845
-312426689
-302024013
-538639081
-639205643
-541828828
Am I getting anything.
I tried the code below and I was expecting to see the numbers 1 - 10 with a random number that was selected, but instead it seems like it goes into some inner loop and you have to hit the reset button to get the program to stop.
Ray
REM ===========
REM testQS3.bas
REM ===========
include "propeller.bas"
include "print.bas"
include "extra.bas"
include "rand.bas"
waitMS(300)
print "Am I getting anything."
x = 0
z = 0
do
x=x+1
z=rand
print z
print x
loop until x = 10
/*
for n = 1 to 10
print rand
next n
*/
END
That worked. Why doesn't it work when you have the def in the program itself? Is there some way that you could narrow down the choice for rand? I was thinking if you could narrow rand selection to, lets say, numbers between16 and 23, then have that particular pin number go high and low, in a random fashion, that just might be an interesting curio with your QS board LEDs blinking in a random fashion.
Ray
It should work if you have the def in the program itself. Your post didn't show that though so I thought you were assuming that rand was now a built-in function. If you post your entire program including the embedded rand function I'll look at it to see why it didn't work for you.
Out of curiosity I ran the rand program three times and got the results below. Comparing the print out, it seems like it keeps producing the same set of random numbers, so does it really need to have some kind of random seed number every time the rand is run? It also looks like there is a lot of negative values that are produced, which would maybe present an unusual problem down the road?
Ray
Yes, it will produce the same set of numbers every time unless you seed the random number generator. You could try something like srand(cnt).
I tried the code below and I was expecting to see the numbers 1 - 10 with a random number that was selected, but instead it seems like it goes into some inner loop and you have to hit the reset button to get the program to stop.
Ray
REM ===========
REM testQS3.bas
REM ===========
include "propeller.bas"
include "print.bas"
include "extra.bas"
include "rand.bas"
waitMS(300)
print "Am I getting anything."
x = 0
z = 0
do
x=x+1
z=rand
print z
print x
loop until x = 10
/*
for n = 1 to 10
print rand
next n
*/
END
This code looks okay. What output are you getting? Unfortunately, I won't be able to try this until much later tonight. It's the middle of my work day now. Sorry!
Actually, I know what the problem is. You're probably using my translation of Heater's random number function. The problem is that it uses the variable "x" itself and that is messing up your loop. The code in rand.bas should probably be changed so that those global variables are called something like "rand_x", "rand_y", etc to avoid conflicting with user variables. This is one problem with xbasic. There is no way to declare module-level globals. Spin of course doesn't have this problem because variables within an object are always local to the object.
I reverted back to IDE -20, the new IDE 0.2.1, is having trouble with the COM ports on all the different boards that I have.
What boards Ray? Which ones were connected when you were having trouble?
You need to help me here. I can go back to the old methodology, but I would rather understand what the problem is.
One thing that really gets in the way is unconnected Bluetooth serial ports. I've tested with them and it takes a while to go through it, but it does work. It's probably best to delete Bluetooth serial ports unless they are connected or heavily used.
To itemize for IDE 0.2.1:
QuickStart Board gets COM17, when you start the IDE it finds COM17, but when you do a run, I get "error:opening serial port". This occurs in a random fashion.
I thought it was just my QS board, so I tried my DNA-RTC Board, gets COM17 and the same thing occurs, "error:opening serial port", in a random fashion. The only thing that I didn't try was to hook up too a different USB port and get different COMxx. I guess maybe I gave up to soon.
To itemize for IDE 0.2.1:
QuickStart Board gets COM17, when you start the IDE it finds COM17, but when you do a run, I get "error:opening serial port". This occurs in a random fashion.
I thought it was just my QS board, so I tried my DNA-RTC Board, gets COM17 and the same thing occurs, "error:opening serial port", in a random fashion. The only thing that I didn't try was to hook up too a different USB port and get different COMxx. I guess maybe I gave up to soon.
Yes, its also a random occurrence, the program just freezes up, and I have to use the Task Manager to shut it down. This problem I have not been able to isolate, not sure what is causing it. One instance I do remember, I tried to run a program without selecting a COM port, that froze up the session, the other instance was not associated with that. So, it is random freeze up the program. Hope this helps.
To itemize for IDE 0.2.1:
QuickStart Board gets COM17, when you start the IDE it finds COM17, but when you do a run, I get "error:opening serial port". This occurs in a random fashion.
I thought it was just my QS board, so I tried my DNA-RTC Board, gets COM17 and the same thing occurs, "error:opening serial port", in a random fashion. The only thing that I didn't try was to hook up too a different USB port and get different COMxx. I guess maybe I gave up to soon.
Ray
This seems strange. Each board with its own FTDI chip should show up as a different com port (at least that is what I see on my Win7 system. I'm not sure how a QS and a DNA-RTC come up with the same COM port.
Could you have something else on your PC that is COM17 and your Propeller boards are showing up as different/higher numbers? The IDE may just be choosing the first (or for some reason REALLY like COM17) regardless of where teh Propeller really is.
I've uploaded a new version that removes the troublesome Propeller-Auto-ID stuff. Find it here.
I did find a way to detect USB port changes. So now you can plug/unplug your board and the serial port list should change accordingly.
Also, I've fixed the 3900 Bytes Total problem (if you noticed that). It now reports the size of the program + about 2000 bytes for the VM. The jury is still out on whether or not the VM bytes gets reclaimed or not ....
I just installed IDE 0.2.2, and so far the COM problem has been resolved, working as expected. I have not run into the program freeze yet, hopefully that also got nixed.
It should work if you have the def in the program itself.
The program below works when you have the defs at the end of the program and dim related stuff at the top. I guess it makes a difference when you place the dim related stuff at the end with the devs.
Ray
REM ===========
REM testQS3.bas
REM ===========
include "propeller.bas"
include "print.bas"
include "extra.bas"
//include "rand.bas"
dim x = 123456789
dim y = 234567891
dim z = 345678912
dim w = 456789123
dim c = 0
waitMS(300)
print "Am I getting anything."
g = 0
do
h=rand
print g // the do loop
print h // random number
g=g+1 // increment the do loop
loop until g = 10
/*
for n = 1 to 10
print rand
next n
*/
END
REM ====================
/*
dim x = 123456789
dim y = 234567891
dim z = 345678912
dim w = 456789123
dim c = 0 */
//////////
def srand(n)
x = y
y = z
z = w
w = n
end def
//////////
def rand
dim t
y = y ^ (y << 5)
y = y ^ (y >> 7)
y = y ^ (y << 22)
t = z + w + c
z = w
c = t < 0
w = t & 2147483647
x = x + 1411392427
return x + y + w
end def
REM ====================
I just installed IDE 0.2.2, and so far the COM problem has been resolved, working as expected. I have not run into the program freeze yet, hopefully that also got nixed.
The program below works when you have the defs at the end of the program and dim related stuff at the top. I guess it makes a difference when you place the dim related stuff at the end with the devs.
Yes, it makes a difference.
Generally speaking a module should look like this:
include
dim
def
code not inside of def
Look at the samples\GameBaby code.
rem =================================================
rem include files
rem
include "GbLCD.bas"
include "GbI2C.bas"
include "GbGUI.bas"
include "lastcog.bas"
include "GbBattery.bas"
include "print.bas"
include "propeller.bas"
include "string.bas"
rem =================================================
rem main program code here
rem don't mix variables inside of code blocks.
rem =================================================
def startup
dim x,y,m,n
dim buttons
REM ---------------------------------------------
REM send user startup message and show our cogid
REM
print "Starting Gamebaby... ";
cog = cogid
print "COGID "; cog
REM ---------------------------------------------
REM startup the LCD and clear screen to background color.
REM
GbLCD_start
GbLCD_clear(GbLCD_BLUE)
REM ---------------------------------------------
REM startup the I2C devices including the button monitor.
REM
GbI2C_start
REM ---------------------------------------------
REM show last available cog number
REM
print "LastCog "; lastcog
REM ---------------------------------------------
REM Make a panel
REM
GbGUI_panel_parms(GbLCD_WHITEST_GRAY,3,15,GbLCD_MAXX-8,GbLCD_MAXY-21,0)
REM ---------------------------------------------
REM Make a title and show battery
REM
GbLCD_setBgColor(GbLCD_BLUE)
GbGUI_textColor(GbLCD_YELLOW)
//GbGUI_Label("GameBaby",5,4)
GbGUI_3Dbutton("OK",GbLCD_MAXX-40,GbLCD_MAXY-35)
do
GbBattery_show(GbLCD_MAXX-20,3,GbLCD_YELLOW, GbLCD_BLUE)
waitcnt(clkfreq/4+cnt)
GbLCD_setBgColor(GbLCD_BLUE)
GbLCD_setFgColor(GbLCD_YELLOW)
GbLCD_printXY(" GameBaby! ",0,0)
x = 4 //GbLCD_getx
y = 2 //GbLCD_gety
buttons = GbButtons_buttons
if oldbut <> buttons then
oldbut = buttons
GbLCD_setTextXY(x,y)
GbLCD_bin(buttons,9)
end if
//GbBattery_showVoltage
GbLCD_setTextXY(28,32)
for n = 0 to 4
GbLCD_hex(GbI2C_accel_readReg(n),2)
next n
GbLCD_setTextXY(28,33)
for n = 0 to 8
GbLCD_hex(GbI2C_ee_readByte(n),2)
next n
GbLCD_setTextXY(28,34)
GbI2C_rtc_readRegs
for n = 0 to 4
GbLCD_hex(GbI2C_rtc_getReg(n),2)
next n
waitcnt(clkfreq/10+cnt)
loop
end def
rem =================================================
rem call startup here
rem =================================================
startup
rem =================================================
rem end of file
rem =================================================
Generally speaking a module should look like this:
include
dim
def
code not inside of def
This is a bit troublesome. If it does indeed make a difference then the xbasic compiler should warn if you get the order wrong. If it isn't going to warn then it should work correctly no matter what order you put things in.
Will I be hauled out of here and summarily executed for asking if there are other multi-processor chips that have something along the lines of a MIL Spec. or MIL Standard that I can find software for?
I now know how Rip VanWinkle must have felt I've been away for sooooo long.
Will I find out early in my products life that the software has become just another oddity mulled over by old geezers like myself.
Will I be hauled out of here and summarily executed for asking if there are other multi-processor chips that have something along the lines of a MIL Spec. or MIL Standard that I can find software for?
I now know how Rip VanWinkle must have felt I've been away for sooooo long.
Will I find out early in my products life that the software has become just another oddity mulled over by old geezers like myself.
It is not clear what you are asking, but it does not sound like Xbasic ?
If you want to see if there are other Multi Core processors our there, the answer is of course, yes.
A new thread in General Discussion, with specifics of which MIL specs you seek, and rough scale of processor you need could get answers.
Generally speaking a module should look like this:
include
dim
def
code not inside of def
I thought that xBasic is a "freestyle" programming language, meaning it has very little, if any structure, like maybe Spin or C languages. The example below runs as expected, so at this point, only dim declarations would have to to be in the top of the code. I, personally, like to see some structure in a program, for the simple reason you can almost be able to see which way the program is going. But I also like the freestyle format, because you can just about put in code as it comes to mind, without structural constraints, and you are almost certain that it will work. This style is probably good for new users since they are not bogged down with too many constraints of programming style, in fact this could be perfect for Arduino users willing to try out the Propeller. This just might be the answer for attracting some Basic Stamp users also.
Ray
REM ==========
REM testQS4.bas
REM ==========
print "Hello, World!"
high(17)
waitMS(3000)
low(17)
END
include "print.bas"
include "extra.bas"
include "propeller.bas"
I found the post that included the source for the virtual machine and after looking through it, made a change to my high() and low() subroutines. Now they work. The key was using t4 to hold my mask as t1 gets a lot of use in the VM code.
def high(pin)
asm
lref 0 // pin --> tos
native 0xa0fc0801 // mov t4, #1
native 0x2cbc0805 // shl t4, tos
native 0x68bfe804 // or outa, t4
native 0x68bfec04 // or dira, t4
returnx
end asm
end def
def low(pin)
asm
lref 0 // pin --> tos
native 0xa0fc0801 // mov t4, #1
native 0x2cbc0805 // shl t4, tos
native 0x64bfe804 // andn outa, t4
native 0x68bfec04 // or dira, t4
returnx
end asm
end def
I added these to my local copy of propeller.bas, though that could become problematic on updating the IDE. As an experiment, I timed these versions versus using plain xbasic:
def high(pin)
outa = outa | (1 << pin)
dira = dira | (1 << pin)
end def
The xbasic code -- when the subroutine is in a library -- takes 4292 ticks; the inline native code takes 2432 ticks.
I found the post that included the source for the virtual machine and after looking through it, made a change to my high() and low() subroutines. Now they work. The key was using t4 to hold my mask as t1 gets a lot of use in the VM code.
def high(pin)
asm
lref 0 // pin --> tos
native 0xa0fc0801 // mov t4, #1
native 0x2cbc0805 // shl t4, tos
native 0x68bfe804 // or outa, t4
native 0x68bfec04 // or dira, t4
returnx
end asm
end def
def low(pin)
asm
lref 0 // pin --> tos
native 0xa0fc0801 // mov t4, #1
native 0x2cbc0805 // shl t4, tos
native 0x64bfe804 // andn outa, t4
native 0x68bfec04 // or dira, t4
returnx
end asm
end def
I added these to my local copy of propeller.bas, though that could become problematic on updating the IDE. As an experiment, I timed these versions versus using plain xbasic:
def high(pin)
outa = outa | (1 << pin)
dira = dira | (1 << pin)
end def
The xbasic code -- when the subroutine is in a library -- takes 5136 ticks (64us); the inline native code takes 3376 ticks (42us).
I'm wondering if I should allow NATIVE to accept more than one instruction at a time and have them all run in sequence so you don't have the overhead of the bytecode intepreter loop between NATIVE instructions. I can look at that when I look at adding symbolic PASM support based on the code for pasm.exe.
David, is xbasic running a virtual machine inside a virtual machine? ie your instruction list, and then underneath that, LMM?
No it interprets the bytecodes directly in PASM code. However, the NATIVE bytecode causes a single Propeller instruction to be executed sort of like the way LMM works.
No it interprets the bytecodes directly in PASM code. However, the NATIVE bytecode causes a single Propeller instruction to be executed sort of like the way LMM works.
So what is the speed between each of the NATIVE lines above ?
Your idea of allowing 'NATIVE to accept more than one instruction at a time' would drop that inter-line overhead to zero ?
I have my doubts because it seems that no one uses any of the Propeller languages much other than Spin, Forth, and C.
I have been wondering why this is, especially the history of parallax and the Basic language. Not all the options for Basic on the propeller tick all the boxes. I've used some crazy ones in the past, like running versions of Basic inside a Z80 emulation on the propeller, and converting Basic to C. Quick wish list would be an IDE, external memory support for large programs and ability to reasonably easily translate Obex spin code. Xbasic does seem to tick all the boxes.
I'm not sure how your Native mode works, but it seems very clever. Where you say it is similar to LMM, are you fetching longs from a cache driver, and then allowing the VM to process those longs one at a time when you use Native mode?
Thinking about inline assembly, there are two types of assembly - Native assembly, and blocks of assembly meant for loading into a cog. I am reaching back into the dark mists of time here with my memory banks, but this was an issue with the catalina program at one stage, as the C purists say you can't have inline assembly, but what is allowed is arrays of hex, so that is how assembly is written. Not that it is necessarily a bad thing, and there are those who can tell you the hex opcodes for instructions on their favourite microprocessor. But would it be possible to add inline assembly (both cog and native) using assembly instructions?
One solution is to run a program through a pre-processor that then calls a command line spin compiler (eg BST) that generates the hex, and then pastes this back in. That program itself can be called with a command line. So no major changes are needed to the IDE. Maybe just a checkbox and a textbox - in the options the checkbox says "Run ASM preprocessor" and the textbox has the name of the file to run.
Then it is a matter of syntax in xbasic - unique text at the beginning and end of 'native' code, and a different unique text at the beginning and end of cog code.
I've already written such a program but it is in vb.net but that is not the most portable of languages. The best solution would be to integrate the code into the IDE. It wouldn't be hugely complicated - something like the BST command line program would need to be included in the package. You need to shell this program repeatedly on little bits of text and read back the input when the shell process is finished, and then paste that hex code back into the program.
This would make it much easier to port Obex code over to xbasic. I'm mindful of how much time people have available though.
The question is why would anyone use BASIC over Spin or C which work very well in their different ways, are well supported and used by many? The later is important because it means help is readily available on the forum here or other places.
...as the C purists say you can't have inline assembly, but what is allowed is arrays of hex, so that is how assembly is written.
This is a little confusing. You are not talking about "assembly as in "assembler language code" here. What you are talking about is the inclusion of random binary blobs of data into the source code of a program. This is done with the "file" statement in Spin. There is no way to do it in C, it is often done by turning the binary into C source defining an array of data. I don't know of any other languages that do allow it.
One can do it in C by converting the binary data into an object file, the same format as that produced by the compiler when compiling an C file, and linking that object file into your program. There is is a tool in the GCC tool chain that does this (objcopy is it?).
When it comes to actual assembler language. Many C compilers allow you to write assembler directly in to the C source code. It's not pretty in GCC so I would use it sparingly. Better to write a separate assembler source file for bigger stuff.
Good points heater. I probably didn't explain that very well. I was thinking of a Spin program with a few lines of Spin, then 496 lines of Pasm. Translate the Spin to C and leave the assembly as it is and it might be a bit tricky convincing a C programmer it is still C. That probably applies to any language on the Propeller. Maybe it is why Spin was invented, and why it is still the most popular language on the Obex.
But with xbasic, maybe the fact that Basic is such a dogs breakfast of a language could be an advantage too? You can say 'here is xbasic and it is a special variant of basic specifically for the propeller, where large amounts of Pasm code in a DAT section is part of the language'.
Or not. As the language purists permit
There are several examples around of taking that Spin program that is a few lines of Spin and 496 lines of Pasm and converting it to C/PASM.
You leave enough Spin around the PASM so it compiles into a binary. The few lines of Spin that actually call the PASM need to be rewritten into several more lines of C (due to the expressive verbosity of C). The PASM may need to be tweakeda bit if there is any parameter passing. The entire process isn't too painful, usually. Once done, the two pieces are just linked together like any multi-file C project.
Comments
Ray
Ray
What boards Ray? Which ones were connected when you were having trouble?
You need to help me here. I can go back to the old methodology, but I would rather understand what the problem is.
One thing that really gets in the way is unconnected Bluetooth serial ports. I've tested with them and it takes a while to go through it, but it does work. It's probably best to delete Bluetooth serial ports unless they are connected or heavily used.
QuickStart Board gets COM17, when you start the IDE it finds COM17, but when you do a run, I get "error:opening serial port". This occurs in a random fashion.
I thought it was just my QS board, so I tried my DNA-RTC Board, gets COM17 and the same thing occurs, "error:opening serial port", in a random fashion. The only thing that I didn't try was to hook up too a different USB port and get different COMxx. I guess maybe I gave up to soon.
Ray
It seems you expected the port to change automatically when connecting another board.
Guess I'll have to check if the port exists every time before doing any loading.
Was there another issue with 0.2.1 ?
Ray
This seems strange. Each board with its own FTDI chip should show up as a different com port (at least that is what I see on my Win7 system. I'm not sure how a QS and a DNA-RTC come up with the same COM port.
Could you have something else on your PC that is COM17 and your Propeller boards are showing up as different/higher numbers? The IDE may just be choosing the first (or for some reason REALLY like COM17) regardless of where teh Propeller really is.
Ray
Since I can't reproduce the problem, and you say it exists, then I'll just put it back to the way it was before.
I've uploaded a new version that removes the troublesome Propeller-Auto-ID stuff. Find it here.
I did find a way to detect USB port changes. So now you can plug/unplug your board and the serial port list should change accordingly.
Also, I've fixed the 3900 Bytes Total problem (if you noticed that). It now reports the size of the program + about 2000 bytes for the VM. The jury is still out on whether or not the VM bytes gets reclaimed or not ....
The program below works when you have the defs at the end of the program and dim related stuff at the top. I guess it makes a difference when you place the dim related stuff at the end with the devs.
Ray
Good news so far. Thanks.
Yes, it makes a difference.
Generally speaking a module should look like this:
include
dim
def
code not inside of def
Look at the samples\GameBaby code.
I now know how Rip VanWinkle must have felt I've been away for sooooo long.
Will I find out early in my products life that the software has become just another oddity mulled over by old geezers like myself.
Tim
It is not clear what you are asking, but it does not sound like Xbasic ?
If you want to see if there are other Multi Core processors our there, the answer is of course, yes.
A new thread in General Discussion, with specifics of which MIL specs you seek, and rough scale of processor you need could get answers.
Ray
I added these to my local copy of propeller.bas, though that could become problematic on updating the IDE. As an experiment, I timed these versions versus using plain xbasic:
The xbasic code -- when the subroutine is in a library -- takes 4292 ticks; the inline native code takes 2432 ticks.
So what is the speed between each of the NATIVE lines above ?
Your idea of allowing 'NATIVE to accept more than one instruction at a time' would drop that inter-line overhead to zero ?
I have been wondering why this is, especially the history of parallax and the Basic language. Not all the options for Basic on the propeller tick all the boxes. I've used some crazy ones in the past, like running versions of Basic inside a Z80 emulation on the propeller, and converting Basic to C. Quick wish list would be an IDE, external memory support for large programs and ability to reasonably easily translate Obex spin code. Xbasic does seem to tick all the boxes.
I'm not sure how your Native mode works, but it seems very clever. Where you say it is similar to LMM, are you fetching longs from a cache driver, and then allowing the VM to process those longs one at a time when you use Native mode?
Thinking about inline assembly, there are two types of assembly - Native assembly, and blocks of assembly meant for loading into a cog. I am reaching back into the dark mists of time here with my memory banks, but this was an issue with the catalina program at one stage, as the C purists say you can't have inline assembly, but what is allowed is arrays of hex, so that is how assembly is written. Not that it is necessarily a bad thing, and there are those who can tell you the hex opcodes for instructions on their favourite microprocessor. But would it be possible to add inline assembly (both cog and native) using assembly instructions?
One solution is to run a program through a pre-processor that then calls a command line spin compiler (eg BST) that generates the hex, and then pastes this back in. That program itself can be called with a command line. So no major changes are needed to the IDE. Maybe just a checkbox and a textbox - in the options the checkbox says "Run ASM preprocessor" and the textbox has the name of the file to run.
Then it is a matter of syntax in xbasic - unique text at the beginning and end of 'native' code, and a different unique text at the beginning and end of cog code.
I've already written such a program but it is in vb.net but that is not the most portable of languages. The best solution would be to integrate the code into the IDE. It wouldn't be hugely complicated - something like the BST command line program would need to be included in the package. You need to shell this program repeatedly on little bits of text and read back the input when the shell process is finished, and then paste that hex code back into the program.
This would make it much easier to port Obex code over to xbasic. I'm mindful of how much time people have available though.
The question is why would anyone use BASIC over Spin or C which work very well in their different ways, are well supported and used by many? The later is important because it means help is readily available on the forum here or other places.
This is a little confusing. You are not talking about "assembly as in "assembler language code" here. What you are talking about is the inclusion of random binary blobs of data into the source code of a program. This is done with the "file" statement in Spin. There is no way to do it in C, it is often done by turning the binary into C source defining an array of data. I don't know of any other languages that do allow it.
One can do it in C by converting the binary data into an object file, the same format as that produced by the compiler when compiling an C file, and linking that object file into your program. There is is a tool in the GCC tool chain that does this (objcopy is it?).
When it comes to actual assembler language. Many C compilers allow you to write assembler directly in to the C source code. It's not pretty in GCC so I would use it sparingly. Better to write a separate assembler source file for bigger stuff.
But with xbasic, maybe the fact that Basic is such a dogs breakfast of a language could be an advantage too? You can say 'here is xbasic and it is a special variant of basic specifically for the propeller, where large amounts of Pasm code in a DAT section is part of the language'.
Or not. As the language purists permit
There are several examples around of taking that Spin program that is a few lines of Spin and 496 lines of Pasm and converting it to C/PASM.
You leave enough Spin around the PASM so it compiles into a binary. The few lines of Spin that actually call the PASM need to be rewritten into several more lines of C (due to the expressive verbosity of C). The PASM may need to be tweakeda bit if there is any parameter passing. The entire process isn't too painful, usually. Once done, the two pieces are just linked together like any multi-file C project.