home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Multimedia & CD-ROM 3
/
mmcd03-jun1995-cd.iso
/
utils
/
various
/
utils-1
/
batchkey.asm
< prev
next >
Wrap
Assembly Source File
|
1991-06-24
|
11KB
|
256 lines
;****************************************************************************
; BATCHKEY allows batch files to get keyboard input. Its syntax is:
;
; BATCHKEY [keylist]
;
; where keylist is an optional list of accepted values. If no list is
; supplied, BATCHKEY returns the ASCII code of any key that is pressed in
; ERRORLEVEL (extended key codes return 0). If a list is supplied,
; BATCHKEY returns an ERRORLEVEL value that reflects the key's position in
; the list. An ERRORLEVEL value of 255 means the key code entered was not
; one of those in the list.
;
; Keylist values can be entered in three forms:
;
; Literal "Y" Y key
; ASCII code 13 Enter key
; Extended code (59) Function key F1
;
; Literal values are not case-sensitive. Thus, the command
;
; BATCHKEY "YN" 27 13 (59)
;
; would return 1 if "Y" or "y" was pressed, 2 if "N" or "n" was pressed,
; 3 if Esc (ASCII 27) was pressed, 4 if Enter (ASCII 13) was pressed, 5
; if function key F1 was pressed, or 255 if any other key was pressed.
;****************************************************************************
code segment
assume cs:code,ds:code
org 100h
begin: jmp main
msg db 13,10,"Invalid parameter",13,10,"$"
buffer db 64 dup (?)
keyflags db 64 dup (0)
keycount dw ?
;****************************************************************************
; Procedure MAIN
;****************************************************************************
main proc near
cld ;Clear direction flag
sub cx,cx ;Initialize count in CX
mov di,offset buffer ;Initialize SI and DI
mov si,81h
call findchar ;Advance to first character
jnc main2
;
; No key list was entered. Return the ASCII code of the first key pressed.
;
main0: mov ah,08h ;Read the keyboard
int 21h
or al,al ;Exit if AL is not 0
jnz main1
mov bl,al ;Save key code
mov ah,08h ;Read extended key code
int 21h
mov al,bl ;Retrieve original code
main1: mov ah,4Ch ;Exit with key code in AL
int 21h
;
; Parse the command line and build the key list.
;
main2: lodsb ;Get a character
cmp al,28h ;Branch if "("
je extended
cmp al,22h ;Branch if quotation mark
jne ascii
;
; Process a string of literal key codes
;
literal: lodsb ;Get a character
cmp al,22h ;Exit when closing quotation
je nextchar ; mark is encountered
cmp al,0Dh ;Error if EOL
je error
call lc2cap ;Capitalize the character
stosb ;Store it in the ley list
inc cx ;Increment count
jmp literal ;Loop back for more
;
; Process an extended key code entry
;
extended: call asc2bin ;ASCII => binary
jnc error ;Exit on error
cmp bl,29h ;Error if ")" not found
jne error
stosb ;Store the key code
inc si ;Advance SI beyond ")"
inc cx ;Increment count
push di ;Set flag indicating this
dec di ; is an extended key
sub di,offset buffer ; code
add di,offset keyflags
mov byte ptr [di],1
pop di
jmp short nextchar ;Continue
;
; Process an ASCII key code entry
;
ascii: dec si ;Decrement SI
call asc2bin ;ASCII => binary
jc error ;Exit on error
call lc2cap ;Capitalize the character
stosb ;Store it in the key list
inc cx ;Increment count
;
; Advance to the next character
;
nextchar: call findchar ;Advance to next character
jnc main2 ;Loop back if found
;
; Read a key code and check for extended key codes.
;
jcxz main0 ;Exit if no codes entered
mov keycount,cx ;Save count
mov si,offset buffer ;Initialize SI and DI
mov di,offset keyflags
mov ah,08h ;Read the keyboard
int 21h
or al,al ;Branch if extended key
jz exonly ; code
;
; Search the list for conventional key codes.
;
call lc2cap ;Capitalize the character
mov bl,al ;Save it in BL
search1: mov al,[di] ;Get flag for next code
inc di
or al,al ;Branch if extended code
jnz next1
mov al,[si] ;Test key code against list
cmp al,bl
je match ;Exit on match
next1: inc si ;Otherwise loop back for more
loop search1
jmp short nomatch ;No match if search exhausted
;
; Search the list for extended key codes.
;
exonly: mov ah,08h ;Read extended code
int 21h
mov bl,al ;Save it in BL
search2: mov al,[di] ;Get flag for next code
inc di
or al,al ;Branch if not extended code
jz next2
mov al,[si] ;Test key code against list
cmp al,bl
je match ;Exit on match
next2: inc si ;Otherwise loop back for more
loop search2
;
; No match was found.
;
nomatch: mov ax,4C00h ;Exit with ERRORLEVEL=0
int 21h
;
;An error was encountered while parsing the command line.
;
error: mov ah,09h ;Display error message
mov dx,offset msg
int 21h
jmp nomatch ;Exit with ERRORLEVEL=255
;
; A match was found.
;
match: mov ax,keycount ;Set ERRORLEVEL and exit
sub ax,cx
inc al
mov ah,4Ch
int 21h
main endp
;****************************************************************************
; FINDCHAR advances SI to the next non-space or non-comma character.
; On return, carry set indicates EOL was encountered.
;****************************************************************************
findchar proc near
lodsb ;Get the next character
cmp al,20h ;Loop if space
je findchar
cmp al,2Ch ;Loop if comma
je findchar
dec si ;Point SI to the character
cmp al,0Dh ;Exit with carry set if end
je eol ; of line is reached
clc ;Clear carry and exit
ret
eol: stc ;Set carry and exit
ret
findchar endp
;****************************************************************************
; ASC2BIN converts a decimal number entered in ASCII form into a binary
; value in AL. Carry set on return indicates that an error occurred in
; the conversion.
;****************************************************************************
asc2bin proc near
sub ax,ax ;Initialize registers
sub bh,bh
mov dl,10
a2b_loop: mov bl,[si] ;Get a character
inc si
cmp bl,20h ;Exit if space
je a2b_exit
cmp bl,2Ch ;Exit if comma
je a2b_exit
cmp bl,0Dh ;Exit if carriage return
je a2b_exit
cmp bl,"0" ;Error if character is not
jb a2b_error ; a number
cmp bl,"9"
ja a2b_error
mul dl ;Multiply the value in AL by
jc a2b_error ; 10 and exit on overflow
sub bl,30h ;ASCII => binary
add ax,bx ;Add latest value to AX
cmp ax,255 ;Error if sum > 255
jna a2b_loop ;Loop back for more
a2b_error: dec si ;Set carry and exit
stc
ret
a2b_exit: dec si ;Clear carry and exit
clc
ret
asc2bin endp
;****************************************************************************
; LC2CAP capitalizes the ASCII code in AL
;****************************************************************************
lc2cap proc near
cmp al,"a" ;Exit if less than "a"
jb l2c_exit
cmp al,"z" ;Exit if greater than "z"
ja l2c_exit
and al,0DFh ;Capitalize
l2c_exit: ret
lc2cap endp
code ends
end begin