home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 2
/
ctrom_ii_b.zip
/
ctrom_ii_b
/
PROGRAM
/
PASCAL
/
PASTUT34
/
TWOLINKS.PAS
< prev
next >
Wrap
Pascal/Delphi Source File
|
1993-03-01
|
11KB
|
385 lines
{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,R-,S+,V+,X-}
{$M 4096,0,20000}
Program TwoLinks;
{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
{ Program to display on the screen the creation of a double-linked }
{ list on the Heap and to show the action as the records of the list }
{ are traversed both forward and backward under the control of the }
{ right and left arrow keys. }
{ The functions Seg and Ofs are used to determine the addresses on }
{ Heap of each record of the linked list and these addresses are then }
{ displayed as Seg:Ofs for the record and for its fields Previous and }
{ Next. The Number field is also displayed. }
{ The active record is shown in red. }
{ }
{ TWOLINKS.PAS -> .EXE R. Shaw 5.12.92 }
{_____________________________________________________________________}
Uses Crt, Dos, hexa;
Type
PItem = ^ TItem;
TItem = record
Previous : PItem;
Number : integer;
Next : PItem;
End;
Var
First, Last, This : PItem;
i, n, interval : integer;
FirstSeg, LastSeg, ThisSeg, FirstOfs, LastOfs, ThisOfs : word;
FirstSegX, LastSegX, FirstOfsX, LastOfsX : string;
PrevSeg, PrevOfs, NextSeg, NextOfs : word;
NextSegX, NextOfsX : string;
ThisSegX, ThisOfsX, PrevSegX, PrevOfsX : Array[1..10] of string;
Speed, reply : char;
k,x,y : integer;
Str : array[0..10] of string;
Step : boolean;
HeapTop : ^integer;
SegHeap, OfsHeap : word;
Procedure Instructions;
begin
TextColor(cyan);
GoToXY(1,13);
writeln(' Please press arrow keys <- or -> to move about list or Q to quit');
writeln(' If at either end, only the inward arrow key is effective.');
write(' The selected record of the double-linked list is shown in ');
TextColor(red);
writeln('red');
GoToXY(14*n+4,12);
end; { Proc Instructions }
Procedure CodeDisplay(k,Colour: integer);
begin
Case k of
0 : begin x := 1; y := 13; Str[0] := 'CODE'; end;
1 : begin x := 5; y := 14; Str[1] := 'New(This);'; end;
2 : begin x := 5; y := 15;
Str[2] := 'If First = Nil then First := This'; end;
3 : begin x := 40; y := 15;
Str[3] := 'else Last^.Next := This; {old Last}'; end;
4 : begin x := 5; y := 16; Str[4] := 'This^.Number := i;'; end;
5 : begin x := 5; y := 17;
Str[5] := 'If First = This then This^.Previous := Nil'; end;
6 : begin x := 49; y := 17;
Str[6] := 'else This^.Previous := Last;'; end;
7 : begin x := 5; y := 18; Str[7] := 'Last := This; {new Last}'; end;
8 : begin x := 5; y := 19; Str[8] := 'Last^.Next := Nil;'; end;
end;
TextColor(Colour);
GoToXY(x,y);
writeln(Str[k]);
end; { Proc CodeDisplay }
Procedure CreateList;
begin
TextColor(yellow);
GoToXY(1,3);
write('Pointer');
GoToXY(1,5);
write('Record');
GoToXY(1,6);
write('Address');
GoToXY(1,8);
write('Record fields');
GoToXY(1,9);
write('Previous');
GoToXY(1,10);
write('Number');
GoToXY(1,11);
write('Next');
If Step then
begin
TextColor(cyan);
GoToXY(5,24);
write('Please press the spacebar to continue to next statement. ');
end
else
begin
TextColor(cyan);
GoToXY(5,24);
write('Successive statements are executed and displayed automatically. ');
end;
TextColor(Yellow);
for i := 1 to n do
begin
New(This);
GoToXY(14*i,3);
write('This');
ThisSeg := Seg(This^);
ThisOfs := Ofs(This^);
ThisSegX[i] := IntToHex(ThisSeg);
ThisOfsX[i] := IntToHex(ThisOfs);
CodeDisplay(1,white);
If i = n then TextColor(Red) else TextColor(white);
GoToXY(14*i,6);
write(ThisSegX[i],':',ThisOfsX[i]);
If Step then reply := readkey else delay(interval);
CodeDisplay(1,yellow);
If First = Nil then
begin
First := This;
GoToXY(14*i,3);
write('First');
CodeDisplay(2,white);
end
else
begin
Last^.Next := This;
CodeDisplay(3,white);
TextColor(white);
GoToXY(14*(i-1),11);
write(ThisSegX[i],':',ThisOfsX[i]);
end;
If Step then reply := readkey else delay(interval);
CodeDisplay(2,yellow);
CodeDisplay(3,yellow);
This^.Number := i;
CodeDisplay(4,white);
If i = n then TextColor(red) else TextColor(white);
GoToXY(14*i,10);
write(This^.Number);
If Step then reply := readkey else delay(interval);
CodeDisplay(4,yellow);
If First = This then
begin
This^.Previous := Nil;
CodeDisplay(5,white);
end
else
begin
This^.Previous := Last;
CodeDisplay(6,white);
end;
PrevSeg := Seg(This^.Previous^);
PrevOfs := Ofs(This^.Previous^);
PrevSegX[i] := IntToHex(PrevSeg);
PrevOfsX[i] := IntToHex(PrevOfs);
If i = n then TextColor(red) else TextColor(white);
GoToXY(14*i,9);
write(PrevSegX[i],':',PrevOfsX[i]);
If Step then reply := readkey else delay(interval);
CodeDisplay(5,yellow);
CodeDisplay(6,yellow);
Last := This;
GoToXY(14*i,3);
If i = 1 then write('First/Last') else write('Last');
If i > 1 then
begin
GoToXY(14*(i-1),3);
If i = 2 then write('First ') else write(' ');
end;
CodeDisplay(7,white);
If Step then reply := readkey else delay(interval);
CodeDisplay(7,yellow);
Last^.Next := Nil;
CodeDisplay(8,white);
If i = n then TextColor(red) else TextColor(white);
GoToXY(14*i,11);
write('0000:0000');
If Step then reply := readkey else delay(interval);
CodeDisplay(8,yellow);
end;
end; { Proc CreateList }
Procedure Change(j, colour : integer);
begin
TextColor(Colour);
GoToXY(14*j,9);
write(PrevSegX[j],':',PrevOfsX[j]);
GoToXY(14*j,10);
write(i);
GoToXY(14*j,6);
write(ThisSegX[j],':',ThisOfsX[j]);
If (j > 0) and (j < n) then
begin
GoToXY(14*j,11);
write(ThisSegX[j+1],':',ThisOfsX[j+1]);
end;
If j = n then
begin
GoToXY(14*j,11);
write('0000:0000');
end;
end; { Proc Change }
Procedure Advance(i, colour : integer);
Var
j :integer;
begin
TextColor(Colour);
If colour = 0 then i := i - 1;
GoToXY(14*i+9,11);
write('──┘');
For j := 10 downto 7 do
begin
GoToXY(14*i+11,j);
write('│');
end;
GoToXY(14*i+11,6);
write('┌─>');
If i <> n then i := i + 1;
GoToXY(14*i-1,12);
write('Please Wait');
If Colour <> 0 then delay(1000);
TextColor(cyan);
GoToXY(70,13);
end; { Proc Advance }
Procedure Retreat(i, colour : integer);
Var
j :integer;
begin
TextColor(colour);
If colour = 0 then i := i + 1;
GoToXY(14*i-3,9);
write('└──');
For j := 8 downto 7 do
begin
GoToXY(14*i-3,j);
write('│');
end;
GoToXY(14*i-5,6);
write('<─┐');
GoToXY(14*(i-1)-1,12);
write('Please Wait');
If Colour <> 0 then delay(1000);
TextColor(cyan);
GoToXY(70,13);
end; { Proc Retreat }
Procedure ArrowKey;
var
Key : char;
EKey : boolean;
begin
interval := 500;
repeat
repeat
Ekey := False;
Key := Readkey;
if UpCase(Key) = 'Q' then exit;
if Key = #0 then
begin
Ekey := True;
Key := Readkey;
if (Key = #75) and (i > 1) then
begin
Retreat(i,red);
delay(interval);
Change(i, white);
dec(i);
Change(i, red);
Retreat(i,black);
end;
if (Key = #77) and (i < 5) then
begin
Advance(i,red);
delay(interval);
Change(i, white);
inc(i);
Change(i, red);
Advance(i,black);
end;
end;
until (EKey = True) and ((Key = #75) or (Key = #77));
until UpCase(Key) = 'Q';
end; { Proc ArrowKey }
Procedure DosDebug;
Function DebugPath : Pathstr;
var
DPath : PathStr;
begin
DPath := '';
DPath := FSearch('DEBUG.EXE', GetEnv('PATH'));
If DPath = '' then DPath := FSearch('DEBUG.COM', GetEnv('PATH'));
If DPath = '' then
begin
writeln('DEBUG file not found. Please check your DOS system.');
writeln;
writeln('Press any key to continue: ');
repeat until keypressed;
end;
DebugPath := DPath;
end; {of Function DebugPath}
begin
TextColor(LightGray);
SwapVectors;
Exec(DebugPath,'');
If DosError <> 0 then writeln('Dos error # ',DosError);
SwapVectors;
end; { Proc DosDebug }
{Main}
begin
ClrScr;
Mark(HeapTop);
SegHeap := Seg(HeapTop^);
OfsHeap := Ofs(HeapTop^);
For i := OfsHeap to (OfsHeap + 1000) do Mem[SegHeap:i] := 0;
Step := False;
TextColor(LightGray);
write('Please specify speed of display as Slow[S] or Fast[F] or Key Step[K]: ');
Speed := readkey;
ClrScr;
TextColor(cyan);
write('THE CREATION OF A DOUBLE-LINKED LIST AND MOVEMENT FROM RECORD TO RECORD.');
Case UpCase(Speed) of
'S' : interval := 4000;
'F' : interval := 1000;
'K' : step := true;
else interval := 0;
end;
CodeDisplay(0,cyan);
For k := 1 to 8 do CodeDisplay(k, yellow);
n := 5;
CreateList;
Window(1,12,80,25);
ClrScr;
Window(1,1,80,25);
Instructions;
GoToXY(70,13);
ArrowKey;
Window(1,13,80,25);
ClrScr;
TextColor(cyan);
GoToXY(1,1);
writeln('Please wait for DOS Debug prompt (-) and then type d followed by a space and');
writeln('then the address of the first record, as shown above, and then press ENTER.');
writeln('After studying the contents of memory, press Q followed by ENTER to quit.');
TextColor(lightGray);
write(' ');
Window(1,16,80,25);
ClrScr;
DosDebug;
end.