Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : ADVSTR.ZIP
Filename : POS.ASM

 
Output of file : POS.ASM contained in archive : ADVSTR.ZIP

; Program ....: Pos.ASM
; Author .....: Chuck Litzell
; Date .......: February 1, 1988
; Versions ...: dBASE III PLUS and Developer's Release
;*****************************************************************************
CODE SEGMENT BYTE PUBLIC 'CODE'
;-----------------------------------------------------------------------------
SAVE MACRO R1,R2,R3,R4,R5,R6,R7,R8
;
; Macro to save registers passed in a list, separated by commas.
;
IRP X,
IFNB
PUSH X
ENDIF
ENDM
ENDM
;-----------------------------------------------------------------------------
RESTORE MACRO R1,R2,R3,R4,R5,R6,R7,R8
;
; Macro to restore registers passed in a list, separated by commas.
; Registers are popped in the reverse order from which they are passed.
;
IRP X,
IFNB
POP X
ENDIF
ENDM
ENDM
;-----------------------------------------------------------------------------
MOVSEG MACRO R1,R2
;
; Macro to move segment value from the second parameter into the first.
; To the programmer, works like MOV.
;
PUSH R2
POP R1
ENDM
;-----------------------------------------------------------------------------
; Test results:
ISEQU EQU 1 ; results in equal.
ISLESS EQU 2 ; results in less than.
ISGREAT EQU 3 ; results in greater than.
; Error codes:
SUCCESS EQU 1 ; Operation successful.
NOMATCH EQU 2 ; No match found.
ILLEGOP EQU 3 ; Requested undefined operation.
NULSTR EQU 4 ; A null string was passed.
UNINIT EQU 5 ; Search string uninitialized
TOOLONG EQU 6 ; Match string too long.
BADROP EQU 7 ; Bad relop specified.
BADDIR EQU 8 ; Illegal direction flag.
; Relational operator codes:
EQ EQU 1 ; Equal to.
NE EQU 2 ; Not equal to.
LT EQU 3 ; Less than.
GT EQU 4 ; Greater than.
LE EQU 5 ; Less than or equal to.
GE EQU 6 ; Greater than or equal to.
; Direction codes:
FWD EQU 1 ; Search from beginning to end.
BKW EQU 2 ; Search from end to beginning.

;-----------------------------------------------------------------------------
MAIN PROC FAR
ASSUME CS:CODE

START: JMP BEGIN
DB 13, 'Pos.BIN', 10, 13
DB 'Written by Chuck Litzell.', 10, 13
DB 'Copyright 1988, Ashton-Tate', 10, 13
DB 26
SRCHBUF DB 255 DUP (0) ; Storage for string to search.
OPCODE DB (?) ; Operation: Init or eXecute.
RELOP DB (?) ; Relational operator code.
STEP DB (?) ; Number bytes to skip each pass.
OCCUR DB (?) ; Occurrence to find.
DIRECT DB (?) ; Direction of search.
MTCHBUF DB 250 DUP (0) ; Storage for string to match.
SRCHLEN DB 255 ; Length of search string.
MTCHLEN DB (?) ; Length of match string.
HITS DB (?) ; Number of hits so far.
SOFFS DB (?) ; Current offset in search string.
ERROR DB (?) ; Error Code.
RESULT DB (?) ; The answer.
;------------------------------------------------------------------------------
BEGIN: SAVE AX,BX,CX,DX,DI,SI,BP ; Save registers.
SAVE DS,BX ; Save address of dBASE memvar.
MOVSEG ES, CS ; Make ES = CS.
MOV DI, OFFSET OPCODE ; Copy dBASE Memvar into program.
MOV SI, BX ; Point to dBASE memvar.
GETVAR: LODSB ; Get a byte in AL.
CMP AL, 0 ; End of string?
JE GOTVAR ; End of copy.
STOSB ; Store the byte.
LOOP GETVAR ; Back for next byte.
GOTVAR:
XOR AL, AL ; Put a null at end.
STOSB ;
MOV AL, OPCODE ; Get operation code in AL.
AND AL, 223 ; Make it capital.
CMP AL, 'I' ; Request to initialize?
JE INITIAL ; Yes. Do initialization.
CMP AL, 'X' ; Request to eXecute?
JE EXECUTE ; Yes. Execute search.
MOV ERROR, ILLEGOP ; Bad operation specified.
JMP DONE ; Exit.
INITIAL:
CALL SETUP ; Call routine to save search string.
JMP DONE ;
EXECUTE:
CALL SEARCH ; Call searching routine.

DONE: RESTORE DS, BX ; Restore dBASE DS.
MOVSEG ES, DS ; Make ES = DS.
MOV DI, BX ; Point to dBASE.
MOV AL, ERROR ; Get error code in AL.
STOSB ; Send to dBASE.
MOV AL, RESULT ; Get answer in AL.
STOSB ; Put in 2nd byte.
RESTORE AX,BX,CX,DX,DI,SI,BP ; Restore registers.
RET ;
MAIN ENDP ; End of MAIN procedure.
;-----------------------------------------------------------------------------
SETUP PROC NEAR
;
; Copy search string to srchbuf. Put length of string in srchlen.
; Return SUCCESS if everything OK.
;
MOVSEG DS, CS ; Make DS = CS.
MOV SI, OFFSET RELOP ; Point to search string beginning
; at RELOP.
MOVSEG ES, CS ; Make ES = CS.
MOV DI, OFFSET SRCHBUF ; Point to search string storage.
SUB CL, CL ; Clear CL for count.
SETUP1: LODSB ; Get a byte.
CMP AL, 0 ; Is it end of the string?
JE SETUP2 ; Yes, exit.
STOSB ; Save byte.
INC CL ; Add one to string length.
JMP SETUP1 ; Go for next.
SETUP2: SUB AL, AL ; Store a null byte.
STOSB ;
MOV SRCHLEN, CL ; Save string length.
CMP CL, 0 ; Is string null?
JNE SETUP3 ; No.
MOV ERROR, NULSTR ; Store error code.
JMP SETUPX ; Return.

SETUP3: MOV ERROR, SUCCESS ; Return success code.

SETUPX: RET
SETUP ENDP
;-----------------------------------------------------------------------------
SEARCH PROC NEAR
;
; Execute the search routine.
;
MOV AL, SRCHLEN ; Get length of search string.
CMP AL, 255 ; Has it been initialized?
JNE SRCH1 ; OK, jump ahead.
MOV ERROR, UNINIT ; Error if search string not init.
JMP SRCHXA ; Forget the rest.

SRCH1: MOV AL, RELOP ; Get relop in AL.
CMP AL, 1 ; Less than 1?
JB ROPBAD ;
CMP AL, 6 ; Greater than 6?
JA ROPBAD ;
JMP DIRCHK ;
ROPBAD: MOV ERROR, BADROP ; Unknown comparison requested.
JMP SRCHXA ; Exit.

DIRCHK: MOV AL, DIRECT ; Get direction flag in AL.
CMP AL, FWD ; Less than 1?
JB DIRBAD ;
CMP AL, BKW ; Greater than 2?
JA DIRBAD ;
JMP SRCH2 ; Direction OK.
DIRBAD: MOV ERROR, BADDIR ; Store code for bad direction
JMP SRCHXA ; Quit

SRCH2: MOVSEG DS, CS ; Make DS = CS.
MOV SI, OFFSET MTCHBUF ; Point to match string.
SUB CL, CL ; Zero CL for length counter.
SRCH3: LODSB ; Get a byte.
CMP AL, 0 ; Is it end of string?
JZ SRCH4 ; Done.
INC CL ; Increment length counter.
JMP SRCH3 ; Get next byte.
SRCH4: MOV MTCHLEN, CL ; Store length of match string.
CMP CL, 0 ; Is string null?
JA CHKLEN ; No see if too long.
MOV ERROR, NULSTR ; Null string was passed.
JMP SRCHXA ; Exit.

CHKLEN: MOV AL, SRCHLEN ;
CMP AL, MTCHLEN ;
JB LENBAD ; Error.
JMP SRCH5 ; Continue.
LENBAD: MOV ERROR, TOOLONG ;
JMP SRCHXA ;

SRCH5: MOV HITS, 0 ; No hits yet.
MOV SOFFS, 0 ; Start at beginning of search string.
MOV ERROR, NOMATCH ; No match found yet.
MOV RESULT, 255 ; Put something there, for now.
MOV AL, DIRECT ; Get direction flag.
CMP AL, FWD ; Forward search?
JE SRCH6 ;
MOV AL, SRCHLEN ; Get search string length in AL.
SUB AL, MTCHLEN ; Subtract match string length.
MOV SOFFS, AL ; This is where compare will start.

SRCH6: MOV AL, SRCHLEN ; Retrieve search string length.
SUB AL, SOFFS ; Remove offset.
JB SRCHXB ; Done if past MTCHLEN.
CMP AL, MTCHLEN ; Any more searches?
JB SRCHXB ; No more searches.
CMP AL, 0 ; Check backward, too.
JB SRCHXB ; No more searches.
CALL COMPARE ; Do the comparison.
MOV AH, RELOP ; Get relational opcode test.
T1: CMP AH, EQ ; Test for equality?
JNE T2 ; No.
CMP AL, ISEQU ; Were they equal?
JE AHIT ; Process a hit.
JMP NXTPAS ; Next compare.
T2: CMP AH, NE ; Test for not equal?
JNE T3 ; No.
CMP AL, ISEQU ; Were they equal?
JNE AHIT ; Process a hit.
JMP NXTPAS ; Next compare.
T3: CMP AH, LT ; Test for less than?
JNE T4 ; No.
CMP AL, ISLESS ; Was it less?
JE AHIT ; Process a hit.
JMP NXTPAS ; Next compare.
T4: CMP AH, GT ; Test for greater than?
JNE T5 ; No.
CMP AL, ISGREAT ; Was it greater?
JE AHIT ; Process a hit.
JMP NXTPAS ; Next compare.
T5: CMP AH, LE ; Test for less than or equal?
JNE T6 ; No.
CMP AL, ISGREAT ; Was it greater?
JNE AHIT ; Process a hit.
JMP NXTPAS ; Next compare.
T6: CMP AH, GE ; Test for greater than or equal?
JNE NXTPAS ; This should never happen.
CMP AL, ISLESS ; Was it less than?
JNE AHIT ; Process a hit.
JMP NXTPAS ; Next compare.

SRCHXB: JMP SRCHXA ; For short jmp.

AHIT: MOV AL, HITS ; Get number of hits so far.
INC AL ; Add this one.
MOV HITS, AL ; Store it back.
CMP AL, OCCUR ; Is this the one?
JL NXTPAS ; No.
MOV ERROR, SUCCESS ; Store success code.
MOV AL, SOFFS ; Get current offset.
INC AL ; Add 1 to offset since it's
; zero-based here.
MOV RESULT, AL ; Where match occurred.
JMP SRCHXA ; Return to MAIN.
NXTPAS: MOV AL, SOFFS ; Get current offset.
MOV AH, DIRECT ; Get direction flag.
CMP AH, FWD ; Is it a forward search?
JE AHEAD ;
SUB AL, STEP ; Back up a step in string.
JMP NEXT ;

AHEAD: ADD AL, STEP ; Add it to AX.

NEXT: MOV SOFFS, AL ;
JMP SRCH6 ; Do next compare.

SRCHXA: RET
SEARCH ENDP
;-----------------------------------------------------------------------------
COMPARE PROC NEAR
;
; This routine compares match string to search string at current offset
; and puts a result code in AL.
;
MOVSEG DS, CS ; Make DS = CS.
SUB AX, AX ; Clear accumulator.
MOV AX, OFFSET SRCHBUF ; Point to search string.
ADD AL, SOFFS ; Move to current offset.
MOV DI, AX ; Point to search string.
MOV SI, OFFSET MTCHBUF ; Point to match string.
SUB CX, CX ; Clear CX.
MOV CL, MTCHLEN ; Number bytes to compare.
CLD ; Search forward.
REPZ CMPSB ; Do the compare.
JE CEQUAL ;
JG CGREAT ;
MOV AL, ISLESS ; Match < search.
JMP COMPX ;
CEQUAL: MOV AL, ISEQU ; Match = search.
JMP COMPX ;
CGREAT: MOV AL, ISGREAT ; Match > search.
COMPX: RET
COMPARE ENDP
;-----------------------------------------------------------------------------
CODE ENDS
;*****************************************************************************
END START