⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tsrbones.asm

📁 一个关于内存驻留的汇编源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;       handling is underway. We do this by querying the Intel 8259A Program-
;       mable Interrupt Controller (PIC) chip's In Service Register (ISR) and
;	testing it to see that it is zero (i.e., nothing being serviced).
;
HotKeyPressed:
                mov     al,ISRREQ       ;al=PIC's OCW3 to ask for ISR Register.
		out	PICPORT,al	;Tell PIC to get ISR ready for reading.
		jmp	Dally		;Give PIC time to make ISR available.
Dally:		in	al,PICPORT	;Fetch the ISR Register from PIC.
                or      al,al           ;Activate processor flags.
                jnz     SetFlag         ;If al not zero, go set flag.
;
;       At this point, HotKey is known to be pressed AND NO hardware interrupt
;	is being serviced. BUT is InDOS flag zero, indicating that DOS is
;	not busy and therefore can safely be entered? This will now be
;	checked:
;
HotKeyNoHWI:
		les	bx,indosptr	;es:bx = pointer to InDOS flag
		mov	al,es:[bx]	;al = InDOS flag.
                or      al,al           ;Activate processor flags.
                jnz     SetFlag         ;Jump if InDOS not zero.
;
;       Include a check on Critical Error flag. Don't trigger the TSR if
;       DOS is in the middle of handling a Critical Error:
;
                les     bx,criterrptr   ;es:bx = pointer to CritErr flag.
                mov     al,es:[bx]      ;al = CritErr flag.
;
;       Also, don't trigger the TSR if time-critical Disk access is underway:
;               Normally, this Disk check would not be necessary since the
;               InDOS flag would not be clear during Disk accesses, BUT some
;               software will bypass DOS and go directly to the BIOS Int13
;               Interrupt for Disk access. Therefore, to be safe, we HAVE to
;               be sure Int13 has not been entered and is not in the process
;               of performing time-critical Disk stuff when we hit the TSR
;               HotKey. Many TSRs don't even check this. They just depend
;               upon users not to hit the HotKey during Disk access. That seems
;               terribly risky to me:
;
                or      al,diskflag     ;al = CritErr | diskflag
                                        ; (| => Logical OR).
                jnz     Exit09          ;If al not zero, try again later.
;
;       Also, don't trigger the TSR if a PrtScrn is in progress:
;       (Is this really necessary? I don't think TSR will trigger during PrtSc)
                les     bx,prtscrn      ;ES:bx = pointer to PrtScrn busy flag.
                cmp     BYTE PTR es:[bx],1      ;Is PrtScrn in progress?
                je      Exit09          ;If so, try again later.
;
                STI                     ;Allow other interrupts in our TSR.
;
                call    ROUTINE         ;All is clear!, so call routine.
                mov     hotkeyflag,0    ;Be sure HotKey flag is reset.
                jmp     SHORT Exit09    ;Exit after TSR routine.
;
SetFlag:
                mov     hotkeyflag,1    ;Set HotKey Flag for use by Int28h.
;
Exit09:
                mov     CS:bellgate,0   ;Open gate allowing new HotKey detect.
BusyExit09:
                pop     es              ;Restore all registers
                pop     ds
                ASSUME  DS:NOTHING      ;v0.01
                pop     bp
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx
		pop	ax
;
;
;	Return from this TSR's Keyboard Interrupt 09h handler routine:
		iret
;
NewInt09	ENDP			;v0.01
;
;*************************************************************************
PAGE
;*************************************************************************
NewInt13        PROC    FAR             ;We hook Int13h only for purpose
                                        ;of setting a flag to prevent our
                                        ;TSR from triggering during time-
                                        ;critical Disk accesses.
                mov     CS:diskflag,1   ;Set flag to show Disk access.
;
                pushf                   ;Invoke prior Int13 handler
                cli                     ;(be sure interrupts disabled)
                call    CS:oldint13     ;by simulating an interrupt.
;
                mov     CS:diskflag,0   ;Clear flag to show Disk finished.
;
; The following RET 2 bumps the SP register up by 2 bytes to effectively
;        take the flags off the stack (where they were put by the invoking
;        INT 13h) WITHOUT popping them off and ruining the meaningful flags
;        left in the Flags register by the original DOS INT13 handler (the
;        DOS INT13 handler also returns via a RET 2 to keep from ruining the
;        Flags that the handler has painstakingly prepared for communicating
;        back to the calling program). The effect on the stack pointer, SP, is
;        exactly the same as with the more usual IRET. It is just that the Flags
;        in the Flag register are preserved at the values the handler placed
;        and wanted there.
;
                RET     2               ;Return from interrupt while
                                        ;preserving flags.
;
NewInt13        ENDP
;*************************************************************************
PAGE
;*************************************************************************
NewInt16	PROC	FAR		;v0.01
;
                push    ds              ;Entry for New Int. Handler.
;                                       ;Save required registers.
;
                push    CS              ;Set data seg   v0.01
                pop     DS              ;to our CodeSeg v0.01
		ASSUME	DS:CodeSeg	;v0.01
;
; This next portion of code provides back to the non-resident
; TSR installation code a check on whether the TSR has already been installed.
; It does this through the following technique:
;        Check to see if the ax, bx, cx, dx registers are loaded with this
;	TSR's signature words. Since all TSR ax signature words are chosen 
;	so as NOT to match any allowed DOS Int16h Function in ah, ALL
;	standard DOS Int16h calls will exit from this sequence of compares
;	at the first JNE instruction below and will ultimately be processed
;	by the standard DOS Int16h handler.
;	 The ONLY place where all the registers are loaded with THIS TSR's
;	signature words and then Int16h called is IN THE INITIALIZATION CODE 
;	AT THE END OF THIS TSR. Given that all the signature words are matched
;	in the four comparisons below, we need to signal back to the
;	invoking TSR initialization code by setting the data registers to
;	values that NEVER would be returned by the standard DOS Int16h handler,
;	and that therefore could ONLY have come from this previously-installed
;	TSR's Int16h handler code. The TSR installation code will then take
;	the return of these unique register values as the indication that
;	this TSR has already been installed.
;
		cmp	ax,TSRsigA	;Is ax = TSR signature word A?
		jne	Exit16		;No, let regular Int16 handle this.
		cmp	bx,TSRsigB	;Is bx = TSR signature word B?
		jne	Exit16		;No, let regular Int16 handle this.
		cmp	cx,TSRsigC	;Is cx = TSR signature word C?
		jne	Exit16		;No, let regular Int16 handle this.
		cmp	dx,TSRsigD	;Is dx = TSR signature word D?
		jne	Exit16		;No, let regular Int16 handle this.
;
;       The ONLY way you ever get to here is by having called Int16h with the
;	ax, bx, cx, dx registers loaded with this TSR's signature words. This
;	only occurs in the TSR initialization routine. Therefore, set the
;       registers to return values that a DOS Int16h never would, and then
;       return from this interrupt back to the TSR initialization routine.
;
                xchg    bx,cx   ;Exchange regs. (DOS Int16h wouldn't do this)
		xchg	ax,dx	;   "         "        "
;
                pop     ds      ;Restore regs.
                iret            ;Return from Int to TSR Initialize routine.
;
Exit16:
                pop     ds                      ;Restore all registers
		ASSUME	DS:NOTHING	;v0.01
;
;       Chain to prior Interrupt 16h handler routine:
                jmp     CS:oldint16
;
NewInt16        ENDP            ;v0.01

;*************************************************************************
PAGE
;*************************************************************************
NewInt28	PROC	FAR		;v0.01
;
                pushf                   ;Call prior handler.
                cli
                call    CS:oldint28
;
;	Determine if this TSR's HotKey has been flagged as pressed:
                cmp     CS:hotkeyflag,1 ;Has HotKey been pressed?
                jne     QuickExit       ;Exit if not.
;
                cmp     CS:bellgate,1   ;Is gate closed?
                je      QuickExit       ;If so, exit.
                mov     CS:bellgate,1   ;Else close gate and proceed.
;
                CLI                     ;DISABLE INTERRUPTS
;       If you are here, then HotKey has been pressed.
                push    ax              ;Entry for New Int. Handler.
                push    bx              ;Save all registers.
                push    cx
                push    dx
                push    si
                push    di
                push    bp
                push    ds
                push    es
;
                push    CS
                pop     DS
                ASSUME  DS:CodeSeg      ;v0.01
;
;
;       Make sure InDOS flag is no greater than 1. The InDOS flag equals
;       the number of DOS calls currently active. If we want to be sure
;       that we do not disrupt DOS by reentry in our TSR user routine,
;       we have to be sure that the present Int28 has occurred while
;       only 1-deep into DOS calls (as it is when DOS is TRULY idling):
                les     bx,indosptr             ;ES:bx points to InDOS flag.
                cmp     BYTE PTR ES:[bx],1      ;Is InDOS flag above 1?
                ja      Exit28                  ;Exit if InDOS > 1.
;
;       DOS is known to be idling at this point.
;	At this point, HotKey is known to have been pressed. Now we will
;	check to be sure that no time-critical hardware interrupt handling
;	is underway. We do this by querying the Intel 8259A Programmable
;	Interrupt Controller (PIC) chip's In Service Register (ISR) and
;	testing it to see that it is zero (i.e., nothing being serviced
;	except Int09 (PIC's IRQ1) ):
HotKeyPressed2:
                mov     al,ISRREQ       ;al=PIC's OCW3 to ask for ISR Register.
		out	PICPORT,al	;Tell PIC to get ISR ready for reading.
		jmp	Dally2		;Give PIC time to make ISR available.
Dally2:		in	al,PICPORT	;Fetch the ISR Register from PIC.
;
;       Also, don't trigger the TSR if time-critical Disk access is underway:
                or      al,diskflag     ;al = ISR | diskflag. (| => Logical OR).
                jnz     Exit28          ;If al not zero, try again later.
;
;       Also, don't trigger the TSR if a PrtScrn is in progress:
;       (Is this really necessary? I don't think TSR will trigger during PrtSc)
                les     bx,prtscrn      ;ES:bx = pointer to PrtScrn busy flag.
                cmp     BYTE PTR es:[bx],1      ;Is PrtScrn in progress?
                je      Exit28                  ;If so, Exit w/o triggering TSR.
;
                STI                     ;ENABLE OTHER INTERRUPTS.
;
HotKeyFlagSet:
;	Here, HotKey is flagged as pressed and DOS is idling (since we are
;       servicing Int28h) and no hardware interrupts are being handled.
;       Also, no Print Screen or Disk access is underway.
;	DOS Int21h Functions above 0Ch can be accessed if required in your 
;	TSR routine:
;
                call    ROUTINE         ;Call TSR routine; DOSOK & No Hardware
					;interrupts being serviced.
                mov     CS:hotkeyflag,0    ;Clear HotKey Flag.
;
Exit28:
                pop     es                      ;Restore all registers
                pop     ds
                ASSUME  ds:NOTHING
                pop     bp
		pop	di
		pop	si
		pop	dx
		pop	cx
		pop	bx
		pop	ax
                mov     CS:bellgate,0
;
QuickExit:
;       Return from this Keyboard Interrupt 28h handler routine:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -