PAGE 64,132
;
;         This program intercepts Int 13H calls and prints
;         the drive, side, track, sector, # of sectors, operation,
;         and return code.
; 
cseg    segment 
        org 100h
INT13   proc far
        assume cs:cseg,ds:cseg
;
        jmp install                    ;install and make routine resident
;
redef13      label      word
oldint13     dd         0              ;save area for old int13 vector
int13loc     equ        13h*4h         ;vector location for int13h
drive_a      equ         'A'
drive_b      equ         'B'
drive_c      equ         'C'
drive_d      equ         'D'
drive_x      equ         'X'
save_ip      dw         0              ;save area for calling pgm's IP
save_cs      dw         0              ;save area for calling pgm's CS
;
message      db 'Drv: '
drive        db ?
             db ' Side: '
side1        db ?
side2        db ?
             db '   Tr: '
track1       db ?
track2       db ?
             db ' Sec: '
sector1      db ?
sector2      db ?
             db '  # secs: '
sec_cnt1     db ?
sec_cnt2     db ?
             db ' Op: '
op_1         db ?
op_2         db ?
             db '   Retcd: '
status1      db ?
status2      db ?
             db '  Addr: '
cs_1         db ?
cs_2         db ?
cs_3         db ?
cs_4         db ?
             db ':'
ip_1         db ?
ip_2         db ?
ip_3         db ?
ip_4         db ?
             db 0ah,0dh
;------------------------------
inst_msg     db 'INT13 is now installed.......$'
;
newint13:
        sti
        push ax
        push bp
        mov bp,sp                      
        mov ax,[bp+4]                  ;Retrieve return IP value 
        mov cs:save_ip,ax              ;    from stack.
        mov ax,[bp+6]                  ;Retrieve return CS value
        mov cs:save_cs,ax              ;    from stack.
        pop bp                         ;Save anything which will be
        pop ax                         ;    be changed during
        pushf                          ;    processing.
        push di
        push si
        push ds
        push es
        push bx
        push cx
        push dx
        push ax
        mov ax,cs
        mov ds,ax
;---------------DRIVE------------------
        cmp dl,00h                     ;Drive A? (dl=00)
        jne chk1                       ; Note: processing is in place for
        mov drive,drive_a              ;    logging disk activity on all
        jmp drv_exit                   ;    drives, if desired.  See below
chk1:   cmp dl,01h                     ;Drive B?
        jne chk2
        mov drive,drive_b
        jmp drv_exit
chk2:   cmp dl,02h                     ;Drive C?
        jne chk3
        mov drive,drive_c
        jmp drv_exit
chk3:   cmp dl,03h
        jne chkx
        mov drive,drive_d
        jmp drv_exit
chkx:   mov drive,drive_x
drv_exit:
;---------------SIDE  (DH) ------------
        mov ah,dh                      ;record side being requested-left digit
        call leftdig                   ;convert to ASCII code for printing
        mov cs:side1,ah                ;move code to message area
        mov ah,dh                      ;same for right digit
        call rightdig
        mov cs:side2,ah
;---------------TRACK NO. (CH)----------
        mov ah,ch
        call leftdig
        mov cs:track1,ah
        mov ah,ch
        call rightdig
        mov cs:track2,ah
;----------------------------------------
;
;----------------SECTOR NO. (CL)---------
        mov ah,cl
        call leftdig
        mov cs:sector1,ah
        mov ah,cl
        call rightdig
        mov cs:sector2,ah
;------------------------------------------
;
;----------------NO. OF SECTORS (AL)-------
;
        pop ax      ;recall ax
        push ax     ;save it again
        mov ah,al
        call leftdig
        mov cs:sec_cnt1,ah
        pop ax
        push ax
        mov ah,al
        call rightdig
        mov cs:sec_cnt2,ah
;--------------------------------------------------
;
;--------------OPERATION TYPE (AH)-----------------
; 00:reset 01:read status 02:read sectors 03:write sec. 04:verify 05:format
;

        pop ax      ;recall ax
        push ax     ;save it again
        call leftdig
        mov cs:op_1,ah
        pop ax
        push ax
        call rightdig
        mov cs:op_2,ah
;-------------- RETURN ADDRESS CS:IP -------------------
;
        mov ax,cs:save_ip
        call leftdig
        mov cs:ip_1,ah
        mov ax,cs:save_ip
        call rightdig
        mov cs:ip_2,ah
        mov ax,cs:save_ip
        xchg ah,al
        call leftdig
        mov cs:ip_3,ah
        mov ax,cs:save_ip
        xchg ah,al
        call rightdig
        mov cs:ip_4,ah
;
        mov ax,cs:save_cs
        call leftdig
        mov cs:cs_1,ah
        mov ax,cs:save_cs
        call rightdig
        mov cs:cs_2,ah
        mov ax,cs:save_cs
        xchg ah,al
        call leftdig
        mov cs:cs_3,ah
        mov ax,cs:save_cs
        xchg ah,al
        call rightdig
        mov cs:cs_4,ah
;--------------------------------
             pop ax                    ;Restore the things which were
             pop dx                    ;    saved
             pop cx
             pop bx
             pop es
             pop ds
             pop si
             pop di
             popf
;--------------------
             pushf           ; Put flags, CS and IP onto stack for return to
             push cs         ;  routine below after standard int 13h processing
             call intcall    ; IP will point to next instruction
;
;---------------------------Report status of int 13h call----------
;
             pushf
             push ax                   ;Save it again
             call leftdig
             mov cs:status1,ah
             pop ax
             push ax
             call rightdig
             mov cs:status2,ah
             pop ax
;------------  PRINT THE MESSAGE --------------------------
             cmp dl,00h  ;******** REMOVE THESE TWO LINES IF YOU WISH
             jne goback  ;********   ALL DISK ACTIVITY TO BE LOGGED
             push ax
             push cx
             push dx
             push si
             mov cx,52h                ; Length of message
             mov si,offset message
             xor dx,dx
prnloop:     mov ah,00h
             mov al,cs:[si]  
             int 17h
             inc si
             loop prnloop
             pop si
             pop dx
             pop cx
             pop ax
goback:      popf
;-------------------------------------------------------
             ret  2          ; Go back to calling program.
                             ; Note:"iret" is not used because the flags
                             ;   would be popped (and we wish to pass back
                             ;   the changed set of flags).  The "2" ensures
                             ;   that the stack is restored by incrementing
                             ;   the stack pointer by two extra bytes.
;-----------------------
intcall      PROC near     ; get set to go to standard int 13h routine
             pushf
             push cs:[redef13 + 2]     ; "cs" of int 13h routine
             push cs:[redef13]         ; "ip" of int 13h routine
             iret                      ; Branch to normal int13h code in ROM
intcall      endp 
;--------------------------
;   Routine to convert high-order digit in AH to an ASCII character
;
leftdig      PROC
             and ah,11110000b ; Mask right 4 bits
             shr ah,1         ; Move high-order digit to low-order pos.
             shr ah,1
             shr ah,1
             shr ah,1
             cmp ah,0ah       ; Check for value 0 through 9
             jnb b37          ; If value hex A through F, jump 
             add ah,30h       ; Add 30h to make ASCII character
             jmp b2
       b37:  add ah,37h       ; If hex A-F, add 37h to make ASCII character
        b2:  ret
leftdig      endp
;-----------------------
;   Routine to convert low-order digit in AH to an ASCII character
;
rightdig     PROC near
             and ah,00001111b ; mask left 4 bits
             cmp ah,0ah
             jnb a37
             add ah,30h
             jmp a1
       a37:  add ah,37h
        a1:  ret
rightdig     endp
;-----------------------
install:
             mov ax,0
             mov es,ax
             mov di,int13loc           ;Save old 
             mov ax,es:[di]            ;   interrupt 13h
             mov bx,es:[di+2]          ;   vector
             mov si,offset oldint13    ;     "
             mov [si],ax               ;     "
             mov [si+2],bx             ;     "
             mov ax,0                  
             mov es,ax
             mov bx,ds
             cli                       ;Turn off interrupts
             mov di,int13loc           ;Change int13h ....
             mov ax,offset newint13    ;   vector to...
             mov es:[di],ax            ;   point to...
             mov es:[di+2],bx          ;   this program.
             sti                       ;Turn interrupts back on
             mov dx,offset inst_msg
             mov ah,09h                ;Print string function
             int 21h                   ;Print "install" message
             mov dx,offset install     ;Address of end of resident routine
             int 27h                   ;Terminate and stay resident
INT13        endp
;------------------------------
cseg         ends
end          INT13
