Skip to content

Instantly share code, notes, and snippets.

@Fortyseven
Created September 27, 2014 14:31
Show Gist options
  • Save Fortyseven/d178c792043c3b740158 to your computer and use it in GitHub Desktop.
Save Fortyseven/d178c792043c3b740158 to your computer and use it in GitHub Desktop.
Old kitchen sink 'utilities' unit for Turbo Pascal (DOS)
{$G+,A+,S-,R-,I-,D+,L-,N-,E-,X+}
Unit UTILS;
{ Utilities Unit
ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
³ Û Û ÜßßÜ Üßß ÜÛßßßÛßßÜ ÛßßßÛß ßß ß ~ ³
³ _ Ü ÜÜ ÜÛß Û Ûß Û ßÜÜÜÜÜß ßÜÜß Ûß Û ³
ÃÄÄÄÄÄÄÄÄÄÄÄÄÄ[SOURCE CODE LIBRARY]ÄÄÄÄÄÄÄÄÄÄÄÄÄ´
ÔÍÍÍÍÍÍÍÍÍÍÍÍ[Misc. Useful Routines]ÍÍÍÍÍÍÍÍÍÍÍ; v1.3
}
Interface
Const
TIMESET = 2610; {2838 / 2610}
TIMEOUT = 7;
Var
timerproc :procedure; {Pointer to User-Interrupt Hook}
Int08Save :procedure; {Stores old Int $8 pointer}
Int09Save :procedure; {Stores old Int $9 pointer}
timercount :integer;
TimerInstalled :boolean;
retraces :word;
total_retraces :word;
{-ÄÄ-ÄÄ-ÄÄ-ÄÄ-ÄÄ-ÄÄ-ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{ÄÄ[Timer Interrupt $1C Hook Functions]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{-ÄÄ-ÄÄ-ÄÄ-ÄÄ-ÄÄ-ÄÄ-ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
Procedure Hook(u:pointer);
{Sets user-defined Timer Interrupt.}
Procedure UnHook;
{Restores original Timer interrupt.}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{ÄÄ[File Functions]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
Function Lines(f:string):LongInt;{Calculates Number of lines in TEXT file}
Function ReadLine(s:string; l:longint):String; {Reads a particular line in}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{ÄÄ[Number/String Manipulation]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
function w2bin(W: Word): string; {Word to Binary conversion. Converts to a STRING.}
function b2bin(B: Byte): string; {Byte to Binary conversion. Converts to a STRING.}
function w2hex(W: Word): string; {Word to Hexadecimal conversion. Converts to a STRING.}
function b2hex(B: Byte): string; {Byte to Hexadecimal conversion. Converts to a STRING.}
function w2dec(W: Word): string; {Word to Decimal conversion?! Converts to a STRING.}
function b2dec(B: Byte): string; {Byte to Decimal conversion?! Converts to a STRING.}
function b2asc(B: Byte): string; {Byte to ASCII conversion. Converts to a "'char'".}
function hex2w(s: string): word;
Function stow(s:string):Word; {Converts string type to word type}
function LongDiv(X: longint; Y: Integer) : Integer; inline($59/$58/$5A/$F7/$F9);
function LongMul(X, Y : integer) : longint; inline($5A/$58/$F7/$EA);
Procedure SetBit(Var Number : Word; Bit : Byte);
Procedure ClearBit(Var Number : word; Bit : Byte);
Function ReadBit(Number, Bit : word) : Boolean;
Function inv(n,min,max:word):word;
{Returns the inverse of a number...(i.e. in [0..10] the inv of
1 would be 9, and in [1..8] a 3 would be 5(?)}
Function Power (x, y : real) : real;
Function Exist(fs :string):boolean;
Function ExistDir(d:string):Boolean;
Function wtos(w:word):String;
Function Upper(s:string):string;
Function Lower(s:string):string;
Function Locase(s:char):char;
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{ÄÄ[Misc Functions]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
Procedure Move386(VAR SRC,DST;CNT:Word);
Procedure FillChar386(VAR BUF;CNT:Word;VAL:Byte);
Procedure CursorOff;
Procedure CursorOn;
Function OnCommandLine(s:string):Boolean; {Scans command line for a parameter}
Procedure Pause;
Function GetIntSeg(int:Word):Word; {Gets Segment where INT x is pointing}
Function GetIntOfs(int:Word):Word; {Gets Offset where INT x is pointing}
Function IsGWPresent:Boolean; {Tells if GameWizard is installed!}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
{--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--ÄÄ--}
Implementation
Uses DOSX, CRTASM, DOS;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
const
Digits : string ='0123456789ABCDEF';
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{Function Lines(f:string):LongInt;
var
z:text;
x:longint;
Begin
x:=0;
assign(z, f);
reset(z);
while not eof(z) do
begin
readln(z);
inc(x);
end;
lines:=x;
close(z);
End;}
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function w2Bin(W: Word): string;
var
s :String;
i,j,k :Word;
begin
k:=1;
s:='';
for i:=$0 to $f do
begin
if (W and k)>0 then s:='1'+s
else s:='0'+s;
k:=k*2;
end;
w2Bin:=s+'b';
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function b2Bin(B: Byte): string;
var
s : String;
i,j,k: Word;
begin
k:=1;
s:='';
for i:=$0 to $7 do begin
if (B and k)>0 then s:='1'+s
else s:='0'+s;
k:=k*2;
end;
B2Bin:=s+'b';
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function w2Hex(W: Word): string;
begin
W2Hex:=Digits[hi(W) and $f0 shr 4+1]+
Digits[hi(W) and $0f+1]+
Digits[lo(W) and $f0 shr 4+1]+
Digits[lo(W) and $0f+1];
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function b2Hex(B: Byte): string;
begin
B2Hex:=Digits[B and $f0 shr 4+1]+
Digits[B and $0f+1];
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function w2Dec(W: Word): string;
var
ss :string;
begin
Str(W,ss);
W2Dec:=ss;
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function b2Dec(B: Byte): string;
var
ss : string;
begin
Str(B,ss);
B2Dec:=ss;
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function b2Asc(B: Byte): string;
begin
B2Asc:=Chr(B);
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function stow(s:string):Word;
Var
i,z :integer;
Begin
Val(s, z, i);
stow:=z;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{ÄÄ[Misc Functions]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure Move386(VAR SRC,DST;CNT:Word); Assembler;
{ SRC = Source Buffer, DST = Destination Buffer, }
{ CNT = Number of BYTEs to move. Requires 386+. }
{ Revision History: }
{ 05-06-95 (SJM) Created by Steven J Morales! }
{ 06-18-95 (SJM) Removed PUSH and POP for speed.} ASM
{ Instructions: Clocks: Comments: }
MOV AX, DS; { 08: Save DS in AX. }
LDS SI, SRC; { 16: Load Source Buffer. }
LES DI, DST; { 16: Load Destination Buffer. }
MOV CX, CNT; { 08: Store length in CX. }
MOV BX, CX; { 02: Store a copy in BX. }
SHR CX, 2; { 09: Number of DWORDs to MOVS. }
DB 66h; REP MOVSW; { --: Extended 32-bit REP MOVSD.}
MOV CX, BX; { 02: Get Length again. }
AND CX, 3; { 04: # of leftover BYTEs (0-3).}
REP MOVSB; { --: Store leftover BYTEs. }
MOV DS, AX; { 08: Restore DS from AX. } END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure FillChar386(VAR BUF;CNT:Word;VAL:Byte); Assembler;
{ BUF = Buffer to fill }
{ CNT = Number of BYTEs to STOSB. Requires 386+ }
{ Revision History: }
{ 05-13-95 (SJM) Created by Steven J Morales! }
{ 09-15-95 (SJM) Re-Optimized for Speed + Size }
{ 09-30-95 (SJM) Re-Optimized for Speed + Size } ASM
{ Instructions: Clocks: Comments: }
LES DI, BUF; { 16: Load Buffer. }
MOV AL, [VAL]; { 08: Load value to fill with. }
MOV AH, AL; { 02: Set Double Bits 5-8 }
DB 66h; XOR CX,CX; { ??: Clear ECX. }
MOV CX, AX; { 02: AX+CX; }
DB 66h; SHL AX,16; { ??: SHL EAX, 16; }
DB 66h; ADD AX,CX; { ??: ADD EAX, ECX; }
MOV CX, [CNT]; { 08: Store length in CX. }
MOV DX, CX; { 02: Store a copy of CNT in DX }
SHR CX, 2; { 09: Number of MOVSDs. }
DB 66h; REP STOSW; { --: REP STOSD (32-Bit MOVS) }
MOV CX, DX; { 08: Get CNT again via DX. }
AND CX, 3; { 04: # of leftover BYTEs (0-3).}
REP STOSB; { --: Store leftover BYTEs. } END;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function hex2w(s: string): word;
var temp : word;
i : integer;
begin
temp:= 0;
for i:= 1 to length(s) do
begin
temp:= temp * 16;
case s[i] of
'0'..'9': temp:= temp + ord(s[i])-ord('0');
'a'..'f': temp:= temp + ord(s[i])-ord('a')+10;
'A'..'F': temp:= temp + ord(s[i])-ord('A')+10;
end;
end;
hex2w:= temp;
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure SetBit(Var Number : Word; Bit : Byte);
Begin
Number := Number OR (1 SHL Bit);
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure ClearBit(Var Number : word; Bit : Byte);
Begin
Number := Number AND NOT (1 SHL Bit);
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function ReadBit(Number, Bit : word) : Boolean;
Begin
ReadBit := (Number AND (1 SHL Bit)) <> 0;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function inv(n,min,max:word):word;
Begin
inv:=max-(n-min);
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function Power (x, y : real) : real;
begin
Power := exp(y*ln(x))
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
function Exist(fs :string):boolean;
var
f: file;
begin
{$I-}
Assign(f,fs);
Reset(f);
Close(f);
{$I+}
Exist:=(IOResult=0) and (fs<>'');
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function wtos(w:word):String;
Var
shoe:string;
Begin
str(w,shoe);
wtos:=shoe;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function Upper(s:string):string;
Var
x,y :word;
st :string;
Begin
st[0]:=s[0];
For x:=1 to length(s) do st[x]:=upcase(s[x]);
upper:=st;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function Lower(s:string):string;
Var
x,y :word;
st :string;
Begin
st[0]:=s[0];
For x:=1 to length(s) do if st[x] in ['a'..'z'] then st[x]:=char(byte(st[x])-31);
lower:=st;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function Locase(s:char):char;
Var
x,y :word;
st :char;
Begin
st:=s;
if st in ['A'..'Z'] then st:=char(byte(st)+32);
locase:=st;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function ExistDir(d:string):Boolean;
Var
cdir :string;
Begin
GetDir(0,cdir);
{$I-}
chdir(d);
{$I+}
if IOResult>0 then ExistDir:=False else ExistDir:=True;
chdir(cdir);
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure CursorOff; Assembler;
Asm
Mov Ax,0100h
Mov Cx,2000h
Int 10h
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure CursorOn; Assembler;
Asm
Mov Ax,0100h
Mov Cx,0607h
Int 10h
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function Lines(f:string):LongInt;
var
z:text; x:longint;
Begin
if upper(f)='CON' then begin writeln('Cannot process CONSOLE for a file.'); halt(20); end;
x:=0;
assign(z, f); reset(z);
while not eof(z) do begin readln(z); inc(x); end;
lines:=x; close(z);
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function OnCommandLine(s:string):Boolean; {Scans command line for a parameter}
var x:word;
begin
oncommandline:=false;
for x:=1 to 64 do
if upper(paramstr(x))=upper(s) then
begin
oncommandline:=true;
exit;
end;
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
procedure SetTimer(x : word); assembler;
asm
cli
mov al,$36
out $43,al
mov ax,x
out $40,al
mov al,ah
out $40,al
sti
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{$F+,S-}
procedure TimerHandler; interrupt; assembler;
{$F-}
asm
inc timercount
cmp timercount,TIMEOUT
jb @noretrace
mov timercount,0
mov dx,$3DA
@vblank:
in al,dx
test al,$08
je @vblank
mov al,$36
out $43,al
mov ax,TIMESET
out $40,al
mov al,ah
out $40,al
{here comes timer code...}
inc retraces
inc total_retraces
mov ax,WORD PTR TimerProc
or ax,WORD PTR TimerProc+2
je @nouserproc
{$F+}
call TimerProc
{$F-}
@nouserproc:
@noretrace:
mov al,$20
out $20,al
sti
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
procedure SetTimerInterrupt;
begin
retraces:=0;
total_retraces:=0;
timercount:=0;
GetIntVec($08,@Int08Save);
SetIntVec($08,addr(TimerHandler));
SetTimer(TIMESET);
TimerInstalled:=TRUE;
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
procedure RestoreTimerInterrupt;
begin
SetIntVec($08,@Int08Save);
SetTimer(0);
TimerInstalled:=FALSE;
end;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
{$F+}
procedure NUL; Assembler;
Asm
End;
{$F-}
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure Hook(u:pointer);
Begin
SetTimerInterrupt;
@TimerProc:=u;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure UnHook;
Begin
If TimerInstalled then RestoreTimerInterrupt;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function ReadLine(s:string; l:longint):String;
Var f :text;
st :string;
x :longint;
Begin
x:=0;
assign(f, s); reset(f);
while not (x=l) do begin readln(f,st); inc(x); end;
close(f);
readline:=st;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Procedure Pause;
Begin
repeat until keypressed; readkey;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function GetIntSeg(int:Word):Word;
Begin
GetIntSeg:=memw[0:(int*4)+2];
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function GetIntOfs(int:Word):Word;
Begin
GetIntOfs:=memw[0:(int*4)];
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Function IsGWPresent:Boolean;
Var int70 :Word;
Begin
Int70:=GetIntSeg($70);
if ((int70=GetIntSeg($21)) or (int70=GetIntSeg($10)))
or ((int70=GetIntSeg($13)) or (int70=GetIntSeg($28)))
then IsGWPresent:=True else IsGWPresent:=False;
End;
{ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ}
Begin
TimerProc :=NUL;
TimerInstalled :=FALSE;
End.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment