Vous êtes sur la page 1sur 6

; note : this template is for .com files only do not use for .exe files!!

;
;
;
; copyright 1986 by dana nowell - all rights reserved
;
; history:
; version date name description
; 1.0 11/10/86 dn first cut
; 1.01 11/21/86 dn fixed memory allocation bug
; added installation message
;

title tsr template

null equ 00h


bell equ 07h ; bell character
backspace equ 08h ; backspace character
tab equ 09h ; tab character
lf equ 0ah ; line feed
f_feed equ 0ch ; form feed
cr equ 0dh ; carriage return
eof equ 1ah ; ctrl z ( end of file )
space equ ' ' ; ascii space character
quote equ '"'

signature1 equ 6144h ; used for already


signature2 equ 616eh ; resident check

dos_int equ 21h ; dos function interrupt


disp_char equ 02h
get_key equ 08h
dos_scr_msg equ 09h
dos_set_int equ 25h
dos_resident equ 31h
dos_get_int equ 35h
dos_terminate equ 4ch
dos_string_term equ '$'

; interrupt vectors used

hook_int equ 1ch ; interrupt to be hooked ( timer tick now )

;------------------------------------------------------------------------------
;
; macro section
;
;------------------------------------------------------------------------------

version_msg macro
jmp short copyright_end

copyright_msg db cr, lf
db 'tsr shell - version 1.01', cr, lf
db 'copyright 1986, dana nowell ', cr, lf, cr, lf
db 'may be distributed without license', cr, lf, '$'
copyright_end:
msg copyright_msg
endm

msg macro ptr

push dx
push ax

lea dx, ptr


mov ah, 09h
int 21h

pop ax
pop dx

endm

com segment para public 'code'


assume cs:com, ds:com, es:com

;------------------------------------------------------------------------------
;
; note: the psp occurs at the beginning of the code segment
; for all programs. in com files the code seg = data seg
;
;------------------------------------------------------------------------------

org 0

psp_start dw ? ; int 20h - possibly a block for unresolved


; externals during link ?

mem_size dw ? ; size of available memory in paragraphs


filler db ? ; reserved usually zero

dos_call db ? ; call
dd ? ; address of dos function handler

term_vector dd ? ; address of dos terminate routine


break_vector dd ? ; address of dos break routine
error_vector dd ? ; address of dos error routine
dos_reserved db 2 dup(?); reserved by dos
dos_handles db 20 dup(?) ; file handle array
environ_ptr dw ? ; seg of dos environment ( offset = 0 )
dos_work db 34 dup(?) ; dos work area

int_21h db ? ; int
db ? ; 21h
db ? ; retf ( return far )
reserved dw ? ; reserved by dos
fcb1_ext db 7 dup(?) ; fcb # 1 extension
fcb1 db 9 dup(?) ; fcb #1
fcb2_ext db 7 dup(?) ; fcb # 2 extension
fcb2 db 20 dup(?) ; fcb #2

;
; disk transfer area ( dta ) and parameter block occupy the same space
;
;
;dta db 128 dup(?) ; disk transfer area

param_len db ? ; length of parameter string ( excludes cr )


parameters db 127 dup(?) ; parameters

;------------------------------------------------------------------------------
;
; note on standard fcb structure :
;
; the standard fcb is larger than the size reserved in the psp if you
; intend to use to fcb data from the psp move it to a different location.
;
;
; standard structure of a file control block
;
;
; extension :
; offset length description
; -7 1 extension active flag ( 0ffh = active )
; -6 5 normally unused should be zeros
; -1 1 file attribute when extension is active
; 1 . . . . . . . 1 read-only
; 2 . . . . . . 1 . hidden
; 4 . . . . . 1 . . system
; 8 . . . . 1 . . . volume label
; 16 . . . 1 . . . . subdirectory
; 32 . . 1 . . . . . archive
; 64 . 1 . . . . . . unused
; 128 1 . . . . . . . unused
;
; fcb :
; offset length description
; 0 1 special drive number ( 1 byte )
; 0 = default
; 1 = a:
; 2 = b: etc
; 1 8 filename or device name
; 9 3 filename extension
; 12 2 current block number
; 14 2 record size
; 16 4 file size in bytes ( dos dir entry at open )
; 20 2 file date ( bit coded as in dir )
; 22 10 dos work area
; 32 1 current record number ( 0 - 127 )
; 33 4 random record number
;
;------------------------------------------------------------------------------

org 100h ; required for com file ( skips psp )

start:
jmp install ; install the demon

;-------------------------------------------------------------------
;
; resident data structures go here
;
;-------------------------------------------------------------------

old_int dd 0 ; original value of hooked interrupt


resident1 dw signature1
resident2 dw signature2

;-------------------------------------------------------------------
;
; new interrupt starts here
;
;-------------------------------------------------------------------

new_int:
pushf

sti ; must turn int on if we're going to use them

;-------------------------------------------------------------------
;
; be well behaved and pass control to original int
;
;-------------------------------------------------------------------

popf
pushf
call dword ptr cs:old_int ; do old interrupt

iret ; bye bye

;------------------------------------------------------------------------------
;
; installation data structures and code go here
;
; warning warning warning - this area does not exist after installation
;
;------------------------------------------------------------------------------

last_resident_byte db 0 ; last resident byte


resident_flag dw 0 ; am i already resident ? ( 0 = no )

install_msg db cr, lf, 'installation complete', cr, lf, '$'


already_installed_msg db cr, lf
db 'already installed - installation aborted'
db cr, lf, '$'

install proc near

version_msg

mov al, hook_int ; int to hook


mov ah, dos_get_int ; get int(al) vector ==> es+bx
int dos_int ; do the int
lea si, old_int ; where to put old timer interrupt vector
mov [si], bx ; save the offset and segment
mov 2[si], es ; ( es also used in check resident )

call check_resident ; am i already resident ?

cmp resident_flag, 0
je not_resident

msg already_installed_msg

mov ah, dos_terminate ; terminate & stay resident


mov al, 1 ; return value is 1 (already installed)
int dos_int ; bye-bye

not_resident:
mov dx, offset new_int ; offset of new timer interrupt
mov al, hook_int ; timer tick
mov ah, dos_set_int ; set int(al) vector from ds+dx
int dos_int ; do the int

; program terminate and stay resident

msg install_msg ; display the installation message

mov dx, offset last_resident_byte

mov cl, 4 ; convert to paragraphs required to


shr dx, cl ; remain resident ( divide by 16 )
inc dx ; allow for any remainder of division

mov ah, dos_resident ; terminate & stay resident


mov al, 0 ; return value is 0 (good return)
int dos_int ; bye-bye

install endp

;
; check resident procedure
; requires es register to contain the segment address of
; the current location for the interrupt being hooked.
; use the dos function 35h to obtain this information.
;

check_resident proc near


cmp es:resident1, signature1
jne not_res
cmp es:resident2, signature2
jne not_res

mov resident_flag, 1

not_res:
ret

check_resident endp

com ends
end start

Vous aimerez peut-être aussi