home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 December
/
simtel1292_SIMTEL_1292_Walnut_Creek.iso
/
msdos
/
progjorn
/
pj_6_4.arc
/
RESIDENT.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-08-30
|
11KB
|
399 lines
; This code illustrates how to install and deinstall a TSR and under what
; circumstances the body of a TSR should be given control.
;
; The hot keys in this example are the Alt + Left Shift keys. This hot key
; combination is defined in the variable hot_keys and can be changed to suit
; the user by changing the bit pattern.
;
; This example is intended to illustrate the recommendations made in the
; following articles:
;
; "DOS: Terminate and Stay Resident", M. Steven Baker
; Programmer's Journal, Nov/Dec 1986, pages 26 - 30
;
; "Coding Guidelines for Resident Programs", Graham Pearson
; Programmer's Journal, Mar/Apr 1987, pages 34 - 38
;
;
; The author can be reached at the following address:
; Kudos Software, 9111 Cadawac Road, Houston, Texas 77074
; Tel: (713) 774-6108
;******************************************************************************
DELAY_COUNT EQU 36 ;Timer counts between hot key triggers
;36 ticks = approx. 2 seconds
; Locations of BIOS Data needed by the resident program
bios_data segment at 40H
org 17H ;Keyboard status flags
kbd_status dw ?
org 6CH ;Timer count - low word. This rolls
low_timer dw ? ;around 0FFFFH once per hour
bios_data ends
;------------------------------------------------------------------------------
code segment
assume cs:code, ds:nothing, es:nothing, ss:nothing
org 100H ;Define starting point for .COM file
entry_point:
jmp install ;Skip over the code to be made resident
;------------------------------------------------------------------------------
hot_keys dw 01010B ;Hot key bits -> Alt + Left Shift
this_time dw ? ;Most-recent time hot keys detected
trig_time dw ? ;Last time resident code was triggered
dos_busy label dword ;Pointer to "DOS is busy" flag
dos_busy_off dw ? ;These values are initialized during
dos_busy_seg dw ? ;the "install" process
criterr_flag dw ? ;Used by diverted INT 24H
;------------------------------------------------------------------------------
; Replacement for INT 24H - critical DOS error
diverted_int24:
mov cs:criterr_flag,0FFFFH ;Switch error flag ON
xor al,al ;Tell DOS to ignore the error
iret ;Return to DOS
int_24_vect label dword
int_24_off dw ? ;These values are initialized each time
int_24_seg dw ? ;the TSR body takes control
;------------------------------------------------------------------------------
; Replacement for INT 9 - keyboard hardware interrupt
diverted_int9:
pushf ;Simulate an INT 9 to pass through the
call_int9 db 09AH ;original BIOS interrupt handler
int_9_vect label dword
int_9_off dw ? ;These values are initialized during
int_9_seg dw ? ;the "install" process
push ds ;Save all registers used by this
push bx ;section of code
lds bx,dos_busy ;See if DOS is busy
cmp byte ptr [bx],0
pop bx ;Restore all registers
pop ds
jz get_bios_data ;Zero means DOS is not busy
dos_is_busy:
iret ;Return control to interrupted process
;------------------------------------------------------------------------------
; Replacement for INT 28 - generated by DOS, esp. during keyboard I/O functions
diverted_int28:
pushf ;Simulate an INT 28H to pass through
call_int28 db 09AH ;the original DOS interrupt handler
int_28_vect label dword
int_28_off dw ? ;These values are initialized during
int_28_seg dw ? ;the "install" process
;------------------------------------------------------------------------------
get_bios_data:
sti ;Restore interrupts
push ds ;Save all registers used by this
push bx ;section of code
mov bx,bios_data ;Retrieve BIOS Data values
mov ds,bx
assume ds:bios_data
mov bx,low_timer ;Retrieve and save timer count
mov cs:this_time,bx
mov bx,kbd_status ;Retrieve keyboard status bits
push cs ;Point DS to our code segment
pop ds
assume ds:code
chk_keys:
and bx,hot_keys ;See if hot keys are pressed
cmp bx,hot_keys
jne back_to_applic
chk_timer:
mov bx,this_time
cmp bx,trig_time ;Enter resident routine if timer
jb time_is_right ;count has rolled around the hour
sub bx,trig_time
sub bx,DELAY_COUNT ;Transfer to resident code only if
jnc time_is_right ;elapsed time between hot keys is
;greater than delay count
back_to_applic:
pop bx ;Restore all registers
pop ds
iret ;Return control to interrupted process
;------------------------------------------------------------------------------
time_is_right:
mov bx,this_time ;Update latest trigger time
mov trig_time,bx
pop bx ;Restore all registers
pop ds
;******************************************************************************
; This is the start of the application-dependent resident code
start_program:
push ax ;Save all registers used by the
push bx ;resident application
push cx
push dx
push si
push di
push bp
push ds
push es
push cs ;Point DS to our CS
pop ds
mov ax,3524H ;Get current INT 24H vector
int 21H
mov int_24_off,bx
mov int_24_seg,es
mov ax,2524H ;Redirect INT 24H
mov dx,offset diverted_int24
int 21H
;******************************************************************************
; Include application specific code here
;******************************************************************************
restore_int24:
lds dx,int_24_vect ;Restore INT 24H
mov ax,2524H ;Error in PJ listing (was 2509H)
int 21H
pop es ;Restore all registers
pop ds
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
iret ;Return control to interrupted process
; This is the end of the application-dependent resident code
end_of_res label word
;******************************************************************************
; This procedure installs the resident section of code in memory.
; It performs the following tasks:
;
; 1 Make sure the operating system is at least DOS 2.00
;
; 2 Make sure the resident code is not already installed in memory
; If it IS already installed, remove it from memory
;
; 3 Retrieve an available vector for installing the signature
;
; 4 Retrieve vector to "DOS is busy" and save it for use by resident code
;
; 5 Update the interrupt vectors required by resident code.
;
; 6 Install the signature in the available vector found in step 3
;
; 7 Terminate and stay resident - transfer control back to DOS
;------------------------------------------------------------------------------
install:
; Make sure that the operating system is at least DOS 2.00
mov ah,30H
int 21H
or al,al
jnz chk_vectors
mov dx,offset baddos_msg ;DS:DX -> Display "bad DOS" message
mov ah,9
int 21H
int 20H ;Return to DOS the old-fashioned way
;------------------------------------------------------------------------------
; See if the resident code is already installed in memory.
; If so, remove the resident code from memory.
; If not, retain an available interrupt vector for later use as a signature.
chk_vectors:
push ds ;Save DS -> CS
xor ax,ax ;Search 32 interrupt vectors starting
mov ds,ax ;at INT 60H - user interrupt area
mov si,60H * 4
mov cx,20H
next_vector:
mov ax,[si + 2]
or ax,ax ;If segment value is zero, get offset
jz get_vect_off ;value
cmp ax,0D0C7H ;Check interrupt segment value against
jne vector_loop ;resident code signature
deinstall:
mov bx,[si] ;Retrieve original resident code
;segment value
xor ax,ax
mov [si],ax ;Remove signature from the
mov [si + 2],ax ;interrupt vector
restore_int9:
mov ds,bx ;DS -> original resident code segment
lds dx,int_9_vect ;Restore INT 9 - keyboard I/O
mov ax,2509H
int 21H
restore_int28:
mov ds,bx ;DS -> original resident code segment
lds dx,int_28_vect ;Restore INT 28 - DOS interrupt
mov ax,2528H
int 21H
mov es,bx ;ES -> code segment to be deinstalled
mov ah,49H
int 21H ;Free allocated memory
mov es,es:[2CH] ;ES -> environment to be deinstalled
mov ah,49H
int 21H ;Free allocated memory
pop ds ;Restore DS -> CS
mov dx,offset remove_msg ;DS:DX -> Display "remove" message
mov ah,9
int 21H
mov ax,4C01H ;Return error code of 1
int 21H ;Return to DOS with error code
get_vect_off:
cmp word ptr [si],0 ;If offset value is zero, this vector
je found_vector ;is available for our use
vector_loop:
add si,4 ;Interrogate next vector
loop next_vector
found_vector:
;Make sure we successfully complete the install process before
;installing the signature in this available interrupt vector
pop ds ;Restore Data Segment
mov free_vector,si ;Save free vector for later
;------------------------------------------------------------------------------
; Retrieve original interrupt vectors and install these in the resident code.
; Redirect the interrupt vectors to point to resident code.
; Install signature in available interrupt vector.
push es ;Save ES -> CS
mov ah,34H ;Retrieve segment + offset
int 21H ;pointer to "DOS is busy" flag
mov dos_busy_off,bx
mov dos_busy_seg,es
mov ax,3509H ;Get current INT 9H vector
int 21H
mov int_9_off,bx
mov int_9_seg,es
mov ax,2509H ;Redirect INT 9H
mov dx,offset diverted_int9
int 21H
mov ax,3528H ;Get current INT 28H vector
int 21H
mov int_28_off,bx
mov int_28_seg,es
mov ax,2528H ;Redirect INT 28H
mov dx,offset diverted_int28
int 21H
pop es ;Restore ES -> CS
mov di,free_vector ;Retrieve value found earlier
push ds ;Save DS -> CS
xor ax,ax ;DS -> interrupt vectors
mov ds,ax
mov [di],cs ;Install signature in the available
mov word ptr [di+2],0D0C7H ;interrupt vector
pop ds ;Restore DS -> CS
;------------------------------------------------------------------------------
; Display installed message
mov dx,offset success_msg ;DS:DX -> Display "success" message
mov ah,9
int 21H
;------------------------------------------------------------------------------
; Prepare for program "terminate and stay resident"
mov dx,offset end_of_res ;Calculate the amount of memory used
dec dx ;by the resident code
or dx,0FH
inc dx ;Round up to the nearest paragraph
mov cl,4 ;Convert code size to paragraphs
shr dx,cl
mov ax,03100H ;Return error code of 0
int 21H ;Terminate but stay resident
;------------------------------------------------------------------------------
free_vector dw ? ;Pointer to available interrupt vector
copyright db ' Copyright (c) 1986 Kudos Software '
baddos_msg db 'TSR will not run with DOS 1.XX'
db 0DH, 0AH, '$'
remove_msg db 'TSR is no longer resident in memory'
db 0DH, 0AH,'$'
success_msg db 'TSR successfully installed in memory'
db 0DH, 0AH, '$'
;------------------------------------------------------------------------------
code ends
end entry_point ;Define entry point for .COM file