lib.mod 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. (* Copyright (C) 1987 Jensen & Partners International *)
  2. IMPLEMENTATION MODULE Lib;
  3. (* Change Log: *)
  4. FROM SYSTEM IMPORT Seg,Ofs,Registers,CarryFlag;
  5. FROM AsmLib IMPORT DosExec,Copy,Concat,Append,Length;
  6. (*$S-,R-,I-,V-,O-*)
  7. PROCEDURE HSort(N: CARDINAL; Less: CompareProc; Swap: SwapProc);
  8. VAR
  9. i,j,k : CARDINAL;
  10. BEGIN
  11. IF N > 1 THEN
  12. i := N DIV 2;
  13. REPEAT
  14. j := i;
  15. LOOP (* Note that total repeats <= N/4 * 1 + N/8 * 2 + N/16 * 3 + .... *)
  16. k := j * 2;
  17. IF k > N THEN EXIT END;
  18. IF (k < N) AND Less(k,k+1) THEN INC(k) END;
  19. IF Less(j,k) THEN Swap(j,k) ELSE EXIT END;
  20. j := k;
  21. END;
  22. DEC(i);
  23. UNTIL i = 0;
  24. i := N;
  25. REPEAT
  26. j := 1;
  27. Swap(j,i);
  28. DEC(i);
  29. LOOP
  30. k := j * 2;
  31. IF k > i THEN EXIT END;
  32. IF ( k < i ) AND Less(k,k+1) THEN INC(k) END;
  33. Swap(j,k);
  34. j := k;
  35. END;
  36. LOOP
  37. k := j DIV 2;
  38. IF (k > 0) AND Less(k,j) THEN Swap(j,k); j := k ELSE EXIT END;
  39. END;
  40. UNTIL i = 0;
  41. END;
  42. END HSort;
  43. PROCEDURE QSort(N: CARDINAL; Less: CompareProc; Swap: SwapProc);
  44. PROCEDURE Sort(l,r: CARDINAL);
  45. VAR
  46. i,j:CARDINAL;
  47. BEGIN
  48. WHILE r > l DO
  49. i := l+1;
  50. j := r;
  51. WHILE i <= j DO
  52. WHILE (i <= j) AND NOT Less(l,i) DO INC(i) END;
  53. WHILE (i <= j) AND Less(l,j) DO DEC(j) END;
  54. IF i <= j THEN Swap(i,j); INC(i); DEC(j) END;
  55. END;
  56. IF j # l THEN Swap(j,l) END;
  57. IF j+j > r+l THEN (* small one recursively *)
  58. Sort(j+1,r);
  59. r := j-1;
  60. ELSE
  61. Sort(l,j-1);
  62. l := j+1;
  63. END;
  64. END;
  65. END Sort;
  66. BEGIN
  67. Sort(1,N);
  68. END QSort;
  69. PROCEDURE Execute ( Name : ARRAY OF CHAR;
  70. CommandLine : ARRAY OF CHAR;
  71. StoreAddr : ADDRESS; (* storage to execute in *)
  72. StoreLen : CARDINAL (* length of store paragraphs *)
  73. ) : CARDINAL;
  74. CONST
  75. MinHeapNeeded = 4;
  76. VAR
  77. fullpath : ARRAY[0..80] OF CHAR;
  78. cline : RECORD
  79. len : SHORTCARD;
  80. txt : ARRAY[0..255] OF CHAR;
  81. END;
  82. reply : CARDINAL;
  83. LoadRec : RECORD
  84. envseg : CARDINAL;
  85. comline : ADDRESS;
  86. FCB1 : ADDRESS;
  87. FCB2 : ADDRESS;
  88. END;
  89. Progbase : CARDINAL;
  90. MaxProgSize : CARDINAL;
  91. residue : CARDINAL;
  92. PROCEDURE GiveBackHeap ( StoreAddr : ADDRESS; (* storage to execute in *)
  93. StoreLen : CARDINAL (* length of store paragraphs *)
  94. );
  95. VAR
  96. R : Registers;
  97. temp : CARDINAL;
  98. BEGIN
  99. Progbase := Seg(StoreAddr^);
  100. R.AH := 4AH;
  101. R.ES := PSP;
  102. R.BX := Seg(StoreAddr^)-PSP;
  103. Dos(R); (* modify so all after seg free *)
  104. R.BX := StoreLen-2;
  105. R.AH := 48H;
  106. Dos(R); (* allocate the seg we want *)
  107. temp := R.AX;
  108. R.BX := 0FFFFH; (* allocate all the rest *)
  109. R.AH := 48H;
  110. Dos(R); (* returns allocated in BX *)
  111. R.AH := 48H;
  112. Dos(R); (* do allocation *)
  113. residue := R.AX;
  114. R.AH := 49H;
  115. R.ES := temp;
  116. Dos(R); (* now free the bit we want *)
  117. END GiveBackHeap;
  118. PROCEDURE RetrieveHeap;
  119. VAR
  120. R : Registers;
  121. BEGIN
  122. R.AH := 49H;
  123. R.ES := residue;
  124. Dos(R); (* now free the residue *)
  125. R.BX := 0FFFFH; (* now modify PSP back to full size *)
  126. R.AH := 4AH;
  127. R.ES := PSP;
  128. Dos(R); (* returns allocated in BX *)
  129. R.AH := 4AH;
  130. Dos(R); (* do modify *)
  131. END RetrieveHeap;
  132. BEGIN
  133. GiveBackHeap( StoreAddr, StoreLen );
  134. cline.len := SHORTCARD( Length(CommandLine) );
  135. Concat(cline.txt,CommandLine,CHR(13));
  136. Copy(fullpath,Name);
  137. LoadRec.envseg := [PSP:2CH]^;
  138. LoadRec.comline := ADR(cline);
  139. LoadRec.FCB1 := [PSP:5CH];
  140. LoadRec.FCB2 := [PSP:6CH];
  141. reply := DosExec( fullpath, ADR(LoadRec) );
  142. RetrieveHeap;
  143. RETURN reply;
  144. END Execute;
  145. CONST
  146. HistoryMax = 54;
  147. VAR
  148. HistoryPtr : CARDINAL;
  149. LowerPtr : CARDINAL;
  150. VAR
  151. History : ARRAY [0..HistoryMax] OF CARDINAL;
  152. PROCEDURE SetUpHistory(Seed: CARDINAL);
  153. VAR
  154. x : LONGCARD;
  155. i : CARDINAL;
  156. BEGIN
  157. HistoryPtr := HistoryMax;
  158. LowerPtr := 23;
  159. x := LONGCARD(Seed);
  160. i := 0;
  161. REPEAT
  162. x := (x*3141592621+17);
  163. History[i] := CARDINAL(x DIV 10000H);
  164. INC(i);
  165. UNTIL i>HistoryMax;
  166. END SetUpHistory;
  167. PROCEDURE RANDOM(Range: CARDINAL) : CARDINAL;
  168. VAR res:CARDINAL;
  169. BEGIN
  170. IF HistoryPtr = 0 THEN
  171. IF LowerPtr = 0 THEN
  172. SetUpHistory(12345);
  173. ELSE
  174. HistoryPtr := HistoryMax;
  175. LowerPtr := LowerPtr-1;
  176. END;
  177. ELSE
  178. HistoryPtr := HistoryPtr-1;
  179. IF LowerPtr = 0 THEN
  180. LowerPtr := HistoryMax;
  181. ELSE
  182. LowerPtr := LowerPtr-1;
  183. END;
  184. END;
  185. res := History[HistoryPtr]+History[LowerPtr];
  186. History[HistoryPtr] := res;
  187. IF Range = 0 THEN
  188. RETURN res;
  189. ELSE
  190. RETURN res MOD Range;
  191. END;
  192. END RANDOM;
  193. PROCEDURE RANDOMIZE;
  194. VAR R : Registers;
  195. BEGIN
  196. WITH R DO
  197. AH := 2CH;
  198. Dos(R);
  199. SetUpHistory(DX+CX);
  200. END;
  201. END RANDOMIZE;
  202. PROCEDURE RAND(): REAL;
  203. VAR
  204. x:RECORD low,high:CARDINAL END;
  205. BEGIN
  206. x.low := RANDOM(0);
  207. x.high := RANDOM(0);
  208. RETURN REAL(LONGCARD(x))/(REAL(MAX(LONGCARD))+1.0);
  209. END RAND;
  210. CONST
  211. MErr = 'Math Error : ';
  212. PROCEDURE MathError(R: LONGREAL; STR: ARRAY OF CHAR);
  213. VAR str : ARRAY[0..40] OF CHAR;
  214. BEGIN
  215. Concat ( str,MErr,STR );
  216. FatalError( str );
  217. END MathError;
  218. PROCEDURE MathError2(R1,R2: LONGREAL; STR: ARRAY OF CHAR);
  219. VAR str : ARRAY[0..40] OF CHAR;
  220. BEGIN
  221. Concat ( str,MErr,STR );
  222. FatalError( str );
  223. END MathError2;
  224. BEGIN
  225. HistoryPtr := 0;
  226. LowerPtr := 0;
  227. END Lib.
  228.