; 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.

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

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

	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).


