Match a string in RAM to a table in NVEM.
Consider an Xwire receive data block to be nn bytes of RAM starting at address bb. This instruction seeks to match the data in the block with one or more "canned" strings stored in NVEM. Its primary use is for decoding information that has come in via an Xwire peripheral.
If argument c is zero, the instruction treats upper and lower case letters as equivalent. If c is non-zero, the case of the RAM string must match exactly the string stored in NVEM.
The data in NVEM must be stored in a very specific "NULL terminated" format. This is best illustrated by an example. Lets say we want to detect which fruit has been requested via an Internet interface and transferred into an Xwire receive data block.
First you construct a list of all possible receive strings in NVEM. Each string must be terminated with a 0 byte. The 0 is not part of the string, it merely signals the end of the string (C-style NULL terminated strings).
strOrange: NV0Byte "Orange",13,0
strApple: NV0Byte "Apple",13,0
strBanana: NV0Byte "Banana",13,0
strLemon: NV0Byte "Lemon",13,0
strPear: NV0Byte "Pear",13,0
strGrape: NV0Byte "Grape",13,0
; Terminator _________________^
Next you construct a table, in NVEM, of pointers to the individual strings. This must be terminated in a 255 byte. The 255 is what tells iiStrFind that it has come to the end of the table.
FruitNames: NV0Ptr strOrange ;Entry #1
NV0Ptr strLemon ;Entry #2
NV0Ptr strApple ;Entry #3
NV0Ptr strPear ;Entry #4
NV0Ptr strBanana ;Entry #5
NV0Ptr strGrape ;Entry #6
NV0Byte 255 ;<<<<< Essential!!!
You will notice that the order of entries is different to the order of the strings themselves. They can be in any order you like. You can have several such tables, with different ordering. You can even use different sub-sets of strings at
Before trying to extract or recognize a string, you must know that a string has actually been received. How you do this will depend on the particular source of the data that is being stored in RAM. We cannot therefore provide such detail here. (See COMRx_StrFind to see how it's done for serial data). Here we'll just have example code for defining the Rx data block.:
XWRxBlock defBYTE 30
XWRxBlkLen EQU 30
This is where we use the actual COMRx_StrFind instruction. First we have to make sure the NVEM access is correctly set up.
NVSetPtr FruitNames
NVSetPage 0 ;0 is the default, so playing very safe!
LoadI 0 ;Start the search at the start of the buffer
iiStrFind XWRxBlock,XWRxBlkfLen,0
The COMRx_StrFind returns its result in X, as follows:
X-register contains the number of the entry in the pointer table, counting from 1. Thus, if in this case the received string was "Apple",13, X would contain 3.X will contain 0 (which makes Branch instruction very appropriate).If a match is found, the index register I is incremented to point to the first character in RAM after the string (auto-index).
Branch
Target NoMatch
Target RxOrange
Target RxLemon
Target RxApple
Target RxPear
Target RxBanana
Target RxGrape
RxOrange: ;Do the orange thing ....
RxLemon: ;Do the lemon thing ....
RxApple: ;Do the apple thing ....
RxPear: ;Do the pear thing ....
RxBanana: ;Do the banana thing ....
RxGrape: ;Do the grape thing ....
You would place your own code to respond to each of the strings atRxOrange,RxLemon, etc.
Quite likely you would then go back to waiting for the next incoming message.
I past the characters of any string it matches.I.COMRx_StrFind instruction has very similar behaviour, only it works on data received via the serial port.