Shop OBEX P1 Docs P2 Docs Learn Events
PropBASIC 00.00.04 Sept 1, 2009 Download it and try it. — Parallax Forums

PropBASIC 00.00.04 Sept 1, 2009 Download it and try it.

BeanBean Posts: 8,129
edited 2009-09-09 12:40 in Propeller 1
Okay, it is still VERY basic. Only a few commands have been implemented. But members have been bugging me for something ANYTHING to try out.

So here it is. Be sure to read the PropBASIC.txt file. It is just a command line utility for now. You MUST HIT ENTER after it is done compiling for it to end.

If you have any questions please ask.


0.0.04 Sept 1, 2009
· Fixed problem with·9-bit constants used as parameters to subroutines.
· Fixed problem with using PAUSE more than once, cause DUPLICATE VARIABLE error

Bean.
·

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Does that byte of memory hold "A", 65, $41 or %01000001 ?
Yes it does...




Post Edited (Bean (Hitt Consulting)) : 9/1/2009 3:21:06 PM GMT
«13

Comments

  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 17:40
    Suggestion: Use binary output in the listing for values defined with PIN -- will make the listing easier to read, I believe. And for consistency with PBASIC (if that is one of the goals, pins should be numbered 0 to 31, not 1 to 32).

    Post Edited (JonnyMac) : 8/31/2009 5:46:14 PM GMT
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 18:05
    Terry,

    The compiler seems to be looking for INVALID.TXT
  • BeanBean Posts: 8,129
    edited 2009-08-31 18:13
    Yes, the PropBASIC.txt file is wrong, it IS 0 to 31 instead of 1 to 32.

    Oops, Sorry about that Jon. I updated the program. Try it now.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Does that byte of memory hold "A", 65, $41 or %01000001 ?
    Yes it does...




    Post Edited (Bean (Hitt Consulting)) : 8/31/2009 6:20:57 PM GMT
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 18:29
    The attached program compiles, but won't run -- is there a problem using Main as a label? And when I changed Main to Flash the compiler didn't catch the GOTO Main error.
  • BeanBean Posts: 8,129
    edited 2009-08-31 18:34
    Jon,
    Yeah it looks like spin will not allow the word "Main" to be used as a label.
    I changed it to "Main1" and it worked.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Does that byte of memory hold "A", 65, $41 or %01000001 ?
    Yes it does...


    ·
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 18:35
    Bean,

    At the end of the FOR-NEXT loop there is a peculiar line:

    IF_BE JMP #+__FOR_idx_1
    


    Is the "+" supposed to be there? It doesn't seem to hurt, but I've never seen such syntax.
  • BeanBean Posts: 8,129
    edited 2009-08-31 18:44
    Jon,
    No that "+" is not supposed to be there. I'll remove that. But I'm surprised that it works....

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Does that byte of memory hold "A", 65, $41 or %01000001 ?
    Yes it does...


    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-08-31 19:27
    Bean,

    I missed NOT from the list of operators.
    So I inserted temp = NOT temp
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    

    LED    PIN 15
    

    temp   VAR LONG
    

    PROGRAM Start
    

    Start:
      LOW LED
      FOR temp = 1 TO 10
        TOGGLE LED
        PAUSE 500
      NEXT
      temp = not temp  
    END
    

    It compiles without error and the line temp = NOT temp
    seems to be ignored.

    regards peter
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 19:38
    Since you're at the front end of the project I'm wondering if I can lure you to the dark side of anal-retentive neatness when formatting the output. I think that if you use a columnar output -- like most PASM programmers seem to use -- the list file is easier to read (see attached). And could you add at least one blank line before labels in the assembly output.

    Also, the Main issue was caused by the compiler's use of Main; suggest you change that to RunPB or something else that a programmer typically wouldn't use.

    Post Edited (JonnyMac) : 8/31/2009 7:48:06 PM GMT
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 19:52
    Suggestion for PAUSE and PAUSEUS: Instead of using "magic numbers" in the listing, create symbols called _1ms and _1us; I think it will make the code loops easier for new programmers to make sense of.

    Delay
                    mov     __param1, #500                          ' PAUSE 500
                    mov     __param2, _1ms
                    add     __param2, cnt
    
    __L0001         waitcnt __param2, _1ms
                    djnz    __param1, #__L0001
    



    And, you might consider optimizing for short delays that are powers of two. A pause of 8 milliseconds might expand to this:

    Delay8                
                    mov     __param1, _1ms                          ' PAUSE 8
                    shl     __param1, #3
                    add     __param1, cnt
                    waitcnt __param1, #0
    

    Post Edited (JonnyMac) : 8/31/2009 9:46:06 PM GMT
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-08-31 22:05
    Bean,

    With so little room in one cog have you considered callable code blocks instead of straight inline compilation?

    ' Pulse (make output and toggle) pin for n microseconds
    ' -- move pin# to _param1
    ' -- move microseconds to _param2
    
    _pulsout                mov     _param3, #1
                            shl     _param3, _param1        wz
                    if_z    jmp     #_pulsout_ret
                            tjz     _param2, #_pulseout_ret
                            xor     outa, _param3
                            or      dira, _param3
                            mov     _param1, _param2
                            call    #_pauseus
                            xor     outa, _param3
    _pulsout_ret            ret
    
    
    ' Pause program in milliseconds
    ' -- move milliseconds to _param1 before calling
    '
    _pause                  tjz     _param1, #_pause_ret
                            mov     _param2, _1ms
                            add     _param2, cnt
    :loop                   waitcnt _param2, _1ms
                            djnz    _param1, #:loop
    _pause_ret              ret
    
    
    ' Pause program in microseconds
    ' -- move microseconds to _param1 before calling
    '
    _pauseus                tjz     _param1, #_pauseus_ret
                            mov     _param2, _1us
                            add     _param2, cnt
    :loop                   waitcnt _param2, _1us
                            djnz    _param1, #:loop
    _pauseus_ret            ret
    

    Post Edited (JonnyMac) : 8/31/2009 10:17:13 PM GMT
  • Ken GraceyKen Gracey Posts: 7,401
    edited 2009-08-31 22:29
    Oh my, an introductory release from Bean has lured one of the PBASIC gurus! JonnyMac (AKA King of Stamps) has held BASIC programming dear to his heart every day for the last 20 years. Not to mention Peter Verkaik, another one who has worked with all of our tools for years. Do I see a team forming? Let me know how we can help!

    Ken Gracey
    Parallax Inc.
  • hover1hover1 Posts: 1,929
    edited 2009-08-31 23:19
    Yes!! Yes!! This could be the start of something big!!

    For the life of me I could not find a reference to PAUSEUS. I broke out my BS2 books and SX books and did a Parallex site search for the command. I finaley found it in the SX/B help. Boy, you couln't have hidden a command any better.·tongue.gif

    I guess it's old hat to you SX guys. This·is to help the BS2 guys that come over to the dark side.
    Syntax: [b]PAUSEUS[/b] [i]Value1 {[noparse][[/noparse], | *] Value2}[/i]
    Function
    Pause the program (do nothing) for a number of microseconds.
    [list][*][b][i]Value1[/i][/b]  is a variable (1 - 255) or constant (1 to 65535, or fractional value[sup]†[/sup]) that affects the [b]PAUSEUS[/b] duration. [*][b][i]Value2[/i][/b]  is a variable (1 - 255) or constant (1 to 255) that affects the [b]PAUSEUS[/b] duration. [/list]
    [sup]†[/sup] [b]Note:[/b] A value up to 65535 is allowed when a single constant parameter is used.
    [sup]†[/sup] [b]Note:[/b] Fractional values (0.01 to 65535.99) are allowed when a single constant parameter is used. SX clock speed will affect the accuracy of fractional timing.
    Explanation
    [b]PAUSEUS[/b] delays the execution of the next program instruction for a number of microseconds based on [i]Value1[/i] and [i]Value2[/i]. For example:
    Tone:  RC.0 = ~RC.0  [b]PAUSEUS[/b] 500  IF RB.0 = 1 THEN Tone
    This code toggles the state of RC.0 every 500 microseconds, creating a 1 kHz tone until pin RB.0 goes low. Note that a [b]PAUSEUS[/b] duration of up to 65535 microseconds is possible when a single constant parameter is used.
    Some projects may require sub- or fractional-microsecond delays. When using a single parameter, a fractional [b]PAUSEUS[/b] value may be specified:
    Tone440:  DO    RC.0 = ~RC.0    [b]PAUSEUS[/b] 1136.36  LOOP
    [b]PAUSEUS[/b] can take one or two values as parameters. When using two parameters, two forms are allowed. Here's an example of the first form:
      [b]PAUSEUS[/b] 238, 2
    Using this form, the [b]PAUSEUS[/b] duration is [i]Value1[/i] + ([i]Value2[/i] * 256). In the example above the program will pause for 750 microseconds. Note that this form is typically used with variables, but will also work with constants up to 255.
    The third form of [b]PAUSEUS[/b] is demonstrated below:
      idx = 3  [b]PAUSEUS[/b] idx * 250
    Using this form, the [b]PAUSEUS[/b] duration is [i]Value1[/i] * [i]Value2[/i]. In the example above the program will pause for 750 microseconds. Note that this form is typically used with variables, but will also work with constants up to 255.
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Related instruction: [url=mk:@MSITStore:C:\Program%20Files\Parallax%20Inc\SX-Key%20v3.2.92\Compilers\SXB\SXB.chm::/pause.htm][u][color=#0000ff]PAUSE[/color][/u][/url]
    (replace this text with your code)
    

    Ken Gracey (Parallax) said...
    Oh my, an introductory release from Bean has lured one of the PBASIC gurus! JonnyMac (AKA King of Stamps) has held BASIC programming dear to his heart every day for the last 20 years. Not to mention Peter Verkaik, another one who has worked with all of our tools for years. Do I see a team forming? Let me know how we can help!

    Ken Gracey
    Parallax Inc.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2009-08-31 23:31
    Well done Bean. Early morning here and all this has happened while I've been asleep! I like the pro-forma program with all the commented areas showing where to put things. That makes writing a structured program a lot easier. When I wrote the sbasic IDE I did something similar - if you ask for a 'new' program or start the program, you don't just get a blank page, you get a structured series of comments so it is fairly clear, for instance, that you have to declare variables before you use them. As a general philosophy, it is easier to delete "hello world" (or some flashing leds) than start with a blank screen and type PRINT 'HELLO WORLD' and find it gives a syntax error because it is supposed to have double quotes instead of single quotes.

    So - you have loops, delays, flashing lights and goto already.

    Can't wait for the next installment!
  • BeanBean Posts: 8,129
    edited 2009-09-01 02:05
    Jon (and others). I just posted version 0.0.3 that support SUB and FUNC. I also make the listing a little nicer. and some other fixes.

    Get it from the top post.

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Does that byte of memory hold "A", 65, $41 or %01000001 ?
    Yes it does...


    ·
  • edited 2009-09-01 02:25
    How do we compile the code? I am sorry newbie question.

    -Andy
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-09-01 02:34
    Cool beans, Bean!

    Small error with setting up for PAUSE 500. The compiler outputs:

    mov     __param1, 500
    


    ... it's missing the # for the immediate value.

    Post Edited (JonnyMac) : 9/1/2009 2:49:52 AM GMT
  • JonnyMacJonnyMac Posts: 9,198
    edited 2009-09-01 02:47
    Let me have Main, please.... smile.gif

    The compiler output uses Main but doesn't have to. Here's the original output:

    PUB Main                                                     '  PROGRAM Start
      CogNew(@__PROGSTART, 0)                                   
                                                                
    DAT                                                         
    __PROGSTART                                                 
                JMP     #Start
    



    I manually edited to this:

    PUB RunPB                                                    '  PROGRAM Start
      CogNew(@Start, 0)                                   
                                                                
    DAT                                                         
                                                                 '' =========================================================================
    
    Start       ORG     0                                        'Start:
    


    ... which works fine, frees 'Main' for programmer use, and saves the beginning (unnecessary?) jmp. I don't think Spin cares about having a Main; it simply runs the first method. Right?
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-09-01 03:10
    I used the example in the text file with E drive and exact syntax.
    Enter causes it to end however no compiled spin file appears on the
    E drive or anywhere. Where is it?

    Post Edited (humanoido) : 9/1/2009 7:11:31 AM GMT
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-09-01 06:29
    Why the additonal variables __TEMP1 and __TEMP2?

    Delay                                                        'SUB Delay
                MOV     __TEMP1,CNT                              '  PAUSE __PARAM1
                ADD     __TEMP1,_1mSec                          
                MOV     __TEMP2,__PARAM1                        
    __L0001                                                     
                WAITCNT __TEMP1,_1mSec                          
                DJNZ    __TEMP2,#__L0001                        
    Delay_ret                                                    'ENDSUB
                RET 
    

    You could just as well use __PARAM2 and __PARAM3.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-09-01 06:43
    I agree with Jonnymac,
    instead of PUB Main call it something else.
    I'd prefer PUB start and also a PUB stop.
    These seem to be the standard names for starting and stopping a cog.

    Also, why putting in
    · _ClkMode = XTAL1 + PLL16X································
    · _XInFreq =·· 5000000······································ 'FREQ 80_000_000

    I only have a spinstamp and therefor always need to edit the generated file.

    I would like to import the generated file as
    OBJ
    · pbcog: "test.spin"

    in my own program (in which I use main as
    the program starting point) and call pbcog.start() from there.

    regards peter
  • HollyMinkowskiHollyMinkowski Posts: 1,398
    edited 2009-09-01 06:56
    @MrBean

    This is a cool and ambitious project smile.gif

    I'd love to be able to write a tiny compiler for a controller.
    I need a good book about compiler creation.
    I would need a "Compiler Construction for Dummies" type of book, not a tome
    usable only by CompSci Phd's

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - Some mornings I wake up cranky.....but usually I just let him sleep -
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-09-01 07:19
    Has anyone actually tried running this? Did it work?
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-09-01 10:56
    Here are two spin programs, one for protoboard and one for spinstamp,
    plus an edited test.spin to make test.spin a loadable module.

    The programs import test.spin
    They also declare a long array to be passed to the PropBasic cog.

    I think that is the most useful setup. I can write my cogcode in PropBasic
    and my mainprogram in spin. Having not to use PASM directly makes
    a difference, even if the compiled PASM is not optimized.

    The modified test.spin
    ''  *** COMPILED WITH PropBasic VERSION 0.00.03  08/31/2009 ***
    ''modified to make it a loadable module
    

    CON                                                          'DEVICE P8X32A, XTAL1, PLL16X
    '  _ClkMode = XTAL1 + PLL16X
    

    '  _XInFreq =   5000000                                       'FREQ 80_000_000
    

    ' LED    PIN 15                                              'LED    PIN 15
    

    ' temp   VAR LONG                                            'temp   VAR LONG
    

    ' Delay  SUB 1                                               'Delay  SUB 1
    

    '           Add1    FUNC 1,1                                 'Add1   FUNC 1,1
    

    VAR
      long cog_id
      
    PUB Start(parAddress)                                                     'PROGRAM Start
      cog_id := CogNew(@__PROGSTART, parAddress)
    

    PUB Stop
      CogStop(cog_id)
                                                       
    DAT                                                         
    __PROGSTART                                                 
                JMP     #__Start
    

    __Start                                                        'Start:
    

                OR      DIRA,LED                                 '  LOW LED
                ANDN    OUTA,LED
    

                MOV     temp,#1                                  '  FOR temp = 1 TO 10
    __FOR_temp_1
    

                OR      DIRA,LED                                 '    TOGGLE LED
                XOR     OUTA,LED
    

                MOV     __PARAM1,500                             '    Delay 500
                CALL    #Delay
    

                ADD     temp,#1                                  '  NEXT
                CMPS    temp,#10 WZ, WC                         
        IF_BE   JMP     #__FOR_temp_1
    

                JMP     #$                                       'END
    

    Delay                                                        'SUB Delay
    

                MOV     __TEMP1,CNT                              '  PAUSE __PARAM1
                ADD     __TEMP1,_1mSec                          
                MOV     __TEMP2,__PARAM1                        
    __L0001                                                     
                WAITCNT __TEMP1,_1mSec                          
                DJNZ    __TEMP2,#__L0001
    

    Delay_ret                                                    'ENDSUB
                RET                                             
    

    Add1                                                         'FUNC Add1
    

                ADDS    __PARAM1,#1                              '  INC __PARAM1
    

    Add1_ret                                                     '  RETURN __PARAM1
                RET
    

                                                                 'ENDFUNC
    

    '**********************************************************************
    LED              LONG 32768
    _1mSec           LONG 80000
    

    __TEMP1          RES 1
    __TEMP2          RES 1
    __PARAM1         RES 1
    __PARAM2         RES 1
    __PARAM3         RES 1
    __PARAM4         RES 1
    __PARAMCNT       RES 1
    temp             RES 1
    

    CON
    

    The protoboard program
    {{
      Protoboard PropBasic test program
    }}
    CON
      _ClkMode = XTAL1 + PLL16X                                 
      _XInFreq = 5000000
    OBJ
      pbcog: "test.spin"
      
    VAR
      long PBparameters[noparse][[/noparse]26]
      
    PUB Main
      pbcog.Start(@PBparameters)
                                                                
    


    regards peter
  • BeanBean Posts: 8,129
    edited 2009-09-01 11:20
    Peter Verkaik said...
    Why the additonal variables __TEMP1 and __TEMP2?

    Delay                                                        'SUB Delay
                MOV     __TEMP1,CNT                              '  PAUSE __PARAM1
                ADD     __TEMP1,_1mSec                          
                MOV     __TEMP2,__PARAM1                        
    __L0001                                                     
                WAITCNT __TEMP1,_1mSec                          
                DJNZ    __TEMP2,#__L0001                        
    Delay_ret                                                    'ENDSUB
                RET 
    

    You could just as well use __PARAM2 and __PARAM3.

    regards peter
    Peter,
    · I've decided that the __PARAMx variables will be used exclusively for subroutine parameters. So you DON'T need to store them into other variables in the subroutine, because they will never be used by PropBASIC commands.

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Does that byte of memory hold "A", 65, $41 or %01000001 ?
    Yes it does...


    ·
  • BeanBean Posts: 8,129
    edited 2009-09-01 11:24
    Peter Verkaik said...
    Also, why putting in
    · _ClkMode = XTAL1 + PLL16X································
    · _XInFreq =·· 5000000······································ 'FREQ 80_000_000

    I only have a spinstamp and therefor always need to edit the generated file.
    Peter,
    · For the spin stamp change "DEVICE P8X32A, XTAL1, PLL16X" to "DEVICE P8X32A, XTAL1, PLL8X". The compiler will then generate the correct _XInFreq for "FREQ 80_000_000".

    Bean.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Does that byte of memory hold "A", 65, $41 or %01000001 ?
    Yes it does...


    ·
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-09-01 11:43
    Hi Bean,

    I understand the necessity for FREQ 80_000_000.
    That value is used for PAUSE and PAUSEUS.
    But why including PLL multiplier and oscillator frequency?
    I don't think a cog needs that info.
    And I want to set clkmode and inxfreq in my program file,
    not in a object that I import in my program file.

    BTW, I tried commenting out DEVICE but then
    the compiler crashes.

    regards peter
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2009-09-01 11:52
    Bean said...
    · I've decided that the __PARAMx variables will be used exclusively for subroutine parameters. So you DON'T need to store them into other variables in the subroutine, because they will never be used by PropBASIC commands.
    That makes sense to keep overhead low. Can I assume the __TEMPx variables are reused whenever possible?
    Is there still a need for __PARAMCNT since all arguments to·a sub are 32bit values anyway?

    regards peter
  • HumanoidoHumanoido Posts: 5,770
    edited 2009-09-01 12:21
    Bean: it is not compiling a file on my computer. Any idea what the problem is?
  • RsadeikaRsadeika Posts: 3,837
    edited 2009-09-01 13:17
    Are you typing in the full path, and the file name? For instance: PropBASIC F:\PropBASIC\test1.bas /p. I made an
    assumption that all you need is PropBASIC test1.bas /p, but that did not work.

    <edit
    The program, I think, is supposed to flash the LED, but with a setting of 'delay 500', I did not see anything happen.
    When I increased the value to 'delay 1500', then I saw it flash. So, I am not sure as to how the delay values
    are supposed to work.
    edit>

    Ray

    Post Edited (Rsadeika) : 9/1/2009 1:34:35 PM GMT
Sign In or Register to comment.