Shop OBEX P1 Docs P2 Docs Learn Events
DCD equivalent in SX/B or a way to access each bit in a loop? — Parallax Forums

DCD equivalent in SX/B or a way to access each bit in a loop?

basicstampedebasicstampede Posts: 214
edited 2008-08-29 19:44 in General Discussion
In BS2, there is a command DCD which returns the highest bit position of 1 in a Byte.

I don't think there is a equivalent in SX/B, but what is a clever way of doing this?

e.g. for %00101111, I want to output %00100000

I tried the below code:

a VAR Byte
b VAR Byte
idx VAR Byte

Main:
··a = %01110000
· FOR idx = 7 to 0
··· b = a.idx
··· LEDs = b
· NEXT·
· GOTO Main

The above code will not compile because of a.idx is invalid.·
Is there a way to sequentially access each bit of a byte variable?
·

Comments

  • JonnyMacJonnyMac Posts: 9,392
    edited 2008-08-29 19:44
    Here's code for NCD (which is what you want) and DCD:

    NCD             FUNC    1, 1, 2
    DCD             FUNC    2, 1
    


    Edit: 12/24/2008: I had a project that required an NCD function so I went back a looked at my code again -- here are better versions of both.

    ' Use: result = NCD value
    ' -- returns position of highest "1" in value
    ' -- 0 (none) to 16 (bit15)
    
    FUNC NCD
      ASM
        SB    __PARAMCNT.1                          ' skip if word
         CLR  __WPARAM12_MSB                        ' clear MSB if byte
        MOV   __PARAM3, #16                         ' initialize position
    
    NCD_Loop:
        JB    __WPARAM12_MSB.7, @NCD_Exit           ' exit if bit is "1"
        CLC                                         '  else shift left
        RL    __WPARAM12_LSB
        RL    __WPARAM12_MSB
        DEC   __PARAM3                              '  and update position
        JNZ   @NCD_Loop                             '  if pos = 0, abort
    
    NCD_Exit:
        MOV   __PARAM1, __PARAM3                    ' return position
      ENDASM
      ENDFUNC
    
    ' -------------------------------------------------------------------------
    
    ' Use: result = DCD bitPos
    ' -- returns 16-bit value based on bitPos (1 to 16)
    ' -- returns 0 if value illegal
    
    FUNC DCD
      ASM
        MOV   __PARAM3, __PARAM1                    ' copy position
        CLR   __WPARAM12_LSB                        ' clear result
        CLR   __WPARAM12_MSB
        DEC   __PARAM3                              ' zero-adjust position
        CJA   __PARAM3, #15, @DCD_Exit              ' abort if illegal
        INC   __WPARAM12_LSB                        ' set bit 0
        TEST  __PARAM3                              ' check for pos 0
        JZ    @DCD_Exit                             '  abort if 0
    
    DCD_Loop:
        CLC                                         ' zero-pad for shift
        RL    __WPARAM12_LSB                        ' shift result
        RL    __WPARAM12_MSB
        DJNZ  __PARAM3, @DCD_Loop                   ' update pos
    
    DCD_Exit:
      ENDASM
      ENDFUNC
    

    Post Edited (JonnyMac) : 12/24/2008 11:32:13 PM GMT
Sign In or Register to comment.