In looking at the title of this thread it reminds me of a conversation that I had with the editor of Dr. Dobbs Journal a long time ago when they had asked me to write an article about a language I was developing at the time. The editor called me up to say that the article was fine except that I needed to come up with a name for the language. My response to him was "What about Bob?" This was a reference to a movie that was out at the time with the same title. So, the language became known as "Bob". Now we have a thread called "What about xbasic". Will hollywood now make a movie with that title? :-)
In looking at the title of this thread it reminds me of a conversation that I had with the editor of Dr. Dobbs Journal a long time ago when they had asked me to write an article about a language I was developing at the time. The editor called me up to say that the article was fine except that I needed to come up with a name for the language. My response to him was "What about Bob?" This was a reference to a movie that was out at the time with the same title. So, the language became known as "Bob". Now we have a thread called "What about xbasic". Will hollywood now make a movie with that title? :-)
No, I'm afraid not. However, the editor of Dr. Dobbs Journal called me right after he received the press release for the Microsoft Bob product suggesting I might be able to get them to pay me lots of money to use "Bob" as a name for their product since I had used it first. Unfortunately, I never trademarked the name and their product was a flop anyway so I lost my chance to become a millionaire! :-)
This should fix the RevA Quickstart loading issue. There are many IDE enhancements. The terminal behaves much better for example. The IDE will also scan for the first available Propeller and set the com port for use (the port will be blank on startup). Other items: Added current file/path to window title. Fixed SaveAs project setting, Made editor tab with smaller. Added program bytes loaded size. Fixed progress bar.
Thanks, Steve. I'm hope that if time allows, some of the niceties you've worked into SimpleIDE will find their way here, too (e.g., PST-compatible terminal).
I'm still in the "play" mode with xBasic. Hoping to get a handle on using ASM.
No, I'm afraid not. However, the editor of Dr. Dobbs Journal called me right after he received the press release for the Microsoft Bob product suggesting I might be able to get them to pay me lots of money to use "Bob" as a name for their product since I had used it first. Unfortunately, I never trademarked the name and their product was a flop anyway so I lost my chance to become a millionaire! :-)
I'd say not being a millionaire is a bummer, but not being associated with THAT Bob is priceless.
Thanks, Steve. I'm hope that if time allows, some of the niceties you've worked into SimpleIDE will find their way here, too (e.g., PST-compatible terminal).
I'm still in the "play" mode with xBasic. Hoping to get a handle on using ASM.
Hi Jon,
I'm afraid it might be difficult to get a handle on the ASM statement because it only really allows the entry of xbasic bytecodes. The only way to make use of PASM is by entering one instruction at a time in hex using the NATIVE bytecode. I need to document the ASM statement sometime soon. Sorry!
I need to document the ASM statement sometime soon. Sorry!
Please keep me abreast of that. What I'd like to do is create a library of routine things and not suffer so much of a speed penalty going through the high-level byte codes. And, I'm interested in the mechanics of language. In a few months I'll be at a big trade show and would like to show some of our customers that they can in fact "hack" EFX-TEK boards using BASIC. To make that easier, I'd like to have pre-built libraries and template files.
Question: There's no harm/foul referencing an a library form inside another library, is there? For example, as a quick test I created a library called timing.bas with this small chunk of code:
include "propeller.bas"
def pause(ms)
dim t = cnt
dim mstix = clkfreq / 1000
do while ms
t = t + mstix
waitcnt(t)
ms = ms - 1
loop
end def
It works, yet I don't know if the code is suffering "bloat" by having my main code and this library include "propeller.bas"
Please keep me abreast of that. What I'd like to do is create a library of routine things and not suffer so much of a speed penalty going through the high-level byte codes. And, I'm interested in the mechanics of language. In a few months I'll be at a big trade show and would like to show some of our customers that they can in fact "hack" EFX-TEK boards using BASIC. To make that easier, I'd like to have pre-built libraries and template files.
Question: There's no harm/foul referencing an a library form inside another library, is there? For example, as a quick test I created a library called timing.bas with this small chunk of code:
include "propeller.bas"
def pause(ms)
dim t = cnt
dim mstix = clkfreq / 1000
do while ms
t = t + mstix
waitcnt(t)
ms = ms - 1
loop
end def
It works, yet I don't know if the code is suffering "bloat" by having my main code and this library include "propeller.bas"
It should be okay but I don't think I've ever tried it. The xbasic compiler trims out functions from include files that are not actually used by the program.
Thanks Steve, I just installed 0.2.1, and its starting to shape up nicely. When I was checking it out I did run across a freeze up of the program, I cannot remember what I did exactly, but next time it happens I will try too document it.
I am starting to wonder about how many people are actually using xBasic at this time? I was starting to think that I was the only one, until JonnyMac made mention, so there are at least two people, this does not sound promising for xBasic unless some more people start sounding off, if in fact that they are using xBasic. So, I guess we wait and see, if there are no more updates or there is no more input to this thread then we will know for sure what the outcome is.
I still think that xBasic is good solution for some of the people that are using the BasicStamp and they want too give the Propeller a try. But I guess the best thing to do for now is too keep putting up code examples and showing different ways of using xBasic with the different hardware that is available. Not sure what the real solution to this would be.
I just found and finished reading through this thread. Fantastic work!
I like the way xbasic has a common IDE to simpleIDE. That makes the learning curve a lot easier.
How much control is there over the xbasic language? Is this set in stone or can it be modified? In particular, one of the things that is nice about Spin is it has binary numbers and having binary numbers makes it much easier to toggle pins and also to port code into pasm. If one were to propose a binary number format (eg 0bNNNN or NNNNb or something else) would this be possible?
The Obex is an amazing repository of code. spin2c has opened the Obex to all the C users. Is there a way of converting Spin to Xbasic? (or indeed, Spin to C, then C to Xbasic?).
Re adding inline pasm code, I gather the current system is to add an array. I wrote a text parser once for C code which stripped out the pasm blobs, converted them to arrays and pasted the arrays back in. It wasn't all that complicated - it just needed a way of finding pasm easily (looking for a unique string at the beginning and end of the pasm code), and then called a command line compiler repeatedly.
Another question - what is the 'engine' running xbasic on the propeller? Is it a single cog interpreter processing bytecode like spin, or is it more compiled code runnning LMM or similar?
I can see some intriguing possibilities for xbasic
How much control is there over the xbasic language? Is this set in stone or can it be modified? In particular, one of the things that is nice about Spin is it has binary numbers and having binary numbers makes it much easier to toggle pins and also to port code into pasm. If one were to propose a binary number format (eg 0bNNNN or NNNNb or something else) would this be possible?
Well, I wrote the xbasic compiler so I guess there is as much control as we need. :-)
I'll try to find out if there is some standard Basic syntax for numbers in another base. I suppose it would be best to try to use a syntax that Basic users would find familiar.
Well, I wrote the xbasic compiler so I guess there is as much control as we need. :-)
I'll try to find out if there is some standard Basic syntax for numbers in another base. I suppose it would be best to try to use a syntax that Basic users would find familiar.
I just looked and noticed that xbasic already allows 0x as a prefix for hex constants and 0b for binary constants. Also, like Spin, you can add embedded underscores between any two digits.
Edit: It even describes hex and binary literals in the xbasic documentation. :-)
Here is the random number code that Heater posted converted to xbasic.
rem rand.bas - Implementation of a 32-bit KISS generator which uses no multiply instructions
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
Here is a test program that illustrates using it:
include "print.bas"
include "rand.bas"
for n = 1 to 10
print rand
next n
I just looked and noticed that xbasic already allows 0x as a prefix for hex constants and 0b for binary constants. Also, like Spin, you can add embedded underscores between any two digits.
Here is the original random number that I posted minus the mod n at the end:
idim rseed = 1
def srand(n)
rseed = n
end def
def rand
dim k1
rem make sure we don't get stuck at zero
if rseed = 0 then
rseed = 1
end if
rem algorithm taken from Dr. Dobbs Journal, November 1985, page 91
k1 = rseed / 127773
rseed = 16807 * (rseed - k1 * 127773)
if rseed - k1 * 2836 < 0 then
rseed = rseed + 2147483647
end if
rem return a random number between 0 and n-1
return rseed
end def
Thanks, Steve. I'm hope that if time allows, some of the niceties you've worked into SimpleIDE will find their way here, too (e.g., PST-compatible terminal).
Terminal stuff is the hardest thing. I have to change the receive mode entirely. Maybe a sub-set of PST-compatible would be easier.
I'm still in the "play" mode with xBasic. Hoping to get a handle on using ASM.
I've spent some time using the asm commands. Here's an overview of what I know ... I'll add to this
The xbasic asm block allows inserting short bits of assembly/machine code into a def function (subroutine). The syntax is very terse at the moment, and there are restrictions. Fortunately, there are some nice examples to learn from. There is also a tool that can give us a hand.
I could be totally wrong about parts of this.
First, one should understand the restrictions.
- Any jump instruction is not available (JMP, JMPRET, CALL, DJNZ, TJZ, TJNZ, etc...)
- Only the C flag can be set or used. The Z flag is off limits today.
- Only 4 registers are available for temporary storage.
- Some special commands are available for accessing def function parameters and results.
- It seems like asm blocks should not be mixed with regular code in a def function.
Available instructions (need help here David):
- halt
- brt
- brtsc
- brf
- brfsc
- br
- not
- neg
- add
- sub
- mul
- div
- rem
- bnot
- band
- bor
- bxor
- shl
- shr
- lt
- le
- eq
- ne
- ge
- gt
- lit number - set number to source of next instruction
- slit
- load
- loadb
- store
- storeb
- lref number - push function parameter number on top of stack
- lset number - pop top of stack to function parameter number
- index
- pushj
- popj
- clean
- frame
- returnz - return value on top of stack to caller
- return - return to caller
- drop - pop top of stack
- dup - push copy of top of stack value to stack
- native word - use a machine code instruction
- trap
As, you can see I haven't used many of the ASM instructions.
Examples (from propeller.bas):
// purpose of this function is to read the CLKFREQ value from HUB address 0
def clkfreq
asm
dup // make space for the return value
native 0x08fc0a00 // rdlong tos, #0
returnx // return value at tos to caller
end asm
end def
Where does 0x08fc0a00 come from?
C:\xbasic3\pasm>cat test.pasm
rdlong tos, #0
C:\xbasic3\pasm>pasm test.pasm
08fc0a00
00000001 t1
00000002 t2
00000003 t3
00000004 t4
00000005 tos
00000006 base
000001f0 par
000001f1 cnt
000001f2 ina
000001f3 inb
000001f4 outa
000001f5 outb
000001f6 dira
000001f7 dirb
000001f8 ctra
000001f9 ctrb
000001fa frqa
000001fb frqb
000001fc phsa
000001fd phsb
000001fe vcfg
000001ff vscl
As you can see the asm tool can be very beneficial. A windows .zip is attached.
All very interesting. I feel like jumping in feet first here.
Ok, let's say I grab an object from the Obex - say it is a display or keyboard or SD driver, and I want to translate this to xbasic.
Presumably, once this is done, it only needs to be done once and it could then go back into the obex as Xbasic code?
If so, there would be an incentive to at least get some of the essential objects translated. Spin and Basic are fairly similar (to me at least!), so I guess you start at the beginning and translate the lines over. I see there are some string routines missing - and that may not be such a problem because instead of adding more code to the compiler, instead we can take string routines from the obex (eg Kye's code) and translate that to xbasic code.
Ok, first big hurdle is going to be inline pasm. This is one very nice feature of Spin, and much better than, say, an inline array of hex numbers. How is inline pasm handled at the moment?
It's late in the day so this may be a silly question, but what is "tos" -- seems like a temporary variable passed from system to the asm code. Going to play a little more before bed.
[Edit] Okay, brain is slow. Assuming "tos" is top of stack.
Hopefully, David can expand on what Steve posted -- perhaps a mini-tutorial on PASM [snippet] coding for xBasic programmers. For example, I compiled this little bit (with the tool Steve provided), but when I tell it to make pin 26 high (LED on PAB), pin 27 goes high instead.
mov t1, #1
shl t1, tos
or outa, t1
or dira, t1
Using the output from PASM.EXE I end up with this:
def high(pin)
asm
lref 0 // pin --> tos
native 0xa0fc0201 // mov t1, #1
native 0x2cbc0205 // shl t1, tos
native 0x68bfe801 // or outa, t1
native 0x68bfec01 // or dira, t1
returnx
end asm
end def
Serious problem, at least with my computer, 0.2.1 IDE cannot connect with the COM port. When I have the QS board plugged in and I start the IDE, it seems like the IDE looks for a matching COM port, then makes the selection. The problem is, when you try to run a program, I get an "error: opening serial port". In this particular case it is COM 17, if that is of any help. After playing around with it for a while it becomes a hit or miss situation, sometimes it connects and sometimes it doesn't.
I pretty much stopped working on xbasic when Steve moved from working on an xbasic IDE to working on SimpleIDE. He was pretty much the only user of xbasic and it didn't seem to make sense to put a lot more effort into it. Recently I've revisited it a bit because I wanted to use its PASM virtual machine with my ebasic interpreter to speed it up and to use less hub memory for the VM code. That is almost working now although it lacks built-in functions to make it useful on the Propeller. Those can be added though and I expect to do that. The nice thing (depending on your point of view) is that ebasic runs on the Propeller. It doesn't require a PC-based tool to build programs. I could revive xbasic if there was any interest.
Some intriguing concepts there. Well, to find out how something works, why not pull it to bits?
Ok, inside the xbasic package is a file called xbasic_vm which is a pasm program. So I think this fits in a cog, and it has a bunch of virtual opcodes and little snippets of pasm code to run each one
OP_HALT = $00 ' halt
OP_BRT = $01 ' branch on true
OP_BRTSC = $02 ' branch on true (for short circuit booleans)
OP_BRF = $03 ' branch on false
OP_BRFSC = $04 ' branch on false (for short circuit booleans)
OP_BR = $05 ' branch unconditionally
OP_NOT = $06 ' logical negate top of stack
OP_NEG = $07 ' negate
OP_ADD = $08 ' add two numeric expressions
OP_SUB = $09 ' subtract two numeric expressions
OP_MUL = $0a ' multiply two numeric expressions
OP_DIV = $0b ' divide two numeric expressions
OP_REM = $0c ' remainder of two numeric expressions
OP_BNOT = $0d ' bitwise not of two numeric expressions
OP_BAND = $0e ' bitwise and of two numeric expressions
OP_BOR = $0f ' bitwise or of two numeric expressions
OP_BXOR = $10 ' bitwise exclusive or
OP_SHL = $11 ' shift left
OP_SHR = $12 ' shift right
OP_LT = $13 ' less than
OP_LE = $14 ' less than or equal to
OP_EQ = $15 ' equal to
OP_NE = $16 ' not equal to
OP_GE = $17 ' greater than or equal to
OP_GT = $18 ' greater than
OP_LIT = $19 ' load literal
OP_LOAD = $1a ' load a long from memory
OP_LOADB = $1b ' load a byte from memory
OP_STORE = $1c ' store a long in memory
OP_STOREB = $1d ' store a byte in memory
OP_LREF = $1e ' load a local variable relative to the frame pointer
OP_LSET = $1f ' set a local variable relative to the frame pointer
OP_INDEX = $20 ' index into a vector
OP_PUSHJ = $21 ' push the pc and jump to a function */
OP_POPJ = $22 ' return to the address on the stack */
OP_CLEAN = $23 ' clean arguments off the stack after a function call */
OP_FRAME = $24 ' create a stack frame */
OP_RETURN = $25 ' remove a stack frame and return from a function call */
OP_RETURNZ = $26 ' remove a stack frame and return zero from a function call */
OP_DROP = $27 ' drop the top element of the stack
OP_DUP = $28 ' duplicate the top element of the stack
OP_NATIVE = $29 ' execute a native instruction
OP_TRAP = $2a ' invoke a trap handler
OP_LAST = $2a
This is not unlike other emulations, eg the Z80 and Zog. But because this virtual machine is simpler than the Z80 one, it appears there is also room for a cache driver in the same cog. So this is a very nice generic package for any language and for external memory options.
So for me, I immediately think - "if xbasic can be compiled to run on this virtual machine, why not spin?", and the reason for that is it could be a way of running "big spin". But I digress.
Looking at the code a bit more, I see two objects - a "vm interface" object and a "cache interface" object. So maybe I was getting ahead of myself there thinking it all fits in one cog. But it would be interesting to think about whether it could, and what sort of external memory configurations could be squeezed into a cog or two. The dracblade sram with latches only uses a bit of a cog, but it is slow - 20 pasm instructions to fetch a byte. SPI memory takes more code space but is faster, particularly quad SPI.
It would be interesting to consider the tradeoffs for a virtual machine that fits a small number of opcodes, a cache and an external memory driver. Maybe if the external memory driver was fast enough, a cache is not needed. And then to think of the minimum number of pins. So in a general sense the overhead of the virtual machine is the minimum number of cogs and the minimum number of prop pins, so that the user has lots of cogs and pins left over for their code.
I suspect one of the optimum solutions is one of the new SPI serial ram chips, 4 propeller pins and a hub cache of a few k. So - how many cogs would that take?
Looking through the xbasic package, there is a lot of supporting spin code. Taking a 'purist' approach, all that spin code would be in xbasic (and pasm). I guess the challenge is a little message that Jurgen had as the Z80 emulation booted up - it was such a simple message - it simply said "goodbye spin". When I first saw it, I thought "you can't have a propeller running without spin". But studying that code showed you could, you just had to pack a lot of clever things into pasm code.
Maybe you cheat with the boot process and run a standard spin program to open an SD card and initiate an SPI ram chip and move data from the SD card to the ram. But then you can say "goodbye spin". You start a cog running a virtual machine, run a program through that machine, and that program has TV drivers and keyboard and a new SD driver etc, all written in your favourite language which is compiled to the virtual machine byte code.
Well, you don't need Spin the high level language but you do need a handful of Spin interpreter byte codes to start a COG running your PASM.
That's how Propeller C compilers do it.
That's how my Pascal like toy language, derived from Jack Crenshaw's TINY, did it many years ago. That Prop Tiny compiles into LMM instructions.
I used Cliff Biffle's assembler "propasm" to do this. That was written in 2006! It's here if you want to play with these ideas: http://cliffhacks.blogspot.fi/2006/10/propasm-propeller-assembler.html
Although I suspect it's better to use the assembler with propgcc now a days.
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.
Has anybody tried the new 'rand' command? It seems I cannot get it to do anything. I used the:
for n = 1 to 10
print rand
next n
When you run this, nothing shows up in the debug screen. I am wondering if something is missing, I will have to read that post again, maybe this is just a concept, and not functional code.
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.
Has anybody tried the new 'rand' command? It seems I cannot get it to do anything. I used the:
for n = 1 to 10
print rand
next n
When you run this, nothing shows up in the debug screen. I am wondering if something is missing, I will have to read that post again, maybe this is just a concept, and not functional code.
Ray
You'll need to put the random number code I posted into a file called rand.bas and add an include of "rand.bas" to your test program.
It's late in the day so this may be a silly question, but what is "tos" -- seems like a temporary variable passed from system to the asm code. Going to play a little more before bed.
[Edit] Okay, brain is slow. Assuming "tos" is top of stack.
Darn....
The "tos" variable is the top element on the stack. I was able to speed up xbasic quite a bit by caching the top element on the stack. So the top element of the stack is in tos, the next element on the stack is in sp[0], then sp[1], etc.
Ok, first big hurdle is going to be inline pasm. This is one very nice feature of Spin, and much better than, say, an inline array of hex numbers. How is inline pasm handled at the moment?
I could combine my simple PASM assembler (the one Steve posted) with the ASM statement to allow symbolic instructions so you don't have to use hex numbers but there would still be the problem that JMP, CALL, JMPRET, etc would not work. This is because the xbasic VM is just executing one native instruction at a time in what is essentially a slow LMM loop.
You'll need to put the random number code I posted into a file called rand.bas and add an include of "rand.bas" to your test program.
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.
Comments
So can we blame you for this? ;-)
http://en.wikipedia.org/wiki/Microsoft_Bob
Here is a link to your article, looks pretty cool:
http://www.drdobbs.com/open-source/bob-a-tiny-object-oriented-language/184409401
C.W.
Thanks, Steve. I'm hope that if time allows, some of the niceties you've worked into SimpleIDE will find their way here, too (e.g., PST-compatible terminal).
I'm still in the "play" mode with xBasic. Hoping to get a handle on using ASM.
I'd say not being a millionaire is a bummer, but not being associated with THAT Bob is priceless.
I added a link to your Bob in my post above.
C.W.
I'm afraid it might be difficult to get a handle on the ASM statement because it only really allows the entry of xbasic bytecodes. The only way to make use of PASM is by entering one instruction at a time in hex using the NATIVE bytecode. I need to document the ASM statement sometime soon. Sorry!
Please keep me abreast of that. What I'd like to do is create a library of routine things and not suffer so much of a speed penalty going through the high-level byte codes. And, I'm interested in the mechanics of language. In a few months I'll be at a big trade show and would like to show some of our customers that they can in fact "hack" EFX-TEK boards using BASIC. To make that easier, I'd like to have pre-built libraries and template files.
Question: There's no harm/foul referencing an a library form inside another library, is there? For example, as a quick test I created a library called timing.bas with this small chunk of code:
It works, yet I don't know if the code is suffering "bloat" by having my main code and this library include "propeller.bas"
I am starting to wonder about how many people are actually using xBasic at this time? I was starting to think that I was the only one, until JonnyMac made mention, so there are at least two people, this does not sound promising for xBasic unless some more people start sounding off, if in fact that they are using xBasic. So, I guess we wait and see, if there are no more updates or there is no more input to this thread then we will know for sure what the outcome is.
I still think that xBasic is good solution for some of the people that are using the BasicStamp and they want too give the Propeller a try. But I guess the best thing to do for now is too keep putting up code examples and showing different ways of using xBasic with the different hardware that is available. Not sure what the real solution to this would be.
Ray
I like the way xbasic has a common IDE to simpleIDE. That makes the learning curve a lot easier.
How much control is there over the xbasic language? Is this set in stone or can it be modified? In particular, one of the things that is nice about Spin is it has binary numbers and having binary numbers makes it much easier to toggle pins and also to port code into pasm. If one were to propose a binary number format (eg 0bNNNN or NNNNb or something else) would this be possible?
The Obex is an amazing repository of code. spin2c has opened the Obex to all the C users. Is there a way of converting Spin to Xbasic? (or indeed, Spin to C, then C to Xbasic?).
Re adding inline pasm code, I gather the current system is to add an array. I wrote a text parser once for C code which stripped out the pasm blobs, converted them to arrays and pasted the arrays back in. It wasn't all that complicated - it just needed a way of finding pasm easily (looking for a unique string at the beginning and end of the pasm code), and then called a command line compiler repeatedly.
Another question - what is the 'engine' running xbasic on the propeller? Is it a single cog interpreter processing bytecode like spin, or is it more compiled code runnning LMM or similar?
I can see some intriguing possibilities for xbasic
I'll try to find out if there is some standard Basic syntax for numbers in another base. I suppose it would be best to try to use a syntax that Basic users would find familiar.
Edit: It even describes hex and binary literals in the xbasic documentation. :-)
Here is a test program that illustrates using it:
Wow, now that is fast service!
Terminal stuff is the hardest thing. I have to change the receive mode entirely. Maybe a sub-set of PST-compatible would be easier.
I've spent some time using the asm commands. Here's an overview of what I know ... I'll add to this
The xbasic asm block allows inserting short bits of assembly/machine code into a def function (subroutine). The syntax is very terse at the moment, and there are restrictions. Fortunately, there are some nice examples to learn from. There is also a tool that can give us a hand.
I could be totally wrong about parts of this.
First, one should understand the restrictions.
- Any jump instruction is not available (JMP, JMPRET, CALL, DJNZ, TJZ, TJNZ, etc...)
- Only the C flag can be set or used. The Z flag is off limits today.
- Only 4 registers are available for temporary storage.
- Some special commands are available for accessing def function parameters and results.
- It seems like asm blocks should not be mixed with regular code in a def function.
Available instructions (need help here David):
- halt
- brt
- brtsc
- brf
- brfsc
- br
- not
- neg
- add
- sub
- mul
- div
- rem
- bnot
- band
- bor
- bxor
- shl
- shr
- lt
- le
- eq
- ne
- ge
- gt
- lit number - set number to source of next instruction
- slit
- load
- loadb
- store
- storeb
- lref number - push function parameter number on top of stack
- lset number - pop top of stack to function parameter number
- index
- pushj
- popj
- clean
- frame
- returnz - return value on top of stack to caller
- return - return to caller
- drop - pop top of stack
- dup - push copy of top of stack value to stack
- native word - use a machine code instruction
- trap
As, you can see I haven't used many of the ASM instructions.
Examples (from propeller.bas):
Where does 0x08fc0a00 come from?
As you can see the asm tool can be very beneficial. A windows .zip is attached.
That's all I have time for now.
Ok, let's say I grab an object from the Obex - say it is a display or keyboard or SD driver, and I want to translate this to xbasic.
Presumably, once this is done, it only needs to be done once and it could then go back into the obex as Xbasic code?
If so, there would be an incentive to at least get some of the essential objects translated. Spin and Basic are fairly similar (to me at least!), so I guess you start at the beginning and translate the lines over. I see there are some string routines missing - and that may not be such a problem because instead of adding more code to the compiler, instead we can take string routines from the obex (eg Kye's code) and translate that to xbasic code.
Ok, first big hurdle is going to be inline pasm. This is one very nice feature of Spin, and much better than, say, an inline array of hex numbers. How is inline pasm handled at the moment?
[Edit] Okay, brain is slow. Assuming "tos" is top of stack.
Darn....
In many languages, tos is used for Top Of Stack - could be a clue there ?
Hopefully, David can expand on what Steve posted -- perhaps a mini-tutorial on PASM [snippet] coding for xBasic programmers. For example, I compiled this little bit (with the tool Steve provided), but when I tell it to make pin 26 high (LED on PAB), pin 27 goes high instead.
Using the output from PASM.EXE I end up with this:
Ray
Some intriguing concepts there. Well, to find out how something works, why not pull it to bits?
Ok, inside the xbasic package is a file called xbasic_vm which is a pasm program. So I think this fits in a cog, and it has a bunch of virtual opcodes and little snippets of pasm code to run each one
This is not unlike other emulations, eg the Z80 and Zog. But because this virtual machine is simpler than the Z80 one, it appears there is also room for a cache driver in the same cog. So this is a very nice generic package for any language and for external memory options.
So for me, I immediately think - "if xbasic can be compiled to run on this virtual machine, why not spin?", and the reason for that is it could be a way of running "big spin". But I digress.
Looking at the code a bit more, I see two objects - a "vm interface" object and a "cache interface" object. So maybe I was getting ahead of myself there thinking it all fits in one cog. But it would be interesting to think about whether it could, and what sort of external memory configurations could be squeezed into a cog or two. The dracblade sram with latches only uses a bit of a cog, but it is slow - 20 pasm instructions to fetch a byte. SPI memory takes more code space but is faster, particularly quad SPI.
It would be interesting to consider the tradeoffs for a virtual machine that fits a small number of opcodes, a cache and an external memory driver. Maybe if the external memory driver was fast enough, a cache is not needed. And then to think of the minimum number of pins. So in a general sense the overhead of the virtual machine is the minimum number of cogs and the minimum number of prop pins, so that the user has lots of cogs and pins left over for their code.
I suspect one of the optimum solutions is one of the new SPI serial ram chips, 4 propeller pins and a hub cache of a few k. So - how many cogs would that take?
Looking through the xbasic package, there is a lot of supporting spin code. Taking a 'purist' approach, all that spin code would be in xbasic (and pasm). I guess the challenge is a little message that Jurgen had as the Z80 emulation booted up - it was such a simple message - it simply said "goodbye spin". When I first saw it, I thought "you can't have a propeller running without spin". But studying that code showed you could, you just had to pack a lot of clever things into pasm code.
Maybe you cheat with the boot process and run a standard spin program to open an SD card and initiate an SPI ram chip and move data from the SD card to the ram. But then you can say "goodbye spin". You start a cog running a virtual machine, run a program through that machine, and that program has TV drivers and keyboard and a new SD driver etc, all written in your favourite language which is compiled to the virtual machine byte code.
I'll ponder this some more...
That's how Propeller C compilers do it.
That's how my Pascal like toy language, derived from Jack Crenshaw's TINY, did it many years ago. That Prop Tiny compiles into LMM instructions.
I used Cliff Biffle's assembler "propasm" to do this. That was written in 2006! It's here if you want to play with these ideas: http://cliffhacks.blogspot.fi/2006/10/propasm-propeller-assembler.html
Although I suspect it's better to use the assembler with propgcc now a days.
Has anybody tried the new 'rand' command? It seems I cannot get it to do anything. I used the: When you run this, nothing shows up in the debug screen. I am wondering if something is missing, I will have to read that post again, maybe this is just a concept, and not functional code.
Ray
Ray