Shop OBEX P1 Docs P2 Docs Learn Events
Special form of ROL and ROR spin instruction with arbitrary length rotate distance? — Parallax Forums

Special form of ROL and ROR spin instruction with arbitrary length rotate distance?

Duane C. JohnsonDuane C. Johnson Posts: 955
edited 2013-01-27 15:58 in Propeller 1
Hi guys;

Anybody have a spin snippet for implementing a variable distance rotate?
The standard spin ROL or ROR only works on the ends of a 32 bit long.
I would like to supply a variable that contains values of 2 to 32 to control the shifts..
I assume one end of the rotate is bit 0.

Extra points for the SHL SHR SAL SAR versions. (Ya I know SAR doesn't exist.)

Even more points if both ends of the shifts can be specified.

Any references or examples?

Thanks guys!!

Duane J

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2013-01-21 21:33
    Not extensively tested but looks like it does the job. Rotation direction is determined by start/end order. If your bit parameters exceed 31..0 then enable the safe-guards. I don't explicitly cover negative n though.
    PUB roxn(value, s, e, n) | distance
    
      distance := ||(s[COLOR="#D3D3D3"]{& 31}[/COLOR]- e[COLOR="#D3D3D3"]{& 31}[/COLOR])
      n //= ++distance
      dirb := value
    
      dirb[s..e] := dirb[s..e] << n | dirb[s..e] >> (distance - n)
    
      return dirb
      
    
  • Duane C. JohnsonDuane C. Johnson Posts: 955
    edited 2013-01-27 11:10
    Hi kuroneko;
    kuroneko wrote: »
    Not extensively tested but looks like it does the job. Rotation direction is determined by start/end order. If your bit parameters exceed 31..0 then enable the safe-guards. I don't explicitly cover negative n though.
    PUB roxn(value, s, e, n) | distance
    
      distance := ||(s[COLOR="#D3D3D3"]{& 31}[/COLOR]- e[COLOR="#D3D3D3"]{& 31}[/COLOR])
      n //= ++distance
      dirb := value
    
      dirb[s..e] := dirb[s..e] << n | dirb[s..e] >> (distance - n)
    
      return dirb
      
    
    Thanks for the quick response.
    I apologize for my slow acknowledgment.

    I just got to the point where I am trying to use your code.

    I can't get it to work. I was assuming the use of DIRB was a trick in my Prop I, which doesn't have a "B" port.
    I can't use DIRA as my "A" port is being used.

    My manual dosn't say I can use the "double dot", "..", operator with regular variables.

    Am I missing something?

    BTW, I'm attempting to add your ROXN command as an extension to the DongleBasic instruction set.

    Thanks!

    Duane J
  • kuronekokuroneko Posts: 3,623
    edited 2013-01-27 15:58
    Using a(n unused) special register is prerequisite for the bit range (the idea here is to avoid all the masking involved when normal variables are used). Just use the method as is, dirb works fine on your Prop I (for this purpose). OTOH, if you tried it with dirb, which part doesn't work?

    POC (demoboard or quickstart)
    PUB null | v
    
      dira[16..23]~~
      v := %10000001
      repeat
        v := roxn(v, 7, 4, 1)       ' left
        v := roxn(v, 0, 3, 1)       ' right
        outa[16..23] := v
        waitcnt(clkfreq/2 + cnt)
    
    PUB roxn([COLOR="#FFA500"]value[/COLOR], s, e, n) | distance
    
      distance := ||(s[COLOR="#D3D3D3"]{& 31}[/COLOR]- e[COLOR="#D3D3D3"]{& 31}[/COLOR])
      n //= ++distance
      [COLOR="#FFA500"]dirb := value[/COLOR]
    
      dirb[s..e] := dirb[s..e] << n | dirb[s..e] >> (distance - n)
    
      return dirb
    
    DAT
    
    Alternatively just post the code section which handles your new command and we go from there.
Sign In or Register to comment.