home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 June
/
SIMTEL_0692.cdr
/
msdos
/
batutl
/
reply1.arc
/
REPLY1.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-07-28
|
10KB
|
307 lines
PAGE ,132 ;SET FOR WIDE LISTING
; REPLY.ASM
;Created By: Charles Thurston, Sunnyvale, CA, October 1987
;Returns ERRORLEVEL to a batch file, depending on user selection of a
;command parameter line; will time out in 10 seconds (CPU-dependent),
;returning a default ERRORLEVEL of 0.
;See REPLY.DOC for usage.
;880112 Toad Hall Tweak, rewrite. David Kirschbaum, kirsch@braggvax.ARPA
; - tightened code in general
; - removed CPU-dependent delay loop, replacing with Int 08H-controlled
; delay.
; - saved about 60 bytes or so despite more "portable" fixes.
; - My new code is in lower case or flagged with "[TH]".
;880729
; - Replaced string tick display with single-char (still staying with
; the DOS services rather than a BIOS write-tty service)
;--------------------------------------------------------------------
CR equ 0DH
LF equ 0AH
CODE_SEG SEGMENT para public 'code'
ASSUME CS:CODE_SEG,DS:CODE_SEG,SS:CODE_SEG,ES:CODE_SEG
; ORG 100H ;THIS COMMAND WAS NOT NEEDED
org 0100H ;[TH] the hell!
;====================================================================
; BEGINNING OF PROGRAM
;
Reply proc near ;[TH]
CALL INPUT ;GO TO INPUT CHECKING
CMP AL,86H ;WAS THERE AN ERROR(86H)
;[TH] JZ EXIT ;IF YES, EXIT
je Error_Exit ;carry means error, msg ofs in dx
;[TH] WAIT is a reserved word for MASM 5.0
;[TH] CALL WAIT ;GO TO WAITING ROUTINE
call Wait1 ;go to waiting routine
;[TH] If an error, we have a message in dx.
;We ALSO have at least a CR/LF string in dx even if we succeeded.
;Ergo : we always print a string on exit.
;AL will have either 86H (error), or the ERRORLEVEL from the Wait procedure.
Error_Exit:
push ax ;[TH] save error level
mov ah,09H ;Display string
int 21H ;ought not disturb AL, but still...
pop ax ;[TH] restore error level
;[TH] EXIT:
MOV AH,4CH ;terminate program
INT 21H ;EXIT WITH CODE IN AL
;====================================================================
; DATA AREA ------ ESTABLISH TABLES AND SYMBOLS
;
TABLE DB 31H DUP(0),'123456789',7H DUP(0),'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
TABLE2 DB 6H DUP(0),'ABCDEFGHIJKLMNOPQRSTUVWXYZ',85H DUP(0)
DUPLIST DB 80H DUP(0)
RESPONSES DB 24H DUP(0)
NONE DB 'Missing Reply Parameter.',0DH,0AH,'$'
WRONG DB 'Invalid Reply Parameter.',0DH,0AH,'$'
DOUBLE DB 'Duplicate Reply Parameter.',0DH,0AH,'$'
ASKTHIS DB 'RESPONSE:$'
;[TH] TIMETICK DB ' .$' no longer used
TIMEOUT DB ' DEFAULT'
feed db 0DH,0AH,'$' ;[TH] share the CR/LF
;[TH] FEED DB 0DH,0AH,'$'
Clock label dword ;[TH]
dw 046CH,0 ;ofs,seg of DOS master clock
;====================================================================
Reply endp ;[TH]
; CHARACTER INPUT AND CHECKING SUBROUTINE
;
INPUT proc near
CLD ;CLEAR DF (e.g., insure fwd)
XOR CX,CX ; " CX
MOV DI,0080H ;SET DI TO INPUT STRING
MOV CL,[DI] ;PUT COUNT INTO CX
JCXZ MISSING ;IF CX=0 PRINT MISSING & END
DEC CX ;SKIP LEADING SPACE
MOV BP,CX ;PUT CX IN BP FOR LATER
XOR AX,AX ;CLEAR AX
MOV SI,0082H ;SI POINTS TO INPUT STRING
;[TH] LEA DI,RESPONSES+0100H ;DI " " RESPONSES
;[TH] LEA BX,TABLE+0100H ;BX " " TABLE
;[TH] author has an obsession with LEAs. Donno why .. they're slower,
;more awkward to code.
mov di,offset Responses ;DI points to responses
mov bx,offset Table ;BX points to table
TRANSLATE:
LODSB ;PUT [SI] INTO AL, INC SI
XLAT ;[BX+AL]=>AL
;[TH] CMP AL,00H ;CHECK IF VALID CHARACTER
or al,al ;check if valid character
JZ INVALID ;PRINT INVALID AND END
STOSB ;STORE AL=>[DI], INC DI
LOOP TRANSLATE ;LOOP UNTIL CX=0
MOV CX,BP ;PUT COUNT INTO CX
XOR AX,AX ;CLEAR AX
;[TH] LEA SI,RESPONSES+0100H ;SI POINTS TO RESPONSES
;[TH] LEA BX,DUPLIST+0100H ;BX " " DUPLIST
mov si,offset Responses ;SI points to responses
mov bx,offset DupList ;BX points to duplist
REDUNDANT:
LODSB ;PUT [SI]=>AL, INC SI
MOV DI,AX ;COPY CHARACTER INTO DI
XLAT ;[BX+AL]=>AL
CMP AL,20H ;DOES IT ALREADY EXIST
JZ DUPLICATE ;YES, PRINT DUPLICATE & END
MOV BYTE PTR[BX+DI],20H ;PUT 20H INTO DUPLIST
LOOP REDUNDANT ;LOOP UNTIL DONE
XOR AX,AX ;CLEAR AX
;[TH] JMP LEAVE ;GO TO LEAVE AND RETURN
ret ;[TH] hell with "classical" code.
;We don't worry about no msg ofs in dx
;since we're gonna go right to Wait
;====================================================================
; ERROR MESSAGE OUTPUTS
;
MISSING:
;[TH] MOV AH,09H ;
;[TH] LEA DX,[NONE+0100H] ;
;[TH] INT 21H ;PRINT "MISSING ..."
;[TH] MOV AL,86H ;SET AL TO ERROR(86H)
;[TH] JMP LEAVE ;RETURN
mov dx,offset None ;'Missing reply parms'
jmp short Leave ;set AL to 86H and return
;
INVALID:
;[TH] MOV AH,09H ;
;[TH] LEA DX,[WRONG+0100H]
;[TH] INT 21H ;PRINT "INVALID ..."
;[TH] MOV AL,86H ;SET AL TO ERROR(86H)
;[TH] JMP LEAVE ;RETURN
mov dx,offset Wrong ;'Invalid parm'
jmp short Leave ;set AL to 86H and return
;
DUPLICATE:
;[TH] MOV AH,09H ;
;[TH] LEA DX,[DOUBLE+0100H]
;[TH] INT 21H ;PRINT "DUPLICATE ..."
mov dx,offset Double ;'Duplicate parm'
Leave: ;[TH]
MOV AL,86H ;SET AL TO ERROR(86H)
;
;[TH] LEAVE:
RET ;RETURN
Input endp
;====================================================================
; START OF TIMING, KEYBOARD RESPONSE, AND CHARACTER CHECKING ROUTINE
;
;WAIT: [TH] a reserved word in MASM 5.0
Wait1 proc near
XOR AX,AX ;CLEAR AX
MOV AH,09H ;
;[TH] LEA DX,ASKTHIS+0100H
mov dx,offset AskThis ;'RESPONSE:'
INT 21H ;PRINT "RESPONSE:"
;Toad Hall Note: I replaced the CPU-dependent timer loop with a direct
;DOS master clock watching procedure. We'll check every 1/18 second, ok?
;This'll work fine (and not be machine speed dependent) if you're
;PC-compatible. If not .. sigh .. comment out MY code and put the
;patched loop back in.
les si,Clock ;get seg, ofs of master clock, DOS Page 0
ASSUME ES:Nothing ;keep MASM happy
mov cx,182 ;set timer counter to 10 seconds (10*18.2)
mov bh,18 ;a handy 18 divisor
Seconds:
mov ax,ES:[si] ;snarf current clock lower word
Tick18: cmp ax,ES:[si] ;same as last check?
je Tick18 ; yep, wait for a 1/18 second tick
;Now check our user for any kbd input
mov ah,0BH ;check kbd status
int 21H
cmp al,0ffh ;FF=ready, 00=not
je Process ; Yep, go process input
;No input, keep ticking
mov ax,cx ;get counter
div bh ;mod 18
or ah,ah ;any remainder?
jne NoDot ;not a full second of ticks yet
;[TH] mov dx,offset TimeTick ;' .' display a tick
;[TH] mov ah,09H ;display text
mov dl,'.' ;display a tick
mov ah,2 ;display single-char output
int 21H
NoDot:
loop Seconds ;loop for 10 seconds
jmp short Default ;..and assume Default at the timeout
Comment | [TH] all this CPU-dependent stuff commented out
MOV CH,0AH ;SET TIMER TO 10+1
SECONDS:MOV CL,02H ;SET TWIDDLE TO 2
HALFSEC: MOV BX,65500 ;SET TWIDDLE COUNT
TWIDDLE: DEC BX ;BX-1=>BX
;[TH] CMP BX,0000 ;IS BX ZERO
or bx,bx ;is BX zero?
JNZ TWIDDLE ;NO, CONTINUE TWIDDLE
MOV AH,0BH ;
INT 21H ;CHECK FOR INPUT READY
CMP AL,0ffh ;-1 ;-1=READY, 00=NOT
JZ PROCESS ;YES, PROCESS INPUT
RETURN: DEC CL ;CL-1=>CL
;[TH] CMP CL,00 ;IS CL ZERO
or cl,cl ;is outer counter zeroed yet?
JNZ HALFSEC ;NO, CONTINUE TIMER
;[TH] MOV AH,09H ;
;[TH] LEA DX,TIMETICK+0100H
;[TH] mov dx,offset TimeTick ;' .'
mov dl,'.' ;timetick
mov ah,2 ;display single-char output
INT 21H ;PRINT " ."
DEC CH ;CH-1=>CH
;[TH] CMP CH,00 ;IS CH ZERO
or ch,ch ;is second counter zeroed?
JZ DEFAULT ;YES, PROCESS DEFAULT
;[TH] If you tell MASM to jump short, it'll prevent dumb NOPs
JMP short SECONDS ;CONTINUE TIMER LOOP
End of tick loop commented-out code |
;====================================================================
; PROCESS KEYBOARD INPUT - CHECK IF VALID RESPONSE
;
PROCESS:
PUSH BX ;SAVE BX
PUSH CX ; " CX
;[TH] no need to save DX or DI as far as I can see..
;[TH] PUSH DI ; " DI
;[TH] PUSH DX ; " DX
XOR DX,DX ;CLEAR DX
MOV AH,08H ;
INT 21H ;GET CHARACTER IN AL
;[TH] LEA BX,TABLE+0100H ;POINT BX TO TABLE
mov bx,offset Table ;Point BX to table
XLAT ;[BX+AL]=>AL
;[TH] CMP AL,00 ;IS CHARACTER VALID
or al,al ;is character valid?
JZ GOBACK ;NO, GO BACK TO WAITING
XOR CX,CX ;CLEAR CX
;[TH] LEA BX,RESPONSES+0100H ;POINT BX TO RESPONSES
mov bx,offset Responses ;point BX to Responses
SEARCH: INC CL ;CL+1=>CL
MOV DL,[BX] ;GET RESPONSES CHARACTER
;[TH] CMP DL,00 ;IS THERE NO CHOOSES
or dl,dl ;are there choices?
JZ GOBACK ;NO, GO BACK TO WAITING
CMP DL,AL ;DOES INPUT="RESPONSES"
JZ FOUND ;YES, GO TO FOUND
INC BX ;BX+1=>BX
JMP short SEARCH ;KEEP SEARCHING
;====================================================================
; GO BACK TO WAITING LOOP
;
GOBACK:
;[TH] POP DX ;RESTORE DX
;[TH] POP DI ; " DI
POP CX ; " CX
POP BX ; " BX
;[TH] JMP short RETURN ;RETURN TO WAITING
jmp short NoDot ;[TH] go back to new waiting procedure
;====================================================================
; KEYBOARD INPUT CHARACTER IS A VALID PARAMETER - SET UP RETURN CODE
;
FOUND:
MOV AH,02H ;
INT 21H ;ECHO CORRECT CHARACTER
;[TH] MOV AH,09H ;
;[TH] LEA DX,FEED+0100H ;
;[TH] INT 21H ;CLEAN UP LINE
ADD CL,CH ;TOTAL THE COUNT
MOV AL,CL ;PUT COUNT IN AL
;[TH] POP DX ;RESTORE DX
;[TH] POP DI ; " DI
POP CX ; " CX
POP BX ; " BX
mov dx,offset Feed ;[TH] send CR/LF
RET ;RETURN TO EXIT
;====================================================================
; PROCESS DEFAULT OPTION - RETURNS "00" IN AL REGISTER
;
DEFAULT:
;[TH] MOV AH,09H
;[TH] LEA DX,TIMEOUT+0100H
;[TH] INT 21H ;PRINT " DEFAULT"
;[TH] MOV AX,0000 ;PUT 0000 IN AX
xor ax,ax ;put 0 in ax
mov dx,offset TimeOut ;'DEFAULT'
RET ;RETURN
Wait1 endp
;====================================================================
CODE_SEG ENDS
END Reply