PropBASIC

2

Comments

  • jmgjmg Posts: 12,087
    edited July 17 Vote Up0Vote Down
    Bean wrote: »
    .... I am the developer of PropBasic and I use it everyday.
    If you have any further questions feel free to ask on the forums and I will help as much as I can.

    There has been some fixes to PropBasic and I'll have to post a new version since it looks like at least some people as still using it.

    Given this thread, I had a quick check of PropBASIC and commands / error parsing.

    I find a quirk in the file-name parsing, where a full/absolute file is ok, but in a batch file a partial name-only fails ?

    ie This works
    ..\src\PropBasic "%~dp0Freq Counter3.pbas"
    where %~dp0 is fixup bandaid,
    but this fails, seems to lack a \ between constructed path and file name ?
    ..\src\PropBasic "Freq Counter3.pbas"

    Most editor params will be of either the $(FULL_CURRENT_PATH) type, or of $(NAME_PART)

    I also had a quick trial of NppExec, which is a console error parser for NotePad++, and I can get that to work with FreeBasic error format, which is
    COM4_Test.bas(50) error 14: Expected identifier, found 'StringTT' in 'Dim b As StringTT'
    COM4_Test.bas(98) error 180: Invalid assignment/conversion in 'b = Input(LOC(1), 1)'

    There is an active FreeBASIC IDE called poseidonFB here https://www.freebasic.net/forum/viewtopic.php?t=23935

    That seems quite active, and keywords look easy to modify.
    It also seems to parse the FreeBASIC error outputs of the form, and nicely inserts red error tag lines in the source window.
    COM4_Test.bas(50) error 14: Expected identifier, found 'StringTT' in 'Dim b As StringTT'
    COM4_Test.bas(98) error 180: Invalid assignment/conversion in 'b = Input(LOC(1), 1)'

    using this filter:
    %FILE%(%LINE%) *error*
    
    (and it can also use %CHAR% to char locate the error cursor too.)


    However, PropBASIC seems to export differently to the console
    Using /Q I can reduce to

    ERROR 23 COULD NOT READ SOURCE FILE "/Q" ;
    ERROR 18 NO "PROGRAM" COMMAND USED ;
    - but that lacks File name, Line, Char index info.


    By using /VP param, I can get this in an error file
    ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.bas,26,10,UNKNOWN COMMAND "DOx"
    ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.bas,116,16,LOOP WITHOUT DO "LOOP"

    Similar, but different... & neither NppExec nor poseidonFB.exe can read error files, they expect to grab the console output.

    26 & 116 here look to be the %LINE% info NppExec can swallow, not sure what 10 & 16 are - not quite char positions ? - perhaps are error code # ?

    An educated guess of a NppExec parser for that file-reported-to-console would be
    ERROR,%ABSFILE%,%LINE%,
    

    My suggestion would be to add an option to report errors in FreeBASIC error message format, so the various FreeBASIC IDE's can be trialed for Prop BASIC
  • jmgjmg Posts: 12,087
    edited July 17 Vote Up0Vote Down
    Some small correction & examples to have PropBASIC callable from within Notepad++, (Using NppExec plugin) and to have click-error-jump work

    This filter allows NppExec to click-jump-to-error-line, which is highlights in the console capture window
    ERROR,%ABSFILE%,%LINE%,*
    

    and this NppExec param calls a batch file..
    C:\Lazarus\PropBASIC\RecipCounter\Npp_PropBASIC.BAT "$(CURRENT_DIRECTORY)\$(NAME_PART)"
    

    works with this Npp_PropBASIC.BAT batch file, in the source dir,
    CD %~dp0
    C:\Lazarus\PropBASIC\src\PropBasic.exe %1.pbas /VP
    TYPE %1.err
    

    creates this C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.err ( Exec when Active Editor Window is Freq Counter3.pbas )
    ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,34,10,UNKNOWN COMMAND "DOy"
    ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,116,16,LOOP WITHOUT DO "LOOP"
    


    and the total Notepad++ console report is this
    C:\Lazarus\PropBASIC\RecipCounter\Npp_PropBASIC.BAT "C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3"
    Process started (PID=13792) >>>
    
       1  ' Frequency counter (0.5 Hz to 40 MHz)
       2  ' Counts frequency on P0, sends ASCII to PC at 115200 Baud
       3  ' 1.0 Second gate time (gate time will be longer if frequency is < 2 Hz)
       4  '
       5  DEVICE   P8X32A, XTAL1, PLL16X
       6  XIN      5_000_000
       7  
       8  BAUD     CON "T115200"   ' Baud rate for PC communications
       9  
      10  Signal   PIN 0 INPUT     ' Input pin for signal
      11  TX       PIN 30 HIGH     ' Output pin for PC communications
      12  
      13  cntStart VAR LONG        ' "cnt" value at start of measurement
      14  cntTime  VAR LONG        ' elapsed "cnt" clocks
      15  sigCnt   VAR LONG        ' count of how many input pulses have been received
      16  temp     VAR LONG        ' loop counter
      17  digit    VAR LONG        ' current digit
      18  digitSum VAR LONG        ' Used for leading zero removal
      19  ascii    HUB STRING (20) ' Holds ascii representation of frequency
      20  
      21  PROGRAM Start            ' Start program at label "Start:"
      22  
      23  
      24  Start:
      25    COUNTERA 80, 0, 0, 1, 0 ' Count positive edges on pin 0
      26    DO
      27      ' Wait for a signal pulse to syncronize to the system counter
      28      WAITPNE Signal, Signal
      29      WAITPEQ Signal, Signal
      30      phsa = 0
      31      cntStart = cnt - 4
      32  
      33      ' Count input pulses until 1.0 seconds have elapsed
      34      DOy
     ERROR 10  UNKNOWN COMMAND "DOy"  ;     DOy
      35        WAITPNE Signal, Signal
      36        WAITPEQ Signal, Signal
      37        sigCnt = phsa
      38        cntTime = cnt - cntStart
      39      LOOP UNTIL cntTime > 80_000_000 ' 1.0 Second gate time
      40      cntTime = cntTime - 4 ' To account for "sigCnt = phsa" instruction
      41  
      42      ' Calculate  frequency if >= 0.5 Hz
      43      IF cntTime <= 160_000_000 THEN
      44  
      45        ' Since cntTime is in 80MHz units, the frequency is sigCnt / (cntTime / 80_000_000) = Hertz
      46        ' Rearranged this can be written as (sigCnt * 80_000_000) / cntTime = Hertz
      47        '
      48        ' We want the result in milliHertz (1/1000 of a hertz) so we need to use:
      49        ' (sigCnt * 80_000_000_000) / cntTime = milliHertz
      50        '
      51        ' Okay, now we have a problem, 80_000_000_000 cannot even be represented in 32 bits. Hmmm
      52        ' What if we calculate the answer one digit at a time...
      53        '
      54        ' The leftmost digit is MegaHertz and that digit can be calculated as:
      55        ' (sigCnt * 80) / cntTime = MegaHertz. This we can do easily.
      56        '
      57        ' Now the "trick" is how do we get the next digit ?
      58        ' We take the remainder from the division, multiply it by 10 and divide again.
      59        '  by repeating this process of taking the remainder and multipling by 10 we
      60        '  can get as many digits as we need until we run out of precision.
      61        '
      62        digitSum = 0                 ' Sum of all digits so far. Used to create replace leading zeros with spaces
      63        ascii = ""
      64        sigCnt = sigCnt * 8          ' Scale signal count to get MegaHertz digit
      65  
      66        FOR temp = 0 TO 13           ' 7 digits + decimal point + 3 digits = 11 digits
      67  
      68          digit = sigCnt / cntTime   ' Calculate this digit of result
      69          sigCnt = __remainder       ' Keep remainder for next digit
      70  
      71          __temp1 = sigCnt * 2       ' sigCnt = sigCnt * 10
      72          sigCnt = sigCnt * 8        ' Scale signal count for next digit
      73          sigCnt = sigCnt + __temp1
      74  
      75  
      76          INC digitSum, digit        ' Add this digit's value to sum
      77          digit = digit + "0"        ' Convert digit to an ascii digit
      78  
      79  
      80          ' If this is a leading zero, make it a space
      81          IF temp < 9 AND            ' Only use leading spaces for digits higher than the units digit
      82           digitSum = 0 THEN         ' If the sum is zero, then we have only had "0" digits so far
      83            digit = " "              '  so use a space instead of a "0" for this digit.
      84          ENDIF
      85  
      86          WRBYTE ascii(temp), digit  ' Put digit into the result string
      87  
      88          ' Insert a comma if needed
      89          IF temp = 1 OR
      90           temp = 5 THEN
      91            INC temp
      92            IF digitSum = 0 THEN
      93              WRBYTE ascii(temp), " "
      94            ELSE
      95              WRBYTE ascii(temp), ","
      96            ENDIF
      97          ENDIF
      98  
      99          ' Insert decimal point at proper place
     100          IF temp = 9 THEN           ' If we just processed the units digit,
     101            INC temp                 '  move pointer to the next character in the result string
     102            WRBYTE ascii(temp), "."  '  and make it a decimal point
     103          ENDIF
     104  
     105        NEXT                         ' Process all digits
     106  
     107        WRBYTE ascii(14), " ", "H", "z", 13, 0
     108  
     109      ELSE
     110        ascii = "Too low (< 0.5Hz)"
     111        ascii = ascii + 13
     112      ENDIF
     113  
     114      SEROUT TX, BAUD, ascii       ' Send frequency to terminal
     115  
     116    LOOP                           ' Repeat forever
     ERROR 16  LOOP WITHOUT DO "LOOP"  ;   LOOP                           ' Repeat forever
     117  
     118  SetDAC SUB 1
     119  SetDAC 1  
     120  SUB SetDAC
     121  ' code to set DAC
     122  value VAR LONG
     123  value = 100
     124  Again:
     125    HIGH TX
     126    LOW TX
     127  DJNZ value, Again
     128  
     129  ENDSUB
     130  
     131  SetDAC_ FUNC 1
     132  'myVar = Calc 1
     133  FUNC SetDAC_
     134  __param1 = __param1 + 1
     135  RETURN __param1
     136  ENDFUNC  
     137  END
    
    PropBasic Version 00.01.44 Jul 13, 2014
    Finished Compile. 137 Lines Read, 258 Lines Generated,  0 Warnings, 2 Errors.
    ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,34,10,UNKNOWN COMMAND "DOy"
    ERROR,C:\Lazarus\PropBASIC\RecipCounter\Freq Counter3.pbas,116,16,LOOP WITHOUT DO "LOOP"
    <<< Process finished (PID=13792). (Exit code 0)
    ================ READY ================
    

    The two ERROR, lines are highlighted in red, and mouse click jumps to that source line, in the editor window.
  • jmgjmg Posts: 12,087
    jmg wrote: »
    There is an active FreeBASIC IDE called poseidonFB here https://www.freebasic.net/forum/viewtopic.php?t=23935

    That seems quite active, and keywords look easy to modify.
    It also seems to parse the FreeBASIC error outputs of the form, and nicely inserts red error tag lines in the source window.
    COM4_Test.bas(50) error 14: Expected identifier, found 'StringTT' in 'Dim b As StringTT'
    COM4_Test.bas(98) error 180: Invalid assignment/conversion in 'b = Input(LOC(1), 1)'
    I tested this PoseidonFB IDE some more, and replace the FBC.EXE compiler path with a PropBASIC build batch file.

    That works, but reveals that the PoseidonFB IDE does not use errorlevel tests for success, instead it uses the inbuilt console error parser.
    If it extracts no error lines, it reports no errors.

    With the fixed console or error file reporting, this batch file should work, under Compile File.
    PoseidonFB IDE calls as Parameters -b,"C:/Lazarus/PropBASIC/RecipCounter/Freq Counter3.pbas"
    CD %~dp0
    C:\Lazarus\PropBASIC\src\PropBasic.exe %2 /VP
    IF %ERRORLEVEL% NEQ 0 (
      TYPE "%~dpn2.err" 
      ) ELSE ( 
       ECHO No Errors, OK to Compile and download in this section.
     )
    
    
  • @ JonnyMac
    I don't publish my code for fear of embarrassment and mockery from the language wars pseudo intellectuals.
    That made me giggle. I wish you would share code -- it would probably benefit people like me who favor something else and may have missed an opportunity. Maybe we just need to be shown the way.

    I think we should use the tools we feel comfortable with no matter what others think. If we get satisfactory results that way (and you certainly do) then what is the problem. Certainly there are many on this message board that have a greater/ faster/ ability to absorb and implement new ways than I. My very first language was tiny basic then 8080 assembler, then assembler in 8051, 6502, Z8, 68000, avr etc but ALL the time was using Basic in its various incarnations as a high level language. For a while had success with Arduino 'C', but wasn't comfortable.
    I recently retry'd working with python. I started to get results but then wanted to get a key from the keyboard. Oh boy. What a can of worms that turned out to be- I searched hi and lo googled all over the place and eventually gave up. Life's too short. Now there is NOTHING WRONG with Python- it just doesn't fit in with my set in ways of thinking. So I use what works for me.
    To my way of thinking ANYTHING that works for you is good.

    Jon- you clearly have more smarts than me- I don't think I can show you the way- you are clearly successful doing what you do.

    But I do love PropBasic; its the only way for ME to achieve useful results in reasonable time on the Prop.

    Dave


  • BeanBean Posts: 7,952
    jmg, I am open to supporting some kind of IDE. But I am really busy at work.
    If you could let me know exactly what would need modified to support any particular IDE.

    Bean
  • I just tried the toggle LED program on the FLiP module, for pin 26 and then 27, they did not work. And then just to very the program, I tried it on the Activity Board, that worked.

    Not sure why it is not working with the FLiP module. Can somebody verify this.

    Ray
  • For reference, this is the code that worked for me with the FLiP module

    flash-led.pbas
    DEVICE P8X32A
    
    LED PIN 26 OUTPUT
    
    PROGRAM Start
    
    Start:
    TOGGLE LED
    PAUSE 1000
    GOTO Start
    
  • jmgjmg Posts: 12,087
    edited July 17 Vote Up0Vote Down
    Bean wrote: »
    jmg, I am open to supporting some kind of IDE. But I am really busy at work.
    If you could let me know exactly what would need modified to support any particular IDE.

    Sure.
    1) as user gh-jmg, I've uploaded changes to github PropBASIC to add /FB switch, that seems to work ok. PoseidonFB IDE now extracts reported errors


    2) Less critical, is the bug fix to the command line, where a filename.bas fails, in current dir, but c:\full\path\to\file.pbas is ok - I'll look at that later.

    Addit: fixed 2), so this line now compiles ok
    ..\src\PropBasic.exe "Freq Counter3.pbas" /FB

  • jmgjmg Posts: 12,087
    PoseidonFB IDE screen grab
    814 x 526 - 35K
  • WhitWhit Posts: 3,975
    edited July 18 Vote Up0Vote Down
    @tritonium - Many here have encouraged me to publish my code without fear. If it works, it works.

    Studying other people's code and having them study and comment on yours can help us all learn!

    Glad to see Bean still supporting PropBASIC - I am UP for any way into using the Propeller - Spin, PASM, C, PropBASIC, or now BlocklyProp!

    That is one of the reasons I enjoy BlocklyProp so much - Easy access for beginners - All the fun of programming without the worries of exact syntax!
    Whit+

    "We keep moving forward, opening new doors, and doing new things, because we're curious and curiosity keeps leading us down new paths." - Walt Disney
  • I downloaded the contents of several PropBASIC libraries that were referenced above for study but all of them, except for the basic shells, require additional code loaded from libraries that I could not locate.

    I am interested in teaching myself to use mathematics on one COG, servo controls on another, and One-Wire data acquisition on a third for example.

    I acquired a laptop that is dedicated to PropBASIC program development so I would like to download all the necessary libraries that support my teaching interests.

    Sincerely,

    Discovery
  • Bean and McPhalen,

    I began my pBASIC language learning program by running the LED toggle program including other features on my Propeller Activity Board. Then I began entering library programs suggested by forum users which include Delays, I2C, One-Wire, Keyboard and others. My approach is to get each of the suggested libraries working by calling them into the LED toggle program and using them.

    My first library attempt is the Delay Library by Jon McPhalen. The compiler spits out ERROR 5 INVALID PARAMETER for the following line of code: PAUSE __parameter1. The compiler also spits out the same error for PAUSEUS __param1 in the Subroutines.

    What should be the actual code?

    Sincerely,

    Discovery
  • JonnyMacJonnyMac Posts: 6,092
    edited July 23 Vote Up0Vote Down
    As I told you, I haven't used PropBASIC in a long time. Those libraries worked when I wrote them -- things have changed, most certainly for the better, but I haven't adapted. I think that Bean said somewhere that the PAUSE commands were already turned into subroutines, so that library may be useless at this point. Back when I wrote that code, every PropBASIC command was compiled in place; I created the libraries to reduce redundant code.

    I just started a new job so I don't know when I'll be able to try PropBASIC again.
    Jon McPhalen
    Hollywood, CA
    It's Jon or JonnyMac -- please do not call me Jonny.
  • Discovery wrote: »
    Bean and McPhalen,

    I began my pBASIC language learning program by running the LED toggle program including other features on my Propeller Activity Board. Then I began entering library programs suggested by forum users which include Delays, I2C, One-Wire, Keyboard and others. My approach is to get each of the suggested libraries working by calling them into the LED toggle program and using them.

    My first library attempt is the Delay Library by Jon McPhalen. The compiler spits out ERROR 5 INVALID PARAMETER for the following line of code: PAUSE __parameter1. The compiler also spits out the same error for PAUSEUS __param1 in the Subroutines.

    What should be the actual code?

    Sincerely,

    Discovery

    Don't have my Prop system with me but you are passing a value to Delay, right?

    PropBASIC ROCKS!
  • Jon...no problem.

    Mickster...that's what I was expecting to take place.

    If someone uses pBasic regularly and has loadable, workable libraries that include one-wire, I2C, and mathematics...it would be helpful to gain access to those libraries.

    Sincerely,

    Discovery
  • BeanBean Posts: 7,952
    Discovery,
    I am really busy at work right now, so I don't have time to make any libraries.
    I would suggest just using the built-in 1-wire and I2C commands to get more comfortable with how PropBasic works.
    If you run out of code space you can switch to LMM mode (large memory model) by simply putting LMM on the PROGRAM line like:
    PROGRAM Start LMM
    

    Bean
  • Hi Bean,

    I understand you are really busy at the moment. I will use the built-in I2C and One-Wire commands and get familiar with writing code into the Large Memory Mode.

    When you are less busy, would you address a library of sine, cosine, exponential, etc. math functions?

    Sincerely,

    Discovery
  • This is Terrific!

    For the first time, I am able to program the Propeller in the Basic Programming Language. Several programs were written to control machinery and devices such as an HVAC unit by setting value1 to be below Low Level Set Point, above the High Level Set Point, or between the two. value1 VAR LONG

    This type variable can only handle integers...how can I set variables to handle real numbers such as 25.4 for example?

    Sincerely,

    Discovery
  • BeanBean Posts: 7,952
    Use "Fixed Point Format".

    You just multiply everything by a set amount.
    For example your variable might hold 1/100 of a volt instead of 1 volt.
    So for example 100 would be 1 volt, and 123 would be 1.23 volts.
    You just need to remember to multiply everything by the same amount.

    Another example is using cents instead of dollars, so if something is $12.34 the variable would hold 1234.

    If the units can be whatever you want, it is easiest to make the units multiples of a power of 2. A common one is 256.
    So if you were using volts 1.23V would be stored as 315 (1.23 * 256). This way displaying the value is easier.
    You shift right by 8 and print the whole value, then print the ".", then AND the original value with 255, multiply by 100 and shift right by 8 and print.

    Bean
  • Excellent Bean,

    How do I print?

    Discovery
  • You might want a serout command. Have you seen this library? It contains tx-rx commands...

    http://forums.parallax.com/discussion/163372/propbasic-libraries

  • Thank you,

    That should solve my problem.

    Discovery
  • Discovery wrote: »
    This is Terrific!


    Tell me about it...But don't tell anyone else because it's our secret weapon ;)

    TerryHittific?

    :lol:
    PropBASIC ROCKS!
  • MicksterMickster Posts: 1,194
    edited July 26 Vote Up0Vote Down
    Discovery wrote: »
    Hi Bean,

    I understand you are really busy at the moment. I will use the built-in I2C and One-Wire commands and get familiar with writing code into the Large Memory Mode.

    When you are less busy, would you address a library of sine, cosine, exponential, etc. math functions?

    Sincerely,

    Discovery

    Just came across this...
    PropBASIC ROCKS!
  • Mickster,

    Thanks for the information. My self-learning course on pBASIC has reached the point of loading LIBRARY files. Just for grins I ran the compiler on the DELAY library and got errors on the __param1 variable but noticed that it was not defined as such in the library code.
    When I ran the source program with the load DELAY library...the library file loaded fine but the compiler called out the same error in the library code that was inserted into the source program code. I think it is neat that the pBASIC loads the library codes then does the error check on each one.
    So, am I correct in assuming that the library codes must be altered so that the variables used in the library code match those in the calling routine source program or are defined in the calling routine?

    Discovery
  • Bean,
    What is the significance of double underlined variables such as __param1 in libraries other than global variables?

    Discovery
  • BeanBean Posts: 7,952
    Discovery wrote: »
    Bean,
    What is the significance of double underlined variables such as __param1 in libraries other than global variables?

    Discovery

    They are system declared variables. They exist even though you haven't declared them.
    They are prefixed with a double underline so that they don't conflict with your programs variable names.

    Bean
  • Thank you...I though so but wondered if they had any other properties.

    Discovery
  • Discovery wrote: »
    Mickster,

    Thanks for the information. My self-learning course on pBASIC has reached the point of loading LIBRARY files. Just for grins I ran the compiler on the DELAY library and got errors on the __param1 variable but noticed that it was not defined as such in the library code.
    When I ran the source program with the load DELAY library...the library file loaded fine but the compiler called out the same error in the library code that was inserted into the source program code. I think it is neat that the pBASIC loads the library codes then does the error check on each one.
    So, am I correct in assuming that the library codes must be altered so that the variables used in the library code match those in the calling routine source program or are defined in the calling routine?

    Discovery

    I haven't used libraries or any sample code, for that matter. Just my own code and I use Viewport for my editor/debugger. The built in scope is a HUGE help.
    PropBASIC ROCKS!
  • Discovery wrote: »
    Thank you...I though so but wondered if they had any other properties.

    Discovery

    __temp1, __temp2, __temp3, __temp4 are used by some PropBasic commands. Be very careful about using these...

    __param1, __param2, __param3, __param4 as used to pass parameters to subroutines and functions.

    You can use __param as temporary variables as long as you don't call any subroutines or functions.

    A common pitfall is using __param1 in a subroutine, but if that subroutines calls another subroutine (with parameters) it will lose it's value.

    For example:
    SUB SendStr
      ' __param1 holds address of the string
      DO
        RDBYTE __param1, __param2 ' Get a character from the string
        IF __param2 = 0 THEN EXIT
        SendChar __param2
        INC __param1
      LOOP
    ENDSUB
    

    The reason the above code will not work, is when you call "SendChar __param2" the SendChar subroutine needs the character in __param1, so the compiler will generate.
      MOV __param1,__param2
      CALL SendChar
    

    So the value in __param1 will be lost during the first call to SendChar.

    The solution is to to this:
    SUB SendStr
      __param2 = __param1
      ' __param2 holds address of the string
      DO
        RDBYTE __param2, __param1 ' Get a character from the string
        IF __param1 = 0 THEN EXIT
        SendChar __param1
        INC __param2
      LOOP
    ENDSUB
    

    Also __temp4 is aliased as __remainder and holds the remainder from any division operation.

    There is also __paramcnt which is used for subroutines that can have a variable number of parameters. These are rare, so this is probably the safest one to use for temporary use.

    Bean
Sign In or Register to comment.