; Doug's Programming Language  -- DPL, Version 2.22
; Copyright (c) 1988 Douglas S. Cody, All rights reserved.
;----------------------------------------
;
; E N V S T R  --  Fetch the matching environment string from the
;		   PSP segment.
;
; Entry Conditions:
;	AX points to the match string
;	BX points to the target string
;	ES holds the PSP segment
; Exit Conditions:
;	Assume all working registers destroyed.
;	All segment registers saved.
;	CARRY SET = not found, CLEAR = found
;
; CALLING EXAMPLE:
;
;	CALL	ENVSTR match target
;
; WHERE:
;	"match" is an ASCIIZ string to be compared against the PSP
;	   environment strings. This match string must NOT have
;	   the equal sign appended to the end. The match string MUST
;	   be in uppercase since DOS holds the environment strings
;	   in uppercase.
;	"target" is a ASCIIZ string which will the string found by
;	   the search.
;
SUBPGM ENVSTR
;
; STACK OFFSETS
;
BPREG		EQU	00		; SAVING BP
PSPSEG		EQU	-2		; STORAGE OFFSET TO PSP
DTTASEG		EQU	-4		; STORAGE OFFSET TO OUR DATA SEGMENT
MTCHSTR		EQU	-6		; STORAGE OFFSET TO MATCH STRING
TRGSTR		EQU	-8		; STORAGE OFFSET TO TARGET STRING
SIREG		EQU	-10		; SAVING SI
DIREG		EQU	-12		; SAVING DI 
;
BEGIN	ENVSTR
;
; SAVE OUR CRITICALS ON THE STACK
;
	PUSH	BP			; FRAME THE STACK
	MOV	BP,SP
	PUSH	ES			; SAVE THE PSP SEGMENT
	PUSH	DS			; SAVE THE DATA SEGMENT
	PUSH	AX			; SAVE THE MATCH STRING
	PUSH	BX			; SAVE THE TARGET STRING
	PUSH	SI			; SAVE THE INDEXES...
	PUSH	DI
;
; SETUP TO POINT TO THE ENVIRONMENT STRINGS
;
	PUSH	ES:[02CH]		; GET THE ENVIRONMENT SEGMENT
	POP	ES
	XOR	DI,DI			; DI WILL BECOME THE ENVIRONMENT POINTER
;
	MOV	[BX],DI			; SET A TERMINATOR IN THE TARGET
;
EVST_05:
;
; GET THE NEXT ENVIRONMENT STRING LENGTH
;
	CALL	GET_LENGTH
	JC	EVST_BAD		; EXIT IF OUT OF ENVIRONMENT STRINGS
;
; COMPARE THE ENVIRONMENT STRING TO THE MATCH STRING
;
	MOV	SI,[BP+MTCHSTR]		; GET THE MATCH STRING ADDRESS
;
EVST_10:
	REPE	CMPSB			; COMPARE CHARACTERS
	JE	EVST_GOOD		; FOUND!!!
;
; STRING NOT FOUND, MOVE DI TO THE START OF THE NEXT ENVIRONMENT STRING
;
	XOR	AL,AL			; MAKE A MATCH IN AL
	MOV	CX,-1			; WE WILL SEARCH FOREVER, IF DOS LET'S US (IT WONT)
; 
EVST_15:
	REPNE	SCASB			; FIND IT!
	JMP	SHORT EVST_05		; GO FOR THE NEXT STRING
;
; STRING WAS FOUND, MOVE IT TO THE TARGET STRING...
;
EVST_GOOD:
	CMP	BYTE PTR ES:[DI],"="	; ARE WE SITTING ON THE EQUAL SIGN?
	JNZ	EVST_G05		; NO, CONTINUE ON...
	INC	DI			; YES, MOVE PAST THE CHARACTER
;
; LOAD ES:[DI] & DS:[SI] FOR A BLOCK MOVE
;
EVST_G05:
	PUSH	ES			; SETUP THE SEGMENTS
	POP	DS			; DS HOLDS THE ENVIRONMENT SEGMENT
	MOV	ES,[BP+DTTASEG]
	MOV	SI,DI			; SI POINTS TO THE ENVIRONMENT STRING
	MOV	DI,[BP+TRGSTR]		; DI POINTS TO THE TARGET STRING
;
EVST_G10:
	LODSB				; FETCH THE SOURCE STRING CHARACTER
	STOSB				; SAVE IN THE TARGET STRING
	OR	AL,AL			; ARE WE DONE?
	JNZ	EVST_G10		; NO, DO IT ALL
;
; ALL DONE, RESTORE ALL & RETURN HOME...
;
	CLC				; CLEAR CARRY
	JMP	EVST_COMM		; & EXIT THROUGH COMMON CODE
;
; WE GET HERE IF THE ENVIRONMENT DID NOT HAVE A MATCH FOR US.
;
EVST_BAD:
	STC				; SET CARRY FOR MISMATCH CONDITION
;
EVST_COMM:
	POP	DI			; RESTORE ALL & EXIT
	POP	SI
	POP	BX
	POP	AX
	POP	DS
	POP	ES
	POP	BP
	RETURN
;
;
;=====================
;   ROUTINE SECTION
;	LEVEL 1
;=====================
;
;
;-----------------------------------------
; G E T _ L E N G T H  --  GET THE LENGTH OF THE
;			   CURRENT ENVIRONMENT STRING
; Entry conditions:
;	ES:DI point to the start of the current string
; Exit conditions:
;	Carry SET   = end of list
;	      CLEAR = data is available for checking
;		      CX holds the environment string length
;
GET_LENGTH	PROC	NEAR
	CMP	BYTE PTR ES:[DI],0	; ARE WE DONE?
	JNZ	GTLN_05			; NO, GO FIND THE LENGTH
	STC
	RET
;
GTLN_05:
	MOV	CX,DI			; CX WILL HOLD OUR STARTING ADDRESS
	MOV	AL,'='			; THIS IS OUR TERMINATOR
;
GTLN_10:
	MOV	AH,ES:[DI]		; GET THE CHARACTER
	SCASB				; SCAN FOR THE CHARACTER
	JZ	GTLN_15			; FOUND! EXIT NOW
	OR	AH,AH			; WAS THIS A NULL TERMINATOR?
	JNZ	GTLN_10			; NO, CONTINUE THE SEARCH
;
GTLN_15:
	DEC	DI			; DISCOUNT THE TERMINATOR
	XCHG	CX,DI			; CX = ENDING ADDRESS, DI=ORIG ADDRESS
	SUB	CX,DI			; CX HOLDS THE LENGTH
	CLC
	RETURN

GET_LENGTH	ENDP
;
ENDPGM	ENVSTR
; 
