system.pas 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  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: '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) and (l<=paramcount) then
  159. begin
  160. p:=args;
  161. paramstr:=strpas(p[l]);
  162. end
  163. else paramstr:='';
  164. end;
  165. {$asmmode att}
  166. procedure randomize;
  167. var hl:longint;
  168. begin
  169. asm
  170. movb $0x2c,%ah
  171. call syscall
  172. movw %cx,-4(%ebp)
  173. movw %dx,-2(%ebp)
  174. end;
  175. randseed:=hl;
  176. end;
  177. {****************************************************************************
  178. Heap management releated routines.
  179. ****************************************************************************}
  180. { this function allows to extend the heap by calling
  181. syscall $7f00 resizes the brk area}
  182. function sbrk(size:longint):longint; assembler;
  183. asm
  184. movl size,%edx
  185. movw $0x7f00,%ax
  186. call syscall
  187. end;
  188. {$ASMMODE direct}
  189. function getheapstart:pointer;assembler;
  190. asm
  191. movl __heap_base,%eax
  192. end ['EAX'];
  193. function getheapsize:longint;assembler;
  194. asm
  195. movl HEAPSIZE,%eax
  196. end ['EAX'];
  197. {$ASMMODE ATT}
  198. {$i heap.inc}
  199. {****************************************************************************
  200. Low Level File Routines
  201. ****************************************************************************}
  202. procedure allowslash(p:Pchar);
  203. {Allow slash as backslash.}
  204. var i:longint;
  205. begin
  206. for i:=0 to strlen(p) do
  207. if p[i]='/' then p[i]:='\';
  208. end;
  209. procedure do_close(h:longint);
  210. begin
  211. { Only three standard handles under real OS/2 }
  212. if (h > 4) or
  213. (os_MODE = osOS2) and (h > 2) then
  214. begin
  215. asm
  216. movb $0x3e,%ah
  217. movl h,%ebx
  218. call syscall
  219. end;
  220. end;
  221. end;
  222. procedure do_erase(p:Pchar);
  223. begin
  224. allowslash(p);
  225. asm
  226. movl P,%edx
  227. movb $0x41,%ah
  228. call syscall
  229. jnc .LERASE1
  230. movw %ax,inoutres;
  231. .LERASE1:
  232. end;
  233. end;
  234. procedure do_rename(p1,p2:Pchar);
  235. begin
  236. allowslash(p1);
  237. allowslash(p2);
  238. asm
  239. movl P1, %edx
  240. movl P2, %edi
  241. movb $0x56,%ah
  242. call syscall
  243. jnc .LRENAME1
  244. movw %ax,inoutres;
  245. .LRENAME1:
  246. end;
  247. end;
  248. function do_read(h,addr,len:longint):longint; assembler;
  249. asm
  250. movl len,%ecx
  251. movl addr,%edx
  252. movl h,%ebx
  253. movb $0x3f,%ah
  254. call syscall
  255. jnc .LDOSREAD1
  256. movw %ax,inoutres;
  257. xorl %eax,%eax
  258. .LDOSREAD1:
  259. end;
  260. function do_write(h,addr,len:longint) : longint; assembler;
  261. asm
  262. movl len,%ecx
  263. movl addr,%edx
  264. movl h,%ebx
  265. movb $0x40,%ah
  266. call syscall
  267. jnc .LDOSWRITE1
  268. movw %ax,inoutres;
  269. .LDOSWRITE1:
  270. end;
  271. function do_filepos(handle:longint): longint; assembler;
  272. asm
  273. movw $0x4201,%ax
  274. movl handle,%ebx
  275. xorl %edx,%edx
  276. call syscall
  277. jnc .LDOSFILEPOS
  278. movw %ax,inoutres;
  279. xorl %eax,%eax
  280. .LDOSFILEPOS:
  281. end;
  282. procedure do_seek(handle,pos:longint); assembler;
  283. asm
  284. movw $0x4200,%ax
  285. movl handle,%ebx
  286. movl pos,%edx
  287. call syscall
  288. jnc .LDOSSEEK1
  289. movw %ax,inoutres;
  290. .LDOSSEEK1:
  291. end;
  292. function do_seekend(handle:longint):longint; assembler;
  293. asm
  294. movw $0x4202,%ax
  295. movl handle,%ebx
  296. xorl %edx,%edx
  297. call syscall
  298. jnc .Lset_at_end1
  299. movw %ax,inoutres;
  300. xorl %eax,%eax
  301. .Lset_at_end1:
  302. end;
  303. function do_filesize(handle:longint):longint;
  304. var aktfilepos:longint;
  305. begin
  306. aktfilepos:=do_filepos(handle);
  307. do_filesize:=do_seekend(handle);
  308. do_seek(handle,aktfilepos);
  309. end;
  310. procedure do_truncate(handle,pos:longint); assembler;
  311. asm
  312. (* DOS function 40h isn't safe for this according to EMX documentation
  313. movl $0x4200,%eax
  314. movl 8(%ebp),%ebx
  315. movl 12(%ebp),%edx
  316. call syscall
  317. jc .LTruncate1
  318. movl 8(%ebp),%ebx
  319. movl 12(%ebp),%edx
  320. movl %ebp,%edx
  321. xorl %ecx,%ecx
  322. movb $0x40,%ah
  323. call syscall
  324. *)
  325. movl $0x7F25,%eax
  326. movl Handle,%ebx
  327. movl Pos,%edx
  328. call syscall
  329. inc %eax
  330. movl %ecx, %eax
  331. jnz .LTruncate1
  332. (* File position is undefined after truncation, move to the end. *)
  333. movl $0x4202,%eax
  334. movl Handle,%ebx
  335. movl $0,%edx
  336. call syscall
  337. jnc .LTruncate2
  338. .LTruncate1:
  339. movw %ax,inoutres;
  340. .LTruncate2:
  341. end;
  342. const
  343. FileHandleCount: longint = 20;
  344. function Increase_File_Handle_Count: boolean;
  345. var Err: word;
  346. L1, L2: longint;
  347. begin
  348. if os_mode = osOS2 then
  349. begin
  350. L1 := 10;
  351. if DosSetRelMaxFH (L1, L2) <> 0 then
  352. Increase_File_Handle_Count := false
  353. else
  354. if L2 > FileHandleCount then
  355. begin
  356. FileHandleCount := L2;
  357. Increase_File_Handle_Count := true;
  358. end
  359. else
  360. Increase_File_Handle_Count := false;
  361. end
  362. else
  363. begin
  364. Inc (FileHandleCount, 10);
  365. Err := 0;
  366. asm
  367. movl $0x6700, %eax
  368. movl FileHandleCount, %ebx
  369. call syscall
  370. jnc .LIncFHandles
  371. movw %ax, Err
  372. .LIncFHandles:
  373. end;
  374. if Err <> 0 then
  375. begin
  376. Increase_File_Handle_Count := false;
  377. Dec (FileHandleCount, 10);
  378. end
  379. else
  380. Increase_File_Handle_Count := true;
  381. end;
  382. end;
  383. procedure do_open(var f;p:pchar;flags:longint);
  384. {
  385. filerec and textrec have both handle and mode as the first items so
  386. they could use the same routine for opening/creating.
  387. when (flags and $100) the file will be append
  388. when (flags and $1000) the file will be truncate/rewritten
  389. when (flags and $10000) there is no check for close (needed for textfiles)
  390. }
  391. var Action: longint;
  392. begin
  393. allowslash(p);
  394. { close first if opened }
  395. if ((flags and $10000)=0) then
  396. begin
  397. case filerec(f).mode of
  398. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  399. fmclosed:;
  400. else
  401. begin
  402. inoutres:=102; {not assigned}
  403. exit;
  404. end;
  405. end;
  406. end;
  407. { reset file handle }
  408. filerec(f).handle := UnusedHandle;
  409. Action := 0;
  410. { convert filemode to filerec modes }
  411. case (flags and 3) of
  412. 0 : filerec(f).mode:=fminput;
  413. 1 : filerec(f).mode:=fmoutput;
  414. 2 : filerec(f).mode:=fminout;
  415. end;
  416. if (flags and $1000)<>0 then
  417. Action := $50000; (* Create / replace *)
  418. { empty name is special }
  419. if p[0]=#0 then
  420. begin
  421. case FileRec(f).mode of
  422. fminput :
  423. FileRec(f).Handle:=StdInputHandle;
  424. fminout, { this is set by rewrite }
  425. fmoutput :
  426. FileRec(f).Handle:=StdOutputHandle;
  427. fmappend :
  428. begin
  429. FileRec(f).Handle:=StdOutputHandle;
  430. FileRec(f).mode:=fmoutput; {fool fmappend}
  431. end;
  432. end;
  433. exit;
  434. end;
  435. Action := Action or (Flags and $FF);
  436. (* DenyAll if sharing not specified. *)
  437. if Flags and 112 = 0 then
  438. Action := Action or 16;
  439. asm
  440. movl $0x7f2b, %eax
  441. movl Action, %ecx
  442. movl p, %edx
  443. call syscall
  444. cmpl $0xffffffff, %eax
  445. jnz .LOPEN1
  446. movw %cx, InOutRes
  447. movw UnusedHandle, %ax
  448. .LOPEN1:
  449. movl f,%edx
  450. movw %ax,(%edx)
  451. end;
  452. if (InOutRes = 4) and Increase_File_Handle_Count then
  453. (* Trying again after increasing amount of file handles *)
  454. asm
  455. movl $0x7f2b, %eax
  456. movl Action, %ecx
  457. movl p, %edx
  458. call syscall
  459. cmpl $0xffffffff, %eax
  460. jnz .LOPEN2
  461. movw %cx, InOutRes
  462. movw UnusedHandle, %ax
  463. .LOPEN2:
  464. movl f,%edx
  465. movw %ax,(%edx)
  466. end;
  467. { for systems that have more handles }
  468. if FileRec (F).Handle > FileHandleCount then
  469. FileHandleCount := FileRec (F).Handle;
  470. if (flags and $100)<>0 then
  471. begin
  472. do_seekend(filerec(f).handle);
  473. FileRec (F).Mode := fmOutput; {fool fmappend}
  474. end;
  475. end;
  476. {$ASMMODE INTEL}
  477. function do_isdevice (Handle: longint): boolean; assembler;
  478. (*
  479. var HT, Attr: longint;
  480. begin
  481. if os_mode = osOS2 then
  482. begin
  483. if DosQueryHType (Handle, HT, Attr) <> 0 then HT := 1;
  484. end
  485. else
  486. *)
  487. asm
  488. mov ebx, Handle
  489. mov eax, 4400h
  490. call syscall
  491. mov eax, 1
  492. jc @IsDevEnd
  493. test edx, 80h
  494. jnz @IsDevEnd
  495. dec eax
  496. @IsDevEnd:
  497. end;
  498. {$ASMMODE ATT}
  499. {*****************************************************************************
  500. UnTyped File Handling
  501. *****************************************************************************}
  502. {$i file.inc}
  503. {*****************************************************************************
  504. Typed File Handling
  505. *****************************************************************************}
  506. {$i typefile.inc}
  507. {*****************************************************************************
  508. Text File Handling
  509. *****************************************************************************}
  510. {$DEFINE EOF_CTRLZ}
  511. {$i text.inc}
  512. {****************************************************************************
  513. Directory related routines.
  514. ****************************************************************************}
  515. {*****************************************************************************
  516. Directory Handling
  517. *****************************************************************************}
  518. procedure dosdir(func:byte;const s:string);
  519. var buffer:array[0..255] of char;
  520. begin
  521. move(s[1],buffer,length(s));
  522. buffer[length(s)]:=#0;
  523. allowslash(Pchar(@buffer));
  524. asm
  525. leal buffer,%edx
  526. movb func,%ah
  527. call syscall
  528. jnc .LDOS_DIRS1
  529. movw %ax,inoutres
  530. .LDOS_DIRS1:
  531. end;
  532. end;
  533. procedure MkDir (const S: string);
  534. begin
  535. if InOutRes = 0 then
  536. DosDir ($39, S);
  537. end;
  538. procedure rmdir(const s : string);
  539. begin
  540. if InOutRes = 0 then
  541. DosDir ($3A, S);
  542. end;
  543. {$ASMMODE INTEL}
  544. procedure ChDir (const S: string);
  545. var RC: longint;
  546. Buffer: array [0..255] of char;
  547. begin
  548. if InOutRes = 0 then
  549. begin
  550. (* According to EMX documentation, EMX has only one current directory
  551. for all processes, so we'll use native calls under OS/2. *)
  552. if os_Mode = osOS2 then
  553. begin
  554. if (Length (S) >= 2) and (S [2] = ':') then
  555. begin
  556. RC := DosSetDefaultDisk ((Ord (S [1]) and
  557. not ($20)) - $40);
  558. if RC <> 0 then
  559. InOutRes := RC
  560. else
  561. if Length (S) > 2 then
  562. begin
  563. Move (S [1], Buffer, Length (S));
  564. Buffer [Length (S)] := #0;
  565. AllowSlash (PChar (@Buffer));
  566. RC := DosSetCurrentDir (@Buffer);
  567. if RC <> 0 then
  568. InOutRes := RC;
  569. end;
  570. end
  571. else
  572. begin
  573. Move (S [1], Buffer, Length (S));
  574. Buffer [Length (S)] := #0;
  575. AllowSlash (PChar (@Buffer));
  576. RC := DosSetCurrentDir (@Buffer);
  577. if RC <> 0 then
  578. InOutRes := RC;
  579. end;
  580. end
  581. else
  582. if (Length (S) >= 2) and (S [2] = ':') then
  583. begin
  584. asm
  585. mov esi, S
  586. mov al, [esi + 1]
  587. and al, not (20h)
  588. sub al, 41h
  589. mov edx, eax
  590. mov ah, 0Eh
  591. call syscall
  592. mov ah, 19h
  593. call syscall
  594. cmp al, dl
  595. jz @LCHDIR
  596. mov InOutRes, 15
  597. @LCHDIR:
  598. end;
  599. if (Length (S) > 2) and (InOutRes <> 0) then
  600. DosDir ($3B, S);
  601. end
  602. else
  603. DosDir ($3B, S);
  604. end;
  605. end;
  606. {$ASMMODE ATT}
  607. procedure getdir(drivenr : byte;var dir : shortstring);
  608. {Written by Michael Van Canneyt.}
  609. var temp:array[0..255] of char;
  610. sof:Pchar;
  611. i:byte;
  612. begin
  613. sof:=pchar(@dir[4]);
  614. { dir[1..3] will contain '[drivenr]:\', but is not }
  615. { supplied by DOS, so we let dos string start at }
  616. { dir[4] }
  617. { Get dir from drivenr : 0=default, 1=A etc... }
  618. asm
  619. movb drivenr,%dl
  620. movl sof,%esi
  621. mov $0x47,%ah
  622. call syscall
  623. end;
  624. { Now Dir should be filled with directory in ASCIIZ, }
  625. { starting from dir[4] }
  626. dir[0]:=#3;
  627. dir[2]:=':';
  628. dir[3]:='\';
  629. i:=4;
  630. {Conversion to Pascal string }
  631. while (dir[i]<>#0) do
  632. begin
  633. { convert path name to DOS }
  634. if dir[i]='/' then
  635. dir[i]:='\';
  636. dir[0]:=char(i);
  637. inc(i);
  638. end;
  639. { upcase the string (FPC function) }
  640. if not (FileNameCaseSensitive) then dir:=upcase(dir);
  641. if drivenr<>0 then { Drive was supplied. We know it }
  642. dir[1]:=char(65+drivenr-1)
  643. else
  644. begin
  645. { We need to get the current drive from DOS function 19H }
  646. { because the drive was the default, which can be unknown }
  647. asm
  648. movb $0x19,%ah
  649. call syscall
  650. addb $65,%al
  651. movb %al,i
  652. end;
  653. dir[1]:=char(i);
  654. end;
  655. end;
  656. {****************************************************************************
  657. System unit initialization.
  658. ****************************************************************************}
  659. function GetFileHandleCount: longint;
  660. var L1, L2: longint;
  661. begin
  662. L1 := 0; (* Don't change the amount, just check. *)
  663. if DosSetRelMaxFH (L1, L2) <> 0 then GetFileHandleCount := 50
  664. else GetFileHandleCount := L2;
  665. end;
  666. var pib:Pprocessinfoblock;
  667. tib:Pthreadinfoblock;
  668. begin
  669. {Determine the operating system we are running on.}
  670. asm
  671. movl $0,os_mode
  672. movw $0x7f0a,%ax
  673. call syscall
  674. testw $512,%bx {Bit 9 is OS/2 flag.}
  675. setnzb os_mode
  676. testw $4096,%bx
  677. jz .LnoRSX
  678. movl $2,os_mode
  679. .LnoRSX:
  680. end;
  681. {$ASMMODE DIRECT}
  682. {Enable the brk area by initializing it with the initial heap size.}
  683. asm
  684. movw $0x7f01,%ax
  685. movl HEAPSIZE,%edx
  686. addl __heap_base,%edx
  687. call ___SYSCALL
  688. cmpl $-1,%eax
  689. jnz Lheapok
  690. pushl $204
  691. {call RUNERROR$$WORD}
  692. Lheapok:
  693. end;
  694. {$ASMMODE ATT}
  695. {Now request, if we are running under DOS,
  696. read-access to the first meg. of memory.}
  697. if os_mode in [osDOS,osDPMI] then
  698. asm
  699. movw $0x7f13,%ax
  700. xorl %ebx,%ebx
  701. movl $0xfff,%ecx
  702. xorl %edx,%edx
  703. call syscall
  704. movl %eax,first_meg
  705. end
  706. else
  707. begin
  708. first_meg := nil;
  709. (* Initialize the amount of file handles *)
  710. FileHandleCount := GetFileHandleCount;
  711. end;
  712. {At 0.9.2, case for enumeration does not work.}
  713. case os_mode of
  714. osDOS:
  715. stackbottom:=0; {In DOS mode, heap_brk is also the
  716. stack bottom.}
  717. osOS2:
  718. begin
  719. dosgetinfoblocks(tib,pib);
  720. stackbottom:=longint(tib^.stack);
  721. end;
  722. osDPMI:
  723. stackbottom:=0; {Not sure how to get it, but seems to be
  724. always zero.}
  725. end;
  726. exitproc:=nil;
  727. {Initialize the heap.}
  728. initheap;
  729. { ... and exceptions }
  730. InitExceptions;
  731. { to test stack depth }
  732. loweststack:=maxlongint;
  733. OpenStdIO(Input,fmInput,StdInputHandle);
  734. OpenStdIO(Output,fmOutput,StdOutputHandle);
  735. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  736. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  737. { no I/O-Error }
  738. inoutres:=0;
  739. end.
  740. {
  741. $Log$
  742. Revision 1.2 2000-10-15 20:43:10 hajny
  743. * ChDir correction, unit name changed
  744. Revision 1.1 2000/10/15 08:19:49 peter
  745. * system unit rename for 1.1 branch
  746. Revision 1.3 2000/09/29 21:49:41 jonas
  747. * removed warnings
  748. Revision 1.2 2000/07/14 10:33:11 michael
  749. + Conditionals fixed
  750. Revision 1.1 2000/07/13 06:31:07 michael
  751. + Initial import
  752. }