Shop OBEX P1 Docs P2 Docs Learn Events
A little Propeller Pasm fun tied up in yet another puzzle - novice — Parallax Forums

A little Propeller Pasm fun tied up in yet another puzzle - novice

Beau SchwabeBeau Schwabe Posts: 6,568
edited 2010-09-09 08:57 in Propeller 1
There is a fair amount of FUN-damental Pasm going on here, and I leave it to you to exercise your mind to realize it for yourself.

{{

Uses Propeller Demo Board LEDs

}}
PUB PAsm
    cognew(@Entry,0)        


DAT
Entry
              mov       dira,                   LED_mask
              or        MainLoop,               temp1
              or        NoEnd,                  temp1
              or        Jump1,                  temp1
              andn      MainLoop,               temp2                             

''#################################################################################################
''#################################################################################################

''      This the only line that you need to change.  What happens when you comment it and why? 

              nop

''#################################################################################################
''#################################################################################################


MainLoop      jmp       AlternativeJump                       
              mov       outa,     LED_Pattern1
Jump1         jmp       NoEnd             

AlternativeJump
              mov       outa,     LED_Pattern2

NoEnd         jmp       NoEnd           

LED_mask      long      %11111111<<$10

LED_Pattern1  long      %11100111<<$10
LED_Pattern2  long      %10110011<<$10

temp1         long      1<<$16
temp2         long      $F<<$12

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2010-09-08 22:38
    FUN-tastic! :)
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-09-08 22:47
    kuroneko,

    Here is a way to get rid of the 'nop' ... commentary now applies to the 'andn' instruction.

    I should have titled this "jumping without using #'s" :smilewinkgrin:



    {{
    
    Uses Propeller Demo Board LEDs
    
    }}
    PUB PAsm
        cognew(@Entry,0)        
    
    
    DAT
    Entry
                  mov       dira,                   LED_mask
                  or        MainLoop,               temp1
                  andn      MainLoop,               temp2              
                  or        NoEnd,                  temp1
                  or        Jump1,                  temp1
    
    MainLoop      jmp       AlternativeJump                       
                  mov       outa,     LED_Pattern1
    Jump1         jmp       NoEnd             
    
    AlternativeJump
                  mov       outa,     LED_Pattern2
    
    NoEnd         jmp       NoEnd           
    
    LED_mask      long      %11111111<<$10
    
    LED_Pattern1  long      %11100111<<$10
    LED_Pattern2  long      %10110011<<$10
    
    temp1         long      1<<$16
    temp2         long      $F<<$12
    
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-08 22:52
    ... still with you :) Let's hear some novice opinions though!
    I should have titled this "jumping without using #'s" :smilewinkgrin:
    Another vote for editable thread titles!
  • jmspaggijmspaggi Posts: 629
    edited 2010-09-09 04:04
    Hi Beau,

    Can you please comment this code line by line?

    For me, this will "simply" crash....
    DAT
    Entry
                  mov       dira,                   LED_mask
                  or        MainLoop,               temp1
                  or        NoEnd,                  temp1
                  or        Jump1,                  temp1
                  andn      MainLoop,               temp2        
    
    MainLoop, NoEnd and Jump1 contain the address of those locations in the code. If you modify them jump on jmp NoEnd, you never know where you will land since NoEnd can be different each time you adjust you code?

    JM
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-09 06:25
    jmspaggi wrote: »
    DAT
    Entry
                  mov       dira,                   LED_mask
                  or        MainLoop,               temp1
                  or        NoEnd,                  temp1
                  or        Jump1,                  temp1
                  andn      MainLoop,               temp2        
    
    MainLoop, NoEnd and Jump1 contain the address of those locations in the code.

    So what do you think happens when or MainLoop, temp1 is executed?

    Based on the top posting, MainLoop is a label/name for cog register $006 holding the value $5C3C0009.
  • jmspaggijmspaggi Posts: 629
    edited 2010-09-09 06:51
    $5C3C0009 or 1<<$16 =
    01011100001111000000000000001001 or
    00000000010000000000000000000000
    01011100011111000000000000001001 = $5C7C0009

    So now, the address pointed by MainLoop is no more the same and point somewhere else.

    I now have to apply the andn.
    temp2=$F<<$12=1111000000000000000000
    NOT temp2=0000111111111111111111

    01011100011111000000000000001001 and
    00000000000000111111111111111111 =
    00000000000000000000000000001001 = 5

    So now, instead of try to jump to cog register $006, it's trying to jump to cog register $005.

    Honestly, I really don't understand that :( It should still not be working.

    JM
  • kuronekokuroneko Posts: 3,623
    edited 2010-09-09 07:01
    jmspaggi wrote: »
    $5C3C0009 or 1<<$16 =
    01011100001111000000000000001001 or
    00000000010000000000000000000000
    01011100011111000000000000001001 = $5C7C0009

    So now, the address pointed by MainLoop is no more the same and point somewhere else.
    MainLoop is still register $006 with a new value, namely $5C7C0009. The or operation just changed the content of register $006.
    jmspaggi wrote: »
    I now have to apply the andn.
    temp2=$F<<$12=1111000000000000000000
    NOT temp2=111111110000111111111111111111
    Cog registers are 32bit, so you have to include the top bits as well.
    jmspaggi wrote: »
    01011100011111000000000000001001 and
    11111111110000111111111111111111 =
    01011100010000000000000000001001 = $5C400009

    So now, instead of try to jump to cog register $006, it's trying to jump to cog register $005.
    Again, MainLoop hasn't changed (it's still $006), just its content. What said content means - once program execution reaches that point - is for you to figure out :)
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2010-09-09 08:57
    jmspaggi,

    "Hi Beau,
    Can you please comment this code line by line?"
    DAT
    Entry
                  mov       dira,                   LED_mask
                  or        MainLoop,               temp1
                  or        NoEnd,                  temp1
                  or        Jump1,                  temp1
                  andn      MainLoop,               temp2
    


    ...I can't do that without giving too much away. However I can give a clue.
    Take a look at MainLoop jmp AlternativeJump that is further down in the program.

    Mainloop can be viewed as a variable name (long) with it's contents containing
    the PAsm instruction.

    In fact if you knew for certain what the proper source/destination fields would
    be, you could replace that line with something like...

    Mainloop long %0101110001111100000000sssssssss

    ...where 's' would be the literal address you wanted to jump.


    So what does the PAsm instruction look like? (You can see a hint above)

    Well looking at the 32 bit instruction format for jmp it looks like this...
    -INSTR- ZCRI -CON- -DEST-     -SRC-
     010111 000i  1111  ddddddddd sssssssss
    
    Where:
    's' is the register or the 9-bit literal
    
    'd' in this case is not used and can be anything
    
    'i' gets set depending on if you specify a register
        or 9-bit literal.
    
        0 = register (use the contents of the register)
        1 = 9-bit literal (use the register address)
    
    

    ... notice in the code MainLoop jmp AlternativeJump that I'm specifying a
    'register' and NOT a '9-bit literal' value.

    Ok, so by itself, that line of code would be dangerous and jump somewhere
    completely undetermined, leading to the common gotcha with using the # that
    has bitten us all.

    However, look further up in the code where you see or MainLoop, temp1

    This line of code basically forces the 'i' to be a logical 1 and that's all
    it does. None of the other 31 bits are affected.

    remember...
    'i' gets set depending on if you specify a register or 9-bit literal.

    By forcing it to a 1, we are telling it to be a literal. This eliminates
    the dangerous 'blind jump' that might otherwise be possible.

    This should provide clues to what the remainder of the program is doing. If
    not just ask, this is an academic puzzle and I really hope people looking at
    this have that "ah ha!" moment. :smilewinkgrin:
Sign In or Register to comment.