; ShowDisk by Tom Hanlin 09/18/90 for the Public Domain ; displays letter of the drive being accessed in the upper right corner ; assembled with OPTASM by SLR RESLEN equ (Install - ShowDisk + 100h + 0Fh) shr 4 Sseg segment byte stack 'prog' ; dummy stack segment Sseg ends Cseg segment byte public 'prog' assume cs:Cseg, ds:Cseg, ss:Sseg org 100h ShowDisk proc far jmp Install ShowDisk endp INTdisk proc far ; new INT 13H hook push ax ; push bx ; push ds ; xor ax,ax ; establish BIOS data segment mov ds,ax ; mov al,ds:[0449h] ; get video mode cmp al,3 ; text mode? jbe #GotMode ; yep, it's fine cmp al,7 ; text mode? je #GotMode ; yep, it's fine mov byte ptr cs:VidSeg+1,0 ; flag "no display done" jmp #StartDone ; skip out #GotMode: mov al,0B8h ; assume color cmp byte ptr ds:[0463h],0D4h; is it color? je #GotSeg ; yep, we're set mov al,0B0h ; must be mono #GotSeg: mov cs:VidSeg+1,al ; save video segment call GetPosn ; get video offset mov ds,cs:VidSeg ; establish video segment mov ax,ds:[bx] ; get char/attr mov cs:OldChar,ax ; save it mov ax,ds:2[bx] ; get char/attr mov cs:OldChar+2,ax; save it mov ah,7 ; display in white on black mov al,dl ; drive number... add al,"A" ; convert to floppy letter test al,80h ; hard drive? jz #GotDrive ; no, we're set sub al,126 ; convert to hard drive letter #GotDrive: mov ds:[bx],ax ; write first char/attr mov al,":" ; mov ds:2[bx],ax ; write second char/attr #StartDone: pop ds ; pop bx ; pop ax ; ; pushf ; db 9Ah ; *** self-modifying code OldDisk dw ? ; *** CALL FAR PTR xxxx:yyyy dw ? ; (original INT 13h vector) ; push ax ; push bx ; push cx ; push bp ; push ds ; lahf ; put flags in AH mov bp,sp ; mov -19[bp],ah ; set it so we'll return flags mov cx,cs:VidSeg ; get video segment jcxz #Done ; if none, we're done xor ax,ax ; establish BIOS data segment mov ds,ax ; call GetPosn ; get video offset mov ds,cx ; establish video segment mov ax,cs:OldChar ; restore chars/attrs mov ds:[bx],ax ; mov ax,cs:OldChar+2; mov ds:2[bx],ax ; #Done: pop ds ; pop bp ; pop cx ; pop bx ; pop ax ; iret ; all done INTdisk endp ; new INT 13H hook INTmux proc ; new INT 2Fh hook cmp ah,0DDh ; is it for us? je #OurMux ; yep, go process it #NormMux: db 0EAh ; *** self-modifying code OldMux dw ? ; *** JMP FAR PTR xxxx:yyyy dw ? ; (original INT 2Fh vector) #OurMux: or al,al ; status request? jnz #OurMux1 ; no, skip dec al ; AL=0FFh to show we're here iret ; go directly home #OurMux1: cmp al,1 ; "remove self" request? jne #NormMux ; no, exit push ds ; xor ax,ax ; mov ds,ax ; mov ax,cs:OldMux ; cli ; interrupts off mov ds:[00BCh],ax ; restore old INT 2Fh vector mov ax,cs:OldMux+2 ; mov ds:[00BEh],ax ; restore old INT 2Fh vector mov ax,cs:OldDisk ; mov ds:[004Ch],ax ; restore old INT 13h vector mov ax,cs:OldDisk+2; mov ds:[004Eh],ax ; restore old INT 13h vector sti ; interrupts on push cs ; pop es ; return current segment in ES pop ds ; iret ; return to sender INTmux endp ; new INT 2Fh hook GetPosn proc near ; get video offset for drive spec mov bx,ds:[044Eh] ; offset of current video page mov ax,ds:[044Ah] ; columns sub ax,2 ; shl ax,1 ; add bx,ax ; where to read/write ret ; GetPosn endp ; get video offset for drive spec OldChar dw ?, ? ; saved characters and attributes VidSeg dw 0B800h ; video display segment (0 if nothing displayed) ; ------------------- non-resident portion ---------------------------- Install proc near ; installation routine call ParseCmdLine ; handle the command line cmp TurnOn,0 ; install ourselves? jnz #Installer ; yep, go do it cmp TurnOff,0 ; remove ourselves? jz #Done ; no, just exit ; mov ax,0DD00h ; check for installation int 2Fh ; inc al ; are we installed? jnz #Done ; no, ignore 'em mov ax,0DD01h ; tell it do remove itself int 2Fh ; mov ah,49h ; free up memory int 21h ; #Done: int 20h ; terminate program ; #Installer: mov ax,0DD00h ; check for installation int 2Fh ; inc al ; are we installed? jz #Done ; yes, ignore 'em mov es,ds:[002Ch] ; mov bx,1 ; one paragraph mov ah,4Ah ; shrink the environment int 21h ; cld ; set direction forward lea si,ProgName ; install our name in mini-environ xor di,di ; mov cx,8 ; 16 bytes maximum rep movsw ; mov ax,3513h ; get disk handler vector (INT 13h) int 21h ; mov OldDisk,bx ; save old disk handler vector mov OldDisk+2,es ; mov ax,2513h ; install new disk handler vector lea dx,INTdisk ; ptr to our routine int 21h ; mov ax,352Fh ; get mux handler vector (INT 2Fh) int 21h ; mov OldMux,bx ; save old multiplex handler vector mov OldMux+2,es ; mov ax,252Fh ; install new mux handler vector lea dx,INTmux ; ptr to our routine int 21h ; mov dx,RESLEN ; size of interrupt handler (parag) mov ax,3100h ; terminate and stay resident int 21h ; Install endp ; installation routine ParseCmdLine proc near ; parse the command line for parms mov si,0080h ; ptr to length of command line mov ax,si ; zero AH lodsb ; length of command line cmp al,1 ; is it null or nearly so? jbe #Help ; yep, go help 'em mov cx,ax ; length of command line #ScanParms: mov di,si ; update ptr to command line mov al,"/" ; switch character repne scasb ; see if we can find it mov si,di ; jne #Done ; no, go exit jcxz #Done ; exit if no parms left lodsb ; get option character dec cx ; account for it and al,0DFh ; convert it to uppercase cmp al,"D" ; D>einstall? je #Deinstall ; yep, take care of it cmp al,"I" ; I>nstall? jne #Help ; no, tell 'em about us ; #Install: mov TurnOn,1 ; set /Install flag jmp #ScanParms ; go try for another parm ; #Deinstall: mov TurnOff,1 ; set /Deinstall flag jmp #ScanParms ; go try for another parm ; #Done: cmp TurnOff,0 ; did we get an option? jnz #Exit ; yep, it's good cmp TurnOn,0 ; did we get an option? jnz #Exit ; yep, it's good ; #Help: lea dx,Info ; ptr to info about ShowDisk mov ah,9 ; display string int 21h ; #Exit: ret ; return to sender ParseCmdLine endp ; parse the command line for parms TurnOn db ? TurnOff db ? Info db "SHOWDISK v1.0 09/20/90 for the Public Domain by Thomas G. Hanlin III",13,10 db 13,10 db "ShowDisk is a utility which, when a drive is accessed, displays the letter",13,10 db "of the drive in the upper right hand corner of the screen. No display will",13,10 db "be done while the computer is in graphics mode.",13,10 db 13,10 db "SHOWDISK display information on ShowDisk",13,10 db "SHOWDISK /I install ShowDisk in memory",13,10 db "SHOWDISK /D deinstall ShowDisk",13,10 db "$" ; The original environment will be discarded by the resident part of ShowDisk, ; since it won't be needed and takes up space. We'll install the following as ; our name in a tiny environment, though, for the benefit of MAP utilities. ProgName db 0,0,1,0,"SHODSK.COM",0,0 Cseg ends end ShowDisk