PAGE ,132 ; TITLE SALEX1.SAL - SAMPLE USING THE SALUT UTILITY ;THE PURPOSE OF THIS IS TO ILLUSTRATE THE USE OF STRUCTURED MACROS CR EQU 13 ;CARRIAGE RETURN LF EQU 10 ;LINE FEED EOM EQU '$' ;END OF MESSAGE INDICATOR PUBLIC CR,LF,EOM EXTRN STAK:BYTE ;INCLUDE THE STACK SEGMENT EXTRN CLS:FAR ;CLEARS THE SCREEN EXTRN DISPLAY:FAR ;SEND MESSAGE TEXT TO CONSOLE DISPLAY EXTRN KEYBOARD:FAR ;READ RESPONSE FROM KEYBOARD EXTRN PROCESS:FAR ;THE APPLICATION, AFTER THE PASSWORD IS OK ; * * * * * * * * * * * * * * * * * * * * * * * * * * DSEG SEGMENT BYTE PUBLIC 'DATA' MSG0 DB 'For your information,',CR,LF,'the password is:',CR,LF PASSWORD DB "123" ;PASSWORD EXPECTED FROM USER PASSWORD_SIZE EQU $-PASSWORD ;NUMBER OF CHARS IN PASSWORD DB CR,LF,EOM MSG1 DB 'ENTER PASSWORD',CR,LF,EOM MSG2 DB CR,LF,'INVALID PASSWORD',CR,LF,EOM MSG3 DB ' TRY AGAIN',CR,LF,EOM MSG4 DB 'SESSION CANCELLED FOR INCORRECT PASSWORD',CR,LF,EOM MSG5 DB 'THIS IS YOUR LAST CHANCE...',CR,LF,EOM INCLUDE SALEXINC.ASM ;DEFINE STRUC DESCRIBING KEYBOARD PARM LIST AREA PARMLST <> ;DEFINE AREA TO RECEIVE KEYBOARD RESPONSES PUBLIC AREA TRY_COUNT EQU 3 ;NUMBER OF ATTEMPTS TO BE MADE TO GET PASSWORD DSEG ENDS ; * * * * * * * * * * * * * * * * * * * * * * * * * * CSEG SEGMENT BYTE PUBLIC 'CODE' ASSUME CS:CSEG,DS:DSEG,ES:DSEG ;THIS SEGMENT'S NAME IS THE SAME AS THAT OF THE CALLING ROUTINE. LINK WILL ;PUT THESE TWO PORTIONS OF THE SAME NAME SEGMENT TOGETHER IN THE LOAD MODULE. ;BECAUSE 'START' IS IN THE SAME NAMED SEGMENT AS ITS CALLER, START CAN BE ;DEFINED AS 'NEAR'. START PROC NEAR PUBLIC START ;AT ENTRY, ES HAS SEG ID OF PROGRAM SEGMENT PREFIX (PSP). ; AX HAS SEG ID OF DSEG. MOV ES,AX ;SET EXTRA SEGMENT TO DATA SEGMENT ALSO CALL CLS ;START WITH A CLEAR SCREEN MOV DX,OFFSET MSG0 ;TELL THE USER WHAT THE PASSWORD IS CALL DISPLAY MOV CX,16 ;LOOP COUNTER FOR PAUSE FOR ABOUT 4 SECONDS XPAUSE: $DO ;(NOTE: THIS LABEL IS UNNECESSARY, AND IS OPTIONAL.) PUSH CX MOV CX,0FFFFH ;THIS LOOP TAKES ABOUT A QUARTER SECOND TO EXECUTE $DO ;THIS LOOP HAS NO INNER PROCESS, BUT JUST DECREMENTS COUNTER IN CX $ENDDO LOOP POP CX $ENDDO LOOP CALL CLS ;WIPE THE HELPFUL HIT FROM SCREEN MOV CX,TRY_COUNT ;SET LIMIT TO NUMBER OF ATTEMPTS $SEARCH COMPLEX MOV DX,OFFSET MSG3 ;" TRY AGAIN" CALL DISPLAY CMP CX,1 ;IF THE RETRY COUNT IS DOWN TO ONE, $IF E MOV DX,OFFSET MSG5 ;"THIS IS YOUR LAST CHANCE" CALL DISPLAY $ENDIF $STRTSRCH ;BEGINNING OF RETRY LOOP PUSH CX ;SAVE COUNT ON STACK MOV DX,OFFSET MSG1 ;"ENTER PASSWORD" CALL DISPLAY CALL KEYBOARD ;READ RESPONSE INTO KEYBOARD BUFFER AREA CMP AREA.RESIZE,PASSWORD_SIZE ;COMPARE RESPONSE SIZE WITH EXPECTED RESPONSE SIZE $EXITIF E,AND ;IF RESPONSE IS PROPER SIZE, AND... MOV SI,OFFSET PASSWORD MOV DI,OFFSET AREA.BUFFER MOV CX,PASSWORD_SIZE REPE CMPSB $EXITIF E ;AND, IF THE RESPONSE IS THE CORRECT STRING, THEN ACCEPT IT ;SUCCESS - PROPER PASSWORD HAS BEEN ENTERED POP CX ;REMOVE LOOP COUNTER FROM STACK CALL PROCESS ;SINCE PASSWORD IS OK, PERFORM FUNCTION OF APPLICATION $ORELSE ;SINCE THAT RESPONSE WAS NOT THE CORRECT PASSWORD MOV DX,OFFSET MSG2 ;"INVALID PASSWORD" CALL DISPLAY POP CX ;GET RETRY COUNTER $ENDLOOP LOOP ;IF MORE ATTEMPTS ALLOWED, GO REPEAT REQUEST FOR PASSWORD ;FAILURE - PASSWORD WAS NOT ENTERED WITHIN THE REQUIRED NUMBER OF RETRIES. MOV DX,OFFSET MSG4 ;"SESSION CANCELLED" CALL DISPLAY $ENDSRCH ;REGARDLESS AS TO THE OUTCOME OF THE SEARCH, ; BOTH 'SUCCESS' AND 'FAILURE' EVENTUALLY COME HERE RET ;NEAR RETURN TO CALLING ROUTINE START ENDP CSEG ENDS END  BOTH 'SUCCESS' AND 'FAILURE' EVENTUALLY COME HERE RET ;NEAR RETURN TO CALLING ROUTINE START ENDP CSEG ENDS E