📄 tsrbones.asm
字号:
iret
;
NewInt28 ENDP ;v0.01
;*************************************************************************
; -END OF TSR's RESIDENT CODE-
; Only the code above will remain locked in memory
; after the initialization performed below.
;*************************************************************************
SUBTTL TSR BOOSTER (Initialization)
PAGE
;*************************************************************************
; BEGINNING OF TSR's INITIALIZATION CODE (THE "BOOSTER"):
; The following code is protected in RAM *ONLY* during initialization
; of the TSR that occurs when the TSR name is first invoked
; at the DOS command level. All the following code is abandonned
; unprotected in RAM after the Terminate-and-Stay-Resident (TSR)
; call to Function 31h of DOS Interrupt 21h below. This
; is allowed to happen because the code's work is complete at
; that point. The code will be overwritten as the memory which
; it temporarily occupied is needed by DOS for other purposes.
;
; I have seen this following section of code colorfully called
; the TSR "Booster". This is quite appropriate since the code
; sits here, strapped to the very end of the TSR, and it is of
; use only during the "blastoff" (initialization) of the TSR, when
; it is used to put the TSR into "orbit" (residency), and after
; which it is "jettisoned" (abandonned unprotected in memory) by
; the DOS TSR call, Int 21h, Fcn 31h.
;
TSRinit PROC NEAR ;v0.01
EndDump EQU $ ;Roy Silvernail - Keep TASM 1.0 happy
;when computing # resident paragraphs.
;
; Get DOS Version Number:
mov ah,30h ;Fcn 30h = Get DOS Version
int 21h ;DOS Version = al.ah
;
; If this is DOS v.1.x, this TSR cannot work, so go print message
; and exit without installing:
cmp al,1 ;Is this DOS Version 1.x?
ja DOSverOK ;If not, DOS version is OK.
push bx ;A "push" for the "pop" at DOSver1 label.
jmp DOSver1 ;If so, TSR won't work so exit.
;
DOSverOK:
; If here, DOS version is 2.0 or later. TSR can work, so proceed.
;
; Check for prior installation of this TSR:
;
mov ax,TSRsigA ;Prime registers for our
mov bx,TSRsigB ;Int16h handler's check
mov cx,TSRsigC ;for prior installation
mov dx,TSRsigD ;thru TSR signature words.
;
Int 16h ;Check prior installation.
;
cmp ax,TSRsigD ;Was TSR signature detected?
jne Install ;If not, Install it.
cmp bx,TSRsigC
jne Install
cmp cx,TSRsigB
jne Install
cmp dx,TSRsigA
jne Install
;
; If you are here, all four TSR signature words were detected and signalled,
; so the TSR is already installed.
; Announce the TSR's PRIOR Installation and exit:
mov dx,Offset PriorInstMsg ;DX points to message.
mov ah,09h ;DOS Fcn. 09h=Display String.
Int 21h ;Display String via DOS.
;
mov ax,4C00h ;Fcn 4C = DOS Terminate call
Int 21h ;Do it.
;
Install:
; If you are here, then DOS version is 2.+ and the TSR has not
; previously been installed.
;
; To conserve RAM usage, release from memory the copy of the DOS
; Environment passed to this TSR (this assumes, of course, that
; your Interrupt handler routine will not need to reference this
; de-allocated Environment) So, if you are going to write your
; TSR routine to reference the Environment, DON'T DEALLOCATE IT
; HERE.
;
;Get segment of Environment
;from 02Ch in the Program
;Segment Prefix (PSP).
;
mov ES,envseg ;ES=PSP's environ seg v0.01
mov ah,49h ;DOS Fcn 49h = Release Memory
int 21h ;Release it via DOS interrupt.
;
; In order to make the TSR's command name show under the "owner" column in
; the "MAPMEM" command of Kim Kokkonen's excellent TSR Mark/Release
; package, allocate a tiny 1-paragraph "Pseudo-Environment" here which
; contains nothing but the TSR name.
;
; Allocate the memory needed by the tiny 'Pseudo-Environment":
mov bx,1 ;Allocate one parag. (16bytes)
mov ah,48h ;and return allocation
int 21h ;segment in ax via DOS call.
;
mov ES,ax ;Pseudo-Env. Segment to ES.
mov si,OFFSET PseudoEnv ;si=source string OFFSET.
mov di,0 ;di=destination string OFFSET.
mov cx,ENVLNGTH ;cx=Bytes in Pseudo-Env.string.
cld ;Forward string move direction.
rep movsb ;Move Pseudo-Env. string @ DS:si to ES:di
;
; Set PSP's Environment segment pointer to point to tiny Pseudo-Environment.
mov envseg,ES
;
;*****************************************************************************
; NOW, capture all the required Interrupts:
;
; **** INT 09 ****
; Get Old Interrupt 09h Vector:
mov ax,3500H+HOOK09 ;Get old Int 9 vector v0.01
int 21h ;Int.Vector in ES:BX via DOS.
;
; Save Old Interrupt 09h Vector:
mov Word Ptr oldint09,bx ;Save Offset of Old Interrupt.
mov word ptr oldint09+2,ES ;save seg v0.01
;
; Install New Interrupt Vector to this TSR's "NewInt09:" Label:
mov ax,2500H+HOOK09 ;Set new Int 9 vector v0.01
mov dx,Offset NewInt09 ;dx=Offset of New Int Handler.
int 21h ;Set New Int via DOS.
;
; **** INT 13 ****
; Get Old Interrupt 13h Vector:
mov ax,3500H+HOOK13 ;Get old Int 13 vector
int 21h ;Int.Vector in ES:BX via DOS.
;
; Save Old Interrupt 13h Vector:
mov Word Ptr oldint13,bx ;Save Offset of Old Interrupt.
mov word ptr oldint13+2,ES ;save Segment.
;
; Install New Interrupt Vector to this TSR's "NewInt13:" Label:
mov ax,2500H+HOOK13 ;Set new Int 13 vector.
mov dx,Offset NewInt13 ;dx=Offset of New Int Handler.
int 21h ;Set New Int via DOS.
;
; **** INT 16 ****
; Get Old Interrupt 16h Vector:
mov ax,3500H+HOOK16 ;get old Int 16H vector v0.01
int 21h ;Int.Vector in ES:BX via DOS.
;
; Save Old Interrupt 16h Vector:
mov Word Ptr oldint16,bx ;Save Offset of Old Interrupt.
mov word ptr oldint16+2,ES ;save segment v0.01
;
; Install New Interrupt Vector to this TSR's "NewInt16:" Label:
mov ax,2500H+HOOK16 ;set new Int 16H vector v0.01
mov dx,Offset NewInt16 ;dx=Offset of New Int Handler.
int 21h ;Set New Int via DOS.
;
; **** INT 28 ****
; Get Old Interrupt 28h Vector:
mov ax,3500H+HOOK28 ;Get old Int 28H vector v0.01
int 21h ;Int.Vector in ES:BX via DOS.
;
; Save Old Interrupt 28h Vector:
mov Word Ptr oldint28,bx ;Save Offset of Old Interrupt.
mov word ptr oldint28+2,ES ;save segment v0.01
;
; Install New Interrupt Vector to this TSR's "NewInt28:" Label:
mov ax,2500H+HOOK28 ;set new Int 28H vector v0.01
mov dx,Offset NewInt28 ;dx=Offset of New Int Handler.
int 21h ;Set New Int via DOS.
;
;*****************************************************************************
; Get Pointer to InDOS flag ("DOS Busy" flag) and save it:
mov ah,34h ;DOS FCN=34h:Get InDOS Pointer.
int 21h ;Pointer in ES:BX
mov Word Ptr indosptr,bx ;Save Offset of InDOS flag.
mov Word Ptr indosptr+2,ES ;Save Segment of InDOS flag.
;
mov Word Ptr criterrptr+2,ES ;Also, Seg of CritErr flag.
push bx ;Save indosptr on stack for use below.
;
; Get DOS Version Number:
mov ah,30h ;Fcn 30h = Get DOS Version
int 21h ;DOS Version = al.ah
;
; If DOS version is 2.x, then DOS Critical Error flag is @ indosptr + 1.
; If DOS version is 3.x+, then DOS Critical Error flag is @ indosptr - 1.
; Determine DOS Version:
cmp al,2 ;Is it DOS Version 2.x?
je DOSver2 ;If yes, jump;
ja DOSver3 ;or, if later version, jump;
;else, it's DOS Version 1.x:
;
DOSver1: ;If here, DOS Version 1.x is being run:
mov dx,OFFSET BailOutMsg ;TBONES needs DOS 2.x or later.
mov ah,09h ;Say we're sorry, but NO GO
int 21h ;via DOS.
pop bx ;Clear stack.
int 20h ;Terminate without installing
;in only way DOS 1.x knows.
;
DOSver2: ;If here, DOS Version 2.x is being run:
pop bx ;Get indosptr from stack.
inc bx ;CritErr flag is @ indosptr+1.
mov Word Ptr criterrptr,bx ;Save CritErr Pointer.
jmp Announce ;Go announce TSR installed.
;
DOSver3: ;If here, DOS Version 3.+ is being run:
pop bx ;Get indosptr from stack.
dec bx ;CritErr flag is @ indosptr-1.
mov Word Ptr criterrptr,bx ;Save CritErr Pointer.
;
; Announce the TSR's Installation:
Announce:
mov dx,Offset InstallMsg ;DX points to message.
mov ah,09h ;DOS Fcn. 09h=Display String.
int 21h ;Display String via DOS.
;
; Lock resident code in memory via Terminate-and-Stay-Resident (TSR) DOS call:
;
;v0.11 DX requires size of resident code (in 16-byte paragraphs)
; This awkward construct is required to keep
; DOS Function 31h happy. Notice how we first compute
; the length of the TSR code in bytes [i.e., end of
; the TSR code (EndDump) minus start of the TSR code
; (0, our BeginDump)], round it up to the next whole paragraph ( + 0Fh),
; and then divide by 16 (SHR 4) to get the number of resident paragraphs:
;
mov dx,(EndDump-BeginDump+0Fh)/16
;Roy Silvernail discovered that the BeginDump and EndDump symbols
;were necessary to keep TASM 1.0 happy when computing # resident paragraphs
;in the above statement.
;
mov ah,31h ;DOS FCN 31h=TSR Call.
int 21h ;Go Resident via DOS TSR call.
;
PseudoEnv: DB ' ',0,0,1,0,'TSRBONES',0
ENVLNGTH EQU $-PseudoEnv
;
BailOutMsg:
db 0Dh,0Ah
db 'Sorry. TSRBONES needs DOS v.2+. You have v.1.x'
db 0Dh,0Ah,'$'
PriorInstMsg:
db 0Dh,0Ah
db 'TSRBONES IS *ALREADY* INSTALLED.'
InstallMsg:
db 0Dh,0Ah
db 'HotKey => Ctrl-Alt-B'
db 0Dh,0Ah
db 0Dh,0Ah
db 'TSRBONES Version 0.1'
db 0Dh,0Ah
db 'Copyright (C) 1990 by Robert Curtis Davis'
db 0Dh,0Ah,'$'
;
TSRinit ENDP ;v0.01
CodeSeg ends
end Entry
;***********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -