Shop OBEX P1 Docs P2 Docs Learn Events
Testing the new Fastspin Assembly, Spin, BASIC, and C for P1 — Parallax Forums

Testing the new Fastspin Assembly, Spin, BASIC, and C for P1

rsutrsut Posts: 45
edited 2019-09-04 14:24 in Propeller 1
I thought I would start this new thread for users trying out Fastspin basic rather than posting to the author's thread which focuses on the development.
Hopeful the author will make suggestions to users that post code here. Reading the thread, there are going to be some changes to fastspin basic which may, effect the syntax a little, but hopefully not the style.

My first contribution, a very simple piece of code to demonstrate a function using fsrw.spin and FullDeplexSerial.spin which I tried whilst exploring fastspin(basic). There are probably better ways to do this. Fastspin(basic), is still in under development so do expect to have to make changes.
rem very simple test of a fastspin(basic)function with fsrw26.and FullDuplexSerial. 
rem
rem test  returns a value from spin object.
rem  abort is a known issue ATM, refered to author of fastspin(basic)
rem   compile code code with ...............propeller-load -e -p<com port> -r -t  %1.eeprom
rem   load eeprom with....... .................  fastspin --fcache=0 -e -O1 %f

dim sd as class using "fsrw.spin"
dim ser as class using "FullDuplexSerial"
dim mode as ubyte
dim file_name as string
dim text as string
dim len as integer

function wrfile(file_name$, text$,  len) 
     dim message as string
     dim x as integer
     message =  "Writing file done......  val returned from pub sd.popen  h_"
     mode= asc("w")
     x=sd.popen(file_name$,mode)
     sd.pwrite(text$,len)
     sd.pclose()
     ser.str(message) 
     ser.hex(x, 4)     
 end function
 
REM Test wrfile function
ser.start(31,30,0,115200)
pausems (1000)
sd.mount(0) 	
wrfile("data5.txt","This is a test",14)
sd.unmount()




Give it a try
Ron
«1

Comments

  • Cluso99Cluso99 Posts: 18,069
    edited 2018-10-18 11:47
    I see that you can use existing spin object. That's really nice :)
    Thanks for posting
  • Thanks for starting this thread, Ron.

    I don't think there will be any major changes to syntax that will affect existing fastspin BASIC programs now, but I am adding new features. Definitely one thing I want to add is an easy way to use BASIC functions like print with the fsrw (and similar) objects.

    (BTW, try/catch is in the current source code repository and seems to be working. I hope to make a new binary release this weekend.)
  • rsutrsut Posts: 45
    edited 2018-10-20 08:14
    I did some more tests last night.

    These functions seem work OK. I need to look at the returns from spin methods more closely,
    so that I can use them, but at the moment I can't catch *aborts* so I can't see the return results.
    Fsrw.spin has countless * aborts*

    I understand we might see a new exe version next week. Eric has included a try/catch scheme in the upcoming release.

    Writing fastspin(basic) feels quite intuitive, but having used propbasic for a while and without LMM
    (although it's available) I'm not yet comfortable with how to best write code to minimise the code size.

    I do like the fact than you can use spin instructions in fastspin(basic)

    I have yet to look at writing code for a cog with fastspin basic.

    Here is my take on functions coded in fastspin basic.
    rem A test of fastspin(basic) function with fsrw26.and FullDuplexSerial. 
    rem last updated 19/10/18
    rem  test  return value from spin methods.
    
    
    
    rem   compile code code with ...............propeller-load -e -p<com port> -r -t  %1.eeprom
    rem   load eeprom with....... .................  fastspin --fcache=0 -e -O1 %f
    
    dim sd as class using "fsrw.spin"
    dim ser as class using "FullDuplexSerial"
    
    REM ====================GLOBAL Variables ======================
    
    dim ubuf(256) as ubyte      REM   buffer for read_file   256  is a dummy val  to test function
    dim mode as ubyte             REM   Holder of  vals asc "a",asc"r",asc"w",asc"d" 
    dim file_name$ as string    REM   File name str--Only one file can be opened at any one time in  fsrw.spin
    dim lx as word                   REM  Used in Subs and Func to hold str(len)
    dim rtx as word                 REM   Holder of val ireturned from a spin  method
    dim message as string       REM   General purpose message holder
    dim fcnt as short               REM  Total # .of chars written to file
    
    rem ===========================================================
    
    
    REM Used for append and write only. A mode error will cause the test prog to Abort.ATM
    function update_file( file_name$,mode,text$)           lx = strsize(text$)                                               
          rtx=sd.popen(file_name$,mode)              
         sd.pwrite(text$,lx)
         if (rtx=0) then
             fcnt=fcnt + lx    REM    TODO ---create a log file to save fcnt 
         endif   
         sd.pclose()
     end function
     
     function read_file( file_name$,fcnt)       REM== Get fcnt from log file
         mode=asc("r")                                                
          rtx=sd.popen(file_name$,mode)              
         sd.pread(ubuf,lx)
         sd.pclose()
        
     end function
    
     
     sub newline()
             ser.tx(13)
             ser.tx(10)
    end sub
     
      REM Test file functions
    ser.start(31,30,0,115200)
    pausems (1000)
    sd.mount(0)
    update_file("file3.txt",asc("w"),"New data saved....")
    newline()
    update_file("file3.txt",asc("a"),"New data appended")
    newline()
    newline()
    if (rtx=0) then
       message = "File was successfully updated, now to read the file "
       newline()
       ser.str (message)
       newline()
       read_file( "file3.txt",36 )    REM 36 is just a dummy to test the function
       ser.str(ubuf)
       newline()
    else
        message = "Error  "
        ser.hex(rtx,4)
    end if   
    sd.unmount()
      
      
    
    


    Ron
  • Ron:

    Have you tried the new fastspin 3.9.7 yet? It uses a lot less COG memory and has some nice new features (like the LEN function). The reduction in COG memory lets us hook up the BASIC I/O routines to Spin, so you can do things like:
    ' basdemo.bas
    dim fsrw as class using "fsrw.spin"
    
    const D0=22, CLK=23, DI=24, CS=25
    
    sub openfile(n as integer, name as string, mode as string)
      dim r
      r = fsrw.popen(name, asc(mode))
      if r < 0 then
        throw r
      end if
      open SendRecvDevice(@fsrw.pputc, @fsrw.pgetc, @fsrw.pclose) as #n
    end sub
    
    dim err
    dim s$
    dim cycles as uinteger
    dim c as integer
    
    try
    
      fsrw.mount_explicit(D0, CLK, DI, CS)
    
      print "testing write"
      openfile(2, "hello.txt", "w")
      print #2, "Hello from basdemo.bas"
      cycles = getcnt()
      print #2, "When this was written, cycles = "; cycles
      print #2, "Goodbye!"
      fsrw.pclose()  ' should be close #2, but close has a bug right now
    
      ' try reading it back
      pausems 1000
      print "testing read"
      openfile(2, "hello.txt", "r")
      print ".. input"
      s$ = input$(80, 2) ' 80 is a bit of a hack, I happen to know everything fits in 80 bytes
      if s$ then
        print "read back:"
        print s$
      else
        print "got end of file"
      endif
      fsrw.pclose() ' should be close #2, but close is bugged
    
      print "all done"
    
    catch err
    
      print "caught error: "; err
    
    end try
    

    The only thing that isn't working correctly right now is that "close #2" is messing up the rest of the program, due to a bug in the BASIC close function. I've already fixed that in the github source release so it'll be in the next binary release too.
  • yetiyeti Posts: 818
    edited 2018-10-22 22:49
    `basdemo.bas` looks really good!
    But I seem to have different Spin library versions here:
    $ make build
    /opt/spin2cpp/bin/fastspin -O2 basdemo.bas
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
    Version 3.9.8-beta Compiled on: Oct 22 2018
    basdemo.bas
    |-fsrw.spin
    |-|-safe_spi_c3.spin
    basdemo.bas(22) error: Bad number of parameters in call to Mount_explicit: expected 7 found 4
    Makefile:24: recipe for target 'basdemo.binary' failed
    make: *** [basdemo.binary] Error 1
    
    It builds fine when I use the single argument (pingroup) mount call or when I add 3 zeroes as the missing args.

    This is due to the C3 adaption. I would not need C3 support for the Propeller-Platform+SD board but I didn't find the other (not C3ified) versions of `fsrw` and `safe-spi`.

    It's too late for me to dive deeper into this today.
    I'll look at it later...
  • I was using the fsrw26.zip version of fsrw. It does seem that there are several floating around. I think either of your solutions (adding zeros for the missing args, or using the pingroup form) should work.
  • Yes.
    My last test with `fsrw` mentioned somewhere else worked with "pingroup 0".
  • My sample program was flawed in that it only did one input$() call (because I happened to know that the file was short, but in general this isn't the case). The read back routine should look more like:
      do
        s$ = input$(1, 2)  ' read back 1 byte at a time from handle 2
        print s$;
      loop until s$ = ""
    
    The decision about how many bytes to read is pretty arbitrary; 1 is the smallest possible, but for better performance you might want to chunk the reads and use "s$ = input$(20, 2)", or whatever. Either way input$ will read as much as it can up to the number of bytes specified, and return a string with that many bytes. At the end of input the string will be short, but that's OK; and reading past end of file will give an empty string.

  • I did the same.
    #ifdef TRY_READ
      pausems 500
      ' try reading it back
      print "testing read"
      openfile(3, "test2.txt", "r")
      s$ = input$(1, 3)
     do while s$ 
         print s$;
         s$ = input$(1, 3)
      loop
        print "got end of file"
      close #3
    #endif
      print "all done"
    
    
    catch err
    
      print "caught error: "; err
    
    end try
    
    


    I tested it on a file of about 3k and worked fine, albeit a little slow.

    Ron



  • Back in the good old BASIC days playing with graphics was a lot of fun and so I started experimenting with FastSpin-BASIC and graphics (currently only in GEAR, but the simulation is using the VGA pins like found on the Demoboard).

    This example is very basic: It just displays a constant picture given as an initialised BASIC array. So there is no need to have subroutines to set pixels. The program is just starting the (Spin) graphics engine to turn the BASIC array into VGA signals.
  • yetiyeti Posts: 818
    edited 2018-11-13 09:34
    "Hopper" (or "hopalong fractal") is bit more action on the screen than the example above.

    The initialisation of the graphics is very similar to the example above but the bitmap array is not a constant. Pixels calculated by a simple iteration are drawn forever.

    The constants defining the iteration and the scale factor for displaying the results are set in the source code.
  • Those are very cool, demos @yeti. Thanks for testing fastspin BASIC!
  • Everyone loves a fresh almond bread (Mandelbrot).
    Right?

    This program uses [Kwabena W. Agyeman]'s "VGA64 Bitmap Engine" to display a 320x240x2 image. Its initialisation is slightly different than in the monochrome examples above and its drawing routine and named constants for the colours are used from BASIC.

    The Mandelbrot algorithm is run in 16 bit rational arithmetic with 12 bit accuracy (1/4096) for the broken part. That's enough for some simple pictures but for deeper zooms you'd need 32 bit rationals or floating point. The main focus of the example is how to interface this VGA engine, so using the faster and a bit less accurate arithmetic is ok here.

  • But now for something not really completely different...

    What if you want to experiment with some graphics, but your Propeller board lacks TV or VGA output?

    Run it "headless", i.e. calculate the picture and output it e.g. via the usual serial connection to the PC or save calculated pictures to a SD card... there are lots of workarounds.

    This example calculates the Mandelbrot image line per line and instead of storing it in a bitmap, each pixel's "result" is printed when it got calculated. I'm not good with colours, so I used PGM, a grayscale picture file format. Using a RGB file format would not have been more complicated. Click a description of the PPM file format for more. ;-)

    And surprise: A side effect of not needing a large bitmap in RAM is being able to generate much larger images. \o/

    Btw.: This Mandelbrot calculation variant uses BASIC's single precision floating point type.

    The captured output, the PGM image, was converted to PNG format for being displayable here and for compactness.
  • RaymanRayman Posts: 14,632
    edited 2018-11-14 15:59
    There are a lot of options for seeing VGA output without a monitor...
    I wrote this one for Spin, but maybe can work here too...
    http://www.rayslogic.com/propeller/programming/PropMonitor/PropMonitor.htm
    Wait, probably not with Kye's driver though...
  • Rayman wrote: »
    There are a lot of options for seeing VGA output without a monitor...
    I wrote this one for Spin, but maybe can work here too...
    http://www.rayslogic.com/propeller/programming/PropMonitor/PropMonitor.htm
    Interfacing Spin "drivers" to FastSpin-BASIC is easy enough but I cannot run the Windows backend here.
  • yetiyeti Posts: 818
    edited 2018-11-15 10:42
    Polyglot...
    Or: Bilingual without Spin?
    $ cat main.bas
    dim c_code as class using "sub1.c"
    
    c_code.yipyip(113,355)
    
    $ cat sub1.c
    #include <stdio.h>
    
    void yipyip(int a, int b)
    {
      printf("Did you know? %d / %d = %f\r\n",b,a,(float)b/a);
    }
    
    $ fastspin -I /opt/propellerbasics/include/fastspin main.bas
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
    Version 3.9.10-beta-1763e52 Compiled on: Nov 15 2018
    main.bas
    |-sub1.c
    main.pasm
    Done.
    Program size is 6936 bytes
    
    $ spinsim -b main.binary 
    Did you know? 355 / 113 = 3.1416
    
    Spin and PASM hide under the hood in this example, so it actually involves all 4 languages FastSpin currently can handle.
  • RaymanRayman Posts: 14,632
    That is pretty neat!
  • Ping!

    This thread fell asleep?

    @rsut would it be ok for you to widen the focus of this thread?

    I think striking through or removing the "basic" in the title ("Testing the new Fastspin basic compiler for P1") to allow all FastSpin languages here would make more sense than starting an other thread for "FastSpin on P1 stuff except BASIC".
  • yetiyeti Posts: 818
    edited 2019-09-05 03:17
    I got a hint about how to get multi dimensional arrays in FlexBASIC. So I hacked together a VGA bitmap example using a 2 dimensional array instead of a linear storage of the bitmap (as used in the graphics examples above).

    Edit@20190904: Newer FastSpin BASIC can declare 2 dimensional arrays directly.
    —▷ https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#arrays

  • yetiyeti Posts: 818
    edited 2019-09-05 19:42
    It possibly can't get easier than this to get started with C and graphics:
    #include <stdint.h>
    
    struct __using("VGA_512x384_Bitmap.spin") vga;
    
    uint32_t sync;
    uint32_t bitmap[vga.hp/32*vga.vp];
    uint16_t colors[vga.xtiles*vga.ytiles];
    
    void main()
    {
      //
      //        lowest pin of VGA pingroup
      //        |
      //        V
      vga.start(16,colors,bitmap,sync);
      //
      // set same colorpair for all tiles
      //
      wordfill(colors,0b110011_00_001100_00,vga.xtiles*vga.ytiles);
      //                ffffff_00_bbbbbb_00
    
      longfill(bitmap,0xf0f0f0f0,vga.hp/32*vga.vp);
    
      for(;;); // for(ever)
    }
    
    Focussing on how to get the VGA "driver" into C this only displays magenta stripes on a green background.
  • Might be an idea to include links to this stuff in the OP...I wouldn't know where to look because everything is so scattered.

    (preparing for a flaming :lol: )
  • Mickster wrote: »
    Might be an idea to include links to this stuff in the OP...I wouldn't know where to look because everything is so scattered.

    The best starting place is spin2gui, which is an IDE that supports all of the languages fastspin has. It can be downloaded from my patreon page at https://www.patreon.com/totalspectrum or from github at https://github.com/totalspectrum/spin2gui/releases.

    Yeti has some great resources at http://yeti.freeshell.org/orgy/fastspin/fastspin.html.
  • Hi

    No kidding; where do you guys find the time????
    Brilliant stuff

    Dave
  • tritonium wrote: »
    Hi

    No kidding; where do you guys find the time????
    Brilliant stuff

    Dave

    Agreed....only just became aware of this stuff.

    Totally appreciate everything but it seems hidden in plain sight.

    I have never known of so many great contributions that are never brought to the forefront....I thought it was only PropBASIC that was underexposed.
  • yetiyeti Posts: 818
    edited 2019-09-08 16:22
    I'm so used to starting each spin program with clock and PLL settings that I almost always forget that FlexSPIN doesn't need it. And even FullDuplexSerial may not always be needed...
    pub surprise | s, c
      s := string("Surprised?",13,10)
      repeat while c := byte[s++]
        _tx(c)
      pausems(1000)
    
    Now it's written down as a reminder.
    \o/
  • Using the well known register names works and makes BASIC look a bit SPINier. It's nice to have this option!
    $ cat xyzzy.bas 
    dira = 0xFFFFFFFF
    do
      outa = cnt
    loop
    
    $ fastspin --code=cog xyzzy.bas 
    Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
    Version 3.9.30 Compiled on: Sep  8 2019
    xyzzy.bas
    xyzzy.pasm
    Done.
    Program size is 68 bytes
    
    1074 x 733 - 63K
  • yetiyeti Posts: 818
    edited 2019-09-22 11:26
    Ok, once again graphics. This time as 2d-array of scanlines of unsigned word cells to better fit the 16x16 layout of the changing elements. This isn't as easy as a POKE into the C64's screen memory, but being able to easily change the 16x16 tiles over compensates the additional efforts:
    #include <propeller.h>
    #include <stdint.h>
    #include <stdlib.h>
    
    struct __using("VGA_512x384_Bitmap.spin") vga;
    uint16_t wordmap[vga.vp][vga.hp>>4];
    uint16_t colors[vga.xtiles*vga.ytiles];
    uint32_t sync;
    
    uint16_t cg[16][2] = {
      { 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0, 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0 },
      { 0b0_0_0_0_1_1_0_0_0_0_1_1_0_0_0_0, 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0 },
      { 0b0_0_0_0_0_1_1_0_0_1_1_0_0_0_0_0, 0b0_0_1_1_0_0_0_0_0_0_0_0_1_1_0_0 },
      { 0b1_0_0_0_0_0_1_1_1_1_0_0_0_0_0_1, 0b1_1_1_0_0_0_0_0_0_0_0_0_0_1_1_1 },
      { 0b1_1_0_0_0_0_0_1_1_0_0_0_0_0_1_1, 0b1_1_0_0_0_0_0_0_0_0_0_0_0_0_1_1 },
      { 0b0_1_1_0_0_0_0_0_0_0_0_0_0_1_1_0, 0b0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 },
      { 0b0_0_1_1_0_0_0_0_0_0_0_0_1_1_0_0, 0b0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 },
      { 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0, 0b0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 },
      { 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0, 0b0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 },
      { 0b0_0_1_1_0_0_0_0_0_0_0_0_1_1_0_0, 0b0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 },
      { 0b0_1_1_0_0_0_0_0_0_0_0_0_0_1_1_0, 0b0_0_0_0_0_0_0_0_0_0_0_0_0_0_0_0 },
      { 0b1_1_0_0_0_0_0_1_1_0_0_0_0_0_1_1, 0b1_1_0_0_0_0_0_0_0_0_0_0_0_0_1_1 },
      { 0b1_0_0_0_0_0_1_1_1_1_0_0_0_0_0_1, 0b1_1_1_0_0_0_0_0_0_0_0_0_0_1_1_1 },
      { 0b0_0_0_0_0_1_1_0_0_1_1_0_0_0_0_0, 0b0_0_1_1_0_0_0_0_0_0_0_0_1_1_0_0 },
      { 0b0_0_0_0_1_1_0_0_0_0_1_1_0_0_0_0, 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0 },
      { 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0, 0b0_0_0_1_1_0_0_0_0_0_0_1_1_0_0_0 }
    };
    
    void randtile(uint8_t x, uint16_t y, uint8_t r) {
      y<<=4;
      for( uint8_t s=0 ; s<16 ; )
        wordmap[y++][x]=cg[s++][r];
    }
    
    void main(void) {
      vga.start(16,colors,wordmap,sync);
      wordfill(colors,0b001100_00_010101_00,vga.xtiles*vga.ytiles);
      //
      // fill the whole screen once
      //
      for( uint8_t y=0 ; y<(vga.vp>>4) ; y++ )
        for( uint8_t x=0 ; x<(vga.hp>>4) ; x++ )
          randtile(x,y,rand()&1);
      //
      // then change random tiles to random values
      //
      for( uint32_t t=CNT ;; waitcnt(t+=CLKFREQ) )
        randtile(rand()%(vga.hp>>4),rand()%(vga.vp>>4),rand()&1);
    }
    

  • msrobotsmsrobots Posts: 3,709
    edited 2019-09-24 02:54
    Is this the cuurent version of Gears you are showing here?

    Interesting.

    Mike
  • yetiyeti Posts: 818
    edited 2019-09-24 05:47
    msrobots wrote: »
    Is this the cuurent version of Gears you are showing here?
    I'm using v14.7.3.0 because (a while ago) that was the last version that didn't crash on Linux. Meanwhile I'm running a newer Mono, so I perhaps should test the newest one (master branch) again. New Mono, new problem?

    Gear has it's problems, but Gear and SpinSim are like virtual Propeller boards with some standard features and so both are nice for documenting things by screenshots or console logs (SpinSim).

    I had to modify Gear's VGA plugin to double or even quadruple the scanline (pixel) length (depends on the VGA object in use) to get a normal looking x:y ratio but that was no big deal: They come as C# sources.
    Edit: Nah! Gear's master branch still crashes here (Debian10, Mono-5.$WHATSOEVER) after loading the Propeller binary.
    :-(
Sign In or Register to comment.