Shop OBEX P1 Docs P2 Docs Learn Events
How to use LOOKUP with a DAT segment list? — Parallax Forums

How to use LOOKUP with a DAT segment list?

Larry MartinLarry Martin Posts: 94
edited 2008-06-27 01:17 in Propeller 1
I am trying to use Lookup to verify that an incoming opcode is in the list of allowable opcodes, and am not getting the right syntax to make it work.

Here is my code (bear with me on indentation):

DAT
_HostOpcodes byte "QOVRrMmSsTtPpLKG", 0

OBJ
Host : "FullDuplexSerial"

PUB HPS_Opcode(p_byte) | ok
ok := lookup(p_byte: _HostOpcodes)
Host.str(string(13,10,"HPS_Opcode: "))
Host.hex(p_byte, 2)
Host.tx($20)
Host.dec(ok)
DumpMemoryToHost(@_HostOpcodes, 16)
if lookup(p_byte: _HostOpcodes) > 0
RESULT := TRUE
elseif lookup(CharToUpper(p_byte): _hex) > 0
RESULT := TRUE
else
RESULT := FALSE

And here is the terminal output from entering a 'V', which is third in the list:

HostProcessSerial: 56 0
HPS_Opcode: 56 0
00000124 51 4F 56 52 72 4D 6D 53 73 54 74 50 70 4C 4B 47

Note that lookup(p_byte: _HostOpcodes) returned 0, as do:
lookup(p_byte: @_HostOpcodes)
lookup(p_byte: $51, $4F, $56 )

The last one looks like the book examples, but still doesn't work.

Can anyone spot my mistake?

Thanks,
Larry

Comments

  • hippyhippy Posts: 1,981
    edited 2008-06-26 03:44
    I'd guess that "ok := lookup(p_byte: _HostOpcodes)" creates just a single item lookup, not a lookup of the list of characters/bytes you stored at _HostOpcodes.

    Why "lookup(p_byte: $51, $4F, $56 )" doesn't work I'd put down to p_byte not having the value of any of the numbers in that lookup ( although it's not clear where you put that test lookup in your code ). You could change "Host.hex(p_byte, 2)" to "Host.hex(p_byte, 8)" to ensure there aren't any upper bits being set in p_byte confusing things.

    PS : add [noparse][[/noparse] code ] and [noparse][[/noparse] /code ] ( no spaces ) around code to show your indentation.
  • Larry MartinLarry Martin Posts: 94
    edited 2008-06-26 12:43
    The p_byte value I was looking up in the example was $56, the third item in the list. I tried using pbyte[noparse][[/noparse]0] in case some upper bits were set, but that failed too.

    I ended up just writing a function that does the lookup, so I'm good for now.

    Is it possible to see the PASM implementation of LOOKUP? That might help me understand the semantics.


    Thanks,
    Larry

    PS Thanks for the [noparse][[/noparse]code] tip
  • Mike GreenMike Green Posts: 23,101
    edited 2008-06-26 13:37
    Spin is compiled into "byte code", not assembly. The definition of the byte codes and the source of the interpreter are available.

    Source: http://forums.parallax.com/showthread.php?p=711386
  • hippyhippy Posts: 1,981
    edited 2008-06-26 17:24
    Attached is the bytecode disassembly of

    DAT
      _HostOpcodes byte "QOVRrMmSsTtPpLKG", 0
    
    PUB HPS_Opcode(p_byte) | ok
      ok := lookup(p_byte: _HostOpcodes)
    
    
    



    As guessed, that generates a one item lookup. It should match the first entry ($51/"Q") but not any others.
  • Larry MartinLarry Martin Posts: 94
    edited 2008-06-26 21:31
    Thanks for all that info. Like I said, I have a workaround for now. Will study these examples later.
  • Larry MartinLarry Martin Posts: 94
    edited 2008-06-26 22:54
    LOOKUP does not seem to be working for me in any form.

    This program, which exercises all the permutations suggested today (thanks, guys):

    DAT
      _crlf byte 13, 10, 0
      _HostOpcodes  byte "QOVRrMmSsTtPpLKG", 0
      _HostOpcodes2 byte "VRrMmSsTtPpLKG", 0
    
    
    CON
      _CLKMODE = XTAL1 + PLL8X
      _XINFREQ = 5_000_000
      pLLIOHostTx                  = 0
      pLLIOHostRx                  = 1
    
    OBJ
      Host : "FullDuplexSerial"
    
    PUB Lookup | p_byte
      Host.start(pLLIOHostRx, pLLIOHostTx, 0, 57600)
      p_byte := $56 ' V
      Host.hex(p_byte,8)
      Host.tx($20)
      Host.dec(lookup(p_byte: $56, $51))           ' should be 1
      Host.tx($20)
      Host.dec(lookup(p_byte: $51, $56))           ' should be 2
      Host.tx($20)
      Host.dec(lookup(p_byte: _HostOpcodes))    ' Q first, should fail (0)
      Host.tx($20)
      Host.dec(lookup(p_byte: _HostOpcodes2))  ' V first, should succeed (1)
      Host.tx($20)
      Host.dec(lookup(p_byte: @_HostOpcodes)) ' DAT array, should be 3
      Host.str(@_crlf)
      'Line 2, try just lowest byte
      Host.hex(p_byte[noparse][[/noparse]0],8)
      Host.tx($20)
      Host.dec(lookup(p_byte[noparse][[/noparse]0]: $56, $51))
      Host.tx($20)
      Host.dec(lookup(p_byte[noparse][[/noparse]0]: $51, $56))
      Host.tx($20)
      Host.dec(lookup(p_byte[noparse][[/noparse]0]: _HostOpcodes))
      Host.tx($20)
      Host.dec(lookup(p_byte[noparse][[/noparse]0]: _HostOpcodes2))
      Host.tx($20)
      Host.dec(lookup(p_byte[noparse][[/noparse]0]: @_HostOpcodes))
      Host.str(@_crlf)
      waitcnt (CLKFREQ + cnt)                                'make sure port stays open long enough to shift out
    
    
    



    creates this output:

    00000056 0 0 0 0 0
    00000056 0 0 0 0 0

    Since I am using LOOKUP, not lookupZ, that means it's all errors, right?

    Same thing happens with Propeller Tool and Propellent (both v1.1)

    I'm going to try and understand the PASM now, and maybe learn something about the system. Thanks to Hippy and Mike Green. Will post anything I learn.
  • Larry MartinLarry Martin Posts: 94
    edited 2008-06-26 23:00
    Got it. I had the semantics backwards.

    Lookup gets the value from the list at the given index. I was trying to get the index of the given value.

    Guess I needed a function after all.

    Hippy, Mike, thanks for your help, sorry for wasting time.

    Larry
  • Mike GreenMike Green Posts: 23,101
    edited 2008-06-26 23:09
    Have a glance at the LOOKDOWN statement.
  • hippyhippy Posts: 1,981
    edited 2008-06-26 23:59
    I'd made the same mistake myself, confusing lookup with lookdown.
  • Larry MartinLarry Martin Posts: 94
    edited 2008-06-27 01:17
    Thanks, Mike. LookDOWN was what I wanted. But now I'm back to the original question:

    DAT
      _crlf byte 13, 10, 0
      _HostOpcodes  byte "QOVRrMmSsTtPpLKG", 0
      _HostOpcodes2 byte "VRrMmSsTtPpLKG", 0
    
    
    CON
      _CLKMODE = XTAL1 + PLL8X
      _XINFREQ = 5_000_000
      pLLIOHostTx                  = 0
      pLLIOHostRx                  = 1
      pLLIOSerialPassthrough       = 2
      pLLIOGapIn                   = 3
      pLLIOStopOut                 = 4
      pLLIOMarkOut                 = 5
      pLLIOOverrunOut              = 6
      pLLIOBadOut                  = 7
      pLLIOGoodOut                 = 10
      pLLIOTargetRx                = 17
      pLLIOTargetTx                = 18
    
    OBJ
      Host : "FullDuplexSerial"
      'Target : "FullDuplexSerial"
    
    PUB Toggle | p_byte
      Host.start(pLLIOHostRx, pLLIOHostTx, 0, 57600)
      p_byte := $56 ' V
      Host.hex(p_byte,8)
      Host.tx($20)
      Host.dec(lookdown(p_byte: $56, $51))
      Host.tx($20)
      Host.dec(lookdown(p_byte: $51, $56))
      Host.tx($20)
      Host.dec(lookdown(p_byte: _HostOpcodes))
      Host.tx($20)
      Host.dec(lookdown(p_byte: _HostOpcodes2))
      Host.tx($20)
      Host.dec(lookdown(p_byte: "QOVRrMmSsTtPpLKG" ))
      Host.tx($20)
      Host.dec(lookdown(p_byte: @_HostOpcodes))
      Host.str(@_crlf)
    
    
    



    Output:
    00000056 1 2 0 1 3 0

    LookDOWN does what I need when the list is included in the function call, but I do this in several places and don't want to encode the list in each function call. I'd really like to have the list centralized, and use it with a pointer (last form).

    The C analogy would be "if (strchr(_HostOpcodes, p_byte)){do_stuff();}"

    Can that be done with Lookdown?
Sign In or Register to comment.