Is there some other way to in Fastspin to turn a number into a string?
Unfortunately, my serial terminal output code isn't compatible (yet) with FastSpin. Still, there are numeric outputs built into the SmartSerial libary that comes with FlexGUI. For fun, I added an itoa() method to do number to string conversion without using width (varies with value).
'' simple hello world program
#ifndef _BAUD
#define _BAUD (__P2__) ? 230_400 : 115_200
#endif
con
#ifdef __P2__
_clkfreq = 160_000_000
rx_pin = 63
tx_pin = 62
#else
_clkmode = xtal1 + pll16x
_clkfreq = 80_000_000
rx_pin = 31
tx_pin = 30
#endif
baud = _BAUD
obj
#ifdef __P2__
ser: "spin/SmartSerial"
#else
ser: "spin/FullDuplexSerial"
#endif
var
byte buf[33]
pub hello | x
ser.start(rx_pin, tx_pin, 0, baud)
ser.printf("Hello, world!\n\n")
waitms(1000)
repeat x from 0 to 15
ser.printf("%d is %s in binary\n", x, itoa(x, 2))
waitms(100)
repeat
waitms(1)
pub itoa(value, base) : p_str | sign, d
'' Convert value to string
'' -- base is desired format
'' -- returns pointer to string
if (value == 0)
buf[0] := "0"
but[1] := \0
return @buf
bytefill(@buf, 0, 33)
p_str := @buf + 31
if (value < 0) and (base == 10)
sign := 1
value := -value
else
sign := 0
repeat
d := value // base
byte[--p_str] := (d < 10) ? "0" + d : "A" + (d - 10)
value /= base
while (value)
if (sign)
byte[--p_str] := "-"
@JonnyMac ... if you use C's "stdio", you don't need "FDS". I think it will initialise IO depending on the P1/P2 compile time options used.
(I could only test it on P1/SpinSim.)
$ cat r.spin
obj
stdio : "stdio.h"
pub main | r
repeat r from -1 to 1
stdio.printf(string("%d "),r)
stdio.puts(string(""))
Is there some other way to in Fastspin to turn a number into a string?
I have compiled the good old FloatString.spin for the P1 with fastspin. Except for a minor issue with the switch statement (which should be solved, now) it worked right away.
@ersmith: While coding in FlexBASIC version 4.1.3 on a Win10 machine with a P2-EVAL as the target:
INSTR() seems to be confused. (I caught this while playing with GPS messages). INSTR() is returning the *last* character position of a target, instead of the first character position. This code shows the bug:
dim test$ as string
test$ = "$GPGSV,4,3,13,27,19,040,2,28,26,266,27,30,35,318,21,6,40,23"
print instr(1, test$, ",")
This should return "7", but returns "57" instead. I'm wondering if the compiler got INSTR() and INSTRREV() confuzzified?
I think I'm seeing something strange with return values...
I've started specifying them now, in order to be compatible with Spin2...
PRI TvToRGB(x):c|j,y,r,g,b'Take a TV color index, x, and convert to RGB value, c, using table
repeat j from 0 to 256
y:=long[@TV_Palette][10]
'c:=y
return y
This part of the code seems to work as expected if I set c:=y and then return.
But, "return y" without that does not work, returns zero.
It seems it returns c, even though I'm telling it to return y.
Or, maybe Spin2 and fastspin are supposed to be different than Spin1 this way?
Wait, I think I was seeing this wrong... I don't know what happened, but all better now...
My end goal is to update my P1 peripheral library / emulator / debugger to P2 with compiled PASM but maybe I could use some C for some things with extra speed of P2 especially if this could allow library compatibility.
I can't really speak for how the prop1 booted, but the prop2 definitely starts up wanting to run native machine code. It's up to the build tools to add a any cocooning environment to that. That said, Taqoz is sitting on the sidelines ready to jump in if desired.
- Is FlexGui producing a binary independent of PNut or is it invoking PNut ( I think it's independent? ) - I can't port x86 even if the source was available
_ FlexGui UI is written in a custom TCL? but the backend engine is c?
- I really would like to bind the backend engine into a Visual Studio c# project, I did this once with OpenSim, it requires an interop API layer. Anyone done this?
You can answer these yourself and get a lot more detail from the flexgui source tree on GutHub. Eric has also placed quite a lot of documentation for flexgui and the tools that it depends on within the source tree.
https://github.com/totalspectrum/flexgui Sources for fastspin & the loader(s) are sub-modules within flexgui. That's where you'll find much of what you are looking for, if you plan to invoke the compiler and loader from Visual Studio.
So, I've converted the old P1 graphics into something that works under Fastspin (and Spin2, I think).
Now, I'm pushing most of the cog code to hubexec, so I can combine this cog code with something else and save a cog.
Surprisingly (because the code is very complicated), it all seems to work with just a couple tweaks except for this part of the wide pixel drawing routine:
Try to get rid of the dots in front of the labels and see if that fixes it. IIRC I've had issues before with that sort of thing in Fastspin though I had a feeling Eric had fixed those.
@ersmith: While coding in FlexBASIC version 4.1.3 on a Win10 machine with a P2-EVAL as the target:
INSTR() seems to be confused. (I caught this while playing with GPS messages). INSTR() is returning the *last* character position of a target, instead of the first character position. This code shows the bug:
dim test$ as string
test$ = "$GPGSV,4,3,13,27,19,040,2,28,26,266,27,30,35,318,21,6,40,23"
print instr(1, test$, ",")
This should return "7", but returns "57" instead. I'm wondering if the compiler got INSTR() and INSTRREV() confuzzified?
Sorry, not quite sure what's going on there... it may be a while before I get a chance to look into this.
Technically a relative branch across boundaries works but the assemblers don't know how. Try this:
tjz arg6,#\loop
EDIT: No that doesn't work. There is only two addressing modes for the test and branch instructions: relative-immediate and absolute-register. So, using another register would work.
If the assemblers supported it then this would universally work:
You can of course craft the machine code yourself. Here's a couple of snippets from experiment I did, using relative JMP, from last year. Not comprehensive but both worked.
Cog code branching to hub code:
' jmp #loctesthub 'HubRAM address is $450
' long $fd900fa0 '($400 - $17 - 1) * 4 = $fa0
long $fd900000 + (($450-$-1)*4)&$fffff
Lut code branching to cog code:
' jmp #_main 'CogRAM address is $9
long $fd900000 + ((9-$-1)*4)&$fffff
You can of course craft the machine code yourself. Here's a couple of snippets from experiment I did, using relative JMP, from last year. Not comprehensive but both worked.
Seems to me if the Silicon does support this, then the P2 Assembler should provide some means to express it ?
Okay, I never was doing a relative branch from hubexec previously. I have worked out how to make the relative JMP from hubexec to cogexec work ... but I can't make an AUGS+TJZ do the same. It seems hubexec doesn't switch off when attempting it this way.
eg: This works but if I comment out the JMP relative it''ll crash on the subsequent TJZ.
Comments
(I could only test it on P1/SpinSim.) But let's wait for the master's comments. ;-)
I have compiled the good old FloatString.spin for the P1 with fastspin. Except for a minor issue with the switch statement (which should be solved, now) it worked right away. (dump of servo motor parameters to the terminal)
INSTR() seems to be confused. (I caught this while playing with GPS messages). INSTR() is returning the *last* character position of a target, instead of the first character position. This code shows the bug: This should return "7", but returns "57" instead. I'm wondering if the compiler got INSTR() and INSTRREV() confuzzified?
I've started specifying them now, in order to be compatible with Spin2...
This part of the code seems to work as expected if I set c:=y and then return.
But, "return y" without that does not work, returns zero.
It seems it returns c, even though I'm telling it to return y.
Or, maybe Spin2 and fastspin are supposed to be different than Spin1 this way?
Wait, I think I was seeing this wrong... I don't know what happened, but all better now...
https://github.com/totalspectrum/flexgui Sources for fastspin & the loader(s) are sub-modules within flexgui. That's where you'll find much of what you are looking for, if you plan to invoke the compiler and loader from Visual Studio.
dgately
Now, I'm pushing most of the cog code to hubexec, so I can combine this cog code with something else and save a cog.
Surprisingly (because the code is very complicated), it all seems to work with just a couple tweaks except for this part of the wide pixel drawing routine:
This part needs to stay in the cog, unless I can figure out why it doesn't work in hubexec…
When moved to hubexec, fastspin complains about three lines like this: so, I changed .shift1 to ##.shift1, but that didn't make it work...
Sorry, not quite sure what's going on there... it may be a while before I get a chance to look into this.
Yes, it writes to a register's bits [8..0]. It won't work in hub exec if you are planning to execute the instruction inline.
In fact, it is affecting some register in the cog.
Only need these in cog now:
And then put this where they used to be:
Says that tjz can't cross hub/cog boundary.
Still trying to understand this... Seems like djnz and tjz can't jump back into cog space, right?
But, plain JMP can?
If the assemblers supported it then this would universally work:
Cog code branching to hub code:
Lut code branching to cog code:
Maybe I did it wrong...
EDIT: Here's a starter:
EDIT: And the AUGS doesn't need any mask either.
EDIT2: Tested going back the other way also works identical:
EDIT3: Fix spelling.
Oops, I've done something wrong. The last few tests have suddenly started failing, maybe I wasn't saving the changes ...
Seems to me if the Silicon does support this, then the P2 Assembler should provide some means to express it ?
What I have proven again is cogexec to hubexec works, with a correction for AUGS cases - The x4 scaling isn't needed.
EDIT: Ha, and the assembler AUGS itself tidies that up:
EDIT2: So, that's correctly branching into hubexec using longword scaling for hubRAM addressing! Here's the example.
EDIT3: Removed some dross from example.
EDIT4: Fix spelling.
eg: This works but if I comment out the JMP relative it''ll crash on the subsequent TJZ.
Full example attached
EDIT: Fix spelling.
I thought it would just skip the loop, but it instead appears to freeze or maybe run the loop forever...
I had this:
and this:
This turns out to not be a good thing and hard to figure out what is wrong.
Except I knew what it was because I had just added that in...
It should cause the REPEAT block to compile to nothing. I will look.