Three different LED blinking programs in FlexBASIC
ersmith
Posts: 6,053
FlexBASIC (the dialect of BASIC supported by fastspin) is a pretty broad and forgiving language, and supports lots of different styles of programming. To illustrate that I thought I'd post 3 very different takes on the traditional LED blinking program.
First, a version in "oldschool" BASIC with line numbers and such:
A more "modern" take in BASIC would use structured programming and look like:
Finally a functional programming take on it:
Note that the recursive definition of "forever" works fine; fastspin does tail call elimination so it gets turned into a loop internally. The "[: ... :]" notation is a simple way to define anonymous functions and subroutines.
First, a version in "oldschool" BASIC with line numbers and such:
10 let LED=16 20 direction(LED) = output 30 output(LED) = output(LED) xor 1 40 pausems 500 50 goto 30This will look pretty familiar to anyone who programmed in BASIC on 8 bit microcomputers. It's not really the way I'd choose to do it today, but flexBASIC supports this kind of old style BASIC programming so it is possible.
A more "modern" take in BASIC would use structured programming and look like:
' declare which pin we will use const LED=16 ' set it as an output direction(LED) = output ' declare a subroutine to toggle a pin sub toggle(pin) output(pin) = output(pin) xor 1 end sub ' loop forever do toggle(LED) pausems(500) loopI've commented that better and broken the toggle operation out into a subroutine, but it's essentially the same program as the old style one (the compiler will generate pretty much the same code, too).
Finally a functional programming take on it:
const LED = 16 sub forever( f as sub() ) f() forever(f) end sub direction(LED) = output forever( [: output(LED) = output(LED) xor 1 : pausems 500 :] )
Note that the recursive definition of "forever" works fine; fastspin does tail call elimination so it gets turned into a loop internally. The "[: ... :]" notation is a simple way to define anonymous functions and subroutines.
Comments
Hehe, yes, that would be heavily deprecated today, but impressive to see it can swallow it, without barfing
Easy to read, but raises questions about what output() actually reads back, eg if the pin is open collector ? is it the pin itself, or the pin-latch ?
I presume this also works, and this reads the pin ?
If you take the pauses out, how fast can each of these toggle a pin ? Is there a generated source/pasm listing you can include in #1 ?
"output(x)" is bit "x" of OUTA (and/or OUTB if x >= 32 and on P2). "input(x)" is, similarly, a bit of INA (or INB).
You can always enable listing with fastspin's -l option. The second example (with the "const" declaration) compiles to;
The first, old-style program is a bit slower since it stores the pin number in a variable:
The last example is considerably slower since it's got a function indirection in it.
I don't like output as both keyword and function..
"output" is always a keyword. It does have different meanings depending on context though. "output" on the right hand side of an assignment to the direction() pseudo-array is basically equivalent to "1", whereas "input" in that context is equivalent to "0". So you can use those values (or constants like that) instead if you prefer.
"output(n)" and "input(n)" act like special bit arrays, basically OUTA and INA, but they can go up to 64 (so they can work on P2s and on P1v where the OUTB and INB registers are hooked up).
All this Spin2 stuff like output and multiple return values does work on the P1 too?
We should refer to you as "The Great ersmith", I stole that from @Heater. he was titling @Cluso99 to be called "The Great clusso99" for his decoding trick with ZiCog.
Question to @ersmith.
I can not figure out how to fill the left space between org 0 and org $200 with 0 in the created binary so that pos $200 in the binary is the code of $200.
If you look at a main-file listing it seems ok.
But when some main containing another object, then it is somehow 52 bytes displaced.
So without using a orgh, what I like to avoid since it is supposed to be a driver object
How in PASM would I write
ORG 0
some code
ORG $200
some LUT code or tables
and have in the created binary ORG $200 - hm - $200 away from ORG 0 and the space in between filled with 0.
Currently it compiles for $200 but sticks right after the COG code in the binary, not at $200
Can I use ORG $200 - $ or ORGF $200 - $ or something like that?
Mike
Help, please
You can use ORGF $200. ORGF is like ORGH in that it fills memory with 0 until it reaches the address specified, but it's for COG addresses instead of HUB addresses.
However, are you sure you really need to do this? If you just want to load some code into LUT, you should probably use its hub address instead, something like: That way you don't need any extra 0 padding in your code.
It just occurs if I include the code as sub object and somehow the memory is shifted by 52 longs.
Since t is a sub-object, to be included by fastspin I think I can not use ORGH since fastspin will place it somewhere.
so I will try orgf .
thanks
Mike
Are you able to share the code that's causing trouble? You're right that ORGH with a number isn't allowed inside an object, but just "ORGH" to say "this code is to go in HUB somewhere" is legal. And hub addresses with @ should work inside sub-objects now (they didn't in older versions of fastspin, but that's been fixed for a few months now I think).
can post in a couple of hours
Mike