Shop OBEX P1 Docs P2 Docs Learn Events
FemtoBASIC for P2 - Page 3 — Parallax Forums

FemtoBASIC for P2

13

Comments

  • Mike Green wrote: »
    David,
    I plan to stick with FastSpin since it's multi-platform and I use a Mac normally. I can run PNut under Windows 10 using Parallels Desktop on the Mac, but it's awkward. I have an old Windows laptop too, but it's unreliable. I just wanted to see if I could move back and forth between FastSpin and PNut. At the moment, that doesn't seem to work.

    Cluso99,
    Thanks
    I think Eric eventually plans on supporting Chip's dialect of Spin2 but I don't know the timeframe for that.

  • RaymanRayman Posts: 13,892
    I think this kind of stuff should be fairly easy to port to Spin2... As you noticed, you need () on method calls. Also, the => and some other operators have changed.

    The real issue is all absolute addressing in FastSpin and all relative addressing in Spin2. But, I don't think you need that...
  • AribaAriba Posts: 2,682
    edited 2020-04-17 22:20
    Here is a modified version of FemtoDongle Basic
    This compiles and runs with PNUT and with Fastspin (flexGUI), so we can compare size and speed for Spin programs.

    A first test shows these results:
    list
    10 t = CNT 
    20 FOR i=1 TO 10000
    30 NEXT i
    40 PRINT (CNT - t) / 160000; " ms"
    OK
    
    Spin2:
    ------
    663 ms
    
    OBJ bytes:       7,120
    VAR bytes:       9,320
    Interpreter      4,088
    Total           20,528
    
    Fastspin:
    ---------
    190 ms
    
    Program size is 28032 bytes
    

    For sure the current version misses all the SD card commands yet.

    Andy
  • Thanks Andy. Next to be added is access to smart pins including named constants for configuring the smart pins. After that comes SD card I/O.
  • Wow! This is coming together really fast. I'd better get working on my BASIC interpreter or I'll be left in the dust! :smile:
  • Attached is the latest P2 FemtoBasic. I've added single dimension arrays and outputting to the console (with DISPLAY) works with 1 to 4 characters per write operation, LSB to MSB. The first character (LSB) is always written so you can output zero bytes. A single SD card file is allowed for now. None of the SD card I/O seem to work just yet, but the routines are the same as for the P1, so it shouldn't be long before that's working. A simple test program is:

    list
    100 DIM a[5]
    110 FOR i=1 TO 5
    120 a[i-1]=i*i
    130 NEXT i
    140 FOR j=1 TO 5
    150 PRINT a[j-1],j
    160 NEXT j
    170 END
    OK
    run
    1 1
    4 2
    9 3
    16 4
    25 5
    OK
  • Cluso99Cluso99 Posts: 18,069
    Nice job Mike :)
  • Nice work, Mike! How big is the executable? My junkbasic compiler is just starting to work and it is already over 140k!
  • So far it's about 33K plus another 16K shared between compressed program source and array storage. Keywords are replaced by single bytes. Multiple spaces outside of strings are eliminated. Named constants (mostly for smart I/O pin initialization) are replaced by single bytes. This is with optimization (-O2). Basic optimization (-O1) uses 50K and unoptimized (-O0) uses 64K
  • Mike GreenMike Green Posts: 23,101
    edited 2020-05-05 01:55
    Here's today's version of FemtoBasic for P2. More works. In particular, you can have

    100 dim a[5],b[5]

    This allocates 5 longs for each of two variables, a and b. In the rest of the program, you can refer to a[z] or b[z]. The arrays are zero-based and are not initialized when you RUN the program.

    You can use a format string like C's printf in PRINT USING or WRITE USING like

    110 print using "test %d and $%5x\n"; x, y

    Look starting at line 289 in the FemtoBasic source file for a comment explaining the details.

    What doesn't work yet ... SD card I/O - uses fsrw.spin2 and sdspi_bashed.spin2. It won't mount the SD card that came with my Evaluation Board. I can copy my binary file to it as _BOOT_P2.BIX and it loads and runs, but it won't mount with this fsrw library.

    I also haven't been able yet to get my flash to work using a modified P1 version of Winbond_Driver. Any SPI read transfers come back as ones. I do have the FLASH switch on. Any suggestions for a Spin driver I can use as a model?
  • Your implementation of PRINT USING sounds nice.
  • Feel free to incorporate those routines (consoleXXX) in anything where they might be useful. I really had intended that FemtoBasic be used as a tool with special purpose statements added to help with debugging hardware or software libraries.
  • Cluso99Cluso99 Posts: 18,069
    Mike Green wrote: »
    Here's today's version of FemtoBasic for P2. More works. In particular, you can have

    100 dim a[5],b[5]

    This allocates 5 longs for each of two variables, a and b. In the rest of the program, you can refer to a[z] or b[z]. The arrays are zero-based and are not initialized when you RUN the program.

    You can use a format string like C's printf in PRINT USING or WRITE USING like

    110 print using "test %d and $%5x\n"; x, y

    Look starting at line 289 in the FemtoBasic source file for a comment explaining the details.

    What doesn't work yet ... SD card I/O - uses fsrw.spin2 and sdspi_bashed.spin2. It won't mount the SD card that came with my Evaluation Board. I can copy my binary file to it as _BOOT_P2.BIX and it loads and runs, but it won't mount with this fsrw library.

    I also haven't been able yet to get my flash to work using a modified P1 version of Winbond_Driver. Any SPI read transfers come back as ones. I do have the FLASH switch on. Any suggestions for a Spin driver I can use as a model?

    Have you checked the SD Card is SDHC and sector addressing (ie not byte addressing)? Basically 8GB cards and up should be sector addressing. There was some cutoff around 2-4GB IIRC.
    I see with a quick look at the sdspi_bashed.spin2 has a PUB doSDHC(n). The response should be 0.
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-05-05 04:28
    Mike,
    You can try running my SD Driver that I published today.

    Postedit:
    I just posted a demo that only reads sector 0 (ie does not write)

    Disable the read/write sections (shown below) and recompile (or you can risk writing to sector 1)

    When it initialises the sd card, the reigsters at $100-$120 are displayed.

    cmdout $100 should be $50 ($50 00 00 00) - this is the last command sent to the card
    cmdpar2 $1003 should be $00 00 00 40 for SDV2 card, $00 00 00 00 for SDV1 (really old card)
    blocksh $10C should be $0 if it is SDHC+ sector addressing else $9 if an old byte addressing card
    '   +-----------------------------------------------------------------------------+
    
        REG[sd.bufad]   := $FC100                           ' sector buffer location in hub
        REG[sd.sector]  := $0000_0000                       ' sector number
        CALL(sd.readSector)                                 ' read the sector
    
        REG[mon.p]      := $FC100                           ' display the sector data read
        REG[mon.p2]     := $FC300                           '
        CALL(mon.TxListA2)                                  ' print list hub (f=List+Addr2)
    
        CALL(mon.TxCR)                                      ' print crlf
    '   +-----------------------------------------------------------------------------+
    
    ' read sector...
        REG[sd.bufad]   := $FC100                           ' sector buffer location in hub
        REG[sd.sector]  := SECTOR_NUM                       ' sector number
        CALL(sd.readSector)                                 ' read the sector
    
        REG[mon.p]      := $100                             '
        REG[mon.p2]     := $120                             '
        CALL(mon.TxListA2)                                  ' print list cog $000-$020 (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
        REG[mon.p]      := $FC100                           ' display the sector data read
        REG[mon.p2]     := $FC300                           '
        CALL(mon.TxListA2)                                  ' print list hub (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' save sector (1st long)...
        SAVEME          := long[$FC100]                     ' 1st long of BUF
        REG[mon.x]      := SAVEME
        CALL(mon.TxHex8)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' change sector (1st long)...
        long[$FC100]    := "b"+"l"<<8+"u"<<16+"e"<<24       ' overwrite 1st long of BUF
        REG[mon.x]      := long[$FC100]                     ' 1st long of BUF
        CALL(mon.TxHex8)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' write modified sector...
        REG[sd.bufad]   := $FC100                           ' sector buffer location in hub
        REG[sd.sector]  := SECTOR_NUM                       ' sector number
        CALL(sd.writeSector)                                ' write the sector
    
        REG[mon.p]      := $100                             '
        REG[mon.p2]     := $120                             '
        CALL(mon.TxListA2)                                  ' print list cog $000-$020 (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' read modified sector...
        REG[sd.bufad]   := $FC100                           ' sector buffer location in hub
        REG[sd.sector]  := SECTOR_NUM                       ' sector number
        CALL(sd.readSector)                                 ' read the sector
    
        REG[mon.p]      := $100                             '
        REG[mon.p2]     := $120                             '
        CALL(mon.TxListA2)                                  ' print list cog $000-$020 (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
        REG[mon.p]      := $FC100                           ' display the sector data read
        REG[mon.p2]     := $FC300                           '
        CALL(mon.TxListA2)                                  ' print list hub (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' restore original sector (1st long)...
        long[$FC100]    := SAVEME                           ' put back to original
        REG[mon.x]      := long[$FC100]                     ' 1st long of BUF
        CALL(mon.TxHex8)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' write back original sector...
        REG[sd.bufad]   := $FC100                           ' sector buffer location in hub
        REG[sd.sector]  := SECTOR_NUM                       ' sector number
        CALL(sd.writeSector)                                ' write the sector
    
        REG[mon.p]      := $100                             '
        REG[mon.p2]     := $120                             '
        CALL(mon.TxListA2)                                  ' print list cog $000-$020 (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
    ' read the sector again...
        REG[sd.bufad]   := $FC100                           ' sector buffer location in hub
        REG[sd.sector]  := SECTOR_NUM                       ' sector number
        CALL(sd.readSector)                                 ' read the sector
    
        REG[mon.p]      := $100                             '
        REG[mon.p2]     := $120                             '
        CALL(mon.TxListA2)                                  ' print list cog $000-$020 (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
        REG[mon.p]      := $FC100                           ' display the sector data read
        REG[mon.p2]     := $FC300                           '
        CALL(mon.TxListA2)                                  ' print list hub (f=List+Addr2)
        CALL(mon.TxCR)                                      ' print crlf
    
    '   +-----------------------------------------------------------------------------+
    
  • Here's another FemtoBasic, this time with flash memory access. I'm really just starting to debug the new features, but it does talk to the flash memory and can count up the number of erased blocks. Arrays and PRINT USING seem to work. I still haven't gotten FSRW and SDSPI to work. I'll be working on the documentation and debugging before I add anything else over the next few days.
  • Cluso99Cluso99 Posts: 18,069
    Mike,
    This should be a simple drop in to your FemtoBasic.
    Replace sdspi_bashed.spin2 with SDexample.spin2

    Notes:
    The getCSD routine will need to have the buffer as 32 bytes long as my routine returns the CSD followed by the CID in one block.
    The start routine does not require the pins as I use the default pins, but you will instead need to provide the address of a sector buffer although I am fairly certain I don't actually use it (forgot to check). You can provide $FC100 which is the ROM section of hub which is usable. The start routine will copy the SD Driver code up into hub ROM area for use there.

    The code uses registers $100-10F but can be compiled for a different location. Same applies for the SD Driver hubexec ROM position. Two lines are in SDDriver_Equ.spin2.

    BTW I think the reason fsrw does not work is it requires an old SD card with byte addressing instead of sector addressing. You'll probably need a card with <=1GB.
  • The last version of FSRW seemed to work with both kinds of SD cards. I'll check.

    Attached is a quickly edited manual for FemtoBasic for the P2. I'll get back to the SD card version in a couple of days. The P1 flash version of FemtoBasic worked pretty well. There was no file updating in place, but you could load and save programs. You needed to copy files to change or append to them. The "wear leveling" was pretty minimal.
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-05-07 05:10
    Mike,
    Just been looking at your code to see how to compile and discovered this
      _clkfreq      = 297_000_000		'set clock frequency
      _XTALFREQ     = 20_000_000                                    ' crystal frequency
      _XDIV         = 4             '\                              '\ crystal divider                      to give 5.0MHz
      _XMUL         = 72            '| 180MHz                       '| crystal / div * mul                  to give 360MHz
      _XDIVP        = 2             '/                              '/ crystal / div * mul /divp            to give 180MHz
      _XOSC         = %01                                   'OSC    ' %00=OFF, %01=OSC, %10=15pF, %11=30pF
      _XSEL         = %11                                   'XI+PLL ' %00=rcfast(20+MHz), %01=rcslow(~20KHz), %10=XI(5ms), %11=XI+PLL(10ms)
      _XPPPP        = ((_XDIVP>>1) + 15) & $F                       ' 1->15, 2->0, 4->1, 6->2...30->14
      _CLOCKFREQ    = _XTALFREQ / _XDIV * _XMUL / _XDIVP            ' internal clock frequency                
      _SETFREQ      = 1<<24 + (_XDIV-1)<<18 + (_XMUL-1)<<8 + _XPPPP<<4 + _XOSC<<2  ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_00  ' setup  oscillator
      _ENAFREQ      = _SETFREQ + _XSEL                                             ' %0000_000e_dddddd_mmmmmmmmmm_pppp_cc_ss  ' enable oscillator
    
    _clkfreq should be set to 180MHz for those calcs.
    Am I missing something???
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-05-07 06:44
    <deleted>
  • Cluso99Cluso99 Posts: 18,069
    edited 2020-05-07 06:46
    Working :)

    Only tested FILES command and it lists my sd card files :)

    Only SD cards with block addressing are supported which should be all cards >2GB

    I only changed the OBJ call in fsrw.spin2 to use sdspi_208.spin2 instead. All existing calls should work.

    Note there is a bug in fastspin 4.1.8 which will be fixed in the next release so I have had to force the return value of $00 until it is fixed (see sdspi_208.spin2)
  • Cluso99,
    Thanks for the help. I suppose with the preprocessor in FastSpin, I ought to be able to keep one source for either flash or SD card I/O. I saw your comment about the bug in FastSpin 4.1.8 and I don't think it affects what I have.
  • RaymanRayman Posts: 13,892
    FSRW with spi_bashed works with my 8 GB card, it just has trouble mounting....

    I have to remove the card and then stick it back it to get it to mount...

    Think it has something to do with the pullup resistors on those pins.
    Going to try to fix that soon...
  • RaymanRayman Posts: 13,892
    Actually, I think I've decided that one of my usd cards just has some flaw that makes me have to depower to reuse...
    I tried a different low level code on it that worked on several different cards and it had the same problem.

    Just tried on a new 64 GB card (formatted as 32 GB FAT32) and it works fine.
    I have made what I think are some improvements to spi_bashed though.
  • RaymanRayman Posts: 13,892
    @Cluso99
    Your zip file seems to be missing "Windbond_Driver.spin2"
  • Here's Windbond_Driver.spin2
  • Latest version. SD card I/O doesn't work yet. Flash files not tested, but you can read & write data and erase 4K sectors. There's a lot yet to test, but most of it seems to work. It's pretty fast thanks to FastSpin producing hub instructions.
  • Here's a test program. It goes through flash sectors looking at the first 16 bytes of each 4K sector, counting the stretches of erased (all $FF) vs not erased (some not $FF) sectors and displaying the counts. The Winbond_Driver file system uses the first 16 bytes to record the file name and segment # of the file along with a link to the next segment. FemtoBasic is stored at the beginning of the flash memory for loading on boot.
  • A number of bugs have been fixed. FILES, SAVE, LOAD, and DELETE work with flash memory. OPEN, CLOSE, READ, and WRITE are next to do.
  • Here's the current flash memory version of FemtoBasic. It needs some more testing and documentation, but I've been able to run some non-trivial test programs with it.

    I've been having a great deal of difficulty getting SD card file system support working. It should be almost a "drop in" substitute for the flash memory driver, but it's not yet. I'll try again in a week or two.
  • Cluso99Cluso99 Posts: 18,069
    Mike,
    Here is a version (from a while ago) with the required fixed so that it compiles (and runs a bit) with pnut v34S.

    I added a 5s delay to get PST running on my PC after the download.

    Winbond Flash support has been removed - 3 "flash." lines commented out and the OBJ definition.
    This is going to be a "biggie" as you are using inline pasm and I'm not sure how pnut handles it. I started changing the waitx(5) to waitms(5) when I realised this isn't going to work with bit-bashing the flash, so just trash the windbond driver from the zip.

    Now the bug(s) with the pnut compilation. There is an issue with receive characters from the PC. I get the version message just fine, and I can type "files" and enter but it returns "syntax error". This works fine with fastspin 4.1.8 compilation (just remember to wait the 5s after download).

    BTW I've only tried the "files" command. I'll leave the rest for you to debug.

    BTW2 pnut complained about a duplicate definition of massFlag which is defined in a VAR and a PUB xxx(massFlag) calling parameter, whereas fastspin did not complain.

    BTW3 The winbond driver only has <lf> which pnut cannot handle. I've changed them to <crlf> in the zipped file.

    Here is the code. Enjoy :)
Sign In or Register to comment.