Serin (check qualifiers)

determines whether text received by Serin matches a table of qualifiers (password).

Another feature of PBASIC's Serin is the ability to compare incoming serial data to a table of qualifiers. Serin halts program execution until it receives data that exactly matches the qualifiers. This makes it possible to recognize key words in a text stream, or to protect access to a sensitive program.

You can add this capability to Serin using the routine Qualify and a few additional instructions. The listing shows how this works. Rather than present the entire Serin listing again, only the Qualify code appears here. To simulate receiving data with Serin, execute up to the ret at the end of the dummy Serin, then enter a byte at address 01Eh (buffer-1).

 Qualifiers must match the case of the password. "SESAME" is not the same as "Sesame" as far as Qualify is concerned. Also, make sure to turn off the Serin filter flag if your password contains characters outside the range of filt_lo to filt_hi.

Serin and Qualify will wait forever to receive the password sequence. You may add code to count the number of bytes received and give up if the proper sequence is not submitted within a preset number of tries.

Demonstrating Qualify.

To see Qualify in operation, you may run it on the PSIM simulator as suggested in the program listing. For a live demonstration, connect the circuit shown below to an erasable PIC or PIC emulator, such as the Parallax downloader. Program the PIC or downloader with the program assembled from the file SERIN_Q.SRC on the disk. Make sure to use a 4-MHz clock on the PIC or downloader. Load a terminal program on the PC connected to the PIC and set it for 2400 baud, no parity, 8 dat a bits, 1 stop bit (N81). Now type in some numbers and text. Nothing happens until you type the password "Sesame". Then the LED toggles.


; QUALIFY table, string
; Reads a one-character Serin string and looks up the character in 
; a table of "qualifiers." If the character matches the next qualifier, 
; the routine increments a counter and checks to determine whether all 
; qualifiers have been matched. If so, it returns a 1 in w. If not, 
; it returns a 0 in w after resetting the counter to the first item in
; the qualifier list. 

        org     8
qual    ds      1       ; Pointer to qualifiers.
buffer  =       31      ; Serin string address. 

; Device data and reset vector
        device  pic16c55,xt_osc,wdt_off,protect_off
        reset   start
        org     0

P_word  jmp     pc+w
        retw    6       ; No. of elements in password. 
        retw    'Sesame'        ; The password. 

; Below is a dummy Serin routine intended for use on the PSIM simulator. 
; Wait until PSIM reaches the "ret" below, then change the data at buffer-1
; (hex address 1E). You can step through Qualify to see how it works. 
; The password "Sesame" is 53h, 65h, 73h, 61h, 6Dh, 65h. 

Serin   mov     buffer-1,#'A'   ; Dummy Serin for demo. 
        ret             ; Enter character data here. 

start   mov     !ra,#4  ; Input for serial data. 
        mov     !rb, #0 ; All outputs for LEDs
        clr     rb      ; LEDs off to begin.
        clr     qual    ; Clear qual to start. 

:loop   call    Serin   ; Receive one byte. 
        call    Qualify ; Check it against password.
        test    w       ; IF w=1 THEN LEDs_on
        snz             ; ELSE :loop
        jmp     :loop   
        XOR     rb,#255 ; Password match: toggle LEDs. 
        jmp     start   ; Do it again. 

; Upon entry, a one-byte Serin string should be stored at buffer-1. 
; Qualify will check it against the next entry in the P_word table, and 
; if there's a match, will increment the qualifier counter qual. If there's
; no match, it will clear qual, and check the character against the first
; entry in P_word. This second step prevents Qualify from failing to 
; recognize passwords after a false start, like "SeSesame." 

Qualify mov     w,++qual        ; Look up next item in P_word.
        call    P_word
        subwf   buffer-1,0      ; Compare it to received byte by
        jnz     :no_match       ; subtraction. If result <> 0, no match. 
        inc     qual    ; Match: increment qual pointer and 
        clr     w       ; get the 0th item in the table (number
        call    P_word  ; of chars in the password). 
        subwf   qual,0  ; IF qual = no._of_P_word_chars THEN
        snz             ; return with 1 in w. 
        retw    1       ; ELSE return with 0 in w. 
        ret
:no_match       test    qual    ; IF qual = 0, return with 0 in w. 
        snz
        ret
        clr     qual    ; ELSE qual = 0: GOTO Qualify (check 
        jmp     Qualify ; char against 0th password entry).