Shop OBEX P1 Docs P2 Docs Learn Events
Starting to play with PASM — Parallax Forums

Starting to play with PASM

gwkaubgwkaub Posts: 10
edited 2014-09-01 23:10 in Propeller 1
I was playing with some simple code and got some strange results:
dat
              org       0
              mov       dira,   inmask
              test       enmsk,  ina             wz      'check enable
enable   mov       dira,   omask
              mov       outa,   data1                   'output
              jmp       @enable 
   

enmsk         long  %0000_0000_0100
data1         long  $00aa_0000
inmask        long  $0000_0000
omask         long  $00ff_0000
          


With above code on quick start board I get output of $79 even if I change data1 from $AA to $00 or $FF.
I can change Output mask (omask) from $FF to $F0 or $0F and it turns off upper/ lower nibble.
I call enable so I thought it will go to that label and ignore first two lines. Not so!

[data]
pub Main
repeat
cognew(@enable,0)


dat
org 0
enable mov dira, inmask
test enmsk, ina wz 'check enable
mov dira, omask
mov outa, data1 'output
jmp @enable


enmsk long %0000_0000_0100
data1 long $00aa_0000
inmask long $0000_0000
omask long $00ff_0000

[/data]

After I move label up all starts working OK. I just don't get why I get $79?

Comments

  • gwkaubgwkaub Posts: 10
    edited 2014-08-31 00:40
    OOPS!
     pub Main
      repeat
        cognew(@enable,0)
    
    
     dat
                  org       0
     enable    mov       dira,   inmask
                  test      enmsk,  ina             wz      'check enable
                  mov       dira,   omask
                  mov       outa,   data1                   'output
                  jmp       @enable
    
    
     enmsk         long  %0000_0000_0100
     data1         long  $00aa_0000
     inmask        long  $0000_0000
     omask         long  $00ff_0000
    
    

    After I move label up all starts working OK. I just don't get why I get $79?
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 00:55
    Shouldn't that be:
            jmp     #enable
    
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 01:03
    Also you never call enable. You are using enable twice:

    1) You call "cognew" and give it "enable" as the address. The Prop loads code from that address into a new COG and runs it.

    2) You jmp to "enable" (should be #enable) within your PASM code forming a loop.

    You are calling cognew in an endless repeat loop so that will start 7 COGs with the same code and then fail repeatedly.

    Clearly those two lines in front of the "enable" do not get loaded to COG and cannot be run.

    Those 7 COGs will all be using the same pins so they are writing over each others outputs. I guess that is not noticed when running this program.

    I think that cognew should have an @ in front of "enable"
  • Mark_TMark_T Posts: 1,981
    edited 2014-08-31 02:09
    Try
    pub Main
      cognew (@enable, 0)  ' start one cog
      repeat               ' loop forever
    
  • gwkaubgwkaub Posts: 10
    edited 2014-08-31 02:46
    The Prop manual Assemembly reference Pg. 346 @ Address of symbol, actually both @ and # work.
    Repeat cognew OOP! got me on that one. I was playing around and got that left In.
    pub Main
       cognew(@enable,0)
    
    dat
                  org       0
                  mov       dira,   inmask
                  test      enmsk,  ina             wz      'check enable
    enable        mov       dira,   omask
            if_z  mov       outa,   data1                   'output
            if_nz mov       outa,   data2
                  jmp       #enable
        
    
    enmsk         long  %0000_0000_0100
    data1         long  $00aa_0000
    data2         long  $0055_0000    
    inmask        long  $0000_0000
    omask         long  $00ff_0000
    
    If the first two lines of code get skipped we should see data1 or data2 out depending on Z flag.
    Comment out the two lines and it works. It doesn't do what one would think.
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 03:05
    Read you manual again. But this time remember that there are two kinds of addresses being talked about here. There is the location of things withing HUB RAM. Use @ for that. Then there is the location withing COG of things, use # for that.

    Using @ in PASM will drive you crazy as it never seems to what users want and seems to be totally broken to me. We can talk about that when when you get to it.

    Things may appear to work when you use the wrong address. But problems may show up when you add more code to your program. For example that "jmp @enable" you had may well work now. It clearly jumps somewhere in COG. But the COG is full of the 496 you loaded to it at cognew time. In you small example most of that is probably NOP. Which will execute, do nothing and eventually execution runs through all the NOPs in your COG and ends up at your "enter" label again. It works! That is until you add more stuff to your program which is no longer NOPs.
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 03:18
    It may not do what you expect, one may have a different idea :)

    I can't remember exactly but I think
    test      ina, enmask 
    
    Might work better.
    test      enmsk,  ina 
    

    Also, why do you only test that input on start up and not in the loop. And why change the dira after start up?
  • kuronekokuroneko Posts: 3,623
    edited 2014-08-31 03:23
    gwkaub wrote: »
    pub Main
       cognew(@enable,0)
    
    dat
                  org       0
                  [COLOR="#FF8C00"]mov       dira,   inmask
                  test      enmsk,  ina             wz[/COLOR]      'check enable
    enable        mov       dira,   omask
            if_z  mov       outa,   data1                   'output
            if_nz mov       outa,   data2
                  jmp       #enable
    
    enmsk         long  %0000_0000_0100
    data1         long  $00aa_0000
    data2         long  $0055_0000    
    inmask        long  $0000_0000
    omask         long  $00ff_0000
    
    cognew will load code starting at @enable which means mov and test never make it into the cog. Because of this all your data references are wrong (off by 2), e.g. omask is cog index 10 (relative to org 0) which is therefore filled with the long located 2 longs after omask in hub RAM.
    org       0
                      mov       dira,   inmask
                      test      enmsk,  ina wz                  'check enable
    000 enable        mov       dira,   omask
    001         if_z  mov       outa,   data1                   'output
    002         if_nz mov       outa,   data2
    003               jmp       #enable
        
    
    004 enmsk         long  %0000_0000_0100
    005 data1         long  $00aa_0000
    006 data2         long  $0055_0000    
    007 inmask        long  $0000_0000
    008 omask         long  $00ff_0000
    
    009               ???
    00A               ???
    
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 03:32
    kuroneko,

    Quite so. I should have been more explicit above. Those first two instructions are never loaded to COG as I said.
    pub Main
       cognew(@enter,0)
    
    dat
                  org       0
    enter
                  ' Bla bla whatever should
                  ' be for done initialization
    loop
                  ' Bla bla whatever should
                  ' be done in a loop
                  jmp       #loop  
    
    Would be the more normal way to organize things.
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-08-31 09:22
    Heater, test ina, enmask is dead wrong, ina should only ever be used as a source, never a destination... at least I've never seen it used intentionally as a dest. Even wrlong ina,hub_address writes the shadow register.


    Putting all of the suggestions together, plus some suggestions from me, should make it look something like this:
    dat                     org
    entry
    '             mov       dira,   inmask                  ' all pins are inputs on startup
                  mov       dira,   omask                   ' omask sets different pins than are being looked at with enmsk, so there's no problem initializing them as outputs 
    :loop
                  test      enmsk,  ina             wz      ' check enable
            if_z  mov       outa,   data1                   ' set output pattern to $AA if enable is not high      
            if_nz mov       outa,   data2
                  jmp       #:loop
    
    enmsk         long      |< 3                            ' decode value 3 into %100
    data1         long      $AA << 16                       ' shift $AA left 16 bits to $00AA_0000
    data2         long      $55 << 16
    'inmask       long      0                               
    omask         long      $FF << 16
    
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 09:51
    Chris,

    Yeah, thanks, I always get those backwards and it's a while since I wrote any PASM.

    Why are you setting dira twice at start up?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-08-31 10:01
    heater wrote:
    Why are you setting dira twice at start up?

    Ditto that question. First of all, all pins are inputs by default when the cog starts, until set to outputs. Second, there's no such thing as separate input and output masks. There's just one mask that gets written to dira, and which defines the pin directions. Third, the state of any pin that's defined as an output can also be read via ina.

    -Phil
  • gwkaubgwkaub Posts: 10
    edited 2014-08-31 14:09
    First of all thanks for all the help.
    I know we have only one DIRA ,but I was going to use 8 pins as input and output.
    I just predefined two masks to switch them. Now I see set as out, but read as inputs?
    Will that work or am I reading output status? PASM has some strange operations.
    thanks again
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-08-31 14:39
    Heater. wrote: »
    Chris,

    Yeah, thanks, I always get those backwards and it's a while since I wrote any PASM.

    Why are you setting dira twice at start up?
    Was that for me? If you'll look closely, the ' mov dira, inmask is commented out. I kept the line so that I'd have something to comment regarding pins starting as inputs.

    gwkaub, any bit that is set in dira is an output, any bit that is clear is an input*. Reading dira will reflect which are inputs and outputs. Likewise with outa. Setting bits in outa causes the Prop to attempt to output a high, and reading outa will reflect which pins are set high or low. Note that outa only shows the intended levels on the pins. A high output shorted to ground or a low output shorted to Vcc will still be read in outa as the desired levels rather than the actual levels. Connecting pins directly to Vcc or ground is obviously something to be avoided.
    Ina shows the actual levels on the pins, regardless of whether the pins are inputs or outputs.

    To reiterate:
    mov dira, #%1100 sets pins 3 and 2 as outputs, pins 1 and 0 remain inputs.
    mov outa, #%1010 sets pins 3 and 1 as highs, and 2 and 0 as lows, but due to dira, only pins 3 and 2 are affected.
    mov t1, ina copies the state of all 32 pins into t1. Assuming there aren't any shorts to Vcc or ground, bits 3 and 2 show the the output levels, all other bits show the state of any external levels on those pins. It's also typically frowned upon to leave any inputs floating; want to either bias them high or low with pullup or pulldown resistors.

    * Things get more complicated when dealing with multiple cogs. A pin will be an output if any cog sets it as output in dira. A pin will be high if any cog that has it set as an output also has it set as a high in outa.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-08-31 17:55
    To set and clear pins defined by a pinmask, assuming the same bits in dira are set:
            or      outa,pinmask  'Set selected pins (defined by 1's in pinmask).
            andn    outa,pinmask  'Clear selected pins (same pinmask as above).  
    

    -Phil
  • Heater.Heater. Posts: 21,230
    edited 2014-08-31 22:25
    Chris,
    Was that for me? If you'll look closely, the ' mov dira, inmask is commented out.
    So it is. Sorry. Didn't notice that fly spec of a comment tick among all the other bits of dust on my monitor. Never did like that commenting style of spin. Nor the curly brace style, that really irks a C/C++/Java/JavaScript programmer.
  • ChrisGaddChrisGadd Posts: 310
    edited 2014-09-01 07:20
    No prob. It's one of the things I love about the Propeller tool, how it changes the color of commented lines.
  • jazzedjazzed Posts: 11,803
    edited 2014-09-01 08:24
    Heater. wrote: »
    Never did like that commenting style of spin. Nor the curly brace style, that really irks a C/C++/Java/JavaScript programmer.


    I think that was intentional .... at one time.

    One of our esteemed VIPs even said once (paraphrased) that Parallax only really needed one type of customer.
  • ElectrodudeElectrodude Posts: 1,658
    edited 2014-09-01 10:49
    Heater. wrote: »
    Nor the curly brace style, that really irks a C/C++/Java/JavaScript programmer.
    I never even notice it unless I'm not using BST i.e. there's no syntax highlighting.
  • Heater.Heater. Posts: 21,230
    edited 2014-09-01 11:10
    Which posses an interesting question:

    Why are not code snippets posted in the forum syntax highlighted?

    There have been HTML highlighters for all kinds of languages on the net for ages. There are highlighters for Spin.

    Why are they not used here?
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-09-01 13:09
    Didn't somebody once post a link to a CGI script he had written that added BBcode highlighting to Spin code?

    -Phil
  • ElectrodudeElectrodude Posts: 1,658
    edited 2014-09-01 13:13
    @PhiPi
    Was it this?

    EDIT: the links to the plugins there are dead. archive.org/web/ doesn't have it either. Anyone have a copy? I want it and need the Firefox version.
  • msrobotsmsrobots Posts: 3,709
    edited 2014-09-01 23:10
    Just use PHP Instead of CODE tags...
    dat                     org
    entry
    '             mov       dira,   inmask                  ' all pins are inputs on startup
                  mov       dira,   omask                   ' omask sets different pins than are being looked at with enmsk, so there's no problem initializing them as outputs 
    :loop
                  test      enmsk,  ina             wz      ' check enable
            if_z  mov       outa,   data1                   ' set output pattern to $AA if enable is not high      
            if_nz mov       outa,   data2
                  jmp       #:loop
    
    enmsk         long      |< 3                            ' decode value 3 into 0
    data1         long      $AA << 16                       ' shift $AA left 16 bits to $00AA_0000
    data2         long      $55 << 16
    'inmask       long      0                               
    omask         long      $FF << 16
    

    [php]
    dat org
    entry
    ' mov dira, inmask ' all pins are inputs on startup
    mov dira, omask ' omask sets different pins than are being looked at with enmsk, so there's no problem initializing them as outputs
    :loop
    test enmsk, ina wz ' check enable
    if_z mov outa, data1 ' set output pattern to $AA if enable is not high
    if_nz mov outa, data2
    jmp #:loop

    enmsk long |< 3 ' decode value 3 into 0
    data1 long $AA << 16 ' shift $AA left 16 bits to $00AA_0000
    data2 long $55 << 16
    'inmask long 0
    omask long $FF << 16
    [/php]

    makes things look better ... somehow ...

    Enjoy!

    Mike
Sign In or Register to comment.