... 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
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.
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?
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.
@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.
@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".
@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.
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...
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.
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.
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'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;
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
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...
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.
Comments
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...
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?
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.
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.
This code works fine: and it returns what you would expect: But this code, with I defined as a ULONG, never exits the loop: and looking at the output you can see it corrupts/wraps variable "I" bigly-big after hitting zero: 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!
EDIT: further testing shows this behavior also holds true for the other non-float types: USHORT, UBYTE, UINTEGER, etc.
I'm looking into this, but it's not immediately obvious what the best way to fix it is.
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.
I know... I’m a royal pain in the compilers tush sometimes.
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.
It's not secret if you read the documentation
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...
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?
I think I've narrowed down the issue to this function call having Position as return value:
Gives this kind of error:
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:
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....
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...
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.