system.pas 24 KB

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