system.pas 25 KB

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