Shop OBEX P1 Docs P2 Docs Learn Events
PNut Sources Available — Parallax Forums

PNut Sources Available

cgraceycgracey Posts: 14,206
edited 2021-12-08 20:32 in Propeller 2

I finally got this together today. I will be updating it as things progress, like with single-step debugging.

This should be everything you need to compile your own PNut.exe from original source files:

https://github.com/parallaxinc/P2_PNut_Public

See the ReadMe.txt file for instructions on how to assemble/compile the whole PNut app.

Everything needed is included, except Delphi 6. Not sure where you can find this, but it's got to be out there, somewhere.

«1

Comments

  • Wow!, thanks Chip

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-08 21:16

    THE SAUCE HAS BEEN SERVED!

    Well, I feel accomplished today :P

    Anyways, here's the C-based CLI compiler I tried to make with the earlier incomplete source I received privately: https://gitlab.com/Wuerfel_21/spinner2 Doesn't actually work properly (IIRC small test programs do build, as do pure P2ASM files, I believe? It's been a while! I also think:tm: it worked perfectly on Linux???), but now I can try to figure out what the delphi code does to make it work, I guess.

    It is also of interest because it has a rakefile that builds everything easily (using DOSBOX-X to run TASM and using flexspin to build the includes). Speaking of, your instructions don't mention that you have to run p2com.bat under a DOS emulation. (Or did you procure a Win32 version of TASM???)

  • Also, to follow up on my Rubyist propaganda from that other thread :3, here is the rake rule I used to convert binaries to TASM incfiles:

    rule ".inc" => ".binary" do |t|
        puts "Converting #{t.source} to #{t.name}"
        File.write(t.name,File.binread(t.source).bytes.each_slice(16).map{|sl|"db #{sl.join ?,}\n"}.join)
    end
    

    vs. Chip's BASIC code

    F=FREEFILE
    OPEN "Spin2_interpreter.inc" FOR OUTPUT AS #F
    
    F2=FREEFILE
    OPEN "Spin2_interpreter.obj" FOR INPUT AS #F2
    
    bc = 0
    for a = 0 to LOF(F2)-1
      if bc = 0 then print #F,"db "; 
      hexout bgetc(F2)
      bc = bc + 1
      if (bc <> 16) and (a <> LOF(F2)-1) then print #F,",";
      if bc = 16 then print #F,chr(13) + chr(10);
      if bc = 16 then bc = 0
    next a
    
    CLOSE #F2
    
    print #F,chr(13) + chr(10);
    CLOSE #F
    END
    
    
    SUB hexout(b)
      print #f, "0";
      if b < 16 then print #f, "0";
      print #F, hex(b);
      print #f, "h";
    END
    

    hmmmm.....

  • cgraceycgracey Posts: 14,206
    edited 2021-12-08 22:11

    Wuerfel_21, yes, you must run a DOS box to execute the .bat file. It just does this:

    tasm32 p2com /m /l /z /c

    I am anxious to hear if you get all this to work.

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-08 22:30

    @cgracey said:
    tasm32 p2com /m /l /z /c

    do these flags do anything? I was just calling it without any flags.

    Also, looking at how your code calls into the compiler:
    - Okay, my approach of compiling a first pass, then compiling all the dependencies, then starting over from scratch is just how it goes. I thought that was very wrong and terrible, but apparently that's working-as-intended:tm:
    - I'm not touching obj_stack_ptr at all, though there's only one use of it so IDK if that's why it breaks.
    - Yeah that's some sphaghetti alright. Why is the compiler-calling code in the same file as the text editor stuff? WHY IS THERE INLINE ASM?

    Don't have a P2 hooked up now, so might take a day or two till I'll get to checking this stuff.

  • cgraceycgracey Posts: 14,206

    @Wuerfel_21 said:

    @cgracey said:
    tasm32 p2com /m /l /z /c

    do these flags do anything? I was just calling it without any flags.

    Also, looking at how your code calls into the compiler:
    - Okay, my approach of compiling a first pass, then compiling all the dependencies, then starting over from scratch is just how it goes. I thought that was very wrong and terrible, but apparently that's working-as-intended:tm:
    - I'm not touching obj_stack_ptr at all, though there's only one use of it so IDK if that's why it breaks.
    - Yeah that's some sphaghetti alright. Why is the compiler-calling code in the same file as the text editor stuff? WHY IS THERE INLINE ASM?

    Don't have a P2 hooked up now, so might take a day or two till I'll get to checking this stuff.

    Why? Because! You know.

    There were two files missing that I just added: ComUnit.pas and ComUnit.dfm.

  • cgraceycgracey Posts: 14,206

    ObjStackPtr (Delphi) or obj_stack_ptr (x86) tracks the recursion level, which is cleared to 0 before CompileRecursively gets called.

  • @cgracey said:
    ObjStackPtr (Delphi) or obj_stack_ptr (x86) tracks the recursion level, which is cleared to 0 before CompileRecursively gets called.

    Ye, I can figure that out, but what does it effect in the compiler? As far as I can tell it only comes into play with debugging enabled?

  • Just out of curiosity, I used this code to build Pnut on Windows 7:.

    I did the Pnut.exe obj step, the Smallbasic inc step, the p2com obj step, then ran the code in my Delphi 7. I didn't need a DOS window to run the bat file; I just did the Windows "open" on it.

    There were a few warnings and one error: on line 1031 in DebugDisplayUnit.pas, Delphi didn't like vLow[i] := -$80000000; it said "overflow in conversion or arithmetic operation". I just set vlow[i] to $80000000 to get it to compile, and that succeeded in compiling and running a Pnut.

    In the new Pnut, I ran a P2 blinky program to check that it can talk to my P2, and it succeeded. I didn't test any of the debug utilities, but the compile and download of a simple P2 program worked.

    Thanks, Chip.

    David

  • cgraceycgracey Posts: 14,206

    @Wuerfel_21 said:

    @cgracey said:
    ObjStackPtr (Delphi) or obj_stack_ptr (x86) tracks the recursion level, which is cleared to 0 before CompileRecursively gets called.

    Ye, I can figure that out, but what does it effect in the compiler? As far as I can tell it only comes into play with debugging enabled?

    The compiler needs to know when it's working on the top-level file vs others, for reasons I can't recall.

  • cgraceycgracey Posts: 14,206

    @"David B" said:
    Just out of curiosity, I used this code to build Pnut on Windows 7:.

    I did the Pnut.exe obj step, the Smallbasic inc step, the p2com obj step, then ran the code in my Delphi 7. I didn't need a DOS window to run the bat file; I just did the Windows "open" on it.

    There were a few warnings and one error: on line 1031 in DebugDisplayUnit.pas, Delphi didn't like vLow[i] := -$80000000; it said "overflow in conversion or arithmetic operation". I just set vlow[i] to $80000000 to get it to compile, and that succeeded in compiling and running a Pnut.

    In the new Pnut, I ran a P2 blinky program to check that it can talk to my P2, and it succeeded. I didn't test any of the debug utilities, but the compile and download of a simple P2 program worked.

    Thanks, Chip.

    David

    Great, David!

    I think vLow[] is an integer and $80000000 is tricky to assign. How did you solve this?

  • I wouldn't say that I solved it because I don't know what the intent of the assignment was; I just modified the number until it compiled.

    Yes, vlow[] is an integer array. Maybe the intent was to set the minimum value? I think Delphi has a "low()" function that might work for that.

  • cgraceycgracey Posts: 14,206

    @"David B" said:
    I wouldn't say that I solved it because I don't know what the intent of the assignment was; I just modified the number until it compiled.

    Yes, vlow[] is an integer array. Maybe the intent was to set the minimum value? I think Delphi has a "low()" function that might work for that.

    I need to review WHY I needed that initial value. Too bad Delphi is so temperamental.

  • pik33pik33 Posts: 2,388

    Forked. Opened in Lazarus. There are several Windows API stuff which is not available in Lazarus, at least without tweaking the code.

  • @"David B" said:
    Just out of curiosity, I used this code to build Pnut on Windows 7:.

    I did the Pnut.exe obj step, the Smallbasic inc step, the p2com obj step, then ran the code in my Delphi 7. I didn't need a DOS window to run the bat file; I just did the Windows "open" on it.

    Are you using 32 bit Windows? Because yeah, that has NTVDM and will just work

  • My Windows 7 computer is 64 bit, but as a test this morning I went through the same procedure on my old 32 bit Windows XP laptop with the exact same results: the initial obj builds worked as before, Delphi complained about -$80000000 as before, the blinky P2 program compiled and ran on my P2 just as before.

    I should say that while I didn't explicitly open a DOS window to run the bat file, opening it does open a DOS window as it does its work.

    Speaking of Windows XP, I've noticed that ever since P2 capability was added to Proptool, Proptool will not load onto Windows XP. I know that using older systems always runs the risk of compatability issues, but I'm sad about that; I really like Proptool's reliability. Most of the other propeller IDEs and compilers I've tried seem to fail with some kind of library error, but Proptool always just simply works. Until now, that is, on XP. My home desktop Windows 7 computer runs the latest proptool just fine but my garage computer and travelling laptop computer both run XP, so they're stuck with the P1-only version of Proptool. :(

  • Thanks for making the source code available!

    Following the readme.txt, i compilled using my Delphi 6 PE, and I got the following warnings, but the build results (Pnut.exe) worked as expected.

    • [Warning] DebugDisplayUnit.pas(742): Variable 'CursX' might not have been initialized
      [Warning] DebugDisplayUnit.pas(742): Variable 'CursY' might not have been initialized
      [Warning] DebugDisplayUnit.pas(735): Variable 'TextX' might not have been initialized
      [Warning] DebugDisplayUnit.pas(735): Variable 'TextY' might not have been initialized
      [Warning] DebugDisplayUnit.pas(1829): Variable 's' might not have been initialized
      [Warning] DebugDisplayUnit.pas(2250): Variable 'tweak' might not have been initialized
      [Warning] DebugDisplayUnit.pas(2880): Return value of function 'TDebugDisplayForm.GetBackground' might be undefined
      [Warning] DebugDisplayUnit.pas(3202): Variable 'tx' might not have been initialized
      [Warning] DebugDisplayUnit.pas(3202): Variable 'ty' might not have been initialized
      [Warning] DebugDisplayUnit.pas(3362): Variable 'xopa' might not have been initialized
      [Warning] DebugDisplayUnit.pas(3722): Variable 'fx' might not have been initialized
      [Warning] DebugDisplayUnit.pas(3723): Variable 'fy' might not have been initialized
      [Warning] DebugDisplayUnit.pas(3737): Return value of function 'TDebugDisplayForm.SmoothClip' might be undefined
      [Warning] DebugDisplayUnit.pas(3796): Constant expression violates subrange bounds
      [Warning] DebugDisplayUnit.pas(3804): Combining signed and unsigned types - widened both operands
      [Warning] DebugDisplayUnit.pas(3805): Combining signed and unsigned types - widened both operands
      [Warning] DebugDisplayUnit.pas(3806): Combining signed and unsigned types - widened both operands
      [Warning] DebugDisplayUnit.pas(3813): Combining signed and unsigned types - widened both operands
      [Warning] SerialUnit.pas(92): Variable 'm' might not have been initialized
      [Warning] SerialUnit.pas(90): Variable 'LoadLimit' might not have been initialized
      [Warning] SerialUnit.pas(203): Return value of function 'HardwareFound' might be undefined
      [Warning] SerialUnit.pas(362): Return value of function 'RByte' might be undefined
      [Warning] SerialUnit.pas(395): Combining signed and unsigned types - widened both operands
      [Warning] SerialUnit.pas(398): Combining signed and unsigned types - widened both operands
      [Warning] SerialUnit.pas(404): Combining signed and unsigned types - widened both operands
      [Warning] EditorUnit.pas(2261): Return value of function 'TEditorForm.PrintPage' might be undefined

    I then compiled the project using Delphi 10.4 Community Edition ( w/patch1) to a Windows 32-bit platform, I got the following warnings and hints: (see zip file).

    Using Delphi 10.4, the build has a font problem - when I open an existing .spin2 file the characters are chinese in nature, but if I save it then open it with Proptool, the text is fine and the .spin2 works fine. Probably need to use the propeller font in the project. I need to pursue the font issue.

    So a feature of Delphi 10.4 is "code once, compile for many platforms" I tried compling the project to MacOs, and IOS, but both times i got a fatal error. What's wierd is that there's no further explaination in the nature of the error. Usually the error has an associated code and explaination to help troubleshoot. Not in the case.

    I complied it using Lazarus and I get the same error as pik33 - it chokes on the windows api code associated with the serial port code.

    I think the project needs to use a third party comport component that is multiplatform compatible. I believe I have such a thing for Delphi 6. The Parallax Serial Terminal is written in delphi 6 using windows api. I'll try rewriting it using the comport component (ComPort Library ver. 4.11 for Delphi 5, 6, 7, 2007-2010,XE)

  • @mojorizing said:
    Using Delphi 10.4, the build has a font problem - when I open an existing .spin2 file the characters are chinese in nature, but if I save it then open it with Proptool, the text is fine and the .spin2 works fine. Probably need to use the propeller font in the project. I need to pursue the font issue.

    That's not a font issue, that's just mojibake. Presumably your file was saved with 8 bit characters but it tried to load it as 16 bit characters.

  • Yes! Wikipedia'd it and "Mojibake" is now in my vocabulary, and it's what's going on with Delphi 10.4. —‚�£½ Š óÞ¢áñ????ðsžšåÞя ("thank you" in mojibake)

  • Greg LaPollaGreg LaPolla Posts: 323
    edited 2021-12-11 05:54

    I have been able to get it all the way to linking in Lazarus. There are some missing units that need to be added to the the uses lines.

    Also all rect calls have to be changed to classes.rect.

    The hard one was the obj file put out by the turbo assembler was not in coff format. I was able to convert it using objconv but the size increases a lot and the linker fails with a unit to big error.

    I am not sure how to get past this one.

    Also all the inline assembly code is i386 based, this code will never be able to be cross compiled or compiled to 64 bit in its current state.

  • cgraceycgracey Posts: 14,206

    The p2com.asm file contains some large undefined buffers. Those are probably blowing up the file size. Maybe those allocations could be done in Lazarus, instead.

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-11 18:01

    Hmmm, so I've started to look at it again and discovered something that didn't even need the full source release... The "List is too large" errors I've been getting seem to have some relation with including files in the DAT section, but it isn't as simple as the feature being entirely broken.

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-11 18:27

    Okay, I must be suffering from a serious case of brainyot, because it was that I didn't allocate enough list buffer... EXCEPT I TRIED THAT AND IT DIDNT WORK BUT NOW IT DOES???? Owie ouch my absolute head.

    Well, that means I guess I just have to update to the latest p2com.asm and my job is done?
    Oh, and move the repository to github for general convenience (was created before public spin2 compiler source was announced and I prefer gitlab for private projects)

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-11 19:05

    Also, it transpires that TASM32.EXE is actually a Win32/DOS hybrid executable??? Another thing I probably should've realized. I just assumed it was a DOS executable after having to deal with the DOS installer. Should probably rewrite the build script to not use dosbox then (and wine to get it to cooperate on Linux, I guess?)

  • @cgracey said:
    The p2com.asm file contains some large undefined buffers. Those are probably blowing up the file size. Maybe those allocations could be done in Lazarus, instead.

    Also, this is something I've already done in my thing. Commented out obj_data and dat_data and changed the code that relates to them to use straight pointers instead of offesets into the buffer. Then I can just malloc them on the heap.

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-11 20:29

    Sorry for... quintupleposting, but here's another breakthrough.

    I've got the compiler set up to bootstrap itself (that is, to compile a minimal version to assemble the PASM files that the full version depends on). It's as simple as processing the source according to this rule:

    file "p2com_bootstrap.asm" => "p2com.asm" do |t|
        puts "Generating bare PASM compiler source for bootstrapping"
        # Just remove all the include directives
        File.write(t.name,File.read(t.source).gsub(/include\s*"\w+\.inc"/,''))
    end
    

    ... and then rolling with that.

  • evanhevanh Posts: 16,032

    Is that Ruby?

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-11 20:45

    @evanh said:
    Is that Ruby?

    Yep. Well, more specifically, it's a rake task. (rake is a make-like utility based on ruby. I really like this tool.).
    You can see the entire rakefile here: https://github.com/Wuerfel21/spinner2/blob/master/Rakefile

  • Would nasm be an easy assembler to switch to? I think it's now capable of producing both COFF and ELF objects.

  • Wuerfel_21Wuerfel_21 Posts: 5,106
    edited 2021-12-11 21:43

    @Circuitsoft said:
    Would nasm be an easy assembler to switch to? I think it's now capable of producing both COFF and ELF objects.

    Nope, TASM syntax is too different.
    I've got the linking all figured out, anyways.

Sign In or Register to comment.