home *** CD-ROM | disk | FTP | other *** search
- ;History:38,1
-
- comment !
- * Copyright 1988 By Russell Nelson. Don't try to make money off of it, and
- * don't pretend that you wrote it.
- *
- * Compu$erve: 70441,205
- * GEnie: BH01
- * Internet: nelson@clutx.clarkson.edu
- * BITNET: NELSON@CLUTX
- * Fido/Opus: Russ Nelson@1:260/360
- !
-
- code segment public
- assume cs:code, ds:code
-
- org 2ch
- phd_environ dw ?
-
- org 5ch
- phd_fcb1 label byte
-
- org 100h
- start:
- jmp start_1
-
- went_tsr db ? ;non-zero if a previous cmd went TSR.
- first_one dw 0 ;segment of line buffer.
- highest_phd dw ? ;address of highest phd we've seen.
- not_yet_flag db ? ;='.' if we should print this one.
- done_one db ? ;non-zero if we've printed a program
- ; name and hence should skip command.com
- command db 'COMMAND.' ;name of command.com
-
- assume ds:nothing
-
-
- compare_command:
- mov di,offset command ;point to command.com.
- compare:
- ;enter with ds:bp -> name to test, cs:di -> name to test it against.
- ;exit with zr if they're equal, nz if not equal.
- mov si,bp
- compare_0:
- lodsb ;compare two characters.
- call tolower
- cmp cs:[di],al
- jne compare_1 ;give up if they're different.
- cmp al,'.' ;success when we hit the extension.
- je compare_1
- inc di
- jmp compare_0
- compare_1:
- ret
-
-
- tolower:
- cmp al,'a' ;Uppercase letter.
- jb tolower_2
- cmp al,'z'
- ja tolower_2
- sub al,20h
- tolower_2:
- ret
-
- print_name:
- ;enter with ds:si -> name of a loaded program.
-
- ;
- ;find where the pathname ends and the filename begins.
- ;
- print_name_3:
- mov bp,si ;remember where we should print from.
- print_name_1:
- lodsb
- cmp al,'\' ;restart if we hit either path separator.
- je print_name_3
- cmp al,'/'
- je print_name_3
- or al,al ;continue until we hit the end of the string.
- jne print_name_1
-
- ;
- ; Should we store because of a TSR?
- ;
- cmp went_tsr,0 ;should we use this as the last TSR?
- jne print_tsr ;not yet - go test to see if we should.
- ;
- ; Have we reached the last TSR yet?
- ;
- cmp not_yet_flag,'.' ;should we print yet?
- jne print_test ;not yet - go test to see if we should.
- ;
- ; Did we just print a program? If so, we can skip the [COMMAND] that follows
- ; it. Otherwise, we should print [COMMAND].
- ;
- xor al,al ;get and reset done_one
- xchg al,done_one
- or al,al ;did we just do a program?
- je print_name_6 ;no - we can print [COMMAND] here.
- ;
- ; Avoid printing [COMMAND] immediately after a program that spawned command.com.
- ;
- call compare_command ;compare command.com to the current one.
- je print_name_2 ;go if they're equal.
-
- print_name_6:
-
- ;
- ;print their name.
- ;
- mov si,bp ;now restart after the rightmost slash.
- mov dl,'['
- mov ah,2
- int 21h
- print_name_4:
- lodsb
- or al,al ;give up when we hit the end.
- je print_name_5
- cmp al,'.' ;give up when we hit the extension.
- je print_name_5
- mov dl,al
- mov ah,2
- int 21h
- jmp print_name_4
- print_name_5:
- mov dl,']'
- mov ah,2
- int 21h
- ;
- ; If we just printed a program, remember it in done_one.
- ;
- call compare_command ;compare it to the current one.
- je print_name_2 ;go if they're equal.
-
- inc done_one ;say that we just did a program.
-
- print_name_2:
- ret
-
- print_test:
- ;
- ; See if we have reached the last TSR yet.
- ;
- mov di,offset phd_fcb1+1 ;point to their filename.
- call compare
- jne print_test_1 ;go if they're different.
-
- mov not_yet_flag,'.' ;print the next one.
- print_test_1:
- ret
-
-
- print_tsr:
- mov di,offset phd_fcb1+1 ;point to their filename.
- mov si,bp
- print_tsr_0:
- lodsb ;print_tsr_ two characters.
- call tolower
- mov cs:[di],al
- inc di
- cmp al,'.' ;success when we hit the extension.
- jne print_tsr_0
- ret
-
-
- prompt:
- assume ds:code
-
- cmp first_one,0 ;do we have a segment yet?
- jne prompt_0 ;yes.
- mov first_one,dx
- prompt_0:
- cmp first_one,dx ;is this command.com?
- jne prompt_3 ;no - don't print anything.
-
- mov al,phd_fcb1+1 ;if al = '.', then the filename is null.
- mov not_yet_flag,al ;if not_yet_flag = '.', print the name.
- mov done_one,0 ;say that we haven't done any yet.
-
- ;
- ; Get the first memory block into ES (undocumented).
- ;
- mov ah,52h
- int 21h
- mov es,es:[bx-2]
-
- ;
- ; Now we step through the phd's (program headers)
- ;
- mov highest_phd,0 ;remember the highest phd we've seen.
- prompt_2:
- cmp byte ptr es:[0],'M' ;All but the last block start with 'M'.
- jne prompt_3
-
- ;
- ; Keep track of the highest phd we've seen, so we don't repeat any.
- ;
- mov ax,es:[1] ;get the phd (owner).
- cmp ax,highest_phd ;is this one higher?
- jbe prompt_4 ;no - skip it.
- mov highest_phd,ax ;yes - remember it.
- ;
- ; Now that we've found the next phd, get its environment. However, we have to
- ; be careful, because some TSRs free their environment memory block in an effort
- ; to conserve memory. This is good and bad, because freeing their environment
- ; makes it impossible for us to determine the program name.
- ;
- push ds
- mov ds,ax ;point to the phd.
- mov bx,phd_environ ;get the environment.
- dec bx
- mov ds,bx ;point to its header.
- cmp ds:[1],ax ;do we still own this memory block?
- jne prompt_8 ;no - forget it.
-
- ;
- ; Now skip to the end of the environment where the program name is kept.
- ;
- mov si,16-1 ;look for the end of all the strings.
- prompt_5:
- inc si
- cmp word ptr [si],0 ;did we hit the end yet?
- jne prompt_5
-
- add si,4 ;point to the name of the program.
- call print_name
- prompt_8:
- pop ds
- ;
- ; Skip to the next memory block.
- ;
- prompt_4:
- mov ax,es ;add the size of this memory block
- add ax,es:[3] ; to get to the next segment.
- inc ax
- mov es,ax
- jmp prompt_2
- prompt_3:
- mov went_tsr,0 ;Okay, we're done with TSRs.
- ret
-
- assume ds:nothing
-
- their_27 dd ? ;remember what their interrupt 27 was.
-
- our_27:
- pushf ;save the flags just in case.
- inc went_tsr
- popf
- jmp their_27
-
-
- their_21 dd ? ;remember what their interrupt 21 was.
-
- our_21:
- ;
- ; Check for buffered input, and save everything if we've got one.
- ;
- pushf
- cmp ah,31h ;TSR call?
- jne our_21_2
- inc went_tsr ;yes - remember it.
- our_21_2:
- cmp ah,0ah ;buffered input?
- jnz our_21_1
-
- push ax
- push bx ;save regs
- push cx
- push dx
- push si
- push di
- push bp
- push ds
- push es
-
- mov dx,ds ;remember their buffer's segment in dx.
-
- mov ax,cs ;set up ds
- mov ds,ax
-
- call prompt
-
- pop es
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- pop bx
- pop ax
-
- our_21_1:
- popf
- jmp cs:their_21
-
-
- start_1:
- ;
- ; Check for MS-LOSS 3.x
- ;
- mov ah,30h
- int 21h
- cmp al,3
- jae start_3
- mov dx,offset bad_ver_msg
- mov ah,9
- int 21h
- int 20h
- start_3:
-
- ;
- ; Terminate the filename in phd_fcb1 with '.' instead of ' '.
- ;
- mov si,offset phd_fcb1+1 ;point to their filename.
- start_2:
- lodsb
- cmp al,' '
- jne start_2
- mov byte ptr ds:[si-1],'.' ;put a period after the filename.
-
- ;
- ; Intercept interrupt 21.
- ;
- mov ax,3521h
- int 21h
- mov word ptr their_21,bx
- mov word ptr their_21+2,es
-
- mov dx,offset our_21
- mov ax,2521h
- int 21h
- ;
- ; Intercept interrupt 27.
- ;
- mov ax,3527h
- int 21h
- mov word ptr their_27,bx
- mov word ptr their_27+2,es
-
- mov dx,offset our_27
- mov ax,2527h
- int 21h
- ;
- ; and TSR.
- ;
- mov dx,offset start_1+15
- shr dx,1
- shr dx,1
- shr dx,1
- shr dx,1
- mov ah,31h
- int 21h
-
- bad_ver_msg db "Requires MS-LOSS 3.x or greater$"
-
- code ends
-
- end start
-