home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Multimedia & CD-ROM 3
/
mmcd03-jun1995-cd.iso
/
utils
/
various
/
utils-1
/
fkeys.asm
< prev
next >
Wrap
Assembly Source File
|
1991-06-24
|
20KB
|
420 lines
;****************************************************************************
; FKEYS programs the function keys to produce DOS commands. Its syntax is
;
; FKEYS [shift-]key ["command"[*]]
;
; where "shift" designates a shift state (CTRL, ALT, or SHIFT), "key"
; designates the function key to be programmed (F1 through F12), "command"
; is the command to assign to the function key, and "*" indicates that the
; command should be executed when the function key is pressed. Omitting
; "command" cancels a function key assignment. The following metastrings
; may be used in the "command" parameter to specify special symbols:
;
; $B Piping operator (|)
; $G Output redirection operator (>)
; $L Input redirection operator (<)
; $T Ctrl-T (command separator)
; $$ Dollar sign
;
; FKEYS requires DOS 4.0 or higher and requires that ANSI.SYS be installed.
;****************************************************************************
code segment
assume cs:code,ds:code
org 100h
begin: jmp main
helpmsg db "Programs the function keys to produce DOS commands."
db 13,10,13,10
db "FKEYS [shift-]key [",22h,"command",22h,"[*]]"
db 13,10,13,10
db " shift Identifies a shift key (Ctrl, Alt, or "
db "Shift).",13,10
db " key Identifies a function key (F1 through "
db "F12).",13,10
db " command Command to be assigned to the function "
db "key.",13,10
db " * Indicates the command should be auto-"
db "executed.",13,10,13,10
db "Running FKEYS without a ",22h,"command",22h
db " parameter cancels a function key assignment."
db 13,10,"$"
errmsg1 db "Syntax: FKEYS [shift-]key [",22h,"command",22h
db "[*]]",13,10,"$"
errmsg2 db "DOS 4.0 or higher required",13,10,"$"
errmsg3 db "ANSI.SYS not installed",13,10,"$"
altkey db "ALT"
ctrlkey db "CTRL"
shiftkey db "SHIFT"
adder1 db 58
adder2 db 122
command db 27,"[0;",128 dup (?)
;****************************************************************************
; Procedure MAIN
;****************************************************************************
main proc near
cld ;Clear direction flag
mov si,81h ;Point SI to command line
call scanhelp ;Scan for "/?" switch
jnc checkver ;Branch if not found
mov ah,09h ;Display help text and exit
mov dx,offset helpmsg ; with ERRORLEVEL=0
int 21h
mov ax,4C01h
int 21h
;
; Make sure this is DOS 4.0 or higher and that ANSI.SYS is installed
; before proceeding.
;
checkver: mov dx,offset errmsg2 ;Exit if DOS version
mov ah,30h ; is less than 4.0
int 21h
cmp al,4
jae checkansi
error: mov ah,09h ;Display error message and
int 21h ; exit with ERRORLEVEL=1
mov ax,4C01h
int 21h
checkansi: mov ax,1A00h ;Check for ANSI.SYS using
int 2Fh ; the DOS multiplex
mov dx,offset errmsg3 ; interrupt
cmp al,0FFh
jne error ;Error if not installed
;
; Capitalize everything that's not between quotation marks.
;
mov si,81h ;Point SI to command line
tocaps1: lodsb ;Get a character
cmp al,0Dh ;Branch if end of line
je parse
cmp al,22h ;Branch if not quotation
jne tocaps3 ; mark
tocaps2: lodsb ;Get a character
cmp al,0Dh ;Branch if end of line
je parse
cmp al,22h ;Is it a quotation mark?
je tocaps1 ;Branch if it is
jmp tocaps2 ;Loop if it's not
tocaps3: cmp al,"a" ;Leave it if less than "a"
jb tocaps1
cmp al,"z" ;Leave it if greater than "z"
ja tocaps1
and byte ptr [si-1],0DFh ;Capitalize it
jmp tocaps1 ;Loop until done
;
; Parse the command line for a function key identifier.
;
parse: mov dx,offset errmsg1 ;Initialize error pointer
mov si,81h ;Reset SI
call findchar ;Find first parameter
jc error ;Error if nothing found
cmp byte ptr [si],"A" ;Is the character an "A?"
jne not_alt ;No, then branch
mov cx,3 ;Set CX to string length
mov di,offset altkey ;Point DI to "ALT"
add adder1,45 ;Update adders
add adder2,6
repe cmpsb ;Compare the strings
jne error ;Error if they don't match
jmp short checkdash
not_alt: cmp byte ptr [si],"C" ;Is the character a "C?"
jne not_ctrl ;No, then branch
mov cx,4 ;Set CX to string length
mov di,offset ctrlkey ;Point DI to "CTRL"
add adder1,35 ;Update adders
add adder2,4
repe cmpsb ;Compare the strings
jne error ;Error if they don't match
jmp short checkdash
not_ctrl: cmp byte ptr [si],"S" ;Is the character an "S?"
jne fkey ;No, then branch
mov cx,5 ;Set CX to string lemgth
mov di,offset shiftkey ;Point DI to "SHIFT"
add adder1,25 ;Update adders
add adder2,2
repe cmpsb ;Compare the strings
jne error1 ;Error if they don't match
checkdash: lodsb ;Get the next character
cmp al,"-" ;Should be a hyphen
jne error1 ;Error if it's not
fkey: lodsb ;Get next character
cmp al,"F" ;Is it "F?"
je fkey1 ;Branch if it is
error1: jmp error ;Error if it's not
fkey1: call asc2bin ;Convert to binary
mov dx,offset errmsg1 ;Initialize error pointer
jc error1 ;Exit on error
cmp al,1 ;Error if number is less
jb error1 ; than 1
cmp al,12 ;Error if number is greater
ja error1 ; than 12
cmp al,10 ;Is it F1 through F10?
jbe fkey2 ;Branch if it is
add al,adder2 ;Convert to ANSI.SYS code
jmp short fkey3 ;Branch around the next line
fkey2: add al,adder1 ;Convert to ANSI.SYS code
fkey3: mov di,offset command+4 ;Point DI to end of command
call bin2asc ;Convert binary to ASCII
mov al,";" ;Append a semicolon
stosb
;
; Parse the command line for a command string.
;
call findchar ;Find next parameter
jnc fkey4 ;Branch if one found
mov si,offset command+2 ;Point SI to key code
mov cx,di ;Compute length of string
sub cx,offset command+3 ; entered thus far
rep movsb ;Copy the key code
jmp short exit ;Output and exit
fkey4: movsb ;Copy the next character
mov dx,offset errmsg1 ;Initialize error pointer
cmp byte ptr [si-1],22h ;Error if it was not a
jne error1 ; quotation mark
fkey5: lodsb ;Read another character
cmp al,0Dh ;Error if it's a carriage
je error1 ; return
cmp al,22h ;Branch if it's a quotation
je fkey7 ; mark
cmp al,"$" ;Branch if character is not
jne fkey6 ; a dollar sign
call convert_mstring ;Convert metastring if it is
fkey6: stosb ;Write it to the string
jmp fkey5 ;Loop back for more
fkey7: cmp byte ptr [si],"*" ;Is next character a "*"?
jne fkey8 ;Branch if it's not
mov byte ptr [di],0Dh ;Append a carriage return
inc di
fkey8: stosb ;Add closing quotation mark
;
; Output the command string to ANSI.SYS and terminate.
;
exit: mov ax,0070h ;Append a "p" and binary
stosw ; zero to the command
mov si,offset command ;Transmit the string to
call dos_out ; ANSI.SYS
mov ax,4C00h ;Exit with ERRORLEVEL=0
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
;****************************************************************************
; FINDDELIM advances SI to the next space or comma character. On return,
; carry set indicates EOL was encountered.
;****************************************************************************
finddelim proc near
lodsb ;Get the next character
cmp al,20h ;Exit if space
je fd_exit
cmp al,2Ch ;Exit if comma
je fd_exit
cmp al,0Dh ;Loop back for more if end
jne finddelim ; of line isn't reached
dec si ;Set carry and exit
stc
ret
fd_exit: dec si ;Clear carry and exit
clc
ret
finddelim endp
;****************************************************************************
; SCANHELP scans the command line for a /? switch. If found, carry returns
; set and SI contains its offset. If not found, carry returns clear.
;****************************************************************************
scanhelp proc near
push si ;Save SI
scanloop: lodsb ;Get a character
cmp al,0Dh ;Exit if end of line
je scan_exit
cmp al,22h ;Branch if it's a quotation
je skip ; mark
cmp al,"?" ;Loop if not "?"
jne scanloop
cmp byte ptr [si-2],"/" ;Loop if not "/"
jne scanloop
add sp,2 ;Clear the stack
sub si,2 ;Adjust SI
stc ;Set carry and exit
ret
scan_exit: pop si ;Restore SI
clc ;Clear carry and exit
ret
skip: lodsb ;Get a character
cmp al,0Dh ;Exit if end of line
je scan_exit
cmp al,22h ;Reenter the loop if it's
je scanloop ; a quotation mark
jmp skip ;Continue scanning
scanhelp endp
;****************************************************************************
; CONVERT_MSTRING converts a $B, $G, $L, $T, or $$ into a single character.
; On entry, AL holds the ASCII code for the dollar sign that prompted the
; call. On exit, AL holds the character to be used in the command.
;****************************************************************************
convert_mstring proc near
mov ah,7Ch ;Substitute "|" for $B
cmp byte ptr [si],"b"
je cm_convert
cmp byte ptr [si],"B"
je cm_convert
mov ah,3Eh ;Substitute ">" for $G
cmp byte ptr [si],"g"
je cm_convert
cmp byte ptr [si],"G"
je cm_convert
mov ah,3Ch ;Substitute "<" for $L
cmp byte ptr [si],"l"
je cm_convert
cmp byte ptr [si],"L"
je cm_convert
mov ah,14h ;Substitute Ctrl-T for $T
cmp byte ptr [si],"t"
je cm_convert
cmp byte ptr [si],"T"
je cm_convert
mov ah,24h ;Substitute "$" for $$
cmp byte ptr [si],"$"
je cm_convert
cmp byte ptr [si],"$"
jne cm_exit
cm_convert: mov al,ah ;Store code in AL
inc si ;Skip next character
cm_exit: ret ;Exit to caller
convert_mstring 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
;****************************************************************************
; BIN2ASC converts a binary value in AX to ASCII form. On entry, ES:DI
; holds the address the string will be written to.
;****************************************************************************
bin2asc proc near
mov bx,10 ;Initialize divisor word and
xor cx,cx ; digit counter
b2a1: inc cx ;Increment digit count
xor dx,dx ;Divide by 10
div bx
push dx ;Save remainder on stack
or ax,ax ;Loop until quotient is zero
jnz b2a1
b2a2: pop ax ;Retrieve a digit from stack
add al,30h ;Convert it to ASCII
stosb ;Store it
loop b2a2 ;Loop until done
ret
bin2asc endp
;****************************************************************************
; DOS_OUT outputs the ASCIIZ string pointed to by DS:SI.
;****************************************************************************
dos_out proc near
lodsb ;Get a character
or al,al ;Exit if it's zero
jz dos_exit
mov ah,02h ;Output it using DOS
mov dl,al ; function 02H
int 21h
jmp dos_out ;Loop until done
dos_exit: ret
dos_out endp
code ends
end begin