Shop OBEX P1 Docs P2 Docs Learn Events
PNut/Spin2 Latest Version (v52 - New MOVBYTS(), ENDIANL(), ENDIANW(), NEXT/QUIT <level>, DEBUG end) - Page 76 — Parallax Forums

PNut/Spin2 Latest Version (v52 - New MOVBYTS(), ENDIANL(), ENDIANW(), NEXT/QUIT <level>, DEBUG end)

1707172737476»

Comments

  • RaymanRayman Posts: 15,721
    edited 2025-08-18 22:19

    Said flash loader could also attempt to load from uSD, if desired, right?
    Could be useful if uSD is on different pins and/or has a power switch.

    Also, could maybe do something fancy like look for a backup boot file if the first one is missing...

    Also, guess this could allow for long file names and directories...

    4-pin uSD booting should be faster. Wonder if that'd make a difference...

  • Wuerfel_21Wuerfel_21 Posts: 5,650
    edited 2025-08-18 22:38

    @Rayman said:
    Said flash loader could also attempt to load from uSD, if desired, right?
    Could be useful if uSD is on different pins and/or has a power switch.

    Only if you can figure out how to hot-patch the SD boot code to do that - a full SD driver is probably too heavy for the 1024 bytes of bootloader space - just use the stock flash bootloader and then make the SD loader be the payload of that.

    @Rayman said:
    4-pin uSD booting should be faster. Wonder if that'd make a difference...

    You can make the SD boot A LOT faster as-is by making _BOOT_P2.BIX a tiny stub that sets the clock, patches some stuff in the ROM code and then pivots into a different boot file. I had one like that:

    CON _CLKFREQ = 300_000_000
    DAT
                  org 0
                  asmclk
                  '' Patch pullup check
                  wrlong #0,##$fc5b4 ' not sure why it fails but ok
                  '' Move filename into place
                  mov $1DC,name+0
                  mov $1DD,name+1
                  mov $1DE,name+2
                  drvh #38 ' Set LED
                  call #$fc578
                  drvl #38 ' Clear LED if fail
                  jmp #$
    
    name          byte "LOADTEST","BIX",0
    

    (as seen, this tries to load LOADTEST.BIX - also note the Pin 38 LED, change or remove that if necessary)
    Booting a large ~400K executable is a lot faster like that.

    You can also compress the executable you're booting. Flexspin and SpinTools have this option built-in, I also made a standalone version

  • ke4pjwke4pjw Posts: 1,230

    I can confirm this is a "me" problem. I am unsure why it does not boot properly, but I will figure it out. A simple program booted correctly from SD.

  • ke4pjwke4pjw Posts: 1,230

    Well, it's working as it should now. Maybe the card was flakey, but all is well now.

    The good news: No code changes for my code to work with PNUT v51a!

  • evanhevanh Posts: 16,778

    Chip,
    I just bumped into something that has changed in recent releases of Pnut. I don't know if this is an explicit change you intended or not. The following compiled and ran when I was compiling with Pnut v46:

        send( "SPI cmode: CPOL=", CPOL + "0", " CPHA=", CPHA + "0", 13,10 )
    

    But now, with Pnut v51a, I need to add an extra set of brackets as per the following:

        send( "SPI cmode: CPOL=", (CPOL + "0"), " CPHA=", (CPHA + "0"), 13,10 )
    

    Otherwise I basically get a syntax error. Pnut v51a reports a missing comma or closing bracket without the edit.

  • cgraceycgracey Posts: 14,284
    edited 2025-10-09 03:54

    There is a new version (v52) of PNut.exe at the top of this thread.

    v52 - 2025.10.08

    • New MOVBYTS(), ENDIANL(), ENDIANW() methods.

    • NEXT/QUIT now allowed to select nesting level of operation.

    • DEBUG(DEBUG_END_SESSION) now ends DEBUG session and exits PNut if -rd was used on command line.

    • New DEBUG Display TERM color commands for added simplicity.

  • @cgracey said:
    There is a new version (v52) of PNut.exe at the top of this thread.

    v52 - 2025.10.08

    • NEXT/QUIT now allowed to select nesting level of operation.

    Blimey! That arrived almost instantly! :smiley:

  • maccamacca Posts: 935
    edited 2025-10-09 10:03

    @cgracey said:

    • NEXT/QUIT now allowed to select nesting level of operation.

    Seems something is broken, I got an error on a simple if/else block:

    Can be reproduced also with the parser.spin2 (and other sources in the PNut package) example.

    Am i missing something ?

    Edit: worst than expected, seems that nothing can be added after a quit statement:

  • @macca Is a number now compulsory ? Does it work with "quit 0" or "quit 1" ?

    (Sure, that would be silly, but just an interesting test / workaround. I'm not able to try it at the moment).

  • maccamacca Posts: 935

    @VonSzarvas said:
    @macca Is a number now compulsory ? Does it work with "quit 0" or "quit 1" ?

    (Sure, that would be silly, but just an interesting test / workaround. I'm not able to try it at the moment).

    Ah, yes, with quit 1 it works (quit 0 is not valid since must be 1 to 16).

  • Oh goody. Might just need the default case adding back into the compiler.

    @cgracey
    May we have an override for "quit" and "next" without a parameter to behave like they used to, equivalent to "quit 1" and "next 1" ?

  • cgraceycgracey Posts: 14,284
    edited 2025-10-09 14:08

    Sorry, Guys!

    I see the problem. It's in my parsing of what comes after NEXT or QUIT. I need to back up when there is a line end, indicating there will be no constant.

    I will have this straightened up in a few hours.

  • cgraceycgracey Posts: 14,284
    edited 2025-10-10 00:09

    The new v52 is now posted on the OBEX and on Github.

    https://obex.parallax.com/obex/pnut-spin2-latest-version/

    NEXT and QUIT do not require integers after them, but an integer is needed if you want to NEXT/QUIT from outside your current REPEAT block. That integer would need to be a value of 2 or more.

  • cgraceycgracey Posts: 14,284
    edited 2025-10-10 00:14

    I added a new file into the .zip called PointerFlexibility.spin2. It gives coding examples of how you can use byte/word/long pointers. The same basic rules apply to structure pointers, as well.

    Here is that file, in case anyone wants to get a quick tour of pointers:

    {Spin2_v52}
    
    pub go() | ^byte p, byte buff[20]       'declare a byte pointer and a 20-byte buffer
    
      [p] := @buff                          'point the pointer to the buffer
    
      p[++].byte := $50                     'write a byte into the buffer, step pointer
      p[++].long := $77777777               'write a long, step pointer
      p[++].word := endianw($BEEF)          'write a big-endian word, step pointer
      p[++].byte := $01                     'write a byte, step pointer (.byte is for clarity, not needed)
      p[++].byte := $02                     'write a byte, step pointer
      p[++].byte := $03                     'write a byte, step pointer
      p[++].long := $FFFFFFFF               'write a long, step pointer
    
      debug(uhex_byte_array_(@buff,20))     'show the buffer
    
      [--]p.word := $5555                   'back up and write a word
      [++]p.word := $AAAA                   'move ahead and write a word
    
      debug(uhex_byte_array_(@buff,20))     'show the buffer
    
      p := $22                              'write a byte
      p[-1] := $33                          'write a byte at [-1]
    
      debug(uhex_byte_array_(@buff,20))     'show the buffer
    
      p++                                   'inc byte
      p[1]--                                'dec byte at [1]
    
      debug(uhex_byte_array_(@buff,20))     'show the buffer
    
      p~~                                   'set byte
      [--]p.long[-1].[31..28]++             'back up long pointer, increment top nibble of long at [-1]
    
      debug(uhex_byte_array_(@buff,20))     'show the buffer
    
    
    '
    ' Pointers are longs and they can be read/modified/written by putting brackets around them:
    '
    ' [p]                   'the actual pointer value (not the data being pointed to)
    ' @[p]                  'the address of the actual pointer value
    '
    '
    ' Once assigned, pointers can be used to read/modify/write the data they point to in
    ' these root syntax forms:
    '
    ' p                     'r/m/w the data being pointed to
    ' [++]p                 'pre-inc pointer by size, then r/m/w the data being pointed to
    ' [--]p                 'pre-dec pointer by size, then r/m/w the data being pointed to
    ' p[++]                 'r/m/w the data being pointed to, then post-inc pointer by size 
    ' p[--]                 'r/m/w the data being pointed to, then post-dec pointer by size 
    '
    '
    ' Any of these root syntax forms can be appended with an optional size override,
    ' an optional index, and an optional bitfield, in that order.
    '
    ' An optional size override starts with a period followed by BYTE/WORD/LONG:
    '
    '       .BYTE           'sets the data size to byte, regardless of the pointer data size
    '       .WORD           'sets the data size to word, regardless of the pointer data size
    '       .LONG           'sets the data size to long, regardless of the pointer data size
    '
    ' ...followed by an optional index in brackets:
    '
    '       [index]         'index gets scaled for byte/word/long addressing
    ' 
    ' ...followed by an optional bitfield, which is a period followed by a bitfield in brackets:
    '
    '       .[bitfield]     'selects a portion of the byte/word/long to read/modify/write
    '
    
  • VonSzarvasVonSzarvas Posts: 3,614
    edited 2025-10-10 05:01

    @cgracey said:
    The new v52 is now posted on the OBEX and on Github.

    https://obex.parallax.com/obex/pnut-spin2-latest-version/

    NEXT and QUIT do not require integers after them, but an integer is needed if you want to NEXT/QUIT from outside your current REPEAT block. That integer would need to be a value of 2 or more.

    .

    NEXT and QUIT can each be followed by an integer value 1..16 to alter the nesting level at which they are to occur. If no integer value is expressed, the default value of 1 is used, which means the current nesting level, The value 2 would mean the outer nesting level, while three would mean the next outer nesting level, and so on.

    What is the intended behavior when the nesting level integer exceeded the number of levels?
    For example, would QUIT maxLevel+1 be the same as QUIT maxLevel ? (Or should that throw a compiler error- or warning at least?...)

Sign In or Register to comment.