FlexGUI 4.2.4: Program your P2 in Spin, BASIC, or C

1356

Comments

  • Eric, I get the attached error message when I try to run FlexGui 4.1.4
    409 x 292 - 30K
  • Andy: Thanks for the bug report. Ouch! I made one last minute change and of course it broke the most important part (startup) but in such a way that my testing didn't show it. There's a new .zip file (flexgui414b.zip) that shold fix the startup problem.
    Ariba wrote: »
    Does ORG .. END produce Cog code, like Spin2 does? I've found that small loops in inline assembly work much faster in Spin2 because of the faster jumps in cogexec. A simple pin toggle is about 2.6 times faster, this can be important if you need the speed.
    No, ORG .. END still produces hubexec code. However, if you compile with option -O2 loops get copied into LUT memory (in a form of FCACHE) before execution. This happens for inline assembly too as long as you don't use "asm const" to suppress optimization.


  • Okay this new ZIP works.

    Here are some errors I've found when I try to compile a bigger PNUT Spin2 file:
    - Ternary operator ? : gives syntax error in fastspin.
    - SQRT is not an operator, fastspin still uses ^^.
    - PINSTART(), PINSETUP(), PINCLEAR() methodes (and maybe others) are not yet implemented.
    - with inline assembly the following does not work (tooks me quite a bit of debugging to find):
        shr   val,#1   wc
        drvc  #pin
    
    DRVC always drives low, eigther the carry gets not set, or drvc produces a wrong opcode.

    There are a lot of subtile changes in Spin2 compared to Spin1, which Fastspin not implements yet. The very simple blink1.spin2 example needs the following modifications to compile in PNUT:
    con
      _clkfreq = 160_000_000
      pin = 56
      delay = _clkfreq / 10
    
    pub demo()                   '<-- ( ) required
      dirb.[pin-32] := 1         'dot for pin/bit index
      repeat
        != outb.[pin-32]         '!= instead of ! and again the dot
        waitcnt(cnt + delay)
    
    I wonder if implementing all those changes will not break most of the code that is already made with fastspin. i.e. Rayman has written alot of fastspin-Spin2 code.

    Andy
  • ersmithersmith Posts: 4,231
    edited 2020-04-06 - 11:49:05
    Thanks Andy. Some comments below:
    Ariba wrote: »
    - Ternary operator ? : gives syntax error in fastspin.
    In fastspin, for now, the first argument to the ternary operator has to have parentheses around it in order to distinguish it from the random operator, so you would write "(a) ? b : c" rather than "a ? b : c". I may change this for .spin2 files, but I'll leave it as it is for .spin because ? does have a meaning for .spin files.
    - SQRT is not an operator, fastspin still uses ^^.
    - PINSTART(), PINSETUP(), PINCLEAR() methodes (and maybe others) are not yet implemented.
    I haven't had a chance to get to these yet.
    - with inline assembly the following does not work (tooks me quite a bit of debugging to find):
        shr   val,#1   wc
        drvc  #pin
    
    DRVC always drives low, eigther the carry gets not set, or drvc produces a wrong opcode.
    I'm not able to reproduce this. Could you provide some context? For example, the following program works as I would expect:
    CON
      pin = 56
      _clkfreq = 160_000_000
      
    PUB main | val
      repeat
        val := %10101010
        repeat 8
          asm
            shr val, #1 wc
            drvc #pin
          endasm
          waitx(_clkfreq/5)
    
    There are a lot of subtile changes in Spin2 compared to Spin1, which Fastspin not implements yet. The very simple blink1.spin2 example needs the following modifications to compile in PNUT
    Yes, fastspin so far only implements the part of Spin2 that is compatible with Spin1 (with a very few exceptions). I really should not have named my examples with .spin2 extensions. Originally I thought ".spin2" would mean "Spin with P2 assembly code", or "Spin which only works on a P2". But that's wrong, it turns out that .spin2 is not compatible with .spin :(.

    I'm slowly making the changes to make fastspin behave differently for .spin2 files and .spin files. All my .spin2 examples should just be renamed to .spin, and I plan to do that in the next release. Fastspin accepts a lot of spin2 features (like multiple return values, method pointers, and some of the new operators whose names can't conflict with existing variables) in .spin files, and that will continue to be the case.
    I wonder if implementing all those changes will not break most of the code that is already made with fastspin. i.e. Rayman has written alot of fastspin-Spin2 code.

    The existing fastspin extended Spin1 dialect will not change, at least as much as I can help it. That is, existing fastspin code which is basically Spin1 for P2, with a few Spin2 features that are compatible with Spin1, should keep working. The file name may have to change. I wish there were a nice extension that would mean "Spin1 for P2". Maybe we could use .spin_p2 instead of .spin2, or something like that.

    The parts of Spin2 that are incompatible with Spin1 will only be activated when a .spin2 file extension is seen. So Rayman may have to rename his files, but he shouldn't have to change his code.
  • ersmith wrote: »
    I wish there were a nice extension that would mean "Spin1 for P2". Maybe we could use .spin_p2 instead of .spin2, or something like that.

    The obvious solution here is to use .spin1½ :smile:

    Or more seriously, maybe just .spin1?
  • ersmith wrote: »
    The existing fastspin extended Spin1 dialect will not change, at least as much as I can help it. That is, existing fastspin code which is basically Spin1 for P2, with a few Spin2 features that are compatible with Spin1, should keep working. The file name may have to change. I wish there were a nice extension that would mean "Spin1 for P2". Maybe we could use .spin_p2 instead of .spin2, or something like that.

    The parts of Spin2 that are incompatible with Spin1 will only be activated when a .spin2 file extension is seen. So Rayman may have to rename his files, but he shouldn't have to change his code.
    This is interesting. It seems like we have to ways of thinking about the dialects of Spin. One is that "Spin" is for P1 and "Spin2" is for P2. The other is that they are different languages and either can target either P1 or P2 (or potentially other non-Parallax processors as well).

  • Thank's Eric for the detailed response.
    ersmith wrote: »
    ...
    I'm not able to reproduce this. Could you provide some context? For example, the following program works as I would expect:
    ...

    Here is the methode that works in Spin2, but not with Fastspin:
    PUB spiWord(val) | i,ce,do,ck       '' send a word over SPI (fast)
      ce,do,ck := cs_pin,sdo_pin,sck_pin
      org
              drvl    ce
              shl     val,#16
              mov     i,#16
      wloop   shl     val,#1  wc
              drvc    do
              drvl    ck
              nop
              drvh    ck
              djnz    i,#wloop
              drvh    ce
      end
    
    I got all zeroes at the SPI device, so I concluded it must be the data out.
    But after some more investigation, I think it may be a timing problem. If I insert another NOP before the DJNZ, it works. The listing shows me that Fastspin changes the PASM code to a REP loop instead of the DJNZ. I'm not sure if it is a good idea to optimize inline assembly, sometimes you want to have control over the exact timing. But I would expect that in Hubexec a REP loop also needs to reload the FIFO when it jumps back, which adds a delay anyway. So why does the NOP fix it? Need to make a few more tests...
  • It's really a timimg problem.
    The CS pin goes high too fast after the last clock, because after a REP loop there is no delay. But with a DJNZ loop there is a delay, also if the jump is not taken.
    This just shows how dangerous optimization of PASM code is.

    Andy
  • Wow! Eric, does your compiler actually optimize PASM? That's got to be a whole different set of rules than what happens to optimize Spin, right? Or, is there some point at which the compiler does an optimization pass on whatever initial PASM code was generated, be it from a high-level language or even in-line PASM?
  • @Ariba:

    There are sometimes good reasons to optimize inline assembly:

    (1) Some of the compiler's own functions are implemented with inline assembly, and I *want* those to be optimized. And in general small functions which are inlined, even ones written in asm, can benefit from being optimized depending on the code that invokes them.
    (2) Some users write inline assembly in an effort to speed up their code. Sometimes the compiler can do better than those users (surprisingly often, in general, although probably not so often for the early adopters of the P2).

    (I'll also note that inline assembly in general is probably best avoided; usually it's better to write high level code.)

    That said, yes, there are times when you do not want the compiler to touch your code, if it's got sensitive timing. Nothing in a DAT section is ever optimized; only inline assembly is. And in C, at least, you can specify inline assembly as "__asm const" or "__pasm const" to tell the compiler not to touch it. I guess there should be something similar for Spin. Perhaps the ORG/END style blocks could be treated like "__asm const" whereas ASM/ENDASM are like "__asm".

    @cgracey:

    There are two sets of optimizations in fastspin: high level optimizations applied to the parse tree (which can do things like constant folding, loop strength reduction, and common sub-expression elimination) and low level optimizations applied to the generated assembly code. Inline assembly is potentially subject to the second set of optimizations; from the compiler's perspective user code is treated just like compiler generated code. There is a way to mark code so the optimizer leaves it alone. I haven't exported that to Spin yet, but in fastspin's C dialect you can mark an inline assembly block as "const" to tell the optimizer not to touch it.

    DAT blocks (top level pasm blocks in C) are never optimized, and actually go through a different path than inline assembly.
  • RaymanRayman Posts: 11,051
    edited 2020-04-06 - 23:45:15
    Personally, I'd like Fastspin and Spin2 to be as close as possible...
    Even if it means rewriting some code...
    Except that I like prefer the absolute addressing scheme in Fastspin, so please don't change that!
  • ersmith wrote: »
    @Ariba:

    There are sometimes good reasons to optimize inline assembly:

    (1) Some of the compiler's own functions are implemented with inline assembly, and I *want* those to be optimized. And in general small functions which are inlined, even ones written in asm, can benefit from being optimized depending on the code that invokes them.
    (2) Some users write inline assembly in an effort to speed up their code. Sometimes the compiler can do better than those users (surprisingly often, in general, although probably not so often for the early adopters of the P2).

    (I'll also note that inline assembly in general is probably best avoided; usually it's better to write high level code.)

    That said, yes, there are times when you do not want the compiler to touch your code, if it's got sensitive timing. Nothing in a DAT section is ever optimized; only inline assembly is. And in C, at least, you can specify inline assembly as "__asm const" or "__pasm const" to tell the compiler not to touch it. I guess there should be something similar for Spin. Perhaps the ORG/END style blocks could be treated like "__asm const" whereas ASM/ENDASM are like "__asm".

    Yes, there are up and downsides of PASM optimizations. I just have it not expected , and therefore tried to find the error in my assembly source. Now I know: I have to look at the listing first.

    If you make ORG .. END special, so that it not optimizes PASM, I would suggest that it also forces caching at the same time. This would mimic Spin2 behavior best.

    Funnily enough the above SPI code worked with full optimization, because only the loop get cached and there was a jump back before the CS high instruction. It was noticable faster with full opt. but some other part of the code got messed up. So it would be great we have a way to fully optimize only critical parts of the code.

    Andy
  • I've released FlexGUI 4.1.5. This has much improved Spin2 support (e.g. it can compile Chip's vga demo) and many bug fixes. It's available at the usual github repository and from my Patreon page.

    As a bonus for my Patreon subscribers I've posted instructions there for using the (still in progress and not yet finished) file I/O features of the standard library to read/write from SD cards or the host PC. When this feature is fully working I'll add the documentation to the github release too.
  • Version 4.1.6 is now available on github (see the link to FlexGUI in my signature for direct access to the binary).
  • Interesting... You have some C code working for SD card I/O?

    Will that be available to Spin code?
  • @ersmith flexgui.exe is missing in the 4.1.6 release. Is this unchanged from previous release?
  • dMajo wrote: »
    @ersmith flexgui.exe is missing in the 4.1.6 release. Is this unchanged from previous release?

    FlexGui.exe was in my download today from Github. (Flexgui.zip for windows)
  • Rayman wrote: »
    Interesting... You have some C code working for SD card I/O?

    Will that be available to Spin code?

    Eventually.
  • dMajo wrote: »
    @ersmith flexgui.exe is missing in the 4.1.6 release. Is this unchanged from previous release?

    It's in the top level directory in the .zip file I just looked at. It used to be duplicated in the bin/ directory as well, but that was just due to a mistake (it never should have been in bin).
  • ersmith wrote: »
    Rayman wrote: »
    Interesting... You have some C code working for SD card I/O?

    Will that be available to Spin code?

    Eventually.

    That would be excellent.
  • ersmith wrote: »
    dMajo wrote: »
    @ersmith flexgui.exe is missing in the 4.1.6 release. Is this unchanged from previous release?

    It's in the top level directory in the .zip file I just looked at. It used to be duplicated in the bin/ directory as well, but that was just due to a mistake (it never should have been in bin).

    Thanks. I usually overwrite with the new release and then I look for the file's timestamp (I've noted, and much appreciate it, that you timestamp the whole archive with the same data).
    This time I found flexgui still from 18th of April in bin folder.

    Thanks for the reply and for doing this wonderful job
  • Eric

    Thank you for implementing LOCKTRY and LOCKREL.
    Unfortunatly LOCKTRY() gives the inverted result compared to PNUTs Spin2. The listing shows that you write the Carry to the result var with:
    muxnc result1,##-1
    while Spin2 uses MUXC

    Andy
  • Cluso99Cluso99 Posts: 16,256
    edited 2020-04-25 - 05:03:33
    Eric,
    I just tried compiling my Monitor Demo in spin2 with Fastspin 4.16.

    It does not like the "mon." prefix in the pasm operands. I presume you've not got around to this yet.
    OBJ
        mon : "RamMonitorEqu"           ' "RamMonitorEqu.spin2"     register & call equates
    .....
    DAT
    entry       mov         mon.bufad,        ##mon.BUF     ' locn of hub buffer for serial routine 
    
    Code is posted here
    forums.parallax.com/discussion/171502/p2-replacing-the-rom-monitor-debugger-and-calling-from-spin-or-pasm
  • Hi Eric,
    I've just tried out FlexGUI 4.1.6 and I noticed that you've added some colour to the text editor. The #includes now have links so we can easily open included files which is very useful.

    However, not all of the links work all the time. If one of the header files has an error and I click on the link in the compiler message window I get a popup dialog saying "*.h not found" even if that file is already open in the editor window. And even more strange, if I click OK I get an application error "invalid command .txt".

    You probably forgot to set the current directory to the folder of the top level source file. That would be a good idea anyway as it would make calling commands (menu - commands - configure commands) much easier as it'd be no longer required to give the full path of all file names.
    857 x 623 - 37K
    433 x 288 - 13K
  • I think I'm seeing that the latest loadp2.exe doesn't need any crystal settings, baud or com port arguments.
    That's nice. I'm going to switch SpinEdit over to removing these things.

    Does the mac version work the same way? I haven't tried SpinEdit with Wine in a long time... If so, might try that again.
  • @ManAtWork : thanks for the bug report. I think that problem is fixed in 4.1.7, which is now available on github and patreon.

    @Rayman: loadp2 should work the same on all platforms.

  • RaymanRayman Posts: 11,051
    edited 2020-04-28 - 18:43:27
    ersmith wrote: »
    ...
    As a bonus for my Patreon subscribers I've posted instructions there for using the (still in progress and not yet finished) file I/O features of the standard library to read/write from SD cards or the host PC. When this feature is fully working I'll add the documentation to the github release too.

    Looks like another option might be to use this:
    http://elm-chan.org/fsw/ff/00index_e.html
  • Isn't the SD access that Eric has in C based on that?
  • @Rayman: As Jon said, that's exactly the code that's in the fastspin C library already for FAT based SD card read/write. There's also a Plan 9 file system for accessing the host PC's files. Both of these are accessible via standard C library calls like fopen().
  • ersmith wrote: »
    @Rayman: As Jon said, that's exactly the code that's in the fastspin C library already for FAT based SD card read/write. There's also a Plan 9 file system for accessing the host PC's files. Both of these are accessible via standard C library calls like fopen().
    And I can say that the PC host filesystem works fine. I use it in my BASIC interpreter line editor for saving and loading files. The directory functions work as well and I use them for the "cat" command that lists a "catalog" of ".bas" files. I haven't tried the SD filesystem yet.

Sign In or Register to comment.