// TSR_2 Example //Scout equals _KeyboardFlags = 0417h (expr Terminate (?) ax=4C^1; 21h=.int expr) (expr JumpFAR ?) -> bytes =0EAh, ^1(4) (expr SetVector (?) di=OFFSET Old_Int_^1 dx=OFFSET Int_^1 al=^1 call Set_Vector expr) (expr RestoreVector (?) si=OFFSET Old_Int_^1 al=^1 call Restore_Vector expr) (expr ChkVector (?, ?) dx=^2 al=^1 si=OFFSET Int_^1 call Chk_Vector expr) (expr FreeEnvironment es=WORD PTR ds:[2Ch] ah=49h; 21h=.int expr) (expr TSR (?) dx=OFFSET ^1; 27h=.int expr) (expr ChkInstall (?) if ax=^1 then al=0FFh; cs=.push; es=.pop; .iret JumpFAR Old_Int_2Fh expr) (expr FreeMemory ah=49h; 21h=.int expr) equals HotKey = 3920h, ShiftStatus = 00000001b equals BufferSize = 0 equals Request = 5678h, Reply = 8765h, MaxAttempt = 3 MODEL Tiny, Pascal .ORG 100h PROGRAM TSR_2 .LOCALS _@ goto Initialize bytes Flags = 00000000b, Attempts, SaveAH ddata In_DOS_Flag (proc FAR Int_28h()[] .sti (if cs:Flags.test.00000001b<> cs:Flags=.or.00000010b; call Process(); cs:Flags=.and.11111101b if) .cli JumpFAR Old_Int_28h proc) (proc FAR Int_16h()[] (if cs:Flags.test.00000100b= (if ah.test.11101110b<> if ax<>Request goto Pass_16h ax=Reply; push cs; pop es; .iret if) if cs:Flags.test.00000001b<> then call Process() (if ah.test.00000001b= (while cs:SaveAH=ah .sti; .pushf; .cli; call DWORD PTR cs:Old_Int_16h() if ax<>HotKey then .iret call ChkShiftStatus() if <> then .iret call Process() ah=cs:SaveAH while) if) cs:SaveAH=ah; cs:SaveAH=-1 .sti; .pushf; .cli; call DWORD PTR cs:Old_Int_16h() (if <> and ax=HotKey call ChkShiftStatus() if <> then 2=.retf ah=cs:SaveAH .pushf; .cli; call DWORD PTR cs:Old_Int_16h() call Process() if) 2=.retf if) Pass_16h: JumpFAR Old_Int_16h proc) (proc ChkShiftStatus()[ax,es] es=ax=0 al=BYTE PTR es:[_KeyboardFlags]; al=.and.00001111b al=.cmp.ShiftStatus return proc) (proc Process()[] .cli (if cs:Flags.test.00000100b= cs:Flags=.or.00000100b; call Main_Shell(); cs:Flags=.and.11111011b if) .sti return proc) (proc Main_Shell()[] (if cs:Flags.test.00000010b= (save bx,ds bx=.lds.cs:In_DOS_Flag BYTE PTR ds:[bx]=.cmp.00h save) if <> goto Skip_PopUp if) .sti; call Main(); .cli cs:Flags=.and.11111110b; return Skip_PopUp: (if cs:Flags.test.00000001b<> cs:Attempts=-1; if <> then return (save ax) ax=0E07h; 10h=.int cs:Flags=.and.11111110b return if) cs:Flags=.or.00000001b; cs:Attempts=MaxAttempt return proc) (proc Main()[ax,cx] // [ Куча всего ] // Например: ax=0E07h; 10h=.int return proc) Initialize: // Проверить наличие себя в памяти ax=Request; 16h=.int (if ax<>Reply // Install ah=34h; 21h=.int WORD PTR In_DOS_Flag=bx; (WORD PTR In_DOS_Flag+2)=es SetVector (16h) SetVector (28h) FreeEnvironment TSR (Initialize+BufferSize) if) // UnInstall ChkVector (16h, es) if is carry goto Finish ChkVector (28h, ) if is carry goto Finish RestoreVector (16h) RestoreVector (28h) FreeMemory goto Finish Finish: Terminate (00h) (proc Set_Vector()[] ah=35h; 21h=.int WORD PTR [di]=bx WORD PTR [di+2]=es ah=25h; 21h=.int return proc) (proc Restore_Vector()[ds] dx=.lds.DWORD PTR es:[si] ah=25h; 21h=.int return proc) (proc Chk_Vector()[] ah=35h; 21h=.int bx=-si ax=es-dx.or.bx .clc if <> then .stc return proc)