[Back to TSR SWAG index] [Back to Main SWAG index] [Original]
{
TSRUNIT v1.10
Copyright (c) 1995 Nir Sofer, All rights reserved
For using with Turbo Pascal 6.0/7.0
You are allowed to copy, modify and share this program with others. But when
you give TSRUNIT source code to other people (or upload it to a BBS) always
give them the whole original files which is included in TSRUNIT package.
For questions, comments or bugs report: Send me a message by one of the
following ways:
1. Internet: nir@netvision.net.il
2. FidoNet: Nir Sofer, at 2:403/138.0
3. Ordinary mail:
Nir Sofer
5 Shderot Hashoshanim St.
52583 Ramat Gan
ISRAEL
All mail will be answered. If you don't get a reply after a week, please
send it again. Mail may be lost somethimes...
READ TSRUNIT.DOC BEFORE USING THIS UNIT !
New in this version:
* Problems with MS-DOS 6.xx fixed by adding INT28 support.
* Check if the TSR has already installed before.
* The type of TsrProcedue variable is a procedure instead of pointer, so you
don't have to add @ operator.
* Consts for all keyboard flags and keyboard scan codes.
* The TsrProcedure variable automatically assigned by InstallTsr procedure
}
unit tsrunit;
{$s-,r-}
interface
type
ProcedureType = procedure;
const
TSRUNITsignature = $DAAD;
RightShift = 1;
LeftShift = 2;
Ctrl = 4;
Alt = 8;
_esc = 1; _a = 30; _f7 = 65;
_1 = 2; _s = 31; _f8 = 66;
_2 = 3; _d = 32; _f9 = 67;
_3 = 4; _f = 33; _f10 = 68;
_4 = 5; _g = 34; _numlock = 69;
_5 = 6; _h = 35; _scrlock = 70;
_6 = 7; _j = 36; _home = 71;
_7 = 8; _k = 37; _up = 72;
_8 = 9; _l = 38; _pgup = 73;
_9 = 10; _lshift = 42; _left = 75;
_0 = 11; _z = 44; _right = 77;
_minus = 12; _x = 45; _end = 79;
_plus = 13; _c = 46; _down = 80;
_bksp = 14; _v = 47; _pgdn = 81;
_tab = 15; _b = 48; _insert = 82;
_q = 16; _n = 49; _delete = 83;
_w = 17; _m = 50;
_e = 18; _rshift = 54;
_r = 19; _alt = 56;
_t = 20; _space = 57;
_y = 21; _capslock = 58;
_u = 22; _f1 = 59;
_i = 23; _f2 = 60;
_o = 24; _f3 = 61;
_p = 25; _f4 = 62;
_enter = 28; _f5 = 63;
_ctrl = 29; _f6 = 64;
var
keysc : byte; {Keyboard scan code variable}
keyflag : byte; {Keyboard flag variable}
TsrProcedure : ProcedureType;
UserSignature : word;
SignatureReturn : word;
procedure SetUserSignature(Check,Return:word);
procedure InstallTsr(tsrproc: ProcedureType); {Make your program resident}
procedure RemoveTsr; {Remove your resident program}
function CheckIntVectors:boolean; {Check if interrupt vectors are still
ours, if yes you are allowed to remove your TSR}
function InstallationCheck:boolean;
implementation
uses dos;
var
old08,old09,old10,old1b,old24,old28,turbo24:pointer;
indosflag,currint:pointer;
active,request,idle:byte;
savesp,savess:word;
busyflag:byte;
{$f+}
{**********************************************************************}
procedure int1b;assembler;
asm
iret {Cancel CTRL-BREAK interrupt}
end;
{**********************************************************************}
procedure int10;assembler;
asm
jmp @cont1
@localds:
nop
nop {Reserved for ds value}
@localint10:
nop
nop
nop
nop {Reserved for old int10 address}
@cont1:
push ds
mov ds,word ptr [cs:@localds]
inc busyflag
pop ds
pushf
call dword ptr [cs:@localint10] {Call old interrupt}
push ds
mov ds,word ptr [cs:@localds]
cmp ax,tsrunitsignature
je @TsrUnitCall
@cont100:
dec busyflag
pop ds
iret
@TsrUnitCall:
cmp bx,UserSignature
jne @cont100
mov cx,SignatureReturn
jmp @cont100
end;
{**********************************************************************}
procedure swap1;
begin {Swap vectors before running TsrProcedure}
getintvec($1b,old1b);
setintvec($1b,@int1b);
getintvec($24,old24);
setintvec($24,turbo24);
end;
{**********************************************************************}
procedure swap2;
begin {Swap vectors after running TsrProcedure}
setintvec($24,old24);
setintvec($1b,old1b);
end;
{**********************************************************************}
procedure activate;assembler;
asm
jmp @start
@localss:
nop
nop {Reserved for ss value}
@localsp:
nop
nop {Reserved for sp value}
@start:
cmp request,1 {Request by INT09 ?}
jne @notrequested
cmp idle,1
je @cont500
les di,indosflag
cmp word ptr [es:di],0 {Check indos flag}
jne @notrequested
@cont500:
cmp busyflag,0 {INT10 busy ?}
jne @notrequested
mov active,1 {The tsr is active now}
mov request,0
mov savess,ss
mov savesp,sp
cli
mov ss,word ptr [cs:@localss]
mov sp,word ptr [cs:@localsp] {Set ss and sp registers of TP}
sti
push bx
push cx
push dx
push si
push bp
call [swap1] {Swap CTRL-BREAK and critical error handler vectors}
call [TsrProcedure] {call your procedure}
call [swap2] {Swap CTRL-BREAK and critical error handler vectors}
pop bp
pop si
pop dx
pop cx
pop bx
cli
mov ss,savess
mov sp,savesp {Set old ss and sp registers}
sti
mov active,0
@notrequested:
end;
{**********************************************************************}
procedure int28;assembler;
asm
jmp @cont1
@localds:
nop
nop
@localint28:
nop
nop
nop
nop
@cont1:
push es
push ds
push ax
push di
push ds
mov ds,word ptr [cs:@localds]
inc idle
pop ds
pushf
call dword ptr [cs:@localint28] {Call old interrupt}
mov ds,word ptr [cs:@localds]
call activate
dec idle
pop di
pop ax
pop ds
pop es
iret
end;
{**********************************************************************}
procedure int08;assembler;
asm
jmp @cont1
@localds:
nop
nop {Reserved for ds value}
@cont1:
push es
push ds
push ax
push di
mov ds,word ptr [cs:@localds]
pushf
call [old08] {Call old interrupt}
call activate
pop di
pop ax
pop ds
pop es
iret
end;
{**********************************************************************}
procedure int09;assembler;
asm
jmp @cont1
@localds:
nop
nop {Reserved for ds value}
@cont1:
push es
push ax
push ds
mov ds,word ptr [cs:@localds]
pushf
call [old09] {Call old INT09}
in al,60h
cmp al,keysc {Check scan code key}
jne @notourkey
xor ax,ax
mov es,ax
mov al,[es:1047]
and al,keyflag
cmp al,keyflag {Check alt\ctrl\shift keys}
jne @notourkey
cmp active,1 {Check if already active}
je @notourkey
mov request,1 {Request activity}
@notourkey:
pop ds
pop ax
pop es
iret
end;
{**********************************************************************}
procedure InstallTsr(tsrproc: ProcedureType);
begin
TsrProcedure:=tsrproc;
getintvec($28,old28);
getintvec($8,old08);
getintvec($9,old09);
getintvec($10,old10);
getintvec($24,turbo24); {Get interrupt vectors}
memw[seg(int10):ofs(int10)+4]:=memw[seg(old10):ofs(old10)];
memw[seg(int10):ofs(int10)+6]:=memw[seg(old10):ofs(old10)+2];
memw[seg(int28):ofs(int28)+4]:=memw[seg(old28):ofs(old28)];
memw[seg(int28):ofs(int28)+6]:=memw[seg(old28):ofs(old28)+2];
{Put interrupt $10 address in INT10 procedure}
memw[seg(activate):ofs(activate)+4]:=sptr;
{Save stack pointer for using when TSR is active}
setintvec($8,@int08);
setintvec($9,@int09);
setintvec($10,@int10);
setintvec($28,@int28);
{Set new interrupt vectors}
asm
mov dx,prefixseg
mov es,dx
mov ax,[es:$2c]
cmp ax,0
jz @cont
mov es,ax
mov ah,$49
int $21 {Release environment block}
@cont:
end;
swapvectors; {Swap TP vectors with old vectors}
keep(0); {Terminate and stay resident}
end;
{**********************************************************************}
function CheckIntVectors:boolean;
{If CheckIntVectors=false, do not remove the tsr !!}
begin
CheckIntVectors:=false;
getintvec($8,currint);
if currint<>@int08 then exit;
getintvec($9,currint);
if currint<>@int09 then exit;
getintvec($10,currint);
if currint<>@int10 then exit;
CheckIntVectors:=true;
end;
{**********************************************************************}
procedure RemoveTsr;
begin
setintvec($8,old08);
setintvec($9,old09);
setintvec($10,old10);
setintvec($1b,old1b);
setintvec($28,old28);
{set old interrupt vectors}
asm
mov dx,prefixseg
mov es,dx
mov ah,$49
int $21 {Release memory block}
end;
asm
mov ax,$4c00
int $21 {Terminate program}
end;
end;
{**********************************************************************}
procedure SetUserSignature(Check,Return:word);assembler;
asm
mov ax,check
mov UserSignature,ax {The value to send to INT 10h}
mov ax,return
mov SignatureReturn,ax {The value that INT 10h will return}
end;
{**********************************************************************}
function InstallationCheck:boolean;assembler;
asm
mov ax,TSRUNITsignature
mov bx,UserSignature
xor cx,cx
int 010h
xor al,al
cmp cx,SignatureReturn {Did you get the return value}
jne @tend
mov al,1 {If yes, your TSR already installed !}
@tend:
end;
{**********************************************************************}
begin
setusersignature($eeaa,$aaff);
busyflag:=0;
idle:=0;
memw[seg(int08):ofs(int08)+2]:=dseg;
memw[seg(int09):ofs(int09)+2]:=dseg;
memw[seg(int10):ofs(int10)+2]:=dseg;
memw[seg(int28):ofs(int28)+2]:=dseg;
memw[seg(activate):ofs(activate)+2]:=sseg;
{Set local data segments}
keysc:=_a;
keyflag:=Alt + Ctrl; {Default key combination}
active:=0;
request:=0;
asm
mov ah,$34
int $21
mov ax,es
sub bx,1
sbb ax,0
mov word ptr [indosflag],bx
mov word ptr [indosflag+2],ax {Get indos flag address}
end;
end.
[Back to TSR SWAG index] [Back to Main SWAG index] [Original]