system.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. {
  2. $Id$
  3. This file is part of the Free Pascal Run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. For details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {****************************************************************************
  12. Local types
  13. ****************************************************************************}
  14. {
  15. TextRec and FileRec are put in a separate file to make it available to other
  16. units without putting it explicitly in systemh.
  17. This way we keep TP compatibility, and the TextRec definition is available
  18. for everyone who needs it.
  19. }
  20. {$i filerec.inc}
  21. {$i textrec.inc}
  22. Procedure HandleError (Errno : Longint); forward;
  23. Procedure HandleErrorFrame (Errno : longint;frame : longint); forward;
  24. type
  25. FileFunc = Procedure(var t : TextRec);
  26. const
  27. { Random / Randomize constants }
  28. OldRandSeed : Cardinal = 0;
  29. InitialSeed : Boolean = TRUE;
  30. Seed2 : Cardinal = 0;
  31. Seed3 : Cardinal = 0;
  32. { For Error Handling.}
  33. ErrorBase : Longint = 0;
  34. { Used by the ansistrings and maybe also other things in the future }
  35. var
  36. emptychar : char;public name 'FPC_EMPTYCHAR';
  37. {****************************************************************************
  38. Routines which have compiler magic
  39. ****************************************************************************}
  40. {$I innr.inc}
  41. Function lo(i : Integer) : byte; [INTERNPROC: In_lo_Word];
  42. Function lo(w : Word) : byte; [INTERNPROC: In_lo_Word];
  43. Function lo(l : Longint) : Word; [INTERNPROC: In_lo_long];
  44. Function lo(l : DWord) : Word; [INTERNPROC: In_lo_long];
  45. Function hi(i : Integer) : byte; [INTERNPROC: In_hi_Word];
  46. Function hi(w : Word) : byte; [INTERNPROC: In_hi_Word];
  47. Function hi(l : Longint) : Word; [INTERNPROC: In_hi_long];
  48. Function hi(l : DWord) : Word; [INTERNPROC: In_hi_long];
  49. Function chr(b : byte) : Char; [INTERNPROC: In_chr_byte];
  50. Function Length(s : string) : byte; [INTERNPROC: In_Length_string];
  51. Function Length(c : char) : byte; [INTERNPROC: In_Length_string];
  52. Procedure Reset(var f : TypedFile); [INTERNPROC: In_Reset_TypedFile];
  53. Procedure Rewrite(var f : TypedFile); [INTERNPROC: In_Rewrite_TypedFile];
  54. {****************************************************************************
  55. Include processor specific routines
  56. ****************************************************************************}
  57. {$IFDEF I386}
  58. {$IFDEF M68K}
  59. {$Error Can't determine processor type !}
  60. {$ENDIF}
  61. {$I i386.inc} { Case dependent, don't change }
  62. {$ELSE}
  63. {$IFDEF M68K}
  64. {$I m68k.inc} { Case dependent, don't change }
  65. {$ELSE}
  66. {$Error Can't determine processor type !}
  67. {$ENDIF}
  68. {$ENDIF}
  69. {****************************************************************************
  70. Set Handling
  71. ****************************************************************************}
  72. { Include set support which is processor specific}
  73. {$I set.inc}
  74. {****************************************************************************
  75. Subroutines for String handling
  76. ****************************************************************************}
  77. { Needs to be before RTTI handling }
  78. {$i sstrings.inc}
  79. Type
  80. PLongint = ^Longint;
  81. PByte = ^Byte;
  82. {$i astrings.inc}
  83. {****************************************************************************
  84. Run-Time Type Information (RTTI)
  85. ****************************************************************************}
  86. {$i rtti.inc}
  87. {****************************************************************************
  88. Math Routines
  89. ****************************************************************************}
  90. {$ifndef RTLLITE}
  91. function Hi(b : byte): byte;
  92. begin
  93. Hi := b shr 4
  94. end;
  95. function Lo(b : byte): byte;
  96. begin
  97. Lo := b and $0f
  98. end;
  99. Function swap (X : Word) : Word;[internconst:in_const_swap_word];
  100. Begin
  101. swap:=(X and $ff) shl 8 + (X shr 8)
  102. End;
  103. Function Swap (X : Integer) : Integer;[internconst:in_const_swap_word];
  104. Begin
  105. Swap:=Integer(Swap(Word(X)));
  106. End;
  107. Function swap (X : Longint) : Longint;[internconst:in_const_swap_long];
  108. Begin
  109. Swap:=(X and $ffff) shl 16 + (X shr 16)
  110. End;
  111. Function Swap (X : Cardinal) : Cardinal;[internconst:in_const_swap_long];
  112. Begin
  113. Swap:=Swap(Longint(X));
  114. End;
  115. {$endif RTLLITE}
  116. {****************************************************************************
  117. Random function routines
  118. This implements a very long cycle random number generator by combining
  119. three independant generators. The technique was described in the March
  120. 1987 issue of Byte.
  121. Taken and modified with permission from the PCQ Pascal rtl code.
  122. ****************************************************************************}
  123. {$R-}
  124. {$Q-}
  125. Procedure UseSeed(seed : Longint);Forward;
  126. Function Random : Real;
  127. var
  128. ReturnValue : Real;
  129. begin
  130. if (InitialSeed) OR ((RandSeed <> OldRandSeed) AND (NOT InitialSeed)) then
  131. Begin
  132. { This is a pretty complicated affair }
  133. { Initially we must call UseSeed when RandSeed is initalized }
  134. { We must also call UseSeed each time RandSeed is reinitialized }
  135. { DO NOT CHANGE THE ORDER OF DECLARATIONS IN THIS BLOCK }
  136. { UNLESS YOU WANT RANDON TO CRASH OF COURSE (CEC) }
  137. InitialSeed:=FALSE;
  138. OldRandSeed:=RandSeed;
  139. UseSeed(RandSeed);
  140. end;
  141. Inc(RandSeed);
  142. RandSeed := (RandSeed * 706) mod 500009;
  143. OldRandSeed:=RandSeed;
  144. INC(Seed2);
  145. Seed2 := (Seed2 * 774) MOD 600011;
  146. INC(Seed3);
  147. Seed3 := (Seed3 * 871) MOD 765241;
  148. ReturnValue := RandSeed/500009.0 +
  149. Seed2/600011.0 +
  150. Seed3/765241.0;
  151. Random := frac(ReturnValue);
  152. end;
  153. Function Random(l : Longint) : Longint;
  154. begin
  155. if (InitialSeed) OR ((RandSeed <> OldRandSeed) AND (NOT InitialSeed)) then
  156. Begin
  157. { This is a pretty complicated affair }
  158. { Initially we must call UseSeed when RandSeed is initalized }
  159. { We must also call UseSeed each time RandSeed is reinitialized }
  160. { DO NOT CHANGE THE ORDER OF DECLARATIONS IN THIS BLOCK }
  161. { UNLESS YOU WANT RANDON TO CRASH OF COURSE (CEC) }
  162. InitialSeed:=FALSE;
  163. OldRandSeed:=RandSeed;
  164. UseSeed(Randseed);
  165. end;
  166. Inc(RandSeed);
  167. RandSeed := (RandSeed * 998) mod 1000003;
  168. OldRandSeed:=RandSeed;
  169. Random := RandSeed mod l;
  170. end;
  171. Procedure UseSeed(seed : Longint);
  172. begin
  173. randseed := seed mod 1000003;
  174. Seed2 := (Random(65000) * Random(65000)) mod 600011;
  175. Seed3 := (Random(65000) * Random(65000)) mod 765241;
  176. end;
  177. { Include processor specific routines }
  178. {$I math.inc}
  179. {****************************************************************************
  180. Memory Management
  181. ****************************************************************************}
  182. {$ifndef RTLLITE}
  183. Function Ptr(sel,off : Longint) : pointer;[internconst:in_const_ptr];
  184. Begin
  185. sel:=0;
  186. ptr:=pointer(off);
  187. End;
  188. {$ifndef INTERNALADDR}
  189. Function Addr(var x):pointer;
  190. begin
  191. Addr:=@x;
  192. end;
  193. {$endif}
  194. Function CSeg : Word;
  195. Begin
  196. Cseg:=0;
  197. End;
  198. Function DSeg : Word;
  199. Begin
  200. Dseg:=0;
  201. End;
  202. Function SSeg : Word;
  203. Begin
  204. Sseg:=0;
  205. End;
  206. {$endif RTLLITE}
  207. {*****************************************************************************
  208. Directory support.
  209. *****************************************************************************}
  210. Procedure getdir(drivenr:byte;Var dir:ansistring);
  211. { this is needed to also allow ansistrings, the shortstring version is
  212. OS dependent }
  213. var
  214. s : shortstring;
  215. begin
  216. getdir(drivenr,s);
  217. dir:=s;
  218. end;
  219. {*****************************************************************************
  220. Miscellaneous
  221. *****************************************************************************}
  222. procedure int_overflow;[public,alias:'FPC_OVERFLOW'];
  223. begin
  224. HandleErrorFrame(215,get_frame);
  225. end;
  226. Function IOResult:Word;
  227. Begin
  228. IOResult:=InOutRes;
  229. InOutRes:=0;
  230. End;
  231. procedure fillchar(var x;count : longint;value : boolean);
  232. begin
  233. fillchar(x,count,byte(value));
  234. end;
  235. procedure fillchar(var x;count : longint;value : char);
  236. begin
  237. fillchar(x,count,byte(value));
  238. end;
  239. {*****************************************************************************
  240. Init / Exit / ExitProc
  241. *****************************************************************************}
  242. {$ifdef HASFINALIZE}
  243. const
  244. maxunits=1024; { See also files.pas of the compiler source }
  245. type
  246. TInitFinalRec=record
  247. InitProc,
  248. FinalProc : TProcedure;
  249. end;
  250. TInitFinalTable=record
  251. TableCount,
  252. InitCount : longint;
  253. Procs : array[1..maxunits] of TInitFinalRec;
  254. end;
  255. var
  256. InitFinalTable : TInitFinalTable;external name 'INITFINAL';
  257. procedure InitializeUnits;[public,alias:'FPC_INITIALIZEUNITS'];
  258. var
  259. i : longint;
  260. begin
  261. with InitFinalTable do
  262. begin
  263. for i:=1to TableCount do
  264. begin
  265. if assigned(Procs[i].InitProc) then
  266. Procs[i].InitProc();
  267. InitCount:=i;
  268. end;
  269. end;
  270. end;
  271. procedure FinalizeUnits;[public,alias:'FPC_FINALIZEUNITS'];
  272. begin
  273. with InitFinalTable do
  274. begin
  275. while (InitCount>0) do
  276. begin
  277. if assigned(Procs[InitCount].FinalProc) then
  278. Procs[InitCount].FinalProc();
  279. dec(InitCount);
  280. end;
  281. end;
  282. end;
  283. {$endif}
  284. Procedure HandleErrorFrame (Errno : longint;frame : longint);
  285. {
  286. Procedure to handle internal errors, i.e. not user-invoked errors
  287. Internal function should ALWAYS call HandleError instead of RunError.
  288. Can be used for exception handlers to specify the frame
  289. }
  290. var
  291. addr : longint;
  292. begin
  293. addr:=get_caller_addr(frame);
  294. If ErrorProc<>Nil then
  295. TErrorProc (ErrorProc)(Errno,pointer(addr));
  296. errorcode:=Errno;
  297. exitcode:=Errno;
  298. erroraddr:=pointer(addr);
  299. errorbase:=get_caller_frame(frame);
  300. halt(errorcode);
  301. end;
  302. Procedure HandleError (Errno : longint);[public,alias : 'FPC_HANDLEERROR'];
  303. {
  304. Procedure to handle internal errors, i.e. not user-invoked errors
  305. Internal function should ALWAYS call HandleError instead of RunError.
  306. }
  307. begin
  308. HandleErrorFrame(Errno,get_frame);
  309. end;
  310. procedure runerror(w : word);[alias: 'FPC_RUNERROR'];
  311. begin
  312. errorcode:=w;
  313. exitcode:=w;
  314. erroraddr:=pointer(get_caller_addr(get_frame));
  315. errorbase:=get_caller_frame(get_frame);
  316. halt(errorcode);
  317. end;
  318. Procedure RunError;
  319. Begin
  320. RunError (0);
  321. End;
  322. Procedure Halt;
  323. Begin
  324. Halt(0);
  325. End;
  326. Procedure dump_stack(var f : text;bp : Longint);
  327. var
  328. i, prevbp : Longint;
  329. Begin
  330. prevbp:=bp-1;
  331. i:=0;
  332. while bp > prevbp Do
  333. Begin
  334. Writeln(stderr,' 0x',HexStr(get_caller_addr(bp),8));
  335. Inc(i);
  336. If i>max_frame_dump Then
  337. exit;
  338. prevbp:=bp;
  339. bp:=get_caller_frame(bp);
  340. End;
  341. End;
  342. Procedure system_exit;forward;
  343. Procedure do_exit;[Public,Alias:'FPC_DO_EXIT'];
  344. var
  345. current_exit : Procedure;
  346. Begin
  347. while exitProc<>nil Do
  348. Begin
  349. InOutRes:=0;
  350. current_exit:=tProcedure(exitProc);
  351. exitProc:=nil;
  352. current_exit();
  353. End;
  354. {$ifdef HASFINALIZE}
  355. { Finalize units }
  356. FinalizeUnits;
  357. {$endif}
  358. { Show runtime error }
  359. If erroraddr<>nil Then
  360. Begin
  361. Writeln(stdout,'Run time error ',Errorcode,' at 0x',hexstr(Longint(Erroraddr),8));
  362. dump_stack(stdout,ErrorBase);
  363. End;
  364. { call system dependent exit code }
  365. System_exit;
  366. End;
  367. Type
  368. PExitProcInfo = ^TExitProcInfo;
  369. TExitProcInfo = Record
  370. Next : PExitProcInfo;
  371. SaveExit : Pointer;
  372. Proc : TProcedure;
  373. End;
  374. const
  375. ExitProcList: PExitProcInfo = nil;
  376. Procedure DoExitProc;
  377. var
  378. P : PExitProcInfo;
  379. Proc : TProcedure;
  380. Begin
  381. P:=ExitProcList;
  382. ExitProcList:=P^.Next;
  383. ExitProc:=P^.SaveExit;
  384. Proc:=P^.Proc;
  385. DisPose(P);
  386. Proc();
  387. End;
  388. Procedure AddExitProc(Proc: TProcedure);
  389. var
  390. P : PExitProcInfo;
  391. Begin
  392. New(P);
  393. P^.Next:=ExitProcList;
  394. P^.SaveExit:=ExitProc;
  395. P^.Proc:=Proc;
  396. ExitProcList:=P;
  397. ExitProc:=@DoExitProc;
  398. End;
  399. {*****************************************************************************
  400. Abstract/Assert support.
  401. *****************************************************************************}
  402. procedure AbstractError;[public,alias : 'FPC_ABSTRACTERROR'];
  403. Type
  404. TAbstractErrorProc=Procedure;
  405. begin
  406. If AbstractErrorProc<>nil then
  407. TAbstractErrorProc(AbstractErrorProc);
  408. RunError(211);
  409. end;
  410. Procedure int_assert(Const Msg,FName:string;LineNo,ErrorAddr:Longint); [Public,Alias : 'FPC_ASSERT'];
  411. type
  412. TAssertErrorProc=procedure(const msg,fname:string;lineno,erroraddr:longint);
  413. begin
  414. if AssertErrorProc<>nil then
  415. TAssertErrorProc(AssertErrorProc)(Msg,FName,LineNo,ErrorAddr)
  416. else
  417. HandleError(227);
  418. end;
  419. Procedure SysAssert(Const Msg,FName:string;LineNo,ErrorAddr:Longint);
  420. begin
  421. If msg='' then
  422. write(stderr,'Assertion failed')
  423. else
  424. write(stderr,msg);
  425. writeln(stderr,' (',FName,', line ',LineNo,').');
  426. end;
  427. {*****************************************************************************
  428. SetJmp/LongJmp support.
  429. *****************************************************************************}
  430. {$i setjump.inc}
  431. {
  432. $Log$
  433. Revision 1.57 1999-04-17 13:10:25 peter
  434. * addr() internal
  435. Revision 1.56 1999/04/15 12:20:01 peter
  436. + finalization support
  437. Revision 1.55 1999/03/01 15:41:03 peter
  438. * use external names
  439. * removed all direct assembler modes
  440. Revision 1.54 1999/02/01 00:05:14 florian
  441. + functions lo/hi for DWord type implemented
  442. Revision 1.53 1999/01/29 09:23:09 pierre
  443. * Fillchar(..,..,boolean) added
  444. Revision 1.52 1999/01/22 12:39:23 pierre
  445. + added text arg for dump_stack
  446. Revision 1.51 1999/01/18 10:05:52 pierre
  447. + system_exit procedure added
  448. Revision 1.50 1998/12/28 15:50:46 peter
  449. + stdout, which is needed when you write something in the system unit
  450. to the screen. Like the runtime error
  451. Revision 1.49 1998/12/21 14:28:21 pierre
  452. * HandleError -> HandleErrorFrame to avoid problem in
  453. assembler code in i386.inc
  454. (call to overloaded function in assembler block !)
  455. Revision 1.48 1998/12/18 17:21:33 peter
  456. * fixed io-error handling
  457. Revision 1.47 1998/12/15 22:43:03 peter
  458. * removed temp symbols
  459. Revision 1.46 1998/12/10 23:59:56 peter
  460. * removed warnign
  461. Revision 1.45 1998/12/01 14:00:10 pierre
  462. + added conversion from exceptions into run time error
  463. (only if syswin32 compiled with -ddebug for now !)
  464. * added HandleError(errno,frame)
  465. where you specify the frame
  466. needed for win32 exception handling
  467. Revision 1.44 1998/11/26 23:16:15 jonas
  468. * changed RandSeed and OldRandSeed to Cardinal to avoid negative random numbers
  469. Revision 1.43 1998/11/17 10:36:07 michael
  470. + renamed astrings.pp to astrings.inc
  471. Revision 1.42 1998/11/16 10:21:25 peter
  472. * fixes for H+
  473. Revision 1.41 1998/11/05 10:29:36 pierre
  474. * fix for length(char) in const expressions
  475. Revision 1.40 1998/11/04 20:34:02 michael
  476. + Removed ifdef useansistrings
  477. Revision 1.39 1998/10/12 22:11:28 jonas
  478. * fixed RandSeed bug
  479. Revision 1.38 1998/10/12 12:43:37 florian
  480. * made FPC_HANDLEERROR public
  481. Revision 1.37 1998/10/07 11:40:08 jonas
  482. * changed seed2 and seed3 to cardinal to prevent overflow
  483. Revision 1.36 1998/10/05 12:32:51 peter
  484. + assert() support
  485. Revision 1.35 1998/10/02 09:25:11 peter
  486. * more constant expression evals
  487. Revision 1.34 1998/09/22 15:30:54 peter
  488. * shortstring=string type added
  489. Revision 1.33 1998/09/16 13:08:03 michael
  490. Added AbstractErrorHandler
  491. Revision 1.32 1998/09/16 12:37:07 michael
  492. Added FPC_ prefix to abstracterror
  493. Revision 1.31 1998/09/15 17:12:32 michael
  494. + Merged changes from fixes branch
  495. Revision 1.30 1998/09/14 10:48:20 peter
  496. * FPC_ names
  497. * Heap manager is now system independent
  498. Revision 1.29.2.1 1998/09/15 17:08:43 michael
  499. + Added abstracterror call
  500. Revision 1.29 1998/09/01 17:36:21 peter
  501. + internconst
  502. Revision 1.28 1998/08/17 12:24:16 carl
  503. + important comment added
  504. Revision 1.27 1998/08/13 16:22:11 jonas
  505. * random now returns a value between 0 and max-1 instead of between 0 and max
  506. Revision 1.26 1998/08/11 00:05:26 peter
  507. * $ifdef ver0_99_5 updates
  508. Revision 1.25 1998/07/30 13:26:18 michael
  509. + Added support for ErrorProc variable. All internal functions are required
  510. to call HandleError instead of runerror from now on.
  511. This is necessary for exception support.
  512. Revision 1.24 1998/07/28 20:37:45 michael
  513. + added setjmp/longjmp and exception support
  514. Revision 1.23 1998/07/23 19:53:20 michael
  515. + Adapted assert to Delphi format
  516. Revision 1.22 1998/07/23 13:08:41 michael
  517. + Implemented DO_ASSERT function.
  518. Revision 1.21 1998/07/15 12:09:35 carl
  519. * would not compile under FPC v0.99.5
  520. Revision 1.20 1998/07/13 21:19:12 florian
  521. * some problems with ansi string support fixed
  522. Revision 1.19 1998/07/08 11:56:55 carl
  523. * randon and Random(l) now work correctly - don't touch it works!
  524. Revision 1.18 1998/07/02 13:01:55 carl
  525. * hmmm... it is luck (BSS zeroed with GAS) that DoError and ErrorBase work.
  526. Now they are initilized instead.
  527. Revision 1.17 1998/07/02 12:53:09 carl
  528. * DOERROR RESOTRED! DON'T TOUCH :)
  529. Revision 1.16 1998/07/02 12:11:50 carl
  530. * no SINGLE in m68k and other processors!
  531. Revision 1.15 1998/07/02 09:25:05 peter
  532. * fixed do_error in runtimeerror
  533. Revision 1.14 1998/07/01 15:29:59 peter
  534. * better readln/writeln
  535. Revision 1.13 1998/06/26 08:21:09 daniel
  536. - Doerror removed.
  537. Revision 1.12 1998/06/25 14:04:25 peter
  538. + internal inc/dec
  539. Revision 1.11 1998/06/25 09:44:20 daniel
  540. + RTLLITE directive to compile minimal RTL.
  541. Revision 1.10 1998/06/15 15:16:26 daniel
  542. * RTLLITE conditional added to produce smaller RTL
  543. Revision 1.9 1998/06/10 07:46:45 michael
  544. + Forgot to commit some changes
  545. Revision 1.8 1998/06/08 12:38:24 michael
  546. Implemented rtti, inserted ansistrings again
  547. Revision 1.7 1998/06/04 23:46:01 peter
  548. * comp,extended are only i386 added support_comp,support_extended
  549. Revision 1.6 1998/05/20 11:23:09 cvs
  550. * test commit. Shouldn't be allowed.
  551. Revision 1.5 1998/05/12 10:42:45 peter
  552. * moved getopts to inc/, all supported OS's need argc,argv exported
  553. + strpas, strlen are now exported in the systemunit
  554. * removed logs
  555. * removed $ifdef ver_above
  556. Revision 1.4 1998/04/16 12:30:47 peter
  557. + inc(pchar), dec(pchar), incc(pchar,a),dec(pchar,a)
  558. Revision 1.3 1998/04/08 07:53:32 michael
  559. + Changed Random() function. Moved from system to processor dependent files (from Pedro Gimeno)
  560. }