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

1192022242530

Comments

  • David BetzDavid Betz Posts: 13,480
    edited 2019-09-12 - 09:12:54
    Roy Eltham wrote: »
    No it's the way it works.
    You are supposed to put your RES stuff last normally, but you could also use RES lines to "define" a header, then specify a file after them, and use the res labels to access the beginning of the file data.
    Regular DAT data takes up space in HUB as well as in COG, but RES doesn't consume HUB space, so it's handy for setting up buffers and temp vars and whatnot for use only in COG memory, but you need to make sure it's initialized properly yourself.
    Also Spin code can access the regular DAT data in HUB space, which is handy for setting things before starting the COG.

    This is how it has worked on P1 forever.
    Well, just because it's been that way forever doesn't mean it isn't a bug! (in the language design) :smile:

  • David Betz:

    Remember how code in the P1 is loaded from HUB into COG?
    If you RES some variables after a cog program, ultimately they take up no memory in HUB because they overlay whatever is next in HUB memory (maybe the beginning of another cog program). Unfortunately when the COG starts up, it loads in whatever those RES areas or in general all 512 longs.
  • Actually 512-16=496 longs.

    And RES is a well used feature, definitely not a design bug. You just need to know how to use it, like anything else. In general, you can avoid it, but when you need it - you need it!!
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Yeah I've seen RES sit over the top of one-time initialization code. Makes for difficulty debugging, but makes up for it by allowing something to fit in a COG that ordinarily could not.
  • whicker wrote: »
    Yeah I've seen RES sit over the top of one-time initialization code. Makes for difficulty debugging, but makes up for it by allowing something to fit in a COG that ordinarily could not.
    It may be useful but its a non-standard use of a term that has been used forever in assemblers. Maybe the design bug is that it should have been called something else.
  • It’s not about fitting into cog, but rather not taking up space in hub.
    A contrived example is where the total compiled code is over 32KB which is the max hub ram. By using res, it may be possible to reduce the hub load size.
    We can of course reuse hub area after it is loaded into cogs. Again, its for serious users.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • RaymanRayman Posts: 9,716
    edited 2019-09-12 - 10:19:50
    Ok, I see the problem now, thanks. This was Chip's code. But, after RES, he used
    orgh    $1000 - $436
    
    To move the bitmap to a later location, so the RES didn't have to be initialized.
    Still, I'd say Chip showed us a bad programming style there, right?

    My problem is that you can't do the orgh $ trick in Spin2, like you can in pure ASM.
    Maybe I wish you could? Not sure...

    Can the compiler warn of RES variables being used without initialization?
    Prop Info and Apps: http://www.rayslogic.com/
  • Rayman wrote: »
    Ok, I see the problem now, thanks. This was Chip's code. But, after RES, he used
    orgh    $1000 - $436
    
    To move the bitmap to a later location, so the RES didn't have to be initialized.
    Still, I'd say Chip showed us a bad programming style there, right?
    Maybe he just forgot the "mov x, #0" at the beginning to initialize x; if that had been in there then the use of "res" would have been perfectly OK. The code is kind of old though. I'm sure that nowadays Chip would use setq2 + rdlong to initialize LUT instead of making a loop.
    My problem is that you can't do the orgh $ trick in Spin2, like you can in pure ASM.
    Maybe I wish you could? Not sure...
    It's not really feasible to do orgh $ in a Spin object. For example, what if two different objects both wanted to do "orgh $1000"? There's also not really any need to, just put a label after the orgh and use that.
    Can the compiler warn of RES variables being used without initialization?

    Not without quite a lot of work, I'm afraid. (And not completely accurately in any case, getting 100% accuracy would be equivalent to solving the halting problem, which is impossible.)
  • whicker wrote: »
    okay, so I tried the HEAPSIZE suggestion:
    const HEAPSIZE = 8192
    dim R$ as string
    dim A as integer
    
    print "Hi"
    
    HERE:
    INPUT "Enter a string"; R$
    PRINT "You typed:"; R$
    GOTO HERE
    


    That's 240 A's. It only takes 2 of these to cause the weirdness (printing only the 1st character).
    At the bottom, it's only printing "Y" instead of "You typed:", and only "A" instead of the 240 A's, and then "E" instead of "Enter a string".

    @whicker: Sorry, I somehow missed that you were testing this on P2 (although you did clearly show that in your first post). Sure enough, there's a bug in the P2 transmit functions that was causing this issue. It's fixed in github now.

    Thanks for the bug report!

  • Dave HeinDave Hein Posts: 5,948
    edited 2019-09-12 - 13:28:52
    I encountered the RES issue in the VGA code quite a while ago. I posted a thread about it, but it only got one comment and 112 views. The thread is at http://forums.parallax.com/discussion/169637/minor-issue-with-vga-640-x-480-8bpp-spin2-and-vga-640-x-480-16bpp-spin2 .

    The "x res 1" should probably be replaced by "x long 0" in future updates so this problem doesn't come up again.

    BTW, the function of RES is quite simple. "RES n" is essentially the same as "ORG $+n".
  • RaymanRayman Posts: 9,716
    edited 2019-09-12 - 13:38:39
    Maybe I missed it... Did we get a new version of the example programs with the ES board?
    We used to get example programs with all the FPGA releases...
    I just looked at V32i, which I think is the latest, and it still has this bad code in it.
    Also, Chip includes an "initialized data" comment, but not his usual "uninitialized data" comment before the RES lines.
    If that comment were there, maybe this would have been more obvious...

    I think it's about time we had some examples like these in Spin2 instead of just ASM that actually work.
    Chip is probably waiting for his Spin2 to be ready to do this...

    But, I've been wanting to combine garryj's USB code with some VGA code for quite some time.
    Problem is having to deal with namespace overlaps...
    Want to use Spin2 mostly to avoid this...
    Prop Info and Apps: http://www.rayslogic.com/
  • David Betz wrote: »
    Roy Eltham wrote: »
    No it's the way it works.
    You are supposed to put your RES stuff last normally, but you could also use RES lines to "define" a header, then specify a file after them, and use the res labels to access the beginning of the file data.
    Regular DAT data takes up space in HUB as well as in COG, but RES doesn't consume HUB space, so it's handy for setting up buffers and temp vars and whatnot for use only in COG memory, but you need to make sure it's initialized properly yourself.
    Also Spin code can access the regular DAT data in HUB space, which is handy for setting things before starting the COG.

    This is how it has worked on P1 forever.
    Well, just because it's been that way forever doesn't mean it isn't a bug! (in the language design) :smile:

    One persons bug is another persons feature. RES can be a life saver when you are trying to squeeze a lot of code into the hub and cogs.
    In science there is no authority. There is only experiment.
    Life is unpredictable. Eat dessert first.
  • Rayman wrote: »
    But, I've been wanting to combine garryj's USB code with some VGA code for quite some time.
    Problem is having to deal with namespace overlaps...
    Want to use Spin2 mostly to avoid this...

    Here's a version of the garryj's OneCogKbM code that has been converted to Spin2. It's the one I used in micropython, and it worked even after being converted to C by spin2cpp. The test program is pretty simple and is probably sensitive to which USB port the keyboard is plugged into (for me it works if plugged into the bottom USB port on the serial host board).
  • Thanks. Looks like SmartSerial does not use up a cog, is this right?
    I might have to switch to that...
    Prop Info and Apps: http://www.rayslogic.com/
  • Rayman wrote: »
    Thanks. Looks like SmartSerial does not use up a cog, is this right?
    I might have to switch to that...

    Correct, it uses a smartpin for the serial I/O.
  • I've published new versions (3.9.31) of fastspin and spin2gui. Note that spin2gui includes fastspin and everything else you need to program a P1 or a P2, so it's probably the easier starting point for development. The URLs are:

    spin2gui: https://www.patreon.com/totalspectrum or https://github.com/totalspectrum/spin2gui/releases/
    fastspin: https://github.com/totalspectrum/spin2cpp/releases/

    New features in spin2gui (the IDE) include:
    - Show previously selected font in the font chooser.
    - Use panes for the top level window, to allow resizing the command output
    - Print compilation time and machine
    - Show links to files that have errors in them, and open those files when the links are clicked on

    New features in fastspin (the compiler) include:

    Version 3.9.31
    - Fixed an off-by-one error in SELECT CASE
    - Allow slightly longer functions to be inlined (improves pintoggle)
    - Fixed getcnt() in BASIC
    - Recognize ! as well as # as a suffix to indicate a floating point variable
    - Fixed some BASIC parsing problems with empty IF/ELSE conditions and empty subroutines.
    - Fixed a problem with printing long strings
    - Changed format of error messages to "filename:line: error: stuff" to match the preprocessor's error format and make parsing easier

    Version 3.9.30
    - Fixed some floating point parsing issues
    - Added some missing C stdio functions
    - In listing files update the COG address for RES statements
    - Reduced use of COG memory in P2
    - Fixed some bad formatting in __builtin_printf
    - Fixed a bug in BASIC parsing of empty lines
    - Fixed return values of some BASIC builtin functions
    - Fixed a garbage collector hang
    - Added "out of memory" error messages
    - Fixed BASIC global multi-dimensional array declarations
  • Dude... you are six shades of awesome. I know what I’m doing tonight!
  • +1

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • yetiyeti Posts: 587
    edited 2019-09-13 - 01:47:37
    I'm not happy with the FQDN after compiles. If I would need to make screenshots, I would need to black out the FQDN.

    My favourite environment is the shell and my IDE is EMACS, but for helping digital neighbours I may come in touch with spin2gui and needing some snapshots. Sure I can patch spin2gui's sources to put whatever I want into there so it's not really unsolvable for me. And as long as GIT can rebase my local changes, it really is only a matter of seconds to apply this to newer versions and probably only minutes else.

    Am I the only one seeing this feature as potentially being an information leak?
    ◁ propeller-wiki ▷ ◁ FastSpin ▷ ◁ Help Spin at RosettaCode.org ▷ ◁ No Source – No Go! ▷ ◁ DK-E ▷ ◁ :-D ▷ ◁ Stay OmmmmmmPtimistic! ▷ ◁ Why Asimov's Laws of Robotics Don't Work ▷ ◁ DNA is a four letter word. ▷ ◁ Stop slavery! Free all mitochondria! ▷
  • JRoarkJRoark Posts: 98
    edited 2019-09-13 - 02:27:59
    Pizza? Check. Beer? Check. Cat? In lap. So here we go!

    Compiler: Version 3.9.31 Compiled on: Sep 12 2019
    Editor: 3.9.31-beta
    Machine: Dell 7000 running Win10
    Processor: FLIP
    Language: BASIC

    Manual
    MID$() is missing from the Keyword List (pgs 4/5/6)
    None of the math operators are documented. Maybe steal this from FreeBasic?

    Request: FRE()
    This is where Eric starts throwing things at me. :blush: It would be really useful during debugging to have a function that returns the amount of the various types of memory available at runtime. Traditionally this is called FRE().
    - FRE(0) returns the free (unused) memory remaining
    - FRE(1) returns the total amount of memory
    - FRE(2) returns the free (unused) heap remaining
    - FRE(3) returns the total heap size
    If not instantly, then maybe put this on the To Do list?

    Request: ATN() or ATAN2()
    There don't appear to be any of the trig functions implemented yet. I understand this might be a big project, but if we could get either ATN() or (preferably) ATAN2(), then things like ACOS() and ASIN() could be quickly derived. That puts a whole lot of mischief into play. Or, if there is something lurking just under the hood like a _ATAN or _ATN, then I can roll my own from there. Another one for the To Do list...

    Boy... I feel sorta lost. Nothing is breaking when I bang on it...
  • JRoark wrote: »
    Pizza? Check. Beer? Check. Cat? In lap. So here we go!
    ...Boy... I feel sorta lost. Nothing is breaking when I bang on it...

    Yes, I checked my case problem too, and it is resolved.

    I still have this weird thing that HUB addresses in PASM seem to be some 52 bytes off when in a included object instead of the main Spin2. I found a way around it to move along, but something is wrong with

    ##\hubaddress

    when in a object and not the main spin2 file.

    FastSpin rocks!

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • yeti wrote: »
    I'm not happy with the FQDN after compiles. If I would need to make screenshots, I would need to black out the FQDN.

    My favourite environment is the shell and my IDE is EMACS, but for helping digital neighbours I may come in touch with spin2gui and needing some snapshots. Sure I can patch spin2gui's sources to put whatever I want into there so it's not really unsolvable for me. And as long as GIT can rebase my local changes, it really is only a matter of seconds to apply this to newer versions and probably only minutes else.

    Am I the only one seeing this feature as potentially being an information leak?

    I hadn't thought of the situation where fastspin is being run on a machine that directly connects to the internet -- all of my machines are NAT'd. It sounds like the message to be printed at the end of compilation should be configurable in spin2gui.

    For now just delete (or comment out by putting # at the beginning) the line:
      .p.bot.txt insert end "on [info hostname]"
    
    in spin2gui/src/gui.tcl.
  • JRoark wrote: »
    Manual
    MID$() is missing from the Keyword List (pgs 4/5/6)
    That's because MID$ (like LEFT$ and RIGHT$) is not a keyword. You are allowed to create your own MID$ function or variable, e.g. something like:
    sub foo
      dim mid$
      mid$ = "hello"
      print mid$
    end sub
    
    is legal.

    Probably a list of predefined functions and variables would be a good thing to add to the docs.
    None of the math operators are documented. Maybe steal this from FreeBasic?
    Yes, that still needs to be done. I hope to get around to it soon, although if someone else beats me to it I'd be happy to accept contributions (hint, hint :) ).
    Request: ATN() or ATAN2()
    There don't appear to be any of the trig functions implemented yet. I understand this might be a big project, but if we could get either ATN() or (preferably) ATAN2(), then things like ACOS() and ASIN() could be quickly derived. That puts a whole lot of mischief into play. Or, if there is something lurking just under the hood like a _ATAN or _ATN, then I can roll my own from there. Another one for the To Do list...
    The floating point routines are kind of a work in progress -- I've got SIN and COS done, but the other trig functions and EXP and LOG still need implementations. I actually started with new Prop2 implementations of the basic floating point add, subtract, multiply, divide, which I mostly have working but haven't integrated yet. Soon, I hope :).

    The FRE() function (or something like it) also sounds like a good idea, thanks for the suggestion.

    Eric
  • msrobots wrote: »
    I still have this weird thing that HUB addresses in PASM seem to be some 52 bytes off when in a included object instead of the main Spin2. I found a way around it to move along, but something is wrong with

    ##\hubaddress

    when in a object and not the main spin2 file.

    Try
    ##@hubaddress
    

    instead -- I think that works. There's still a problem with recognizing whether or not something is a hub address when used in an object, but if you prefix it with "@ to force the hub address then most of the cases do work out. I'm still working on fixing the problems when @" is left off.

    Thanks,
    Eric
  • Cluso99Cluso99 Posts: 15,405
    edited 2019-09-13 - 13:51:11
    Eric,
    I've just downloaded the latest and shiniest spin2gui 3.9.31 :smiley:

    I tried to compile a spin1/pasm1 program within spin2gui but no luck.
    Is this possible or must I use the command line?
    The errors seem to indicate that my xx.spin file is compiling for P2.

    Postedit:
    Using the command line I've compiled it and looked at the .pasm output file.
    I have an error: fit 496 failed: pc is 574

    So the cog is full. Any tips for where do I start?
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Cluso99 wrote: »
    I've just downloaded the latest and shiniest spin2gui 3.9.31 :smiley:

    I tried to compile a spin1/pasm1 program within spin2gui but no luck.
    Is this possible or must I use the command line?

    The errors seem to indicate that my xx.spin file is compiling for P2.
    The default is to compile for P2, but you can select P1 by going to the Commands menu, selecting "Configure Commands...", and then pressing "P1 defaults".
    Postedit:
    Using the command line I've compiled it and looked at the .pasm output file.
    I have an error: fit 496 failed: pc is 574

    So the cog is full. Any tips for where do I start?

    Are you able to share your code? For P1 you can save a lot of COG space by disabling FCACHE. To do that, passing "--fcache=0" on the command line. That's easy if you're using the command line yourself; to do it with spin2gui you'll have to use "Configure Commands..." and add --fache=0 to the compile command.
  • Cluso99Cluso99 Posts: 15,405
    edited 2019-09-13 - 15:21:30
    Thanks Eric :)

    I turned off fcache and it compiles with a listing too :)
    BUT it's 39KB so overflows hub :(
    I will have to take a good look at what the output looks like to see what I can shrink down. It will be fine for P2 tho :)

    Like your reporting of jumps/calls without # warning. I'll add the +0 to suppress the errors.

    I have overlays in the pasm code section to load short code blocks into cog to run.
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • I don't know why, but writing Spin2 code for P2 feels very strange...
    Been doing pure ASM for so long...
    Prop Info and Apps: http://www.rayslogic.com/
  • one nice addition to BASIC and SPIN would be the use of WITH or maybe USING for multiple calls to one object. Say instead of

    ser.str("ABC")
    ser.str("CDE")

    to write

    WITH ser
    .str("ABC")
    .str("CDE")

    Tjhat is something I was missing in C# (and still do) after moving away from VB.

    Mike
    I am just another Code Monkey.
    A determined coder can write COBOL programs in any language. -- Author unknown.
    Press any key to continue, any other key to quit

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this post are to be interpreted as described in RFC 2119.
  • msrobots wrote: »
    one nice addition to BASIC and SPIN would be the use of WITH or maybe USING for multiple calls to one object. Say instead of

    ser.str("ABC")
    ser.str("CDE")

    to write

    WITH ser
    .str("ABC")
    .str("CDE")

    Tjhat is something I was missing in C# (and still do) after moving away from VB.

    Mike

    Since I’m already scheduled for a good, old fashioned tush-kicking from Eric for my earlier feature requests, I’ll double down and say “I’m with Mike” on this one. That would be handy.
Sign In or Register to comment.