-f100 500 0
-a100
1149:0100 ;
1149:0100 ;----------------------------------------
1149:0100 ; DOSMON - DOS Activity Monitor
1149:0100 ;----------------------------------------
1149:0100 ;
1149:0100 ; This program will terminate and stay resident.  It intercepts the
1149:0100 ; DOS service interrupt and displays status information on the
1149:0100 ; screen during DOS service execution periods.
1149:0100 ;
1149:0100 ; S.H.Smith, 15-may-86
1149:0100 ;
1149:0100 
-
-a100
1149:0100 ;----------------------------------------
1149:0100 ; startup entry point
1149:0100 ;----------------------------------------
1149:0100    jmp 2e0       ;install
1149:0103 
-
-a103
1149:0103 ; vector for old interrupt
1149:0103    db 0,0,0,0
1149:0107 
-
-a107
1149:0107 ; segment address for display memory
1149:0107 ; filled in by startup code
1149:0107    dw 0
1149:0109 
-
-a10e
1149:010E ; twiddle display index
1149:010E    dw 0
1149:0110 
-
-a110
1149:0110 ; twiddle display characters
1149:0110    db "Ä\³/"
1149:0114 
-
-a118
1149:0118 ; 118..11B used for vector back to user
1149:0118 ; 11c used for first save char
1149:0118 ; 11e used for second save char
1149:0118 ; 120 used for third save char
1149:0118 ; 122 scratch ax save
1149:0118 ; 124 ss save
1149:0118 ; 126 sp save
1149:0118 
-
-a130
1149:0130 ; a signature in bytes
1149:0130    db 0a,0d,'DOSMON - DOS Activity Monitor',0a,0d
1149:0151    db '$  S.H.Smith, 15-May-86',0a,0d
1149:016A    db 1a
1149:016B 
-
-a170
1149:0170 ;----------------------------------------
1149:0170 ; new DOS service interrupt
1149:0170 ;----------------------------------------
1149:0170 ;
1149:0170    cs:
1149:0171    pop [118]       ;get return ip
1149:0175    cs:
1149:0176    pop [11a]       ;get return cs
1149:017A    popf            ;get flags
1149:017B ;
1149:017B    pushf
1149:017C    push ds
1149:017D    push es
1149:017E    push bx         ;save entry registers
1149:017F    push ax
1149:0180 ;
1149:0180 ;----------------------------------------
1149:0180 ; save the previous display data
1149:0180 ;
1149:0180    cs:
1149:0181    mov ax,[107]    ;get display segment into es
1149:0184    mov es,ax
1149:0186 ;
1149:0186    es:
1149:0187    mov ax,[94]     ;save original screen contents
1149:018A    cs:
1149:018B    mov [11c],ax
1149:018E ;
1149:018E    es:
1149:018F    mov ax,[96]     ;second char
1149:0192    cs:
1149:0193    mov [11e],ax
1149:0196 ;
1149:0196    es:
1149:0197    mov ax,[98]     ;third char
1149:019A    cs:
1149:019B    mov [120],ax
1149:019E ;
1149:019E ;----------------------------------------
1149:019E ; prepare display with blanks
1149:019E ;
1149:019E    mov ax,0f20     ;space with attribute of 15
1149:01A1    es:
1149:01A2    mov [94],ax
1149:01A5    es:
1149:01A6    mov [96],ax     ;set attribute of the function code locations
1149:01A9    es:             ;and leave them blank in case of 'exec' function
1149:01AA    mov [98],ax
1149:01AD ;
1149:01AD    pop ax          ;get DOS function code into ah
1149:01AE    push ax
1149:01AF ;
1149:01AF    cmp ah,4b       ;is this an exec call?
1149:01B2    jz 228          ;leave display blank if so
1149:01B4 ;
1149:01B4 ;----------------------------------------
1149:01B4 ; display the rotating twiddle character
1149:01B4 ;
1149:01B4    cs:
1149:01B5    mov bx,[10e]    ;get twiddle index
1149:01B9    inc bx
1149:01BA    mov al,bl       ;advance to next twiddle position
1149:01BC    and al,3        ;bx=bx mod 4 to rotate through twiddles
1149:01BE    mov bl,al
1149:01C0    cs:
1149:01C1    mov [10e],bx    ;save next twiddle index
1149:01C5 ;
1149:01C5    cs:
1149:01C6    mov ah,[110+bx] ;get the next twiddle character
1149:01CA    es:
1149:01CB    mov [94],ah     ;put twiddle status on screen
1149:01CF ;
1149:01CF ;----------------------------------------
1149:01CF ; display the DOS service number in hex
1149:01CF ;
1149:01CF    pop ax          ;get the dos function code into ah
1149:01D0    push ax
1149:01D1 ;
1149:01D1    and ah,0f
1149:01D4    add ah,30       ;convert low digit to hex
1149:01D7 ;
1149:01D7    cmp ah,3a       ;handle A..F
1149:01DA    jb 1e8
1149:01DC    add ah,7
1149:01DF    jmp 1e8
1149:01E1 
-
-a1e8
1149:01E8    es:
1149:01E9    mov [98],ah     ;and set LSB on screen
1149:01ED ;
1149:01ED    pop ax          ;get fresh copy of function code into ah
1149:01EE    push ax
1149:01EF ;
1149:01EF    shr ah,1        ;move down bits for high digit
1149:01F1    shr ah,1
1149:01F3    shr ah,1
1149:01F5    shr ah,1        ;make high byte hex and put on screen
1149:01F7    and ah,0f
1149:01FA    add ah,30
1149:01FD ;
1149:01FD    cmp ah,3a       ;handle A..F
1149:0200    jb 218
1149:0202    add ah,7
1149:0205    jmp 218
1149:0207 
-
-a218
1149:0218    es:
1149:0219    mov [96],ah     ;set MSB on screen
1149:021D    jmp 228
1149:021F 
-
-a228
1149:0228 ;----------------------------------------
1149:0228 ; perform the DOS service function
1149:0228 ;
1149:0228    pop ax
1149:0229    pop bx
1149:022A    pop es          ;restore initial entry registers
1149:022B    pop ds
1149:022C    popf
1149:022D ;
1149:022D    cs:
1149:022E    push [118]
1149:0232    cs:             ;push static variables to make this program
1149:0233    push [11a]      ;recursive - DOS uses many recursive functions
1149:0237    cs:
1149:0238    push [11c]
1149:023C    cs:
1149:023D    push [11e]
1149:0241    cs:
1149:0242    push [120]
1149:0246    cs:
1149:0247    push [124]
1149:024B    cs:
1149:024C    push [126]
1149:0250 ;
1149:0250    cs:
1149:0251    mov [122],ax
1149:0254    mov ax,ss
1149:0256    cs:
1149:0257    mov [124],ax    ;preserve ss:sp in case dos loses it!
1149:025A    mov ax,sp
1149:025C    cs:
1149:025D    mov [126],ax
1149:0260    cs:
1149:0261    mov ax,[122]
1149:0264 ;
1149:0264    pushf           ;push flags to simulate action of 'int 21'
1149:0265    cs:
1149:0266    call far [103]  ;call the real DOS service interrupt
1149:026A ;
1149:026A    cs:
1149:026B    mov [122],ax
1149:026E    cs:
1149:026F    mov ax,[124]    ;restore ss:sp
1149:0272    mov ss,ax
1149:0274    cs:
1149:0275    mov ax,[126]
1149:0278    mov sp,ax
1149:027A    cs:
1149:027B    mov ax,[122]
1149:027E ;
1149:027E    cs:
1149:027F    pop [126]
1149:0283    cs:
1149:0284    pop [124]
1149:0288    cs:
1149:0289    pop [120]
1149:028D    cs:
1149:028E    pop [11e]       ;restore static variables after return from recursion
1149:0292    cs:
1149:0293    pop [11c]
1149:0297    cs:
1149:0298    pop [11a]
1149:029C    cs:
1149:029D    pop [118]
1149:02A1 ;
1149:02A1    pushf
1149:02A2    push ax         ;save DOS exit registers for later use
1149:02A3    push es
1149:02A4    push ds
1149:02A5 ;
1149:02A5 ;----------------------------------------
1149:02A5 ; restore original screen contents
1149:02A5 ;
1149:02A5    cs:
1149:02A6    mov ax,[107]    ;get display page into es
1149:02A9    mov es,ax
1149:02AB ;
1149:02AB    cs:
1149:02AC    mov ax,[11c]
1149:02AF    es:            ;put old data on screen
1149:02B0    mov [94],ax    ;first char
1149:02B3 ;
1149:02B3    cs:
1149:02B4    mov ax,[11e]
1149:02B7    es:
1149:02B8    mov [96],ax    ;second char
1149:02BB ;
1149:02BB    cs:
1149:02BC    mov ax,[120]
1149:02BF    es:
1149:02C0    mov [98],ax    ;third char
1149:02C3 ;
1149:02C3 ;----------------------------------------
1149:02C3 ; end of interrupt - return to the caller
1149:02C3 ;
1149:02C3    pop ds
1149:02C4    pop es
1149:02C5    pop ax
1149:02C6    popf             ;get return flags
1149:02C7    cs:
1149:02C8    jmp far [118]    ;jump back to user code
1149:02CC 
-
-a2e0
1149:02E0 ;----------------------------------------
1149:02E0 ; startup code
1149:02E0 ;----------------------------------------
1149:02E0 ; determine where the video ram is.  this is done by putting a special
1149:02E0 ; character on the screen and then looking for it in the various video
1149:02E0 ; ram locations.
1149:02E0 ;
1149:02E0    push cs
1149:02E1    pop ds
1149:02E2 ;
1149:02E2    mov ah,3         ;get cursor position
1149:02E4    int 10           ;video bios service
1149:02E6    push ax
1149:02E7    push bx
1149:02E8    push dx          ;save it for later
1149:02E9 ;
1149:02E9    mov dx,0
1149:02EC    mov ah,2         ;home the cursor
1149:02EE    int 10
1149:02F0 ;
1149:02F0    mov ah,0A
1149:02F2    mov al,88        ;display a funny char at cursor
1149:02F4    mov cx,1
1149:02F7    int 10
1149:02F9 ;
1149:02F9 ; move cursor back to original position
1149:02F9 ;
1149:02F9    pop dx
1149:02FA    pop bx
1149:02FB    pop ax
1149:02FC    mov ah,2
1149:02FE    int 10
1149:0300 ;
1149:0300 ; look for MONO video ram
1149:0300 ;
1149:0300    mov dl,88
1149:0302    mov ax,b000
1149:0305    mov es,ax
1149:0307    es:
1149:0308    cmp dl,[0]
1149:030C    jz 360
1149:030E ;
1149:030E ; look for COLOR video ram
1149:030E ;
1149:030E    mov ax,b800
1149:0311    mov es,ax
1149:0313    es:
1149:0314    cmp dl,[0]
1149:0318    jz 360
1149:031A ;
1149:031A ; couldn't find video ram; display a message and abort
1149:031A ;
1149:031A    mov dx,308
1149:031D    mov ah,9
1149:031F    int 21           ;display error message
1149:0321    int 20           ;terminate program
1149:0323 
-
-a328
1149:0328    db "ERROR: Can't find display memory$"
1149:0349 
-
-a360
1149:0360 ;
1149:0360    cs:
1149:0361    mov [107],ax     ;set the display segment
1149:0364 ;
1149:0364 ;----------------------------------------
1149:0364 ; display the program signon message now that we are sure
1149:0364 ; that we can be installed
1149:0364 ;
1149:0364    mov dx,130
1149:0367    mov ah,9
1149:0369    int 21           ;display signon message
1149:036B ;
1149:036B ;----------------------------------------
1149:036B ; now install new interrupt handler
1149:036B ;
1149:036B    mov ax,0
1149:036E    mov es,ax
1149:0370 ;
1149:0370 ; save old DOS service vector
1149:0370 ;
1149:0370    es:
1149:0371    mov ax,[84]
1149:0374    cs:
1149:0375    mov [103],ax
1149:0378 ;
1149:0378    es:
1149:0379    mov ax,[86]
1149:037C    cs:
1149:037D    mov [105],ax
1149:0380 ;
1149:0380 ; install new vector
1149:0380 ;
1149:0380    mov ax,170       ;entry point offset
1149:0383    es:
1149:0384    mov [84],ax
1149:0387 ;
1149:0387    mov ax,cs        ;this code segment
1149:0389    es:
1149:038A    mov [86],ax
1149:038D ;
1149:038D ; set last resident code offset
1149:038D ; and terminate-and-stay-resident
1149:038D ;
1149:038D    mov al,0         ;exit code
1149:038F    mov dx,30        ;paragraphs to keep resident
1149:0392    mov ah,31        ;keep process function
1149:0394    int 21           ;terminate and stay in memory
1149:0396 
-
-rcx
CX 0000
:400
-ndosmon.com
-w
Writing 0400 bytes
-q
