Shop OBEX P1 Docs P2 Docs Learn Events
PASM version of LOOKDOWNZ? — Parallax Forums

PASM version of LOOKDOWNZ?

JonnyMacJonnyMac Posts: 9,108
edited 2012-10-12 17:51 in Propeller 1
In Spin I would do this:

setup := lookdownz(ch: %1100, %1110, %1101, %1111)



This is what I'm doing in PASM -- is there a better (more effective/efficient) way?

chloop                  and     ch, #%11                        ' keep 0..3
                        cmp     ch, #0                  wz
                if_e    mov     setup, #%1100
                if_e    jmp     #muxbits
                        cmp     ch, #1                  wz
                if_e    mov     setup, #%1110
                if_e    jmp     #muxbits
                        cmp     ch, #2                  wz
                if_e    mov     setup, #%1101
                if_e    jmp     #muxbits
                        mov     setup, #%1111

muxbits

Comments

  • lonesocklonesock Posts: 917
    edited 2009-05-18 17:35
    Maybe try this?

    mov setup, ch
    rev setup, #30
    or setup, #%1100
    jmp     #muxbits
    
    



    edited: sorry, left out the main jmp

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2009-05-18 17:47
    Very cool -- thank you!
  • lonesocklonesock Posts: 917
    edited 2009-05-18 18:02
    JonnyMac said...
    Very cool -- thank you!
    Sure, no problem. By the way, since you modify both of the variables "ch" & "setup", you could remove the extra "mov" instruction if you modified #muxbits to just use "ch" directly.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2009-05-18 19:26
    Well, ch needs to stand alone as it's being used as an index into an array.

    The trick works great with the mux bits for the ADC0834, but not with the ADC0838 (as I can see now). I looked at the way SX/B compiles LOOKDOWN and came up with this PASM equivalent for the ADC0838; seems to work but is brute force. Is there a better way? Speed is not an issue at all.

    mloop                   andn    outa, csMask                    ' activate adc (/CS = 0)
                            and     ch, #%111                       ' keep ch legal, 0 to 7
                            mov     setup, #%11000                  ' assume ch0
                            cmp     ch, #0                  wz      ' test
                    if_e    jmp     #muxbits
                            mov     setup, #%11100                  ' assume ch1
                            cmp     ch, #1                  wz      ' test
                    if_e    jmp     #muxbits                
                            mov     setup, #%11001                  ' assume ch2
                            cmp     ch, #2                  wz      ' test
                    if_e    jmp     #muxbits
                            mov     setup, #%11101                  ' assume ch3
                            cmp     ch, #3                  wz      ' test
                    if_e    jmp     #muxbits
                            mov     setup, #%11010                  ' assume ch4
                            cmp     ch, #4                  wz      ' test
                    if_e    jmp     #muxbits
                            mov     setup, #%11110                  ' assume ch5
                            cmp     ch, #5                  wz      ' test
                    if_e    jmp     #muxbits                
                            mov     setup, #%11011                  ' assume ch6
                            cmp     ch, #6                  wz      ' test
                    if_e    jmp     #muxbits
                            mov     setup, #%11111                  ' must be ch7                                 
    
    muxbits                 or      dira, dioMask                   ' make dio an output
    
  • lonesocklonesock Posts: 917
    edited 2009-05-18 20:10
    Sure. The original version I gave you was specific to that one mapping. As you can see, the ADC0838 seems to count up in binary, but the bits are out of order. The 1's bit is in what would normally be the 4's bit. The 2's bit is in what would normally be the 1's bit, and the 4's bit is where the 2's bit would normally be. So, you can do the following:

    ' start with the high bits, which never change
    mov setup, #%11000
    
    ' if the 1's bit is set in ch, set it in setup
    test ch, #%001 wc
    muxc setup, #%100
    
    ' if the 2's bit is set in ch, set it in setup
    test ch, #%010 wc
    muxc setup, #%001
    
    ' if the 4's bit is set in ch, set it in setup
    test ch, #%100 wc
    muxc setup, #%010
    
    ' and do the jump
    jmp     #muxbits 
    
    



    I _think_ that should work.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2009-05-18 22:05
    Jon,

    As long as the bits just need order swapping then either lonesock's method or the method below will work... either way it comes out to the same number of instructions.


                                   ' setup                                     ch     Cflag        
            mov     setup, #%11    '%...11   %........_........_........_.....abc         ?             
            ror     ch,    #2   wc '%...11   %bc......_........_........_.......a         c 
            rcl     setup, #1      '%..11c   %bc......_........_........_.......a         c 
            ror     ch,    #31  wc '%..11c   %c......._........_........_......ab         a
            rcl     setup, #1      '%.11ca   %c......._........_........_......ab         a
            ror     ch,    #31  wc '%.11ca   %........_........_........_.....abc         b
            rcl     setup, #1      '%11cab   %........_........_........_.....abc         b                                                                                
                                                                                
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 5/18/2009 10:13:03 PM GMT
  • lonesocklonesock Posts: 917
    edited 2009-05-18 22:43
    Again, as a "works for this mapping only", you could do the following:

    ' copy in the channel information
    mov setup, ch
    
    ' shift the 2's bit and the 4's bit one place to the right, while storing the 1's bit in C
    shr setup, #1 wc
    
    ' mask off what we're interested in
    and setup, #%011
    
    ' add the 1's bit back in to the 4's place
    muxc setup, #%100
    
    ' set the high bits
    or setup, #%11000
    
    ' do the jump
    jmp #muxbits
    
    



    It saves a few instructions, but the readability goes way down [noparse][[/noparse]8^)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2009-05-18 23:59
    Thanks, again; I really appreciate your feedback.

    Follow-up: I whipped up a quick test program and verified that it works, Jonathan; and, as setup starts clean, I could drop the AND.

    Post Edited (JonnyMac) : 5/19/2009 12:47:37 AM GMT
  • AribaAriba Posts: 2,690
    edited 2009-05-19 01:00
    A more general approach for a lookup table:
            movs lookup,ch
            add  lookup,#table
            nop
    lookup  mov setup,0-0
            ...
    table   long %1100,%1110,%1101,%1111
    
    



    Andy
  • JonnyMacJonnyMac Posts: 9,108
    edited 2009-05-19 01:12
    Thank you, Ariba, that is what I was originally looping for. That said, I'm having trouble getting it to work in my program. Will scour the forum looking for similar code.

    Post Edited (JonnyMac) : 5/19/2009 1:23:14 AM GMT
  • Beau SchwabeBeau Schwabe Posts: 6,566
    edited 2009-05-19 03:15
    John,

    yes, Ariba's approach is going to execute the fastest. The example that he gave though uses a reserved Spin variable 'lookup'
    that might have been causing you some problems. Here is the same code demonstrating the LEDs on the DEMO board.



                  mov       ch,      #3   ' <-change this value from 0 to 3
                  movs look_up,      ch
                  add  look_up,      #table
                  nop
    look_up       movs setup,        0-0
    
    '---------------------------------------------------------------------------------
    '                               This stuff for the LED's
    '---------------------------------------------------------------------------------
                  shl       setup,   #16            '<--Just to see it in on the LED's
                  mov       dira,    LEDmask        'Make the LEDs an output                
                  mov       outa,    setup          'show the data with the LEDs
    '---------------------------------------------------------------------------------
    
    EndlessLoop   jmp       #EndlessLoop
    
    table   long %1100,%1110,%1101,%1111
    
    '-----------------------------------------------------------------------
    
    LEDmask long  %00000000_11111111_00000000_00000000
    ch      long  0
    setup   long  0
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.
  • JonnyMacJonnyMac Posts: 9,108
    edited 2009-05-19 03:53
    Yep, found that (lookup is a keyword) and have my ADC0834 and ADC0838 drivers using the code that Ariba suggested. I'm still very new to PASM and working at getting my head wrapped around self-modifying code. Thanks for the assist, Beau.

    Post Edited (JonnyMac) : 5/19/2009 4:01:11 AM GMT
  • bennettdanbennettdan Posts: 614
    edited 2011-04-04 22:34
    I know this is an old thread but I have a project that could use a lookup table in pasm. The last post by Beau using Ariba's I have a couple of questions about it to see if I am clear about how to use the code.
    "mov ch, #3 ' <-change this value from 0 to 3"
    Does this line of code point to third value from the left in the "#table" which is %1101?

    "add look_up, #table"
    I see this line of code points to the table correct?

    Also if I wanted to make two tables then I could do this?
                  mov       ch,      #3   ' <-change this value from 0 to 3
                  movs look_up,      ch
                  add  look_up,      #table   '<-change this from table to table1
                  nop
    look_up       movs setup,        0-0
    
    '---------------------------------------------------------------------------------
    '                               This stuff for the LED's
    '---------------------------------------------------------------------------------
                  shl       setup,   #16            '<--Just to see it in on the LED's
                  mov       dira,    LEDmask        'Make the LEDs an output                
                  mov       outa,    setup          'show the data with the LEDs
    '---------------------------------------------------------------------------------
    
    EndlessLoop   jmp       #EndlessLoop
    
    table   long %1100,%1110,%1101,%1111
    table1  long %0001,%0011,%0111,%1001
    '-----------------------------------------------------------------------
    
    LEDmask long  %00000000_11111111_00000000_00000000
    ch      long  0
    setup   long  0
    
    
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-04 23:10
    bennettdan wrote: »
    "mov ch, #3 ' <-change this value from 0 to 3"
    Does this line of code point to third value from the left in the "#table" which is %1101?
    This line sets the index into the table. Because it's zero based 3 points to the 4th entry (%1111).
    bennettdan wrote: »
    "add look_up, #table"
    I see this line of code points to the table correct?
    In fact this adds the table base address to the index to form the final element address (base+index).

    If you want more than one table then simply change the base address (i.e. use a different one). You could also merge the tables and adjust the index accordingly. For example in your code fragment using index 4 and base table is equivalent to using index 0 and base table1.
  • bennettdanbennettdan Posts: 614
    edited 2011-04-04 23:27
    kuroneko,
    I see what you are saying about the zero base 3 is the 4th entry.
    So what you are saying is that index 4 ,base adress table is pointing to the same as index 0, base adress table1 which is %0001 this is because the longs are inline correct?
    So as long as they are not seperated with a different long then the index is just added to the base adress of the first long table?
  • kuronekokuroneko Posts: 3,623
    edited 2011-04-04 23:36
    bennettdan wrote: »
    So what you are saying is that index 4 ,base adress table is pointing to the same as index 0, base adress table1 which is %0001 this is because the longs are inline correct?
    If by inline you mean consecutive then yes. If there is something between the two tables (e.g. sub-routines, other data) then it's better to refer to each table explicitly.
    bennettdan wrote: »
    So as long as they are not seperated with a different long then the index is just added to the base adress of the first long table?
    Exactly. You may want to consider using different tables anyway depending on what they are used for. Otherwise you get confused later (after a few month) when you review your code :) Like why is index 4 referring to the first entry?
  • bennettdanbennettdan Posts: 614
    edited 2011-04-04 23:44
    kuroneko,
    Thanks for the help I believe I understand it now.
  • edited 2012-10-12 15:45
    I've been researching arrays in PASM and how to reference individual elements. That naturally led me to self modifying code and this thread. I was wondering about the last line in both pieces of code. Ariba's code has a mov instruction and Beau's code has a movs instruction. Why the difference?

    Ariba's code
                  movs lookup,      ch
                  add  lookup,      #table
                  nop
    lookup        mov  setup,        0-0
    

    Beau's code
                  movs look_up,      ch
                  add  look_up,      #table   '<-change this from table to table1
                  nop
    look_up       movs   setup,      0-0
    

    Sandy
  • kuronekokuroneko Posts: 3,623
    edited 2012-10-12 16:59
    For this particular example it doesn't matter as you are only interested in the lower nibble. It all comes down to what you do with it later on (movs leaves the upper 23 bits of setup unchanged).
  • Mark_TMark_T Posts: 1,981
    edited 2012-10-12 17:51
    If the lookup table fits in a single long you can access packed fields with shifts:
                    shl   ch, #2
                    mov   setup, table
                    shr   setup, ch
                    and   setup, #11
    
    ...
    table           long  11_1101_1110_1100
    
Sign In or Register to comment.