flexspin compiler for P2: Assembly, Spin, BASIC, and C in one compiler - Page 15 — Parallax Forums

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

• Posts: 4,885
Rayman wrote: »
If you do this with "OBJ", then you must need some kind of Spin "Start" function to start the assembly cog, right?

Sounds like you're saying to just do it the same way as with P1...

Yes. The P1 way of doing objects seems to work well, and provides good namespace isolation and modularity. Did you have something else in mind?
• Posts: 11,962
Maybe it's OK. I'll have to try it out and see...
• Posts: 8,690
Are there version of FastSpin, Spin2CPP, and Spin2gui available for or planned for Linux?
• Posts: 10,907
Ah, yep, that's the native development environ. I see mention of Debian and Ubuntu explicitly.
• Posts: 4,885
kwinn wrote: »
Are there version of FastSpin, Spin2CPP, and Spin2gui available for or planned for Linux?

There are no pre-packaged binaries, but the default for the source code is to build for Linux. I used to provide pre-built binaries for Linux, but nobody was downloading them. I think most Linux users prefer to build code themselves.

The build process for fastspin/spin2cpp is very straightforward:
  git clone https://github.com/totalspectrum/spin2cpp
cd spin2cpp
make

Binaries are placed in the "build" directory.

• Posts: 337
I've been working on getting my USB "boot protocol" mouse/keyboard host/drive converted to a spin object. I've got the USB controlRead/controlWrite transfer routines working and I can enumerate a device. Currently the code is all cog/lut execution, but I'm out of space. To get a device configured and transferring mouse/keyboard data will require hub execution too, and my first attempts at implementing it haven't gone well.

Is "native" p2 hub execution in a DAT block supported by fastspin?

I'm sure my woes are due to not fully understanding which addressing mode to use when calling hub code from cog/lut, but trying to determine the "right" way has me scratching my head::

CALL #hubsub fails.
CALL #\hubsub fails.
CALL #@hubsub works.

Aren't #2 and #3 essentially the same?

#2 compiles to:
01690     BC 0B A0 FD |                 call    #\testsub

and #3:
01690     D0 21 A0 FD |                 call    #@testsub


I haven't found anything in the fastspin docs regarding hub execution in a DAT block of a spin object. If it is doable, IMO a "Cliff Notes" regarding JMP/CALL addressing "gotchas" for cog/lut/hub regions would be a welcome addition.

Any insight would be greatly appreciated!
Thanks!
• Posts: 4,885
The four calls
   call #testsub
call #\testsub
call #@testsub
call #\@testsub

are potentially all different. "\" forces the call to be compiled as an absolute address rather than PC relative, and "@" forces the assembler to use the HUB address of testsub rather than the default address. The default address is the same as the HUB address after an ORGH, but is not the same after ORG. For example:
   ORGH $400 ORG 0 call #label1 call #\label1 call #@label1 call #\@label1 label1 ret  There "label1" is located in HUB memory at address$410, but its COG address is 4 (COG memory is addressed by longwords). So this is basically assembled the same as:
   call #4    ' will be assembled as a relative call in COG memory
call #\4   ' will be assembled as an absolute call in COG memory
call #$410 ' will jump to HUB memory (absolute call if we start in COG) call #\$410 ' always an absolute jump to HUB memory


All this is the same in both fastspin and PNut, by the way.

If you want to use hubexec in a Spin object, which is only available in fastspin, then I would recommend (a) using the most recent version of fastspin (3.9.25), and (b) always putting @ in front of labels used for HUB calls. (b) isn't always necessary in pure PASM code: if the last ORG type directive before a label was an ORGH then the label will have its HUB value by default, so label and @label are the same. But in Spin objects the compiler may not compute the HUB address of "label" correctly if there's no @ in front of it. It's not clear yet what the "official" Spin2 compiler will do in this case.
• Posts: 11,962
I think the backslash means absolute address.
Don’t think that can work with spin...
• Posts: 337
edited 2019-04-28 00:24
ersmith wrote: »
All this is the same in both fastspin and PNut, by the way.

If you want to use hubexec in a Spin object, which is only available in fastspin, then I would recommend (a) using the most recent version of fastspin (3.9.25), and (b) always putting @ in front of labels used for HUB calls. (b) isn't always necessary in pure PASM code: if the last ORG type directive before a label was an ORGH then the label will have its HUB value by default, so label and @label are the same. But in Spin objects the compiler may not compute the HUB address of "label" correctly if there's no @ in front of it. It's not clear yet what the "official" Spin2 compiler will do in this case.
Thanks, your info has removed the scales from mine eyes . It's been at least a decade since I last did anything meaningful in spin, and my aging brain is taking longer than I'd like to get back in the groove

Thanks again for the quick response!
• Posts: 17,701
IIRC there is details of the / @ etc label prefixes in the Tricks and Traps Reference thread and followup discussion in the Tricks and Traps Discussion thread. There are some gotchas here where the compilers seem to do different things. There is also reference to a further thread where its' discussed in more detail. I suggest you look at the listing to see what has been used where it really matters.
• Posts: 673
@ersmith Here's a bug submission for SELECT CASE in BASIC.

Code written in this manner only runs the code in ELSE, despite similar code listed in the basic.pdf manual.
Issue: It will always just print "Something Other Than A or B Was Pressed" despite sending an A or B keypress over serial.
    PRINT "PRESS A or B"
K$= INPUT$(1)
KEYPRESS = ASC(K$) PRINT " "; KEYPRESS SELECT CASE K$
CASE "A"
PRINT "KEY A Was Pressed"
CASE "B"
PRINT "KEY B Was Pressed"
CASE "a"
PRINT "KEY a Was Pressed"
CASE "b"
PRINT "KEY b Was Pressed"
CASE ELSE
PRINT "Something Other Than A or B Was Pressed"
END SELECT

PRESS A or B
C 67
Something Other Than A or B Was Pressed
PRESS A or B
B 66
Something Other Than A or B Was Pressed
PRESS A or B
A 65
Something Other Than A or B Was Pressed
PRESS A or B

• Posts: 4,885
whicker wrote: »
@ersmith Here's a bug submission for SELECT CASE in BASIC.

Thanks for the bug report! The code wasn't at all doing what I wanted it to. I think I see how to fix it though, so it should work properly in the next release.

• Posts: 4,885
There are new versions available now of (3.9.26) of spin2gui and fastspin. The changes are:

- Added DEF FNA(X)=X form to BASIC
- Fixed declarations of functions inside other C functions
- Fixed SELECT CASE in BASIC when the test is on strings or floats
- Fixed an optimizer bug that affected local arrays
- Fixed space allocation for local arrays in C functions
- On P2, default to 160MHz and 230400 baud if no explicit clkset is given
- Made BASIC read functions support base 16 and base 2 numbers
- Implemented struct assignment for C
- Experimental -z option to compress the code (produces smaller but slower code)

The -z flag is only supported for P1 now, and is still quite buggy, so not ready for production, but eventually it will allow for smaller but slower code (like PropGCC's CMM mode).

On P2 if no explicit clkset() is given before any output, we default to 160 MHz with 230400 baud. This makes porting programs much simpler (no need to add in the clkset and _setbaud calls).

The C compiler support in fastspin is quite a bit better now, and is able to compile the dhrystone, xxtea, and fftbench benchmarks properly. I hope to update the C compiler benchmarks threads later.
• Posts: 4,885
New versions (3.9.27) of fastspin and spin2gui are available now. The main change is that Spin CASE statements (and BASIC SELECT and C switch) use a jump table now if they can, and the CASE_FAST keyword is supported to force use of a jump table and to produce an error if a jump table cannot be used. There is also better support for old style C function declarations, and a CAST operator has been added to BASIC to allow easy conversion between pointer and integer types.
• Posts: 10,907
Eric,
Found another minor missing error message. NOP isn't permitted to have conditional execution, or a _ret_. When applying such, there is no error reported.
• Posts: 4,885
Thanks Evan. That's fixed in github now (adding any kind of condition to a NOP produces an error).
• Posts: 3,344
edited 2019-06-18 12:26
found some misbehavior

outa, ptra++ results in

error: unknown operator in constant expression 281

same for dirh / dirl ...
Enjoy!

Mike
• Posts: 4,885
msrobots wrote: »
found some misbehavior

outa, ptra++ results in

error: unknown operator in constant expression 281

same for dirh / dirl ...
Enjoy!

Mike

It sounds like you're trying to compile P2 code for P1?
• Posts: 3,344
edited 2019-06-18 12:59
no it is my current project

sorry typo

outh, ptra++ does not work and should, doesn't it?

confused

Mike
• Posts: 10,907
edited 2019-06-18 13:37
That one isn't legal Mike. ptra++ will only work for the RD/WRxxxx hub access instructions.
outh	ptra++

Fastspin gives an error, it's not an ordinary error but this occurs:
error: unknown operator in constant expression 281

EDIT: Doh! I see you already posted the error message.
• Posts: 4,885
Ah, I see -- fastspin wasn't specifically checking for bad use of ptra++ and such, it was just finding it out in a later phase of compilation when those expressions turned out to be invalid. I've checked in a fix for this. Thanks for the bug report Mike (and for the clarification Evan).
• Posts: 3,344

is it not valid to use ptra++ as source for a outl command?

I currently just use another long in COG ram and increment it by myself.

confused

Mike
• Posts: 4,885
Auto-incrementing (using ++ after ptra or ptrb) is only valid in the source for a read or write instruction (rdlong, wrlong, rdbyte, wrbyte, etc.). It is not valid for any other instructions.

What did you want "outl ptra++" to do? Did you think it would fetch the data pointed at by ptra and use that for the outl? You can accomplish that by:
   rdlong x, ptra++
outl x

Or, if you just wanted to increment ptra and use it for the out value you can do:
   outl ptra
add  ptra, #1  ' or whatever size increment you wanted here

• Posts: 10,907
msrobots wrote: »
is it not valid to use ptra++ as source for a outl command?
Correct. If you look through the instruction set spreadsheet you'll see just a few that have a /P in the S-operand column of the Assembly Syntax.
• Posts: 10,907
Eric,
I'm in the process of getting up to speed with one of Mikes many projects that is written in fastspin. He's used the CASE statement and clearly hasn't had any issues. I suspect I'm using a newer version of fastpin. I'm using fastspin version 3.9.28-beta- from a couple days back.

For me, the case is always taking the "other" branch. But when I edit the statement to be case_fast instead, it behaves correctly again.

• Posts: 4,885
evanh wrote: »
I'm in the process of getting up to speed with one of Mikes many projects that is written in fastspin. He's used the CASE statement and clearly hasn't had any issues. I suspect I'm using a newer version of fastpin. I'm using fastspin version 3.9.28-beta- from a couple days back.

For me, the case is always taking the "other" branch. But when I edit the statement to be case_fast instead, it behaves correctly again.

Could you give the most current version in github a try? Someone else ran into a case bug which I fixed yesterday, I hope it's the same as what you're seeing.

Regards,
Eric
• Posts: 10,907
Yep, fixed, thanks.
• Posts: 10,907
edited 2019-06-30 11:16
Eric,
I've gone and done something dumb without thinking, I tried to CMP two constants (each with a #)! ... and Fastspin didn't complain. It wasn't until I tested with Pnut that I realised my mistake.

Basically, I am sort of doing a selective build but without the code saving. Conditional compiles would be better but I don't think that's an option in Pasm only code. Or is it?

• Posts: 4,885
evanh wrote: »
Eric,
I've gone and done something dumb without thinking, I tried to CMP two constants (each with a #)! ... and Fastspin didn't complain. It wasn't until I tested with Pnut that I realised my mistake.

Whoops, that's definitely a bug! I must have broken something back when I added code to support immediates in the dest field (which some P2 instructions support). Thanks for the bug report, I'll look into it.
Basically, I am sort of doing a selective build but without the code saving. Conditional compiles would be better but I don't think that's an option in Pasm only code. Or is it?

fastspin is fine with conditional compiles in PASM code. It only supports #ifdef and #ifndef though, not full featured #if.

Regards,
Eric
• Posts: 10,907
ersmith wrote: »
fastspin is fine with conditional compiles in PASM code. It only supports #ifdef and #ifndef though, not full featured #if.
Thanks.