| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- (* Copyright (C) 1987 Jensen & Partners International *)
- IMPLEMENTATION MODULE Lib;
- (* Change Log: *)
- FROM SYSTEM IMPORT Seg,Ofs,Registers,CarryFlag;
- FROM AsmLib IMPORT DosExec,Copy,Concat,Append,Length;
- (*$S-,R-,I-,V-,O-*)
- PROCEDURE HSort(N: CARDINAL; Less: CompareProc; Swap: SwapProc);
- VAR
- i,j,k : CARDINAL;
- BEGIN
- IF N > 1 THEN
- i := N DIV 2;
- REPEAT
- j := i;
- LOOP (* Note that total repeats <= N/4 * 1 + N/8 * 2 + N/16 * 3 + .... *)
- k := j * 2;
- IF k > N THEN EXIT END;
- IF (k < N) AND Less(k,k+1) THEN INC(k) END;
- IF Less(j,k) THEN Swap(j,k) ELSE EXIT END;
- j := k;
- END;
- DEC(i);
- UNTIL i = 0;
- i := N;
- REPEAT
- j := 1;
- Swap(j,i);
- DEC(i);
- LOOP
- k := j * 2;
- IF k > i THEN EXIT END;
- IF ( k < i ) AND Less(k,k+1) THEN INC(k) END;
- Swap(j,k);
- j := k;
- END;
- LOOP
- k := j DIV 2;
- IF (k > 0) AND Less(k,j) THEN Swap(j,k); j := k ELSE EXIT END;
- END;
- UNTIL i = 0;
- END;
- END HSort;
- PROCEDURE QSort(N: CARDINAL; Less: CompareProc; Swap: SwapProc);
- PROCEDURE Sort(l,r: CARDINAL);
- VAR
- i,j:CARDINAL;
- BEGIN
- WHILE r > l DO
- i := l+1;
- j := r;
- WHILE i <= j DO
- WHILE (i <= j) AND NOT Less(l,i) DO INC(i) END;
- WHILE (i <= j) AND Less(l,j) DO DEC(j) END;
- IF i <= j THEN Swap(i,j); INC(i); DEC(j) END;
- END;
- IF j # l THEN Swap(j,l) END;
- IF j+j > r+l THEN (* small one recursively *)
- Sort(j+1,r);
- r := j-1;
- ELSE
- Sort(l,j-1);
- l := j+1;
- END;
- END;
- END Sort;
- BEGIN
- Sort(1,N);
- END QSort;
- PROCEDURE Execute ( Name : ARRAY OF CHAR;
- CommandLine : ARRAY OF CHAR;
- StoreAddr : ADDRESS; (* storage to execute in *)
- StoreLen : CARDINAL (* length of store paragraphs *)
- ) : CARDINAL;
- CONST
- MinHeapNeeded = 4;
- VAR
- fullpath : ARRAY[0..80] OF CHAR;
- cline : RECORD
- len : SHORTCARD;
- txt : ARRAY[0..255] OF CHAR;
- END;
- reply : CARDINAL;
- LoadRec : RECORD
- envseg : CARDINAL;
- comline : ADDRESS;
- FCB1 : ADDRESS;
- FCB2 : ADDRESS;
- END;
- Progbase : CARDINAL;
- MaxProgSize : CARDINAL;
- residue : CARDINAL;
- PROCEDURE GiveBackHeap ( StoreAddr : ADDRESS; (* storage to execute in *)
- StoreLen : CARDINAL (* length of store paragraphs *)
- );
- VAR
- R : Registers;
- temp : CARDINAL;
- BEGIN
- Progbase := Seg(StoreAddr^);
- R.AH := 4AH;
- R.ES := PSP;
- R.BX := Seg(StoreAddr^)-PSP;
- Dos(R); (* modify so all after seg free *)
- R.BX := StoreLen-2;
- R.AH := 48H;
- Dos(R); (* allocate the seg we want *)
- temp := R.AX;
- R.BX := 0FFFFH; (* allocate all the rest *)
- R.AH := 48H;
- Dos(R); (* returns allocated in BX *)
- R.AH := 48H;
- Dos(R); (* do allocation *)
- residue := R.AX;
- R.AH := 49H;
- R.ES := temp;
- Dos(R); (* now free the bit we want *)
- END GiveBackHeap;
- PROCEDURE RetrieveHeap;
- VAR
- R : Registers;
- BEGIN
- R.AH := 49H;
- R.ES := residue;
- Dos(R); (* now free the residue *)
- R.BX := 0FFFFH; (* now modify PSP back to full size *)
- R.AH := 4AH;
- R.ES := PSP;
- Dos(R); (* returns allocated in BX *)
- R.AH := 4AH;
- Dos(R); (* do modify *)
- END RetrieveHeap;
- BEGIN
- GiveBackHeap( StoreAddr, StoreLen );
- cline.len := SHORTCARD( Length(CommandLine) );
- Concat(cline.txt,CommandLine,CHR(13));
- Copy(fullpath,Name);
- LoadRec.envseg := [PSP:2CH]^;
- LoadRec.comline := ADR(cline);
- LoadRec.FCB1 := [PSP:5CH];
- LoadRec.FCB2 := [PSP:6CH];
- reply := DosExec( fullpath, ADR(LoadRec) );
- RetrieveHeap;
- RETURN reply;
- END Execute;
- CONST
- HistoryMax = 54;
- VAR
- HistoryPtr : CARDINAL;
- LowerPtr : CARDINAL;
- VAR
- History : ARRAY [0..HistoryMax] OF CARDINAL;
- PROCEDURE SetUpHistory(Seed: CARDINAL);
- VAR
- x : LONGCARD;
- i : CARDINAL;
- BEGIN
- HistoryPtr := HistoryMax;
- LowerPtr := 23;
- x := LONGCARD(Seed);
- i := 0;
- REPEAT
- x := (x*3141592621+17);
- History[i] := CARDINAL(x DIV 10000H);
- INC(i);
- UNTIL i>HistoryMax;
- END SetUpHistory;
- PROCEDURE RANDOM(Range: CARDINAL) : CARDINAL;
- VAR res:CARDINAL;
- BEGIN
- IF HistoryPtr = 0 THEN
- IF LowerPtr = 0 THEN
- SetUpHistory(12345);
- ELSE
- HistoryPtr := HistoryMax;
- LowerPtr := LowerPtr-1;
- END;
- ELSE
- HistoryPtr := HistoryPtr-1;
- IF LowerPtr = 0 THEN
- LowerPtr := HistoryMax;
- ELSE
- LowerPtr := LowerPtr-1;
- END;
- END;
- res := History[HistoryPtr]+History[LowerPtr];
- History[HistoryPtr] := res;
- IF Range = 0 THEN
- RETURN res;
- ELSE
- RETURN res MOD Range;
- END;
- END RANDOM;
- PROCEDURE RANDOMIZE;
- VAR R : Registers;
- BEGIN
- WITH R DO
- AH := 2CH;
- Dos(R);
- SetUpHistory(DX+CX);
- END;
- END RANDOMIZE;
- PROCEDURE RAND(): REAL;
- VAR
- x:RECORD low,high:CARDINAL END;
- BEGIN
- x.low := RANDOM(0);
- x.high := RANDOM(0);
- RETURN REAL(LONGCARD(x))/(REAL(MAX(LONGCARD))+1.0);
- END RAND;
- CONST
- MErr = 'Math Error : ';
- PROCEDURE MathError(R: LONGREAL; STR: ARRAY OF CHAR);
- VAR str : ARRAY[0..40] OF CHAR;
- BEGIN
- Concat ( str,MErr,STR );
- FatalError( str );
- END MathError;
- PROCEDURE MathError2(R1,R2: LONGREAL; STR: ARRAY OF CHAR);
- VAR str : ARRAY[0..40] OF CHAR;
- BEGIN
- Concat ( str,MErr,STR );
- FatalError( str );
- END MathError2;
- BEGIN
- HistoryPtr := 0;
- LowerPtr := 0;
- END Lib.
|