Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




COMPLETE TURBO PASCAL

software


Capitolul 9

LowerDownCaseIsWhite

(* >>> LowerDounCaseIsWhite <<< ----- ----- --------------- *)

(* Nume fisier : UPDNCASE.SRC *)

(* Colectie de rutine pentru testarea caracterelor. *)



(* -------- ----- ------ ----- ----- ----------- *)

FUNCTION CapsLock (Ch: CHAR): CHAR;

(* ---- Converteste o litera mica in litera mare. --- *)

CONST

LowerCase: SET OF CHAR= ['a'..'z'];

BEGIN

IF Ch IN LowerCase THEN

CapsLock := CHR (ORD (Ch) - 32)

ELSE

CapsLock := Ch

END;

FUNCTION DownCase (Ch: CHAR): CHAR;

(* ---- Converteste o litera mare in litera mica. --- *)

CONST

UpperCase: SET OF CHAR= ['A'..'Z'];

BEGIN

IF Ch IN UpperCase THEN

DownCase := CHR (ORD (Ch) + 32)

ELSE

DownCase := Ch

END;

FUNCTION IsWhite (Ch: CHAR): BOOLEAN;

(* --- Verifica daca caracteruì apartine "spatiilor albe". --- *)

CONST

Whitespace: SET OF CHAR= [#8, #10, #12, #13, ' '];

BEGIN

IsWhite := Ch IN Whitespace

END;

Capitol 13

Rooter

(* >>> Rooter <<< -------- ----- ------ -- *)

(* Nume fisier : ROOTER.PAS *)

(* Program demonstrativ instructiuni simple. *)

(* -------- ----- ------ ----- ----- ------- *)

PROGRAM Rooter;

VAR

r, s: REAL;

BEGIN

WriteLn ('>> Determinarea radacinii patrate a unui numar <<'); WriteLn;

Write ('>> Introduceti numarul : '); ReadLn (r);

S := Sqrt (r);

WriteLn (' Radacina patrata a lui ', r:10:5, ' este ', s:10:5, '.');

ReadLn

END.

BetterRooter

(* >>> BetterRooter <<< ----- ----- --------- ----- ----- *)

(* Nume fisier : ROOTER2.PAS *)

(* Program demonstrativ cu instructiuni compuse. *)

(* -------- ----- ------ ----- ----- ------- *)

PROGRAM BetterRooter;

VAR

r, s: REAL;

BEGIN

WriteLn('>> Determinarea radacinii patrate a unui numar <<'); WriteLn;

r := 1;

WHILE r <> 0 DO

BEGIN

Write('>> Introduceti numarul (0 pentru terminare) : '); ReadLn(r);

IF r > 0 THEN

BEGIN

S := Sqrt (r);

Write(' Radacina patrata a lui ', r:10:5);

WriteLn(' este ', s:10:5, '.'); WriteLn

END

ELSE

IF r < 0 THEN

BEGIN

WriteLn('>> Eroarea !<< Nu se calculeaza radacina');

WriteLn(' patrata din numere negative.'); WriteLn

END

END;

WriteLn('>> S-a terminat determinarea radacinilor patrate ...')

END.

IsMono

(* >>> IsMono <<< -------- ----- ------ -------- *)

(* Nume fisier : ISMONO.PAS *)

(* Programul testeaza daca display-ul instalat in sistem *)

(* este monocrom sau color, folosind functia Monochrome. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM IsMono;

BEGIN

IF Monochrome THEN

Halt (5)

ELSE

Halt (0)

END.

Capitol 14

BoxTest

(* >>> BoxTest <<< -------- ----- ------ ----- *)

(* Nume fisier : BOXTEST.PAS *)

(* Program demonstrativ - caractere grafice. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM BoxTest;

USES CRT;

TYPE

GrafRec= RECORD

ULCorner,

URCorner,

LLCorner,

LRCorner,

HBar,

VBar,

LineCross,

TDown,

TUp,

TRight,

TLeft: STRING[4]

END;

String80= STRING[80];

VAR

GrafChars: GrafRec;

X, Y,

Width,

Height: INTEGER;

PROCEDURE DefineChars (VAR GrafChars: GrafRec);

BEGIN

WITH GrafChars DO

BEGIN

ULCorner := CHR (201);

URCorner := CHR (187);

LLCorner := CHR (200);

LRCorner := CHR (188);

HBar := CHR (205);

VBar := CHR (186);

LineCross := CHR (206);

TDown := CHR (203);

TUp := CHR (202);

TRight := CHR (185);

TLeft := CHR (204)

END

END;

PROCEDURE MakeBox (X, Y, Width, Height: INTEGER; GrafChars: GrafRec);

VAR

i, j: INTEGER;

BEGIN

IF X < 0 THEN

X := (80 - Width) DIV 2;

WITH GrafChars DO

BEGIN

GoToXY (X, Y);

Write (ULCorner);

FOR i := 3 TO Width DO

Write (HBar);

Write (URCorner);

GoToXY (X, (Y + Height) - 1);

Write (LLCorner);

FOR i := 3 TO Width DO

Write (HBar);

Write (LRCorner);

FOR i := 1 TO Height - 2 DO

BEGIN

GoToXY (x, Y + i); Write (VBar);

GoToXY ((X + Width) - 1, Y + i); Write (VBar)

END

END

END;

BEGIN

Randomize;

ClrScr;

DefineChars(GrafChars);

WHILE NOT KeyPressed DO

BEGIN

X := Random(72);

Y := Random(21);

REPEAT

Width := Random(80 - X)

UNTIL Width > 1;

REPEAT

Height := Random 25 - Y)

UNTIL Height > 1;

MakeBox(X, Y, Width, Height, GrafChars);

Delay(500)

END

END.

ShellSort

(* >>> ShellSort <<< -------- ----- ------ -- *)

(* Nume fisier : SHELSORT.SRC *)

(* Rutina de sortare folosind algoritmul Shell. *)

(* -------- ----- ------ ----- ----- ---------- *)

PROCEDURE ShellSort(VAR SortBuf: KeyArray; Recs: INTEGER);

VAR

Spread,

i, j, k, l: INTEGER;

PROCEDURE KeySwap(VAR RR, SS: KeyRec);

VAR

T: KeyRec;

BEGIN

T := RR;

RR := SS;

SS := T

END;

BEGIN

Spread := Recs DIV 2;

WHILE Spread > 0 DO

BEGIN

FOR I := Spread + 1 TO Recs DO

BEGIN

J := I - Spread;

WHILE J > 0 DO

BEGIN

L := J + Spread;

IF SortBuf[J].KeyData <= SortBuf[L].KeyData THEN

J := 0

ELSE

KeySwap (SortBuf[J], SortBuf[L]);

J := J - Spread

END

END;

Spread := Spread DIV 2

END

END;

PushPop

(* >>> PushPop <<< -------- ----- ------ ------ *)

(* Nume fisier : PUSHPOP.PAS *)

(* Program demonstrativ pentru recursivitate. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM PushPop;

CONST

Levels= 5;

VAR

Depth: INTEGER;

PROCEDURE Dive (VAR Depth: INTEGER);

BEGIN

WriteLn ('Push !');

WriteLn ('Adincimea dv. este acum : ', Depth);

Depth := Depth + 1;

IF Depth <= Levels THEN

Dive (Depth);

WriteLn ('Pop !')

END;

BEGIN

Depth := 1;

Dive (Depth)

END.

Factorial

(* >>> Factorial <<< -------- ----- ------ ----- *)

(* Nume fisier : FACTRIAL.SRC *)

(* Rutina recursiva pentru calculul factorialului. *)

(* -------- ----- ------ ----- ----- ------------- *)

FUNCTION Factorial (N: INTEGER): INTEGER;

BEGIN

IF N > 1 THEN

Factorial := N * Factorial (N - 1)

ELSE

Factorial := 1

END;

QuickSort

(* >>> QuickSort <<< -------- ----- ------ --- *)

(* Nume fisier : QUIKSORT.SRC *)

(* Rutina de sortare folosind algoritmul Quick Sort. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROCEDURE QuickSort (VAR SortBuf: KeyArray; Recs: String30);

PROCEDURE KeySwap (VAR RR, SS: KeyRec);

VAR

T: KeyRec;

BEGIN

T := RR;

RR := SS;

SS := T

END;

PROCEDURE DoSort (Low, High: INTEGER);

VAR

I, J: INTEGER;

Pivot: KeyRec;

BEGIN

IF Low < High THEN

BEGIN

I := Low; J := High;

Pivot := SortBuf[J];

REPEAT

WHILE (I < J) AND (SortBuf[I].KeyData <= Pivot.KeyData) DO

INC (I);

WHILE (J > I) AND (SortBuf[J].KeyData >= Pivot.KeyData) DO

DEC (J);

IF I < J THEN

KeySwap (SortBuf[I], SortBuf[J])

UNTIL I >= J;

KeySwap (SortBuf[I], SortBuf[High]);

IF (I - Low) < (High - I) THEN

BEGIN

DoSort (Low, I - 1);

DoSort (I + 1, High)

END

ELSE

BEGIN

DoSort (I + 1, High);

DoSort (Low, I + 1)

END

END

END;

BEGIN

DoSort (1, Recs)

END.

SortTest

(* >>> SortTest <<< -------- ----- ------ ---- *)

(* Nume fisier : SORTTEST.PAS *)

(* Program demonstrativ - sortarea datelor. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM SortTest;

USES CRT, DOS, BoxStuff;

CONST

HighLite= TRUE;

CR= TRUE;

NoHighLite= FALSE;

NoCR= FALSE;

GetInteger= FALSE;

Numeric= TRUE;

CapsLock= TRUE;

Shell= TRUE;

Quick= FALSE;

TYPE

String255= STRING[255]

String80= STRING[80];

String30= STRING[30];

KeyRec= RECORD

Ref: INTEGER;

KeyData: String30

END;

KeyArray= ARRAY[0..500] OF KeyRec;

KeyFile= FILE OF KeyRec;

VAR

I, J¬ IVal,

Error: INTEGER;

R: REAL;

Ch: CHAR;

Response: String80;

Escape: BOOLEAN;

WorkArray: KeyArray;

Randoms: KeyFile;

PROCEDURE GenerateRandomKeyFile (KeyQuantity: INTEGER);

VAR

WorkKey: KeyRec;

I, J: INTEGER;

BEGIN

Assign (Randoms, 'RANDOMS.KEY');

Rewrite (Randoms);

FOR I := 1 TO KeyQuantity DO

BEGIN

FillChar (WorkKey, SizeOf (WorkKey), 0);

FOR J := 1 TO SizeOf (WorkKey, KeyData) - 1 DO

WorkKey.KeyData[J] := CHR (Pull (65, 91));

WorkKey.KeyData[0] := CHR (30);

Write (Randoms, WorkKey)

END;

Close (Randoms)

END;

PROCEDURE DisplayKeys;

VAR

WorkKey: KeyRec;

BEGIN

Assign (Randoms, 'RANDOMS.KEY');

Reset (Randoms);

Window (25, 13, 70, 22);

GoToXY (1, 1);

WHILE NOT EOF (Randoms) DO

BEGIN

Read (Randoms, WorkKey);

IF NOT EOF (Randoms) THEN

WriteLn (WorkKey.KeyData)

END;

Close (Randoms);

WriteLn;

WriteLn (' >>>> Apasati <CR> <<<<');

ReadLn;

ClrScr;

Window (1, 1, 80, 25)

END;

PROCEDURE DoSort (Shell: BOOLEAN);

VAR

Counter: INTEGER;

BEGIN

Assign (Randoms, 'RANDOMS.KEY'); Reset (Randoms);

Counter := 1;

WriteAt (20, 15, NoHighLite, NoCR, 'Incarcare ...');

WHILE NOT EOF (Randoms) DO

BEGIN

Read (Randoms, WorkArray[Counter];

Counter := Succ (Counter)

END;

Close (Randoms);

Write ('... sortare ...');

IF Shell THEN

ShellSort (WorkArray, Counter - 1)

ELSE

QuickSort (WorkArray, Counter - 1);

Write ('... gata');

WriteAt (-1, 21, NoHighLite, NoCR, '>>> Tastati <CR> <<<');

ReadLn;

ClearRegion (2, 15, 77, 22)

END;

BEGIN

ClrScr; CursorOff;

MakeBox (1, 1, 80, 24, GrafChars);

WriteAt (24, 3, HighLite, NoCr, 'Sortare - COMPLETE TURBO PASCAL V5.0');

REPEAT

WriteAt(25,5,NoHighLite,NoCR,'[1] Generare fisier cu chei aleatoare');

WriteAt(25,6,NoHighLite,NoCR,'[2] Afisare fisier cu chei aleatoare');

WriteAt(25,7,NoHighLite,NoCR,'[3] Sortare cu algoritmul Shell');

WriteAt(25,8,NoHighLite,NoCR,'[4] Sortare cu algoritmul Quick Sort');

WriteAt (30, 10, NoHighLite, NoCR,'Introduceti 1 - 4 : ');

Response := ''; IVal := 0;

GetString (46, 10, Response, 2, CapsLock, Numeric,

GetInteger, R, IVal, Error, Escape);

CASE IVal OF

0:;

1: GenerateRandomKeyFile (250);

2: DisplayKeys;

3: DoSort (Shell);

4: DoSort (Quick)

END

UNTIL (IVal = 0) OR Escape;

CursorOn

END.

Capitol 15

StripWhite

(* >>> StripWhite <<< -------- ----- ------ -- *)

(* Nume fisier : STRIPWHT.SRC *)

(* Rutine elimina caracterele "spatii albe" din fata *)

(* unui sir. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROCEDURE StripWhite (VAR Target: STRING);

CONST

Whitespace: SET OF CHAR= [#8, #10, #12, #13, ' '];

BEGIN

WHILE (Length (Target) > 0) AND (Target[1] IN Whitespace) DO

Delete (Target, 1, 1)

END;

GetExt

(* >>> GetExt <<< -------- ----- ------ ------ *)

(* Nume fisier : GETEXT.SRC *)

(* Rutina returneaza extensia unui fisier. *)

(* -------- ----- ------ ----- ----- ----------- *)

FUNCTION GetExt (FileName: STRING): STRING;

VAR

DotPos: INTEGER;

BEGIN

DotPos := Pos ('.', FileName);

IF DotPos = 0 THEN

GetExt := ''

ELSE

GetExt := Copy (FileName, DotPos, (Length (FileName) - DotPos) + 1)

END;

Evaluator

(* >>> Evaluator <<< -------- ----- ------ ---- *)

(* Nume fisier : EVALUTOR.PAS *)

(* Program demonstrativ - conversie sir numeric in *)

(* valoare numerica. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM Evaluator;

VAR

SST: STRING;

R: REAL;

Result: INTEGER;

BEGIN

REPEAT

Write ('Introduceti un numar sub forma unui sir : ');

ReadLn (SST);

IF Length (SST) > 0 THEN

BEGIN

VAL (SST, R, Result);

IF Result <> 0 THEN

Write('>> Nu se poate evalua sirul. <<');

Writeln('Caracterul #', Result, ' este eronat.')

ELSE

WriteLn '>> Echivalentul numeric al sirului este : ', R:18:10)

END;

Writeln

UNTIL Length (SST) = 0

END.

GetString

(* >>> GetString <<< -------- ----- ------ ---- *)

(* Nume fisier : GETSTRIN.SRC *)

(* Rutina generalizata de introducere a sirurilor. *)

(* Aceasta prezinta cimpul intre doua bare verticale. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROCEDURE GetString (X, Y: INTEGER;

VAR XString: String80;

MaxLen: INTEGER;

CapsLock,

Numeric,

GetReal: BOOLEAN;

VAR RValue: REAL;

VAR IValue: INTEGER;

VAR Error: INTEGER;

VAR Escape: BOOLEAN);

VAR

I, J: INTEGER;

Ch: CHAR;

Cursor: CHAR;

Dot: CHAR;

BLength: BYTE;

Clearit: String80;

Worker: String80;

Printables: SET OF CHAR;

Lowercase: SET OF CHAR;

Numerics: SET OF CHAR;

CR: BOOLEAN;

BEGIN

Printables := [' '..'}']; Lowercase := ['a'..'z'];

IF GetReal THEN Numerics := ['-', '.', '0'..'9', 'E', 'e']

ELSE Numerics := ['-', '0'..'9'];

Cursor := '_'; Dot := '.';

FillChar (Clearit, SizeOf (Clearit), '.');

Clearit[0] := Chr (MaxLen);

IF Numeric THEN

IF (GetReal AND (RValue = 0.0)) OR

(NOT GetReal AND (IValue = 0)) THEN XString := ''

ELSE

IF GetReal THEN Str (RValue:MaxLen, XString)

ELSE Str(IValue:MaxLen, XString);

IF Length (XString) > MaxLen THEN XString[0] := Chr(MaxLen);

GoToXY(X, Y); Write ('|', Clearit, '|');

GoToXY(X + 1, Y); Write (XString);

IF Length(XString) < MaxLen THEN

BEGIN GoToXY(X + Length (XString) + 1, Y); Write(Cursor) END;

Worker := XString;

REPEAT

WHILE NOT KeyPressed DO BEGIN END;

Ch := ReadKey;

IF Ch IN Printables THEN

IF Length(Worker) >= MaxLen THEN UhUh

ELSE

IF Numeric AND (NOT (Ch IN Numerics)) THEN UhUh

ELSE

BEGIN

IF Ch IN Lowercase THEN

IF CapsLock THEN Ch := Chr(Ord (Ch) - 32);

Worker := CONCAT(Worker, Ch);

GoToXY(X + 1, Y); Write(Worker);

IF Length(Worker) < MaxLen THEN Write (Cursor)

END

ELSE

CASE Ord(Ch) OF

8, 127: IF Length(Worker) <= 0 THEN UhUh

ELSE

BEGIN

Delete(Worker, Length(Worker), 1);

GoToXY(X + 1, Y); Write(Worker, Cursor);

IF Length(Worker) < MaxLen - 1 THEN Write(Dot)

END;

13: CR := TRUE;

24: BEGIN

GoToXY(X + 1, Y); Write(Clearit);

Worker := ''

END;

27: Escape := TRUE;

ELSE UhUh

END;

UNTIL CR OR Escape;

GoToXY(X + 1, Y); Write(Clearit);

GoToXY(X + 1, Y); Write(Worker);

IF CR THEN

BEGIN

XString := Worker;

IF Numeric THEN

CASE GetReal OF

TRUE: Val(Worker, RValue, Error);

FALSE: Val(Worker, IValue, Error)

END

ELSE

BEGIN

RValue := 0.0;

IValue := 0

END

END

END;

Screen

(* >>> Screen <<< -------- ----- ------ ------ *)

(* Nume fisier : SCREEN2.PAS *)

(* Program demonstrativ - ecran de introducere. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM Screen;

USES CRT, DOS, BoxStuff;

CONST

CapsLock= TRUE;

NoCapsLock= False;

Numeric= TRUE;

NonNumeric= FALSE;

TYPE

String80= STRING[80];

String30= STRING[30];

String6= STRING[6];

String4= STRING[4];

String3= STRING[3];

AdapterType= (None, MDA, CGA, EGAMono, EGAColor,

VGAMono, VGAColor, MCGAMono, MCGAColor);

MAPRec= RECORD

Name,

Address,

City: String30;

State: String3;

Zip: String6

END;

VAR

Ch: CHAR;

CurrentRecord: MAPRec;

Edit,

Quit,

Escape: BOOLEAN;

Width,

Height, I, J: INTEGER;

R: REAL;

PROCEDURE GetScreen (VAR ScreenData: MAPRec;

Edit: BOOLEAN;

VAR Escape: BOOLEAN);

BEGIN

MakeBox (1, 1, 79, 20, GrafChars);

IF NOT Edit THEN

WITH ScreenData DO

BEGIN

Name := '';

Address := '';

City := '';

State := '';

Zip := ''

END;

GoToXY (23, 2);

WriteLn ('>> Ecran pentru introducere date personale <<');

With ScreenData DO

BEGIN

GoToXY (9, 7);

Write ('>> Nume : |..............................|');

GoToXY (9, 9);

Write ('>> Adresa : |..............................|');

GoToXY (9, 11);

Write ('>> Localitate : |..............................|');

GoToXY (9, 13);

Write ('>> Judet: |...|');

GoToXY (9, 15);

Write ('>> Cod postal: |......|');

IF Edit THEN

WITH ScreenData DO

BEGIN

GoToXY (26, 7); Write (Name);

GoToXY (26, 9); Write (Address);

GoToXY (26, 11); Write (City);

GoToXY (26, 13); Write (State);

GoToXY (26, 15); Write (Zip)

END;

GetString (25, 7, Name, 30, NoCapsLock, NonNumeric,

FALSE, R, I, J, Escape);

IF NOT Escape THEN

GetString (25, 9, Address, 30, NoCapsLock, NonNumeric,

FALSE, R, I, J, Escape);

IF NOT Escape THEN

GetString (25, 11, City, 30, NoCapsLock, NonNumeric,

FALSE, R, I, J, Escape);

IF NOT Escape THEN

GetString (25, 13, State, 30, NoCapsLock, NonNumeric,

FALSE, R, I, J, Escape);

IF NOT Escape THEN

GetString (25, 15, Zip, 30, NoCapsLock, NonNumeric,

FALSE, R, I, J, Escape);

END

END;

BEGIN

Edit := FALSE;

CursorOff;

REPEAT

ClrScr;

GetScreen (CurrentRecord, Edit, Escape);

IF Escape THEN

Quit := TRUE

ELSE

BEGIN

Quit := FALSE; GoToXY(1, 22);

Write ('>> Rezumat : ');

WITH CurrentRecord DO

BEGIN

Write (Name, '/', Address, '/', Zip);

GoToXY (1, 23); Write ('>> Corect (D/N) ? ');

IF Da THEN Edit := FALSE

ELSE Edit := TRUE

END

END

UNTIL Quit;

ClrScr;

CursorOn

END.

ReverseName

(* >>> ReverseName <<< -------- ----- ------ -- *)

(* Nume fisier : RVRSNAME.SRC *)

(* Rutina inverseaza numele cu prenumele. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROCEDURE ReverseName (VAR Name: STRING);

VAR

TName: STRING;

BEGIN

IF Pos ('*', Name) <> 0 THEN

BEGIN

TName := Copy (Name, 1, (Pos ('*', Name) - 1));

Delete (Name, 1, Pos ('*', Name);

Name := Concat (Name, ' ', TName)

END

END;

ForceCase

(* >>> ForceCase <<< -------- ----- ------ ---- *)

(* Nume fisier : FRCECASE.SRC *)

(* Rutina asigura conversia literelor in mari sau mici, *)

(* in functie de valoarea parametrului Up. *)

(* -------- ----- ------ ----- ----- ------------ *)

FUNCTION ForceCase (Up: BOOLEAN; Target: STRING): STRING;

CONST

UpperCase: SET OF CHAR= ['A'..'Z'];

LowerCase: SET OF CHAR= ['a'..'z'];

VAR

I: INTEGER;

BEGIN

IF Up THEN

FOR i := 1 TO LENGTH (Target) DO

IF Target[i] IN LowerCase THEN

target[i] := UpCase (Target[i])

ELSE

ELSE

FOR i := 1 TO LENGTH (Target) DO

IF Target[i] IN Uppercase THEN

Target[i] := CHR (ORD (Target[i]) + 32);

ForceCase := Target

END;

Capitol 16

Power

(* >>> Power <<< -------- ----- ------ -------- *)

(* Nume fisier : POWER.SRC *)

(* Rutina pentru ridicarea la puteri reale. *)

(* -------- ----- ------ ----- ----- ------------ *)

FUNCTION Power (Mantissa, Exponent: REAL): REAL;

BEGIN

Power := Exp (Ln (Mantissa) * Exponent)

END;

Pull

(* >>> Pull <<< -------- ----- ------ -------- *)

(* Nume fisier : PULL.SRC *)

(* Rutina returneaza un numar aleator cuprins intr-un *)

(* interval dat. *)

(* -------- ----- ------ ----- ----- ----------- *)

FUNCTION Pull (Low, High: INTEGER): INTEGER;

VAR

I: INTEGER;

BEGIN

REPEAT

I := Random (High + 1)

UNTIL I >= Low;

Pull := I

END;

Rollem

(* >>> Rollem <<< -------- ----- ------ ----- *)

(* Nume fisier : ROLLEM.PAS *)

(* Program demonstrativ numere aleatoare. *)

(* -------- ----- ------ ----- ----- ---------- *)

PROGRAM Rollem;

USES CRT, BoxStuff;

CONST

DiceFaces: ARRAY[0..5, 0..2] OF STRING[5]=

((' ', ' o ', ' '),

('o ', ' ', ' o'),

(' o', ' o ', 'o '),

('o o', ' ', 'o o'),

('o o', ' o ', 'o o'),

('o o o', ' ', 'o o o'));

TYPE

String80= STRING[80];

VAR

Dice, Toss¬ I,

DiceX¬ X¬ Y,

Width, Height: INTEGER;

Quit: BOOLEAN;

Ch: CHAR;

Banner: String80;

PROCEDURE Roll (X, Y: INTEGER;

NumberOfDice: INTEGER;

VAR Toss: INTEGER);

VAR

I, J¬ Throw¬ XOffset: INTEGER;

BEGIN

IF (NumberOfDice * 9) + X >= 80 THEN

NumberOfDice := (80 - X) DIV 9;

FOR I := 1 TO NumberOfDice DO

BEGIN

XOffset := (I + 1) * 9;

MakeBox (X + XOffset, Y, 7, 5, GrafChars);

Throw := Random (6);

FOR J := 0 TO 2 DO

BEGIN

GoToXY (X + 1 + XOffset, Y + 1 + J);

Write (DiceFaces [Throw, j])

END

END

END;

BEGIN

Randomize;

ClrScr;

Quit := FALSE;

Banner := 'GONNA Roll THE BONES!';

MakeBox(-1, 1, Length(Banner) + 4, 3, GrafChars);

GoToXY (80 - Length (Banner)) DIV 2, 2); Write(Banner);

REPEAT

REPEAT

FOR I := 6 TO 18 DO

BEGIN

GoToXY (1, I); ClrEol

END;

GoToXY (1, 6); Write ('>> Cite zaruri vreti in acest joc : ');

ReadLn (Dice);

IF Dice = 0 THEN

Quit := TRUE

ELSE

IF (Dice < 1) OR (Dice > 5) THEN

BEGIN

GoToXY(0, 23); Write ('>> Numarul corect este intre 1 si 5 <<')

END

UNTIL (Dice >= 0) AND (Dice <= 5);

GoToXY (0, 16); ClrEol;

IF NOT Quit THEN

BEGIN

DiceX := (80 - (9 * Dice)) DIV 2;

REPEAT

GoToXY(1, 16); ClrEol;

Roll(DiceX, 9, Dice, Toss);

GoToXY(1, 16); Write('>> Jucati din nou (Y/N) : '); ReadLn(Ch)

UNTIL NOT (Ch IN ['Y', 'y']);

GoToXY (1, 18); Write ('>>Jucati din nou (Y/N) : '); ReadLn(Ch);

IF NOT (Ch IN ['Y', 'y']) THEN

Quit := TRUE

END

UNTIL Quit

END.

Beep

(* >>> Beep <<< -------- ----- ------ -------- *)

(* Nume fisier : BEEP.SRC *)

(* Rutina de avertizare sonora tip telefon. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROCEDURE Beep;

VAR

I: INTEGER;

BEGIN

FOR I := 1 TO 3 DO

BEGIN

Sound (800);

Delay (50);

Sound (500);

Delay (50)

END;

NoSound

END;

UhUh

(* >>> UhUh <<< -------- ----- ------ --------- *)

(* Nume fisier : UHUH.SRC *)

(* Rutina de avertizare sonora a erorilor. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROCEDURE UhUh;

VAR

I: INTEGER;

BEGIN

FOR I := 1 TO 2 DO

BEGIN

Sound (50);

Delay (100);

NoSound;

Delay (50)

END

END;

SendMorse

(* >>> SendMorse <<< -------- ----- ------ ----- *)

(* Nume fisier : SENDMORS.SRC *)

(* Rutina converteste un text intr-un cod morse audibil, *)

(* cu o frecventa si viteza stabilita. Textul este transmis *)

(* rutinei sub forma unui sir de caractere. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROCEDURE SendMorse(PlainText: STRING; ToneFrequency, CodeSpeed: INTEGER);

VAR

I, DitLength,

ToneLength: INTEGER;

CodeChar: STRING;

BlendNextTwo: BOOLEAN;

PROCEDURE Morse (CodeChar: STRING);

(* -------- ----- ------ ----- ----- ---------- *)

(* Rutina converteste textul codificat, sub forma de *)

(* puncte si linii, in sunete cu durate corespunzatoare. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

I: INTEGER;

BEGIN

FOR I := 1 TO Length (CodeChar) DO

IF CodeChar[I] IN ['.', '-'] THEN

BEGIN

IF CodeChar[I] = '.' THEN ToneLength := DitLength

ELSE ToneLength := DitLength * 3;

Sound (ToneFrequency); Delay (ToneLength);

NoSound; Delay (DitLength)

END

END;

BEGIN

BlendNextTwo := FALSE;

DitLength := Round ((1.2 / CodeSpeed) * 1000.0);

FOR I := 1 TO Length (PlainText) DO

IF PlainText[I] = '*' THEN BlendNextTwo := TRUE

ELSE

BEGIN

PlainText[I] := UpCase (PlainText[I]);

CASE PlainText[I] OF

'A': CodeChar := '.-';

'B': CodeChar := '-...';

'C': CodeChar := '-.-.';

'D': CodeChar := '-..';

'E': CodeChar := '.';

'F': CodeChar := '..-.';

'G': CodeChar := '--.';

'H': CodeChar := '....';

'I': CodeChar := '..';

'J': CodeChar := '.---';

'K': CodeChar := '-.-';

'L': CodeChar := '.-..';

'M': CodeChar := '--';

'N': CodeChar := '-.';

'O': CodeChar := '---';

'P': CodeChar := '.--.';

'Q': CodeChar := '--.-';

'R': CodeChar := '.-.';

'S': CodeChar := '...';

'T': CodeChar := '-';

'U': CodeChar := '..-';

'V': CodeChar := '...-';

'W': CodeChar := '.--';

'X': CodeChar := '-..-';

'Y': CodeChar := '--..';

'Z': CodeChar := '--..';

'1': CodeChar := '.----';

'2': CodeChar := '..---';

'3': CodeChar := '...--';

'4': CodeChar := '....-';

'5': CodeChar := '.....';

'6': CodeChar := '-....';

'7': CodeChar := '--...';

'8': CodeChar := '---..';

'9': CodeChar := '----.';

'0': CodeChar := '-----';

'?': CodeChar := '..--..';

'.': CodeChar := '.-.-.-';

',': CodeChar := '--..--';

'/': CodeChar := '-..-.';

'$': CodeChar := '...-..-';

'-': CodeChar := '-....-';

ELSE CodeChar := ''

END;

Morse (CodeChar);

IF NOT BlendNextTwo THEN Delay (DitLength * 2);

BlendNextTwo := FALSE

END

END;

MorseTest

(* >>> MorseTest <<< -------- ----- ------ ---- *)

(* Nume fisier : MORSETEST.PAS *)

(* Program demonstrativ - conversie morse. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM MorseTest;

USES CRT;

TYPE

String80= STRING[80];

VAR

SendString: String80;

SendSpeed: INTEGER;

BEGIN

ClrScr;

Write (' Viteza de transmitere : ');

ReadLn (SendSpeed);

WriteLn;

WriteLn;

Write (' Textul de transmis : ');

Readln (SendString);

SendMorse (SendString, 850, SendSpeed)

END.

Capitol 17

BoxStuff

(* >>> BoxStuff <<< -------- ----- ------ -- *)

(* Nume fisier : BOXSTUFF.PAS *)

(* Biblioteca de rutine pentru "casete" de text. *)

(* -------- ----- ------ ----- ----- --------- *)

UNIT BoxStuff;

INTERFACE

USES CRT;

TYPE

GrafRec= RECORD

ULCorner, URCorner,

LLCorner, LRCorner,

HBar, VBar,

LineCross,

TDown, TUp,

TRight, TLeft: STRING[4]

END;

VAR

GrafChars: GrafRec;

PROCEDURE MakeBox (X, Y, Width, Height: INTEGER; GrafChars: GrafRec);

IMPLEMENTATION

PROCEDURE DefineChars (VAR GrafChars: GrafRec);

(* -------- ----- ------ ----- ----- ----------- *)

(* Rutina locala apelata in partea de initializare a *)

(* unit-ului si este folosita pentru atribuirea valorilor *)

(* cimpurilor din GrafChars. *)

(* -------- ----- ------ ----- ----- ----------- *)

BEGIN

WITH GrafChars DO

BEGIN

ULCorner := CHR (201); URCorner := CHR (187);

LLCorner := CHR (200); LRCorner := CHR (188);

HBar := CHR (205); VBar := CHR (186);

LineCross := CHR (206);

TDown := CHR (203); TUp := CHR (202);

TRight := CHR (185); TLeft := CHR (204)

END

END;

PROCEDURE MakeBox (X, Y, Width, Height: INTEGER; GrafChars: GrafRec);

(* -------- ----- ------ ----- ----- -------- *)

(* Rutina asigura desenarea casetei in functie de *)

(* valorile transmise. *)

(* -------- ----- ------ ----- ----- -------- *)

VAR

i, j: INTEGER;

BEGIN

IF X < 0 THEN

X := (80 - Width) DIV 2;

WITH GrafChars DO

BEGIN

GoToXY (X, Y); Write (ULCorner);

FOR i := 3 TO Width DO

Write (HBar);

Write (URCorner);

GoToXY (X, (Y + Height) - 1);

Write (LLCorner);

FOR i := 3 TO Width DO

Write (HBar);

Write (LRCorner);

FOR i := 1 TO Height - 2 DO

BEGIN

GoToXY (X, Y + i); Write (VBar);

GoToXY ((X + Width) - 1, Y + i); Write (VBar)

END

END

END;

BEGIN

DefineChars (GrafChars)

END.

BoxTest2

(* >>> BoxTest2 <<< -------- ----- ------ -- *)

(* Nume fisier : BOXTEST2.PAS *)

(* Program demonstrativ pentru unit-ul BoxStuff. *)

(* -------- ----- ------ ----- ----- --------- *)

PROGRAM BoxTest2;

USES CRT, BoxStuff;

TYPE

String80= STRING[80];

CONST

EscKey= #27;

VAR

X, Y, J,

Width,

Height: INTEGER;

Ch: CHAR;

BEGIN

FOR J := 0 TO 5 DO

BEGIN

ClrScr;

X := 10 + J * 2;

Y := 6 - J;

Width := 20 + J * 5;

Height := 10 + J;

MakeBox (X, Y, Width, Height, GrafChars);

REPEAT UNTIL KeyPressed;

Ch := ReadKey

END

END.

Mouse

(* >>> Mouse <<< -------- ----- ------ -- *)

(* Nume fisier : MOUSE.PAS *)

(* Rutine pentru lucru cu mouse-ul. *)

(* -------- ----- ------ ----- ----- ------ *)

UNIT Mouse;

INTERFACE

USES DOS;

VAR

ButtonCount: INTEGER;

FUNCTION IsLogitechMouse: BOOLEAN;

PROCEDURE ResetMouse;

PROCEDURE PointerOn;

PROCEDURE PointerOff;

PROCEDURE PollMouse (VAR x, y: WORD; VAR Left, Center, Right: BOOLEAN);

PROCEDURE PointerToXY (x, y: WORD);

PROCEDURE SetColumnRange (High, Low: WORD);

PROCEDURE SetRowRange (High, Low: WORD);

IMPLEMENTATION

VAR

M1, M2, M3, M4: WORD;

PROCEDURE MouseCall (VAR M1, M2, M3, M4: WORD);

VAR

Regs: Registers;

BEGIN

WITH Regs DO

BEGIN

AX := M1; BX := M2;

CX := M3; DX := M4

END;

Intr (51, Regs);

WITH Regs DO

BEGIN

M1 := AX; M2 := BX;

M3 := CX; M4 := DX

END

END;

FUNCTION NumberOfMouseButtons: INTEGER;

BEGIN

M1 := 0;

MouseCall (M1, M2, M3, M4);

NumberOfMouseButtons := M2

END;

FUNCTION MouseIsInstalled: BOOLEAN;

TYPE

BytePtr= ^BYTE;

VAR

TestVector: BytePtr;

BEGIN

GetIntVec (51, POINTER (TestVector));

IF (TestVector = NIL) OR (TestVector^ = $CF) THEN

MouseIsInstalled := FALSE

ELSE MouseIsInstalled := TRUE

END;

FUNCTION IsLogitechMouse;

TYPE

Signature= ARRAY[0..13] OF CHAR;

SigPtr= ^Signature;

CONST

LogitechSig: Signature= 'LOGITECH MOUSE';

VAR

TestVector: SigPtr;

l: LONGINT;

BEGIN

GetIntVec (51, POINTER (TestVector));

LONGINT (TestVector) := LONGINT (TestVector) + 16;

IF TestVector^ = LogitechSig THEN IsLogitechMouse := TRUE

ELSE IsLogitechMouse := FALSE

END;

PROCEDURE ResetMouse;

BEGIN

M1 := 0;

MouseCall (M1, M2, M3, M4)

END;

PROCEDURE PointerOn;

BEGIN

M1 := 1;

MouseCall (M1, M2, M3, M4)

END;

PROCEDURE PointerOff;

BEGIN

M1 := 2;

MouseCall (M1, M2, M3, M4)

END;

PROCEDURE PollMouse (VAR X, Y: WORD; VAR Left, Center, Right: BOOLEAN);

BEGIN

M1 := 3;

MouseCall (M1, M2, M3, M4);

X := M3; Y := M4;

IF (M2 AND $01) = $01 THEN Left := TRUE ELSE Left := FALSE;

IF (M2 AND $02) = $02 THEN Right := TRUE ELSE Right := FALSE;

IF (M2 AND $04) = $04 THEN Center := TRUE ELSE Center := FALSE

END;

PROCEDURE PointerToXY (X, Y: WORD);

BEGIN

M1 := 4; M3 := X; M4 := Y;

MouseCall (M1, M2, M3, M4)

END;

PROCEDURE SetColumnRange (High, Low: WORD);

BEGIN

M1 := 7; M3 := Low; M4 := High;

MouseCall (M1, M2, M3, M4)

END;

PROCEDURE SetRowRange (High, Low: WORD);

BEGIN

M1 := 8; M3 := Low; M4 := High;

MouseCall (M1, M2, M3, M4)

END;

(* ----- ----- ---- Sectiunea de initializare ----- ----- ----- *)

(* Functia MouseIsInstalled verifica intreruperea 51 din *)

(* vector; daca aceasta este NIL sau refera un IRET, atunci *)

(* se presupune ca muose-ul este neinstalat. *)

(*-------- ----- ------ ----- ----- ---------------*)

BEGIN

IF NOT MouseIsInstalled THEN

BEGIN

WRITELN ('>>> EROARE : Driver-ul mouse nu a fost detectat.');

WRITELN (' Revenire in DOS'); HALT (1)

END;

ButtonCount := NumberOfMouseButtons

END.

Unit1

(* >>> Unit1 <<< -------- ----- ------ ------ *)

(* Nume fisier : UNIT1.PAS *)

(* Rutine salveaza valoarea curenta a lui ExitProc *)

(* intr-un pointer. *)

(* -------- ----- ------ ----- ----- ---------- *)

UNIT Unit1;

INTERFACE

IMPLEMENTATION

VAR

Save: POINTER;

PROCEDURE Unit1ExitProcedure;

BEGIN

WriteLn ('Unit #1 -- Exit procedure ...');

ExitProc := Save

END;

BEGIN

Save := ExitProc;

ExitProc := @Unit1ExitProcedure;

WriteLn ('Unit #1 -- Initialization procedure ...')

END.

Unit2

(* >>> Unit2 <<< -------- ----- ------ ------- *)

(* Nume fisier : UNIT1.PAS *)

(* Rutina salveaza adresa procedurii de iesire din *)

(* Unit1. *)

(* *)

(* -------- ----- ------ ----- ----- ----------- *)

UNIT Unit2;

INTERFACE

IMPLEMENTATION

VAR

Save: POINTER;

PROCEDURE Unit2ExitProcedure;

BEGIN

WriteLn ('Unit #2 -- Exit procedure ...');

ExitProc := Save

END;

BEGIN

Save := ExitProc;

ExitProc := @Unit2ExitProcedure;

WriteLn ('Unit #2 -- Initialization procedure ...')

END.

Unit3

(* >>> Unit3 <<< -------- ----- ------ ------ *)

(* Nume fisier : UNIT3.pas *)

(* Rutine salveaza valoarea curenta a lui ExitProc *)

(* intr-un pointer. *)

(* -------- ----- ------ ----- ----- ---------- *)

UNIT Unit3;

INTERFACE

IMPLEMENTATION

VAR

Save: POINTER;

PROCEDURE Unit3ExitProcedure;

BEGIN

WriteLn ('Unit #3 -- Exit procedure ...');

ExitProc := Save

END;

BEGIN

Save := ExitProc;

ExitProc := @Unit3ExitProcedure;

WriteLn ('Unit #3 -- Initialization procedure ...')

END.

Main

(* >>> Main <<< -------- ----- ------ ---------- *)

(* Nume fisier : MAIN.PAS *)

(* Program demonstrativ - inlantuirea procedurilor de *)

(* iesire. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM Main;

USES Unit1, Unit2, Unit3;

BEGIN

WriteLn ('Programul principal incepe aici.');

WriteLn ('Programul principal se termina aici.')

END.

Capitol 18

ClearRegion

(* >>> ClearRegion <<< ----- ----- --------- ----- ----- *)

(* Nume fisier : CLREGION.SRC *)

(* Rutina sterge portiunea indicata de pe ecran. *)

(* -------- ----- ------ ----- ----- ------ *)

PROCEDURE ClearRegion (X1, Y1, X2, Y2: INTEGER);

BEGIN

Window (X1, Y1, X2, Y2);

ClrScr;

Window (1, 1, 80, 25)

END;

WriteAt

(* >>> WriteAt <<< -------- ----- ------ -- *)

(* Nume fisier : WRITEAT.SRC *)

(* Rutina asigura afisarea unui mesaj in pozitia *)

(* indicata (daca X si Y sint pozitivi) sau centrata *)

(* (daca X si/sau Y sint negativi). *)

(* -------- ----- ------ ----- ----- -------- *)

PROCEDURE WriteAt(X,Y: INTEGER; HighLite, UseCR: BOOLEAN; TheText: STRING);

BEGIN

IF Y < 0 THEN Y := 12;

IF X < 0 THEN X := (80 - LENGTH(TheText)) DIV 2; GoToXY(X, Y);

IF HighLite THEN LowVideo;

IF UseCR THEN

WriteLn (TheText)

ELSE

Write (TheText);

NormVideo

END;

Da

(* <<< Da >>> -------- ----- ------ --------- *)

(* Nume fisier : DA.SRC *)

(* Fisierul contine functia Da. *)

(*-------- ----- ------ ----- ----- ----------- *)

FUNCTION Da: BOOLEAN;

VAR

Ch: CHAR;

BEGIN

REPEAT

Ch := UpCase (ReadKey)

UNTIL Ch IN ['D', 'N'];

WriteLn (Ch);

IF Ch = 'D' THEN

Da := TRUE

ELSE

Da := FALSE

END;

FlipField

(* >>> FlipField <<< -------- ----- ------ -------- *)

(* Nume fisier : FLIPFLD.SRC *)

(* Rutina faciliteaza introducerea datelor pentru cimpurile *)

(* ce pot avea una din doua valori diferite. Pentru aceasta *)

(* specificati pozitia cimpului (X, Y), un sir ptr. fiecare caz*)

(* adevarat si fals, si valoarea logica initiala ce indica care*)

(* din cele doua alternative se va afisa la inceput. *)

(* -------- ----- ------ ----- ----- ---------------- *)

PROCEDURE FlipField (X, Y: INTEGER; VAR State: BOOLEAN;

TrueString: String30; FalseString: String30; VAR Escape: BOOLEAN);

VAR

Blanker: String80;

KeyStroke: 0..255;

WorkState: BOOLEAN;

Ch: CHAR;

PROCEDURE ShowState (NowState: BOOLEAN);

BEGIN

GoToXY (X, Y); Write (Blanker);

GoToXY (X, Y);

IF NowState THEN Write (TrueString© ELSE Write (FalseString)

END;

BEGIN

Escape := FALSE; Ch := CHR (0);

LowVideo;

FillChar (Blanker, SizeOf (Blanker), ' ');

WorkState := State;

IF LENGTH (TrueString) > LENGTH (FalseString) THEN

Blanker[0] := CHR(LENGTH(TrueString))

ELSE

Blanker[0] := CHR(LENGTH(FalseString));

ShowState (WorkState);

REPEAT

WHILE NOT KeyStat (Ch) DO BEGIN END;

KeyStroke := ORD (Ch);

IF KeyStroke = 27 THEN Escape := TRUE

ELSE

IF KeyStroke <> 13 THEN WorkState := NOT WorkState;

ShowState (WorkState)

UNTIL (KeyStroke = 13) OR Escape;

IF NOT Escape THEN State := WorkState;

NormVideo;

ShowState (State)

END;

QueryDispzitiv

(* >>> QueryAdapterType <<< ----- ----- --------- ----- ------- *)

(* Nume fisier : QUERYDSP.SRC *)

(* Rutina determina tipul cuplorului display-ului curent *)

(* instalat, pe care-l returneaza sub forma unei valori a *)

(* tipului enumerat AdapterType. *)

(* Tipuì AdapterType trebuie sa fie predefinit astfel : *)

(* AdapterType= (None, MDA, CGA, EGAMono, EGAColor, *)

(* VGAMono, VGAColor, MCGAMono, MCGAColor); *)

(* -------- ----- ------ ----- ----- ------------- *)

FUNCTION QueryAdapterType: AdapterType;

VAR

Regs: Registers;

Code: BYTE;

BEGIN

Regs.AH := $1A;

Regs.AL := $00;

Intr ($10, Regs);

IF Regs.AL = $1A THEN

CASE Regs.BL OF

$00: QueryAdapterType := None;

$01: QueryAdapterType := MDA;

$02: QueryAdapterType := CGA;

$04: QueryAdapterType := EGAColor;

$05: QueryAdapterType := EGAMono;

$07: QueryAdapterType := VGAMono;

$08: QueryAdapterType := VGAColor;

$0A, $0C: QueryAdapterType := MCGAColor;

$0B: QueryAdapterType := MCGAMono;

ELSE QueryAdapterType := CGA

END

ELSE

BEGIN

Regs.AH := $12;

Regs.BX := $10;

Intr ($10, Regs);

IF Regs.BX <> $10 THEN

BEGIN

Regs.AH := $12;

Regs.BL := $10;

Intr ($10, Regs);

IF (Regs.BH = 0) THEN QueryAdapterType := EGAColor

ELSE QueryAdapterType := EGAMono

END

ELSE

BEGIN

Intr ($11, Regs);

Code := (Regs.AL AND $30) SHR 4;

CASE Code OF

1: QueryAdapterType := CGA;

2: QueryAdapterType := CGA;

3: QueryAdapterType := MDA

ELSE QueryAdapterType := CGA

END

END

END

END;

CursorOff

(* >>> CursorOff <<< -------- ----- ------ --- *)

(* Nume fisier : CURSOFF.SRC *)

(* Suprima cursorul dispaly-ului. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROCEDURE CursorOff;

VAR

Regs: Registers;

BEGIN

WITH Regs DO

BEGIN

AX := $0100;

CX := $2000

END;

Intr (16, Regs)

END;

DeterminePoints

(* >>> DeterminePoints <<< ----- ----- --------- ----- ------- *)

(* Nume fisier : FONTSIZE.SRC *)

(* Rutina determina inaltimea celulei caracterului ptr. *)

(* fontul curent in uz. Pentr MDA si CGA aceasta valoare *)

(* este stabilita hard; ptr. EGA, VGA si MCGA valoarea *)

(* trebuie obtinuta din ROM BIOS. *)

(* -------- ----- ------ ----- ----- ------------ *)

FUNCTION DeterminePoints: INTEGER;

VAR

Regs: Registers;

BEGIN

CASE QueryAdapterType OF

CGA: DeterminePoints := 8;

MDA: DeterminePoints := 14;

EGAMono,

EGAColor,

VGAMono,

VGAColor,

MCGAMono,

MCGAColor: BEGIN

WITH Regs DO

BEGIN

AH := $11;

AL := $30;

BL := 0

END;

Intr ($10, Regs);

DeterminePoints := Regs.CX

END

END

END;

CursorOn

(* >>> CursorOn <<< -------- ----- ------ ----- *)

(* Nume fisier : CURSON.SRC *)

(* Activeaza cursorul dispaly-ului. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROCEDURE CursorOn;

VAR

Points: BYTE;

Regs: Registers;

BEGIN

Points := DeterminePoints;

Mem[$40:$87] := Mem[$40:$87] OR $01;

WITH Regs DO

BEGIN

AX := $0100; CH := Points - 3; CL := Points - 1

END;

Intr (16, Regs)

END;

Font

(* >>> Font <<< -------- ----- ------ --------- *)

(* Nume fisier : FONT.PAS *)

(* Utilitar pentru aflarea si modificarea fontului. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM Font;

USES CRT, DOS;

TYPE

AdapterType= (None, MDA, CGA, EGAMono, EGAColor,

VGAMono, VGAColor, MCGAMono, MCGAColor);

FontSizes= SET OF BYTE;

CONST

AdapterStrings: ARRAY[AdapterType] OF STRING=

('None', 'MDA', 'CGA', 'EGAMono', 'EGAColor',

'VGAMono', 'VGAColor', 'MCGAMono', 'MCGAColor');

VAR

InstalledAdapter: AdapterType;

LegalSizes, AdapterSizes: FontSizes;

ErrorPos: INTEGER;

ErrorSize: STRING;

NewFont, FontCode: BYTE;

OldAdapters: SET OF AdapterType;

Regs: Registers;

PROCEDURE ShowFontSizeError (BadSize: STRING);

BEGIN

WriteLn (BadSize, ' nu este o dimensiune valida pentru font.');

WriteLn ('Valorile legale sint 8, 14 si 16,');

WriteLn ('*daca* cuplorul dispaly-ului dv. le admite.')

END;

BEGIN

LegalSizes := [8, 14, 16];

OldAdapters := [CGA, MDA];

IF ParamCount < 1 THEN

BEGIN

InstalledAdapter := QueryAdapterType;

WriteLn('>> FONT << V1.1 de Jeff Duntemann');

WriteLn(' din COMPLETE TURBO PASCAL 5.0'); WriteLn;

WriteLn('Cuplorul instalat este: ',AdapterStrings[InstalledAdapter]);

WriteLn(' Dimensiunea fontului curent este : ', DeterminePoints);

WriteLn; WriteLn;

WriteLn(' Pentru a modifica dimensiunea fontului curent, apelati');

WriteLn('FONT.EXE avind ca parametru dimensiunea dorita, care');

WriteLn('trebuie sa fie 8, 14 sau 16'); WriteLn;

WriteLn('Spre exemplu :'); WriteLn(' C>FONT 14'); WriteLn;

WriteLn(' Retineti ca dimensiunea fontului la CGA sau MDA nu');

WriteLn('se poate modifica.'); Writeln; ReadLn

END

ELSE

BEGIN

VAL (ParamStr (1), NewFont, ErrorPos);

IF ErrorPos <> 0 THEN ShowFontSizeError(ParamStr(2))

ELSE

IF NOT (NewFont IN LegalSizes) THEN

BEGIN

STR(NewFont, ErrorSize); ShowFontSizeError(ErrorSize)

END

ELSE

BEGIN

InstalledAdapter := QueryAdapterType;

CASE InstalledAdapter OF

CGA: AdapterSizes := [8];

MDA: AdapterSizes := [14];

EGAMono, EGAColor: AdapterSizes := [8, 14];

VGAMono, VGAColor: AdapterSizes := [8, 14, 16];

MCGAMono, MCGAColor: AdapterSizes := [16]

END;

IF NOT (NewFont IN AdapterSizes) THEN

BEGIN

WriteLn (' Aceasta dimensiune a fontului nu exista');

WriteLn ('in cuplorul display-ului dv.')

END

ELSE

BEGIN

ClrScr;

IF NOT (InstalledAdapter IN OldAdapters) THEN

BEGIN

CASE NewFont OF

8: FontCode := $12;

14: FontCode := $11;

16: FontCode := $10

END;

Regs.AH := $11;

Regs.AL := FontCode; Regs.BX := 0; Intr ($10, Regs);

Mem[$40:$87] := Mem[$40:$87] OR $01;

Regs.AX := $100;

Regs.BX := 0;

Regs.CH := NewFont - 2; Intr ($10, Regs);

HALT (DeterminePoints)

END

END

END

END

END.

Capitol 19

WriteInt

(* >>> WriteInt <<< -------- ----- ------ ------ *)

(* Nume fisier : WRITEINT.PAS *)

(* Programul scrie echivalentul ASCII al numerelor de la *)

(* 1 la 25 intr-un fisier text. Fiecare numar este urmat de *)

(* perechea codurilor CR/LF. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM WriteInt;

VAR

IntText: TEXT;

I: INTEGER;

BEGIN

Assign (IntText, 'INTEGERS.BIN');

Rewrite (IntText);

FOR I := 1 TO 25 DO

WriteLn (IntText, I);

Close (IntText)

END.

Averager

(* >>> Averager <<< -------- ----- ------ --- *)

(* Nume fisier : AVERAGER.PAS *)

(* Program demonstrativ pentru I/O in fisiere binare. *)

(* -------- ----- ------ ----- ----- ---------- *)

PROGRAM Averager;

VAR

intFile: FILE OF INTEGER;

i, j, Count: Integer;

Average, Total: REAL;

BEGIN

ASSIGN (intFile, 'INTEGERS.BIN');

RESET (intFile);

i := IOResult;

IF i <> 0 THEN

WriteLn ('>> Fisierul INTEGERS.BIN lipseste.')

ELSE

BEGIN

Count := 0; Total := 0.0;

WHILE NOT EOF (intFile) DO

BEGIN

Read (intFile, j);

IF NOT EOF (intFile) THEN

BEGIN

Count := Count + 1; Total := Total + j

END;

END;

CLOSE (intFile); Average := Total / Count; WriteLn;

WriteLn ('>> Exista ', Count, ' intregi in INTEGERS.BIN.');

WriteLn (' Valoarea lor medie este : ', Average:10:4, '.')

END;

READLN

END.

Case

(* >>> Caser <<< -------- ----- ------ ------- *)

(* Nume fisier : CASE.PAS *)

(* Program de conversie litere mari/litere mici pentru *)

(* fisierele text. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM Caser;

CONST

Upper= TRUE;

Lower= FALSE;

TYPE

String40= STRING[40];

String80= STRING[80];

String255= STRING[255];

VAR

i, j, k: INTEGER;

Quit,

NewCase: BOOLEAN;

Ch: CHAR;

WorkFile,

TempFile: TEXT;

WorkLine,

WorkName,

TempName,

CaseTag: String80;

PROCEDURE MakeTemp (FileName: String80; VAR TempName: String80);

(* -------- ----- ------ ----- ----- -------------- *)

(* Determina numele fisierului temporar. Extensia acestui *)

(* fisier va fi .$$$. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

Point: INTEGER;

BEGIN

Point := POS ('.', FileName);

IF Point > 0 THEN

Delete (FileName, Point, LENGTH (FileName) - Point + 1);

TempName := Concat (FileName, '.$$$')

END;

BEGIN

Quit := FALSE;

IF ParamCount < 2 THEN

BEGIN

WriteLn('>> CASE << V2.0 COMPLETE TURBO PASCAL V5.0');

WriteLn(' Jeff Duntemann'); WriteLn;

WriteLn(' Programul forteaza ca toate caracterele unui fisier');

WriteLn(' text sa fie sau cu litere mari sau cu litere mici.');

WriteLn; WriteLn(' Sintaxa de apelare :'); WriteLn;

WriteLn(' CASE UP|DOWN <specificator_fisier>'); WriteLn;

WriteLn(' Spre exemplu, pentru a forta ca toate caracterele');

WriteLn(' fisierului FOO.COB sa fie cu litere mari se va');

WriteLn(' apela programul CASE in modul urmator :'); WriteLn;

WriteLn(' CASE UP FOO.COB'); WriteLn

END

ELSE

BEGIN

WorkName := ParamStr(2);

ASSIGN(WorkFile, WorkName);

RESET (WorkFile);

IF IOResult <> 0 THEN

BEGIN

WriteLn('<< Eroare !<< Fisierul ', WorkName, ' nu exista.');

WriteLn(' Incercati cu un alt nume de fisier.')

END

ELSE

BEGIN

CaseTag := ParamStr(1); CaseTag := ForceCase(Upper, CaseTag);

IF CaseTag = 'UP' THEN NewCase := Upper

ELSE IF CaseTag = 'DOWN' THEN NewCase := Loweò

ELSE Quit := TRUE;

IF Quit THEN

BEGIN

WriteLn ('>> Eroare ! << Parametrul de conversie trebuie');

WriteLn ('sa fie UP (litere mari) si DOWN (litere mici).');

WriteLn (' Apelati din CASE fie cu UP fie cu DOWN.')

END

ELSE

BEGIN

Write ('Conversia se face in ');

IF NewCase THEN WriteLn('litere mari.')

ELSE WriteLn('litere mici.');

MakeTemp(WorkName, TempName);

ASSIGN(tempFile, tempName); REWRITE(tempFile);

WHILE NOT EOF (WorkFile) DO

BEGIN

ReadLn(WorkFile, WorkLine);

Write('.');

WorkLine := ForceCase(NewCase, WorkLine);

WriteLn(tempFile, WorkLine)

END;

CLOSE(tempFile); CLOSE(WorkFile);

ERASE(WorkFile);

RENAME(tempFile, WorkName)

END

END

END

END.

KeySearch

(* >>> KeySearch <<< -------- ----- ------ --- *)

(* Nume fisier : KSEARCH.SRC *)

(* Rutina de cautare binara pentru cheia unui articol *)

(* dintr-un fisier. Tipul articolului trebuie sa fie *)

(* definit de urmatoarea maniera : *)

(* KeyRec= RECORD *)

(* Ref: INTEGER; *)

(* KeyData: String30 *)

(* END; *)

(* Functia returneaza TRUE daca cheia este gasita. *)

(* -------- ----- ------ ----- ----- ----------- *)

FUNCTION KeySearch (VAR Keys: KeyFile; VAR KeyRef: INTEGER;

Matchit: String80): BOOLEAN;

VAR

RecCount, Mid¬ High, Low: INTEGER;

Found¬ Collided: BOOLEAN;

SearchRec: KeyRec;

BEGIN

KeyRef := 0;

RecCount := FileSize (Keys); High := RecCount; Low := 0;

KeySearch := FALSE; Found := FALSE; Collided := FALSE;

Mid := (Low + High) DIV 2;

IF RecCount > 0 THEN

REPEAT

Seek (Keys, Mid);

Read (Keys, SearchRec);

IF (low = Mid) OR (High = Mid) THEN Collided := TRUE;

IF Matchit = SearchRec.KeyData THEN

BEGIN

Found := TRUE;

KeySearch := TRUE;

KeyRef := SearchRec.Ref

END

ELSE

BEGIN

IF Matchit > SearchRec.KeyData THEN

Low := Mid

ELSE

High := Mid;

Mid := (Low - High + 1) DIV 2;

KeyRef := Mid

END

UNTIL Collided OR Found

END;

ShowName

(* >>> ShowName <<< -------- ----- ------ ------ *)

(* Nume fisier : SHOWNAME.PAS *)

(* Program demonstrativ pentru cautarea binara intr-un *)

(* fisier cu chei. *)

(* Programul are nevoie de doua fisiere : FRIENDS.MAP si *)

(* FRIENDS.KEY. FRIENDS.MAP contine articole cu urmatoarele *)

(* date : nume, adresa, localitate, cod stat si cod postal. *)

(* Fisierul FRIENDS.KEY este un fisier de chei sortate *)

(* continind cheile extrase din FRIENDS.MAP. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM ShowName;

TYPE

String3= STRING[3];

String6= STRING[6];

String10= STRING[10];

String30= STRING[30];

String40= STRING[40];

String80= STRING[80];

String255= STRING[255];

MAPRec= RECORD

Name,

Address,

City: String30;

State: String3;

Zip: String6;

Phone: String10

END;

MAPFile= FILE OF MAPRec;

KeyRec= RECORD

Ref: INTEGER;

KeyData: String30

END;

KeyFile= FILE OF KeyRec;

VAR

i, j, k,

RecNum: INTEGER;

Parm: String30;

WorkRec: MAPRec;

WorkFile: MAPFile;

WorkKey: KeyFile;

BEGIN

IF ParamCount < 1 THEN

BEGIN

WriteLn('>> Eroare !<< Trebuie sa introduceti numele dorit');

WriteLn(' in linia de comanda.'); WriteLn;

WriteLn(' SHOWNAME Ionescu*Ion')

END

ELSE

BEGIN

Parm := ParamStr(1);

ASSIGN(WorkFile, 'FRIENDS.MAP');

RESET(WorkFile);

ASSIGN(WorkKey, 'FRIENDS.KEY');

RESET(WorkKey);

IF KeySearch(WorkKey, RecNum, Parm) THEN

BEGIN

Seek(WorkFile, RecNum);

Read(WorkFile, WorkRec);

WITH WorkRec DO

BEGIN

WriteLn('>>Nume : ', name);

WriteLn(' Adresa : ', address);

WriteLn(' Localitate : ', City);

WriteLn(' Cod postal : ', Zip);

WriteLn(' Telefon : ', Phone)

END

END

ELSE

WriteLn('>> Regret, ', Parm, ' nu este in fisier.')

END

END.

GLoad

(* >>> GLoad <<< -------- ----- ------ ------- *)

(* Nume fisier : GLOAD.SRC *)

(* Rutina incarca ecranul grafic dintr-un fisier. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROCEDURE GLoad (GName: STRING; VAR IOR: INTEGER);

TYPE

ScreenBuff= ARRAY[0..16383] OF BYTE;

VAR

GBuff: ScreenBuff ABSOLUTE $8800:0;

GFile: FILE;

BEGIN

Assign(GFile, GName);

Reset (GFile, 16384);

IOR := IOResult;

IF IOR = 0 THEN

BEGIN

BlockRead(GFile, GBuff, 1); Close(GFile)

END

END;

GSave

(* >>> GSave <<< -------- ----- ------ ------- *)

(* Nume fisier : GSAVE.SRC *)

(* Rutina salveaza ecranul grafic intr-un fisier. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROCEDURE GSave (GName: STRING; VAR IOR: INTEGER);

TYPE

ScreenBuff= ARRAY[0..16383] OF BYTE;

VAR

GBuff: ScreenBuff ABSOLUTE $8800:0;

GFile: FILE;

BEGIN

Assign(GFile, GName); Rewrite(GFile, 16384);

BlockWrite(GFile, GBuff, 1);

IOR := IOResult; Close (GFile)

END;

GraphFiler

(* >>> GraphFiler <<< -------- ----- ------ ---- *)

(* Nume fisier : GFILE.PAS *)

(* Program demonstrativ - I/O fisier grafica. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM GraphFiler;

USES CRT, GRAPH3;

VAR

I, ErrorCode: INTEGER;

BEGIN

ClrScr;

HiResColor (15);

HiRes;

TextColor (1);

FOR I := 0 to 199 DO

IF I MOD 5 = 0 THEN

Draw (0, 0, 640, I, 1);

GSave ('LINES.PIC', ErrorCode);

Write ('Apasati <RETURN> ptr. stergere ecran si incarcarea imaginii');

ReadLn;

HiRes;

GLoad ('LINES.PIC', ErrorCode);

ReadLn

END.

HexDump

(* >>> HexDump <<< -------- ----- ------ ----- *)

(* Nume fisier : HEXDUMP.PAS *)

(* Program pentru afisarea hexazecimala a continutului *)

(* fiserelor disc. *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM HexDump;

USES CRT;

CONST

Up= TRUE;

Down= FALSE;

TYPE

String255= STRING[255];

String128= STRING[128];

String80= STRING[80];

String40= STRING[40];

Block= ARRAY[0..127] OF BYTE;

BlockArray= ARRAY[0..15] OF Block;

VAR

Parm: String80;

Ch: CHAR;

DumpFile: FILE;

XBlock: Block;

DiskData: BlockArray;

I, J, K,

Blocks,

BlockCount,

Buffers,

BytesRead,

Remains: INTEGER;

Device: TEXT;

PROCEDURE DumpBlock (XBlock: Block; VAR Device: TEXT);

VAR

I, J, K: INTEGER;

Ch: CHAR;

BEGIN

FOR I := 0 TO 8 DO

BEGIN

FOR J := 0 TO 15 DO

BEGIN

WriteHex (Device, Ord (XBlock[(I * 16) + J]));

Write (Device, ' ')

END;

Write (Device,' |');

FOR J := 0 TO 15 DO

BEGIN

Ch := Chr (XBlock[(I * 16) + j]);

IF ((Ord (Ch) < 127) AND (Ord (Ch) > 31)) THEN

Write (Device, Ch)

ELSE

Write (Device, '.')

END;

WriteLn (Device, '|')

END;

FOR I := 0 TO 1 DO WriteLn (Device, '')

END;

PROCEDURE ShowHelp (HelpName: String80);

VAR

HelpFile: TEXT;

HelpLine: String80;

I: INTEGER;

BEGIN

WriteLn;

Assign(HelpFile, HelpName);

Reset (HelpFile);

IF IOResult = 0 THEN

FOR I := 1 TO 24 DO

BEGIN

ReadLn (HelpFile, HelpLine);

WriteLn (HelpLine)

END;

Close (HelpFile)

END;

BEGIN

Parm := '';

IF ParamCount > 1 THEN

Parm := ForceCase (Up, ParamStr (2));

IF ParamCount < 1 THEN

BEGIN

WriteLn('>>Eroare !<< Trebuie sa introduceti un nume de');

WriteLn(' fisier dupa comanda.');

Write(' Doriti afisarea ecranului Help (D/N) : ');

IF Da THEN ShowHelp('UMPHELP.TXT')

END

ELSE

BEGIN

Assign (DumpFile, ParamStr (1));

Reset (DumpFile);

IF IOResult <> 0 THEN

BEGIN

WriteLn('>>Eroare !<< Fisierul ', ParamStr (1), ' nu exista.');

Write(' Doriti afisarea ecranului Help (D/N) : ');

IF Da THEN ShowHelp ('UMPHELP.TXT')

END

ELSE

BEGIN

IF (Pos('PRINT', Parm) = 1) OR (Pos ('P', Parm) = 1) THEN

Assign(Device, 'PRN')

ELSE Assign (Device, 'CON');

Rewrite(Device);

BlockCount := FileSize(DumpFile) + 1;

IF BlockCount = 0 THEN

WriteLn('Fisierul ', ParamStr (1), ' este gol.')

ELSE

BEGIN

Buffers := BlockCount DIV 16; Remains := BlockCount MOD 16;

FOR I := 1 TO Buffers DO

BEGIN

BlockRead(DumpFile, DiskData, 16, BytesRead);

FOR J := 0 TO 15 DO DumpBlock (DiskData[J], Device)

END;

IF Remains > 0 THEN

BEGIN

BlockRead (DumpFile, DiskData, Remains, BytesRead);

FOR I := 0 TO Remains - 1 DO

DumpBlock(DiskData[I], Device)

END

END;

Close (DumpFile)

END

END

END.

ShowDir

(* >>> ShowDir <<< -------- ----- ------ ------- *)

(* Nume fisier : SHOWDIR.PAS *)

(* Program demonstrativ - citire director. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM ShowDir;

VAR

I: BYTE;

Error: INTEGER;

CurrentDirectory: STRING;

BEGIN

FOR I := 0 TO 4 DO

BEGIN

GetDir (I, CurrentDirectory);

IF I = 0 THEN

Write ('Logged drive : ')

ELSE

Write ('Drive ', Chr (64 + I), ': ');

WriteLn (CurrentDirectory)

END

END.

Capitol 20

Vectors

(* >>> Vectors <<< -------- ----- ------ --------- *)

(* Nume fisier : VECTORS.PAS *)

(* Programul permite inspectarea si modificarea vectorilor *)

(* intreruperilor 8086 precum si vizionarea primilor 256 de *)

(* octeti ai orcarui vector. *)

(* -------- ----- ------ ----- ----- --------------- *)

PROGRAM Vectors;

USES DOS;

CONST

Up= TRUE;

TYPE

String80= STRING[80];

Block= ARRAY[0..255] OF BYTE;

PtrPieces= ARRAY[0..3] OF BYTE;

VAR

I, NewVector¬ VSeg, VOfs,

ErrorPosition¬ VectorNumber: INTEGER;

Vector: POINTER;

MemBlock: Block;

Quit: BOOLEAN;

Command: String80;

CommandChar: CHAR;

PROCEDURE StripWhite (VAR Target: STRING);

CONST

Whitespace: SET OF CHAR= [#8, #10, #12, #13, ' '];

BEGIN

WHILE (Length (Target) > 0) AND (Target[1] IN Whitespace) DO

Delete(Target, 1, 1)

END;

PROCEDURE WriteHex(BT: BYTE);

CONST

HexDigits: ARRAY[0..15] OF CHAR= '0123456789ABCDEF';

VAR

BZ: BYTE;

BEGIN

BZ := BT AND $06;

BT := BT SHR 4;

Write (HexDigits[BT], HexDigits[BZ])

END;

FUNCTION ForceCase(Up: BOOLEAN; Target: STRING): STRING;

CONST

UpperCase: SET OF CHAR= ['A'..'Z'];

LowerCase: SET OF CHAR= ['a'..'z'];

VAR

I: INTEGER;

BEGIN

IF Up THEN

FOR I := 1 TO Length (Target) DO

IF Target[I] IN Lowercase THEN

Target[I] := UpCase (Target[I])

ELSE

ELSE

FOR I := 1 TO Length (Target) DO

IF Target[I] IN UpperCase THEN

Target[I] := Chr (Ord (Target[I]) + 32);

ForceCase := Target

END;

PROCEDURE ValHex(HexString:STRING;VAR Value:LONGINT;VAR ErrCode:INTEGER);

VAR

I, Position: INTEGER;

PlaceValue, TempValue: LONGINT;

HexDigits: STRING;

BEGIN

ErrCode := 0; TempValue := 0; PlaceValue := 1;

HexDigits := '0123456789ABCDEF'; StripWhite (HexString);

IF Pos ('$', HexString) = 1 THEN Delete (HexString, 1, 1);

HexString := ForceCase (Up, HexString);

IF (Length (HexString) > 8) THEN ErrCode := 9

ELSE

IF (Length (HexString) < 1) THEN ErrCode := 1

ELSE

BEGIN

FOR I := Length (HexString) DOWNTO 1 DO

BEGIN

Position := Pos (Copy (HexString, I, 1), HexDigits);

IF Position = 0 THEN

BEGIN

ErrCode := 1;

Exit

END;

TempValue := TempValue + ((Position - 1) * PlaceValue);

PlaceValue := PlaceValue * 16

END;

Value := TempValue

END

END;

PROCEDURE DumpBlock (XBlock: Block);

VAR

I, J, K: INTEGER;

Ch: CHAR;

BEGIN

FOR I := 0 TO 15 DO

BEGIN

FOR J := 0 TO 15 DO

BEGIN

WriteHex(Ord (XBlock[(I * 16) + J])); Write(' ')

END;

Write(' |');

FOR J := 0 TO 15 DO

BEGIN

Ch := Chr (XBlock[(I * 16) + J]);

IF ((Ord(Ch) < 127) AND (Ord(Ch) > 31)) THEN Write(Ch)

ELSE Write('.')

END;

WriteLn ('|')

END;

FOR I := 0 TO 1 DO WriteLn ('')

END;

PROCEDURE ShowHelp;

BEGIN

WriteLn;

WriteLn(' Apasati RETURN pentru a trece la urmatorul vector.');

WriteLn;

WriteLn(' Pentru afisarea unui anumit vector, introduceti numarul');

WriteLn('vectorului (0-255) in zecimal sau precedat de "$" pentru');

WriteLn('hexazecimal, dupa care apasati RETURN.');

WriteLn;

WriteLn(' Comenzile valide sint :'); WriteLn;

WriteLn('D: Vidajul primilor 256 octeti referiti de vectorul curent.');

Write('E: Introducerea unei valori noi(zecimal sau hexa) ptr.');

WriteLn(' vectorul curent.');

WriteLn('H: Afisarea acestui mesaj Help.');

WriteLn('Q: Iesire din VECTORS');

WriteLn('X: Iesire din VECTORS');

Write('Z: Adresa segment si de start a vectorului curent egala ');

WriteLn('cu 0.');

WriteLn('?: Afisarea acestui mesaj Help'); WriteLn;

WriteLn(' Indicatorul ">>IRET" semnifica referirea pointerului ');

WriteLn('unei instructiuni IRET'); WriteLn

END;

PROCEDURE DisplayVector (VectorNumber: INTEGER);

VAR

Dump: INTEGER;

Chunks: PtrPieces;

Vector: POINTER;

Tester: ^BYTE;

BEGIN

GetIntVec (VectorNumber, Vector); Tester := Vector;

Chunks := PtrPieces (Vector); Write(VectorNumber:3, ' $');

WriteHex(VectorNumber); Write(' [');

WriteHex(Chunks[3]); WriteHex(Chunks[2]); Write(':');

WriteHex(Chunks[1]); WriteHex(Chunks[0]); Write(']');

IF Tester^ = $CF THEN Write(' >>IRET ') ELSE Write(' ')

END;

PROCEDURE DumpTargetData (VectorNumber: INTEGER);

VAR

Vector: POINTER;

Tester: ^Block;

BEGIN

GetIntVec (VectorNumber, Vector);

Tester := Vector; MemBlock := Tester^;

IF MemBlock[0] = $CF THEN WriteLn ('Vectorul refera un IRET.');

DumpBlock (MemBlock)

END;

PROCEDURE ChangeVector (VectorNumber: INTEGER);

VAR

Vector: POINTER;

LongTemp, TempValue: LONGINT;

SegPart, OfsPart: WORD;

BEGIN

GetIntVec(VectorNumber, Vector); LongTemp := LONGINT(Vector);

SegPart := LongTemp SHL 16; OfsPart := LongTemp AND $0000FFFF;

Write('Introduceti segmentul ');

Write('(RETURN retine valoarea curenta) : '); ReadLn (Command);

StripWhite (Command);

IF Length (Command) > 0 THEN

BEGIN

Val (Command, TempValue, ErrorPosition);

IF ErrorPosition = 0 THEN SegPart := TempValue

ELSE

BEGIN

ValHex(Command, TempValue, ErrorPosition);

IF ErrorPosition = 0 THEN SegPart := TempValue

END;

Vector := Ptr(SegPart, OfsPart);

SetIntVec(VectorNumber, Vector)

END;

DisplayVector(VectorNumber);

WriteLn; Write('Introduceti adresa de start ');

Write('(RETURN retine valoarea curenta) : '); ReadLn (Command);

StripWhite(Command);

IF Length (Command) > 0 THEN

BEGIN

Val (Command, TempValue, ErrorPosition);

IF ErrorPosition = 0 THEN OfsPart := TempValue

ELSE

BEGIN

ValHex (Command, TempValue, ErrorPosition);

IF ErrorPosition = 0 THEN OfsPart := TempValue

END

END;

Vector := Ptr(SegPart, OfsPart);

SetIntVec(VectorNumber, Vector)

END;

BEGIN

Quit := FALSE;

VectorNumber := 0;

WriteLn('>> VECTORS << V2.0 de Jeff Duntemann');

WriteLn(' din COMPLETE TURBO PASCAL V5.0'); WriteLn;

WriteLn; ShowHelp;

REPEAT

DisplayVector(VectorNumber); Readln(Command);

IF Length (Command) > 0 THEN

BEGIN

Val (Command, NewVector, ErrorPosition);

IF ErrorPosition = 0 THEN VectorNumber := NewVector

ELSE

BEGIN

StripWhite(Command);

Command := ForceCase (Up, Command);

CommandChar := Command[1];

CASE CommandChar OF

'Q', 'X': Quit := TRUE;

'D': DumpTargetData (VectorNumber);

'E': ChangeVector (VectorNumber);

'H': ShowHelp;

'Z': BEGIN

Vector := NIL;

SetIntVec (VectorNumber, Vector);

DisplayVector (VectorNumber);

WriteLn ('zerorizare.');

VectorNumber := (VectorNumber + 1) MOD 256

END;

'?': ShowHelp

END

END

END

ELSE

VectorNumber := (VectorNumber + 1) MOD 256

UNTIL Quit

END.

FlushKey

(* >>> FlushKey <<< -------- ----- ------ ------ *)

(* Nume fisier : FLUSHKEY.SRC *)

(* Rutina foloseste serviciile ROM BIOS pentru a extrage *)

(* din bufferul tastaturii caracterele asteptate. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROCEDURE FlushKey;

VAR

Regs: Registers;

BEGIN

Regs.AH := $01;

Intr ($16, Regs);

IF (Regs.Flags AND $0040) = 0 THEN

REPEAT

Regs.AH := 0;

Intr ($16, Regs);

Regs.AH := $01;

Intr ($16, Regs)

UNTIL (Regs.Flags AND $0040) <> 0

END;

FlushTest

(* >>> FlushTest <<< -------- ----- ------ ----- *)

(* Nume fisier : FLUSHTST.PAS *)

(* Program demonstrativ - golirea bufferului tastaturii. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM FlushTest;

USES CRT, DOS;

VAR

I, J: INTEGER;

Ch: CHAR;

PROCEDURE Counter;

BEGIN

FOR I := 1 TO 1000 DO

BEGIN

GoToXY (1, WhereY); ClrEol;

J := J + 1; Write (J)

END; WriteLn

END;

BEGIN

REPEAT

Counter; FlushKey;

Write('Terminati programul acum (Y/N) ? '); ReadLn

UNTIL Ch IN ['Y', 'y']

END

GetKey

(* >>> GetKey <<< -------- ----- ------ --------- *)

(* Nume fisier : GETKEY.SRC *)

(* Rutina foloseste serviciile ROM BIOS pentru testarea *)

(* prezentei caracterului asteptat in bufferul tastaturii, *)

(* iar daca este cel asteptat, il va returna. Functia insasi *)

(* va returna TRUE daca a fost citit un caracter. Caracterul *)

(* este furnizat in Ch. Daca s-a apasat o tasta "speciala" *)

(* (non-ASCII), variabila Extended devine TRUE iar codul *)

(* scan al tastei speciale va fi furnizat in variabila Scan. *)

(* In plus GETKEY furnizeaza starea "shift" ori de cite ori *)

(* este apelata indiferent daca s-a citit sau nu un caracter.*)

(* Starea Shift este returnata in octetul Shifts astfel : *)

(* Biti Semnificatie *)

(* 7 6 5 4 3 2 1 0 *)

(* 1 . . . . . . . INSERT ( 1 = Activat ) *)

(* . 1 . . . . . . CAPS LOCK ( 1 = Activat ) *)

(* . . 1 . . . . . NUM LOCK ( 1 = Activat ) *)

(* . . . 1 . . . . SCROLL LOCK ( 1 = Activat ) *)

(* . . . . 1 . . . ALT ( 1 = Apasat ) *)

(* . . . . . 1 . . CTRL ( 1 = Apasat ) *)

(* . . . . . . 1 . LEFT SHIFT ( 1 = Apasat ) *)

(* . . . . . . . 1 RIGHT SHIFT ( 1 = Apasat ) *)

(* Testarea bitilor individual se face folosind operatorul *)

(* AND si o masca, spre exemplu : *)

(* IF (Shifts AND $0A) = $0A THEN CtrlAndAltArePressed; *)

(* -------- ----- ------ ----- ----- -------------- *)

FUNCTION GetKey (VAR Ch: CHAR; VAR Extended: BOOLEAN;

VAR Scan: BYTE; VAR Shifts: BYTE): BOOLEAN;

VAR

Regs: Registers;

Ready: BOOLEAN;

BEGIN

Extended := FALSE; Scan := 0;

Regs.AH := $01;

Intr ($16, Regs);

Ready := (Regs.Flags AND $40) = 0;

IF Ready THEN

BEGIN

Regs.AH := 0;

Intr ($16, Regs);

Ch := Chr (Regs.AL);

Scan := Regs.AH;

IF Ch = Chr (0) THEN Extended := TRUE ELSE Extended := FALSE

END;

Regs.AH := $02;

Intr ($16, Regs);

Shifts := Regs.AL;

GetKey := Ready

END;

KeyTest

(* >>> KeyTest <<< -------- ----- ------ ------- *)

(* Nume fisier : KEYTEST.PAS *)

(* Program demonstrativ - accesul complet la tastatura. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM KeyTest;

USES CRT, DOS;

VAR

Ch: CHAR;

Ready,

Extended: BOOLEAN;

Scan,

Shifts: BYTE;

BEGIN

Ch := ' '; Ready := FALSE; ClrScr;

CursorOff;

GoToXY (20, 1);

Write ('>> COMPLETE TURBO PASCAL - demo citire tastatura');

GoToXY (30, 2); Write ('(Apasati ESC pentru iesire ... )');

GoToXY (12, 17); Write ('Ctrl: ');

GoToXY (5, 18); Write ('Left Shift: ');

GoToXY (46, 18); Write ('Right Shift: ');

GoToXY (13, 19); Write ('Alt: ');

GoToXY (50, 19); Write ('Caps Lock: ');

GoToXY (64, 19); Write ('Insert: ');

GoToXY (52, 13); Write ('Num Lock: ');

GoToXY (64, 13); Write ('Scroll Lock: ');

GoToXY (31, 7); Write ('<Ultima tasta apasata: >');

FlushKey;

REPEAT

Ready := GetKey (Ch, Extended, Scan, Shifts);

GoToXY (29, 8);

IF Ready THEN

IF Extended THEN Write ('Extins; Scan cod = ', Scan)

ELSE Write (' ', Ch, ' ');

GoToXY (17, 18); IF (Shifts AND $02) <> 0 THEN

Write (Chr (31))

ELSE Write (Chr (30));

GoToXY (62, 18); IF (Shifts AND $01) <> 0 THEN

Write (Chr (31))

ELSE Write (Chr (30));

GoToXY (18, 17); IF (Shifts AND $04) <> 0 THEN

Write (Chr (31))

ELSE Write (Chr (30));

GoToXY (18, 19); IF (Shifts AND $08) <> 0 THEN

Write (Chr (31))

ELSE Write (Chr (30));

GoToXY (61, 19); IF (Shifts AND $40) <> 0 THEN

Write (Chr (15))

ELSE Write (' ');

GoToXY (72, 19); IF (Shifts AND $80) <> 0 THEN

Write (Chr (15))

ELSE Write (' ');

GoToXY (62, 13); IF (Shifts AND $20) <> 0 THEN

Write (Chr (15))

ELSE Write (' ');

GoToXY (77, 13); IF (Shifts AND $10) <> 0 THEN

Write (Chr (15))

ELSE Write (' ');

UNTIL Ch = Chr (27);

TextMode (3)

END.

CalcTime

(* >>> CalcTime <<< -------- ----- ------ ------ *)

(* Nume fisier : CALCTIME.SRC *)

(* Rutina converteste valorile timpului DOS transmis in *)

(* TimeRec in siruri. Articolul TimeRec trebuie definit : *)

(* TimeRec= RECORD *)

(* TimeComp: WORD; *)

(* TimeString: String80; *)

(* Hours, Minutes, *)

(* Seconds, Hundredths: INTEGER *)

(* END; *)

(* -------- ----- ------ ----- ----- ------------- *)

PROCEDURE CalcTime (VAR ThisTime: TimeRec);

TYPE

String5= STRING[5];

VAR

Temp1,

Temp2: String5;

AmPm: CHAR;

I: INTEGER;

BEGIN

WITH THisTime DO

BEGIN

I := Hours;

IF Hours = 0 THEN I := 12;

IF Hours > 12 THEN

I := Hours - 12;

IF Hours > 11 THEN AmPm := 'p' ELSE AmPm := 'a';

Str (I:2, Temp1); Str (Minutes, Temp2);

IF Length (Temp2) < 2 THEN Temp2 := '0' + Temp2;

TimeString := Temp1 + ':' + Temp2 + AmPm;

TimeComp := (Hours SHL 11 ) OR (Minutes SHL 5) OR (Seconds SHR 1)

END

END;

TimeRec

(* >>> TimeRec <<< -------- ----- ------ ------ *)

(* Nume fisier : TIMEREC.DEF *)

(* Contine definirea articolului TimeRec. *)

(* -------- ----- ------ ----- ----- ------------ *)

TimeRec= RECORD

TimeComp: WORD;

TimeString: String80;

PM: BOOLEAN;

Hours, Minutes, Seconds, Hundredths: INTEGER

END;

CalcDate

(* >>> CalcDate <<< -------- ----- ------ ------- *)

(* Nume fisier : CALCDATE.SRC *)

(* Rutina determina valorile cimpurilor DateString, *)

(* LongDateString si DateComp di articolul DateRec transmis *)

(* acesteia. Calculele se fac pe baza datelor din cimpurile *)

(* Year, Month si Day ale aceluiasi articol. *)

(* Articolul DateRec trebuie definit astfel : *)

(* DateRec= RECORD *)

(* DateComp: WORD *)

(* LongDateString: String80; *)

(* DateString: String80; *)

(* Year, Month, Day: INTEGER; *)

(* DayOfWeek: INTEGER *)

(* END; *)

(* DateString va fi de forma : Wednesday, July 17, 1986 *)

(* DateOfWeek este un cod cuprins intre 0 si 6, 0 = Sunday. *)

(* DateComp este un cardinal generat cu formula : *)

(* DateComp = (Year - 1980) * 512 + (Month * 32) + Day *)

(* Este utilizat ptr.compararea a doua date calendaristice. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROCEDURE CalcDate (VAR ThisDate: DateRec);

TYPE String9= STRING[9];

CONST

MonthTags: ARRAY[1..12] OF String9=

('January', 'February', 'March', 'April', 'May', 'June', 'July',

'August', 'September', 'Octomber', 'November', 'December');

DayTags: ARRAY[0..6] OF String9= ('Sunday', 'Monday', 'Tuesday',

'Wednesday', 'Thursday', 'Friday', 'Saturday');

VAR Temp1: String80;

BEGIN

WITH ThisDate DO

BEGIN

DayOfWeek := DateToDayOfWeek(Year, Month, Day);

Str(Month, DateString); Str (Day, Temp1);

DateString := DateString + '/' + Temp1;

LongDateString := DayTags[DayOfWeek] + ', ';

LongDateString := LongDateString +

MonthTags[Month] + ' ' + Temp1 + ', ';

Str (Year, Temp1); LongDateString := LongDateString + Temp1;

DateString := DateString + '/' + Copy (Temp1, 3, 2);

DateComp := (Year - 1980) * 512 + (Month * 32) + Day

END

END;

DateRec

(* >>> DateRec <<< -------- ----- ------ ------ *)

(* Nume fisier : DATEREC.DEF *)

(* Contine definirea articolului DateRec. *)

(* -------- ----- ------ ----- ----- ------------ *)

DateRec= RECORD

DateComp: WORD;

LongDateString: String80;

DateString: String80;

Year, Month, Day, DayOfWeek: INTEGER

END;

Toucher

(* >>> Toucher <<< -------- ----- ------ -------- *)

(* Nume fisier : TOUCHER.PAS *)

(* Demonstreaza folosirea rutinelor calendaristice DOS. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM Toucher;

USES DOS;

VAR

I: INTEGER;

Stamp: LONGINT;

Now: DateTime;

Target: FILE;

Sec100, DayOfWeek: WORD;

BEGIN

IF ParamCount < 1 THEN

BEGIN

WriteLn ('>>TOUCHER V1.0 de Jeff Duntemann');

WriteLn (' din COMPLETE TURBO PASCAL V5.0');

WriteLn; WriteLn; WriteLn (' Forma de apelare :');

WriteLn; WriteLn (' TOUVHER <nume_fisier>'); WriteLn;

WriteLn (' TOUCHER este un utilitar care inlocuieste "marca"');

WriteLn (' timp/data a fisierului specificat cu timpul si data ');

WriteLn ('curenta. Acesta se poate utiliza pentru actualizarea');

WriteLn ('datei unui fisier.'); WriteLn

END

ELSE

BEGIN

Assign (Target, ParamStr (1));

Reset (Target);

I := IOResult;

IF I <> 0 THEN

WriteLn ('>>Eroare ! Fisierul indicat nu poate fi deschis ...')

ELSE

BEGIN

WITH Now DO

GetTime (Hour, Min, Sec, Sec100);

WITH Now DO

GetDate (Year, Month, Day, DayOfWeek);

PackTime (Now, Stamp);

SetFTime (Target, Stamp);

Close (Target)

END

END

END.

DateToDayOfWeek

(* >>> DateToDayOfWeek <<< -------- ----- ------ - *)

(* Nume fisier : DAYOWEEK.SRC *)

(* Rutina determina denumirea zilei datei transmise. *)

(* Principiul de lucru se bazeaza pe stabilirea datei curente *)

(* a sistemului ca fiind data transmisa pentru a obtine ziua *)

(* din saptamina in AL. (Data curenta reala se salveaza la *)

(* inceputul lucrului rutinei si se restaureaza la terminare *)

(* acesteia). *)

(* -------- ----- ------ ----- ----- --------------- *)

FUNCTION DateToDayOfWeek (Year, Month, Day: INTEGER): INTEGER;

VAR

DayNumber: INTEGER;

LeapYearDay: BOOLEAN;

SaveDate¬ WorkDate: Registers;

CONST

DayArray: ARRAY[1..12] OF INTEGER=

(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

BEGIN

LeapYearDay := FALSE;

IF (Month = 2) AND ((Year MOD 4) = 0) AND (Day = 29) THEN

LeapYearDay := TRUE;

IF (NOT LeapYearDay) AND (Day > DayArray[Month]) THEN

DateToDayOfWeek = -1

ELSE

BEGIN

WorkDate.AH := $2B;

SaveDate.AH := $2A;

MSDOS (SaveDate);

WITH WorkDate DO

BEGIN

CX := Year; DH := Month; DL := Day;

MSDOS (WorkDate);

AH := $2A;

MSDOS (WorkDate);

DayNumber := AL;

IF LeapYearDay THEN

IF DayNumber = 0 THEN

DayNumber := 6

ELSE

DayNumber := Pred (DayNumber);

DateToDayOfWeek := DayNumber

END;

SaveDate.AH := $2B;

MSDOS (SaveDate)

END

END;

DirRec

(* >>> DirRec <<< -------- ----- ------ ------- *)

(* Nume fisier : DIRREC.DEF *)

(* Definirea articolului DirRec. *)

(* -------- ----- ------ ----- ----- ------------ *)

DirRec= RECORD

FileName: String15;

Attrib: BYTE;

FileSize: LONGINT;

TimeStamp: TimeRec;

DateStamp: DateRec;

Prior, Next: DIRPtr

END;

Capitolul 21

ListMan

(* >>> ListMan <<< -------- ----- ------ --------- *)

(* Nume fisier : LISTMAN.PAS *)

(* Program demonstrativ - utilizarea variabilelor dinamice *)

(* -------- ----- ------ ----- ----- --------------- *)

PROGRAM ListMan;

USES CRT;

TYPE

String30= STRING[30];

String15= STRING[15];

String6= STRING[6];

ArtPtr= ^ArticolLista;

ArticolLista= RECORD

Nume, Adresa,

Oras: String30;

Tara: String15;

CodPostal: String6;

Urmator: ArtPtr

END;

FisierPersoane= FILE OF ArticolLista;

VAR

Ch: CHAR;

Radacina: ArtPtr;

Iesire: BOOLEAN;

PROCEDURE StergeLini (Prima, Ultima: INTEGER);

VAR

I: INTEGER;

BEGIN

FOR I := Prima TO Ultima DO

BEGIN GOTOXY(1, I); ClrEol; GOTOXY(1, Prima) END

END;

PROCEDURE PrezentareArticol (ArtLucru: ArticolLista);

VAR

I: INTEGER;

BEGIN

StergeLini (17, 22);

WITH ArtLucru DO

BEGIN

WriteLn(' >> Nume: ', Nume); WriteLn(' >> Adresa: ',Adresa);

WriteLn(' >> Localitate: ', Oras); WriteLn(' >> Tara: ', Tara);

WriteLn(' >> Cod postal: ', CodPostal)

END

END;

PROCEDURE VerificareSpatiu;

VAR

Spatiu: INTEGER;

SpatiuReal¬ SpatiuArticol: REAL;

BEGIN

Spatiu := MemAvail;

IF Spatiu < 0 THEN SpatiuReal := 65536.0 + Spatiu

ELSE SpatiuReal := Spatiu;

SpatiuArticol := SpatiuReal / SizeOf (ArticolLista);

StergeLini (2, 3); WriteLn (' >> Exista spatiu pentru ',SpatiuArticol:6:0,

' articole in lista dumneavoastra.');

END;

PROCEDURE EliminareLista (VAR Radacina: ArtPtr);

VAR

Retine: ArtPtr;

BEGIN

GOTOXY(27, 10); Write(' >> Sinteti sigur (D/N) ? ');

IF Da THEN

IF Radacina <> NIL THEN

REPEAT

Retine := Radacina^.Urmator;

Dispose(Radacina);

Radacina := Retine

UNTIL Radacina = NIL;

StergeLini (10, 10); VerificareSpatiu

END;

PROCEDURE AdaugaArticole ( VAR Radacina: ArtPtr);

VAR

I: INTEGER;

Abandonº BOOLEAN;

ArtLucru: ArticolLista;

Ultim¬ Curent: ArtPtr;

BEGIN

GOTOXY(27, 7); Write ('<< Adaugare articole >>');

REPEAT

StergeLini (24, 24);

FillChar(ArtLucru, SizeOf(ArtLucru), CHR(0));

StergeLini(9, 15);

WITH ArtLucru DO

BEGIN

Write (' >> Nume: '); ReadLn (Nume);

Write (' >> Adresa: '); ReadLn (Adresa);

Write (' >> Localitate: '); ReadLn (Oras);

Write (' >> Tara: '); ReadLn (Tara);

Write (' >> Cod postal: '); ReadLn (CodPostal)

END; Abandon := FALSE;

IF Radacina = NIL THEN

BEGIN

New (Radacina); ArtLucru.Urmator := NIL; Radacina^ := ArtLucru

END

ELSE

BEGIN

Curent := Radacina;

REPEAT

IF Curent^.Nume = ArtLucru.Nume THEN

BEGIN

PrezentareArticol(Curent^);

GotoXY (1, 15); Write(' >> Articolul exista deja in lista. ',

'Abandonati introducerea (D/N) ? ');

IF Da THEN Abandon := TRUE ELSE Abandon := FALSE;

StergeLini (15, 22)

END; Ultim := Curent; Curent := Curent^.Urmator

UNTIL (Curent = NIL) OR Abandon OR (Curent^.Nume > ArtLucru.Nume);

IF NOT Abandon THEN

IF Radacina^.Nume > ArtLucru.Nume THEN

BEGIN

New (Radacina);

ArtLucru.Urmator:=Ultim;

Radacina^:=ArtLucru

END

ELSE

BEGIN

New (Ultim^.Urmator);

ArtLucru.Urmator := Curent;

Ultim^.Urmator^:=ArtLucru;

VerificareSpatiu

END

END;

GotoXY (1, 24); Write (' >> Adaugati un alt articol in lista (D/N) ? ')

UNTIL NOT Da

END;

PROCEDURE IncarcaLista (VAR Radacina: ArtPtr);

VAR

NumeLucru: String30;

FisierLucru: FisierPersoane;

Curent: ArtPtr;

I: INTEGER;

Ok: BOOLEAN;

BEGIN

Iesire := FALSE;

REPEAT

StergeLini (10, 10);

Write (' >> Introduceti numele fisierului ce se va incarca : ');

ReadLn (NumeLucru);

IF Length (NumeLucru) = 0 THEN

BEGIN StergeLini (10, 12); Iesire := TRUE END

ELSE

BEGIN

Assign (FisierLucru, NumeLucru);

Reset (FisierLucru);

IF IOResult <> 0 THEN

BEGIN

Write(' >> Acest fisier nu exista. Introduceti alt nume.');

Ok := FALSE

END

ELSE Ok := TRUE

END

UNTIL Ok OR Iesire;

IF NOT Iesire THEN

BEGIN

StergeLini (10, 12); Curent := Radacina;

IF Radacina = NIL THEN

BEGIN

New (Radacina);

Read(FisierLucru, Radacina^);

Curent := Radacina

END

ELSE

WHILE Curent^.Urmator <> NIL DÏ Curent := Curent^.Urmator;

IF Radacina^.Urmator <> NIL THEN

REPEAT

New (Curent^.Urmator);

Curent := Curent^.Urmator;

Read (FisierLucru, Curent^)

UNTIL Curent^.Urmator = NIL;

VerificareSpatiu; Close (FisierLucru)

END

END;

PROCEDURE VizualizareLista (Radacina: ArtPtr);

VAR

I: INTEGER;

FisierLucru: FisierPersoane;

Curent: ArtPtr;

BEGIN

IF Radacina = NIL THEN

BEGIN

GotoXY(27, 18); WriteLn(' >> Lista dv. este goala. '); GotoXY(26, 20);

Write(' >> Apasati <CR> pentru continuare ...'); ReadLn

END

ELSE

BEGIN

GotoXY(31, 7); Write(' >> Vizualizare articole <<');

Curent := Radacina;

WHILE Curent <> NIL DO

BEGIN

PrezentareArticol (Curent^); Curent := Curent^.Urmator;

GotoXY (1, 23);

Write('>> Apasati <CR> pentru a vizualiza urmatorul articol...');

ReadLn

END; StergeLini(19, 22)

END

END;

PROCEDURE SalvareLista (Radacina: ArtPtr);

VAR

NumeLucru: String30;

FisierLucru: FisierPersoane;

Curent: ArtPtr;

I: INTEGER;

BEGIN

GotoXY (1, 10);

Write (' >> Numele fisierului in care se va salva lista : ');

ReadLn (NumeLucru);

Assign (FisierLucru, NumeLucru);

Rewrite (FisierLucru);

Curent := Radacina;

WHILE Curent <> NIL DO

BEGIN

Write (FisierLucru, Curent^);

Curent := Curent^.Urmator

END;

Close (FisierLucru)

END;

BEGIN

ClrScr; GotoXY (28, 1); Write ('<< Construirea listei inlantuite >>');

VerificareSpatiu;

GotoXY (18,8); Write ('-------- ----- ------ ----');

Radacina := NIL; Iesire := FALSE;

REPEAT

StergeLini (4, 7); StergeLini (9, 24); GotoXY (1, 4);

WriteLn('>> [A]daugare articol, [I]ncarcare, [V]izualizare, [S]alvare,');

Write(' [E]liminare lista sau [T]erminare : ');

REPEAT

Ch := UpCase (ReadKey)

UNTIL Ch IN ['A', 'E', 'I', 'S', 'T', 'V']; WriteLn (Ch);

CASE Ch OF

'A' : AdaugaArticole (Radacina);

'E' : EliminareLista (Radacina);

'I' : IncarcaLista (Radacina);

'S' : SalvareLista (Radacina);

'T' : Iesire := TRUE;

'V' : VizualizareLista (Radacina)

END

UNTIL Iesire

END.

GetDirectory

(* >>> GetDirectory <<< -------- ----- ------ --- *)

(* Nume fisier : GETDIR.SRC *)

(* Rutina returneaza un pointer catre lista inlantuita cu *)

(* articole de tip DIRRec, articole ce trebuie predefinite, *)

(* impreuna cu tipul pointer DIRPtr care le refera : *)

(* DIRPtr= ^DIRRec; *)

(* DIRRec= RECORD *)

(* FileName: String15; *)

(* Attrib: BYTE; *)

(* FileSize: LONGINT; *)

(* TimeStamp: TimeRec; *)

(* DateStamp: DateRec; *)

(* Prior, *)

(* Next: DIRPtr *)

(* END; *)

(* Lista inlantuita va contine un articol pentru fiecare *)

(* fisier din directorul curent. *)

(* Tipurile TimeRec si DateRec trebuie sa fie definite *)

(* inainte de utilizarea rutinei GetDirectory; la fel si *)

(* tipul String80 si rutina DTAToDIR. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROCEDURE GetDirectory (FileSpec: String80; Sorted, SortOnName: BOOLEAN;

VAR Ascending, Descending: DIRPtr);

TYPE

String9: STRING[9];

VAR

I, FindError: INTEGER;

Regs: Registers;

OurDTA: SearchRec;

Root, Current, Last, Holder: DIRPtr;

PositionFound: BOOLEAN;

FUNCTION LaterThan (LeftEntry, RightEntry: DIRPtr): BOOLEAN;

BEGIN

IF LeftEntry^.DateStamp.DateComp > RightEntry^.DateStamp.DateComp THEN

LaterThan := TRUE

ELSE

IF (LeftEntry^.DateStamp.DateComp = RightEntry^.DateStamp.DateComp)

AND

(LeftEntry^.TimeStamp.TimeComp > RightEntry^.TimeStamp.TimeComp) THEN

LaterThan := TRUE

ELSE

LaterThan := FALSE

END;

PROCEDURE AppendToEnd (VAR Holder, Descending: DIRPtr);

BEGIN

Descending^.Next := Holder;

Descending^.Next^.Prior := Descending;

Descending := Descending^.Next

END;

BEGIN

FindFirst (FileSpec, $16, OurDTA);

FindError := DOSError;

IF FindError = 2 THEN

BEGIN

Ascending := NIL;

Descending := NIL

END

ELSE

BEGIN

New (Root);

DTAToDIR(Root^);

Current := Root;

Descending := Root;

IF FindError <> 18 THEN

REPEAT

FindNext (OurDTA);

FindError := DOSError;

IF FindError <> 18 THEN

BEGIN

New(Holder);

DTAToDIR(Holder^);

IF Sorted THEN

BEGIN

Current := Root;

REPEAT

IF SortOnName THEN

IF Current^.FileName > Holder^.FileName THEN

PositionFound := TRUE

ELSE

PositionFound := FALSE

ELSE

IF LatherThan (Current, Holder) THEN

PositionFound := TRUE

ELSE

PositionFound := FALSE;

IF NOT PositionFound THEN

Current := Current^.Next

UNTIL (Current = NIL) OR PositionFound;

IF PositionFound THEN

BEGIN

IF Current = Root THEN

BEGIN

Holder^.Next := Root;

Current^.Prior := Holder;

Root := Holder

END

ELSE

BEGIN

Holder^.Next := Current;

Holder^.Prior := Current^.Prior;

Current^.Prior.Next := Holder;

Current^.Prior := Holder

END

END

ELSE

AppendToEnd (Holder, Descending)

END

ELSE

AppendToEnd (Holder, Descending)

END

UNTIL FindError = 18;

Ascending := Root

END

END;

Spacer

(* >>> Spacer <<< -------- ----- ------ ----------- *)

(* Nume fisier : SPACER.PAS *)

(* Program demonstrativ - gestiunea listei dublu inlantuite *)

(* Programul este de fapt un utilitar similar comenzii DIR din *)

(* DOS afisind fisierele conform specificatorului indicat. *)

(* -------- ----- ------ ----- ----- ---------------- *)

PROGRAM Spacer;

USES DOS;

CONST

SortByName= TRUE;

SortByDate= FALSE;

TYPE

String80= STRING[80];

String15= STRING[15];

DTAPtr= ^SearchRec;

VAR

Parms: BYTE;

SpaceTaken: REAL;

RunUp,

RunDown,

Current: DIRPtr;

FileSpec,

WorkString: String80;

Sorted,

SortSpec,

Ascending: BOOLEAN;

I: INTEGER;

BEGIN

Sorted := FALSE;

SortSpec := SortByName;

Ascending := TRUE;

Parms := ORD(ParamCount)

CASE Parms OF

0: BEGIN

WriteLn('>>SPACER<< V2.00 de Jeff Duntemann');

WriteLn(' din COMPLETE TURBO PASCAL V5.0');

WriteLn;

WriteLn(' Programul afiseaza toate directoarele ce corespund');

WriteLn('specificatorului indicat, inclusiv cele ascunse si sistem.');

WriteLn(' In plus, cumuleaza dimensiunile fisierelor gasite, afisind');

WriteLn('la sfirsit cantitatea totala ocupata de acestea.');

WriteLn; WriteLn; WriteLn(' Sintaxa apelului :'); WriteLn;

WriteLn(' SPACER <specificator_fisier> N|D A|D'); WriteLn;

WriteLn('unde <specificator_fisier> este un specificator de fisier');

WriteLn('legal DOS, inclusiv nume cu "*".');

WriteLn(' Al doilea parametru este N sau D :');

WriteLn(' N indica sortarea dupa nume;');

WriteLn(' D indica sortarea dupa data si timp.'); WriteLn;

WriteLn(' Al treilea parametru este A sau D :');

WriteLn(' A indica afisarea in ordine ascendenta;');

WriteLn(' D indica afisarea in ordine descendenta.');

WriteLn('Daca nu se indica acest parametru afisarea se face in')

WriteLn('ordine ascendenta.'); WriteLn;

WriteLn(' Daca nu se indica ultimi doi parametri afisarea se face');

WriteLn('in ordinea fizica.');

Halt

END;

1: FileSpec := ParamStr (1);

2: BEGIN

Sorted := TRUE;

FileSpec := ParamStr (1);

WorkString := ParamStr (2);

CASE UpCase (WorkString [1]) OF

'D': SortSpec := SortByDate;

'N': SortSpec := SortByName

ELSE Sorted := FALSE

END

END;

3: BEGIN

Sorted := TRUE;

FileSpec := ParamStr (1);

WorkString := ParamStr (2);

CASE UpCase (WorkString[1]) OF

'D': SortSpec := SortByDate;

'N': SortSpec := SortByName

ELSE Sorted := FALSE

END;

IF Sorted THEN

BEGIN

WorkString := ParamStr (3);

CASE UpCase (WorkString[1]) OF

'A': Ascending := TRUE;

'D': Ascending := FALSE

ELSE

Ascending := TRUE

END

END

END;

END;

GetDirectory (FileSpec, Sorted, SortSpec, RunUp, RunDown);

IF Ascending THEN Current := RunUp ELSE Current := RunDown;

IF Current = NIL THEN WriteLn ('Nu au fost gasite fisiere,')

ELSE

BEGIN

SpaceTaken := 0.0;

IF Ascending THEN

WHILE Current <> NIL DO

BEGIN

WriteLn (DirToString (Current^));

SpaceTaken := SpaceTaken + Current^.FileSize;

Current := Current^.Next

END

ELSE

WHILE Current <> NIL DO

BEGIN

WriteLn (DirToString (Current^));

SpaceTaken := SpaceTaken + Current^.FileSize;

Current := Current^.Prior

END;

WriteLn; Write('Spatiul total ocupat de aceste fisiere este ');

WriteLn(SpaceTaken:9:0, ' octeti.')

END

END.

DisposeOfDirectory

(* >>> DisposeOfDirectory <<< ----- ----- --------- ----- ------- *)

(* Nume fisier : DISPDIR.SRC *)

(* Rutina elibereaza articolele din lista construita cu *)

(* rutina GetDirectory. *)

(* Tipul DIRRec si DIRPtr trebuie sa fie definit inainte *)

(* de includerea acestei rutine. *)

(* -------- ----- ------ ----- ----- --------------- *)

PROCEDURE DisposeOfDirectory (RootPointer: DIRPtr);

VAR

Holder: DIRPtr;

BEGIN

IF RootPointer <> NIL THEN

REPEAT

Holder := RootPointer^.Next;

Dispose (RootPointer);

RootPointer := Holder

UNTIL RootPointer = NIL

END;

Capitolul 22

DrawMark

(* >>> DrawMarker <<< -------- ----- ------ ------- *)

(* Nume fisier : DRAWMARK.SRC *)

(* Aceasta rutina foloseste trasarea cu linii relative ptr. *)

(* a desena "poli-markere" in pozitia pointerului curent (CP). *)

(* Modelele ce se vor desena sint date in tablouri, fiecare *)

(* pereche de valori indicind "modificarea pe X" respectiv *)

(* "modificarea pe Y". Prima pereche de valori se foloseste *)

(* ptr. mutarea CP, nu ptr. trasare linie, astfel ca marcherul *)

(* sa fie complet in afara pozitiei CP. *)

(* -------- ----- ------ ----- ----- ---------------- *)

TYPE

PointArray= ARRAY[0..9, 0..1] OF INTEGER;

CONST

Lozenge: PointArray = ((0, -3), (-3, 3), (3, 3), (3, -3), (-3, -3),

(0, 0), (0, 0), (0, 0), (0, 0), (0, 0));

Cross: PointArray = ((0, 0), (0, -3), (0, 6), (0, -3), (3, 0),

(-6, 0), (0, 0), (0, 0), (0, 0), (0, 0));

Square: PointArray = ((-2, -2), (0, 4), (4, 0), (0, -4), (-4, 0),

(0, 0), (0, 0), (0, 0), (0, 0), (0, 0));

PROCEDURE DrawMarker (Marker: PointArray);

VAR

i: INTEGER;

BEGIN

MoveRel(Marker[0,0], Marker[0,1]);

i := 1;

WHILE NOT ((Marker[i,0] = 0) AND (Marker[i,1]) = 0)) DO

BEGIN LineRel (Marker[i,0], Marker[i,1]); Inc (i© END

END;

Square

(* >>> Square <<< -------- ----- ------ ---------- *)

(* Nume fisier : SQUARE.SRC *)

(* Rutina traseaza un patrat in X, Y care este simetric *)

(* independent de dispozitivul sau modul grafic curent. *)

(* Parametrul Side contine marimea laturei, in pixeli, iar *)

(* MeasureXAxis este o valoare logica care indica daca *)

(* marimea lui Side este masurata de-a lungul axei X sau a *)

(* axei Y. MeasureXAxis = TRUE presupune ca Side este masurat *)

(* de-a lungul axei X, si FALSE daca Side este masurat de-a *)

(* lungul axei Y. *)

(* -------- ----- ------ ----- ----- --------------- *)

PROCEDURE Square (x, y, Side: WORD; MeasureXAxis: BOOLEAN);

VAR

xa, ya,

xl, yl: WORD;

BEGIN

xl := Side; yl := Side; GetAspectRatio (xa, ya);

IF MeasureXAxis THEN yl := ROUND ((xa / xa) * Side)

ELSE xl := ROUND ((ya / xa) * Side);

Rectangle (x, y, x + xl, y + yl)

END;

AspectRatio

(* >>> AspectRatio <<< -------- ----- ------ ---- *)

(* Numele fisierului : SETASP.PAS *)

(* Programul demonstreaza reglarea raportului dimensional *)

(* (aspect ratio). *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM AspectRatio;

USES CRT, GRAPH;

VAR

i, Color,

GraphDriver,

GraphMode,

ErrorCode: INTEGER;

Palette : PaletteType;

PROCEDURE AdjustAspectRatio;

VAR

Side, Delta: INTEGER;

w, Color,

XAspect, YAspect: WORD;

Ch: CHAR;

Quit: BOOLEAN;

TheLine: STRING;

Filler: FillSettingsType;

PROCEDURE ShowRatio;

VAR

temp: STRING;

BEGIN

SetFillStyle (0, 0);

Bar (0, 0, GetMaxX, 20);

WITH Filler DO SetFillStyle (Pattern, Color);

GetAspectRatio (XAspect, YAspect);

TheLine := 'Raport curent : ';

STR (XAspect:6, temp);

TheLine := TheLine + temp + '/';

STR (YAspect:6, temp);

TheLine := TheLine + temp +

'. Sagetile pentru ajustare; Q pentru iesire ...';

OutTextXY (10, 10, TheLine)

END;

BEGIN

Quit := FALSE; Side := 180;

Color := GetColor;

GetFillSettings (Filler);

GetAspectRatio (XAspect, YAspect);

Delta := YAspect DIV 100;

Square ((GetMaxX DIV 2) - (Side DIV 2),

(GetMaxY DIV 2) - (Side DIV 2), Side, True);

ShowRatio;

REPEAT

Ch := UpCase (ReadKey);

IF Ch <> #0 THEN

IF Ch = 'Q' THEN Quit := TRUE ELSE Quit := FALSE

ELSE

BEGIN

Ch := ReadKey;

CASE ORD (Ch) OF

$48 : BEGIN

SetColor (0);

Square ((GetMaxX DIV 2) - (Side DIV 2),

(GetMaxY DIV 2) - (Side DIV 2), Side, True);

w := YAspect + Delta;

SetAspectRatio (XAspect, w); SetColor (Color);

Square ((GetMaxX DIV 2) - (Side DIV 2),

(GetMaxY DIV 2) - (Side DIV 2), Side, True);

ShowRatio

END;

$50 : BEGIN

SetColor (0);

Square ((GetMaxX DIV 2) - (Side DIV 2),

(GetMaxY DIV 2) - (Side DIV 2), Side, True);

w := YAspect - Delta;

SetAspectRatio (XAspect, w); SetColor (Color);

Square ((GetMaxX DIV 2) - (Side DIV 2),

(GetMaxY DIV 2) - (Side DIV 2), Side, True);

ShowRatio

END;

END

END

UNTIL Quit

END;

BEGIN

GraphDriver := Detect;

InitGraph (GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

IF ErrorCode <> 0 THEN

BEGIN

WriteLn (' >> Oprire datorita erorii grafice : ',

GraphErrorMsg (ErrorCode));

HALT (2)

END;

AdjustAspectRatio;

CloseGraph

END.

Halucinatii

(* >>> Halucinatii <<< -------- ----- ------ ---- *)

(* Nume fisier : GRAPHABS.PAS *)

(* Programul demonstreaza comutarea paletei culorilor din *)

(* sistemul grafic BGI. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM Halucinatii;

USES CRT, GRAPH;

VAR

i, Color: INTEGER;

Palette: PaletteType;

GraphDriver, GraphMode, ErrorCode: INTEGER;

BEGIN

GraphDriver := Detect;

InitGraph (GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

IF ErrorCode <> 0 THEN

BEGIN

WriteLn ('>> Abandonarea programului datorita erorii');

WriteLn (' grafice : ', GraphErrorMsg (ErrorCode));

Halt (2)

END;

SetBkColor (White);

Randomize;

GetPalette (Palette);

FOR Color := 0 TO 10000 DO

BEGIN

SetColor (Random (Palette.Size));

Line (Random (GetMaxX), Random (GetMaxY),

Random (GetMaxX), Random (GetMaxY))

END;

REPEAÔ

REPEAÔ i := Random (Palette.Size© UNTIL i <> 0;

SetPalette (i, Random (Palette.Size))

UNTIL KeyPressed;

CloseGraph

END.

Patterns

(* >>> Patterns <<< -------- ----- ------ ------ *)

(* Nume fisier : PATTERNS.PAS *)

(* Program demonstrativ - modele de umplere grafice. *)

(* (patterns) *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM Patterns;

USES GRAPH;

CONST

HalfTone1: FillPatternType ½ ($CC, $33, $CC, $33, $CC, $33, $CC, $33);

HalfTone2: FillPatternType ½ ($AA, $55, $AA, $55, $AA, $55, $AA, $55);

Squiggles: FillPatternType ½ ($94, $84, $48, $30, $00, $C1, $22, $14);

Vertical: FillPatternType ½ ($CC, $CC, $CC, $CC, $CC, $CC, $CC, $CC);

Bricks: FillPatternType ½ ($01, $82, $44, $28, $10, $20, $40, $80);

Blocks: FillPatternType ½ ($00, $3C, $42, $42, $42, $42, $3C, $00);

VAR

GraphDriver,

GraphMode,

ErrorCode: INTEGER;

BEGIN

GraphDriver := Detect;

InitGraph (GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

IF ErrorCode <> 0 THEN

BEGIN

WriteLn ('>> Abandonarea programului datorita unei erori');

WriteLn (' grafice : ', GraphErrorMsg (ErrorCode)); Halt (2)

END;

SetFillPattern (HalfTone1, White);

Bar (0, 0, 99, 100); Rectangle (0, 0, 99, 100);

SetFillPattern (HalfTone2, White);

Bar (110, 0, 209, 100); Rectangle (110, 0, 209, 100);

SetFillPattern (Squiggles, White);

Bar (220, 0, 319, 100); Rectangle (220, 0, 319, 100);

SetFillPattern (Vertical, White);

Bar (0, 105, 99, 199); Rectangle (0, 105, 99, 199);

SetFillPattern (Bricks, White);

Bar (110, 105, 209, 199); Rectangle (110, 105, 209, 199);

SetFillPattern (Blocks, White);

Bar (220, 105, 319, 199); Rectangle (220, 105, 319, 199);

ReadLn; CloseGraph

END.

Polygons

(* >>> Polygons <<< -------- ----- ------ ------- *)

(* Nume fisier : POLYGONS.PAS *)

(* Program demonstrativ - desenare si hasurare poligoane. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM Polygons;

USES GRAPH;

CONST

Squiggles: FillPatternType = ($94, $84, $48, $30, $00, $C1, $22, $14);

Pentagon: ARRAY[0..5] OF PointType =

((X: 100; Y: 10), (X: 200; Y: 80),

(X: 155; Y: 160), (X: 45; Y: 160),

(X: 0; Y: 80), (X: 100; Y: 10));

BigDipper: ARRAY[0..5] OF PointType =

((X: 350; Y: 20), (X: 420; Y: 35),

(X: 475; Y: 100), (X: 450; Y: 160),

(X: 530; Y: 195), (X: 600; Y: 130));

VAR

GraphDriver, GraphMode, i, ErrorCode: INTEGER;

BEGIN

GraphDriver := Detect;

InitGraph (GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

IF ErrorCode <> 0 THEN

BEGIN

WriteLn (' >> Abandonare program; Eroare grafica : ',

GraphErrorMsg (ErrorCode));

Halt (2)

END;

SetFillPattern (Squiggles, White);

DrawPoly (6, Pentagon);

FOR i := 0 TO 5 DO

Pentagon[i].Y := Pentagon[i].Y + 160;

FillPoly (6, Pentagon);

DrawPoly (6, BigDipper);

FOR i := 0 TO 5 DO

BigDipper[i].Y := BigDipper[i].Y + 140;

FillPoly (6, BigDipper);

ReadLn; CloseGraph

END.

RoundedRectangle

(* >>> RoundedRectangle >>> ----- ----- --------- ----- -------- *)

(* Nume fisier : ROUNDRCT.SRC *)

(* Rutina deseneaza un dreptunghi in punctul de coordonate *)

(* X si Y; dimensiunile in pixeli este Width (latime) si *)

(* Height (inaltime); colturile sint rotunjite ca raza R. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROCEDURE RoundedRectangle (X, Y, Width, Height, R: WORD);

VAR

ULData,

LLData,

LRData,

URData: ArcCoordsType;

BEGIN

Arc (X + R, Y + R, 90, 180, R);

GetArcCoords (ULData);

Arc (X + R, Y + Height + R, 180, 270, R);

GetArcCoords (LLData);

Arc (X + Width + R, Y + Height + R, 270, 360, R);

GetArcCoords (LRData);

Arc (X + Width + R, Y + R, 0, 90, R);

GetArcCoords (URData);

Line (ULData.XEnd, ULData.YEnd, LLData.XStart, LLData.YStart);

Line (LLData.XEnd, LLData.YEnd, LRData.XStart, LRData.YStart);

Line (LRData.XEnd, LRData.YEnd, URData.XStart, URData.YStart);

Line (URData.XEnd, URData.YEnd, ULData.XStart, ULData.YStart);

END;

PieMan

(* >>> PieMan <<< -------- ----- ------ --------- *)

(* Nume fisier : PIEMAN.PAS *)

(* Program demonstrativ - utilizarea procedurii PieSlice. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM PieMan;

USES GRAPH;

CONST

HalfTone1: FillPatternType = ($CC, $33, $CC, $33, $CC, $33, $CC, $33);

HalfTone2: FillPatternType = ($AA, $55, $AA, $55, $AA, $55, $AA, $55);

Squiggles: FillPatternType = ($94, $84, $48, $30, $00, $C1, $22, $14);

Vertical: FillPatternType = ($CC, $CC, $CC, $CC, $CC, $CC, $CC, $CC);

Bricks: FillPatternType = ($01, $82, $44, $28, $10, $20, $40, $80);

Blocks: FillPatternType = ($00, $3C, $42, $42, $42, $42, $3C, $00);

VAR

GraphDriver,

GraphMode,

ErrorCode: INTEGER;

BEGIN

GraphDriver := Detect;

InitGraph (GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

IF ErrorCode <> 0 THEN

BEGIN

WriteLn ('>> Abandonarea programului datorita unei erori');

WriteLn (' grafice : ', GraphErrorMsg (ErrorCode));

Halt (2)

END;

RoundedRectangle (30, 30, 300, 260, 35);

PieSlice (220, 160, 0, 45, 120);

SetFillPattern (Bricks, White); PieSlice (220, 160, 45, 110, 120);

SetFillPattern (Squiggles, White); PieSlice (220, 160, 110, 130, 120);

SetFillPattern (Halftone1, White); PieSlice (220, 160, 130, 200, 120);

SetFillPattern (Blocks, White); PieSlice (220, 160, 200, 245, 120);

SetFillPattern (Halftone2, White); PieSlice (220, 160, 245, 295, 120);

SetFillPattern (Vertical, White); PieSlice (220, 160, 295, 360, 120);

SetFillStyle (SolidFill, White); PieSlice (500, 230, 0, 360, 70);

SetFillPattern (Bricks, White); PieSlice (500, 75, 0, 360, 70);

SetLineStyle (3, 0, 1);

SetFillStyle (EmptyFill, White); PieSlice (400, 360, 0, 40, 75);

ReadLn; CloseGraph

END.

FontsBGI

(* >>> FontsBGI <<< -------- ----- ------ ------- *)

(* Nume fisier : FONTSBGI.PAS *)

(* Program demonstrativ - fonturile grafice din BGI. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM FontsBGI;

USES GRAPH;

VAR

i, j, k, GraphDriver, GraphMode, ErrorCode: INTEGER;

TestString: STRING;

BEGIN

GraphDriver := Detect; InitGraph (GraphDriver, GraphMode, '');

ErrorCode := GraphResult;

IF ErrorCode <> 0 THEN

BEGIN

WriteLn ('>> Abandonarea programului datorita unei erori');

WriteLn (' grafice : ', GraphErrorMsg (ErrorCode)); Halt (2)

END;

j := 0; (ª ---­ Fonôul impliciô ---­ *)

FOR i := 1 TO 3 DO

BEGIN

SetTextStyle (DefaultFont, HorizDir, i);

OutTextXY (0, j, 'Font implicit');

j := j + 5 + TextHeight('Font implicit')

END;

j := 60; TestString := 'Font mic'; (ª ---­ Fontuì SmallFonô ---­ *)

FOR i := 4 TO 8 DO

BEGIN

SetTextStyle (SmallFont, HorizDir, i); OutTextXY (0, j, TestString);

j := j + TextHeight (TestString)

END;

j := 100; TestString := 'Font triplat'; (ª ---­ Fontuì TriplexFonô ---­ *)

FOR i := 4 TO 10 DO

BEGIN

SetTextStyle (SmallFont, HorizDir, i); OutTextXY (320, j, TestString);

j := j + TextHeight (TestString)

END;

j := 155; TestString := 'SansSerif'; (ª ---­ Fontuì SansSeriæ ---­ *)

FOR i := 4 TO 10 DO

BEGIN

SetTextStyle (SansSerifFont, HorizDir, i); OutTextXY (0, j, TestString);

j := j + TextHeight (TestString)

END;

j := 120; TestString := 'Gothic'; (ª ---­ Fontuì Gothiã ---­ *)

FOR i := 4 TO 7 DO

BEGIN

SetTextStyle (GothicFont, VertDir, i); OutTextXY (j, 70, TestString);

j := j + TextHeight (TestString)

END;

ReadLn; CloseGraph

END.

DemoMenu

(* >>> DemoMenõ <<< -------- ----- ------ ------- *)

(* Nume fisier : DEMOMENU.DEF *)

(* Fisierul contine constantele structurate necesare *)

(* afisarii meniurilor "pull-down" si sint folosite in *)

(* unit-ul PULDOWN.PAS. *)

(* Continutul fisierului se va modifica in functie de *)

(* aplicatie. *)

(* Tipul MenuDesc este definit in unit_ul PullDown. *)

(* -------- ----- ------ ----- ----- -------------- *)

CONST

DemoMenu: MenuDesc =

((XStart: 18; XEnd: 58;

Title: 'Fisiere';

MenuSize: 11;

ImagePtr: NIL;

Active: TRUE;

Choices: 5; ItemList:

((Item: 'Receptie'; ItemCode: 21; ItemActive: TRUE),

(Item: 'Salvare '; ItemCode: 22; ItemActive: TRUE),

(Item: 'Stergere'; ItemCode: 23; ItemActive: TRUE),

(Item: 'Redenumire'; ItemCode: 24; ItemActive: TRUE),

(Item: 'Iesire'; ItemCode: 25; ItemActive: TRUE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 74; XEnd: 114;

Title: 'Editare';

MenuSize: 11;

ImagePtr: NIL;

Active: TRUE;

Choices: 9; ItemList:

((Item: 'Grab'; ItemCode: 31; ItemActive: TRUE),

(Item: 'Pull'; ItemCode: 32; ItemActive: TRUE),

(Item: 'Erase'; ItemCode: 33; ItemActive: TRUE),

(Item: 'Join'; ItemCode: 34; ItemActive: TRUE),

(Item: 'Swap'; ItemCode: 35; ItemActive: TRUE),

(Item: 'Invert'; ItemCode: 36; ItemActive: TRUE),

(Item: 'Recolor'; ItemCode: 37; ItemActive: TRUE),

(Item: 'Split'; ItemCode: 38; ItemActive: TRUE),

(Item: 'Duplicate'; ItemCode: 39; ItemActive: TRUE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 129; XEnd: 175;

Title: 'Desen';

MenuSize: 11;

ImagePtr: NIL;

Active: TRUE;

Choices: 4; ItemList:

((Item: 'Freehand'; ItemCode: 41; ItemActive: TRUE),

(Item: 'PolyLine'; ItemCode: 42; ItemActive: TRUE),

(Item: 'Spray'; ItemCode: 43; ItemActive: TRUE),

(Item: 'Dragstemp'; ItemCode: 44; ItemActive: TRUE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 179; XEnd: 215;

Title: 'Text';

MenuSize: 11;

ImagePtr: NIL;

Active: TRUE;

Choices: 5; ItemList:

((Item: 'Load Font'; ItemCode: 51; ItemActive: TRUE),

(Item: 'Place Text'; ItemCode: 52; ItemActive: TRUE),

(Item: 'Set Direction'; ItemCode: 53; ItemActive: TRUE),

(Item: 'Dropsshadow'; ItemCode: 54; ItemActive: TRUE),

(Item: 'Point Size'; ItemCode: 55; ItemActive: TRUE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))),

(XStart: 15; XEnd: 55;

Title: '';

MenuSize: 0;

ImagePtr: NIL;

Active: FALSE;

Choices: 0; ItemList:

((Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE),

(Item: ''; ItemCode: 0; ItemActive: FALSE))));

PullDown

(* >>> PullDowN <<< -------- ----- ------ ------ *)

(ª Nume fisier º PULLDOWN.PAS *)

(* Sistem grafic de meniuri derulantE "pull-down". *)

(* -------- ----- ------ ----- ----- ------------- *)

UNIT PullDown;

INTERFACE

USES DOS, GRAPH, CRT, Mouse;

TYPE

String15= STRING[15];

ItemRec = RECORD

Item : String15;

ItemCode : BYTE;

ItemActive: BOOLEAN

END;

MenuRec = RECORD

XStart, XEnd: WORD;

Title: String15;

MenuSize: WORD;

ImagePtr: POINTER;

Active: BOOLEAN;

Choices: BYTE;

ItemList: ARRAY [0..18] OF ItemRec

END;

MenuDesc = ARRAY[0..12] OF MenuRec;

PROCEDURE ActivateMenu (VAR CurrentMenu: MenuDesc; MenuNumber: BYTE);

PROCEDURE DeactivateMenu (VAR CurrentMenu: MenuDesc; MenuNumber: BYTE);

PROCEDURE ActivateItem (VAR CurrentMenu: MenuDesc; Code: BYTE);

PROCEDURE DeactivateItem (VAR CurrentMenu: MenuDesc; Code: BYTE);

FUNCTION InvalidMenu (CurrentMenu: MenuDesc; VAR BadCode: BYTE): BOOLEAN;

PROCEDURE SetUpMenu (CurrentMenu : MenuDesc);

PROCEDURE Menu (CurrentMenu: MenuDesc; VAR ReturnCode: WORD;

VAR Amulet: BOOLEAN);

IMPLEMENTATION

PROCEDURE ChangeItemStatus (VAR CurrentMenu: MenuDesc;

Code: BYTE; ToActive: BOOLEAN);

(* -------- ----- ------ ----- ----- ------------*)

(* Rutina este locala unit-ului PullDown si asigura *)

(* modificarea starii (selectat sau nu) unui articol din *)

(* meniul "pull-down". *)

(*-------- ----- ------ ----- ----- -------------*)

VAR

I, MenuNumber: BYTE;

ItemFound: BOOLEAN;

BEGIN

MenuNumber := 0; ItemFound := FALSE;

REPEAT

WITH CurrentMenu[MenuNumber] DO

BEGIN

i := 0;

REPEAT

IF ItemList[i].ItemCode = Code THEN

BEGIN

ItemList[i].ItemActive := ToActive;

ItemFound := TRUE;

IF ImagePtr <> NIL THEN

BEGIN

FreeMem (ImagePtr, MenuSize);

ImagePtr := NIL

END

END

ELSE INC (i)

UNTIL ItemFound OR (i > Choices)

END;

INC (MenuNumber)

UNTIL ItemFound OR (MenuNumber > 12)

END;

PROCEDURE ActivateMenu (VAR CurrentMenu: MenuDesc; MenuNumber: BYTE);

(* -------- ----- ------ ----- ----- -------------*)

(* Rutina activeaza meniul specificat prin MenuNumber, *)

(* indiferent daca acesta a fost sau nu activ la invocare. *)

(* ImagePtr este setat pe NIL si meniul va fi redesenat. *)

(*-------- ----- ------ ----- ----- --------------*)

BEGIN

WITH CurrentMenu[MenuNumber] DO

BEGIN

ImagePtr := NIL; Active := TRUE

END

END;

PROCEDURE DeactivateMenu (VAR CurrentMenu: MenuDesc; MenuNumber: BYTE);

(* -------- ----- ------ ----- ----- -------------*)

(* Rutina inactiveaza meniul specificat prin MenuNumber, *)

(* indiferent daca acesta este activ sau nu la apelare. *)

(* ImagePtr este setat pe NIL si meniul va fi redesenat. *)

(*-------- ----- ------ ----- ----- --------------*)

BEGIN

WITH CurrentMenu[MenuNumber] DO

BEGIN

ImagePtr := NIL; Active := FALSE

END

END;

PROCEDURE ActivateItem (VAR CurrentMenu: MenuDesc; Code: BYTE);

(* -------- ----- ------ ----- ----- -------------*)

(* Rutina activeaza articolul cu codul Code, indiferent *)

(* de starea articolului la invocare. ImagePtr este setat *)

(* pe NIL astfel ca meniul va fi redesenat. *)

(*-------- ----- ------ ----- ----- --------------*)

BEGIN

ChangeItemStatus (CurrentMenu, Code, TRUE)

END;

PROCEDURE DeactivateItem (VAR CurrentMenu: MenuDesc; Code: BYTE);

(* -------- ----- ------ ----- ----- -------------*)

(* Rutina inactiveaza articolul cu codul Code, indiferent *)

(* de starea articolului la invocare. ImagePtr este setat *)

(* pe NIL astfel ca meniul va fi redesenat. *)

(*-------- ----- ------ ----- ----- --------------*)

BEGIN

ChangeItemStatus (CurrentMenu, Code, FALSE)

END;

FUNCTION InvalidMenu (CurrentMenu: MenuDesc; VAR BadCode: BYTE): BOOLEAN;

(* -------- ----- ------ ----- ----- -------------*)

(* Functia verifica daca nu exista un cod duplicat in *)

(* cadrul tabloului meniu transmis prin CurrentMenu. *)

(* Intotdeauna sistemul de meniuri acepta numai articole *)

(* de meniuri cu coduri unice. *)

(* Aceasta functie se va executa pentru orice tablou de *)

(* meniuri pe care doriti sa le folositi si abandonati *)

(* programul daca se detecteaza un cod dublu. *)

(*-------- ----- ------ ----- ----- --------------*)

VAR

i, j : WORD;

OrdSet: SET OF BYTE;

DuplicateFound: BOOLEAN;

BEGIN

DuplicateFound := FALSE;

OrdSet := [];

FOR i := 0 TO 12 DO

WITH CurrentMenu[i] DO

BEGIN

j := 0;

REPEAT

IF ItemList[j].ItemCode > 0 THEN

IF ItemList[j].ItemCode IN OrdSet THEN

BEGIN

DuplicateFound := TRUE;

BadCode := ItemList[j].ItemCode

END

ELSE

BEGIN

OrdSet := OrdSet + [ItemList[j].ItemCode]; INC (j)

END

ELSE INC (j)

UNTIL (j > Choices) OR DuplicateFound

END;

InvalidMenu := DuplicateFound

END;

PROCEDURE SetUpMenu (CurrentMenu: MenuDesc);

(* -------- ----- ------ ----- ----- -------------*)

(* Rutina initializeaza afisarea barei meniu, a titlurilor*)

(* si a amuletei barei meniu. *)

(*-------- ----- ------ ----- ----- --------------*)

VAR

i,

DrawX,

DrawY: WORD;

BEGIN

SetFillStyle (SolidFill, White);

Bar (0, 0, GetMaxX, 11);

SetColor (0);

Rectangle (2, 1, 12, 9);

FOR i := 3 TO 8 DO IF ODD (i) THEN Line (4, 1, 10, 1);

DrawX := CurrentMenu[0].XStart;

DrawY := 2;

i := 0;

REPEAT

OutTextXY (DrawX, DrawY, CurrentMenu[i].Title);

INC (i);

DrawX := CurrentMenu[i].XStart

UNTIL (LENGTH (CurrentMenu[i].Title) = 0) OR (i > 13)

END;

PROCEDURE Menu (CurrentMenu: MenuDesc; VAR ReturnCode: WORD;

VAR Amulet: BOOLEAN);

(* -------- ----- ------ ----- ----- -------------*)

(* Este rutina principala pentru meniuri. Este necesar ca *)

(* inaintea ei sa se fi executat rutinele InvalidMenu si *)

(* SetUpMenu. Selectarea unei comenzi din bara meniu se *)

(* face prin pozitionarea mouse-ului pe cuvintul dorit, *)

(* dupa care se muta mouse-ul in meniul "pull-down" si se *)

(* alege optiunea prin apsarea pe butonul dreapta. *)

(* Codul articolului selectat este furnizat in ReturnCode.*)

(* ReturnCode este 0 daca nu se selecteaza un articol. *)

(*-------- ----- ------ ----- ----- --------------*)

VAR

PointerX, PointerY: Word;

Left, Center, Right: BOOLEAN;

I, J,

MenuWidth,

M1X, M1Y,

M2X, M2Y: INTEGER;

FoundMenu: BOOLEAN;

SaveColor: INTEGER;

UnderMenu: POINTER;

BounceBar: POINTER;

Pick: WORD;

UpperBound, LowerBound: INTEGER;

PROCEDURE RestoreUnderMenuBox ;

BEGIN

PointerOff;

PutImage (M1X, M1Y, UnderMenu^, NormalPut);

PointerOn

END;

BEGIN

Amulet := FALSE; SaveColor := GetColor; SetColor (White);

PollMouse (PointerX, PointerY, Left, Right, Center);

IF (PointerX > 1) AND (PointerX < 13) AND

(PointerY > 0) AND (PointerY < 10) THEN

BEGIN

Amulet := TRUE;

SetColor (SaveColor);

EXIT

END;

i := -1;

REPEAT

i := 1 + 1;

IF (PointerX >= CurrentMenu[i].XStart) AND

(PointerX <= CurrentMenu[i].XEnd) AND

CurrentMenu[i].Active THEN FoundMenõ := True

FoundMenu := TRUE

ELSE FoundMenu := FALSE

UNTIL FoundMenu OR (LENGTH (CurrentMenu[i].Title) = 0) OR (i > 13);

IF FoundMenu THEN

BEGIN

PointerOff;

WITH CurrentMenu[i] DO

BEGIN

MenuWidth := 0;

FOR j := 0 TO Choices - 1 DO

IF LENGTH (ItemList[j].Item) > MenuWidth THEN

MenuWidth := LENGTH (ItemList[j].Item);

MenuWidth := MenuWidth * 8;

M1X := XStart; M1Y := 11; M2X := XStart + MenuWidth + 6;

M2Y := (Choices + 1) * 12;

MenuSize := ImageSize (M1X, M1Y, M2X, M2Y);

GetMem (UnderMenu, MenuSize);

GetImage(M1X, M1Y, M2X, M2Y, UnderMenu^);

SetFillStyle (SolidFill, Black); Bar (M1X, M1Y, M2X, M2Y);

SetFillStyle (SolidFill, White);

GetMem(BounceBar,ImageSize(M1X +1,M1Y + 1,M2X - 1,M1Y + 12));

Bar (M1X + 1, M1Y + 1, M2X - 1, M1Y + 12);

GetImage (M1X + 1, M1Y + 1, M2X -1, M2Y + 12, BounceBar^);

IF ImagePtr = NIL THEN

BEGIN

Rectangle (M1X, M1Y, M2X, M2Y);

SetColor (Black);

IF ItemList[0].ItemActive THEN

OutTextXY (XStart + 3, 14, ItemList[0].Item);

SetColor(White);

FOR j := 1 TO Choices - 1 DO

IF ItemList[j].ItemActive THEN

OutTextXY(XStart + 3,14 * (j * 12), ItemList[j].Item);

GetMem(ImagePtr, MenuSize);

GetImage(M1X, M1Y, M2X, M2Y, ImagePtr^)

END;

PutImage (M1X, M1Y, ImagePtr^, NormalPut);

PointerOn;

UpperBound := 12;

LowerBound := 24;

Pick := 0;

REPEAT

PollMouse (PointerX, PointerY, Left, Center, Right);

IF (PointerX<M1X) OR (PointerX>M2X) OR (PointerY>M2Y) THEN

Right := TRUE

ELSE

BEGIN

IF PointerY < UpperBound THEN

IF PointerY>12 THEN

BEGIN

PointerOff;

IF ItemList[Pick].ItemActive THEN

PutImage(M1X + 1,UpperBound,BounceBar^,XORPut);

UpperBound := UpperBound - 12;

LowerBound := LowerBound - 12;

Pick := Pick - 1;

IF ItemList[Pick].ItemActive THEN

PutImage(M1X + 1,UpperBound,BounceBar^,XORPut);

PointerOn

END;

IF PointerY > LowerBound THEN

BEGIN

PointerOff;

IF ItemList[Pick].ItemActive THEN

PutImage (M1X + 1, UpperBound, BounceBar^,XORPut);

UpperBound := UpperBound + 12;

LowerBound := LowerBound + 12;

Pick := Pick + 1;

IF ItemList[Pick].ItemActive THEN

PutImage (M1X +1, UpperBound, BounceBar^, XORPut);

PointerOn

END

END;

UNTIL (NOT Left) OR Right;

RestoreUnderMenuBox;

IF Right THEN ReturnCode := 0

ELSE

IF ItemList[Pick].ItemActive THEN

ReturnCode := ItemList[Pick].ItemCode

ELSE ReturnCode := 0

END;

PointerOn

END;

SetColor (SaveColor)

END;

END.

Scrrible

(* >>> Scribble <<< -------- ----- ------ ---- *)

(* Nume fisier : SCRIBBLE.PAS *)

(* Program demonstrativ - meniuri "pull down". *)

(* -------- ----- ------ ----- ----- ----------- *)

PROGRAM Scribble;

USES DOS, CRT, GRAPH, Mouse, PullDown;

VAR

GraphDriver, GraphMode, ErrorCode, i, j: INTEGER;

R: REAL;

M1, M2, M3, M4, ReturnCode: WORD;

XText, YText, Mule: STRING;

PointerX, PointerY: WORD;

Left, Center, Right, Amulet, Quit: BOOLEAN;

DuplicateCode: BYTE;

ExitSave: POINTER;

SaveColor: WORD;

Palette: PaletteType;

Color: Word;

PROCEDURE ReturnToTextMode;

BEGIN

PointerOff;

CloseGraph;

ExitProc := ExitSave

END;

BEGIN

ExitSave := ExitProc;

ExitProc := @ReturnToTextMode;

ClrScr;

IF InvalidMenu (DemoMenu, DuplicateCode) THEN

BEGIN

WRITELN('>>> Abandonare pentru meniu dublu : ', DuplicateCode); HALT (1)

END;

GraphDriver := Detect;

InitGraph (GraphDriver, GraphMode, '');

IF ErrorCode <> 0 THEN

BEGIN

WRITELN('>>> Abandonare pentru eroarea grafica : ',

GraphErrorMsg (ErrorCode));

HALT (2)

END;

SetUpMenu(DemoMenu); PointerOn; SetColor(Yellow); Quit := FALSE;

REPEAT

PollMouse (PointerX, PointerY, Left, Center, Right);

IF Left THEN

BEGIN

IF PointerY < 12 THEN

BEGIN

Menu (DemoMenu, ReturnCode, Amulet);

PollMouse (PointerX, PointerY, Left, Center, Right);

MoveTo (PointerX, PointerY);

IF ReturnCode <> 0 THEN

CASE ReturnCode OF

25 : Quit := TRUE;

END;

END

ELSE

IF (GetX <> PointerX) OR (GetY <> PointerY) THEN

BEGIN

PointerOff;

LineTo (PointerX, PointerY);

PointerOn

END

END

ELSE

MoveTo (PointerX, PointerY)

UNTIL KeyPressed OR Quit

END.

Capitolul 23

VarDump

(* >>> VarDump <<< -------- ----- ------ --- *)

(* Nume fisier : VARDUMP.SRC *)

(* Rutina afiseaza un vidaj hexazecimal a tuturor *)

(* variabilelor sau constantelor cu tip transmise in *)

(* parametrul VAR fara tip, Target. VarDump apeleaza *)

(* WriteHex; fiti siguri ca WriteHex este disponibil. *)

(* -------- ----- ------ ----- ----- --------- *)

PROCEDURE VarDump ( VAR Device: TEXT; VAR Target; ItSize: INTEGER);

CONST

Printables: SET OF CHAR= [' '..'>'];

VAR

i, j, Full, Left: INTEGER;

DumpIt: ARRAY[0..MaxInt] OF BYTE ABSOLUTE Target;

PROCEDURE DumpLine (Offset, ByteCount: INTEGER);

VAR

i: INTEGER;

BEGIN

FOR i := 0 TO ByteCount - 1 DO

BEGIN

WriteHex (Device, DumpIt ([(Offset * 16) + i]);

Write (device, ' ')

END;

FOR i := 0 TO 56 - (ByteCount * 3) DO Write (Device, ' ');

Write (Device ,'|');

FOR i := 0 TO ByteCount - 1 DO

IF CHR (DumpIt[(Offset * 16) + i]) IN Printables THEN

Write (Device, CHR(DumpIt[(Offset * 16) + i]))

ELSE Write (Device, '.');

Write (Device, '|')

END;

BEGIN

Full := ItSize DIV 16;

Left := ItSize MOD 16;

FOR i := 0 TO Full - 1 DO

DumpLine (i, 16);

IF Left > 0 THEN

DumpLine (Full, Left);

WriteLn (Device)

END;

ShowHelp

(* >>> ShowHelp <<< -------- ----- ------ -- *)

(* Nume fisier : SHOWHELP.SRC *)

(* Rutina reprezinta un sistem simplu de help pe un *)

(* singur ecran. Sistemul asigura salvarea ecranului cu *)

(* informatiile utile, afisarea ecranului cu informatia *)

(* help si restaurarea ecranului initial la apasarea *)

(* unei taste. Dv. trebuie sa inlocuiti informati help *)

(* din ShowHelpData cu ceea ce doriti sa afisati (aici *)

(* este prezentat un exemplu pentru programul JTERM). *)

(* Informatia help se afiseaza atunci cind se apasa *)

(* tasta functionala F1. *)

(* -------- ----- ------ ----- ----- --------- *)

PROCEDURE ShowHelp;

CONST

ScreenX= 80;

ScreenY= 25;

VAR

XSave, YSave: INTEGER;

VideoSeg, VidSegment, VideoBufferSize: WORD;

SavePtr, VideoPtr: ^WORD;

Dummy: CHAR;

FUNCTION Monochrome: BOOLEAN;

VAR

Regs: Registers;

BEGIN

INTR (17, Regs);

IF (Regs.AX AND $0030) = $30 THEN Monochrome := TRUE

ELSE Monochrome := FALSE

END;

PROCEDURE SaveScreenOut;

BEGIN

XSave := WhereX; YSave := WhereY;

VideoBufferSize := ScreenX * ScreenY * 2;

GetMem (SavePtr, VideoBufferSize);

IF Monochrome THEN

VidSegment := $8000

ELSE VidSegment := $8800;

VideoPtr := Ptr (VidSegment, 0);

Move (VideoPtr^, VideoPtr^, VideoBufferSize)

END;

PROCEDURE ShowHelpData;

BEGIN

GoToXY(30, 3); WriteLn('>>>> JTERM <<<<');

Write(' Din COMPLETE TURBO PASCAL 5.0, de Jeff Duntemann');

GoToXY(1,7);

WriteLn('Implicit parametrii de comunicare sint 1200, 8, N, 1');

WriteLn('Puteti folosi JTERM la 300 boud prin urmatorul apel :');

WriteLn; WriteLn(' C:\>Jterm 300'); WriteLn;

WriteLn('In mod curent comenzile active sint :'); WriteLn;

WriteLn(' F1: Afisarea acestui ecran help');

WriteLn(' Ctrl-Z: Stergerea ecranului');

WriteLn(' Ctrl-X: Retine si termina JTERM');

END;

PROCEDURE BringScreenBack;

BEGIN

Move (SavePtr^, VideoPtr^, VideoBufferSize);

FreeMem (SavePtr, VideoBufferSize);

GoToXY (XSave, YSave)

END;

BEGIN

SaveScreenOut; ClrScr; ShowHelpData;

GoToXY (20, 23); Write ('Apasati orice tasta pentru continuare ...');

REPEAT UNTIL KeyPressed;

Dummy := ReadKey;

IF Dummy = CHR (0) THEN Dummy := ReadKey;

BringScreenBack

END;

Binary

(* >>> BinaryDemo <<< ----- ----- --------- ----- -------- *)

(* Nume fisier : BITTEST.PAS *)

(* Program demonstrativ - testari binare. *)

(* -------- ----- ------ ----- ----- -------- *)

PROGRAM BinaryDemo;

VAR

i, j: INTEGER;

FUNCTION TestBit (VAR Target; BitNum: INTEGER): BOOLEAN;

VAR

Subject: INTEGER ABSOLUTE Target;

Dummy: INTEGER;

BEGIN

Dummy := Subject;

Dummy := Dummy SHR BitNum;

IF ODD (Dummy) THEN TestBit := TRUE ELSE TestBit := FALSE

END;

BEGIN

REPEAT

Write('>> Introduceti un intreg (0 pentru iesire) : '); ReadLn(i);

FOR j := 15 DOWNTO 0 DO

IF TestBit(i, j) THEN Write ('1') ELSE Write('0');

WriteLn; WriteLn

UNTIL i = 0

END.

WriteHex

(* >>> WriteHex <<< -------- ----- ------ - *)

(* Nume fisier : WRITEHEX.SRC *)

(* Rutina asigura scrierea hexazecimala a datelor. *)

(* -------- ----- ------ ----- ----- -------- *)

PROCEDURE WriteHex (VAR Device: TEXT; BT: BYTE);

CONST

HexDigits: ARRAY[0..15] OF CHAR ='0123456789ABCDEF';

VAR

BZ: BYTE;

BEGIN

BZ := BT AND $0F;

BT := BT SHR 4;

Write (Device, HexDigits[BT], HexDigits[BZ])

END;

SoftTest

(* >>> SoftIntTest <<< ----- ----- --------- ----- ----- *)

(* Nume fisier : SOFTINT.PAS *)

(* Programul demonstrativ pentru rutinele soft de *)

(* deservire a intreruperilor. *)

(* -------- ----- ------ ----- ----- ------ *)

PROGRAM SoftIntTest;

USES DOS, CRT;

VAR

Foo: WORD;

Regs: Registers;

OldVector: Pointer;

PROCEDURE EnableInterrupts;

INLINE ($F8);

PROCEDURE SoftISR (Fings, CS, IP, AX, BX, CX, DX, SI, DS, ES, BP: WORD);

INTERRUPT;

BEGIN

EnableInterrupts;

Foo := AX;

BX := 17

END;

PROCEDURE OurExitProc;

BEGIN

SetIntVec (76, OldVector)

END;

BEGIN

ExitProc := @OurExitProc;

Foo := 0;

ClrScr;

GetIntVec (76, OldVector);

SetIntVec (76, @SoftISR);

Regs.AX := 42;

Regs.BX := 0;

Intr (76, Regs);

WriteLn ('Foo = ', Foo);

WriteLn ('BX = ', Regs.BX);

ReadLn

END.

JTerm

(* >>> JTerm <<< -------- ----- ------ ----- *)

(* Nume fisier : JTERM.PAS *)

(* Programul dirijeaza intreruperile unui "terminal *)

(* mut" pentru PC. Se ilustreaza utilizarea rutinelor *)

(* INTERRUPT din Turbo Pascal, si un mod simplificat de *)

(* utilizare a portului serial al echipamentului. *)

(* -------- ----- ------ ----- ----- --------- *)

PROGRAM JTerm;

USES DOS, CRT;

CONST

Com1Int= 12;

RBR= $3F8;

THR= $3F8;

LCR= $3F8;

IER= $3F9;

MCR= $3FC;

LSR= $3FD;

DLL= $3F8;

DLM= $3F9;

DLAB= $80;

BAUD300= 384;

BAUD1200= 96;

NOPARITY= 0;

BITS8= $03;

DTR= $01;

RTS= $02;

OUT2= $08;

DCW1= $21;

DCW2= $20;

IRQ4= $10;

TYPE

CircularBuffer= ARRAY[0..1023] OF CHAR;

VAR

Quit,

HiBaud: BOOLEAN;

KeyChar,

CommChar: CHAR;

Divisor: WORD;

ClearIt: BYTE;

Buffer: CircularBuffer;

LastRead,

LastSaved: INTEGER;

NoShow: SET OF CHAR;

OldVector: POINTER;

PROCEDURE EnableInterrupts;

INLINE ($F8);

PROCEDURE Incoming (Flags, CS, IP, AX, BX, CX¬ DX, SI, DI, DS, ES,SP: WORD);

INTERRUPT;

BEGIN

EnableInterrupts;

IF LastSaved >= 1023 THEN LastSaved := 0

ELSE INC (LastSaved);

Buffer [LastSaved] := CHAR (Port [RBR]);

Port [DCW2] := $20

END;

PROCEDURE JTermExitProc;

BEGIN

Port[IER] := 0;

Port[DCW1] := Port[DCW1] OR IRQ4;

Port[MCR] := 0;

SetIntVec (Com1Int, OldVector)

END;

PROCEDURE SetupSerialPort;

BEGIN

LastRead := 0; LastSaved := 0;

Port[IER] := 0;

GetIntVec (Com1Int, OldVector);

ExitProc := @JTermExitProc;

SetIntVec (Com1Int, @Incoming);

Port[LCR] := Port[LCR] OR DLAB;

Port[DLL] := Lo (Divisor);

Port[DLM] := Hi (Divisor);

Port[LCR] := BITS8 OR NOPARITY;

Port[MCR] := DTR OR RTS OR OUT2;

ClearIt := Port[RBR];

ClearIt := Port[LSR];

Port[IER] := $01

END;

S FUNCTION InStat: BOOLEAN;

BEGIN

IF LastSaved <> LastRead THEN InStat := TRUE

ELSE InStat := FALSE

END;

FUNCTION InChar: CHAR;

(* -------- ----- ------ ----- ----- --------- *)

(* Rutina returneaza ultimul caracter din bufferul *)

(* circular. *)

(* -------- ----- ------ ----- ----- --------- *)

BEGIN

IF LastRead >= 1023 THEN LastRead := 0

ELSE LastRead := SUCC (LastRead);

InChar := Buffer[LastRead]

END;

PROCEDURE OutChar (Ch: CHAR);

(* ----­ Rutina transmite un caracter la portul "comm". ----- *)

BEGIN

Port[THR] := BYTE (Ch)

END;

BEGIN

HiBaud := TRUE;

Divisor := BAUD1200;

IF ParamCount > 0 THEN

IF ParamStr(1) = '300' THEN

BEGIN

HiBaud := FALSE;

Divisor := BAUD300

END;

DirectVideo := TRUE;

NoShow := [#0, #127];

SetupSerialPort;

ClrScr;

WriteLn ('>>> JTERM by Jeff Duntemann');

Quit := FALSE;

REPEAT

IF InStat THEN

BEGIN

CommChar := InChar;

CommChar := CHAR (BYTE (CommChar) AND $7F);

IF NOT (CommChar IN NoShow) THEN

Write (CommChar)

END;

IF KeyPressed THEN

BEGIN

KeyChar := ReadKey;

IF KeyChar = CHR (0) THEN

BEGIN

KeyChar := ReadKey;

CASE ORD (KeyChar) OF

59: ShowHelp;

END

END

ELSE

CASE ORD (KeyChar) OF

24: Quit := TRUE;

26: ClrScr;

ELSE OutChar (KeyChar)

END

END

UNTIL Quit

END.

Searcher

(* >>> Searcher <<< -------- ----- ------ -- *)

(* Nume fisier : SEARCHER.PAS *)

(* Unit-ul contine rutine de cautare in directoare. *)

(* -------- ----- ------ ----- ----- --------- *)

UNIT Searcher;

INTERFACE

USES DOS;

TYPE

HitProc= PROCEDURE (Found: SearchRec; inDirectory:STRING);

PROCEDURE SearchAll (Directory: STRING; Spec: STRING;

Attribute: BYTE; Doit: HitProc);

PROCEDURE SearchOne (Directory: STRING; Spec: STRING;

Attribute: BYTE; Doit: HitProc);

PROCEDURE SearchCurrent (Spec: STRING; Attribute: BYTE; Doit: HitProc);

IMPLEMENTATION

PROCEDURE SearchAll (Directory: STRING; Spec: STRING;

Attribute: BYTE; Doit: HitProc);

(* -------- ----- ------ ----- ----- -------------- *)

(* Rutina este o "masina" de cautare ce parcurge intregul *)

(* arbore al directorului DOS din volumul de disc curent, *)

(* analizind fisierele ce corespund specificatorului Spec si *)

(* au atributele Attribute. Daca se gaseste fisierul cauta, *)

(* atunci DTA fisierului gasit este transmis parametrului *)

(* procedural, care apoi executa o anumita actiune folosind *)

(* informatia din DTA. *)

(* Logica de baza a utilizarii FIND FIRST si FIND NEXT *)

(* este aproape identica cu cea din programul LOCATE.PAS, cu *)

(* deosebirea ca LOCATE.PAS numai afiseaza informatia din *)

(* fisierele gasite. Transmitind diferite proceduri in *)

(* HitProc este posibil sa se execute orice actiune cu un *)

(* fisier gasit. *)

(* -------- ----- ------ ----- ----- -------------- *)

VAR

CurrentDTA: SearchRec;

TempDirectory, NextDirectory: STRING;

BEGIN

IF Directory = '\' THEN TempDirectory := Directory + '*.*'

ELSE TempDirectory := Directory + '\*.*';

FindFirst (TempDirectory, $10, CurrentDTA);

WHILE (DOSError <> 2) AND (DOSError <> 18) DO

BEGIN

IF ((CurrentDTA.Attr AND $10) = $10)

AND (CurrentDTA.Name[1] <> '.') THEN

BEGIN

IF Directory <> '\' THEN NextDirectory := Directory + '\'

ELSE NextDirectory := Directory;

NextDirectory := NextDirectory + CurrentDTA.Name;

SearchAll (NextDirectory, Spec, Attribute, Doit)

END;

FindNext (CurrentDTA)

END;

IF Directory = '\' THEN TempDirectory := Directory + '\' + Spec

ELSE TempDirectory := Directory + Spec;

FindFirst (TempDirectory, Attribute, CurrentDTA);

IF DOSError = 3 THEN

WriteLn ('Calea nu a fost gasita; verifica ortografia.')

ELSE

IF (DOSError = 2) OR (DOSError = 18) THEN

ELSE

BEGIN

Doit (CurrentDTA, Directory);

IF DOSError <> 18 THEN

REPEAT

FindNext (CurrentDTA);

IF DOSError <> 18 THEN Doit (CurrentDTA, Directory)

UNTIL (DOSError = 18) OR (DOSError = 2)

END

END;

PROCEDURE SearchOne (Directory: STRING; Spec: STRING;

Attribute: BYTE; Doit: HitProc);

(* -------- ----- ------ ----- ----- ---------- *)

(* Aceasta procedura reprezinta un subset al rutinei *)

(* SearchAll. Ea cauta numai in directorul specificat in *)

(* Directory, si nu in intreg arborele. *)

(* -------- ----- ------ ----- ----- ---------- *)

VAR

TempDirectory: STRING;

CurrentDTA: SearchRec;

BEGIN

IF Directory = '\' THEN TempDirectory := Directory + '\' + Spec

ELSE TempDirectory := Directory + Spec;

FindFirst (TempDirectory, Attribute, CurrentDTA);

IF DOSError = 3 THEN

WriteLn ('Calea nu a fost gasita; verifica ortografia.')

ELSE

IF (DOSError = 2) OR (DOSError = 18) THEN

ELSE

BEGIN

Doit (CurrentDTA, Directory);

IF DOSError <> 18 THEN

REPEAT

FindNext (CurrentDTA);

IF DOSError <> 18 THEN

Doit (CurrentDTA, Directory)

UNTIL (DOSError = 18) OR (DOSError = 2)

END

END;

PROCEDURE SearchCurrent (Spec: STRING; Attribute: BYTE; Doit: HitProc);

(* ---- Rutina executa cautarea numai in directorul curent® ---- *)

VAR

Directory: STRING;

BEGIN

GetDir (0, Directory);

SearchOne (Directory, Spec, Attribute, Doit)

END;

END.

Tally

(* >>> Tally <<< -------- ----- ------ -------- *)

(* Nume fisier : TALLY.PAS *)

(* Utilitar pentru identificarea dimensiunii fiserelor. *)

(* -------- ----- ------ ----- ----- ------------ *)

PROGRAM Tally;

USES DOS, Searcher;

VAR

i: INTEGER;

Total: LONGINT;

SearchSpec, InitialDirectory: STRING;

PROCEDURE Tallier (Foundit: SearchRec; inDirectory: STRING);

(* ----- Rutina cumuleaza dimensiunea fiecarui fisier gasit

in directorul specificat. ----­ *)

BEGIN

IF inDirectory = '\' THEN WriteLn (inDirectory, Foundit.Name)

ELSE WriteLn (inDirectory, '\', Foundit.Name);

Total := Total + Foundit.Size

END;

BEGIN

IF ParamCount = 0 THEN

BEGIN

WriteLn('>>> TALLY <<< V1.00 de Jeff Duntemann');

WriteLn(' din cartea COMPLETE TURBO PASCAL 5.0'); Writeln;

WriteLn (' Programul cauta toate fisierele care corespund');

WriteLn ('specificatorului indicat, afiseaza calea completa');

WriteLn ('si determina spatiul disc ocupat de acestea.'); WriteLn;

WriteLn (' Sintaxa apelului :'); WriteLn;

WriteLn ('TALLY <specificator-fisier>'); WriteLn

END

ELSE

BEGIN Total := 0; WriteLn; SearchSpec := ParamStr(1);

IF POS ('\', SearchSpec) = 0 THEN InitialDirectory := '\'

ELSE

BEGIN

i := LENGTH (SearchSpec);

WHILE SearchSpec[i] <> '\' DÏ i := PRED (i);

InitialDirectory := COPY(SearchSpec, 1, i - 1);

Delete(SearchSpec, 1, i)

END;

SearchAll (InitialDirectory, SearchSpec, 0, Tallier);

WriteLn ('Fisierele listate ocupa ', Total, ' octeti pe disc.')

END

END.

Capitolul 24

87There

(* >>> Is87There <<< -------- ----- ------ ---- *)

(* Nume fisier : 87THERE.SRC *)

(* Rutina detecteaza prezenta coprocesorului 8087. *)

(* -------- ----- ------ ----- ----- ------------ *)

FUNCTION Is87There: BOOLEAN;

VAR

ControlWord: WORD;

BEGIN

ControlWord := 0;

INLINE

($90/$08/$E3/

$90/$09/$7E/<ControlWord);

IF Hi (ControlWord) = 0 THEN

Is87There := FALSE

ELSE

Is87There := TRUE

END;

Look1

(* >>> Look1 <<< -------- ----- ------ --------- *)

(* Nume fisier : LOOK1.PAS *)

(* Programul goleste stiva inainte de invocarea unei *)

(* functii. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM Look1;

TYPE

String30= STRING[30];

IntArray= ARRAY[0..99] OF INTEGER;

VAR

Ok: BOOLEAN;

Before, After, Register: WORD;

StackMarker: POINTER;

MyArray: IntArray;

FUNCTION Dummy (VAR Values: IntArray; Fudge: INTEGER;

Level, Clearence: CHAR; Message: String30): BOOLEAN;

VAR

Grade, Cutoff: CHAR;

BEGIN

INLINE ($90/$90/$90/$90);

INLINE ($88/$25/$A3/Register);

After := Register;

StackMarker := Ptr (SSeg, Register);

VarDump (Output, StackMarker^, Trunc (Before - After))

END;

BEGIN

INLINE ($88/$C4/$A3/Register);

Before := Register;

Ok := Dummy (MyArray, 42, 'Q', 'Z', 'I was burn on a pirate ship. ')

END.

Look2

(* >>> Look2 <<< -------- ----- ------ --------- *)

(* Nume fisier : LOOK2.PAS *)

(* Program demonstrativ - vidarea stivei inainte si dupa *)

(* pozitionarea poineterului stivei. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM Look2;

TYPE

String30= STRING[30];

IntArray= ARRAY[0..9] OF INTEGER;

VAR

Ok: BOOLEAN;

Before, After, Register: WORD;

StackMarker: POINTER;

MyArray: IntArray;

FUNCTION Dummy (VAR Values:IntArray; Fudge: INTEGER;

Level, Clearence: CHAR; Message: String30): BOOLEAN;

BEGIN

INLINE ($88/$C4/$A3/Register);

After := Register;

StackMarker := Ptr (SSeg, Register);

WriteLn ('Inainte modificarii rezultatelor sau a variabilelor locale :');

VarDump (Output, StackMarker^, Trunc (Before - After);

Dummy := FALSE;

Grade := 'A';

Cutoff := 'C';

WriteLn ('Dupa modificarea rezultatelor sau a variabilelor locale :');

VarDump (Output, StackMarker^, Trunc (Before - After)

END;

BEGIN

INLINE ($88/$C4/$A3/Register);

Before := Register; WriteLn ('Continutul stivei :');

Ok := Dummy (MyArray, 42, 'Q','Z', 'I was born on a pirate ship. ')

END.

MovLocal

(* >>> MOVLocal <<< -------- ----- ------ ------ *)

(* Nume fisier : MOVLOCAL.PAS *)

(* Program demonstrativ - mutarea variabilelor locale. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM MOVLocal;

USES CRT;

PROCEDURE Foo;

VAR Fee, Fie: INTEGER;

BEGIN

Fee := 0; Fie := 0; INLINE ($B8/$11/00);

INLINE ($89/$86/Fee);

WriteLn ('Fee = ', Fee); ReadLn; INLINE ($8B/$9E/Fee);

INLINE ($89/$9E/Fie);

WriteLn ('Fie = ', Fie); ReadLn

END;

BEGIN

ClrScr; Foo

END.

MovParameter

(* >>> MOVParameter <<< -------- ----- ------ -- *)

(* Nume fisier : MOVPARAM.PAS *)

(* Program demonstrativ - mutarea parametrilor. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM MOVParameter;

USES CRT;

PROCEDURE Foo (Foe, Fum: INTEGER);

VAR

Fee, Fie: INTEGER;

BEGIN

Fee := 0; Fie := 0; WriteLn ('Fum = ', Fum);

INLINE ($8B/$8E/Foe);

INLINE ($89/$8E/Fee);

WriteLn ('Fee = ', Fee); ReadLn;

INLINE ($8B/$96/Fee);

INLINE ($89/$96/Fum);

WriteLn ('Fum = ', Fum); ReadLn

END;

BEGIN

ClrScr; Foo (42, 17)

END.

VARParamINLINE

(* >>> VARParmINLINE <<< -------- ----- ------ - *)

(* Nume fisier : MVPARMIN.PAS *)

(* Program demonstrativ - utilizarea instructiunii LES *)

(* (Load Pointer Using ES) in INLINE. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM VARParmINLINE;

USES CRT;

VAR

Flarf: INTEGER;

PROCEDURE Foo (VAR Fum: INTEGER);

BEGIN

INLINE ($C4/$BE/Fum);

INLINE ($BA/$71/$00);

INLINE ($26/$89/$15)

END;

BEGIN

ClrScr; Flarf := 0; Foo (Flarf);

WriteLn ('Flarf = ', Flarf); ReadLn

END.

FastIncrement

(* >>> FastIncrement <<< -------- ----- ------ - *)

(* Nume fisier : FASTINX.PAS *)

(* Program demonstrativ - lucru cu parametrii variabile. *)

(* -------- ----- ------ ----- ----- ------------- *)

PROGRAM FastIncrement;

USES CRT;

TYPE

IntArray= ARRAY[0..16000] OF INTEGER;

VAR

I: INTEGER;

Scores: IntArray;

PROCEDURE Increment (VAR Scores: IntArray;

ByHowMuch: INTEGER);

BEGIN

INLINE ($C4/$BE/Scores/

$89/$80/$3E/

$8B/$9E/ByHowMuch/

$26/$01/$1D/

$47/

$47/

$E2/$FA);

END;

BEGIN

ClrScr;

FillChar (Scores, SizeOf (Scores), Chr (0));

FOR I := 0 TO 10 DO

WriteLn (Scores[I]);

Readln;

Increment (Scores, 72);

FOR I := 0 TO 10 DO

WriteLn (Scores[I]);

ReadLn

END.

PointerINLINE

(* >>> PointerINLINE <<< -------- ----- ------ -- *)

(* Nume fisier : PTRINLN.PAS *)

(* Program demonstrativ - variabile dinamice cu INLINE. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM PointerINLINE;

USES CRT;

TYPE IntPtr= ^INTEGER;

VAR MyPtr: IntPtr;

BEGIN

ClrScr; New (MyPtr); MyPtr^ := 42;

WriteLn('Inainte : ', MyPtr^);

INLINE($C4/$3E/MyPtr/

$26/$80/$05/$03);

WriteLn ('Dupa : ', MyPtr^);

ReadLn

END.

CodeMark

(* >>> CodeMark <<< -------- ----- ------ ------- *)

(* Nume fisier : CODEMARK.SRC *)

(* Rutina este un macro INLINE care furnizeaza un pointer *)

(* catre codul urmatoarei instructiuni. Acest pointer poate *)

(* fi transmis catre VarDump pentru a afisa a zona de cod. *)

(* -------- ----- ------ ----- ----- -------------- *)

FUNCTION CodeMark: POINTER;

INLINE ($8C/$CA/

$E8/$00/$00/

$58/

$05/$0B/$00);

Boiler

; B O I L E R - Boilerplate external assembly language source file

; Boiler se apeleaza din programe Turbo Pascal folosind conventia

; de procedura /EXTERNAL

; Declararea procedurii insasi ca externa in program se realizeaza astfel :

;

; PROCEDURE Boiler; EXTERNAL;

; Pentru reasamblare/relinkeditare BOILER se foloseste MASM sau TASM :

; C>TASM BOILER

CODE SEGMENT BYTE PUBLIC

ASSUME CS:CODE

PUBLIC BOILER

BOILER PROC NEAR

PUSH BP ; Salvarea valorii anterioare a lui BP in stiva

MOV BP, SP ; SP devine noua valoare a lui BP

; Corpul procesului dv. incepe aici ...

MOV SP, BP ; Restaurarea pointerului stivei

POP BP

RET

BOILER ENDP

CODE ENDS

END

Clears

; C L E A R S - primitiva pentru stergerea ecranului in Turbo Pascal

; Rutina CLEARS se apeleaza folosind conventiile de apelare a procedurilor

; externe - /EXTERNAL.

; Avantajul acestei rutine fata de ClrScr consta in faptul ca ea poate

; sterge un ecran memorat in heap si poate sterge ecranul cu un caracter

; diferit de spatiu. In bufferul de sters se poate scrie un atribut ca un

; caracter de stergere.

; Pentru a folosi CLEARS pe un ecran vizibil, trebuie sa declarati un

; pointer care sa refere bufferul grafic sau text :

; VAR

; VisibileScreen: POINTER;

; VisibileScreen := Ptr ($8000, 0);

; VisibileScreen := Ptr ($8800, 0);

; Declararea procedurii insasi se realizeaza astfel :

; PROCEDURE CLEARS (Target: POINTER; ScreenSize: INTEGER;

; Attribute: INTEGER; CharFill: BYTE);

; EXTERNAL;

; Transmiteti lui CLEARS codul atributului pe care doriti sa-l folositi

; in Attribute (in mod normal $0700 pentru display text "normal") si

; caracterul pentru "sters" in CharFill. Folositi 32 sau Ord(' ') pentru

; spatii sau caracterele "halftone" (176-178) pentru ecrane in stil

; Framework. Retineti ca, codul atributului trebuie sa fie in octetul HIGH

; in parametrul actual transmis lui Attribute.

; Exemple :

; Stergerea ecranului vizibil cu spatii :

; Clears (VisibleScreen, 4096, $0700, ' ');

; Stergerea unui ecran din heap :

; Clears (NewScreen, 4096, $0700, 176);

; Desigur, trebuie sa declarati VisibleScreen si NewScreen si sa le

; stabiliti sa refere fie ecranul din heap fie bufferul ecranului vizibil.

CODE SEGMENT BYTE PUBLIC

ASSUME CS:CODE

PUBLIC CLEARS

; Structura stivei

ONSTACK STRUC

OLDBP DW ? ; BP apelantului este salvat in stiva

RETADDR DW ? ; Adresa cea mai recenta de revenire

FILLER DW ? ; Caracterul care umple bufferul de sters

ATTRIB DW ? ; Atributul bufferului de sters

BUFSIZE DW ? ; Dimensiunea, in octeti, a bufferului de sters

BUFOFS DW ? ; Originea de start a bufferului

BUFSEG DW ? ; Originea segmentului bufferului

ENDMARK DB ? ; Eticheta fictiva ptr. a marca sfirsitul datelor din stiva

ONSTACK ENDS

CLEARS PROC NEAR

PUSH BP

MOV BP, SP ; Conventia de apelare

; In primul rind se testeaza pentru buffer = NIL ... iesire daca este asa

START: CLD ; Stergerea indicatorilor de directie

MOV AX, [BP].ATTRIB ; Incarca codul atributului in AX

AND AX, 0FF00H ; Mascarea octetului inferior al codului atributului

MOV BX, [BP].FILLER ; Incarca codul de umplere in BX

AND BX, 0FFH ; Mascarea octetului superior al codului de umplere

OR AX, BX ; Si combina ATTRIB & FILLER in AX

MOV BX, [BP].BUFOFS ; Stabileste DI pentru bufferul TARGET

MOV DI, BX

MOV BX, [BP].BUFSEG

MOV ES, BX

; Ciclare pentru inregistrarea caracterului si a atributului in buffer

MOV CX, [BP].BUFSIZE ; Setarea contorului

REP STOSW ; Executa memorarea sirului

; Curatirea stivei si iesire

BYE: MOV SP, BP ; Restaurarea valoriloe anterioare

POP SP

RET ENDMARK-RETADDR-2

CLEARS ENDP

CODE ENDS

END

Stick

; S T I C K - intrare joystick, in limbaj de asamblare, pentru Turbo Pascal

; STICK se apeleaza folosind conventia de apelarea procedurilor externe :

; /EXTERNAL.

; Declararea procedurii insasi se realizeaza astfel :

;

; PROCEDURE STICK (StickNumber: INTEGER;

; VAR X, Y: INTEGER); EXTERNAL;

; StickNumber specifica care din joystick-uri se citeste, iar X si Y sint

; parametrii ce returneaza intregi proportionali cu pozitia joystick-ului.

; Acesti intregi difera de la stick la stick in functie de rezistenta

; potentiometrelor folosite in stick, dar in mod obisnuit sint cuprinsi

; intre 3 si 150.

; Placa IBM standard pentru controlul jocului se compune din doua manete

; (one-shots), care transmit un impuls la portul $201 de I/O. Durata acestui

; impuls depinde de constanta RC a portiunii de rezistenta a potentiometrului

; joystick-ului.

; Pentru citirea unuia din cele doua joystick-uri, o valoare fictiva este

; scrisa in portul $201 de I/O. Portul $201 trebuie apoi testat continuu,

; incrementind un registru la fisecare eveniment. Atunci cind bitul care

; corespunde coordonatelor X sau Y ale joystick-ului isi modifica starea,

; valoarea din registru este returnata drept valoare a coordonatelor

; stick-ului care a fost manevrat.

; Configuratia de biti ai joystick-ului returnati portului $201 este :

; |7 6 5 4 3 2 1 0|

; | | | |______ coordonata X, joystick #1

; | | |________ coordonata Y, joystick #1

; | |__________ coordonata X, joystick #2

; |____________ coordonata Y, joystick #2

; Urmatoareá structura defineste planul parametrilor unui stick :

ONSTACK STRUC

OLDSP DW ? ; Virful stivei

RETADDR DD ? ; Adresa indepartata de revenire

YADDR DD ? ; Adresa indepartata a valorii Y

XADDR DD ? ; Adresa indepartata a valorii X

STIK_NO DW ? ; Numarul stic-ului

ONSTACK ENDS

CODE SEGMENT PUBLIC

ASSUME CS:CODE

PUBLIC STICK

STICK_X EQU 1

STICK_Y EQU 2

STICK PROC FAR

PUSH BP ; Salvarea BP al apelantului

MOV BP, SP ; Pointerul stivei devine noul BP

PUSH DS

; Citirea valorii axei X

MOV AH, STICK_X ; Mutarea bitilor de testat

CMP [BP].STIK_NO, 2 ; Se verifica daca este stic-ul #1 sau #2

JNE TEST_X

SHL AH, 1 ; Se decaleaza stinga pentru stick-ul #2

SHL AH, 1

TEST_X: MOV AL, 1 ; Initializarea valorii de iesire

MOV DX, 201H ; Stabilirea adresei portului

MOV BX, 0 ; si pastrarea valorii de executie in BX

MOV CX, BX ; Stabileste limita maxima a ciclului la 64K

OUT DX, AL ; Testarea unei manete

AGAIN_X: IN AL, DX ; Citeste bitii unei manete

TEST AL, AH ; Testeaza bitul 0 superior

JE DELAY ; Salt daca bitul 0 este superior

INC BX ; Altfel incrementeaza BX si cicleaza din nou

LOOP AGAIN_X

MOV BX, -1 ; Seteaza X=-1 dacu nu exista raspuns

; Intirziere pentru maxim trei impulsuri de iesire

DELAY: MOV CX, 512

WAIT: LOOP WAIT

; Citirea valorii axei Y

MOV AH, STICK_Y

CMP [BP].STIK_NO, 2

JNE TEST_Y

SHL AH, 1

SHL AH, 1

TEST_Y: MOV SI, 0

MOV CX, SI

OUT DX, AL

AGAIN_Y: IN AL, DX

TEST AL, AH

JE DONE

INC SI

LOOP AGAIN_Y

MOV SI, -1

; Mutarea valorilor returnate din registre in parametrii VAR X si Y

DONE: LOS DI, [BP].XADDR ; Adresa lui X in DS:DI

MOV [DI], BX ; Valoarea lui X din BX in DS:DI

LOS DI, [BP].YADDR ; Adresa lui Y in DS:DI

MOV [DI], SI ; Valoarea lui Y din SI in DS:DI

; Acesta este totul ... Acum se sterge stiva si se revine in apelant

POP DS

MOV SP, BP

POP BP

RET 10

STICK ENDP

CODE ENDS

END

StrPlate

; S T R P L A T E - Boilerplate string external function

; STRPLATE se apeleaza folosind conventiile pentru proceduri EXTERNAL :

:

; FUNCTION STRPLATE (Source: STRING): STRING;

EXTERNAL;

PHYSLEN EQU 255

ONSTACK STRUC

OLDBP DW ? ; Valoarea BP a apelantului

RETADDR DW ? ; Adresa de revenire

PARMPTR DD ? ; Pointer catre parametrul sir

FUNCPTR DD ? ; Pointer catre zona cuvint a rezultatului functiei

ONSTACK ENDS

CODE SEGMENT BYTE PUBLIC

ASSUME CS:CODE

PUBLIC STRPLATE

STRPLATE PROC NEAR ; Apel indepartat daca procedura este intr-un unit

PUSH BP ; Salvarea valorii BP anterioare in stiva

MOV BP, SP ; SP devine noua valoare a lui BP

; Intre cele doua linii intrerupte se introduce

; functia proprie de operarea asupra sirului

; Spre exemplu, operatia de copiere a parametrului in rezultatul functiei :

PUSH DS ; Salvare DS aplelant

LDS SI, [BP].PARMPTR ; Mutare adresa parametru in DS:DI

LES DI, [BP].FUNCPTR ; Mutare adresa rezultat functie in ES:DI

MOV CX, PHYSLEN + 1 ; Numarul octetilor de mutat

CLD ; Setare indicator directie autoincrementare

REPZ MOVSB ; Executarea mutarii blocului

POP DS ; Restaurarea valorii DS al apelantului

MOV SP, BP ; Restaurarea pointerului stivei apelantului

POP BP ; Restaurarea pointerului de baza apelant

RET FUNCPTR - RETADDR - 2 ; Stergerea stivei si revenire

STRPLATE ENDP

CODE ENDS

END

Button

; B U T T O N - Functia returneaza starea butoanelor joystick-ului

; Declararea procedurii :

;

; FUNTION BUTTON (StickNumber, ButtonNumber: INTEGER): BOOLEAN;

EXTERNAL;

; StckNumber spacifica care din joystick se citeste, iar ButtonNumber indica

; care din butoanele joystick-ului se citeste. Daca butonul specificat este

; actionat, BUTTON returneaza valoarea TRUE.

; Informatia se obtine prin citirea portului o201 de I/O. Primii patru biti

; superiori reprezinta starea celor patru butoane (cite doi pantru cele doua

; joystick-uri posibile). Bitul inferior reprezinta un buton apasat.

; Structura bitilor returnati de portul $201 este :

; |7 6 5 4 3 2 1 0|

; | | | |

; | | | |_______________ Buton #1, joystick #1

; | | |_________________ Buton #2, joystick #1

; | |___________________ Buton #1, joystick #2

; |_____ _______ ______ ______ Buton #2, joystick #

; Retineti faptul ca valoarea returnata de functie este transmita codului

; rutinei in registrul AL.

ONSTACK STRUC

OLDBP DW ? ; Virful stivei

RETADDR DD ? ; Adresa indepartata de revenire

BTN_NO DW ? ; Numarul butonului

STIK_NO DW ? ; Numarul joystick-ului

ONSTACK ENDS

CODE SEGMENT BYTE PUBLIC

ASSUME CS:CODE

PUBLIC BUTTON

BUTTON PROC FAR

PUSH BP ; Salvarea in stiva a valorii anterioare a lui BP

MOV BP, SP ; SP devine noul BP

; Cea mai mare parte a rutinei stabileste masca de testare pentru

; fiecare din cei patru biti testati.

MOV BL, 010H ; Se incepe cu bitul 4

CMP [BP].STIK_NO, 2 ; Se testeaza ptr. joystick-ul 2 ?

JNE WHICH ; Daca nu, se trece la WHICH

SHL BL, 1 ; altfel se deplaseaza cu 2 spre stinga

SHL BL, 1 ; astfel ca sa se ajunga pe bitul 6

WHICH: CMP [BP].BTN_NO, 2 ; Se testeaza butonul 2 ?

JNE READEN ; Daca nu, masca e corecta; citeste portul

SHL BL, 1 ; altfel, deplaseaza un bit la stg ptr btn 2

; Masca bitului este acum corecta. Bitii butonului sint cititi din portul

; $201 si testati impreuna cu masca. De notat faptul ca bitii cititi din

; port trebuie sa fie inversati astfel incit indicatorul Z sa fie setat in

; loc sa fie sters biyul butonului activ.

READEN: MOV DX, 0201h ; Setarea adresei portului citit

IN AL, DX ; Citirea bitilor butoanelor din portul $201

NOT AL ; Inversare biti pentru sensul corespunzator

; al indicatorului Z dupa testare

TEST AL, BL ; Se verifica daca bitul este "superior"

JNZ PUSHED ; Daca este asa, butonul este apasat;

MOV AL, 0 ; Altfel muta FALSE in AL

JMP DONE ; si se merge la iesire

PUSHED: MOV AL, 1 ; Buton apasat; muta TRUE in AL

DONE: MOV SP, BP ; Restaurare SP & BP anterior

POP SP

RET 6

BUTTON ENDP

CODE ENDS

END

GameTest

(* >>> GameTest <<< -------- ----- ------ ------- *)

(* Nume fisier : GAMETEST.PAS *)

(* Program demonstrativ - cod masina pentru joystick. *)

(* -------- ----- ------ ----- ----- -------------- *)

PROGRAM GameTest;

USE CRT, Gamebord;

VAR

X, Y: INTEGER;

BEGIN

ClrScr; X := 0; Y := 0;

GoToXY (2, 9); WriteLn ('Axa X Axa Y');

WHILE NOT KeyPressed DO

BEGIN

GoToXY (1, 5);

IF Button (2, 1) THEN WriteLn ('Buton 1 apasat')

ELSE WriteLn ('Nimic pe 1 ....');

IF Button (2, 2) THEN WriteLn ('Buton 2 apasat')

ELSE WriteLn ('Nimic pe 2 ....');

Stick (2, X, Y); GoToXY (1, 10); WriteLn (X:5, ' ', Y:5)

END

END.

GameBord

(* >>> GameBord <<< -------- ----- ------ -------- *)

(* Nume fisier : GAMEBORD.PAS *)

(* Biblioteca contine rutine in limbaj de asamblare pentru *)

(* citirea oricarui din cele doua joystick-uri si a butoanelor*)

(* asociate lor. *)

(* -------- ----- ------ ----- ----- --------------- *)

UNIT GameBord;

INTERFACE

FUNCTION Button (StickNumber, ButtonNumber: INTEGER): BOOLEAN;

PROCEDURE Stick (StickNumber: INTEGER; VAR X, Y: INTEGER);

IMPLEMANTATION

FUNCTION Button (StickNumber, ButtonNumber: INTEGER): BOOLEAN; EXTERNAL;

PROCEDURE Stick (StickNumber: INTEGER; VAR X, Y: INTEGER; EXTERNAL;

END.

Gamer

; G A M E R - suportul in limbaj de asamblare pentru joystick

; GAMER este un simplu fisier sursa limbaj asamblare care contine rutinele

; STICK.ASM si BUTTON.ASM. Scopul lui GAMER este de a prezenta cum se pot

; combinar mai multe rutine in limbaj de asamblare intr-un singur modul cod

; masina.

CODE SEGMENT BYTE PUBLIC ; Segmentul este aliniat la octet

ASSUME CS:CODE

PUBLIC BUTTON, STICK ; Cele doua proceduri accesibile din modul

; B U T T O N - Functia returneaza starea butoanelor joystick-ului

; Antetul complet al procedurii :

; FUNTION BUTTON (StickNumber, ButtonNumber: INTEGER): BOOLEAN;

; StickNumber spacifica care din joystick se citeste, iar ButtonNumber indica

; care din butoanele joystick-ului se citeste. Daca butonul specificat este

; actionat, BUTTON returneaza valoarea TRUE.

; Informatia se obtine prin citirea portului $201 de I/O. Primii patru biti

; superiori reprezinta starea celor patru butoane (cite doi pantru cele doua

; joystick-uri posibile). Bitul inferior reprezinta un buton apasat.

; Structura bitilor returnati de portul $201 este :

; |7 6 5 4 3 2 1 0|

; | | | |

; | | | |_______________ Buton #1, joystick #1

; | | |_________________ Buton #2, joystick #1

; | |___________________ Buton #1, joystick #2

; |_____ _______ ______ ______ Buton #2, joystick #

; Retineti faptul ca valoarea returnata de functie este transmita codului

; rutinei in registrul AL.

ONSTACK1 STRUC

OLDBP DW ? ; Virful stivei

RETADDR DD ? ; Adresa indepartata de revenire

BTN_NO DW ? ; Numarul butonului

STIK_NO DW ? ; Numarul joystick-ului

ONSTACK1 ENDS

BUTTON PROC FAR

PUSH BP ; Slavarea in stiva a valorii anterioare a lui BP

MOV BP, SP ; SP devine noul BP

; Cea mai mare parte a rutinei stabileste masca de testare pentru

; fiecare din cei patru biti testati.

MOV BL, 010H ; Se incepe cu bitul 4

CMP [BP].STIK_NO, 2 ; Se testeaza ptr. joystick-ul 2 ?

JNE WHICH ; Daca nu, se trece la WHICH

SHL BL, 1 ; altfel se deplaseaza cu 2 spre stinga

SHL BL, 1 ; astfel ca sa se ajunga pe bitul 6

WHICH: CMP [BP].BTN_NO, 2 ; Se testeaza butonul 2 ?

JNE READEN ; Daca nu, masca e corecta; citeste portul

SHL BL, 1 ; altfel, deplaseaza un bit la stg ptr btn 2

; Masca bitului este acum corecta. Bitii butonului sint cititi din portul

; $201 si testati impreuna cu masca. De notat faptul ca bitii cititi din

; port trebuie sa fie inversati astfel incit indicatorul Z sa fie setat in

; loc sa fie sters bityul butonului activ.

READEN: MOV DX, 0201h ; Setarea adresei portului citit

IN AL, DX ; Citirea bitilor butoanelor din portul $201

NOT AL ; Inversare biti pentru sensul corespunzator

; al indicatorului Z dupa testare

TEST AL, BL ; Se verifica daca bitul este "superior"

JNZ PUSHED ; Daca este asa, butonul este apasat;

MOV AL, 0 ; Altfel muta FALSE in AL

JMP BDONE ; si se merge la iesire

PUSHED: MOV AL, 1 ; Buton apasat; muta TRUE in AL

BDONE: MOV SP, BP ; Restaurare SP & BP anterior

POP SP

RET 6

BUTTON ENDP

; S T I C K - intrare joystick, in limbaj de asamblare, pentru Turbo Pascal

; Antetul complet al procedurii este :

; PROCEDURE STICK (StickNumber: INTEGER; VAR X, Y: INTEGER);

; StickNumber specifica care din joystick-uri se citeste, iar X si Y sint

; parametrii ce returneaza intregi proportionali cu pozitia joystick-ului.

; Acesti intregi difera de la stick la stick in functie de rezistenta

; potentiometrelor folosite in stick, dar in mod obisnuit sint cuprinsi

; intre 3 si 150.

; Placa IBM standard pentru controlul jocului se compune din doua manete

; (one-shots), care transmit un impuls la portul $201 de I/O. Durata acestui

; impuls depinde de constanta RC a portiunii de rezistenta a potentiometrului

; joystick-ului.

; Pentru citirea unuia din cele doua joystick-uri, o valoare fictiva este

; scrisa in portul $201 de I/O. Portul $201 trebuie apoi testat continuu,

; incrementind un registru la fisecare eveniment. Atunci cind bitul care

; corespunde coordonatelor X sau Y ale joystick-ului isi modifica starea,

; valoarea din registru este returnata drept valoare a coordonatelor

; stick-ului care a fost manevrat.

; Configuratia de biti ai joystick-ului returnati portului $201 este :

; |7 6 5 4 3 2 1 0|

; | | | |______ coordonata X, joystick #1

; | | |________ coordonata Y, joystick #1

; | |__________ coordonata X, joystick #2

; |____________ coordonata Y, joystick #2

; Aceasta structura defineste planul parametrilor unui stick :

ONSTACK2 STRUC

OLDSP2 DW ? ; Virful stivei

RETADDR2 DD ? ; Adresa indepartata de revenire

YADDR2 DD ? ; Adresa indepartata a valorii Y

XADDR2 DD ? ; Adresa indepartata a valorii X

STIK_NO2 DW ? ; Numarul stic-ului

ONSTACK2 ENDS

STICK_X EQU 1

STICK_Y EQU 2

STICK PROC FAR

PUSH BP ; Salvarea BP al apelantului

MOV BP, SP ; Pointerul stivei devine noul BP

PUSH DS

; Citirea valorii axei X

MOV AH, STICK_X ; Mutarea bitilor de testat

CMP [BP].STIK_NO2, 2 ; Se verifica daca este stic-ul #1 sau #2

JNE TEST_X

SHL AH, 1 ; Se decaleaza stinga pentru stick-ul #2

SHL AH, 1

TEST_X: MOV AL, 1 ; Initializarea valorii de iesire

MOV DX, 201H ; Stabilirea adresei portului

MOV BX, 0 ; si pastrarea valorii de executie in BX

MOV CX, BX ; Stabileste limita maxima a ciclului la 64K

OUT DX, AL ; Testarea unei manete

AGAIN_X: IN AL, DX ; Citeste bitii unei manete

TEST AL, AH ; Testeaza bitul 0 superior

JE DELAY ; Salt daca bitul 0 este superior

INC BX ; Altfel incrementeaza BX si cicleaza din nou

LOOP AGAIN_X

MOV BX, -1 ; Seteaza X=-1 dacu nu exista raspuns

; Intirziere pentru maxim trei impulsuri de iesire

DELAY: MOV CX, 512

WAIT: LOOP WAIT

; Citirea valorii axei Y

MOV AH, STICK_Y

CMP [BP].STIK_NO2, 2

JNE TEST_Y

SHL AH, 1

SHL AH, 1

TEST_Y: MOV SI, 0

MOV CX, SI

OUT DX, AL

SAGAIN_Y: IN AL, DX

TEST AL, AH

JE DONE

INC SI

LOOP AGAIN_Y

MOV SI, -1

; Mutarea valorilor returnate din registre in parametrii VAR X si Y

DONE: LOS DI, [BP].XADDR2 ; Adresa lui X in DS:DI

MOV [DI], BX ; Valoarea lui X din BX in DS:DI

LOS DI, [BP].YADDR2 ; Adresa lui Y in DS:DI

MOV [DI], SI ; Valoarea lui Y din SI in DS:DI

; Acesta este totul ... Acum se sterge stiva si se revine in apelant

POP DS

MOV SP, BP

POP BP

RET 10

STICK ENDP

CODE ENDS

END


Document Info


Accesari: 1195
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )