system.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. {
  2. $Id$
  3. ****************************************************************************
  4. Free Pascal -- OS/2 runtime library
  5. Copyright (c) 1999-2000 by Florian Klaempfl
  6. Copyright (c) 1999-2000 by Daniel Mantione
  7. Free Pascal is distributed under the GNU Public License v2. So is this unit.
  8. The GNU Public License requires you to distribute the source code of this
  9. unit with any product that uses it. We grant you an exception to this, and
  10. that is, when you compile a program with the Free Pascal Compiler, you do not
  11. need to ship source code with that program, AS LONG AS YOU ARE USING
  12. UNMODIFIED CODE! If you modify this code, you MUST change the next line:
  13. <This an official, unmodified Free Pascal source code file.>
  14. Send us your modified files, we can work together if you want!
  15. Free Pascal is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. Library GNU General Public License for more details.
  19. You should have received a copy of the Library GNU General Public License
  20. along with Free Pascal; see the file COPYING.LIB. If not, write to
  21. the Free Software Foundation, 59 Temple Place - Suite 330,
  22. Boston, MA 02111-1307, USA.
  23. ****************************************************************************}
  24. unit {$ifdef VER1_0}sysos2{$else}System{$endif};
  25. {Changelog:
  26. People:
  27. DM - Daniel Mantione
  28. Date: Description of change: Changed by:
  29. - First released version 0.1. DM
  30. Coding style:
  31. My coding style is a bit unusual for Pascal. Nevertheless I friendly ask
  32. you to try to make your changes not look all to different. In general,
  33. set your IDE to use tab characters, optimal fill on and a tabsize of 4.}
  34. interface
  35. {Link the startup code.}
  36. {$l prt1.oo2}
  37. {$I SYSTEMH.INC}
  38. {$I heaph.inc}
  39. type Tos=(osDOS,osOS2,osDPMI);
  40. var os_mode:Tos;
  41. first_meg:pointer;
  42. type Psysthreadib=^Tsysthreadib;
  43. Pthreadinfoblock=^Tthreadinfoblock;
  44. Pprocessinfoblock=^Tprocessinfoblock;
  45. Tbytearray=array[0..$ffff] of byte;
  46. Pbytearray=^Tbytearray;
  47. Tsysthreadib=record
  48. tid,
  49. priority,
  50. version:longint;
  51. MCcount,
  52. MCforceflag:word;
  53. end;
  54. Tthreadinfoblock=record
  55. pexchain,
  56. stack,
  57. stacklimit:pointer;
  58. tib2:Psysthreadib;
  59. version,
  60. ordinal:longint;
  61. end;
  62. Tprocessinfoblock=record
  63. pid,
  64. parentpid,
  65. hmte:longint;
  66. cmd,
  67. env:Pbytearray;
  68. flstatus,
  69. ttype:longint;
  70. end;
  71. const UnusedHandle=$ffff;
  72. StdInputHandle=0;
  73. StdOutputHandle=1;
  74. StdErrorHandle=2;
  75. FileNameCaseSensitive : boolean = false;
  76. var
  77. { C-compatible arguments and environment }
  78. argc : longint;external name '_argc';
  79. argv : ppchar;external name '_argv';
  80. envp : ppchar;external name '_environ';
  81. implementation
  82. {$I SYSTEM.INC}
  83. procedure DosGetInfoBlocks (var Atib: PThreadInfoBlock;
  84. var Apib: PProcessInfoBlock); cdecl;
  85. external 'DOSCALLS' index 312;
  86. function DosSetRelMaxFH (var ReqCount, CurMaxFH: longint): longint; cdecl;
  87. external 'DOSCALLS' index 382;
  88. function DosSetCurrentDir (Name:PChar): longint; cdecl;
  89. external 'DOSCALLS' index 255;
  90. function DosSetDefaultDisk (DiskNum:longint): longint; cdecl;
  91. external 'DOSCALLS' index 220;
  92. {This is the correct way to call external assembler procedures.}
  93. procedure syscall; external name '___SYSCALL';
  94. {***************************************************************************
  95. Runtime error checking related routines.
  96. ***************************************************************************}
  97. {$S-}
  98. procedure st1(stack_size:longint);[public,alias: 'FPC_STACKCHECK'];
  99. begin
  100. { called when trying to get local stack }
  101. { if the compiler directive $S is set }
  102. {$ASMMODE DIRECT}
  103. asm
  104. movl stack_size,%ebx
  105. movl %esp,%eax
  106. subl %ebx,%eax
  107. {$ifdef SYSTEMDEBUG}
  108. movl U_SYSOS2_LOWESTSTACK,%ebx
  109. cmpl %eax,%ebx
  110. jb Lis_not_lowest
  111. movl %eax,U_SYSOS2_LOWESTSTACK
  112. Lis_not_lowest:
  113. {$endif SYSTEMDEBUG}
  114. cmpb $2,U_SYSOS2_OS_MODE
  115. jne Lrunning_in_dos
  116. movl U_SYSOS2_STACKBOTTOM,%ebx
  117. jmp Lrunning_in_os2
  118. Lrunning_in_dos:
  119. movl __heap_brk,%ebx
  120. Lrunning_in_os2:
  121. cmpl %eax,%ebx
  122. jae Lshort_on_stack
  123. leave
  124. ret $4
  125. Lshort_on_stack:
  126. end ['EAX','EBX'];
  127. {$ASMMODE ATT}
  128. { this needs a local variable }
  129. { so the function called itself !! }
  130. { Writeln('low in stack ');}
  131. HandleError(202);
  132. end;
  133. {no stack check in system }
  134. {****************************************************************************
  135. Miscellaneous related routines.
  136. ****************************************************************************}
  137. {$asmmode intel}
  138. procedure system_exit; assembler;
  139. asm
  140. mov ah, 04ch
  141. mov al, byte ptr exitcode
  142. call syscall
  143. end;
  144. {$asmmode att}
  145. {$asmmode direct}
  146. function paramcount:longint;assembler;
  147. asm
  148. movl _argc,%eax
  149. decl %eax
  150. end ['EAX'];
  151. function paramstr(l:longint):string;
  152. function args:pointer;assembler;
  153. asm
  154. movl _argv,%eax
  155. end ['EAX'];
  156. var p:^Pchar;
  157. begin
  158. if L = 0 then
  159. begin
  160. GetMem (P, 260);
  161. {$ASMMODE INTEL}
  162. asm
  163. mov edx, P
  164. mov ecx, 260
  165. mov eax, 7F33h
  166. call syscall
  167. end;
  168. {$ASMMODE ATT}
  169. ParamStr := StrPas (PChar (P));
  170. FreeMem (P, 260);
  171. end
  172. else
  173. if (l>0) and (l<=paramcount) then
  174. begin
  175. p:=args;
  176. paramstr:=strpas(p[l]);
  177. end
  178. else paramstr:='';
  179. end;
  180. {$asmmode att}
  181. procedure randomize;
  182. var hl:longint;
  183. begin
  184. asm
  185. movb $0x2c,%ah
  186. call syscall
  187. movw %cx,-4(%ebp)
  188. movw %dx,-2(%ebp)
  189. end;
  190. randseed:=hl;
  191. end;
  192. {****************************************************************************
  193. Heap management releated routines.
  194. ****************************************************************************}
  195. { this function allows to extend the heap by calling
  196. syscall $7f00 resizes the brk area}
  197. function sbrk(size:longint):longint; assembler;
  198. asm
  199. movl size,%edx
  200. movw $0x7f00,%ax
  201. call syscall
  202. end;
  203. {$ASMMODE direct}
  204. function getheapstart:pointer;assembler;
  205. asm
  206. movl __heap_base,%eax
  207. end ['EAX'];
  208. function getheapsize:longint;assembler;
  209. asm
  210. movl HEAPSIZE,%eax
  211. end ['EAX'];
  212. {$ASMMODE ATT}
  213. {$i heap.inc}
  214. {****************************************************************************
  215. Low Level File Routines
  216. ****************************************************************************}
  217. procedure allowslash(p:Pchar);
  218. {Allow slash as backslash.}
  219. var i:longint;
  220. begin
  221. for i:=0 to strlen(p) do
  222. if p[i]='/' then p[i]:='\';
  223. end;
  224. procedure do_close(h:longint);
  225. begin
  226. { Only three standard handles under real OS/2 }
  227. if (h > 4) or
  228. (os_MODE = osOS2) and (h > 2) then
  229. begin
  230. asm
  231. movb $0x3e,%ah
  232. movl h,%ebx
  233. call syscall
  234. end;
  235. end;
  236. end;
  237. procedure do_erase(p:Pchar);
  238. begin
  239. allowslash(p);
  240. asm
  241. movl P,%edx
  242. movb $0x41,%ah
  243. call syscall
  244. jnc .LERASE1
  245. movw %ax,inoutres;
  246. .LERASE1:
  247. end;
  248. end;
  249. procedure do_rename(p1,p2:Pchar);
  250. begin
  251. allowslash(p1);
  252. allowslash(p2);
  253. asm
  254. movl P1, %edx
  255. movl P2, %edi
  256. movb $0x56,%ah
  257. call syscall
  258. jnc .LRENAME1
  259. movw %ax,inoutres;
  260. .LRENAME1:
  261. end;
  262. end;
  263. function do_read(h,addr,len:longint):longint; assembler;
  264. asm
  265. movl len,%ecx
  266. movl addr,%edx
  267. movl h,%ebx
  268. movb $0x3f,%ah
  269. call syscall
  270. jnc .LDOSREAD1
  271. movw %ax,inoutres;
  272. xorl %eax,%eax
  273. .LDOSREAD1:
  274. end;
  275. function do_write(h,addr,len:longint) : longint; assembler;
  276. asm
  277. movl len,%ecx
  278. movl addr,%edx
  279. movl h,%ebx
  280. movb $0x40,%ah
  281. call syscall
  282. jnc .LDOSWRITE1
  283. movw %ax,inoutres;
  284. .LDOSWRITE1:
  285. end;
  286. function do_filepos(handle:longint): longint; assembler;
  287. asm
  288. movw $0x4201,%ax
  289. movl handle,%ebx
  290. xorl %edx,%edx
  291. call syscall
  292. jnc .LDOSFILEPOS
  293. movw %ax,inoutres;
  294. xorl %eax,%eax
  295. .LDOSFILEPOS:
  296. end;
  297. procedure do_seek(handle,pos:longint); assembler;
  298. asm
  299. movw $0x4200,%ax
  300. movl handle,%ebx
  301. movl pos,%edx
  302. call syscall
  303. jnc .LDOSSEEK1
  304. movw %ax,inoutres;
  305. .LDOSSEEK1:
  306. end;
  307. function do_seekend(handle:longint):longint; assembler;
  308. asm
  309. movw $0x4202,%ax
  310. movl handle,%ebx
  311. xorl %edx,%edx
  312. call syscall
  313. jnc .Lset_at_end1
  314. movw %ax,inoutres;
  315. xorl %eax,%eax
  316. .Lset_at_end1:
  317. end;
  318. function do_filesize(handle:longint):longint;
  319. var aktfilepos:longint;
  320. begin
  321. aktfilepos:=do_filepos(handle);
  322. do_filesize:=do_seekend(handle);
  323. do_seek(handle,aktfilepos);
  324. end;
  325. procedure do_truncate(handle,pos:longint); assembler;
  326. asm
  327. (* DOS function 40h isn't safe for this according to EMX documentation
  328. movl $0x4200,%eax
  329. movl 8(%ebp),%ebx
  330. movl 12(%ebp),%edx
  331. call syscall
  332. jc .LTruncate1
  333. movl 8(%ebp),%ebx
  334. movl 12(%ebp),%edx
  335. movl %ebp,%edx
  336. xorl %ecx,%ecx
  337. movb $0x40,%ah
  338. call syscall
  339. *)
  340. movl $0x7F25,%eax
  341. movl Handle,%ebx
  342. movl Pos,%edx
  343. call syscall
  344. inc %eax
  345. movl %ecx, %eax
  346. jnz .LTruncate1
  347. (* File position is undefined after truncation, move to the end. *)
  348. movl $0x4202,%eax
  349. movl Handle,%ebx
  350. movl $0,%edx
  351. call syscall
  352. jnc .LTruncate2
  353. .LTruncate1:
  354. movw %ax,inoutres;
  355. .LTruncate2:
  356. end;
  357. const
  358. FileHandleCount: longint = 20;
  359. function Increase_File_Handle_Count: boolean;
  360. var Err: word;
  361. L1, L2: longint;
  362. begin
  363. if os_mode = osOS2 then
  364. begin
  365. L1 := 10;
  366. if DosSetRelMaxFH (L1, L2) <> 0 then
  367. Increase_File_Handle_Count := false
  368. else
  369. if L2 > FileHandleCount then
  370. begin
  371. FileHandleCount := L2;
  372. Increase_File_Handle_Count := true;
  373. end
  374. else
  375. Increase_File_Handle_Count := false;
  376. end
  377. else
  378. begin
  379. Inc (FileHandleCount, 10);
  380. Err := 0;
  381. asm
  382. movl $0x6700, %eax
  383. movl FileHandleCount, %ebx
  384. call syscall
  385. jnc .LIncFHandles
  386. movw %ax, Err
  387. .LIncFHandles:
  388. end;
  389. if Err <> 0 then
  390. begin
  391. Increase_File_Handle_Count := false;
  392. Dec (FileHandleCount, 10);
  393. end
  394. else
  395. Increase_File_Handle_Count := true;
  396. end;
  397. end;
  398. procedure do_open(var f;p:pchar;flags:longint);
  399. {
  400. filerec and textrec have both handle and mode as the first items so
  401. they could use the same routine for opening/creating.
  402. when (flags and $100) the file will be append
  403. when (flags and $1000) the file will be truncate/rewritten
  404. when (flags and $10000) there is no check for close (needed for textfiles)
  405. }
  406. var Action: longint;
  407. begin
  408. allowslash(p);
  409. { close first if opened }
  410. if ((flags and $10000)=0) then
  411. begin
  412. case filerec(f).mode of
  413. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  414. fmclosed:;
  415. else
  416. begin
  417. inoutres:=102; {not assigned}
  418. exit;
  419. end;
  420. end;
  421. end;
  422. { reset file handle }
  423. filerec(f).handle := UnusedHandle;
  424. Action := 0;
  425. { convert filemode to filerec modes }
  426. case (flags and 3) of
  427. 0 : filerec(f).mode:=fminput;
  428. 1 : filerec(f).mode:=fmoutput;
  429. 2 : filerec(f).mode:=fminout;
  430. end;
  431. if (flags and $1000)<>0 then
  432. Action := $50000; (* Create / replace *)
  433. { empty name is special }
  434. if p[0]=#0 then
  435. begin
  436. case FileRec(f).mode of
  437. fminput :
  438. FileRec(f).Handle:=StdInputHandle;
  439. fminout, { this is set by rewrite }
  440. fmoutput :
  441. FileRec(f).Handle:=StdOutputHandle;
  442. fmappend :
  443. begin
  444. FileRec(f).Handle:=StdOutputHandle;
  445. FileRec(f).mode:=fmoutput; {fool fmappend}
  446. end;
  447. end;
  448. exit;
  449. end;
  450. Action := Action or (Flags and $FF);
  451. (* DenyAll if sharing not specified. *)
  452. if Flags and 112 = 0 then
  453. Action := Action or 16;
  454. asm
  455. movl $0x7f2b, %eax
  456. movl Action, %ecx
  457. movl p, %edx
  458. call syscall
  459. cmpl $0xffffffff, %eax
  460. jnz .LOPEN1
  461. movw %cx, InOutRes
  462. movw UnusedHandle, %ax
  463. .LOPEN1:
  464. movl f,%edx
  465. movw %ax,(%edx)
  466. end;
  467. if (InOutRes = 4) and Increase_File_Handle_Count then
  468. (* Trying again after increasing amount of file handles *)
  469. asm
  470. movl $0x7f2b, %eax
  471. movl Action, %ecx
  472. movl p, %edx
  473. call syscall
  474. cmpl $0xffffffff, %eax
  475. jnz .LOPEN2
  476. movw %cx, InOutRes
  477. movw UnusedHandle, %ax
  478. .LOPEN2:
  479. movl f,%edx
  480. movw %ax,(%edx)
  481. end;
  482. { for systems that have more handles }
  483. if FileRec (F).Handle > FileHandleCount then
  484. FileHandleCount := FileRec (F).Handle;
  485. if (flags and $100)<>0 then
  486. begin
  487. do_seekend(filerec(f).handle);
  488. FileRec (F).Mode := fmOutput; {fool fmappend}
  489. end;
  490. end;
  491. {$ASMMODE INTEL}
  492. function do_isdevice (Handle: longint): boolean; assembler;
  493. (*
  494. var HT, Attr: longint;
  495. begin
  496. if os_mode = osOS2 then
  497. begin
  498. if DosQueryHType (Handle, HT, Attr) <> 0 then HT := 1;
  499. end
  500. else
  501. *)
  502. asm
  503. mov ebx, Handle
  504. mov eax, 4400h
  505. call syscall
  506. mov eax, 1
  507. jc @IsDevEnd
  508. test edx, 80h
  509. jnz @IsDevEnd
  510. dec eax
  511. @IsDevEnd:
  512. end;
  513. {$ASMMODE ATT}
  514. {*****************************************************************************
  515. UnTyped File Handling
  516. *****************************************************************************}
  517. {$i file.inc}
  518. {*****************************************************************************
  519. Typed File Handling
  520. *****************************************************************************}
  521. {$i typefile.inc}
  522. {*****************************************************************************
  523. Text File Handling
  524. *****************************************************************************}
  525. {$DEFINE EOF_CTRLZ}
  526. {$i text.inc}
  527. {****************************************************************************
  528. Directory related routines.
  529. ****************************************************************************}
  530. {*****************************************************************************
  531. Directory Handling
  532. *****************************************************************************}
  533. procedure dosdir(func:byte;const s:string);
  534. var buffer:array[0..255] of char;
  535. begin
  536. move(s[1],buffer,length(s));
  537. buffer[length(s)]:=#0;
  538. allowslash(Pchar(@buffer));
  539. asm
  540. leal buffer,%edx
  541. movb func,%ah
  542. call syscall
  543. jnc .LDOS_DIRS1
  544. movw %ax,inoutres
  545. .LDOS_DIRS1:
  546. end;
  547. end;
  548. procedure MkDir (const S: string);
  549. begin
  550. if InOutRes = 0 then
  551. DosDir ($39, S);
  552. end;
  553. procedure rmdir(const s : string);
  554. begin
  555. if InOutRes = 0 then
  556. DosDir ($3A, S);
  557. end;
  558. {$ASMMODE INTEL}
  559. procedure ChDir (const S: string);
  560. var RC: longint;
  561. Buffer: array [0..255] of char;
  562. begin
  563. if InOutRes = 0 then
  564. begin
  565. (* According to EMX documentation, EMX has only one current directory
  566. for all processes, so we'll use native calls under OS/2. *)
  567. if os_Mode = osOS2 then
  568. begin
  569. if (Length (S) >= 2) and (S [2] = ':') then
  570. begin
  571. RC := DosSetDefaultDisk ((Ord (S [1]) and
  572. not ($20)) - $40);
  573. if RC <> 0 then
  574. InOutRes := RC
  575. else
  576. if Length (S) > 2 then
  577. begin
  578. Move (S [1], Buffer, Length (S));
  579. Buffer [Length (S)] := #0;
  580. AllowSlash (PChar (@Buffer));
  581. RC := DosSetCurrentDir (@Buffer);
  582. if RC <> 0 then
  583. InOutRes := RC;
  584. end;
  585. end
  586. else
  587. begin
  588. Move (S [1], Buffer, Length (S));
  589. Buffer [Length (S)] := #0;
  590. AllowSlash (PChar (@Buffer));
  591. RC := DosSetCurrentDir (@Buffer);
  592. if RC <> 0 then
  593. InOutRes := RC;
  594. end;
  595. end
  596. else
  597. if (Length (S) >= 2) and (S [2] = ':') then
  598. begin
  599. asm
  600. mov esi, S
  601. mov al, [esi + 1]
  602. and al, not (20h)
  603. sub al, 41h
  604. mov edx, eax
  605. mov ah, 0Eh
  606. call syscall
  607. mov ah, 19h
  608. call syscall
  609. cmp al, dl
  610. jz @LCHDIR
  611. mov InOutRes, 15
  612. @LCHDIR:
  613. end;
  614. if (Length (S) > 2) and (InOutRes <> 0) then
  615. DosDir ($3B, S);
  616. end
  617. else
  618. DosDir ($3B, S);
  619. end;
  620. end;
  621. {$ASMMODE ATT}
  622. procedure getdir(drivenr : byte;var dir : shortstring);
  623. {Written by Michael Van Canneyt.}
  624. var temp:array[0..255] of char;
  625. sof:Pchar;
  626. i:byte;
  627. begin
  628. sof:=pchar(@dir[4]);
  629. { dir[1..3] will contain '[drivenr]:\', but is not }
  630. { supplied by DOS, so we let dos string start at }
  631. { dir[4] }
  632. { Get dir from drivenr : 0=default, 1=A etc... }
  633. asm
  634. movb drivenr,%dl
  635. movl sof,%esi
  636. mov $0x47,%ah
  637. call syscall
  638. end;
  639. { Now Dir should be filled with directory in ASCIIZ, }
  640. { starting from dir[4] }
  641. dir[0]:=#3;
  642. dir[2]:=':';
  643. dir[3]:='\';
  644. i:=4;
  645. {Conversion to Pascal string }
  646. while (dir[i]<>#0) do
  647. begin
  648. { convert path name to DOS }
  649. if dir[i]='/' then
  650. dir[i]:='\';
  651. dir[0]:=char(i);
  652. inc(i);
  653. end;
  654. { upcase the string (FPC function) }
  655. if not (FileNameCaseSensitive) then dir:=upcase(dir);
  656. if drivenr<>0 then { Drive was supplied. We know it }
  657. dir[1]:=char(65+drivenr-1)
  658. else
  659. begin
  660. { We need to get the current drive from DOS function 19H }
  661. { because the drive was the default, which can be unknown }
  662. asm
  663. movb $0x19,%ah
  664. call syscall
  665. addb $65,%al
  666. movb %al,i
  667. end;
  668. dir[1]:=char(i);
  669. end;
  670. end;
  671. {****************************************************************************
  672. System unit initialization.
  673. ****************************************************************************}
  674. function GetFileHandleCount: longint;
  675. var L1, L2: longint;
  676. begin
  677. L1 := 0; (* Don't change the amount, just check. *)
  678. if DosSetRelMaxFH (L1, L2) <> 0 then GetFileHandleCount := 50
  679. else GetFileHandleCount := L2;
  680. end;
  681. var pib:Pprocessinfoblock;
  682. tib:Pthreadinfoblock;
  683. begin
  684. {Determine the operating system we are running on.}
  685. asm
  686. movl $0,os_mode
  687. movw $0x7f0a,%ax
  688. call syscall
  689. testw $512,%bx {Bit 9 is OS/2 flag.}
  690. setnzb os_mode
  691. testw $4096,%bx
  692. jz .LnoRSX
  693. movl $2,os_mode
  694. .LnoRSX:
  695. end;
  696. {$ASMMODE DIRECT}
  697. {Enable the brk area by initializing it with the initial heap size.}
  698. asm
  699. movw $0x7f01,%ax
  700. movl HEAPSIZE,%edx
  701. addl __heap_base,%edx
  702. call ___SYSCALL
  703. cmpl $-1,%eax
  704. jnz Lheapok
  705. pushl $204
  706. {call RUNERROR$$WORD}
  707. Lheapok:
  708. end;
  709. {$ASMMODE ATT}
  710. {Now request, if we are running under DOS,
  711. read-access to the first meg. of memory.}
  712. if os_mode in [osDOS,osDPMI] then
  713. asm
  714. movw $0x7f13,%ax
  715. xorl %ebx,%ebx
  716. movl $0xfff,%ecx
  717. xorl %edx,%edx
  718. call syscall
  719. movl %eax,first_meg
  720. end
  721. else
  722. begin
  723. first_meg := nil;
  724. (* Initialize the amount of file handles *)
  725. FileHandleCount := GetFileHandleCount;
  726. end;
  727. {At 0.9.2, case for enumeration does not work.}
  728. case os_mode of
  729. osDOS:
  730. stackbottom:=0; {In DOS mode, heap_brk is also the
  731. stack bottom.}
  732. osOS2:
  733. begin
  734. dosgetinfoblocks(tib,pib);
  735. stackbottom:=longint(tib^.stack);
  736. end;
  737. osDPMI:
  738. stackbottom:=0; {Not sure how to get it, but seems to be
  739. always zero.}
  740. end;
  741. exitproc:=nil;
  742. {$ifdef MT}
  743. if os_mode = os_OS2 then
  744. begin
  745. { allocate one ThreadVar entry from the OS, we use this entry }
  746. { for a pointer to our threadvars }
  747. DataIndex := TlsAlloc;
  748. { the exceptions use threadvars so do this _before_ initexceptions }
  749. AllocateThreadVars;
  750. end;
  751. {$endif MT}
  752. {Initialize the heap.}
  753. initheap;
  754. { ... and exceptions }
  755. InitExceptions;
  756. { to test stack depth }
  757. loweststack:=maxlongint;
  758. OpenStdIO(Input,fmInput,StdInputHandle);
  759. OpenStdIO(Output,fmOutput,StdOutputHandle);
  760. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  761. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  762. { no I/O-Error }
  763. inoutres:=0;
  764. end.
  765. {
  766. $Log$
  767. Revision 1.5 2001-01-23 20:38:59 hajny
  768. + beginning of the OS/2 version
  769. Revision 1.4 2000/11/13 21:23:38 hajny
  770. * ParamStr (0) fixed
  771. Revision 1.3 2000/11/11 23:12:39 hajny
  772. * stackcheck alias corrected
  773. Revision 1.2 2000/10/15 20:43:10 hajny
  774. * ChDir correction, unit name changed
  775. Revision 1.1 2000/10/15 08:19:49 peter
  776. * system unit rename for 1.1 branch
  777. Revision 1.3 2000/09/29 21:49:41 jonas
  778. * removed warnings
  779. Revision 1.2 2000/07/14 10:33:11 michael
  780. + Conditionals fixed
  781. Revision 1.1 2000/07/13 06:31:07 michael
  782. + Initial import
  783. }