;This code contains a fixed-string lexer which searches a ;stream of characters for any number of strings. ;This code is in the public domain, so it comes with no ;warranty of any kind. I hope you find it useful, despite ;some of the limitations. -- Paul, paul@ece.orst.edu ;for each string, you need to dedicate one byte of internal ;memory. Make sure the stack doesn't grow on top of these... ;these are only used with indirect addressing, so you can ;make use of the other 128 bytes of ram in the 8052 which ;can only be used with indirect addressing. Remember that ;that R0 to R7 use memory locations between 0 to 1F, depending ;on which bank you have selected. .equ c_binary, 0x27 .equ c_ascii, 0x28 .equ c_fast, 0x29 .equ c_medium, 0x2A .equ c_slow, 0x2B ;before you start, be sure to load these memory locations ;up with zeros begin: clr a mov r0, #c_binary mov @r0, a mov r0, #c_ascii mov @r0, a mov r0, #c_fast mov @r0, a mov r0, #c_medium mov @r0, a mov r0, #c_slow mov @r0, a ;the main program loop. You just check for an incoming character, ;and when you have one, jump to the code. You put your program ;in the section after "main2". Alternately, your program could ;check for I/O and call to "key1" when it has some time to spare. main: jnb ri, main2 acall keypress main2: ;insert your program here. ljmp main ;so now that you've got a character from the input stream, you ;need to supply a little block of code for each string you want ;to detect keypress: ;handle incoming data from serial port mov r2, sbuf clr ri ;each block of code just loads dptr with the location of the ;string you want to find, r0 with the location of the internal ;ram location you reserved earlier, and calls to the lexer code, ;which does all the hard work. If the carry is set, then it ;detected the string, otherwise you continue the process for ;every string you want... key1: mov dptr, #binary mov r0, #c_binary acall lexer jnc key2 ;insert action for "binary" here ret key2: mov dptr, #ascii mov r0, #c_ascii acall lexer jnc key3 ;insert action for "ascii" here ret key3: mov dptr, #fast mov r0, #c_fast acall lexer jnc key4 ;insert action for "fast" here ret key4: mov dptr, #medium mov r0, #c_medium acall lexer jnc key5 ;insert action for "medium" here ret key5: mov dptr, #slow mov r0, #c_slow acall lexer jnc key6 ;insert action for "slow" here ret key6: ret ;these are the strings that the lexer will search for in the ;incoming data stream. Each string must have it's length ;defined as a byte at the beginning, as shown. Obviously ;the lexer is limited to looking for strings less than 256 ;characters long. binary: .db 6, "binary" ascii: .db 5, "ascii" fast: .db 4, "fast" medium: .db 6, "medium" slow: .db 4, "slow" ;A simple fixed-string lexer. For each character received from an ;input stream, this routine is called once for every string which ;is to be recognized within the input stream. ; Input registers: ; r0 Memory location to the index variable for this ; particular string. ; r2 The character we received. ; dptr Pointer to the string pattern we want to match. ; Output registers: ; c Carry set if complete string found, clear if no match yet. ; mem Value @r0 adjusted appropriately for the next call. lexer: mov a, @r0 inc a ;don't look at length byte movc a, @a+dptr ;get character from string clr c subb a, r2 jnz lex_nope ;at this point, it matches the string, so now ;the question becomes "are we at the end?" inc @r0 ;advance index clr a movc a, @a+dptr ;get string length clr c subb a, @r0 ;subtract index jz lex_match ;we're not at the end of the string yet clr c ret lex_match: ;we've found all of the string now mov @r0, a ;reset index automatically setb c ret lex_nope: ;the received character doesn't match the string ;so we set the index back to zero, and return with ;carry clear mov @r0, #0 clr c ret