FastSpin

Table of Contents

1 Famous First Words

This is work in progress or better work in FastSpin and will change often and massively.

Currently I'm assimilating my FastSpin related snippets, programs, thoughts and whatsoever into this EMACS Orgmode document with few comments and explanations so reading more about FastSpin in Parallax's forum and FastSpin's own source and documentation is a better start than this place.

1.1 Forum Threads

fastspin compiler for P2
https://forums.parallax.com/discussion/164187

New BASIC compiler for Prop1 and Prop2
https://forums.parallax.com/discussion/168913

Testing the new Fastspin basic compiler for P1
https://forums.parallax.com/discussion/169141

2 Appetiser

2.1 FlexSPIN

File hello.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub main

  ser.start(31, 30, 0, 115200)

  ser.str(string("Hello, FlexSPIN!",13,10))

  waitcnt(_clkfreq + cnt)
  ser.stop

  cogstop(0)

Compile to hello.spin.binary:

fastspin -O2 hello.spin -o hello.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
hello.spin
|-FullDuplexSerial.spin
hello.spin.pasm
Done.
Program size is 1724 bytes

Run the result in spinsim:

spinsim -b hello.spin.binary
Hello, FlexSPIN!

2.2 FlexBASIC

File hello.bas:

print"Hello, FlexBASIC!"

Compile to hello.bas.binary:

fastspin -O2 hello.bas -o hello.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
hello.bas
hello.bas.pasm
Done.
Program size is 1500 bytes

Run the result in spinsim:

spinsim -b hello.bas.binary
Hello, FlexBASIC!

2.3 FlexC

File hello.c:

#include <stdio.h>

void main( void )
{
    printf("Hello, FlexC!\n");
}

Compile to hello.c.binary:

fastspin -O2 hello.c -o hello.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
hello.c
hello.c.pasm
Done.
Program size is 1500 bytes

Run the result in spinsim:

spinsim -b hello.c.binary
Hello, FlexC!

3 FastSpin - The Program

Assuming you have fastspin installed in a directory being mentioned in your PATH variable:

fastspin
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.15 Compiled on: Jan 19 2019
usage: fastspin [options] filename.spin | filename.bas
  [ -h ]              display this help
  [ -L or -I <path> ] add a directory to the include path
  [ -o <name> ]      set output filename to <name>
  [ -b ]             output binary file format
  [ -e ]             output eeprom file format
  [ -c ]             output only DAT sections
  [ -l ]             output DAT as a listing file
  [ -f ]             output list of file names
  [ -q ]             quiet mode (suppress banner and non-error text)
  [ -p ]             disable the preprocessor
  [ -D <define> ]    add a define
  [ -u ]             ignore for openspin compatibility (unused method elimination always enabled)
  [ -2 ]             compile for Prop2
  [ -O# ]            set optimization level:
          -O0 = no optimization
          -O1 = basic optimization
          -O2 = all optimization
  [ -H nnnn ]        set starting hub address
  [ -E ]             skip initial coginit code (usually used with -H)
  [ -w ]             compile for COG with Spin wrappers
  [ -C ]             enable case sensitive mode
  [ --code=cog ]     compile for COG mode instead of LMM
  [ --fcache=N ]     set FCACHE size to N (0 to disable)
  [ --fixedreal ]    use 16.16 fixed point in place of floats

4 Unsorted Snippets and Examples

As long as I have no better idea, the examples are sorted by their hopefully meaningfull filenames.

4.1 FlexSPIN

4.1.1 inline-asm.spin

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/spin.md#inline-assembly.

File inline-asm.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub main
  ser.start(31,30,0,115200)

  ser.str(string("the answer is "))
  ser.dec(answer(14))
  ser.str(string(13,10))

  waitcnt(_clkfreq+cnt)
  ser.stop
  cogstop(0)

pub answer(question)
  asm
          mov     result, question        ' result as target
          add     result, result          ' result as source too
          add     result, question
  endasm

Compile to inline-asm.spin.binary:

fastspin -O2 inline-asm.spin -o inline-asm.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
inline-asm.spin
|-FullDuplexSerial.spin
inline-asm.spin.pasm
Done.
Program size is 2152 bytes

Run it in spinsim:

spinsim -b inline-asm.spin.binary
the answer is 42

4.1.2 inline-asm-loop-unroll.spin

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/spin.md#inline-assembly.

File inline-asm-loop-unroll.spin:

' see https://forums.parallax.com/discussion/comment/1177581/#Comment_1177581

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub main | r,t,d,d1,d2
  ser.start(31,30,0,115200)

  d1:=r?
  d2:=r?

  ser.str(string("d1,d2        ... "))
  ser.dec(d1)
  ser.tx(",")
  ser.dec(d2)
  ser.str(string(13,10))

  t:=cnt
  d:=d1*d2
  t:=cnt-t
  ser.str(string("internal     ... "))
  ser.dec(t)
  ser.str(string(13,10))

  t:=cnt
  d:=mul1(d1,d2)
  t:=cnt-t
  ser.str(string("assembler(1) ... "))
  ser.dec(t)
  ser.str(string(13,10))

  t:=cnt
  d:=mul2(d1,d2)
  t:=cnt-t
  ser.str(string("assembler(2) ... "))
  ser.dec(t)
  ser.str(string(13,10))

  t:=cnt
  d:=mul4(d1,d2)
  t:=cnt-t
  ser.str(string("assembler(4) ... "))
  ser.dec(t)
  ser.str(string(13,10))

  waitcnt(_clkfreq+cnt)
  ser.stop
  cogstop(0)

pub mul1(v1,v2):vres
  asm
              abs       v1, v1 wc
        if_c  neg       v2, v2
              abs       v2, v2 wc
              mov       vRes, v2
              min       v2, v1
              max       v1, vRes
        if_c  neg       v2, v2
              mov       vRes, #0
  loop1       shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
        if_nz jmp       #loop1
  endasm

pub mul2(v1,v2):vres
  asm
              abs       v1, v1 wc
        if_c  neg       v2, v2
              abs       v2, v2 wc
              mov       vRes, v2
              min       v2, v1
              max       v1, vRes
        if_c  neg       v2, v2
              mov       vRes, #0
  loop2       shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
              shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
        if_nz jmp       #loop2
  endasm

pub mul4(v1,v2):vres
  asm
              abs       v1, v1 wc
        if_c  neg       v2, v2
              abs       v2, v2 wc
              mov       vRes, v2
              min       v2, v1
              max       v1, vRes
        if_c  neg       v2, v2
              mov       vRes, #0
  loop4       shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
              shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
              shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
              shr       v1, #1 wc, wz
        if_c  add       vRes, v2
              shl       v2, #1
        if_nz jmp       #loop4
  endasm

Compile to inline-asm-loop-unroll.spin.lmm.binary:

fastspin -O2 inline-asm-loop-unroll.spin -o inline-asm-loop-unroll.spin.lmm.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
inline-asm-loop-unroll.spin
|-FullDuplexSerial.spin
inline-asm-loop-unroll.spin.lmm.pasm
Done.
Program size is 2864 bytes

Run it in spinsim:

spinsim -b inline-asm-loop-unroll.spin.lmm.binary
d1,d2        ... -447283201,1975265200
internal     ... 608
assembler(1) ... 912
assembler(2) ... 960
assembler(4) ... 1152

Compile to inline-asm-loop-unroll.spin.cog.binary:

fastspin -O2 inline-asm-loop-unroll.spin --code=cog -o inline-asm-loop-unroll.spin.cog.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
inline-asm-loop-unroll.spin
|-FullDuplexSerial.spin
inline-asm-loop-unroll.spin.cog.pasm
Done.
Program size is 2160 bytes

Run it in spinsim:

spinsim -b inline-asm-loop-unroll.spin.cog.binary
d1,d2        ... 240553262,1411327060
internal     ... 548
assembler(1) ... 496
assembler(2) ... 440
assembler(4) ... 412

Interesting: In LMM assembler, unrolling the loop slows it down. This needs a closer look.

4.1.3 mandelbrot-s4p12.spin

File mandelbrot-s4p12.spin:

''
'' mandelbrot-s4p12.spin
''
con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

  xmin=round(-2.1*float(1<<12))
  xmax=round( 0.7*float(1<<12))

  ymin=round(-1.2*float(1<<12))
  ymax=round( 1.2*float(1<<12))

  maxiter=32

  MPX=79 ' 0..79
  MPY=24 ' 0..24

  dx=(xmax-xmin)/MPX
  dy=(ymax-ymin)/MPY

  c4=4<<12

obj
  ser : "spin/FullDuplexSerial"

pub main | c,cx,cy,x,y,x2,y2,iter,px,py

  ser.start(31,30,0,115200)

  cy:=ymin
  repeat py from 0 to MPY
    cx:=xmin
    repeat px from 0 to MPX
      x:=0
      y:=0
      iter:=0
      repeat while iter=<maxiter
        x2:=(x*x)~>12
        y2:=(y*y)~>12
        if x2+y2>c4
          quit
        y:=((x*y)~>11)+cy
        x:=x2-y2+cx
        iter+=1
      cx+=dx
      ser.tx(iter+32)
    cy+=dy
    ser.tx(10)

  waitcnt(_clkfreq+cnt)
  ser.stop
  cogstop(0)

Compile to mandelbrot-s4p12.spin.binary:

fastspin -O2 mandelbrot-s4p12.spin -o mandelbrot-s4p12.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
mandelbrot-s4p12.spin
|-FullDuplexSerial.spin
mandelbrot-s4p12.spin.pasm
Done.
Program size is 1892 bytes

Run it in spinsim:

spinsim -b mandelbrot-s4p12.spin.binary
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$######""""""""""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######""""""
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*4:/+('&%%$$$$$$#######"""
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),AAAAAAA,'&%%%%%$$$$########
!!!!!!!"""####################$$$$$$$$%%%&'())((())*,AAAAAA/+))('&&&&)'%$$######
!!!!!!""###################$$$$$%%%%%%&&&'+.AA=/<AAAAAAAAAAAAAAA/++A..:2%%$#####
!!!!!"################$$$%%%%%%%%%%&&&&'),+1AAAAAAAAAAAAAAAAAAAAAAAAA1('&%$$####
!!!!"##########$$$$$%%&(-(''''''''''''(*,5AAAAAAAAAAAAAAAAAAAAAAAAAAAA+)-&%$$###
!!!!####$$$$$$$$%%%%%&'(*-A1.+.A-4+))**AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4-(&%$$$##
!!!!#$$$$$$$$$%%%%%%'''++.5AAAAAAAAA8/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3(%%$$$$#
!!!#$$$$$$$%&&&&''().-5.5AAAAAAAAAAAAA>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'&%%$$$$#
!!!(**+-+;732/;0045;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+)'&&%%$$$$#
!!!#$$$$$$$%&&&&''().-3.AAAAAAAAAAAAAA?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'&%%$$$$#
!!!!#$$$$$$$$$%%%%%%'''/,.7AAAAAAAAA;/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0'%%$$$$#
!!!!####$$$$$$$$%%%%%&'(*-:2.,/>-5+))**<AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4+(&%$$$##
!!!!"##########$$$$$%%&(-(''''(''''''((*,4AAAAAAAAAAAAAAAAAAAAAAAAAAA4+)-&%$$###
!!!!!"################$$$%%%%%%%%%%&&&&')A,4AAAAAAAAAAAAAAAAAAAAAAAAA/('&%%$####
!!!!!!""##################$$$$$$%%%%%%&&&'*.AAA0AAAAAAAAAAAAAAAA1,,A//9)%%$#####
!!!!!!!"""####################$$$$$$$$%%%&(())((()**-AAAAAA/+)))'&&&')'%$$######
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,AAAAAAA+'&&%%%%%$$$########
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7A0+('&%%%$$$$$#######"""
!!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+.)-*&%$$$$$$######""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$%%'6(%%%$$$$$######""""""""""
!!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""

4.1.4 mandelbrot-s8p24.spin

File mandelbrot-s8p24.spin:

' mandelbrot-s8p24.spin

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

  xmin=round(-2.1*float(1<<24))
  xmax=round( 0.7*float(1<<24))

  ymin=round(-1.2*float(1<<24))
  ymax=round( 1.2*float(1<<24))

  maxiter=32

  MPX=79 ' 0..MPX
  MPY=24 ' 0..MPY

  dx=(xmax-xmin)/MPX
  dy=(ymax-ymin)/MPY

  c4=4<<24

obj
  ser : "spin/FullDuplexSerial"

pub main | c,cx,cy,x,y,x2,y2,iter,px,py

  ser.start(31,30,0,115200)

  cy:=ymin
  repeat py from 0 to MPY
    cx:=xmin
    repeat px from 0 to MPX
      x:=0
      y:=0
      iter:=0
      repeat while iter=<maxiter
        x2:=(x**x)<<8 | (x*x)>>24 ' x*x
        y2:=(y**y)<<8 | (y*y)>>24 ' y*y
        if x2+y2>c4
          quit
        y:=((x**y)<<9 | (x*y)>>23)+cy ' 2*x*y+cy
        x:=x2-y2+cx
        iter+=1
      cx+=dx
      ser.tx(iter+32)
    cy+=dy
    ser.tx(10)

  waitcnt(_clkfreq+cnt)
  ser.stop
  cogstop(0)

Compile to mandelbrot-s8p24.spin.binary:

fastspin -O2 mandelbrot-s8p24.spin -o mandelbrot-s8p24.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
mandelbrot-s8p24.spin
|-FullDuplexSerial.spin
mandelbrot-s8p24.spin.pasm
Done.
Program size is 1948 bytes

Run it in spinsim:

spinsim -b mandelbrot-s8p24.spin.binary
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####"""""""""""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######""""""
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*A;/*('&%%$$$$$$#######"""
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),AAAAAA@+'&%%%%%$$$$########
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-AAAAAA.+))('&&&&+&%$$######
!!!!!!""###################$$$$$%%%%%%&&&'+.AAA08AAAAAAAAAAAAAAA/+,A//A)%%$#####
!!!!!"################$$$%%%%%%%%%%&&&&')-+7AAAAAAAAAAAAAAAAAAAAAAAAA4(&&%$$####
!!!!"##########$$$$$%%&(,('''''''''''((*-5AAAAAAAAAAAAAAAAAAAAAAAAAAA3+)4&%$$###
!!!!####$$$$$$$$%%%%%&'(*-A1.+/A-4+))**AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3+'&%$$$##
!!!!#$$$$$$$$$%%%%%%'''++.7AAAAAAAAA9/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<6'%%$$$$#
!!!#$$$$$$$%&&&&''().-2.6AAAAAAAAAAAAA>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'&%%$$$$#
!!!378<@AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2+)'&&%%$$$$#
!!!#$$$$$$$%&&&&''().-2.6AAAAAAAAAAAAA>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'&%%$$$$#
!!!!#$$$$$$$$$%%%%%%'''++.7AAAAAAAAA9/0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<6'%%$$$$#
!!!!####$$$$$$$$%%%%%&'(*-A1.+/A-4+))**AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3+'&%$$$##
!!!!"##########$$$$$%%&(,('''''''''''((*-5AAAAAAAAAAAAAAAAAAAAAAAAAAA3+)4&%$$###
!!!!!"################$$$%%%%%%%%%%&&&&')-+7AAAAAAAAAAAAAAAAAAAAAAAAA4(&&%$$####
!!!!!!""###################$$$$$%%%%%%&&&'+.AAA08AAAAAAAAAAAAAAA/+,A//A)%%$#####
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-AAAAAA.+))('&&&&+&%$$######
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),AAAAAA@+'&%%%%%$$$$########
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*A;/*('&%%$$$$$$#######"""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####"""""""""""
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""

4.2 FlexBASIC

4.2.1 colon.bas

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#multiple-statements-per-line.

File colon.bas:

print"Hello, "; : print "world!"

Compile to colon.bas.binary:

fastspin -O2 colon.bas -o colon.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.17 Compiled on: Feb  3 2019
colon.bas
colon.bas.pasm
Done.
Program size is 1572 bytes

Run it in spinsim:

spinsim -b colon.bas.binary
Hello, world!

4.2.2 hopper-vga-512x384x1.bas

See https://forums.parallax.com/discussion/comment/1453190/#Comment_1453190.

File hopper-vga-512x384x1.bas:

''++ -------------------------------------------------------------------------
'' hopper-vga-512x384x1.bas
''
'' set the VGA pin(group) as neede a few lines below.
''-- -------------------------------------------------------------------------

''++
'' set up VGA and preset the tiles' colors
''
dim vga as class using "VGA_512x384_Bitmap.spin"
''
dim shared as ulong sync
dim shared as ulong bitmap(vga.hp/32*vga.vp)
dim shared as ushort colors(vga.xtiles*vga.ytiles)
''
''        lowest pin of VGA pingroup
''        |
''        V
vga.start(16, @colors, @bitmap, @sync)
''
'' set same colorpair for all tiles
''
wordfill(@colors,&b111111_00_000001_00,192) ' ffffff_00_bbbbbb_00
''--

''++ =========================================================================

const a =   3.0
const b =  -5.0
const c =   7.0

const scale = 10.0

dim as single x,y,xn,yn

x = 0.0
y = 0.0

do
  xn = y-sgn(x)*sqrt(abs(b*x-c))
  yn = a-x
  x  = xn
  y  = yn
  plot 255.5+x*scale,191.5+y*scale
loop

''-- =========================================================================

''++
sub plot(x as integer,y as integer)
#ifdef PRINT
  print x," ",y
#endif
  if 0<=x and x<=511 and 0<=y and y<=383 then
    var index = y<<4 + x>>5 + 1
    bitmap(index) = bitmap(index) or 1<<(x and 31)
  end if
end sub
''--

''++
function sgn(x as single) as single
  if x>0.0 return 1.0
  if x<0.0 return -1.0
  return 0.0
end function
''--

Compile to hopper-vga-512x384x1.bas.binary:

fastspin -O2 hopper-vga-512x384x1.bas -o hopper-vga-512x384x1.bas.binary -I /opt/parallax.spin.src/spin
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.14-beta-1162b0d3 Compiled on: Jan  2 2019
hopper-vga-512x384x1.bas
|-VGA_512x384_Bitmap.spin
hopper-vga-512x384x1.bas.pasm
Done.
Program size is 27876 bytes

4.2.3 inline-asm.bas

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#asm.

File inline-asm.bas:

function answer(question as ulong) as ulong
  dim result as ulong
  asm
          mov     result, question
          add     result, result
          add     result, question
  end asm
  return result
end function

print "the answer is ";answer(14)

Compile to inline-asm.bas.binary:

fastspin -O2 inline-asm.bas -o inline-asm.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.20-beta-50cc2ca0 Compiled on: Feb 13 2019
inline-asm.bas
inline-asm.bas.pasm
Done.
Program size is 2220 bytes

Run it in spinsim:

spinsim -b inline-asm.bas.binary
the answer is 42

4.2.4 line-numbers.bas

File line-numbers.bas:

100 for i=0 to 5
110   gosub 900
120 next i
199 goto 999
900 if i < 2 print "book! ";
910 if i mod 2 print "raaadiiiooo! ";
920 if i mod 3 print "yipyip! ";
930 print
940 return
999 print "happy! happy! happy!"

Loosely based upon https://www.youtube.com/watch?v=z_trSIBCgF0. ;-)

Compile to line-numbers.bas.binary:

fastspin -O2 line-numbers.bas -o line-numbers.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.18 Compiled on: Feb 10 2019
line-numbers.bas
line-numbers.bas.pasm
Done.
Program size is 1900 bytes

Run it in spinsim:

spinsim -b line-numbers.bas.binary
book! 
book! raaadiiiooo! yipyip! 
yipyip! 
raaadiiiooo! 
yipyip! 
raaadiiiooo! yipyip! 
happy! happy! happy!

4.2.5 long-lines.bas

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#extending-lines.

File long-lines.bas:

print"Hello, "; _
     "World!"

Compile to long-lines.bas.binary:

fastspin -O2 long-lines.bas -o long-lines.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
long-lines.bas
long-lines.bas.pasm
Done.
Program size is 1520 bytes

Run it in spinsim:

spinsim -b long-lines.bas.binary
Hello, World!

4.2.6 mandelbrot-s4p12.bas

File mandelbrot-s4p12.bas:

'
' translated to BASIC from mandelbrot16-20180406-fds.spin
'-------------------------------------------------------------------------------

'++
  const xmin = (-21<<12)/10
  const xmax = (  7<<12)/10

  const ymin = (-12<<12)/10
  const ymax = ( 12<<12)/10

  const maxiter = 32

  const MPX = 79 ' 0..79
  const MPY = 24 ' 0..24

  const dx = (xmax-xmin)/MPX
  const dy = (ymax-ymin)/MPY

  const c4 = 4<<12
'--

'++
' was main
'
  dim as integer x,y,x2,y2,cx,cy,iter

  cy = ymin
  for py = 0 to MPY
    cx = xmin
    for px = 0 to MPX
      x = 0
      y = 0
      x2 = 0
      y2 = 0
      iter = 0
      while iter < maxiter and x2+y2 <= c4
        y = ((x*y)>>11)+cy
        x = x2-y2+cx
        iter = iter+1
        x2 = (x*x)>>12
        y2 = (y*y)>>12
      end while
      cx = cx+dx
      print \(iter+32);
    next px
    cy = cy+dy
    print
  next py

#ifdef MagicExit
  print \255;\0;\0;
#endif
'--

Compile to mandelbrot-s4p12.bas.binary:

/opt/propellerbasics/bin/fastspin -O2 mandelbrot-s4p12.bas -o mandelbrot-s4p12.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
mandelbrot-s4p12.bas
mandelbrot-s4p12.bas.pasm
Done.
Program size is 1576 bytes

Run it in spinsim:

spinsim -b mandelbrot-s4p12.bas.binary
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'+)%%%$$$$$#####"""""""""""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(+,)++&%$$$$$$######""""""
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*5:/+('&%%$$$$$$#######"""
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@,'&%%%%%$$$$########
!!!!!!!"""####################$$$$$$$$%%%&'())((())*,@@@@@@/+))('&&&&)'%$$######
!!!!!!""###################$$$$$%%%%%%&&&'+.@@=/<@@@@@@@@@@@@@@@/++@..93%%$#####
!!!!!"################$$$%%%%%%%%%%&&&&'),+2@@@@@@@@@@@@@@@@@@@@@@@@@1(&&%$$####
!!!!"##########$$$$$%%&(-(''''''''''''(*,5@@@@@@@@@@@@@@@@@@@@@@@@@@@@+)-&%$$###
!!!!####$$$$$$$$%%%%%&'(*-@1.+.@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4-(&%$$$##
!!!!#$$$$$$$$$%%%%%%'''++.6@@@@@@@@@8/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3(%%$$$$#
!!!#$$$$$$$%&&&&''()/-5.5@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@?'&%%$$$$#
!!!(**+/+<523/80/46@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+)'&&%%$$$$#
!!!#$$$$$$$%&&&&''().-2.@@@@@@@@@@@@@@?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$#
!!!!#$$$$$$$$$%%%%%&'''/,.7@@@@@@@@@;/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@0'%%$$$$#
!!!!####$$$$$$$$%%%%%&'(*-:2.,/?-5+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@4+(&%$$$##
!!!!"##########$$$$$%%&(-(''''(''''''((*,4@@@@@@@@@@@@@@@@@@@@@@@@@@@4+).&%$$###
!!!!!"################$$$%%%%%%%%%%&&&&')<,4@@@@@@@@@@@@@@@@@@@@@@@@@/('&%%$####
!!!!!!""##################$$$$$$%%%%%%&&&'*.@@@0@@@@@@@@@@@@@@@@1,,@//9)%%$#####
!!!!!!!"""####################$$$$$$$$%%%&(())((()**-@@@@@@/+)))'&&&')'%$$######
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''(,@@@@@@@+'&&%%%%%$$$########
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*7@0+('&%%%$$$$$#######"""
!!!!!!!!!!!"""""""######################$$$$$$$$$%%%&&(+-).*&%$$$$$$######""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$%%'3(%%%$$$$$######""""""""""
!!!!!!!!!!!!!!!""""""""""""#####################################""""""""""""""""

4.2.7 mandelbrot-s8p24.bas

File mandelbrot-s8p24.bas:

'
' translated from mandelbrot32-20180317-b.spin
'-------------------------------------------------------------------------------

'++
  const xmin = (-21<<24)/10
  const xmax = (  7<<24)/10

  const ymin = (-12<<24)/10
  const ymax = ( 12<<24)/10

  const maxiter = 32

  const MPX = 79 ' 0..79
  const MPY = 24 ' 0..24

  const dx = (xmax-xmin)/MPX
  const dy = (ymax-ymin)/MPY

  const c4 = 4<<24
'--

'++
' was main
'
dim as integer x,y,x2,y2,cx,cy,iter

  cy = ymin
  for py = 0 to MPY
    cx = xmin
    for px = 0 to MPX
      x = 0
      y = 0
      x2 = 0
      y2 = 0
      iter = 0
      while iter < maxiter and x2+y2 <= c4
        y = hack.multimes2(x,y)+cy
        x = x2-y2+cx
        iter = iter+1
        x2 = hack.mul(x,x)
        y2 = hack.mul(y,y)
      end while
      cx = cx+dx
      print \(iter+32);
    next px
    cy = cy+dy
    print
  next py

#ifdef MagicExit
  print \255;\0;\0;
#endif
'--

'++
class hacks using "mandelbrot-s8p24.hacks.spin"
dim hack as hacks
' hack.mul(x,y) does s8p24 fp multiplication
' hack.multimes2(x,y) does mul(x,y)*2
'--

File mandelbrot-s8p24.hacks.spin:

pub mul(x,y)
  return (x**y)<<8 | (x*y)>>24

pub multimes2(x,y)
  return (x**y)<<9 | (x*y)>>23

Compile to mandelbrot-s8p24.bas.binary:

fastspin -O2 mandelbrot-s8p24.bas -o mandelbrot-s8p24.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
mandelbrot-s8p24.bas
|-mandelbrot-s8p24.hacks.spin
mandelbrot-s8p24.bas.pasm
Done.
Program size is 1648 bytes

Run it in spinsim:

spinsim -b mandelbrot-s8p24.bas.binary
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####"""""""""""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######""""""
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######"""
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$########
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$######
!!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$#####
!!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$####
!!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$###
!!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$##
!!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$#
!!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$#
!!!379<@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2+)'&&%%$$$$#
!!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$#
!!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$#
!!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$##
!!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$###
!!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$####
!!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$#####
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$######
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$########
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######"""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####"""""""""""
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""

4.2.8 mandelbrot-single.bas

File mandelbrot-single.bas:

'
' translated to BASIC from mandelbrot16-20180406-fds.spin
'-------------------------------------------------------------------------------

'++
  const xmin = -2.1
  const xmax =  0.7

  const ymin = -1.2
  const ymax =  1.2

  const maxiter = 32

  const MPX = 79 ' 0..79
  const MPY = 24 ' 0..24

  const dx = (xmax-xmin)/MPX
  const dy = (ymax-ymin)/MPY

  const c4 = 4.0 ' square of escape radius
'--

'++
' was main
'
  dim as single x,y,x2,y2,cx,cy
  dim as integer iter

  cy = ymin
  for py = 0 to MPY
    cx = xmin
    for px = 0 to MPX
      x = 0.0
      y = 0.0
      x2 = 0.0
      y2 = 0.0
      iter = 0
      while iter < maxiter and x2+y2 <= c4
        y = 2.0*x*y+cy
        x = x2-y2+cx
        iter = iter+1
        x2 = x*x
        y2 = y*y
      end while
      cx = cx+dx
      print \(iter+32);
    next px
    cy = cy+dy
    print
  next py

#ifdef MagicExit
  print \255;\0;\0;
#endif
'--

Compile to mandelbrot-single.bas.binary:

fastspin -O2 mandelbrot-single.bas -o mandelbrot-single.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
mandelbrot-single.bas
mandelbrot-single.bas.pasm
Done.
Program size is 2492 bytes

Run it in spinsim:

spinsim -b mandelbrot-single.bas.binary
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####"""""""""""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######""""""
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######"""
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$########
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$######
!!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$#####
!!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$####
!!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$###
!!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$##
!!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$#
!!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$#
!!!7:=?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@2+)'&&%%$$$$#
!!!#$$$$$$$%&&&&''().-2.6@@@@@@@@@@@@@>@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'&%%$$$$#
!!!!#$$$$$$$$$%%%%%%'''++.7@@@@@@@@@9/0@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@<6'%%$$$$#
!!!!####$$$$$$$$%%%%%&'(*-@1.+/@-4+))**@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@3+'&%$$$##
!!!!"##########$$$$$%%&(,('''''''''''((*-5@@@@@@@@@@@@@@@@@@@@@@@@@@@3+)4&%$$###
!!!!!"################$$$%%%%%%%%%%&&&&')-+7@@@@@@@@@@@@@@@@@@@@@@@@@4(&&%$$####
!!!!!!""###################$$$$$%%%%%%&&&'+.@@@08@@@@@@@@@@@@@@@/+,@//@)%%$#####
!!!!!!!"""####################$$$$$$$$%%%&'())((())*-@@@@@@.+))('&&&&+&%$$######
!!!!!!!!""""#####################$$$$$$$$$$%%%&&&''),@@@@@@@+'&%%%%%$$$$########
!!!!!!!!!"""""#######################$$$$$$$$$$%%%%&')*@;/*('&%%$$$$$$#######"""
!!!!!!!!!!!"""""""#######################$$$$$$$$%%%&&(++)++&$$$$$$$######""""""
!!!!!!!!!!!!!"""""""""#######################$$$$$$$%'0(%%%$$$$$#####"""""""""""
!!!!!!!!!!!!!!!"""""""""""""####################################""""""""""""""""

4.2.9 mandelbrot-single-pgm-800x800.bas

File mandelbrot-single-pgm-800x800.bas:

'
' translated from mandelbrot32-20180317-b.spin
'-------------------------------------------------------------------------------

'++
' constants

  const xmin = -2.1 ' -0.79568
  const xmax =  2.1 ' -0.79068

  const ymin = -2.1 ' -0.16337
  const ymax =  2.1 ' -0.15837

  const maxiter = 31

  const MPX = 799 ' 0..800
  const MPY = 799 ' 0..800

  const dx = (xmax-xmin)/MPX
  const dy = (ymax-ymin)/MPY

  const c4 = 4.0
'--

'++
' was main
'
  dim as single x,y,x2,y2,cx,cy
  dim as integer iter

  ' portable greymap header
  print"P2 ";MPX+1;" ";MPY+1;" ";maxiter

  cy = ymin
  for py = 0 to MPY
    cx = xmin
    for px = 0 to MPX
      x = 0.0
      y = 0.0
      x2 = 0.0
      y2 = 0.0
      iter = 0
      while iter < maxiter and  x2+y2 <= c4
        y = 2.0*x*y+cy
        x = x2-y2+cx
        iter = iter+1
        x2 = x*x
        y2 = y*y
      end while
      cx = cx+dx
      print iter
    next px
    cy = cy+dy
  next py
'--

Compile to mandelbrot-single-pgm-800x800.bas.binary:

fastspin -O2 mandelbrot-single-pgm-800x800.bas -o mandelbrot-single-pgm-800x800.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.14-beta-1162b0d3 Compiled on: Jan  2 2019
mandelbrot-single-pgm-800x800.bas
mandelbrot-single-pgm-800x800.bas.pasm
Done.
Program size is 6016 bytes

Run it in spinsim:

spinsim -b mandelbrot-single-pgm-800x800.bas.binary > mandelbrot-single-pgm-800x800.bas.pgm

mandelbrot-single-pgm-800x800.bas.pgm

pnmtopng < mandelbrot-single-pgm-800x800.bas.pgm > mandelbrot-single-pgm-800x800.bas.pgm.png

mandelbrot-single-pgm-800x800.bas.pgm.png

mandelbrot-single-pgm-800x800.bas.pgm.png

4.2.10 option-base.bas

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#option-base.

File option-base.bas:

option base 1

dim a(2)
dim b(3)

''
'' set
''
for i=1 to 2
  a(i) = 1000+i
next i

for i=0 to 2
  b(i) = 2000+i
next i

''
'' get
''
for i=1 to 2
  print "a(";i;") = ";a(i)
next i

for i=0 to 2
  print "b(";i;") = ";b(i)
next i

Compile to option-base.bas.binary:

fastspin -O2 option-base.bas -o option-base.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
option-base.bas
option-base.bas.pasm
Done.
Program size is 4852 bytes

Run it in spinsim:

spinsim -b option-base.bas.binary
a(1) = 1001
a(2) = 2000
b(0) = 2000
b(1) = 2001
b(2) = 2002

option base 1 did not prevent using the wrong array indices but at least it documents what the coder had in mind and so may give a hint in which direction the code should be corrected.

That's why I think defining arrays without prior option base n settings should be illegal. There should not be a default because being forced to use option base n adds a bit of documentation that may help to find such errors faster.

4.3 FlexC

4.3.1 inline-asm.c

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/c.md#inline-assembly.

File inline-asm.c:

#include <stdio.h>

int answer(int question) {
   int result;
   __asm {
       mov result, question
       add result, result
       add result, question
   };
   return result;
}

void main( void ) {
  printf( "the answer is %d\n", answer(14) );
}

Compile to inline-asm.c.binary:

fastspin -O2 inline-asm.c -o inline-asm.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
inline-asm.c
inline-asm.c.pasm
Done.
Program size is 2280 bytes

Run it in spinsim:

spinsim -b inline-asm.c.binary
the answer is 42

4.3.2 mandelbrot-float.c

File mandelbrot-float.c:

#include <stdio.h>
#include <stdint.h>

#define XMIN (-2.1)
#define XMAX (0.7)
#define YMIN (-1.2)
#define YMAX (1.2)

#define MAXI (32)

#define DX   ((XMAX-XMIN)/78)
#define DY   ((YMAX-YMIN)/22)

int main(){
  float cx, cy, x, y, x2, y2;
  uint32_t iter;
  
  for( cy=YMIN; cy<=YMAX; cy+=DY ) {
    for( cx=XMIN; cx<=XMAX; cx+=DX ) {
      x = y = x2 = y2 = 0.0;
      for( iter=0; iter<MAXI && x2+y2<=4.0; iter++ ) {
        y = 2*x*y+cy;
        x = x2-y2+cx;
        x2 = x*x;
        y2 = y*y;
      }
      putchar('0'+iter%10);
    }
    putchar(13);
    putchar(10);
  }
}

Compile to mandelbrot-float.c.binary:

fastspin -O2 mandelbrot-float.c -o mandelbrot-float.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
mandelbrot-float.c
mandelbrot-float.c.pasm
Done.
Program size is 2728 bytes

Run it in spinsim:

spinsim -b mandelbrot-float.c.binary
1111111111111122222222222223333333333333333333333333333333333332222222222222222
1111111111112222222223333333333333333333333344444445600655444443333332222222222
1111111111222222233333333333333333333334444444445556689915265444444333333222222
1111111112222333333333333333333333344444444445555679615223096555544444333333322
1111111122233333333333333333333344444444455666667784022222688766555554443333333
1111112223333333333333333333444444455556686041912622272228222214887800654433333
1111122333333333333333334444555555556667891322222222222222222222222290755443333
1111123333333333334445676666666666667782322222222222222222222222222229765544333
1111233334444444455556791320919402999919222222222222222222222222222222536544433
1111334444444455555567791522222222263322222222222222222222222222222222296544443
1113444444456666778032342222222222222222222222222222222222222222222225865544443
1112852022222222222222222222222222222222222222222222222222222222221297665544443
1113444444456666778032342222222222222222222222222222222222222222222225865544443
1111334444444455555567791522222222263322222222222222222222222222222222296544443
1111233334444444455556791320919402999919222222222222222222222222222222536544433
1111123333333333334445676666666666667782322222222222222222222222222229765544333
1111122333333333333333334444555555556667891322222222222222222222222290755443333
1111112223333333333333333333444444455556686041912622272228222214887800654433333
1111111122233333333333333333333344444444455666667784022222688766555554443333333
1111111112222333333333333333333333344444444445555679615223096555544444333333322
1111111111222222233333333333333333333334444444445556689915265444444333333222222
1111111111112222222223333333333333333333333344444445600655444443333332222222222

4.3.3 mandelbrot-s4p12.c

File mandelbrot-s4p12.c:

// fixpoint arithmetic mandelbrot program
// using 16 bits: viiiffffffffffff
//                ||  |_ broken part
//                ||____ integer part
//                |_____ sign bit
//
// so fixedpoint(x) = x * 4096
//                  = x << 12
// and fixedpoint(x*y) = (x*y)>>12

#include <stdio.h>
#include <stdint.h>

#define XMIN (-8601)
#define XMAX ( 2867)
#define YMIN (-4915)
#define YMAX ( 4915)

#define MAXI (32)

#define DX   ((XMAX-XMIN)/78)
#define DY   ((YMAX-YMIN)/22)

int main() {
  int32_t cx,cy,x,y,x2,y2;
  uint32_t iter;
  
  for( cy=YMIN; cy<=YMAX; cy+=DY ) {
    for( cx=XMIN; cx<=XMAX; cx+=DX ) {
      x = y = x2 = y2 = 0;
      for( iter=0; iter<MAXI && x2+y2<=16384; iter++ ) {
        y = ((x*y)>>11)+cy;
        x = x2-y2+cx;
        x2 = (x*x)>>12;
        y2 = (y*y)>>12;
      }
      putchar('0'+iter%10);
    }
    putchar(13);
    putchar(10);
  }
}

Compile to mandelbrot-s4p12.c.binary:

fastspin -O2 mandelbrot-s4p12.c -o mandelbrot-s4p12.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
mandelbrot-s4p12.c
mandelbrot-s4p12.c.pasm
Done.
Program size is 1344 bytes

Run it in spinsim:

spinsim -b mandelbrot-s4p12.c.binary
1111111111111122222222222223333333333333333333333333333333333332222222222222222
1111111111112222222223333333333333333333333344444445690655444443333332222222222
1111111111222222233333333333333333333334444444445556689016265444444333333222222
1111111112222333333333333333333333344444444445555679515223996555544444333333322
1111111122233333333333333333333344444444455666667784022222268766555554443333333
1111112223333333333333333333444444455556682041912622262226222224887800654433333
1111122333333333333333334444555555556667891422222222222222222222222200755443333
1111123333333333334445676666655666667783522222222222222222222222222219765544333
1111233333444444455556796320912301999919222222222222222222222222222222246544433
1111334444444455555567791522222222263322222222222222222222222222222222296544443
1113444444456666678032342222222222222222222222222222222222222222222225865544443
1118902122533155728222222222222222222222222222222222222222222222222297665544443
1113444444456666778042452222222222222222222222222222222222222222222226765544443
1111334444444455555577791502222222274422222222222222222222222222222222296544443
1111233334444444455556799421911204999918222222222222222222222222222222026544433
1111123333333333344445686666666666677781122222222222222222222222222229875544333
1111122333333333333333334445555555556667891422222222222222222222222200755443333
1111112223333333333333333333444444455556787341012622222222222345888810654433333
1111111222233333333333333333333344444444455666677786222222328766655554443333333
1111111112222333333333333333333333344444444445555679216223006555544444333333322
1111111111222222233333333333333333333334444444445556689624965444444333333222222
1111111111112222222223333333333333333333333344444455690655544444333332222222222
1111111111111122222222222223333333333333333333333333333333333332222222222222222

4.3.4 Importing Stuff in C

4.3.4.1 (OLD) Importing LMM-C in LMM-C - io-funcs.c

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/c.md#external-classes-eg-spin-objects. File io-funcs.c:

int puts( const char *s ) {
  int n = 0;

  while( *s ) {
    _tx( *(s++) );
    ++n;
  }
  return n;
}

File io-funcs-demo.c:

struct __using("io-funcs.c") io;

void main( void ) {
  io.puts("Hello, FlexC!\r\n");
}

Compile to io-funcs-demo.c.binary:

fastspin -O2 io-funcs-demo.c -o io-funcs-demo.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-b09b7c75 Compiled on: Dec 22 2018
io-funcs-demo.c
|-io-funcs.c
io-funcs-demo.c.pasm
Done.
Program size is 600 bytes

Run it in spinsim:

spinsim -b io-funcs-demo.c.binary
Hello, FlexC!
4.3.4.2 (NEW) Importing LMM-C and Cog-C in LMM-C - SimpleSerial.c

This is a quick and dirty partial translation of "SimpleSerial.spin" to C. It will be used to demonstrate including of external objects running in LMM or COG mode.

See https://github.com/totalspectrum/spin2cpp/blob/master/Lib/SimpleSerial.spin.

File SimpleSerial.c:

//
// SimpleSerial.c
//
// ...a crude, quick and dirty partial translation of spin2cpp's
// Lib/SimpleSerial.spin (commit 5c67857f0523280874ee654e6139a8d23c7b21c9)
//

#include <stdint.h>

uint8_t txpin, rxpin;
uint32_t baud, txmask, rxmask, bitcycles;

#ifdef PC
// we will be using stdio
#include <stdio.h>
#include <stdlib.h>
//
#else
//
#include <propeller.h>
#ifdef __P2__
#define DIRR DIRB   
#define OUTR OUTB
#define INR  INB
#else
#define DIRR DIRA
#define OUTR OUTA
#define INR  INA
#endif
//
#endif

//
// code: largely taken from FullDuplexSerial.spin
//

uint32_t start(uint32_t rx_pin, uint32_t tx_pin, uint32_t mode, uint32_t baudrate)
{
#ifndef PC
  baud = baudrate;
  bitcycles = clkfreq / baudrate;
  txpin = tx_pin;
  txmask = 1<<txpin;
  rxpin = rx_pin;
  rxmask = 1<<rxpin;
#endif
  return 1;
}

void tx(uint8_t c)
{
  uint32_t val, waitcycles;
#ifdef PC
  putchar(c);
#else
  OUTR |= txmask;
  DIRR |= txmask;
  val = ((uint16_t)c | 256) << 1; // c needs the cast or a bigger type above
  waitcycles = CNT + bitcycles;
  for( int8_t i = 0 ; i<10 ; i++ ) {
     waitcnt( waitcycles += bitcycles );
     if (val & 1)
       OUTR |= txmask;
     else
       OUTR &= !txmask;
     val >>= 1;
  }
#endif
}

uint8_t rx(void) // does NOT return errorcodes outside of the 8 bit range
{
  uint32_t waitcycles, mask, val, x;
#ifdef PC
  val = getchar();
#else
  mask = rxmask;
  DIRR &= !mask; // set for input
  // wait for start bit
  do{
    x = INR;
  }while( x & mask );
  val = 0;
  waitcycles = CNT + (bitcycles >> 1);  // sync for one half bit
  for( int i=0 ; i<8 ; i++ ) {
      val = val >> 1;
      waitcnt(waitcycles += bitcycles);
      x = INR;
      if ( x & mask )
        val |= 0x80;
  }
  // wait for stop bit?
  // skip it for now
  // waitpeq(mask, mask, 0)
#endif
  return val;
}

int32_t stop(void)
{
  waitcnt(clkfreq + cnt);
  return 1;
}
4.3.4.2.1 Include SimpleSerial.c

This simply includes SimpleSerial.c while compiling the main program. It is like including Spin objects in Spin programs and indeed FlexC's way of doing this works with code from FlexSPIN and FlexBASIC too.

File SimpleSerialDemo1.c:

struct __using("SimpleSerial.c") sio;

void str(const char *s)
{
  char c;
  while( c = *s++ )
    sio.tx(c);
}

void main(void)
{
  sio.start(31, 30, 0, 115200);

  str("Yayyyy FastSpin!.\r\n");

  // @@@TODO@@@ make a better batchable sio.rx() test.
  for(;;) {
    char c = sio.rx();
    if( c == 27 )
      break;
    else
      sio.tx( c );
  }

  sio.stop();
}

Compile to SimpleSerialDemo1.c.binary:

fastspin -O2 SimpleSerialDemo1.c -o SimpleSerialDemo1.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-b48d52d1 Compiled on: Feb 20 2019
SimpleSerialDemo1.c
|-SimpleSerial.c
SimpleSerialDemo1.c.pasm
Done.
Program size is 1260 bytes

Run it in spinsim:

( sleep 1 ; printf "Absolutely!\r\n\e" ) | spinsim -b SimpleSerialDemo1.c.binary
Yayyyy FastSpin!.
Absolutely!
4.3.4.2.2 Include SimpleSerial.c compiled to COG-PASM

For information about compiling for running in an own cog, see https://github.com/totalspectrum/spin2cpp/blob/master/Fastspin.md#spin-wrappers.

Compile the same SimpleSerial.c from above to SimpleSerial.c.cog.spin:

fastspin -O2 -w SimpleSerial.c -o SimpleSerial.c.cog.spin
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
SimpleSerial.c

File SimpleSerialDemo2.c:

struct __using("SimpleSerial.c.cog.spin") sio;

void str(const char *s)
{
  char c;
  while( c = *s++ )
    sio.tx(c);
}

void main(void)
{
  sio.__cognew();
  sio.start(31, 30, 0, 115200);

  str("Yayyyy FastSpin!.\r\n");

  // @@@TODO@@@ make a better batchable sio.rx() test.
  for(;;) {
    char c = sio.rx();
    if( c == 27 )
      break;
    else
      sio.tx( c );
  }

  sio.stop();
  sio.__cogstop();
}

Compile to sio-funcs-demo.c.binary:

fastspin -O2 SimpleSerialDemo2.c -o SimpleSerialDemo2.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
SimpleSerialDemo2.c
|-SimpleSerial.c.cog.spin
SimpleSerialDemo2.c.pasm
Done.
Program size is 2228 bytes

Run it in spinsim:

( sleep 1 ; printf "Absolutely!\r\n\e" ) | spinsim -b SimpleSerialDemo2.c.binary
Yayyyy FastSpin!.
Absolutely!

6 Labour Ward

6.1 The Mystery Of Array Initialising

See http://forums.parallax.com/discussion/comment/1457704/#Comment_1457704 and https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#global-member-and-local-variables.

File array-initialiser-1.bas:

dim as integer a(5) = { _
1, 2, 3, _
4, 5 _
}

print a(2)

Compile to array-initialiser-1.bas:

fastspin -O2 array-initialiser-1.bas -o array-initialiser-1.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-22261a8 Compiled on: Dec 14 2018
array-initialiser-1.bas
array-initialiser-1.bas(4) error: initialization is not supported for member variable a

Retry:

File array-initialiser-2.bas:

dim shared as integer a(5) = { _
1, 2, 3, _
4, 5 _
}

print a(2)

Compile to array-initialiser-2.bas.binary:

fastspin -O2 array-initialiser-2.bas -o array-initialiser-2.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-dbb1546 Compiled on: Dec 11 2018
array-initialiser-2.bas
array-initialiser-2.bas.pasm
Done.
Program size is 4344 bytes

Run it in spinsim:

spinsim -b array-initialiser-2.bas.binary
2

Eric explains this behaviour in https://forums.parallax.com/discussion/comment/1457711/#Comment_1457711:

The reason is a little obscure: an ordinary "dim" declares a member variable, which will be different in each instance of a class (even the top level program is really embedded in a class). These cannot be initialized because they're not in a fixed place in memory and there are many copies. "shared" variables though can be initialized because there is only one copy.

6.2 FullDuplexSerialDemo.bas

File FullDuplexSerialDemo.bas:

dim ser2 as class using "spin/FullDuplexSerial.spin"

ser2.start(31, 30, 0, 115200 )

open SendRecvDevice( @ser2.tx, @ser2.rx, @ser2.stop ) as #2

print #2,"Hi! (printed via FullDuplexSerial.spin)"

waitcnt cnt+clkfreq

close #2

Compile to FullDuplexSeriaDemo.bas.binary:

fastspin -O2 FullDuplexSeriaDemo.bas -o FullDuplexSeriaDemo.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
FullDuplexSeriaDemo.bas
|-FullDuplexSerial.spin
FullDuplexSeriaDemo.bas.pasm
Done.
Program size is 5292 bytes

Run it in spinsim:

spinsim -b FullDuplexSeriaDemo.bas.binary
Hi! (printed via FullDuplexSerial.spin)

6.3 Defines

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#preprocessor.

Predefined:

File defines1.bas:

print "__propeller__ -> ";_
#ifdef __propeller__
  __propeller__
#else
  "*undefined*"
#endif

print "__FASTSPIN__  -> ";_
#ifdef __FASTSPIN__
  __FASTSPIN__
#else
  "*undefined*"
#endif

print "__SPINCVT__   -> ";_
#ifdef __SPINCVT__
  __SPINCVT__
#else
  "*undefined*"
#endif

print "__FLEXBASIC__ -> ";_
#ifdef __FLEXBASIC__
  __FLEXBASIC__
#else
  "*undefined*"
#endif

print "__SPIN2PASM__ -> ";_
#ifdef __SPIN2PASM__
  __SPIN2PASM__
#else
  "*undefined*"
#endif

print "__SPIN2CPP__  -> ";_
#ifdef __SPIN2CPP__
  __SPIN2CPP__
#else
  "*undefined*"
#endif

print "__cplusplus   -> ";_
#ifdef __cplusplus
  __cplusplus
#else
  "*undefined*"
#endif

print "__P2__        -> ";_
#ifdef 
#else
  "*undefined*"
#endif

Compile to defines1.bas.binary:

fastspin -O2 defines1.bas -o defines1.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-7aa43d00 Compiled on: Dec 17 2018
defines1.bas
defines1.bas.pasm
Done.
Program size is 5100 bytes

Run it in spinsim:

spinsim -b defines1.bas.binary
__propeller__ -> 1
__FASTSPIN__  -> 3
__SPINCVT__   -> 3
__FLEXBASIC__ -> 3
__SPIN2PASM__ -> 1
__SPIN2CPP__  -> *undefined*
__cplusplus   -> *undefined*
__P2__        -> *undefined*

Own defines:

File defines2.bas:

#define camouflage "/\/\oo!"
print camouflage

Compile to defines2.bas.binary:

fastspin -O2 defines2.bas -o defines2.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.13-beta-7aa43d00 Compiled on: Dec 17 2018
defines2.bas
defines2.bas.pasm
Done.
Program size is 1488 bytes

Run it in spinsim:

spinsim -b defines2.bas.binary
/\/\oo!

6.4 spin2operators.spin

See docs/spin.md#spin2-operators.

File spin2operators.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub init
  ser.start( 31, 30, 0, 115200 )
  main
  waitcnt( _clkfreq + cnt )
  ser.stop
  cogstop( 0 )

pub main | a, b, c, d

  ''++
  '' a \ b   uses the value of a, but then sets a to b
  ''
  a := 113
  b := 335

  ser.dec( a \ b )
  ser.str( string( 13, 10 ) )
  ser.dec( a )
  ser.str( string( 13, 10 ) )
  ''--

  ''++
  '' evil mad scientist mode... mwhuaaahaahhaahahaaa...
  ''
  a := 0
  b := 90
  c := 180
  d := 270

  repeat 13
    ser.dec( a \ b \ c \ d \ a )
    ser.tx( 32 )

  ser.str( string( "...", 13, 10 ) )
  ''--

  ''++
  '' x <=> y returns -1, 0, or 1 if x < y, x == y, or x > y
  ''
  '' @@@TODO@@@ add example
  ''--

Compile to spin2operators.spin.binary:

fastspin -O2 spin2operators.spin -o spin2operators.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
spin2operators.spin
|-FullDuplexSerial.spin
spin2operators.spin.pasm
Done.
Program size is 2280 bytes

Run it in spinsim:

spinsim -b spin2operators.spin.binary
113
335
0 90 180 270 0 90 180 270 0 90 180 270 0 ...

6.5 Inline IF

@@@TODO@@@ Find a nicer example.

File InlineIFDemo.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub main

  ser.start(31, 30, 0, 115200)

  ser.dec( ( 1 < 2 ) ? 1 : 0 ) 
  ser.str(string(13,10))

  ser.dec( ( 1 > 2 ) ? 1 : 0 ) 
  ser.str(string(13,10))

  waitcnt(_clkfreq + cnt)
    ser.stop

  cogstop(0)

Compile to InlineIFDemo.spin.binary:

fastspin -O2 InlineIFDemo.spin -o InlineIFDemo.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
InlineIFDemo.spin
|-FullDuplexSerial.spin
InlineIFDemo.spin.pasm
Done.
Program size is 2172 bytes

Run it in spinsim:

spinsim -b InlineIFDemo.spin.binary
1
0

6.6 Inline IF-2

File InlineIFDemo2.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub main

  ser.start(31, 30, 0, 115200)

  ser.dec( ( 1 < 2 ) ? a : b )
  ser.str(string(13,10))

  waitcnt(_clkfreq + cnt)
    ser.stop

  cogstop(0)

pri a
  ser.str(string("called a",13,10))
  return 1

pri b
  ser.str(string("called b",13,10))
  return 2

Compile to InlineIFDemo2.spin.binary:

fastspin -O2 InlineIFDemo2.spin -o InlineIFDemo2.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
InlineIFDemo2.spin
|-FullDuplexSerial.spin
InlineIFDemo2.spin.pasm
Done.
Program size is 2136 bytes

Run it in spinsim:

spinsim -b InlineIFDemo2.spin.binary
called a
1

So no side effects by calling b.

6.7 tuple.spin

File tuple.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

pub main | i, s, d

  ser.start(31, 30, 0, 115200)

  s, d := 0, 1                  ' tuple assignment
  repeat i from 1 to 10
    s, d := f(s, d)             ' tuple assignment
    ser.dec(s)
    ser.tx(32)

  ser.str(string(13, 10))
  waitcnt(_clkfreq + cnt)
    ser.stop
  cogstop(0)

pub f(s, d) : ss, dd            ' function returning a tuple
  ss := s + d
  dd := s

Compile to tuple.spin.binary:

fastspin -O2 tuple.spin -o tuple.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
tuple.spin
|-FullDuplexSerial.spin
tuple.spin.pasm
Done.
Program size is 2136 bytes

Run it in spinsim:

spinsim -b tuple.spin.binary
1 1 2 3 5 8 13 21 34 55 

6.8 spinlibdemo.spin

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/spin.md#pub-file-and-pri-file.

File spinlibdemo.spinlib:

pub strcpy(s, d) : r
  r := d
  repeat while byte[d++] := byte[s++]

pub strlen(s) : r
  r := s
  repeat while byte[r]
    r++
  r -= s

File spinlibdemo.spinh:

pub file "spinlibdemo.spinlib" strcpy(s, d)
pub file "spinlibdemo.spinlib" strlen(s)

File spinlibdemo.spin:

con
  _clkmode = xtal1+pll16x
  _clkfreq = 80_000_000

obj
  ser : "spin/FullDuplexSerial"

var
  byte str32[32]

pub main
  ser.start(31, 30, 0, 115200)

  strcpy(string("Hello, World!", 13, 10), str32)
  ser.str(str32)

  ser.dec(strlen(str32))
  ser.str(string(" bytes including CR/LF", 13, 10))

  waitcnt(_clkfreq + cnt)
    ser.stop
  cogstop(0)

''
'' this is the thing to be demonstrated:
''
#include "spinlibdemo.spinh"

Compile to spinlibdemo.spin.binary:

fastspin -O2 spinlibdemo.spin -o spinlibdemo.spin.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
spinlibdemo.spin
|-FullDuplexSerial.spin
spinlibdemo.spinlib
spinlibdemo.spin.pasm
Done.
Program size is 2272 bytes

Run it in spinsim:

spinsim -b spinlibdemo.spin.binary
Hello, World!
15 bytes including CR/LF

6.9 anonymous.bas

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/basic.md#anonymous-functions.
(Where in the doc are anonymous subroutines?)

@@@TODO@@@ Anonymous function example(s).

File anonymous.bas:

''
'' anonymous subroutine
''
dim as sub() anonsub

anonsub = sub()
  print "Rumpelstiltskin?"
end sub

anonsub

''
'' anonymous subroutine (short variant)
''
anonsub = [: print "Rumpelstiltskin!" ]

anonsub()

Compile to anonymous.bas.binary:

fastspin -O2 anonymous.bas -o anonymous.bas.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.20-beta-7ed0e6c6 Compiled on: Feb 14 2019
anonymous.bas
anonymous.bas.pasm
Done.
Program size is 4148 bytes

Run it in spinsim:

spinsim -b anonymous.bas.binary
Rumpelstiltskin?
Rumpelstiltskin!

6.10 screen-bitmap-as-type.bas

This demonstrates a way to define multidimensional arrays a(y)(x) as alternative to the more common form a(y,x) which is planned to be implemented later.

File screen-bitmap-as-type.bas:

option base 0

dim vga as class using "VGA_512x384_Bitmap.spin"

type scanline as ubyte(vga.hp / 8 - 1)
type screen as scanline(vga.vp - 1)

dim shared as ulong sync
dim shared as screen bitmap

dim shared as ushort colors(vga.xtiles * vga.ytiles - 1)
''
''        lowest pin of VGA pin group
''        |
''        V
vga.start(16, @colors, @bitmap, @sync)
''
'' set set same colorpair for all tiles
''
wordfill(@colors, &b111111_00_000000_00, 192)

bytefill(@bitmap, 0, vga.vp * vga.hp / 8 )

for x = 0 to 383
  plot x, x
  plot 511-x, x
next

do
loop

sub plot x,y
  var byt = x >> 3
  bitmap(y)(byt) = bitmap(y)(byt) or (1 << (x and 7))
end sub

Compile to screen-bitmap-as-type.bas.binary:

fastspin -O2 screen-bitmap-as-type.bas -o screen-bitmap-as-type.bas.binary -L /opt/parallax.spin.src/spin
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.20-beta-7ed0e6c6 Compiled on: Feb 14 2019
screen-bitmap-as-type.bas
|-VGA_512x384_Bitmap.spin
screen-bitmap-as-type.bas.pasm
Done.
Program size is 26320 bytes

7 Sick Bay

7.1 stdio.h - printf

To do … laaater. ;-)

$ cat printftest.c
#include <stdio.h>

void main(void)
{
  int i = printf("%s\n","Test.");
  printf("returned %d\n",i);
}
$ make printftest -B
cc     printftest.c   -o printftest
$ ./printftest
Test.
returned 6
$ fastspin printftest.c -I /opt/propellerbasics/include
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2018 Total Spectrum Software Inc.
Version 3.9.12 Compiled on: Dec 10 2018
printftest.c
/tmp/mc-yeti/printftest.c(6) error: incompatible types in assignment

7.2 longlong.c

See https://github.com/totalspectrum/spin2cpp/blob/master/doc/c.md#missing-features.

File longlong.c:

#include <stdio.h>

void main(void) {
   long long a, a1, a2;

   printf("sizeof(long long) = %d\n", sizeof(a));

   a1 = 0xffffffff;
   a2 = 0x10101010;
   a  = a1 * a2;
}

Compile to longlong.c.binary:

fastspin -O2 longlong.c -o longlong.c.binary
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.21-beta-f8ca5a2a Compiled on: Feb 19 2019
longlong.c
/home/yeti/wrk/orgy/fastspin/longlong.c(8) error: Cannot handle expression yet
/home/yeti/wrk/orgy/fastspin/longlong.c(9) error: Cannot handle expression yet
/home/yeti/wrk/orgy/fastspin/longlong.c(10) error: Cannot handle expression yet

Run it in spinsim:

spinsim -b longlong.c.binary

8 Build FastSpin

git clone https://github.com/totalspectrum/spin2cpp.git
Cloning into 'spin2cpp'...
cd spin2cpp
make
mkdir -p ./build
bison -p spinyy -t -b ./build/spin -d frontends/spin/spin.y
frontends/spin/spin.y: warning: 20 shift/reduce conflicts [-Wconflicts-sr]
bison -p basicyy -t -b ./build/basic -d frontends/basic/basic.y
frontends/basic/basic.y: warning: 29 shift/reduce conflicts [-Wconflicts-sr]
bison -p cgramyy -t -b ./build/cgram -d frontends/c/cgram.y
frontends/c/cgram.y: warning: 2 shift/reduce conflicts [-Wconflicts-sr]
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/lexer.o -c frontends/lexer.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/symbol.o -c symbol.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/ast.o -c ast.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/expr.o -c expr.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/dofmt.o -c util/dofmt.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/flexbuf.o -c util/flexbuf.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/lltoa_prec.o -c util/lltoa_prec.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/strupr.o -c util/strupr.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/strrev.o -c util/strrev.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/strdupcat.o -c util/strdupcat.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/preprocess.o -c preprocess.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/cppexpr.o -c backends/cpp/cppexpr.c
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/testlex testlex.c build/lexer.o build/symbol.o build/ast.o build/expr.o build/dofmt.o build/flexbuf.o build/lltoa_prec.o build/strupr.o build/strrev.o build/strdupcat.o build/preprocess.o build/cppexpr.o -lm
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/common.o -c frontends/common.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/spinc.o -c spinc.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/functions.o -c functions.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/cse.o -c cse.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/loops.o -c loops.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/pasm.o -c pasm.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/outdat.o -c backends/dat/outdat.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/outlst.o -c backends/dat/outlst.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/spinlang.o -c frontends/spin/spinlang.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/basiclang.o -c frontends/basic/basiclang.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/clang.o -c frontends/c/clang.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/outasm.o -c backends/asm/outasm.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/assemble_ir.o -c backends/asm/assemble_ir.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/optimize_ir.o -c backends/asm/optimize_ir.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/inlineasm.o -c backends/asm/inlineasm.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/outcpp.o -c backends/cpp/outcpp.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/cppfunc.o -c backends/cpp/cppfunc.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/outgas.o -c backends/cpp/outgas.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/directive.o -c mcpp/directive.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/expand.o -c mcpp/expand.c
mcpp/expand.c: In function 'stringize':
mcpp/expand.c:1292:17: warning: variable 'file' set but not used [-Wunused-but-set-variable]
     FILEINFO *  file;
                 ^~~~
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/mbchar.o -c mcpp/mbchar.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/mcpp_eval.o -c mcpp/mcpp_eval.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/mcpp_main.o -c mcpp/mcpp_main.c
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/mcpp_system.o -c mcpp/mcpp_system.c
mcpp/mcpp_system.c: In function 'NormalizePath':
mcpp/mcpp_system.c:911:16: warning: return discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
         return path;
                ^~~~
gcc -MMD -MP -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/mcpp_support.o -c mcpp/mcpp_support.c
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -DGITREV=e379a378 -o build/version.o -c version.c
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/spin.tab.o -c build/spin.tab.c
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/basic.tab.o -c build/basic.tab.c
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/cgram.tab.o -c build/cgram.tab.c
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/spin2cpp spin2cpp.c build/common.o build/spinc.o build/lexer.o build/symbol.o build/ast.o build/expr.o build/dofmt.o build/flexbuf.o build/lltoa_prec.o build/strupr.o build/strrev.o build/strdupcat.o build/preprocess.o build/cppexpr.o build/functions.o build/cse.o build/loops.o build/pasm.o build/outdat.o build/outlst.o build/spinlang.o build/basiclang.o build/clang.o build/outasm.o build/assemble_ir.o build/optimize_ir.o build/inlineasm.o build/outcpp.o build/cppfunc.o build/outgas.o build/directive.o build/expand.o build/mbchar.o build/mcpp_eval.o build/mcpp_main.o build/mcpp_system.o build/mcpp_support.o build/version.o build/spin.tab.o build/basic.tab.o build/cgram.tab.o -lm
gcc -g -Wall -I. -I./build -DFLEXSPIN_BUILD -o build/fastspin fastspin.c build/common.o build/spinc.o build/lexer.o build/symbol.o build/ast.o build/expr.o build/dofmt.o build/flexbuf.o build/lltoa_prec.o build/strupr.o build/strrev.o build/strdupcat.o build/preprocess.o build/cppexpr.o build/functions.o build/cse.o build/loops.o build/pasm.o build/outdat.o build/outlst.o build/spinlang.o build/basiclang.o build/clang.o build/outasm.o build/assemble_ir.o build/optimize_ir.o build/inlineasm.o build/outcpp.o build/cppfunc.o build/outgas.o build/directive.o build/expand.o build/mbchar.o build/mcpp_eval.o build/mcpp_main.o build/mcpp_system.o build/mcpp_support.o build/version.o build/spin.tab.o build/basic.tab.o build/cgram.tab.o -lm
ls -l build/fastspin build/spin2cpp
-rwxr-xr-x 1 yeti yeti 1298304 Jan 19 03:59 build/fastspin
-rwxr-xr-x 1 yeti yeti 1302280 Jan 19 03:59 build/spin2cpp
build/fastspin
Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2019 Total Spectrum Software Inc.
Version 3.9.15 Compiled on: Jan 19 2019
usage: build/fastspin [options] filename.spin | filename.bas
  [ -h ]              display this help
  [ -L or -I <path> ] add a directory to the include path
  [ -o <name> ]      set output filename to <name>
  [ -b ]             output binary file format
  [ -e ]             output eeprom file format
  [ -c ]             output only DAT sections
  [ -l ]             output DAT as a listing file
  [ -f ]             output list of file names
  [ -q ]             quiet mode (suppress banner and non-error text)
  [ -p ]             disable the preprocessor
  [ -D <define> ]    add a define
  [ -u ]             ignore for openspin compatibility (unused method elimination always enabled)
  [ -2 ]             compile for Prop2
  [ -O# ]            set optimization level:
          -O0 = no optimization
          -O1 = basic optimization
          -O2 = all optimization
  [ -H nnnn ]        set starting hub address
  [ -E ]             skip initial coginit code (usually used with -H)
  [ -w ]             compile for COG with Spin wrappers
  [ -C ]             enable case sensitive mode
  [ --code=cog ]     compile for COG mode instead of LMM
  [ --fcache=N ]     set FCACHE size to N (0 to disable)
  [ --fixedreal ]    use 16.16 fixed point in place of floats
build/spin2cpp
Spin to C++ converter version 3.9.15
Usage: build/spin2cpp [options] file.spin
Options:
  --asm:     output (user readable) PASM code
  --binary:  create binary file for download
  --cogspin: create PASM based Spin object (translate Spin to PASM)
  --ccode:   output C code instead of C++
  --cse:     perform common subexpression optimizations on C code
  --cc=CC:   use CC as the C++ compiler instead of PropGCC
  --code=x : PASM output only: control placement of code
             x can be cog (default) or hub (for LMM)
  --ctypes : use inferred pointer (and other) types in generated C/C++ code
  --data=x : PASM output only: control placement of data
             x can be cog or hub (default is hub)
  --dat:     output binary blob of DAT section only
  --eeprom:  create EEPROM binary file for download
  --elf:     create executable ELF file with propgcc
  --files:   print list of .cpp files to stdout
  --fixed:   use 16.16 fixed point in place of float
  --fcache=N: set size of FCACHE area
  --gas:     create inline assembly out of DAT area;
             with --dat, create gas .S file from DAT area
  --list:    produce a listing file
  --main:    include C++ main() function
  --noheader: skip the normal comment about spin2cpp version
  --nocse:   disable common subexpression optimizations on PASM code
  --noopt:   turn off all optimization in PASM output
  --nopre:   do not run preprocessor on the .spin file
  --nofcache: disable FCACHE (same as --fcache=0)
  --normalize: normalize case of all identifiers
  --p2:       use Propeller 2 instructions (experimental)
  --require:  require a specific version (or later) of spin2cpp
  --side:     create a SimpleIDE file for the C/C++ outputs
  -Dname=val: define a preprocessor symbol
  -g:         add debug info to output (original source for PASM output)
  -I dir:     add dir to the object search path
  -L dir:     same as -I
  -o file:    place final output in file
  -y:         debug parser
  --version:  print version and exit

9 Famous Last Words

                                           .-----+-----.
                         .----+----.       |  The END  |
                         | Repent! |       | is neigh! |
                         ·----+----·       ·-----+-----·
                              |  _    _       _  |
                              |\°v°  °v°     ò.ó/|
                                |_|\/|_|)   /|_|
--------------------------------^-^--^-^-----^-^--------------------------------

10 The End

Author: yeti

Created: 2019-02-20 Mi 18:43

Emacs 25.1.1 (Org mode 8.2.10)

Validate