fastspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler

16061626365

Comments

  • ersmith wrote: »
    but it seems to be considered poor style.
    ... Mostly because it hinders incremental compilation, which fastspin doesn't support, anyways. I guess it'd also cause problems if you wanted to use a build script that just compiles all *.c files it finds.
  • Found something strange... I got an error when trying to use "pB" as a local variable (because it's a hardware register), so changed to "pBmp".
    But, I missed the change in a key line. It worked anyway! How can this be?

    Here's the routine. This code takes RGB bytes from an image buffer, turns them into RGB words, then copies to screen buffer (gotten with GetBuffer()).
    I meant to do pBuff:=GetBuffer() instead of pB:=GetBuffer(). I don't think this should have worked because pBmp isn't initialized, but it does.
    setting pBmp to zero doesn't work, so somehow it is getting initialized to the right value...
    PUB Buffer2Vga(p,w,h,n)|x,y,z,i,r,g,b,c,pBmp 'copy buffer of rgb (if n==3) vales to 16 bit screen buffer
        pB:=GetBuffer()
        repeat y from 0 to h-1
            repeat x from 0 to w-1
                r:=byte[p++]
                g:=byte[p++]
                b:=byte[p++]    
                c:=r<<24+g<<16+b<<8
                org
                    rgbsqz  c
                end
                word[pBmp][x]:=c
            pBmp+=640*2
    
  • RaymanRayman Posts: 11,281
    edited 2020-09-16 - 15:58:21
    The above is really bizarre... I'm looking at the PASM2, but don't see how this is possible yet...
    I see pBmp being initialized to zero, but somehow is getting changed...
    I think it must be something to do with a call to FCACHE_LOAD after the registers are pushed...
    I guess the registers are being pushed at the beginning and popped at the end because of the use of the PB register....

    Not sure worth investigating...

    Would it be best to not allow register names to be used in Spin2 outside of assembly blocks?
  • The line "pb := GetBuffer()" is legal because it assigns a value to hardware register "pb". But it's not doing what you want because you really wanted to write "pBmp := GetBuffer()".

    Hardware registers may be used in Spin2, e.g. for setting pins in OUTA and OUTB. PB happens to fall under that. I don't know if Chip's interpreter somehow restricts which registers may be used in Spin2. If it does then I'll change fastspin.
  • TonyB_TonyB_ Posts: 1,521
    edited 2020-09-17 - 09:18:32
    I write pure P2 assembly code but I can't use some symbol names that I want because they are P1 reserved words, e.g. IF and SPR. Is it possible to tell the compiler to ignore P1 stuff?
  • TonyB_ wrote: »
    I write pure P2 assembly code but I can't use some symbol names that I want because they are P1 reserved words, e.g. IF and SPR. Is it possible to tell the compiler to ignore P1 stuff?

    PNut doesn't like "IF" either, so I don't think you'll ever be able to use that in assembly. SPR should be Spin1 only, I'll change it to that (the Spin2 version of it is "REG"). Note that in fastspin it's the file extension that determines Spin1 or Spin2, *not* the processor being compiled for.
  • JRoarkJRoark Posts: 548
    edited 2020-09-17 - 18:59:12
    @ersmith: This is an odd one in the current version of FlexBASIC:

    This code works fine:
    dim i as long
    	for i = 31 to 0 step -1
    		print i;",";
    	next i
    
    and it returns what you would expect:
    31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0
    
    But this code, with I defined as a ULONG, never exits the loop:
    dim i as ulong
    	for i = 31 to 0 step -1
    		print i;",";
    	next i
    
    and looking at the output you can see it corrupts/wraps variable "I" bigly-big after hitting zero:
    31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,4294967295,4294967294,4294967293,4294967292,4294967291,4294967290,4294967289,4294967288,4294967287,4294967286,4294967285,4294967284,4294967283,4294967282,4294967281,4294967280,4294967279,4294967278,4294967277,4294967276,4294967275,4294967274.....(etc, etc)
    
    FWIW, it has been MONTHS since I've been able to break FlexBASIC, even though I've been trying. This thing is getting rather hard to kill! :smile:

    EDIT: further testing shows this behavior also holds true for the other non-float types: USHORT, UBYTE, UINTEGER, etc.
  • @JRoark: I think you'll find that the exact problem is an unsigned type counting down to 0, and that's because the final test (is x >= 0?) is always true if x is unsigned. If you count down to 1 it should be fine; similarly if you count down using a signed variable it should be fine too.

    I'm looking into this, but it's not immediately obvious what the best way to fix it is.
  • ersmith wrote: »
    @JRoark: I think you'll find that the exact problem is an unsigned type counting down to 0, and that's because the final test (is x >= 0?) is always true if x is unsigned. If you count down to 1 it should be fine; similarly if you count down using a signed variable it should be fine too.

    I'm looking into this, but it's not immediately obvious what the best way to fix it is.
    Maybe you could do the test before the decrement? That way it could be "is x > 0".

  • David Betz wrote: »
    ersmith wrote: »
    @JRoark: I think you'll find that the exact problem is an unsigned type counting down to 0, and that's because the final test (is x >= 0?) is always true if x is unsigned. If you count down to 1 it should be fine; similarly if you count down using a signed variable it should be fine too.

    I'm looking into this, but it's not immediately obvious what the best way to fix it is.
    Maybe you could do the test before the decrement? That way it could be "is x > 0".

    The trouble is that the BASIC for loop is being converted to a C for loop like "for( x=7; x >= 0; --x )" and for those the increment always happens after the test.

    I've fixed it in github by special casing 0 with an unsigned variable so (in that case only) the loop becomes "for( x=7; x <= 7; --x )". Counting up to $ffffffff has a similar fix.

    There are potentially problems with signed variables running into the same thing when crossing $7fffffff and $80000000. Actually there's no way in general to prevent all possible confusions given a limited variable size and arbitrary steps. Floating point is much less susceptible to these kinds of issues. But fixing the 0 special case fixes the most common possible confusion.
  • JRoarkJRoark Posts: 548
    edited 2020-09-18 - 15:27:21
    Thanks, Eric!

    I know... I’m a royal pain in the compilers tush sometimes. :)
  • RaymanRayman Posts: 11,281
    edited 2020-09-19 - 19:50:47
    The included FatFs uSD reader seems to fail to open a file when compiled with "-O2" option...
    Anything to do about this? Hoping that change to the delays didn't mess it up...

    I tried big delays and it still didn't work...

  • Rayman wrote: »
    The included FatFs uSD reader seems to fail to open a file when compiled with "-O2" option...
    Anything to do about this? Hoping that change to the delays didn't mess it up...

    I tried big delays and it still didn't work...

    Try "-O2,!cse". The CSE can cause some subtle bugs in my experience.
  • That worked! Thanks.
  • evanhevanh Posts: 9,854
    edited 2020-09-19 - 20:26:06
    that's a secret switch! And what is CSE?
  • evanh wrote: »
    that's a secret switch! And what is CSE?

    It's not secret if you read the documentation :)
  • evanhevanh Posts: 9,854
    edited 2020-09-19 - 21:49:27
    ah, I usually stop at --help. Sometimes I'll do a google. Online manuals often don't get much of a look-in.
  • RaymanRayman Posts: 11,281
    edited 2020-09-19 - 23:35:55
    The main() routine in this mp2 decoder has this in it:
    unsigned char buffer[144000];
    

    And yet, the binary is only 75 kB... How can this be? Is it on the stack somehow?

    BTW: This value was originally 1440000, which compiled, but didn't run...
  • evanhevanh Posts: 9,854
    edited 2020-09-19 - 23:58:46
    If that's within a function then it's known as an auto - which means not persistent. Which is same as local in other languages. For small items it can be optimised into a register for the duration but, yeah, stack will be the default otherwise. Static and extern declarations get put on the heap. I think definitions outside of a function are inherently static - which means persistant.

  • Ok, that makes sense. Should have realized that... It's just a local variable. Thanks.
  • Was trying to compile Nuklear... This may not actually work out, but just looking at it...

    Anyway, it gives this error on array size "NK_BUFFER_MAX", but I think this value is defined in the enum just before it... Is this a bug?
    687 x 741 - 52K
  • Is vector a c++ only thing, not likely to be supported?
  • Anything std:* is C++ libraries, and unlikely to be supported soon. Most of the std:* stuff also requires template support, and I'm unsure if Eric plans to add that.
  • I came across this function... It compiles, and prints out what looks right, but then puts out some garbage... Should this work?
    void
    die(const char* fmt, ...) {
    	va_list ap;
    
    	va_start(ap, fmt);
    	vfprintf(stderr, fmt, ap);
    	va_end(ap);
    
    	if (fmt[0] && fmt[strlen(fmt) - 1] == ':') {
    		fputc(' ', stderr);
    		perror(NULL);
    	}
    	else {
    		fputc('\n', stderr);
    	}
    
    	exit(1);
    }
    
  • RaymanRayman Posts: 11,281
    edited 2020-09-22 - 15:38:14
    I'm having an issue with a function that returns a "Position".
    I think I've narrowed down the issue to this function call having Position as return value:
    Position insertstr(Position p, char* src)
    {
    

    Gives this kind of error:
    1>NoVi.p2asm:921: error: Unknown symbol _loadfile_0010_p_0043_01
    1>NoVi.p2asm:935: error: Unknown symbol loadfile_0010_tmp014__01
    

    Ran into this trying to compile MVI. For debugging it, I made this "NoVi" version, adding things from MVI until it broke again... Source attached...

    Guess I should say that the Position structure is defined like this:
    typedef struct Line Line;
    struct Line {
    	char* s;  /* string content */
    	size_t l; /* length excluding \0 */
    	size_t v; /* visual length */
    	size_t m; /* multiples of LINSIZ? */
    	Line* p;  /* previous line */
    	Line* n;  /* next line */
    };
    
    typedef struct {
    	Line* l;
    	size_t o;  /* offset */
    } Position;
    

  • I'm getting a similar error trying to compile raycastlib... https://gitlab.com/drummyfish/raycastlib/-/tree/master

    It's giving an error on trying to get an address to an element of a structure within a structure...
    Also, this is strange... I tried to apply a fix (that didn't work so well) and got this output (below).
    It makes a working binary, but exits on errors....
    1>Propeller Spin/PASM Compiler 'FastSpin' (c) 2011-2020 Total Spectrum Software Inc.
    1>Version 4.3.2-beta-v4.3.1-30-gdde657a0 Compiled on: Sep 11 2020
    1>testSDL.c
    1>|-VGA_16bpp.spin2
    1>clock.c
    1>fmt.c
    1>posixio.c
    1>bufio.c
    1>errno.c
    1>testSDL.p2asm
    1>Done.
    1>../raycastlib.h:1297: warning: incompatible pointer types in assignment
    1>./programs/testSDL.p2asm:323: error: Unknown symbol _RCL_angleToDirection_result_0006_01
    1>./programs/testSDL.p2asm:343: error: Unknown symbol _RCL_castRayMultiHit_currentPos_0016_01
    1>./programs/testSDL.p2asm:354: error: Unknown symbol _RCL_castRayMultiHit_currentSquare_0017_01
    1>./programs/testSDL.p2asm:368: error: Unknown symbol _RCL_castRayMultiHit_nextSideDist_0019_01
    1>./programs/testSDL.p2asm:440: error: Unknown symbol _RCL_castRayMultiHit_delta_0020_01
    1>./programs/testSDL.p2asm:474: error: Unknown symbol _RCL_castRayMultiHit_step_0021_01
    1>./programs/testSDL.p2asm:905: error: Unknown symbol RCL_castRaysMultiHit_tmp012__01
    
  • @Rayman : thanks for the bug reports. Here's an updated fastspin binary that fixes at least some of the problems.
  • Thanks! That does fix the NoVi issue. I'm amazed at the kind of stuff that compiles! Digging through these test codes is helping sharpen my C skills...

    Could you also look at this one? Gives an error on line 1300 of raycastlib.h. I think it's trying to reference an element within a structure within a structure...
  • Think I’m seeing that loadp2 only works with low number com ports. Can that be?
  • evanhevanh Posts: 9,854
    edited 2020-09-25 - 00:30:44
    Specifying the port with -p option may help. I always specify the port, by board identifier, because I have multiple Eval Boards attached. For example, I use the shell history to repeatedly issue this: filename=test-hr-streamer; echo; fastspin -I include -q -l -2b ${filename}.spin2; echo; loadp2 -p /dev/serial/by-id/usb-Parallax_Inc_Propeller_P2-ES_EVAL_P23YOO42-if00-port0 ${filename}.binary -v -t -b230400 -SINGLE

    And when I wish to change the target board I either go back to prior history or backspace on the identifier and use name completion to fill in the alternative identifier.

Sign In or Register to comment.