;*************************************************************
;**   Terminate-but-Stay-Resident                           **
;**   Original from the "Programmer's Journal"              **
;**   Modified by Alroger L. Gomes Jr.                      **
;**   Any comments/question send message for "Roger Gomes"  **
;**   on the PDSE BBS (408)735-7190. Have Fun!              **
;*************************************************************
; Insert you program on line # 157.

Delay_Count     Equ     36                      ;36 ticks=approx. 2 seconds

;  Locations of BIOS Data needed by the resident program

Bios_Data       Segment at 40h
        Org     17h
        Kbd_Status      dw      ?
        Org     6Ch
        Low_Timer       dw      ?
Bios_Data       EndS


Code            Segment
        Assume  Cs:Code, Ds:Code, Es:Nothing, Ss:Nothing
        Org     100h
Entry_Point:
        Jmp     Install

        Hot_Keys        dw      01010B
        This_Time       dw      ?
        Trig_Time       dw      ?
        Dos_Busy        Label   dword
        Dos_Busy_Off    dw      ?
        Dos_Busy_Seg    dw      ?
        Criterr_Flag    db      ?

Already8	db	0
MenuON  	db      0


;*** Replacement for Int 24h - critical Dos Error ***
Diverted_Int24:
        Mov     Cs:Criterr_Flag,1
        Xor     Al,Al
        Iret

        Int_24_Vect     Label   dword
        Int_24_Off      dw      ?
        Int_24_Seg      dw      ?

;***** ID CODE *****
Res_ID1 dw      'Al'
Res_ID2 dw      'ro'
Res_ID3 dw      'ge'
;*******************

;*** Replacement for Int 8 - Timer hardware Interrupt ***
Diverted_Int8:
        Pushf
        Call_Int8       db      09Ah
        Int_8_Vect      Label   dword
        Int_8_Off       dw      ?
        Int_8_Seg       dw      ?

        Cmp     Cs:MenuOn,0
        Je      MenuNOT
	Iret
MenuNOT:
	Mov	Cs:MenuOn,1
        Push    Ds
        Push    Bx
        Lds     Bx,Cs:Dos_Busy
        Cmp     Byte Ptr [Bx],0
        Pop     Bx
        Pop     Ds
	Mov	Cs:MenuOn,0
	Jz	Get_Bios_Data
Dos_is_Busy:
        Iret

;*** Replacement for Int 28 - Generated by Dos, esp. during keyboard I/O ***
Diverted_Int28:
        Pushf
        Call_Int28      db      09Ah
        Int_28_Vec      Label   dword
        Int_28_Off      dw      ?
        Int_28_Seg      dw      ?
	Cmp	Cs:MenuOn,0
	Je	Get_Bios_Data
	Iret	

Get_Bios_Data:
	Mov	Cs:MenuOn,1
        Sti
        Push    Ds
        Push    Ax
        Mov     Ax,Bios_Data
        Mov     Ds,Ax
        Assume  Ds:Bios_Data
        Mov     Ax,Low_Timer
        Mov     Cs:This_time,Ax
        Mov     Ax,Kbd_Status
        Push    Cs
        Pop     Ds
        Assume  Ds:Code
Chk_Keys:
        And     Ax,Hot_Keys
        Cmp     Ax,Hot_Keys
        Jne     Back_to_Applic
Chk_Timer:
        Mov     Ax,This_Time
        Cmp     Ax,Trig_Time
        Jb      Time_is_Right
        Sub     Ax,Trig_Time
        Sub     Ax,Delay_Count
        Jnc     Time_is_Right

Back_to_Applic:
        Pop     Ax
        Pop     Ds
	Mov	Cs:MenuOn,0
        Iret

Time_is_Right:
        Mov     Ax,This_Time
        Mov     Trig_Time,Ax
        Pop     Ax
        Pop     Ds

;***************************************************************************
; This is the Start of the application-dependent resident code

Start_Program:
	Mov	Cs:MenuOn,1
        Push    Ax
        Push    Bx
        Push    Cx
        Push    Dx
        Push    Si
        Push    Di
        Push    Bp
        Push    Ds
        Push    Es

        Push    Cs
        Pop     Ds

        Mov     Ax,3524h
        Int     21h
        Mov     Int_24_Off,Bx
        Mov     Int_24_Seg,Es
        Mov     Ax,2524h
        Mov     Dx,Offset Diverted_Int24
        Int     21h

;****************************************************************************

; Insert your program here.

;****************************************************************************

Restore_Int24:
        Lds     Dx,Int_24_Vect
        Mov     Ax,2524h
        Int     21h
        Pop     Es
        Pop     Ds
        Pop     Bp
        Pop     Di
        Pop     Si
        Pop     Dx
        Pop     Cx
        Pop     Bx
        Pop     Ax
        Mov     Cs:MenuOn,0
	Mov	Cs:Already8,0
        Iret

;  This is the end off the applicant-dependent resident code

        End_of_Res      Label   word

;***************************************************************************
; Installation

Install:
	Mov	Ax,Cs
	Mov	Ds,Ax
	Mov	Es,Ax

	Mov	Ah,9
	Mov	Dx,OffSet CopyRight
	Int	21h

; Make sure that it is at least Dos 2.00
        Mov     Ah,30h
        Int     21h
        Or      Al,Al
        Jnz     Chk_Vectors
        Mov     Dx,Offset BadDos_Msg
        Mov     Ah,9
        Int     21h
        Int     20h

; See if resident code is already Installed in Memory

Chk_Vectors:
	Mov	Ax,Cs
	Mov	Ds,Ax
	Mov	Es,Ax

        Mov     Ax,3508h
        Int     21h
        Cmp     Word Ptr [Es:Bx-6],'Al'
        Jne     Not_Installed1
        Cmp     Word Ptr [Es:Bx-4],'ro'
        Jne     Not_Installed1
        Cmp     Word Ptr [Es:Bx-2],'ge'
        Jne     Not_Installed1

        Mov     Dx,Offset No_Install_Msg
        Mov     Ah,9
        Int     21h
        Mov     Ax,4C01h
        Int     21h

Not_Installed1:
        Mov     Ax,3577h
        Int     21h
	Mov	Ax,Es
        Cmp     Ax,'Al'
        Jne     Not_Installed
        Cmp     Bx,'ro'
        Jne     Not_Installed

        Mov     Dx,Offset No_Install_Msg
        Mov     Ah,9
        Int     21h
        Mov     Ax,4C01h
        Int     21h

Not_Installed:
	Mov	Ax,Cs
	Mov	Ds,Ax
	Mov	Es,Ax

        Push    Es
	Mov	Ax,Cs
	Mov	Ds,Ax
	Mov	Es,Ax

        Mov     Ah,34h
        Int     21h
        Mov     Dos_Busy_Off,Bx
        Mov     Dos_Busy_Seg,Es

        Mov     Ax,3508h
        Int     21h
        Mov     Int_8_Off,Bx
        Mov     Int_8_Seg,Es
	
	Mov	Ax,Cs
	Mov	Es,Ax
	Mov	Ds,Ax

        Mov     Ax,2508h
        Mov     Dx,Offset Diverted_Int8
        Int     21h

	Mov	Ax,'Al'
	Mov	Ds,Ax
	Mov	Dx,'ro'
	Mov	Ax,2577h
	Int	21h
	Mov	Ax,Cs
	Mov	Ds,Ax

        Mov     Ax,3528h
        Int     21h
        Mov     Int_28_Off,Bx
        Mov     Int_28_Seg,Es
        Mov     Ax,2528h
        Mov     Dx,Offset Diverted_Int28
        Int     21h
        Pop     Es

; Terminate and stay resident
	Mov	Dx,Offset Install
	Int	27h

No_Install_Msg  db      'xxxx is already in memory!',10,13,10,13,'$'
BadDos_Msg      db      'DOS 2.0 or greater needed!',10,13,10,13,'$'
CopyRight	db  	'xxxx by ?????? - yyyy        $'

Code    EndS
        End     Entry_Point

