Shop OBEX P1 Docs P2 Docs Learn Events
So, what about xbasic? - Page 9 — Parallax Forums

So, what about xbasic?

12345679»

Comments

  • jazzedjazzed Posts: 11,803
    edited 2014-01-18 13:26
    Look at TvText.bas

    Program bin2xbasic.exe doesn't magically give you spin functions. You have to make your own versions. That's what TvText.bas does..
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-01-18 14:08
    Oh, boy! I just looked at TvText.bas. You know I thought this whole procedure was going to be as simple as doing the conversion and then you would have access to the commands that were in the spin file, just like in Spin you would call an object file and use all the commands within that program. So, basically you have to do the defs for all the commands that are in the spin file. I don't get it, how is this a selling point for using spin files with xBasic? It seems like you are better off, and not duplicating efforts, if you just take the PASM part of the spin program, and just use PASM.exe to come up with the byte code, am I missing something here? I guess with inline assembly you could almost cut/paste asm below the dat and insert in xBasic, and there you would have the base code. Maybe some effort should be put into inline asm, and not this very cumbersome ordeal of trying to convert an existing spin file.

    Ray
  • Heater.Heater. Posts: 21,230
    edited 2014-01-18 14:23
    Ray,

    If I understand correctly when you extract the PASM from a Spin object using open Spin you are getting the binary blob that results from assembling the PASM part. All the Spin stuff is thrown away as this is not doing a Spin xbasic translation. It would be a lot of work for someone to create such a translator. There is one for Spin to C though.

    So you have the blob and you can start it in your basic program, but then you have to provide all those access functions and logic that was in Spin before.

    This is a recurring theme with people creating or using odd languages on the Prop. and wanting to reuse PASM code.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-18 14:25
    Rsadeika wrote: »
    Oh, boy! I just looked at TvText.bas. You know I thought this whole procedure was going to be as simple as doing the conversion and then you would have access to the commands that were in the spin file, just like in Spin you would call an object file and use all the commands within that program. So, basically you have to do the defs for all the commands that are in the spin file. I don't get it, how is this a selling point for using spin files with xBasic? It seems like you are better off, and not duplicating efforts, if you just take the PASM part of the spin program, and just use PASM.exe to come up with the byte code, am I missing something here? I guess with inline assembly you could almost cut/paste asm below the dat and insert in xBasic, and there you would have the base code. Maybe some effort should be put into inline asm, and not this very cumbersome ordeal of trying to convert an existing spin file.

    Ray
    I'm afraid people are still misunderstanding the ASM and NATIVE statements in xbasic. There is no way that you could cut the PASM out of a Spin object and just convert it to NATIVE instructions and have it work. I only added the NATIVE bytecode to xbasic so that I could include a few PASM instructions in otherwise xbasic code. This was for PASM instructions like waitcnt, coginit, etc that are impossible to implement in xbasic. Coding anything else using NATIVE will not result in faster code since every NATIVE instruction is also a bytecode. The way to run PASM code fast is to bundle it into a blob that gets loaded into a COG. This is exactly what happens all the time in Spin objects except that the PASM blobs are inline in the Spin source. There is no inline assembly in Spin (although there probably will be in Spin2!). Even if I extend NATIVE to allow more than one instruction to be coded at a time and if I merge in the simple pasm.exe assembler, it still won't be good for more than a handful of PASM instructions at a time. My guess is that I can probably spare up to 16 COG locations for these PASM sequences which I don't believe will be enough to run any of the PASM code that is in OBEX. I'm happy that some of you have expressed an interest in xbasic and I'm willing to support it to do what it was originally intended for but it was never supposed to be a replacement for Spin or C. If you need a language with those capabilities I suggest you use one of those instead of xbasic. On the other hand, if you're interested in a version of Basic that is pretty fast and can execute code out of external memory, then xbasic may be good for you.
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-01-18 14:55
    I guess the selling point for XBasic is the ability to use HUB, FLASH, or RAM space with the limited command set of xBasic. And the use of COGs is even more difficult, not standard issue in xBasic. Now the question is how do you expand the command set which would allow you to create something like FullDuplexSerial library? It seems like I am going in circles with this, I need to create a new mindset for myself as it pertains to xBasic, if that would help any.

    Ray
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-18 14:55
    I hope my experiments in NATIVE coding haven't annoyed you, David. I think I understand the limitations -- I'm just trying to learn to exploit NATIVE opcodes where I can.

    As I have all my basic IO working (please have look at the attached when you can -- I may be fooling myself), I decided to port elements of my Spin template to xBasic. I'm able to get freqout working, but I can't seem to pass a character as a parameter (small issue, but I'd like to understand why).

    This works, expecting 0 for ctra or 1 for ctrb:
    def freqout(ctrx, pin, freq, ms)
      if (ctrx = 0) then
        if (freq > 0) then
          ctra = ((0b00100) << 26) | pin 
          frqa = (0x8000_0000 / (clkfreq / freq)) << 1 
        else
          ctra = 0
        end if
        low(pin)
        if (ms > 0) then
          pause(ms)
          ctra = 0
        end if
      else if (ctrx = 1) then
        if (freq > 0) then
          ctrb = ((0b00100) << 26) | pin 
          frqb = (0x8000_0000 / (clkfreq / freq)) << 1 
        else
          ctrb = 0
        end if
        low(pin)
        if (ms > 0) then
          pause(ms)
          ctrb = 0
        end if
      end if
    end def
    


    I tested the free-run and timed modes of the function with this snippet running on the PAB:
    freqout(0, 26,  1, 0)
    freqout(1, 27, 10, 5000)
    freqout(0, 26,  0, 0)
    


    And it works! The 0 and 1 versus "A" and "B" isn't a big bother; I just try to keep my code friendly and want to better understand passing parameters in xbasic.
  • jazzedjazzed Posts: 11,803
    edited 2014-01-18 15:14
    Jon,

    Did you try 'A' and 'B' instead of "A" and "B" ?
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-18 15:20
    JonnyMac wrote: »
    I hope my experiments in NATIVE coding haven't annoyed you, David. I think I understand the limitations -- I'm just trying to learn to exploit NATIVE opcodes where I can.
    No, they didn't annoy me. I'm happy to see people using xbasic. I just want to set reasonable expectations. Using NATIVE is fine when you need to access some underlying Propeller functionality but it isn't a way to make your code run faster at least in its current form. Thanks for taking the time to try xbasic!
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-18 16:03
    jazzed wrote: »
    Jon,

    Did you try 'A' and 'B' instead of "A" and "B" ?

    Whoops... rookie error on my part. Thanks, Steve, that fixed it.
    def freqout(ctrx, pin, freq, ms)
      select ctrx
        case 1, 'A', 'a'
          if (freq > 0) then
            ctra = ((0b00100) << 26) | pin 
            frqa = (0x8000_0000 / (clkfreq / freq)) << 1 
          else
            ctra = 0
          end if
          low(pin)
          if (ms > 0) then
            pause(ms)
            ctra = 0
          end if
        case 2, 'B', 'b'
          if (freq > 0) then
            ctrb = ((0b00100) << 26) | pin 
            frqb = (0x8000_0000 / (clkfreq / freq)) << 1 
          else
            ctrb = 0
          end if
          low(pin)
          if (ms > 0) then
            pause(ms)
            ctrb = 0
          end if
      end select
    end def
    


    On another topic... any chance of getting line numbers in the edit panel and line:column in the status line? I think that will help locating errors flagged by the compiler.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-01-18 16:17
    Oh, boy! I just looked at TvText.bas. You know I thought this whole procedure was going to be as simple as doing the conversion and then you would have access to the commands that were in the spin file, just like in Spin you would call an object file and use all the commands within that program. So, basically you have to do the defs for all the commands that are in the spin file. I don't get it, how is this a selling point for using spin files with xBasic? It seems like you are better off, and not duplicating efforts, if you just take the PASM part of the spin program, and just use PASM.exe to come up with the byte code, am I missing something here? I guess with inline assembly you could almost cut/paste asm below the dat and insert in xBasic, and there you would have the base code. Maybe some effort should be put into inline asm, and not this very cumbersome ordeal of trying to convert an existing spin file.

    Ray

    Well, let's take a real example and work through it.

    First point - most of the time when someone has written pasm in spin, it is for code that ends up running in a cog. Running in some sort of emulation, eg LMM or NATIVE will not work, because the timing will be wrong, and it probably won't run fast enough.

    So for converting an object, the pasm has to stay the same.

    I'm going to use the TV Text object, because the code is fairly simple. This is one of the original objects created by Chip back in 2008 http://obex.parallax.com/object/618

    There are three Spin files. Let's ignore the Demo file for the moment and get into the core of the program - TV.spin
    CON
    
      fntsc         = 3_579_545     'NTSC color frequency
      lntsc         = 3640          'NTSC color cycles per line * 16
      sntsc         = 624           'NTSC color cycles per sync * 16
    
      fpal          = 4_433_618     'PAL color frequency
      lpal          = 4540          'PAL color cycles per line * 16
      spal          = 848           'PAL color cycles per sync * 16
    
      paramcount    = 14
      colortable    = $180          'start of colortable inside cog
      
    
    VAR
    
      long  cog
    
    
    PUB start(tvptr) : okay
    
    '' Start TV driver - starts a cog
    '' returns false if no cog available
    ''
    ''   tvptr = pointer to TV parameters
    
      stop
      okay := cog := cognew(@entry, tvptr) + 1
    
    
    PUB stop
    
    '' Stop TV driver - frees a cog
    
      if cog
        cogstop(cog~ - 1)
    
    
    DAT
    
    '*******************************
    '* Assembly language TV driver *
    '*******************************
    ...
    

    The first part is some constants. They should translate to xbasic easily.
    Then there is some code to start a cog and to stop a cog. I think that is in xbasic.
    And then there is the DAT section. This is the part that needs to be separated out and compiled to a binary array.
    At this point, we need to note that the PAR value sent to the cog has the variable name tvptr. But there are two parts to this spin program, and what that really points to is an array in the file tv_text, down the bottom, called tv_params.
    So this is a bit complicated, because we need to follow through that value to what it really points to. It helps to have both tv.spin and tv_params.spin open at the same time in the propeller IDE.

    Now it gets a bit complicated. xbasic does not have objects (though I think we can create them very easily, just by having a compiler add the object name to the beginning of all variables). So we will need to do this manually, and first merge all the spin files into one big file. That can be as simple as just copying and pasting the text together, but then you need to go through and check there are no variable names the same in each file. tv.spin only has one variable called "cog", so the process is to go through the tv_text.spin and check there are no variables also called "cog". A text search makes this easier. So the VAR sections of each spin file can be merged.

    Now we have another problem - both spin files have PUBs called "start" and "stop". So we need unique names for those. So lets see how "object oriented xbasic" could work in practice. For the PUB start in tv.spin, we rename that as "tv_start" and for the PUB start in tv_text.spin, we rename that "tv_text_start". This means these PUBs have unique names in the merged text file. We would also need to rename the calling routines in the "tv_text_demo.spin" program as well. One thing that can be seen is that authors of objects have already been using underscores in names, so maybe we could look at another naming convention to show where the object part of the file is. I think C++ uses a double colon. My personal preference would be a period, but that would be up to the authors of xbasic. So we could have something like "tv.start" and "tv_text.start" And for a really cool IDE, if you added an include for tv_text.bas at the beginning of the program, the IDE would search through this file, create a list of all the subroutines, and when you type "tv_text." it would bring up a dropdown menu of all the subroutines available in that object. But I digress...

    Ok, so now we have merged everything into one object file. Now it is a matter of translating each line one at a time into xbasic.

    I guess this is where we might find a need for new keywords and instructions. How would this code be translated to xbasic for instance? Is there an equivalent for lookupz? Do we need to expand out everything in brackets and put them on separate lines, and possibly create a few extra variables to do this?
    PUB hex(value, digits)
    '' Print a hexadecimal number
      value <<= (8 - digits) << 2
      repeat digits
        out(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
    

    This is the one object that has already been translated so, this is what it looks like in xbasic
    REM===================================================
    REM Print a hexidecimal number to current text position
    REM @param value - decimal number
    REM @param digits - number of digits to print
    REM
    def TvText_hex(value, digits)
        dim n = 0
        dim mask    = 0xf   // faster than using constants
        dim one     = 1     // faster than using constants
        do while digits > 0
            digits = digits - one
            n = (value >> (digits<<2)) & mask
            TvText_putchar(TvText_hexarray(n))
        loop
    end def
    
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-18 16:25
    Dr_Acula wrote: »
    Well, let's take a real example and work through it.

    First point - most of the time when someone has written pasm in spin, it is for code that ends up running in a cog.
    Actually, that's *ALL* of the time. There is no way to do inline assembly in Spin. It is all for loading into a COG.
  • jazzedjazzed Posts: 11,803
    edited 2014-01-18 16:34
    JonnyMac wrote: »
    Whoops... rookie error on my part. Thanks, Steve, that fixed it.

    Great.
    JonnyMac wrote: »
    On another topic... any chance of getting line numbers in the edit panel and line:column in the status line? I think that will help locating errors flagged by the compiler.

    Yes. This was one of my initial UGH reactions having not messed with the IDE in a while. I know what needs to be done, it's just a matter of having half a day to do it.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-18 17:02
    It's award season in Hollywood (and I've only watched a couple screeners...) -- we like to say, "For your consideration..."

    On that note, this is a possible implementation of pulsout(). Just like the BASIC Stamp, it blocks until finished.
    def pulsout(ctrx, pin, us)
    
      select ctrx
        case 1, 'A', 'a'
          low(pin)
          ctra = (0b00100 << 26) | pin
          frqa = 1
          phsa = -us * (clkfreq / 1_000_000) 
          do  while (phsa < 0)
          loop
          ctra = 0
    
        case 2, 'B', 'b'
          low(pin)
          ctrb = (0b00100 << 26) | pin
          frqb = 1
          phsb = -us * (clkfreq / 1_000_000) 
          do  while (phsb < 0)
          loop
          ctrb = 0
      end select
    end def
    

    Yes. This was one of my initial UGH reactions having not messed with the IDE in a while. I know what needs to be done, it's just a matter of having half a day to do it.

    Thanks, Steve.
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-18 17:39
    I've blown way past my alloted play time with xbasic today -- but I'm thinking about including a blurb in my March column so I'd like to have a few things sussed out.

    I can do this in Spin, and it works as expected (using PAB):
    set_freq("A", 26, 1)  
    
      repeat
        waitpeq(1 << 26, 1 << 26, 0)
        high(27)
        waitpne(1 << 26, 1 << 26, 0)
        low(27)
    


    The LED on P26 flashes (via the counter) and the LED on 27 tracks it via the code loop.

    If I translate that to xbasic like this:
    dim mask = 1 << 26
    
    freqout('A', 26, 1, 0)
    
    do
      waitpeq(mask, mask)
      high(27)
      waitpne(mask, mask)
      low(27)
    loop
    


    ...P27 never lights. Am I missing something with waitpeq and waitpne?
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-18 18:02
    JonnyMac wrote: »
    I've blown way past my alloted play time with xbasic today -- but I'm thinking about including a blurb in my March column so I'd like to have a few things sussed out.

    I can do this in Spin, and it works as expected (using PAB):
    set_freq("A", 26, 1)  
    
      repeat
        waitpeq(1 << 26, 1 << 26, 0)
        high(27)
        waitpne(1 << 26, 1 << 26, 0)
        low(27)
    


    The LED on P26 flashes (via the counter) and the LED on 27 tracks it via the code loop.

    If I translate that to xbasic like this:
    dim mask = 1 << 26
    
    freqout('A', 26, 1, 0)
    
    do
      waitpeq(mask, mask)
      high(27)
      waitpne(mask, mask)
      low(27)
    loop
    


    ...P27 never lights. Am I missing something with waitpeq and waitpne?
    I'm wondering if maybe I hand-assembled them wrong. I seem to remember some problem with one of those when I moved it over to ebasic3. I'll look into it tonight.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-18 19:03
    JonnyMac wrote: »
    I've blown way past my alloted play time with xbasic today -- but I'm thinking about including a blurb in my March column so I'd like to have a few things sussed out.

    I can do this in Spin, and it works as expected (using PAB):
    set_freq("A", 26, 1)  
    
      repeat
        waitpeq(1 << 26, 1 << 26, 0)
        high(27)
        waitpne(1 << 26, 1 << 26, 0)
        low(27)
    


    The LED on P26 flashes (via the counter) and the LED on 27 tracks it via the code loop.

    If I translate that to xbasic like this:
    dim mask = 1 << 26
    
    freqout('A', 26, 1, 0)
    
    do
      waitpeq(mask, mask)
      high(27)
      waitpne(mask, mask)
      low(27)
    loop
    


    ...P27 never lights. Am I missing something with waitpeq and waitpne?
    Didn't you determine a few days ago that t1 was not safe to use? It looks like the code in propeller.bas uses t1 a lot. I wonder if changing it to use t4 might make waitpeq and waitpne start working? If so I may have to do something to guarantee that t1-t4 are actually available to NATIVE instructions.
  • pjvpjv Posts: 1,903
    edited 2014-01-18 22:25
    David Betz wrote: »
    I'm afraid people are still misunderstanding the ASM and NATIVE statements in xbasic. There is no way that you could cut the PASM out of a Spin object and just convert it to NATIVE instructions and have it work. I only added the NATIVE bytecode to xbasic so that I could include a few PASM instructions in otherwise xbasic code. This was for PASM instructions like waitcnt, coginit, etc that are impossible to implement in xbasic. Coding anything else using NATIVE will not result in faster code since every NATIVE instruction is also a bytecode. The way to run PASM code fast is to bundle it into a blob that gets loaded into a COG. This is exactly what happens all the time in Spin objects except that the PASM blobs are inline in the Spin source. There is no inline assembly in Spin (although there probably will be in Spin2!). Even if I extend NATIVE to allow more than one instruction to be coded at a time and if I merge in the simple pasm.exe assembler, it still won't be good for more than a handful of PASM instructions at a time. My guess is that I can probably spare up to 16 COG locations for these PASM sequences which I don't believe will be enough to run any of the PASM code that is in OBEX. I'm happy that some of you have expressed an interest in xbasic and I'm willing to support it to do what it was originally intended for but it was never supposed to be a replacement for Spin or C. If you need a language with those capabilities I suggest you use one of those instead of xbasic. On the other hand, if you're interested in a version of Basic that is pretty fast and can execute code out of external memory, then xbasic may be good for you.

    David,

    If you do go down the path of letting a cog run some inline PASM code, then I would urge for the 16 long, or possibly a couple more. I would like to experiment with xBasic, knitting it together with my multi threading realtime kernel. Among other things, it has the capability of loading short (16 long) PASM snippets. So, while I'm not yet sure of the way this may all work, having the 16 longs available would likely be of considerable help.

    My intent would be to have multiple selections from a library of real time threads running simultaneous in a single cog under control of xBasic.

    Cheers,

    Peter (pjv)
  • JonnyMacJonnyMac Posts: 9,107
    edited 2014-01-19 00:03
    Didn't you determine a few days ago that t1 was not safe to use? It looks like the code in propeller.bas uses t1 a lot. I wonder if changing it to use t4 might make waitpeq and waitpne start working? If so I may have to do something to guarantee that t1-t4 are actually available to NATIVE instructions.

    I still don't quite understand the mechanics of the VM interface, but I did change to t4 and added drop -- these versions [seem to] work.
    def waitpeq(state, mask)
      asm
        lref 1              // get mask
        native 0xa0bc0805   // mov t4, tos
        drop
        lref 0              // get state
        native 0xf03c0a04   // waitpeq tos, t4
        returnx
      end asm
    end def
    
    
    def waitpne(state, mask)
      asm
        lref 1              // get mask
        native 0xa0bc0805   // mov t4, tos
        drop
        lref 0              // get state
        native 0xf43c0a04   // waitpne tos, t4
        returnx
      end asm
    end def
    
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2014-01-19 00:44
    Peter said
    If you do go down the path of letting a cog run some inline PASM code, then I would urge for the 16 long, or possibly a couple more.

    One thing that xbasic would be able to do that spin cannot is to be able to run cogs, then discard the code. This would only be applicable when running from external memory. With spin, there is a cost to running cog code as the code ends up taking up hub memory. But with xbasic running from external memory, you can fire off a cog, pass some parameters, set a flag when the cog has finished, then overwrite that cog with new code. You could be reloading a cog hundreds of times a second with different code each time. This would work with code we have now. You would just need to keep one cog free.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-19 04:36
    I started writing an internals document for xbasic which I've attached to this message. Once you read this I hope you'll understand why DROP is required in this code:
        lref 1              // get mask
        native 0xa0bc0805   // mov t4, tos
        drop
    
    Basically, LREF 1 pushes a value onto the stack. The NATIVE instruction doesn't change the stack at all so to clean up the stack after the NATIVE instruction completes you need to add DROP. If you neglect to add DROP you'll end up restoring the PC incorrectly when you execute the RETURN instruction at the end of the function.

    Obviously, I forgot to do that when I wrote the waitpeq function. I need to go through and check to see if there are any other instances of this type of omission. Thanks for catching it! Also, I think I'm going to add new temporaries that are used by the VM opcodes themselves so I can guarantee that t1-t4 are always available to NATIVE instructions.

    internals.pdf
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-01-19 05:13
    I thought that I would try some IO things, the snippet below compiles, but does not work as expected. When I run it in the debug screen, I see the > char, but when I key something in, it shows up on the edit screen. In the simple form of the program, without the 'ELSE IF', when I key in 'quit' it would not jump out of the loop. For some reason the GOTO is not working as expected in this format. The 'inputStr()' , not sure what the '0' refers too, but at one point when I changed it to a '1', I was getting an IO session on the debug screen, but in this instance, that is not working at the moment.

    Ray

    include "propeller.bas"
    include "print.bas"
    include "input.bas"
    include "string.bas"
    
    dim a(40) as byte
    
    do
        print "> ";
        inputStr(0,a)
        if strcpy(a,"quit")then
    	  GOTO gbye
        ELSE IF strcpy(a,"help") then
          help
        ELSE
          print "??"
        END IF
        
    loop
    
    gbye: 
    print "The END"
    END
    
    def help
      print "Menu - help, quit, "
    end def
    
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-19 05:28
    Rsadeika wrote: »
    I thought that I would try some IO things, the snippet below compiles, but does not work as expected. When I run it in the debug screen, I see the > char, but when I key something in, it shows up on the edit screen. In the simple form of the program, without the 'ELSE IF', when I key in 'quit' it would not jump out of the loop. For some reason the GOTO is not working as expected in this format. The 'inputStr()' , not sure what the '0' refers too, but at one point when I changed it to a '1', I was getting an IO session on the debug screen, but in this instance, that is not working at the moment.

    Ray

    include "propeller.bas"
    include "print.bas"
    include "input.bas"
    include "string.bas"
    
    dim a(40) as byte
    
    do
        print "> ";
        inputStr(0,a)
        if strcpy(a,"quit")then
    	  GOTO gbye
        ELSE IF strcpy(a,"help") then
          help
        ELSE
          print "??"
        END IF
        
    loop
    
    gbye: 
    print "The END"
    END
    
    def help
      print "Menu - help, quit, "
    end def
    
    I think you want "strcmp" to compare two strings not "strcpy".
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-01-19 06:04
    Thanks, I could of swore I saw strcmp() and not strcpy(), wishful thinking on my part. So I guess I have to try coding a strcmp() command. I was thinking of doing a straight forward 'if str1 AND str2 = 0', but it looks like AND only deals with numerical values. I guess I have to come up with a loop that compares each element of the string to see if they are the same, if they are, then it would designated as '0' if not then '1'. Now how do I convert each string element too its numeric value for comparison?

    Ray
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-19 06:08
    Rsadeika wrote: »
    Thanks, I could of swore I saw strcmp() and not strcpy(), wishful thinking on my part. So I guess I have to try coding a strcmp() command. I was thinking of doing a straight forward 'if str1 AND str2 = 0', but it looks like AND only deals with numerical values. I guess I have to come up with a loop that compares each element of the string to see if they are the same, if they are, then it would designated as '0' if not then '1'. Now how do I convert each string element too its numeric value for comparison?

    Ray
    strcmp should be a simple variant on strcpy. It's left as an exercise to the reader! :-)
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-01-19 10:52
    The more I get into xBasic the more I am starting to realize that it is a "barebones" language, just enough to get you started. Here is another quick and dirty user IO session, gives you enough of an idea to expand on the theme. You have to be careful with the input, it only excepts numerical values, if you put in a character it treats it like a 0 value. So, there is an opportunity for some one to improve on this theme, or not.

    Ray
    REM ==========
    REM testQS4.bas
    REM ==========
    include "print.bas"
    include "extra.bas"
    include "propeller.bas"
    include "input.bas"
    include "string.bas"
    /*
    * Using the QuickStart Board.
    */
    
        print "Hello, World!"
        high(17)     // Turn on LED
        waitMS(1000) // Wait one second.
        low(17)      // Turn off LED
        help     // Show menu
    /* User IO loop. */
    do
        print "> ";
        a = inputInt(0) // Get a number.
        if a = 0 then 
          GOTO lend  // If 0 break out of loop.
        else if a = 1 then
          help      // If 1 show Menu.
        else
          print "??"  // Number not listed.
        end if
    loop
    
    lend:
    print "The END"
    END
    
    /* Menu */
    def help
      print "Menu 0 - Quit"
      print "         1 - Help"
    end def
    
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-19 11:19
    Rsadeika wrote: »
    The more I get into xBasic the more I am starting to realize that it is a "barebones" language, just enough to get you started. Here is another quick and dirty user IO session, gives you enough of an idea to expand on the theme. You have to be careful with the input, it only excepts numerical values, if you put in a character it treats it like a 0 value. So, there is an opportunity for some one to improve on this theme, or not.

    Ray
    REM ==========
    REM testQS4.bas
    REM ==========
    include "print.bas"
    include "extra.bas"
    include "propeller.bas"
    include "input.bas"
    include "string.bas"
    /*
    * Using the QuickStart Board.
    */
    
        print "Hello, World!"
        high(17)     // Turn on LED
        waitMS(1000) // Wait one second.
        low(17)      // Turn off LED
        help     // Show menu
    /* User IO loop. */
    do
        print "> ";
        a = inputInt(0) // Get a number.
        if a = 0 then 
          GOTO lend  // If 0 break out of loop.
        else if a = 1 then
          help      // If 1 show Menu.
        else
          print "??"  // Number not listed.
        end if
    loop
    
    lend:
    print "The END"
    END
    
    /* Menu */
    def help
      print "Menu 0 - Quit"
      print "         1 - Help"
    end def
    
    By the way, the "inputInt" function isn't really intended to be called directly. The xbasic compiler automatically generates calls to it when you use the INPUT statement. I think you should be able to do this:
      input "> "; a
    
  • RsadeikaRsadeika Posts: 3,837
    edited 2014-01-19 11:39
    3.2 Simple Statements

    Here is a list of statements that stand by themselves:

    INCLUDE
    REM
    DEF3
    DIM
    IF4
    LET
    GOTO
    PRINT
    STOP
    END
    I usually go to the include folder and use what ever defs are in there, I did not see 'input' in the docs or the defs, as a stand alone statement. Is there an updated list of stand alone statements, and other things that are not in the docs?

    Ray
  • David BetzDavid Betz Posts: 14,516
    edited 2014-01-19 11:42
    Rsadeika wrote: »
    I usually go to the include folder and use what ever defs are in there, I did not see 'input' in the docs or the defs, as a stand alone statement. Is there an updated list of stand alone statements, and other things that are not in the docs?

    Ray
    I'm sorry to say that my friend Kenn Goutal who wrote the xbasic manual died a few years ago. I guess I need to update it to include newer features.
  • bsnutbsnut Posts: 521
    edited 2014-01-19 23:03
    David Betz wrote: »
    I'm sorry to say that my friend Kenn Goutal who wrote the xbasic manual died a few years ago. I guess I need to update it to include newer features.
    Its great to hear that you are going to add the newer features to a great program that you and Steve are willing to continue to support.

    I also thank Jon for posting a link to the XBasic site in the EFX-TEK support forums where I learned about this XBasic program to the Propeller chip, which is the brains for the EFX-TEK's HC-8 and would be fun hack (program) with XBasic since it has shift registers for the 8 TTL inputs.

    I will continue to follow this thread to keep up to date of what is going on with XBasic.
Sign In or Register to comment.