home *** CD-ROM | disk | FTP | other *** search
- page 66,132
- ;============================================================================
- ; ALIAS.COM adds a command line stack, a command line editor, and
- ; an alias function to COMMAND.COM. Syntax is:
- ;
- ; ALIAS [alias [command]] [/F filename] [/S nn] [/U]
- ; [/B] [/E] [/D] [/L] [/U] [/*] [//]
- ;
- ; where /B = Set size of buffer for future alias commands
- ; /D = Disable alias translation
- ; /E = Enable alias translation
- ; /F = Filename of file with list of commands
- ; /L = List aliases currently in list
- ; /M = Set minimum command length to save
- ; /S = Size of command line stack where "nn" is the number of commands
- ; to save
- ; /U = Uninstall the program
- ; /* or // = Comment. Ignore remainder of the line.
- ;
- ;
- ; Revision History:
- ;
- ; Version 1.0 Initial Release PC Magazine Vol 8 Num 22
- ;
- ;============================================================================
-
- code segment
- assume cs:code
-
- org 2ch
- env_segment dw ? ;Word containing the segment
- ; of the program's env. block.
- org 80h
- command_tail db ? ;Offset of the command tail.
-
- org 100h
-
- main: jmp initialize
- program db 13,10,"ALIAS 1.0 "
- copyright db "(c) 1989 Ziff Communications Co.",10,13
- authors db "PC Magazine ",254," Doug Boling and Jeff Prosise"
- db 10,13,"$",1Ah
-
- cmdcom_psp dw 0 ;Segment of COMMAND.COM PSP
- master_env dw 0 ;Segment of master environment
-
- cef_pointer dd ? ;Pointer to critical err flag
- dos_version dw 0 ;DOS Version number
-
- chk_alias db 1 ;Alias enable flag.
- aliaslist_ptr dd ? ;Pointer to alias list.
- aliaslist_size dw 0f600h ;Pointer to end of list seg
- work_buff_ptr dw ? ;Pointer to alias working buff
-
- cmdstack_base dw ?
- cmdstack_size dw 16 ;Size of command stack.
- minlength db 1 ;Minimum len of cmd to stack
-
- mystack_ptr dw offset end_of_resident + 512 ;Ptr to internal stack
- saved_ss dw ?
- saved_sp dw ?
- int21h dd -1 ;Int 21 vector (DOS)
- int2fh dd -1 ;Int 2f vector (DOS MULTIPLEX)
-
- multiplex_id db 0dbh ;Program ID for multiplex int
-
- points dw ? ;Scan lines per character
- columns db ? ;Number of screen columns
- cursor_mode dw ? ;Cursor mode
- bufferptr db ? ;Input buffer pointer
- next_ptr dw 0 ;Address where next command
- ; will be stored
- cmd_ptr dw 0 ;Address of current command
- ; in command stack
- insert_flag db 0 ;0 = insert off, 1 = on
- exkeys db 71,72,75,77,79,80 ;Extended keycode list
- db 82,83,115,116,117
- exkeys_end = $
-
- ex_entry dw offset ctrl_end ;Jump table for extended
- dw offset ctrl_right ; keycodes
- dw offset ctrl_left
- dw offset delete
- dw offset toggle_ins
- dw offset next_cmd
- dw offset eol
- dw offset move_right
- dw offset move_left
- dw offset prev_cmd
- dw offset home
-
- ;============================================================================
- ; DOSINT processes calls to interrupt 21h
- ;============================================================================
- dosint proc far
- assume cs:code,ds:nothing,es:nothing
- cmp ah,0ah ;Check for char input
- je dosint_1 ;If so, continue
- goto_dos:
- jmp cs:[int21h] ;else pass the call to DOS
- ;
- ;Compare the active PSP with COMMAND.COM PSP.
- ;
- dosint_1:
- push ax ;Save registers
- push bx
- mov ah,51h ;Get active PSP segment
- cmp word ptr cs:[dos_version],310h
- jb early_dos
- pushf
- call cs:[int21h]
- jmp short chkpsp1
- early_dos:
- push es ;If before DOS 3.1, set
- les bx,cs:[cef_pointer] ; critical error flag to
- inc byte ptr es:[bx] ; force DOS to use the aux
- pushf ; stack.
- call cs:[int21h] ;Get active PSP segment
- mov ax,bx
- les bx,cs:[cef_pointer] ;Reset critical error flag
- dec byte ptr es:[bx]
- mov bx,ax
- pop es
- chkpsp1:
- cmp bx,cs:[cmdcom_psp]
- je dosint_2
- pop bx ;Else, cleanup and goto DOS
- pop ax
- jmp short goto_dos
- dosint_2:
- cld ;Set direction flag
- mov cs:[saved_ss],ss ;Save SS:SP
- mov cs:[saved_sp],sp
- cli
- push cs ;Move to internal stack
- pop ss
- mov sp,cs:[mystack_ptr]
- sti
- push bp ;Save remaining registers.
- mov bp,sp ;Set up stack access
- push cx
- push dx
- push di
- push si
- push ds
- push es
- ;
- ;The call is from COMMAND.COM. Invoke line editor.
- ;
- push dx
- call cmd_input
- pop dx
- cmp cs:[cmdstack_size],0
- je dosint_3
- call cmd_record
- ;
- ;Check for alias before returning to COMMAND.COM
- ;
- dosint_3:
- cmp cs:[chk_alias],0 ;See if alias translation
- je dosint_exit ; is enabled.
- mov si,[bp-4] ;Get pointer to input buffer
- inc si
- xor cx,cx
- or cl,ds:[si] ;Get length of buffer
- je dosint_exit ;If buffer empty, exit.
- inc si ;Point to 1st char in buffer
- mov ax,cs
- mov es,ax ;Set ES to installed code.
- call searchalias ;See if an alias is found.
- jc dosint_exit ;No, exit.
- ;
- ;If alias found, copy it from alias list to internal buffer.
- ;
- mov si,di ;Load SI with alias pointer
- mov ax,es
- mov ds,ax ;Point DS to alias list seg
- xor cx,cx
- mov cl,ds:[si+3] ;Get size of alias
- call getalias ;Get alias from list
- ;
- ;Append remainder of command line to alias if no cmd line parameters were used.
- ;
- or dx,dx ;See if any command line
- jne dosint_6 ; parameters were used.
- push si ;Save pointer to buffer.
- push ds
- mov di,si
- add di,cx ;Point DI to end of alias
- mov dx,cx ;Save length of alias
- mov si,[bp-4] ;Point DS:SI to command.com
- mov ds,[bp-10] ; data buffer.
- xor cx,cx
- inc si
- mov cl,[si] ;Get length of command line.
- cmp ah,cl ;See if enough space in
- ja dosint_4 ; internal buffer. If not
- mov cl,ah ; copy only until buff full.
- dosint_4:
- inc si
- mov bl,1 ;Skip past alias.
- call scan4char
- jc dosint_5
- dec si ;Back up 1 char
- inc cx
- add dx,cx ;Add length of command line.
- rep movsb ;Copy command line
- dosint_5:
- mov cx,dx ;Restore length of command
- pop ds ;Restore pointer
- pop si
- ;
- ;Copy alias from internal buffer to COMMAND.COM data buffer.
- ;
- dosint_6:
- mov di,[bp-4] ;Point ES:DI to command.com
- mov es,[bp-10] ; data buffer.
- mov al,es:[di] ;Get size of data buffer
- dec al ;If alias longer than buffer,
- cmp al,cl ; copy only the enough
- ja dosint_7 ; characters to fill the
- xor cx,cx ; buffer.
- mov cl,al
- dosint_7:
- inc di ;Move DI past length bytes
- mov es:[di],cl ;Save length of command
- inc di
- rep movsb ;Copy alias.
- mov byte ptr es:[di],13 ;Append carriage return
- dosint_exit:
- mov cx,cs:[cursor_mode] ;Set default cursor
- mov ah,1
- int 10h
- pop es
- pop ds
- pop si
- pop di
- pop dx
- pop cx
- pop bp
- cli
- mov ss,cs:[saved_ss] ;Restore stack pointer
- mov sp,cs:[saved_sp]
- pop bx
- pop ax
- iret ;Return to COMMAND.COM
- dosint endp
-
- ;-----------------------------------------------------------------------------
- ; GETALIAS Copies an alias from the alias list while substituting any
- ; environment variables and command line parameters.
- ; Entry: DS:SI - pointer to alias
- ; Exit: DS:SI - pointer to buffer containing translated alias.
- ; AH - free space in buffer
- ; CX - length of the alias
- ;-----------------------------------------------------------------------------
- getalias proc near
- mov di,work_buff_ptr ;Point DI to internal buffer
- xor ax,ax ;Point to command by adding
- mov al,ds:[si+2] ; the size of the alias to
- add si,ax ; pointer to the entry.
- add si,4 ;Move past list data.
- mov ah,126 ;AH contains max size of buff
- xor dx,dx ;Clear flag for line params
- alias_1:
- lodsb ;Get byte from alias
- cmp al,"%" ;See if special character
- je alias_3 ;Yes, process special char.
- alias_2:
- stosb ;Store byte from alias
- dec ah ;Dec buffer size counter
- jz alias_6 ;If internal buffer full, done
- loop alias_1
- jmp short alias_6 ;If at end of alias, done
- ;
- ;A percent sign has been found indicating a 'soft' parameter.
- ;
- alias_3:
- mov al,ds:[si] ;Get character after %
- cmp al,"%" ;If double %, include in one
- je alias_4 ; % in alias.
- mov bh,al ;Copy and check to see if
- sub bh,"0" ; the next char is a number.
- jb alias_5 ; If so, assume a line
- cmp bh,9 ; parameter.
- ja alias_5
- call sublineparam ;Substitute a line paramter
- inc dx
- alias_4:
- inc si ;Move SI past number or
- dec cx ; trailing % sign.
- loop alias_1
- jmp short alias_6 ;If at end of alias, done
- alias_5:
- call subenvvar ;Substitute an environment var
- loop alias_1
- alias_6:
- mov si,work_buff_ptr ;Point SI to internal buffer
- mov cx,di ;Compute size of completed
- sub cx,si ; alias.
- ret
- getalias endp
-
- ;-----------------------------------------------------------------------------
- ; SUBLINEPARAM substitutes a parameter from the command line into the alias.
- ; Entry: DS:SI - pointer to alias
- ; ES:DI - pointer to buffer to copy the line parameter
- ; AH - remaining space in the internal buffer
- ; BH - binary number of the line parameter
- ; CX - length of the alias
- ; Exit: ES:DI - pointer to byte after the parameter in the buffer
- ; DS:SI - pointer to the character after the line parameter number
- ; CX - remaining length of the alias
- ;-----------------------------------------------------------------------------
- sublineparam proc near
- push cx
- push si
- push ds
- mov si,[bp-4] ;Get pointer to command.com
- mov ds,[bp-10] ; data buffer.
- xor cx,cx
- mov cl,ds:[si+1] ;Get number of chars in buffer.
- inc si ;Point to the first byte of
- inc si ; data.
- sublineparam_1:
- or bh,bh ;Check count of param to find.
- jz sublineparam_2
- mov bl,1
- call scan4char ;Find next space
- jc sublineparam_exit
- dec bl
- call scan4char ;Find next word
- jc sublineparam_exit
- dec bh ;Dec parameter count
- jne sublineparam_1 ;If not done, loop back.
- dec si ;Backup to 1st char in word.
- sublineparam_2:
- lodsb ;Get character from parameter
- cmp al," " ;If space, parameter done
- jbe sublineparam_exit
- stosb
- dec ah ;Dec buffer size counter
- jnz sublineparam_2
- sublineparam_exit:
- pop ds
- pop si
- pop cx
- ret
- sublineparam endp
-
- ;-----------------------------------------------------------------------------
- ; SUBENVVAR substitutes an environment variable into alias.
- ; Entry: DS:SI - pointer to variable to substitute
- ; ES:DI - pointer to buffer to copy the contents of the variable
- ; AH - remaining space in internal buffer
- ; CX - length of alias string
- ; Exit: DS:SI - pointer to the byte after the variable name
- ; ES:DI - pointer to the byte after the variable contents
- ; CF - set if variable not found
- ;-----------------------------------------------------------------------------
- subenvvar proc near
- push dx
- push ds
- push es
- ;
- ;Compute the length of the variable name.
- ;
- mov bx,di ;Save pointer to internal buff
- mov di,si ;Compute the length of the
- mov dx,cx ; environment variable by
- mov al,"%" ; searching for the trailing
- repne scasb ; % sign.
- sub dx,cx ;Compute length of variable.
- dec dx ;Subtract % byte fron length.
- push di ;Save ptr to end of env var.
- ;
- ;Search the Master Environment block for the variable pointed to by DS:SI
- ;
- mov es,cs:[master_env] ;Get segment of master env blk
- xor di,di ;Point ES:DI to environment.
- push cx ;Save alias size.
- push bx ;Save ptr to internal buffer
- mov bx,si ;Save pointer to var name
- subenvvar_1:
- mov si,bx ;Get back ptr to var name.
- mov cx,dx ;Compare env var to var in
- repe cmpsb ; alias.
- je subenvvar_2 ;Variable found, exit loop
- xor al,al ;Find next environment var.
- mov cx,-1 ;Scan the entire segment.
- repne scasb
- cmp byte ptr es:[di],0 ;If double zero, end of env
- jne subenvvar_1 ; block. else, loop back.
- pop di ;Restore DI and exit
- jmp short subenvvar_exit
- ;
- ;Environment variable found. Substitute into alias.
- ;
- subenvvar_2:
- mov si,es ;DS:SI points to env string
- mov ds,si ;ES:DI points to internal buff
- mov si,cs
- mov es,si
- mov si,di ;Copy pointer to var contents.
- pop di ;Restore ptr to internal buff
- subenvvar_3:
- lodsb ;Move environment pointer past
- cmp al,"=" ; the equals sign.
- jne subenvvar_3
- subenvvar_4:
- lodsb ;Move pointer to first
- cmp al," " ; non-space character.
- jb subenvvar_4
- subenvvar_5:
- or al,al ;See if at the end of variable
- je subenvvar_exit
- stosb ;Save character in command
- lodsb ;Get next character
- dec ah ;Dec buffer size count.
- jne subenvvar_5 ;If buffer not full, continue
- subenvvar_exit:
- pop cx ;Restore alias length
- pop si ;Restore alias pointer
- pop es ;Restore segment registers
- pop ds
- pop dx
- ret
- subenvvar endp
-
- ;-----------------------------------------------------------------------------
- ; SUBKEY searches the alias list for a key substitution
- ; Entry: AL - extended key code
- ; Exit: CF - clear if key found, set if not found
- ; DX - offset address of matching entry in alias list (if CF = 0)
- ; CX - length of matching entry (if CF = 0)
- ;-----------------------------------------------------------------------------
- subkey proc near
- push bx
- push di
- push si
- push ds
- push es
- xor ah,ah ;Indicate extended code.
- les di,cs:[aliaslist_ptr] ;Get pointer to alias list.
- subkey_1:
- mov dx,es:[di] ;Get next entry offset
- cmp dx,-1 ;See if at the end of the list
- je subkey_notfound
- cmp es:[di+4],ax ;Check for key code.
- je subkey_found ;If found, exit loop
- subkey_2:
- add di,dx ;Else, point to next entry.
- jmp short subkey_1
- ;
- ;Copy alias into internal buffer.
- ;
- subkey_found:
- mov si,di ;Load SI with alias pointer
- mov ax,es
- mov ds,ax ;Point DS to alias list seg
- xor cx,cx
- mov cl,ds:[si+3] ;Get size of alias
- call getalias ;Get alias from list
- mov dx,si ;Copy pointer to buffer
- clc ;Set key found flag
- subkey_exit:
- pop es
- pop ds
- pop si
- pop di
- pop bx
- ret
- subkey_notfound:
- stc ;Set key not found flag
- jmp subkey_exit
- subkey endp
-
- ;-----------------------------------------------------------------------------
- ; SEARCHALIAS searches the alias list for a matching alias.
- ; Entry: DS:SI - pointer to alias
- ; ES - segment of installed code
- ; CX - length input buffer
- ; Exit: CF - clear if alias found
- ; ES:DI - pointer to matching entry in alias list, if CF is clear
- ;-----------------------------------------------------------------------------
- searchalias proc near
- push bx ;Save registers
- push cx
- push si
- xor bx,bx
- searchalias_1:
- lodsb ;Compute the length of the
- or al,al ; length of the alias by
- je searchalias_2 ; finding the next space.
- cmp al," " ;Allow zero byte in alias
- jbe searchalias_3 ; for function key labels.
- searchalias_2:
- inc bx
- loop searchalias_1
- searchalias_3:
- pop si
- les di,es:[aliaslist_ptr] ;Get pointer to alias list.
- mov cx,bx ;Get length of alias
- searchalias_4:
- mov bx,es:[di]
- cmp bx,-1 ;See if at the end of the list
- je searchalias_notfound
- cmp es:[di+2],cl ;Compare lengths
- jne searchalias_5
- push cx ;Save size and starting
- push di ; pointers.
- push si
- add di,4 ;Point to start of alias field.
- repe cmpsb ;Compare alias to input string
- pop si
- pop di
- pop cx
- je searchalias_6 ;If found, exit loop
- searchalias_5:
- add di,bx ;Else, point to next entry.
- jmp short searchalias_4
- searchalias_6:
- clc ;Set alias found flag
- searchalias_exit:
- pop cx
- pop bx
- ret
- searchalias_notfound:
- stc
- jmp short searchalias_exit
- searchalias endp
-
- ;-----------------------------------------------------------------------------
- ; SCAN4CHAR scans a string to find the first character.
- ; Entry: SI - pointer to ASCII string
- ; BL - 0 = find next char, 1 = find next space
- ; CX - file length
- ; Exit: AL - first nonspace character
- ; CF - set if carriage return found
- ;-----------------------------------------------------------------------------
- scan4char proc near
- assume ds:nothing,es:nothing
- scan4loop:
- jcxz scan4_eol ;See if at the end of the file.
- lodsb
- dec cx ;Decrement file length counter.
- cmp al,13 ;Check for carriage return.
- jne scan4_1
- scan4_eol:
- stc
- jmp short scan4_exit1
- scan4_1:
- or bl,bl ;Check if searching for space
- jne scan4_2 ; or character.
- cmp al," " ;Check for space or other
- jbe scan4loop ; 'white' characters.
- jmp short scan4_exit
- scan4_2:
- cmp al," " ;Check for characters.
- ja scan4loop
- scan4_exit:
- clc
- scan4_exit1:
- ret
- scan4char endp
-
- ;----------------------------------------------------------------------------
- ; CMD_INPUT replaces DOS' 0Ah text input function.
- ;----------------------------------------------------------------------------
- cmd_input proc near
- push ds ;Save DS
- xor ax,ax ;Then zero it
- mov ds,ax
- mov ax,ds:[0485h] ;Get number of scan lines
- cmp ax,cs:[points] ; per character and branch
- je cmd1 ; if it hasn't changed
-
- mov cs:[points],ax ;Record new number of scan
- mov ax,ds:[0460h] ; lines per character and
- mov cs:[cursor_mode],ax ; cursor mode
- cmd1:
- pop ds ;Restore DS
- call set_cursor ;Set cursor mode
-
- mov ah,15 ;Get video page and columns
- int 10h
- dec ah ;Calculate max column number
- mov cs:[columns],ah ;Save it
- mov ax,ds ;Point ES:DI to buffer
- mov es,ax
- mov di,dx
- add di,2
- mov si,dx ;Point DS:SI to character count
- inc si
- mov byte ptr [si],0 ;Zero initial count
- mov cs:[bufferptr],1 ;Set initial index value
- cld ;Clear DF
- ;
- ;Wait for a keycode to appear in the keyboard buffer.
- ;
- getkey: mov ah,0Bh ;Check buffer for keycode
- int 21h
- or al,al ;Anything there?
- jne getchar ;Yes, then go get it
- int 28h ;No, then execute interrupt 28h
- jmp getkey ;Loop back for another try
- ;
- ;Read the keycode and process it if it's not an extended code.
- ;
- getchar:
- mov ah,8 ;Read character from buffer
- int 21h
- or al,al ;Is it an extended code?
- je excode ;Yes, then branch
-
- cmp al,8 ;Backspace key?
- jne getc1 ;No, then branch
- call backspace ;Rub out a character
- jmp getkey ;Return to loop
- getc1:
- cmp al,9 ;Tab key?
- jne getc2 ;No, then branch
- call tab ;Tab to next tab boundary
- jmp getkey ;Return to loop
- getc2:
- cmp al,27 ;ESC key?
- jne getc3 ;No, then branch
- call clear_line ;Yes, then clear input line
- mov cs:[cmd_ptr],0 ;Zero current command pointer
- jmp getkey
- getc3:
- cmp al,7Fh ;Ctrl-Backspace?
- jne getc4 ;No, then branch
- call ctrl_bs ;Yes, then delete word
- jmp getkey
- getc4:
- cmp al,13 ;ENTER key?
- je enter ;Yes, then branch
- call printchar ;No, then print the character
- getc5:
- jmp getkey
- enter:
- call eol ;Place cursor at end-of-line
- mov byte ptr es:[di],13 ;Insert carriage return code
- mov ah,2 ;Advance to next line
- mov dl,13
- int 21h
- get_exit:
- ret
- ;
- ;Process extended keycodes.
- ;
- excode:
- mov ah,8 ;Read extended code
- int 21h
-
- cmp al,3Bh ;See if below F1
- jb excode3
- cmp al,71h ;See if above Alt-F10
- ja excode3
- cmp al,54h ;See if above Shift-F1
- jae excode1
- cmp al,44h ;See if above F10
- ja excode3
- excode1:
- call subkey ;Scan alias list for match
- jc getkey ;Exit if no match found
- push cx
- push dx
- call clear_line ;Clear command line
- pop dx
- pop cx
- excode2:
- push si
- mov si,dx ;Copy offset address into SI
- mov al,byte ptr cs:[si] ;Get next character
- pop si
- cmp al,13 ;Exit and execute command
- je enter ; on carriage return
- inc dx
- push cx
- push dx
- call printchar ;Print it
- pop dx
- pop cx
- jc getc5
- loop excode2 ;Loop until done
- jmp getkey ;Return to input loop
- excode3:
- push es ;Save buffer address
- push di
- mov cx,cs ;Point ES:DI to list of
- mov es,cx ; supported keycodes
- mov di,offset exkeys
- mov cx,offset exkeys_end - offset exkeys
- repne scasb ;Scan list
- pop di ;Clear the stack
- pop es
- jne excode4 ;Ignore if key not found
- shl cx,1 ;Convert CX to address
- add cx,offset ex_entry
- push bx ;Save page number in BH
- mov bx,cx ;Get entry address from table
- mov ax,cs:[bx]
- pop bx ;Restore BH
- call ax ;Call handling routine
- excode4:
- jmp getkey ;Return to input loop
- cmd_input endp
-
- ;------------------------------------------------------------------------------
- ; PREV_CMD outputs the previous command in the command stack.
- ;------------------------------------------------------------------------------
- prev_cmd proc near
- mov dx,cs:[cmd_ptr] ;Get current stack index
- cmp dx,cs:[cmdstack_size] ;Exit if at top of command
- je prev_exit ; stack
- or dx,dx ;Branch if not at bottom of
- jnz prev1 ; command stack
- ;
- ;Copy the current contents of the command line to the search buffer.
- ;
- mov cl,[si] ;Get count of characters on
- xor ch,ch ; command line in CX
- inc cx
- push es ;Save registers
- push di
- push si
- mov ax,cs ;Point ES:DI to search text
- mov es,ax ; buffer
- mov di,offset command_tail
- rep movsb ;Copy command line text
- pop si ;Restore registers
- pop di
- pop es
- ;
- ;Search for the previous command and output it.
- ;
- prev1:
- inc dx ;Increment stack index
- mov ax,cs:[next_ptr] ;Get stack base index
- sub ax,dx ;Calculate address of previous
- cmp ax,0 ; command
- jge prev2
- add ax,cs:[cmdstack_size]
- prev2:
- mov cl,7 ;Calculate offset address of
- shl ax,cl ; the command
- add ax,cs:[cmdstack_base]
- cmp byte ptr cs:[command_tail],0 ;Output command if there is
- je prev3 ; no search criterion
- call check_string ;Compare strings
- jz prev3 ;Output command if the strings
- cmp dx,cs:[cmdstack_size] ; match
- jne prev1
- ret ;Exit if at top of stack
- prev3:
- push si ;Save SI
- mov si,ax ;Transfer address to SI
- cmp byte ptr cs:[si],0 ;Valid command?
- pop si ;Restore SI
- je prev_exit ;No, then ignore keypress
- mov cs:[cmd_ptr],dx ;Save new command pointer
- call write_command ;Output the command string
- prev_exit:
- ret
- prev_cmd endp
-
- ;------------------------------------------------------------------------------
- ; NEXT_CMD outputs the next command in the command stack.
- ;------------------------------------------------------------------------------
- next_cmd proc near
- mov dx,cs:[cmd_ptr] ;Get current stack index
- or dx,dx ;Exit if it's zero
- jz next_exit
- next1:
- dec dx ;Decrement stack index
- mov cs:[cmd_ptr],dx ;Save command pointer
- or dx,dx ;Clear line and exit if
- jz next3 ; the result is zero
- mov ax,cs:[next_ptr] ;Get stack base index
- sub ax,dx ;Calculate address of next
- cmp ax,0 ; command
- jge next2
- add ax,cs:[cmdstack_size]
- next2:
- mov cl,7 ;Calculate offset address of
- shl ax,cl ; command
- add ax,cs:[cmdstack_base]
- cmp byte ptr cs:[command_tail],0 ;Output command if there is
- je next4 ; no search criterion
- call check_string ;Compare strings
- jz next4 ;Output command if the strings
- jmp next1 ; match
- next3:
- call clear_line
- cmp byte ptr cs:[command_tail],0
- je next_exit
- mov ax,offset command_tail
- next4:
- call write_command ;Output the command string
- next_exit:
- ret
- next_cmd endp
-
- ;------------------------------------------------------------------------------
- ; CHECK_STRING compares the string in the search buffer with another string.
- ; Entry: AX - string address
- ; Exit: ZF - set if strings are equivalent, clear if they are not
- ;------------------------------------------------------------------------------
- check_string proc near
- push ds ;Save registers
- push si
- push es
- push di
- mov cx,cs ;Point DS and ES to
- mov ds,cx ; code segment
- mov es,cx
- mov si,offset command_tail ;Point DS:SI to text in
- mov cl,[si] ; search buffer
- xor ch,ch
- inc si
- mov di,ax ;Point DI to other string
- inc di ;
- repe cmpsb ;Compare strings
- pop di ;Restore registers
- pop es
- pop si
- pop ds
- ret
- check_string endp
-
- ;------------------------------------------------------------------------------
- ; PRINT_STRING writes an ASCII string to the command line.
- ; Entry: DS:SI - string address
- ; CX - number of characters
- ;------------------------------------------------------------------------------
- print_string proc near
- jcxz ps_exit ;Exit if no characters
- push dx
- cld
- mov ah,2 ;Print the character
- ps1:
- lodsb ;Get a byte
- mov dl,al ;Transfer it to DL
- int 21h ;Output character
- loop ps1 ;Loop until done
- pop dx
- ps_exit:
- ret
- print_string endp
-
- ;------------------------------------------------------------------------------
- ; WRITE_COMMAND outputs a command string.
- ; Entry: AX - string offset address
- ; Exit: AL - character after string
- ;------------------------------------------------------------------------------
- write_command proc near
- push ax ;Save address
- call clear_line ;Clear input line
- pop ax ;Retrieve string address
- push ds ;Save DS and SI
- push si
- push cs ;Point DS to string segment
- pop ds
- mov si,ax ;Point SI to the string
- mov cl,[si] ;Get string length
- xor ch,ch
- mov byte ptr es:[di-1],cl ;Store string length
- inc si ;Advance SI to string text
- write1:
- mov ah,2 ;Print one character
- mov dl,[si]
- int 21h
- movsb ;Transfer character to buffer
- inc cs:[bufferptr] ;Advance pointer
- loop write1 ;Loop until done
- lodsb ;Get first character after string
- pop si ;Restore registers
- pop ds
- ret
- write_command endp
-
- ;------------------------------------------------------------------------------
- ; TOGGLE_INS toggles the insert flag.
- ;------------------------------------------------------------------------------
- toggle_ins proc near
- xor cs:[insert_flag],1 ;Toggle insert flag
- call set_cursor ;Set cursor mode
- ret
- toggle_ins endp
-
- ;------------------------------------------------------------------------------
- ; TAB tabs to the next tab boundary.
- ;------------------------------------------------------------------------------
- tab proc near
- mov al,cs:[bufferptr] ;Calculate number of
- dec al ; spaces to insert for
- xor ah,ah ; soft tab
- mov bl,8
- div bl
- mov cx,8
- sub cl,ah
- tab1:
- push cx ;Print spaces
- mov al,32
- call printchar
- pop cx
- jc tab_exit
- loop tab1
- tab_exit:
- ret
- tab endp
-
- ;------------------------------------------------------------------------------
- ; BACKSPACE deletes the character left of the cursor.
- ;------------------------------------------------------------------------------
- backspace proc near
- cmp cs:[bufferptr],1 ;At beginning of command line?
- je bs_exit ;Yes, then ignore it
- mov cl,[si] ;Get count
- sub cl,cs:[bufferptr] ;Calculate distance to end-of-line
- inc cl
- xor ch,ch
- push cx ;Save it
- jcxz bs1 ;Branch if at end-of-line
- ;
- ;Shift all characters right of the cursor in the buffer one slot left.
- ;
- push si ;Save SI and DI
- push di
- mov si,di ;Position them for shifts
- dec di
- rep movsb ;Shift characters right of cursor
- pop di ;Restore registers
- pop si
- ;
- ;Display the new string and update input parameters.
- ;
- bs1:
- call move_left ;Move cursor left
- bs2:
- pop cx ;Retrieve shift count
- push dx ;Save cursor position
- push si ;Save SI
- mov si,di ;Point SI to new part of string
- call print_string ;Print the new part
- mov ah,2 ;Blank the last character
- mov dl,32
- int 21h
- pop si ;Restore registers
- pop dx ;Restore cursor address
- mov ah,2 ;Reset the cursor
- int 10h
- dec byte ptr [si] ;Decrement character count
- bs_exit:
- ret
- backspace endp
-
- ;------------------------------------------------------------------------------
- ; PRINTCHAR writes a new character to the input buffer and echoes it.
- ; Entry: AL - character to print
- ; Exit: CF clear if character printed
- ; CF set if buffer full
- ;------------------------------------------------------------------------------
- printchar proc near
- cmp cs:[insert_flag],0 ;Insert state on?
- jne print3 ;Yes, then branch
- ;
- ;Print a character in overstrike mode.
- ;
- mov cl,[si] ;Get count
- cmp cl,cs:[bufferptr] ;End-of-line?
- jae print2 ;No, then branch
- mov cl,[si-1] ;Get maximum length
- sub cl,[si] ;Subtract current length
- cmp cl,1 ;Buffer full?
- je beep ;Yes, then branch
- print1:
- inc byte ptr [si] ;Increment count
- print2:
- stosb ;Deposit new character
- mov ah,2 ;Then print it
- mov dl,al
- int 21h
- inc cs:[bufferptr] ;Advance buffer pointer
- print_exit:
- clc ;Clear CF and exit
- ret
- beep:
- mov ax,0E07h ;Print ASCII 7 thru BIOS
- int 10h
- stc
- ret
- ;
- ;Print a character in insert mode.
- ;
- print3:
- mov cl,[si-1] ;Get maximum length
- sub cl,[si] ;Subtract current count
- cmp cl,1 ;Buffer full?
- je beep ;Yes, then branch
- mov cl,[si] ;Get count
- cmp cl,cs:[bufferptr] ;End-of-line?
- jb print1 ;Yes, then branch
- sub cl,cs:[bufferptr] ;Calculate number of shifts
- inc cl
- xor ch,ch
- push cx ;Save shift count
- push si ;Save SI
- add di,cx ;Position DI to end-of-line
- mov si,di ;Position SI just before it
- dec si
- std ;Set DF for now
- rep movsb ;Make room for new character
- cld ;Clear DF
- pop si ;Restore SI
- mov es:[di],al ;Deposit new character
- mov ah,3 ;Get cursor position
- int 10h
- pop cx ;Retrieve shift count
- inc cx ;Increment it
- push dx ;Save cursor position
- push si ;Save SI
- mov si,di ;Point SI to current location
- call print_string ;Print new part of string
- pop si ;Restore SI and DX
- pop dx
- mov ah,2 ;Reset cursor position
- int 10h
- inc byte ptr [si] ;Add to character count
- call move_right ;Move cursor right
- jmp print_exit
- printchar endp
-
- ;------------------------------------------------------------------------------
- ; DELETE deletes the character at the cursor.
- ;------------------------------------------------------------------------------
- delete proc near
- mov cl,[si] ;Get count
- cmp cl,cs:[bufferptr] ;End-of-line?
- jb del2 ;Yes, then ignore keypress
- sub cl,cs:[bufferptr] ;Calculate number of shifts
- xor ch,ch ;Byte to word in CX
- push cx ;Save shift count
- jcxz del1 ;Branch if no shifts
- push si ;Save SI and DI
- push di
- mov si,di ;Position registers for shift
- inc si
- rep movsb ;Shift chars right of cursor
- pop di ;Restore registers
- pop si
- del1:
- mov ah,3 ;Get cursor position
- int 10h
- jmp bs2 ;Exit thru BACKSPACE routine
- del2:
- ret
- delete endp
-
- ;------------------------------------------------------------------------------
- ; CTRL_BS deletes the word at the cursor.
- ;------------------------------------------------------------------------------
- lesschars dw ? ;Count of chars deleted
- shiftcount dw ? ;Count of chars shifted
-
- ctrl_bs proc near
- mov cl,[si] ;Exit now if there is nothing
- xor ch,ch ; on the command line
- or cx,cx
- jnz cbs1
- cbs_exit:
- ret
- cbs1:
- cmp cs:[bufferptr],1 ;Exit if the cursor is at the
- je cbs3 ; at the end of the command
- cmp cl,cs:[bufferptr] ; line or if it is under a
- jb cbs_exit ; space; otherwise, move to
- cmp byte ptr [di],32 ; the beginning of the
- je cbs_exit ; current word
- cmp byte ptr [di-1],32
- je cbs3
- cbs2:
- push cx ;Save CX
- call ctrl_left ;Move to start of word
- pop cx ;Restore CX
- cbs3:
- inc cx ;Calculate max number of
- push cx ; characters to search
- mov dl,cs:[bufferptr] ; looking for the next
- xor dh,dh ; word or end-of-line
- sub cx,dx
- push di ;Save DI
- cbs4:
- inc di ;Search until DI addresses
- cmp byte ptr [di],32 ; either the first character
- je cbs5 ; in the next word or the
- cmp byte ptr [di-1],32 ; end of the command line
- je cbs6
- cbs5:
- loop cbs4
- cbs6:
- mov dx,di ;Save final value of DI
- pop di ;Restore DI
- pop cx ;Retrieve count
- mov cs:[lesschars],dx ;Calculate number of chars to
- sub cs:[lesschars],di ; be deleted
- sub cx,dx ;Then calculate how many chars
- add cx,si ; must be shifted
- mov cs:[shiftcount],cx
- jcxz cbs7 ;Branch if no shift
- push si ;Save registers
- push di
- mov si,dx ;Point DS:SI to next word
- rep movsb ;Delete current word
- pop di ;Restore registers
- pop si
- cbs7:
- mov cx,cs:[lesschars] ;Update character counter
- sub [si],cl ; in input buffer
- mov ah,3 ;Save the current cursor
- int 10h ; position on the stack
- push dx
- push si ;Update the text on the
- mov si,di ; command line
- mov cx,cs:[shiftcount]
- call print_string
- pop si
- mov cx,cs:[lesschars]
- cbs8:
- mov ah,2 ;Print as many spaces as
- mov dl,32 ; there were characters
- int 21h ; deleted
- loop cbs8
- pop dx ;Restore cursor position
- mov ah,2 ; and exit
- int 10h
- ret
- ctrl_bs endp
-
- ;------------------------------------------------------------------------------
- ; CTRL_END deletes command line text from the cursor to the end of the line.
- ;------------------------------------------------------------------------------
- ctrl_end proc near
- mov cl,[si] ;Exit if already at end
- cmp cl,cs:[bufferptr] ; of line
- jb ce_exit
- sub cl,cs:[bufferptr] ;Calculate number of chars
- xor ch,ch ; to be deleted
- inc cx
- sub [si],cl ;Update count in input buffer
- push cx
- mov ah,3 ;Get and save cursor position
- int 10h
- pop cx
- push dx
- ce1:
- mov ah,2 ;Print as many spaces as
- mov dl,32 ; there are characters
- int 21h ; to delete
- loop ce1
- mov ah,2 ;Reset cursor position and
- pop dx ; exit
- int 10h
- ce_exit:
- ret
- ctrl_end endp
-
- ;------------------------------------------------------------------------------
- ; MOVE_LEFT moves the cursor one character left.
- ;------------------------------------------------------------------------------
- move_left proc near
- cmp cs:[bufferptr],1 ;At beginning of line?
- je left2 ;Yes, then ignore keypress
- mov ah,3 ;Get cursor position
- int 10h
- dec dl ;Decrement it by 1
- cmp dl,0FFh
- jne left1
- mov dl,cs:[columns] ;Decrement row number by 1
- dec dh ; if cursor wraps around
- left1:
- mov ah,2 ;Set new position
- int 10h
- dec di ;Decrement pointers
- dec cs:[bufferptr]
- left2:
- ret
- move_left endp
-
- ;------------------------------------------------------------------------------
- ; MOVE_RIGHT moves the cursor one character right.
- ;------------------------------------------------------------------------------
- move_right proc near
- mov cl,[si] ;Get count
- cmp cl,cs:[bufferptr] ;End-of-line?
- jb rt2 ;Yes, then ignore keypress
- mov ah,3 ;Get cursor position
- int 10h
- inc dl ;Increment column number
- cmp dl,cs:[columns] ;Increment row number if
- jna rt1 ; cursor wraps around
- xor dl,dl
- inc dh
- rt1:
- mov ah,2 ;Position cursor
- int 10h
- inc di ;Advance pointers
- inc cs:[bufferptr]
- rt2:
- ret
- move_right endp
-
- ;------------------------------------------------------------------------------
- ; CTRL_LEFT moves the cursor one word left.
- ;------------------------------------------------------------------------------
- ctrl_left proc near
- call move_left ;Move one character left
- cmp cs:[bufferptr],1 ;Beginning of line?
- je cl_exit ;Yes, then exit
- cmp byte ptr es:[di],32 ;Loop back if current char
- je ctrl_left ; is a space
- cmp byte ptr es:[di-1],32 ;Loop back if char to the
- jne ctrl_left ; left is not a space
- cl_exit:
- ret
- ctrl_left endp
-
- ;------------------------------------------------------------------------------
- ; CTRL_RIGHT moves the cursor one word right.
- ;------------------------------------------------------------------------------
- ctrl_right proc near
- call move_right ;Move one character right
- mov cl,[si] ;End-of-line?
- cmp cl,cs:[bufferptr] ;Yes, then exit
- jb cr_exit
- cmp byte ptr es:[di],32 ;Loop back if current char
- je ctrl_right ; is a space
- cmp byte ptr es:[di-1],32 ;Loop back if char to the
- jne ctrl_right ; left is not a space
- cr_exit:
- ret
- ctrl_right endp
-
- ;------------------------------------------------------------------------------
- ; HOME relocates the cursor to the beginning of the command line.
- ;------------------------------------------------------------------------------
- home proc near
- mov cl,cs:[bufferptr] ;Get position pointer
- dec cl ;Calculate distance from start
- xor ch,ch
- jcxz home_exit ;Exit if already there
- home1:
- push cx ;Save count
- call move_left ;Move left one space
- pop cx ;Retrieve count
- loop home1 ;Loop until done
- home_exit:
- ret
- home endp
-
- ;------------------------------------------------------------------------------
- ; EOL advances the cursor to the end of the command line.
- ;------------------------------------------------------------------------------
- eol proc near
- mov cl,[si] ;Get count
- cmp cl,cs:[bufferptr] ;Already at end?
- jb eol_exit ;Yes, then exit
- sub cl,cs:[bufferptr] ;Calculate distance from end
- inc cl
- xor ch,ch ;Byte to word in CX
- eol1:
- push cx ;Advance right CX times
- call move_right
- pop cx
- loop eol1
- eol_exit:
- ret
- eol endp
-
- ;------------------------------------------------------------------------------
- ; CLEAR_LINE clears the command line.
- ; Entry: BH - current video page
- ;------------------------------------------------------------------------------
- clear_line proc near
- mov cl,[si] ;Get count
- xor ch,ch
- jcxz cline2 ;Exit if no characters
- push cx ;Save count
- call home ;Home the cursor
- mov ah,3 ;Get cursor position
- int 10h
- pop cx ;Restore CX
- push dx ;Save cursor address
- mov ah,2 ;Print ASCII spaces
- mov dl,32
- cline1:
- int 21h
- loop cline1
- mov ah,2 ;Home cursor again
- pop dx
- int 10h
- mov byte ptr [si],0 ;Reset count
- cline2:
- ret
- clear_line endp
-
- ;------------------------------------------------------------------------------
- ; CMD_RECORD records the latest command in the command stack.
- ; Entry: DS:DX - input buffer address
- ;------------------------------------------------------------------------------
- cmd_record proc near
- mov si,dx ;Point SI to input buffer
- mov al,[si+1] ;Get length of input string
- cmp al,cs:[minlength] ;Is the length zero?
- jb cmd_exit ;Yes, then exit now
- inc si ;Advance SI to count byte
- push cs ;Point ES to command stack
- pop es ; segment
- mov di,cs:[next_ptr] ;Get command stack pointer
- mov cl,7 ;Convert it to offset address
- shl di,cl
- add di,cs:[cmdstack_base]
- mov cl,al ;Transfer string length to CL
- inc cl ;Increment for count byte
- xor ch,ch ;Byte to word in CX
- cld ;Clear DF
- rep movsb ;Copy string to command stack
- inc cs:[next_ptr] ;Update pointer
- mov ax,cs:[cmdstack_size]
- cmp cs:[next_ptr],ax ;Wrap around if necessary
- jne cmdrec1
- mov cs:[next_ptr],0
- cmdrec1:
- mov cs:[cmd_ptr],0 ;Zero current command pointer
- cmd_exit:
- ret
- cmd_record endp
-
- ;------------------------------------------------------------------------------
- ; SET_CURSOR sets the cursor mode based on the state of the insert flag.
- ;------------------------------------------------------------------------------
- set_cursor proc near
- cmp cs:[insert_flag],0 ;Test state of insert flag
- je setc1 ;Branch if not set
- mov cx,cs:[cursor_mode] ;Raise top by 2 scan lines
- sub ch,2
- jns setc2 ;Exit if it wraps around
- ret
- setc1:
- mov cx,cs:[cursor_mode] ;Set default cursor
- setc2:
- mov ah,1 ;Set cursor mode
- int 10h
- ret
- set_cursor endp
-
- ;============================================================================
- ; MUXINT processes calls to interrupt 2Fh
- ; Entry: AH - Device ID
- ; Exit: AL - 0FFh if AH = Alias device ID. Unchanged otherwise.
- ; ES - Code segment if AH = Alias device ID. Unchanged otherwise.
- ;============================================================================
- muxint proc far
- assume cs:code,ds:nothing,es:nothing
- cmp ah,cs:[multiplex_id] ;Check for program ID
- je muxint_1 ;Its us, indicate installed.
- jmp cs:[int2fh] ;else pass the call on
- muxint_1:
- mov al,-1 ;Indicate Alias installed
- push cs ;ES = installed code segment
- pop es
- iret
- muxint endp
-
- even ;Align stack on word boundry
- end_of_resident = $
- ;----------------------------------------------------------------------------
- ; Start of non-resident code.
- ;----------------------------------------------------------------------------
- final_install:
- rep movsb ;Copy alias list
- mov di,cmdstack_base ;Initialize command stack
- mov cx,cmdstack_size ; area with leading zeroes
- jcxz tsr ;Branch if size is zero
- xor al,al
- cld
- final_loop:
- stosb
- add di,127
- loop final_loop
- tsr:
- mov ax,3100h ;Terminate and stay resident
- int 21h
-
- ;----------------------------------------------------------------------------
- ; Non-resident data.
- ;----------------------------------------------------------------------------
- alrdy_installed db 0 ;Installed flag
- other_seg dw 0 ;Segment of installed code
- databuff_seg dw 0 ;Segment of data buffer.
-
- alias_buffer dw 512 ;Extra buffer for alias list.
- aliaslist_end dw 0 ;Offset of end of the list.
- alias_inlist db 0 ;Flag used in alias list append
-
- infomsg1 db "ALIAS uninstalled$"
- infomsg2 db 13,10,9,"Command stack size: $"
- infomsg3 db 13,10,9,"Minimum stacked command length: $"
- infomsg4 db 13,10,9,"Bytes free in alias buffer: $"
- infomsg5 db 13,10,9,"Alias translation is $"
- infomsg5d db "disabled",13,10,"$"
- infomsg5e db "enabled",13,10,"$"
- infomsg6 db 13,10,9,"FUNCTION KEY DEFINITIONS$"
- infomsg7 db 13,10,9,"ALIAS DEFINITIONS$"
- infomsg8 db 13,10,"For help type ALIAS ?$"
-
- filemsg1 db 13,10,"Error in line $" ;File identification message.
- filemsg2 db " of file: "
- filenam_field db 78 dup (0) ;Name of current entry file.
-
- errmsg0 db "Need DOS 2.0 or greater$"
- errmsg1 db "ALIAS not installed$"
-
- errmsg2 db 13,10,"Syntax: ALIAS [alias [command]] "
- db "[/F filename] [/S nn] [/U]",13,10
- db 14 dup (" ")
- db "[/B nn] [/E] [/D] [/L] [/M]",13,10,10
- db 9,"ALIAS alias command",13,10
- db 9,"ALIAS [fn] command",13,10,10
- db 9,"/B = Buffer size",13,10
- db 9,"/D = Disable alias translation",13,10
- db 9,"/E = Enable alias translation",13,10
- db 9,"/F = Filename of command file",13,10
- db 9,"/L = List aliases",13,10
- db 9,"/M = Minimum command length to stack",13,10
- db 9,"/S = Size of command stack",13,10
- db 9,"/U = Uninstall",13,10,"$"
-
- errmsg3 db "Can",39,"t uninstall$"
- errmsg4 db "Can",39,"t change parameter after installation$"
- errmsg5 db "Illegal number$"
- errmsg6 db "Can",39,"t find alias file$"
- errmsg7 db "Can",39,"t find COMMAND.COM$"
- errmsg8 db "Not enough memory$"
- errmsg9 db "Alias list full$"
- errmsg10 db "List and stack too large$"
- errmsg11 db "Invalid key assignment$"
- errmsg12 db "Number too big$"
- errmsg13 db "Alias not in list$"
- errmsg14 db "Error using Int 2Fh$"
- endmsg db 13,10,"$"
-
- shiftmsg db "S-$"
- altmsg db "A-$"
- ctlmsg db "C-$"
-
- file_linecount dw 0 ;Line number being processed.
- caps_flag db 0
- param_found db 0 ;Cmd line parameter found flag
- append_cr db 0 ;Append cr to alias flag
- cmdcom_name db "COMMAND" ;Name of command.com
-
- cmd_switches db "sfeldbum*/" ;Letters of valid commands.
- cmd_switch_end = $
- cmd_jmp_tbl dw offset setstacksize ;This jump table is used to
- dw offset loadaliasfile ; call the routines that
- dw offset enablealias ; process the command line
- dw offset listalias ; arguments
- dw offset disablealias
- dw offset setlistbuffer
- dw offset remove
- dw offset minstacklen
- dw offset comment_line ;Comments can be indicated by
- dw offset comment_line ; a /* or a //.
-
- ;----------------------------------------------------------------------------
- ; Initialization routine.
- ;----------------------------------------------------------------------------
- initialize proc near
- assume cs:code,ds:code,es:code
- cld
- mov ah,30h ;Get DOS version
- int 21h
- xchg al,ah ;Swap major, minor numbers
- mov dx,offset errmsg0 ;Bad DOS version
- cmp ah,2 ;Run if DOS 2.0 or greater.
- jae init1
- jmp_disp_error:
- jmp disp_error
- init1:
- mov dos_version,ax ;Save version number
-
- mov ah,4ah ;Reduce memory allocation to
- mov bx,1000h ; just this segment.
- int 21h
-
- mov ax,offset end_of_code ;Initialize alias list
- mov word ptr [aliaslist_ptr],ax ; pointers.
- mov ax,cs
- mov word ptr [aliaslist_ptr+2],ax
- lds di,aliaslist_ptr ;Initialize alias list
- mov ax,-1 ; by writing a -1 as
- stosw ; an end flag.
- mov aliaslist_end,di
- ;
- ;See if a copy is already resident in memory. If > DOS 3.0, use int 2Fh.
- ;
- mov byte ptr [main+2],0 ;Initialize fingerprint
- cmp dos_version,300h ;See if DOS 3.0 or later
- jb find_copy1 ;No, search the old way.
- mov cx,16 ;Try 16 different IDs.
- find_copy:
- xor ax,ax
- mov es,ax
- mov ah,multiplex_id ;Load ID. Use Int 2Fh to
- int 2fh ; reach installed code so
- or al,al ; that we are compatible
- jne find_copy0 ; with 386 memory managers.
- push cs
- pop es ;If AL not changed, ALIAS not
- jmp short find_copy4 ; installed.
- find_copy0:
- push cx
- call cmpheader ;See if really Alias by
- pop cx ; comparing file headers.
- je find_copy3
- inc multiplex_id ;ID used by another program.
- loop find_copy ; Change and try again.
- mov dx,offset errmsg14 ;All IDs taken, print error
- jmp disp_error ; msg and exit.
- ;
- ;For DOS 2.x find the installed code the old fashioned way by scanning
- ;the memory control blocks.
- ;
- find_copy1:
- xor bx,bx ;zero BX for start
- mov ax,cs ;keep CS value in AX
- find_copy2:
- inc bx ;increment search segment value
- mov es,bx
- assume es:nothing
- cmp ax,bx ;not installed if current
- je find_copy4 ; segment is found.
- call cmpheader
- jne find_copy2 ;loop back if not found
- find_copy3:
- inc alrdy_installed ;Set installed flag
- find_copy4:
- mov other_seg,es ;Save seg of installed code
- ;
- ;Parse the command line for switches.
- ;
- mov ah,48h ;Allocate memory block for
- mov bx,0800h ; alias file buffer.
- int 21h
- mov dx,offset errmsg8 ;Not enough memory msg
- jc jmp_disp_error
- mov databuff_seg,ax ;Save segment to file buffer.
- mov es,ax ;Treat the command line as
- xor di,di ; a 1 line file.
- mov si,offset command_tail
- xor cx,cx
- or cl,[si] ;Get command line length
- je parse_line_end ;If zero, skip parse routine
- inc si ;Copy command line into file
- inc cx ; buffer.
- push cx
- rep movsb
- pop cx ;CX = file size.
- xor si,si ;Point SI to start of buffer
- push es
- pop ds ;Set DS to file buffer seg
- assume ds:nothing
- mov es,cs:[other_seg] ;Set ES to installed code
- ;
- ;Parse command line and command files.
- ;
- parse_line_loop:
- xor bl,bl
- call scanline ;Get 1st character
- jc parse_2 ;If carriage return, skip line
- cmp al,"/" ;Compare character to switch.
- je parse_switch_found
- cmp al,"?" ;See if help character
- je parse_line_error
- call setkey ;Must be alias definition
- jc parse_error
- mov param_found,1 ;Set parameter found flag
- jmp short parse_2 ;Return to parse loop
- parse_line_error:
- mov dx,offset errmsg2 ;Command not found msg
- parse_error: jmp short disp_error
- parse_switch_found:
- mov param_found,1 ;Set parameter found flag
- lodsb ;Get command line switch
- dec cx
- cmp al,'A' ;Convert to lower case if
- jb parse_1 ; necessary.
- cmp al,'Z'
- ja parse_1
- or al,20h
- parse_1:
- push cx ;Scan the list of allowable
- push es ; command switches. If switch
- push cs ; found, use its position for
- pop es ; an index into the list of
- mov di,offset cmd_switches ; routines.
- mov cx,offset cmd_switch_end - offset cmd_switches
- mov bx,offset cmd_switch_end - offset cmd_switches - 1
- repne scasb
- mov ax,cx ;Copy index into list
- pop es
- pop cx
- jne parse_line_error
- sub bx,ax ;Compute offset into list
- shl bx,1 ;Convert to word offset
- add bx,offset cmd_jmp_tbl ;Add the start addr of table.
- call cs:[bx] ;Call command routine.
- jc disp_error ;If error terminate parse.
- parse_2:
- jcxz parse_line_end ;If at file end, exit parse.
- jmp short parse_line_loop
- ;
- ;See if installed. If not, install.
- ;
- parse_line_end:
- cmp cs:[param_found],1 ;See if any parameters found
- je init2 ;If already installed and
- cmp cs:[alrdy_installed],0 ; no parameters on the
- je init2 ; command line, default to
- mov es,cs:[other_seg] ; showing program information
- call listalias
- init2:
- mov ah,49h ;Release memory block used
- mov es,cs:[databuff_seg] ; for file buffer.
- int 21h
- push cs
- pop ds
- assume ds:code
- mov word ptr databuff_seg,0
- cmp alrdy_installed,0 ;If not already installed,
- je install ; jump to install routine.
- exit:
- mov ax,4C00h ;Terminate with RC = 0
- int 21h
- ;
- ;Display error message.
- ;
- disp_error:
- xor ax,ax ;If file buffer still
- or ax,databuff_seg ; allocated, deallocate it.
- jz disp_error0
- mov ah,49h ;Release memory block used
- mov es,ax ; for file buffer.
- int 21h
- disp_error0:
- push cs
- pop ds
- assume ds:code
- cmp byte ptr filenam_field,0
- je disp_error1 ;If processing a file, print
- push dx ; a message informing the
- mov dx,offset filemsg1 ; user the filename being
- call printmsg ; processed and the line
- mov ax,file_linecount ; that the error occured.
- call hex2asc
- mov dx,offset filemsg2
- call printmsgcr
- pop dx
- disp_error1:
- call printmsgcr ;print string
- mov ax,4c01h ;Terminate with RC = 1
- int 21h
- ;
- ;Install routine. Find segment of COMMAND.COM, hook into int 21h, 2Fh and TSR.
- ;
- assume ds:code
- install:
- mov dx,offset program ;Display copyright message
- call printmsg
-
- push ds ;Save DS
- xor ax,ax ;Then zero it
- mov ds,ax
- mov cs:[points],ax ;Record number of scan lines
- mov ax,ds:[0460h] ; per character and cursor
- mov cs:[cursor_mode],ax ; mode
- pop ds ;Restore DS
-
- mov byte ptr filenam_field,0 ;Don't callout file on error
- mov ah,52h ;get address of first MCB
- int 21h
- mov ax,es:[bx-2] ;point ES to MCB
- mov cx,20 ;Allow only 20 loops.
- mcb_loop:
- mov es,ax
- cmp byte ptr es:[0],"M" ;check for mcb signature
- jne mcb_error
- inc ax ;point AX to memory block
- cmp ax,es:[1] ;See if this is a PSP block
- je psp_found
- mcb_continue:
- add ax,es:[3] ;Get size of memory block
- loop mcb_loop
- mcb_error:
- mov dx,offset errmsg7 ;Can't locate command.com PSP
- jmp disp_error
- psp_found:
- cmp dos_version,0400h ;If DOS 4.00 or greater,
- jb psp_found_1 ; COMMAND.COM may not be the
- push ds ; first program loaded. Look
- mov si,offset cmdcom_name ; at the name of the program
- mov di,8 ; stored in the last 8 bytes
- mov cx,7 ; of the memory control
- repe cmpsb ; block. If the string
- pop ds ; "COMMAND" isn't found, keep
- jne mcb_continue ; looking.
- psp_found_1:
- mov cmdcom_psp,ax ;Save segment of cmd.com PSP
- mov es,ax
- mov ax,es:[2ch] ;Get seg of master environment
- mov master_env,ax
- ;
- ;Set up pointers to the cmd stack and to move the alias list to the end of the
- ;command stack so it takes up less space when ALIAS resident.
- ;
- mov di,mystack_ptr ;Get base of internal stack
- mov work_buff_ptr,di ;Copy ptr to alias buffer
- add di,128 ;Add size of buffer
- mov cmdstack_base,di ;Copy for start of cmd stack
- mov ax,cmdstack_size ;Get size of command stack
- mov ah,128 ;128 bytes for each entry
- mul ah
- add di,ax ;Add to cmd stack for
- mov si,word ptr aliaslist_ptr ; start of the
- mov cx,aliaslist_end ; alias list.
- mov word ptr aliaslist_ptr,di ;Save new pointer.
- sub cx,si ;Compute size of list.
- mov dx,di ;See if we have enough room
- add dx,cx ; for everything in one seg.
- jnc install_1
- mov dx,offset errmsg10 ;Not enough memory, exit.
- jmp disp_error
- install_1:
- add dx,alias_buffer ;Add additional space for list
- mov aliaslist_size,dx ;Save pointer to end of seg
- add dx,15 ;Convert memory needed to
- shr dx,1 ; paragraphs.
- shr dx,1
- shr dx,1
- shr dx,1
- cmp di,si ;Check for overlap in the move
- jb install_2 ;If overlap, copy list from
- std ; the top down to avoid
- add di,cx ; overwriting the list.
- add si,cx
- dec si
- dec di
- ;
- ;Revector interrupts 21h and 2Fh (if necessary).
- ;
- install_2:
- mov ax,3521h ;Get interrupt 21 (DOS)
- int 21h ; vector.
- mov word ptr [int21h],bx
- mov word ptr [int21h+2],es
- push dx ;Save memory size parameter
- mov ax,2521h ;Point int 21 to internal
- mov dx,offset dosint ; routine.
- int 21h
-
- cmp dos_version,300h ;See if we are using Int 2Fh
- jb install_3
- mov ax,352fh ;Get interrupt 2F (MUX)
- int 21h ; vector.
- mov word ptr [int2fh],bx
- mov word ptr [int2fh+2],es
- mov ax,252fh ;Point int 2F to internal
- mov dx,offset muxint ; routine.
- int 21h
- install_3:
- pop dx
- push ds ;ES = DS
- pop es
- jmp final_install ;Jump to safe place for move.
- initialize endp
-
- ;-----------------------------------------------------------------------------
- ; CMPHEADER compares the first 16 bytes of this file with the segment
- ; pointed to by ES.
- ; Entry: DS - code segment
- ; ES - pointer to segment to compare
- ; Exit: ZF - 0 = segments match.
- ;-----------------------------------------------------------------------------
- cmpheader proc near
- mov si,offset main+2 ;Search this segment for ASCII
- mov di,si ; fingerprint.
- mov cx,16
- repe cmpsb
- ret
- cmpheader endp
-
- ;-----------------------------------------------------------------------------
- ; PRINTMSG prints the message pointed to by DX to the screen.
- ; Entry: DX - pointer to ASCII message terminated by $
- ;-----------------------------------------------------------------------------
- printmsg proc near
- assume ds:nothing,es:nothing
- push ds
- push cs
- pop ds
- assume ds:code
- mov ah,9 ;Print message
- int 21h
- pop ds
- ret
- printmsg endp
-
- ;-----------------------------------------------------------------------------
- ; PRINTMSGCR calls PRINTMSG, then appends a carriage return to the message.
- ; Entry: DX - pointer to ASCII message terminated by $
- ;-----------------------------------------------------------------------------
- printmsgcr proc near
- assume ds:nothing,es:nothing
- push dx
- call printmsg
- mov dx,offset endmsg
- call printmsg
- pop dx
- ret
- printmsgcr endp
-
- ;-----------------------------------------------------------------------------
- ; SETSTACKSIZE - Sets the size of the command line stack.
- ; Entry: DS:SI - points to stack size in ascii
- ; Exit: CF - Clear if sucessful, Set if error, DX points to error msg.
- ;-----------------------------------------------------------------------------
- setstacksize proc near
- assume ds:nothing,es:nothing
- xor bl,bl ;Check for installed code
- call setparameter ;Get num and convert to binary
- jc setstack_exit ;Check for error
- mov cs:[cmdstack_size],ax ;Save parameter
- setstack_exit:
- ret
- setstacksize endp
-
- ;-----------------------------------------------------------------------------
- ; SETLISTBUFFER - Sets the size of the additional buffer reserved for alias
- ; list expansion.
- ; Entry: DS:SI - points to buffer size in ascii
- ; Exit: CF - Clear if sucessful, Set if error, DX points to error msg.
- ;-----------------------------------------------------------------------------
- setlistbuffer proc near
- assume ds:nothing,es:nothing
- xor bl,bl ;Check for installed code
- call setparameter ;Get num and convert to binary
- jc setlistbuffer_exit ;Check for error
- mov cs:[alias_buffer],ax ;Save buffer size parameter
- setlistbuffer_exit:
- ret
- setlistbuffer endp
-
- ;-----------------------------------------------------------------------------
- ; MINSTACKLEN - sets the minimum legth of a command to stack.
- ; Entry: ES - segment of the installed code
- ; DS:SI - points to buffer size in ascii
- ; Exit: CF - Clear if sucessful, Set if error, DX points to error msg.
- ;-----------------------------------------------------------------------------
- minstacklen proc near
- assume ds:nothing,es:nothing
- mov bl,1 ;Don't check for installed code
- call asc2bin ;Get num and convert to binary
- jc minstacklen_exit ;Check for error
- cmp al,126
- jb minstacklen_1
- mov dx,offset errmsg12 ;Stack length too big
- stc
- jmp short minstacklen_exit
- minstacklen_1:
- or al,al ;Make sure min length is not
- jne minstacklen_2 ; specified at 0. If so,
- inc al ; change to 1.
- minstacklen_2:
- mov es:[minlength],al ;Save minimum length parameter
- minstacklen_exit:
- ret
- minstacklen endp
-
- ;-----------------------------------------------------------------------------
- ; SETPARAMETER - Common code used by the set stack and set buffer and set
- ; minimum command length routines.
- ; Entry: DS:SI - points to ascii number
- ; BL - Flag to indicate check for installed code, BL=0, check.
- ; Exit: CF - Clear if sucessful, Set if error.
- ;-----------------------------------------------------------------------------
- setparameter proc near
- assume ds:nothing,es:nothing
- mov dx,offset errmsg4 ;Can't change parameter msg
- cmp cs:[alrdy_installed],1 ;If already installed don't
- je setparam_error ; change parameter.
- call asc2bin
- setparam_exit:
- ret
- setparam_error:
- stc ;Set error flag.
- jmp short setparam_exit
- setparameter endp
-
- ;-----------------------------------------------------------------------------
- ; SETKEY modifies the alias list to add function key definitions.
- ; Entry: DS:SI - pointer to string identifing the function key
- ; ES - pointer to segment of installed code
- ; Exit: CF - clear if successful
- ;-----------------------------------------------------------------------------
- setkey proc near
- assume ds:nothing,es:nothing
- push es
- cmp al,"[" ;Determine alias or key
- je setkey_1
- dec si ;Backup before last key
- inc cx
- jmp short setkey_5
- setkey_1:
- lodsb ;Get next character
- dec cx
- jcxz setkey_badkey
- mov bx,58 ;Load default F1 keycode
- or al,20h ;Convert to lower case
- cmp al,"f"
- je setkey_3
- add bx,25 ;Assume shift F1 keycode
- cmp al,"s"
- je setkey_2
- add bx,10 ;Assume ctl F1 keycode
- cmp al,"c"
- je setkey_2
- add bx,10 ;Assume alt F1 keycode
- cmp al,"a"
- jne setkey_badkey
- setkey_2:
- lodsb ;Get next character
- dec cx
- or al,20h ;Convert to lower case
- cmp al,"f" ;Make sure next key is "f"
- jne setkey_badkey
- setkey_3:
- call asc2bin
- jc setkey_badkey ;If bad number, exit
- or ax,ax
- je setkey_badkey ;Make sure not zero
- cmp ax,10
- ja setkey_badkey ;Make sure less than 10
- cmp byte ptr [si-1],"]" ;Check for closing bracket
- jne setkey_badkey ; if not found, error
- add bx,ax ;Add in function key number
- cmp byte ptr [si]," " ;Check to see if a character
- jbe setkey_4 ; trails the closing bracket.
- cmp byte ptr [si],"*" ;Check to see if an * is
- jne setkey_badkey ; appended to the function
- lodsb ; key assignment. If so,
- dec cx ; remove key and set flag
- mov cs:[append_cr],1 ; to append cr to command.
- setkey_4:
- sub si,2 ;Back up to keycode.
- xor bh,bh
- mov ds:[si],bx ;Save keycode on command line
- add cx,2
- setkey_5:
- call setalias ;Use SETALIAS to load
- setkey_exit:
- pop es ;Restore ptr to installed seg
- ret
- setkey_badkey:
- mov dx,offset errmsg11 ;Bad key assignment msg
- stc
- jmp setkey_exit
- setkey endp
-
-
- ;-----------------------------------------------------------------------------
- ; SETALIAS modifies the alias list according to command line agruments.
- ; Entry: DS:SI - pointer to string to be inserted into alias list.
- ; ES - pointer to segment of installed code.
- ; Exit: CF - clear if successful
- ;-----------------------------------------------------------------------------
- setalias proc near
- assume ds:nothing,es:nothing
- push es
- xor bl,bl ;Find 1st character on
- call scanline ; command line.
- jnc setalias_1 ;If at end of line, exit
- jmp setalias_exit ; routine.
- setalias_1:
- ;
- ;Get length of alias, then search list for matching alias
- ;
- dec si ;Backup to before 1st char.
- inc cx
- mov byte ptr cs:[alias_inlist],0 ;Assume not in list
- call searchalias ;Is there already an alias?
- jc setalias_2 ;No, continue.
- inc byte ptr cs:[alias_inlist]
- ;
- ;If in list, erase old alias from list.
- ;
- call delete_aliasent ;Delete entry from list
- setalias_2:
- ;
- ;Append new alias to the end of the list.
- ;
- mov bp,di ;Save ptr to end of list.
- add di,4 ;Move past length fields.
- push es ;Get max size of alias list.
- mov es,cs:[other_seg]
- mov dx,es:[aliaslist_size]
- pop es
- ;
- ;Append alias to list.
- ;
- xor ax,ax ;Clear character counter
- setalias_3:
- lodsb ;Get byte
- dec cx ;Decriment buffer counter.
- jcxz setalias_4 ;If at end of file, exit.
- cmp al,13 ;See if at end of line.
- jne setalias_6 ;No, continue.
- setalias_4:
- cmp byte ptr cs:[alias_inlist],0
- jne setalias_5 ;Was alias in list?
- jmp setalias_notnfil ;No, incomplete alias specifed
- setalias_5:
- jmp setalias_exit ;Yes, alias simply erased.
- setalias_6:
- cmp al,' ' ;See if at end of tag.
- je setalias_8 ;Yes, exit copy loop
- cmp al,9 ;Check for tab
- je setalias_8
- cmp di,dx ;See if alias list is full
- jbe setalias_7 ;No, continue
- jmp setalias_full ;Yes, exit routine
- setalias_7:
- stosb ;No, add character to list
- inc ah ;Inc size of tag
- jmp short setalias_3
- setalias_8:
- mov es:[bp+2],ah ;Save size of alias
- ;
- ;Append command to alias list.
- ;
- mov cs:[caps_flag],0 ;Clear environment var flag.
- xor bx,bx ;Find 1st character in
- call scanline ; command.
- jc setalias_exit ;If no command, exit
- xor ah,ah ;Clear character counter
- setalias_9:
- cmp al,"%" ;Check for environment var
- jne setalias_11 ; by checking for % signs.
- cmp cs:[caps_flag],0 ;If caps flag set capitialize
- jne setalias_10 ; string before saving.
- mov bl,ds:[si] ;Get next character
- cmp bl,"0" ;If numberic, assume this is
- jb setalias_10 ; a line parameter, not an
- cmp bl,"9" ; environment variable so
- jbe setalias_11 ; don't set caps flag.
- cmp bl,"%" ;Don't let double % signs
- je setalias_11 ; indicate environment var.
- setalias_10:
- not byte ptr cs:[caps_flag] ;Toggle caps flag
- setalias_11:
- cmp cs:[caps_flag],0 ;Capitialize environment
- je setalias_12 ; variables so they will
- cmp al,"a" ; match when searched for in
- jb setalias_12 ; the environment block.
- cmp al,"z"
- ja setalias_12
- and al,0dfh ;Make character uppercase.
- setalias_12:
- cmp di,dx ;See if alias list is full
- ja setalias_full ;Yes, exit routine
- stosb ;Append character on list
- inc ah ;Inc character counter.
- jcxz setalias_13 ;Check for end of file.
- lodsb ;Get next character
- dec cx ;Dec file counter.
- cmp al,13 ;See if carriage return.
- jne setalias_9 ;If not continue
- setalias_13:
- cmp cs:[append_cr],1 ;If flag set, append carrage
- jne setalias_14 ; return to command.
- mov al,13
- inc ah
- stosb
- mov cs:[append_cr],0 ;Clear flag
- setalias_14:
- mov es:[bp+3],ah ;Save command size
- mov word ptr es:[di],-1 ;Set new end of list flag
- mov ax,di ;Save end pointer to list
- add ax,2 ;Make room for the end flag.
- mov cs:[aliaslist_end],ax
- sub di,bp ;Compute size of entry
- mov es:[bp],di ;Put size over old end flag.
- inc cs:[file_linecount] ;Point counter to next line.
- setalias_exit:
- clc
- setalias_exit1:
- pop es ;Restore ptr to installed seg
- ret
- setalias_full:
- mov dx,offset errmsg9 ;Alias list too large msg.
- stc
- jmp short setalias_exit1
- setalias_notnfil:
- mov dx,offset errmsg13 ;Alias not in list.
- stc
- jmp short setalias_exit1
- setalias endp
-
- ;-----------------------------------------------------------------------------
- ; DELALIASENTRY - Deletes an alias entry
- ; Entry: DS:SI - pointer to the entry in the alias list to delete
- ; Exit: CF - clear if successful
- ;-----------------------------------------------------------------------------
- delete_aliasent proc near
- push cx ;Save registers
- push si
- push ds ;Yes, remove entry from list
- push es ; by moving the remainder of
- pop ds ; the list over this entry.
- mov si,es:[di] ;Point SI to the next list
- add si,di ; entry.
- delent_1:
- cmp word ptr es:[si],-1 ;Check for the end of the list
- je delent_2
- mov cx,es:[si] ;Get size of entry
- rep movsb ;Copy next entry over current
- jmp short delent_1 ; entry.
- delent_2:
- mov word ptr es:[di],-1 ;Set end of list indicator
- pop ds ;Get back file buffer pointer
- pop si
- pop cx
- ret
- delete_aliasent endp
-
- ;-----------------------------------------------------------------------------
- ; LOADALIASFILE loads a file containing a list of alias commands.
- ; Entry: DS:SI - pointer to the name of the file to open
- ; exit: CX - size of the file in bytes
- ; CF - clear if successful
- ;-----------------------------------------------------------------------------
- loadaliasfile proc near
- assume ds:nothing,es:nothing
- xor bl,bl
- call scanline ;Find 1st char of filename.
- mov dx,si ;Copy filename pointer
- inc bl ;Find end of filename
- call scanline
- mov byte ptr [si-1],0 ;Make filename ASCIIZ.
- dec dx
- mov ax,3d00h ;Open file (Read only)
- int 21h
- jc loadfile_error
- mov bx,ax ;Copy file handle
- ;
- ;Save the name of the file for error messages.
- ;
- push si
- push es
- mov di,offset filenam_field
- push cs
- pop es
- mov si,dx
- loadfile_1:
- lodsb
- stosb
- or al,al
- jne loadfile_1
- mov byte ptr es:[di-1],"$" ;Terminate string with $.
- pop es
- pop si
- ;
- ;Open file and read contents into file buffer.
- ;
- mov ah,3fh ;Read alias file
- xor dx,dx ;Pont to base of file buffer.
- mov cx,07f00h ;Read up to 32512 bytes.
- int 21h
- mov si,ax
- mov byte ptr ds:[si],13 ;Append a CR to end of file.
- mov cx,ax ;Save new file size
- xor si,si ;Reset file pointer.
- mov ah,3eh ;Close file.
- int 21h
- mov cs:[file_linecount],1 ;Reset line counter.
- loadfile_exit:
- clc
- loadfile_exit1:
- ret
- loadfile_error:
- stc
- mov dx,offset errmsg6 ;Bad filename specified.
- jmp short loadfile_exit1
- loadaliasfile endp
-
- ;-----------------------------------------------------------------------------
- ; LISTALIAS prints the alias list to screen.
- ; Entry: ES - segment of the installed code
- ;-----------------------------------------------------------------------------
- listalias proc near
- assume ds:nothing,es:nothing
- push ds
- ;
- ;Print Command stack size and amount of alias buffer space remaining
- ;
- mov dx,offset infomsg2 ;Print size of command stack
- call printmsg
- mov ax,es:[cmdstack_size] ;Get size of command stack
- call hex2asc ;Print size
- mov dx,offset infomsg3 ;Print min cmd length
- call printmsg
- xor ax,ax
- mov al,es:[minlength] ;Get min cmd length to stack
- call hex2asc ;Print length
- mov dx,offset infomsg4 ;Print label to buffer size
- call printmsg
- lds si,es:[aliaslist_ptr] ;Get pointer to alias list
- listalias_1:
- cmp word ptr [si],-1 ;Scan through alias list to
- je listalias_2 ; find the end of the list.
- add si,[si] ;Point to next entry
- jmp short listalias_1
- listalias_2:
- mov ax,es:[aliaslist_size] ;Get offset to end of buffer
- sub ax,si ;Subtract end of alias list
- sub ax,2 ;Correct for end pointer
- call hex2asc ;Print size
- mov dx,offset infomsg5 ;Indicate if alias translation
- call printmsg ; is enabled or disabled
- mov dx,offset infomsg5d ;Disabled message
- cmp byte ptr es:[chk_alias],0 ;See if alias enabled
- je listalias_3
- mov dx,offset infomsg5e ;Enabled message
- listalias_3:
- call printmsg
- ;
- ;Scan through alias list to print function key assignments
- ;
- xor dx,dx ;Clear alias found flag
- lds si,es:[aliaslist_ptr] ;Get pointer to alias list
- listalias_4:
- cmp word ptr [si],-1 ;Check for end of list
- jne listalias_5
- jmp listalias_11
- listalias_5:
- mov bx,si ;Save pointer to entry.
- cmp byte ptr [si+5],0 ;See if key assignment
- je listalias_6 ;If so, skip entry
- or dh,1 ;Set alias found flag
- add si,[bx] ;Point to next entry
- jmp short listalias_4
- listalias_6:
- ;
- ;Convert scan code into function key label
- ;
- test dh,80h ;See if first time though
- jne listalias_7
- push dx
- mov dx,offset infomsg6 ;If first time print header
- call printmsgcr
- pop dx
- or dh,80h ;Set header printed flag
- listalias_7:
- call printtab
- push dx
- add si,4 ;Point SI to command string
- mov al,[si] ;Get key code
- mov dh,al
- cmp al,84 ;Check for base code
- jb listalias_9
- sub dh,25
- mov di,offset shiftmsg ;Assume shift prefix
- cmp al,94 ;Check for shift
- jb listalias_8
- sub dh,10
- mov di,offset ctlmsg ;Assume control prefix
- cmp al,104 ;Check for ctl
- jb listalias_8
- mov di,offset altmsg ;Assume alt prefix
- sub dh,10
- listalias_8:
- push dx ;Print prefix identifier
- mov dx,di
- call printmsg
- pop dx
- listalias_9:
- mov dl,"F" ;Set function key
- mov ah,2 ;Character output
- int 21h
- mov al,dh ;Get modified key code
- sub al,58 ;Convert from scan code to hex
- xor ah,ah
- call hex2asc ;Print function key number
- mov cl,[bx+3] ;Get length of command
- inc si ;Point SI to command string
- inc si
- mov di,bx
- add di,[bx]
- cmp byte ptr [di-1],13 ;Check for carrage return
- jne listalias_10 ; after command. If found,
- mov dl,'*' ; indicate immediate command
- mov ah,2 ; by appending an * to the
- int 21h ; end of the function key.
- listalias_10:
- call printtab
- call printtab
- call print_string ;Print command to screen
- mov dx,offset endmsg ;Append carriage return to
- call printmsg ; advance to next line. SI
- pop dx ; points to the next entry.
- jmp listalias_4
- ;
- ;Scan through alias list to print aliases.
- ;
- listalias_11:
- test dh,1 ;See if any aliases found
- je listalias_exit ;If no aliases, skip remainder
- mov dx,offset infomsg7 ;Print header
- call printmsgcr
- xor cx,cx ;Clear CX
- lds si,es:[aliaslist_ptr] ;Get pointer to alias list
- listalias_12:
- mov bx,si ;Save pointer to entry.
- cmp byte ptr [si+5],0 ;See if key definition
- jne listalias_13 ;If so, skip entry
- add si,[bx]
- jmp short listalias_14
- listalias_13:
- call printtab
- add si,4 ;Point SI to alias string
- mov cl,[bx+2] ;Get length of alias
- call print_string ;Print alias to screen
- call printtab
- call printtab
- mov cl,[bx+3] ;Get length of command
- call print_string ;Print command to screen
- mov dx,offset endmsg ;Append carriage return to
- call printmsg ; advance to next line.
- listalias_14:
- cmp word ptr [si],-1 ;Check for end of list. SI
- jne listalias_12 ; points to the next entry.
- listalias_exit:
- mov dx,offset infomsg8 ;Print pointer to help msg
- call printmsgcr
- pop ds
- clc
- ret
- listalias endp
-
- ;-----------------------------------------------------------------------------
- ; PRINTTAB prints a TAB character to the screen.
- ; Entry: ES - segment of the installed code
- ;-----------------------------------------------------------------------------
- printtab proc near
- assume ds:nothing,es:nothing
- mov ah,2 ;Character output
- mov dl,9 ;Print TAB character
- int 21h
- ret
- printtab endp
-
- ;-----------------------------------------------------------------------------
- ; ENABLEALIAS enables alias translation.
- ; Entry: ES - segment of the installed code
- ;-----------------------------------------------------------------------------
- enablealias proc near
- assume ds:nothing,es:nothing
- mov byte ptr es:[chk_alias],1 ;Enable alias
- clc
- ret
- enablealias endp
-
- ;-----------------------------------------------------------------------------
- ; DISABLEALIAS disables alias translation.
- ; Entry: ES - segment of the installed code
- ;-----------------------------------------------------------------------------
- disablealias proc near
- assume ds:nothing,es:nothing
- mov byte ptr es:[chk_alias],0 ;Disable alias
- clc
- ret
- disablealias endp
-
- ;-----------------------------------------------------------------------------
- ; REMOVE uninstalls the installed program from memory.
- ;-----------------------------------------------------------------------------
- remove proc near
- assume ds:nothing,es:nothing
- push ds
- mov dx,offset errmsg1 ;Not installed msg
- cmp cs:[alrdy_installed],0 ;See if installed
- je remove_exit ;Not installed, error
-
- mov cx,cs:[other_seg] ;Get segment of installed code
- mov ax,3521h ;Get DOS vector
- int 21h
- mov ax,es ;Check to make sure DOS
- cmp ax,cs:[other_seg] ; vector not modified.
- jne remove_error
-
- lds dx,es:[int2fh] ;Get old interrupt 2F vector
- cmp dx,-1 ;See if Int used
- je remove_1 ;No, skip check of Int 2F
- mov ax,352fh ;Get MUX vector
- int 21h
- mov ax,es ;Check to make sure MUX
- cmp ax,cs:[other_seg] ; vector not modified.
- jne remove_error
- mov ax,252fh ;Set interrupt
- int 21h
- remove_1:
- lds dx,es:[int21h] ;Get old interrupt 21 vector
- mov ax,2521h ;Set interrupt
- int 21h
- mov cx,es:[env_segment]
- mov ah,49h ;Free memory block
- int 21h
- mov es,cx ;Free environment block
- mov ah,49h
- int 21h
- mov dx,offset infomsg1 ;Indicate uninstalled.
- mov byte ptr filenam_field,0 ;Clear filename field
- remove_exit:
- stc
- pop ds
- remove_exit1: ret
- remove_error:
- mov dx,offset errmsg3 ;Can't remove error msg
- jmp short remove_exit
-
- remove endp
-
- ;-----------------------------------------------------------------------------
- ; COMMENT_LINE allows comments in the alias file by skipping to the next
- ; carriage return.
- ; Entry: SI - pointer to ASCII string
- ; CX - file length
- ;-----------------------------------------------------------------------------
- comment_line proc near
- assume ds:nothing,es:nothing
- comment_loop:
- push es
- push ds
- pop es
- mov di,si ;Copy file pointer
- mov al,13 ;Scan for carriage return.
- repne scasb
- inc cs:[file_linecount] ;Inc file line counter.
- mov si,di ;Restore file pointer.
- pop es
- clc
- ret
- comment_line endp
-
- ;-----------------------------------------------------------------------------
- ; HEX2ASC converts a binary number to ASCII and prints it to the screen.
- ; Entry: AX - binary number
- ;-----------------------------------------------------------------------------
- hex2asc proc near
- assume ds:nothing,es:nothing
- push bx
- mov cx,5 ;Allow max of five digits
- hex_loop1:
- xor dx,dx ;Clear high word
- mov bx,10 ;Load number base
- div bx ;Divide by base (10)
- add dl,30h ;Convert to ascii
- push dx ;Save digit on stack
- loop hex_loop1
- mov cx,5 ;Allow max of five digits
- mov bl,"0" ;Set leading zero indicator
- hex_loop2:
- pop dx ;Get digit off stack
- or bl,dl ;Don't print leading zeros.
- cmp bl,"0" ;The first non zero will
- je hex_1 ; change bl to non-zero.
- mov ah,2 ;DOS character output
- int 21h
- hex_1:
- loop hex_loop2
- hex_exit:
- pop bx
- ret
- hex2asc endp
-
- ;-----------------------------------------------------------------------------
- ; ASC2BIN - converts an ASCII number of the command line to hex.
- ; Entry: DS:SI - pointer to ASCII number
- ;-----------------------------------------------------------------------------
- asc2bin proc near
- push bx
- xor bl,bl
- call scanline ;Find next character.
- mov di,offset errmsg5 ;Bad number message
- jc asc_error ;If no number found, error
- mov bl,al ;Copy first digit.
- xor ax,ax ;Clear out sum
- xor bh,bh ;Clear high byte for word adds
- asc_loop:
- cmp bl," " ;If space, assume end of
- jbe asc_exit ; number.
- cmp bl,"]" ;Exit if closing bracket
- je asc_exit ; encountered
- sub bl,"0" ;Check for valid number then
- jb asc_error ; convert to binary.
- cmp bl,9
- ja asc_error
- mov dx,10 ;DX holds base multiplier
- mul dx ;Shift over current number
- jc asc_overflow ;If overflow, indicate error
- add ax,bx ;Add new digit to sum.
- jcxz asc_exit ;If end of file, exit.
- mov bl,ds:[si] ;Get next ASCII character
- inc si ;Point to next character
- dec cx ;Dec file size counter
- jmp short asc_loop ;Go back for more
- asc_exit:
- clc ;Clear error flag.
- asc_exit1:
- pop bx
- ret
- asc_overflow:
- mov di,offset errmsg12 ;Number too large message.
- asc_error:
- mov dx,di ;Copy message pointer.
- stc ;Set error flag.
- jmp short asc_exit1
- asc2bin endp
- ;-----------------------------------------------------------------------------
- ; SCANLINE performs the same function as SCAN4CHAR but keeps track of the
- ; carriage returns.
- ; Entry: SI - pointer to ASCII string
- ; BL - 0 = find next char, 1 = find next space
- ; CX - file length
- ; Exit: AL - first nonspace character
- ; CF - set if carriage return found
- ;-----------------------------------------------------------------------------
- scanline proc near
- call scan4char ;Find the next char.
- jnc scanline_exit
- inc cs:[file_linecount] ;Point to next line.
- stc
- scanline_exit:
- ret
- scanline endp
-
- end_of_code = $
- code ends
-
- end main