system.pp 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by the Free Pascal development team.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit system;
  12. interface
  13. { two debug conditionnals can be used
  14. - SYSTEMDEBUG
  15. -for STACK checks
  16. -for non closed files at exit (or at any time with GDB)
  17. - SYSTEM_DEBUG_STARTUP
  18. specifically for
  19. - proxy command line (DJGPP feature)
  20. - list of args
  21. - list of env variables (PM) }
  22. { include system-independent routine headers }
  23. {$I systemh.inc}
  24. { include heap support headers }
  25. {$I heaph.inc}
  26. const
  27. { Default filehandles }
  28. UnusedHandle = -1;
  29. StdInputHandle = 0;
  30. StdOutputHandle = 1;
  31. StdErrorHandle = 2;
  32. FileNameCaseSensitive : boolean = false;
  33. { Default memory segments (Tp7 compatibility) }
  34. seg0040 = $0040;
  35. segA000 = $A000;
  36. segB000 = $B000;
  37. segB800 = $B800;
  38. var
  39. { Mem[] support }
  40. mem : array[0..$7fffffff] of byte absolute $0:$0;
  41. memw : array[0..$7fffffff] of word absolute $0:$0;
  42. meml : array[0..$7fffffff] of longint absolute $0:$0;
  43. { C-compatible arguments and environment }
  44. argc : longint;
  45. argv : ppchar;
  46. envp : ppchar;
  47. dos_argv0 : pchar;
  48. {$ifndef RTLLITE}
  49. { System info }
  50. LFNSupport : boolean;
  51. {$endif RTLLITE}
  52. type
  53. { Dos Extender info }
  54. p_stub_info = ^t_stub_info;
  55. t_stub_info = packed record
  56. magic : array[0..15] of char;
  57. size : longint;
  58. minstack : longint;
  59. memory_handle : longint;
  60. initial_size : longint;
  61. minkeep : word;
  62. ds_selector : word;
  63. ds_segment : word;
  64. psp_selector : word;
  65. cs_selector : word;
  66. env_size : word;
  67. basename : array[0..7] of char;
  68. argv0 : array [0..15] of char;
  69. dpmi_server : array [0..15] of char;
  70. end;
  71. p_go32_info_block = ^t_go32_info_block;
  72. t_go32_info_block = packed record
  73. size_of_this_structure_in_bytes : longint; {offset 0}
  74. linear_address_of_primary_screen : longint; {offset 4}
  75. linear_address_of_secondary_screen : longint; {offset 8}
  76. linear_address_of_transfer_buffer : longint; {offset 12}
  77. size_of_transfer_buffer : longint; {offset 16}
  78. pid : longint; {offset 20}
  79. master_interrupt_controller_base : byte; {offset 24}
  80. slave_interrupt_controller_base : byte; {offset 25}
  81. selector_for_linear_memory : word; {offset 26}
  82. linear_address_of_stub_info_structure : longint; {offset 28}
  83. linear_address_of_original_psp : longint; {offset 32}
  84. run_mode : word; {offset 36}
  85. run_mode_info : word; {offset 38}
  86. end;
  87. var
  88. stub_info : p_stub_info;
  89. go32_info_block : t_go32_info_block;
  90. {$ifdef SYSTEMDEBUG}
  91. const
  92. accept_sbrk : boolean = true;
  93. {$endif}
  94. {
  95. necessary for objects.pas, should be removed (at least from the interface
  96. to the implementation)
  97. }
  98. type
  99. trealregs=record
  100. realedi,realesi,realebp,realres,
  101. realebx,realedx,realecx,realeax : longint;
  102. realflags,
  103. reales,realds,realfs,realgs,
  104. realip,realcs,realsp,realss : word;
  105. end;
  106. function do_write(h,addr,len : longint) : longint;
  107. function do_read(h,addr,len : longint) : longint;
  108. procedure syscopyfromdos(addr : longint; len : longint);
  109. procedure syscopytodos(addr : longint; len : longint);
  110. procedure sysrealintr(intnr : word;var regs : trealregs);
  111. function tb : longint;
  112. implementation
  113. { include system independent routines }
  114. {$I system.inc}
  115. const
  116. carryflag = 1;
  117. type
  118. tseginfo=packed record
  119. offset : pointer;
  120. segment : word;
  121. end;
  122. var
  123. doscmd : string[128]; { Dos commandline copied from PSP, max is 128 chars }
  124. old_int00 : tseginfo;cvar;
  125. old_int75 : tseginfo;cvar;
  126. {$asmmode ATT}
  127. {*****************************************************************************
  128. Go32 Helpers
  129. *****************************************************************************}
  130. function far_strlen(selector : word;linear_address : longint) : longint;assembler;
  131. asm
  132. movl linear_address,%edx
  133. movl %edx,%ecx
  134. movw selector,%gs
  135. .Larg19:
  136. movb %gs:(%edx),%al
  137. testb %al,%al
  138. je .Larg20
  139. incl %edx
  140. jmp .Larg19
  141. .Larg20:
  142. movl %edx,%eax
  143. subl %ecx,%eax
  144. end;
  145. function tb : longint;
  146. begin
  147. tb:=go32_info_block.linear_address_of_transfer_buffer;
  148. end;
  149. function tb_segment : longint;
  150. begin
  151. tb_segment:=go32_info_block.linear_address_of_transfer_buffer shr 4;
  152. end;
  153. function tb_offset : longint;
  154. begin
  155. tb_offset:=go32_info_block.linear_address_of_transfer_buffer and $f;
  156. end;
  157. function tb_size : longint;
  158. begin
  159. tb_size:=go32_info_block.size_of_transfer_buffer;
  160. end;
  161. function dos_selector : word;
  162. begin
  163. dos_selector:=go32_info_block.selector_for_linear_memory;
  164. end;
  165. function get_ds : word;assembler;
  166. asm
  167. movw %ds,%ax
  168. end;
  169. function get_cs : word;assembler;
  170. asm
  171. movw %cs,%ax
  172. end;
  173. procedure sysseg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
  174. begin
  175. if count=0 then
  176. exit;
  177. if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
  178. asm
  179. pushw %es
  180. pushw %ds
  181. cld
  182. movl count,%ecx
  183. movl source,%esi
  184. movl dest,%edi
  185. movw dseg,%ax
  186. movw %ax,%es
  187. movw sseg,%ax
  188. movw %ax,%ds
  189. movl %ecx,%eax
  190. shrl $2,%ecx
  191. rep
  192. movsl
  193. movl %eax,%ecx
  194. andl $3,%ecx
  195. rep
  196. movsb
  197. popw %ds
  198. popw %es
  199. end ['ESI','EDI','ECX','EAX']
  200. else if (source<dest) then
  201. { copy backward for overlapping }
  202. asm
  203. pushw %es
  204. pushw %ds
  205. std
  206. movl count,%ecx
  207. movl source,%esi
  208. movl dest,%edi
  209. movw dseg,%ax
  210. movw %ax,%es
  211. movw sseg,%ax
  212. movw %ax,%ds
  213. addl %ecx,%esi
  214. addl %ecx,%edi
  215. movl %ecx,%eax
  216. andl $3,%ecx
  217. orl %ecx,%ecx
  218. jz .LSEG_MOVE1
  219. { calculate esi and edi}
  220. decl %esi
  221. decl %edi
  222. rep
  223. movsb
  224. incl %esi
  225. incl %edi
  226. .LSEG_MOVE1:
  227. subl $4,%esi
  228. subl $4,%edi
  229. movl %eax,%ecx
  230. shrl $2,%ecx
  231. rep
  232. movsl
  233. cld
  234. popw %ds
  235. popw %es
  236. end ['ESI','EDI','ECX'];
  237. end;
  238. var
  239. _args : ppchar;external name '_args';
  240. procedure setup_arguments;
  241. function atohex(s : pchar) : longint;
  242. var
  243. rv : longint;
  244. v : byte;
  245. begin
  246. rv:=0;
  247. while (s^<>#0) do
  248. begin
  249. v:=byte(s^)-byte('0');
  250. if (v > 9) then
  251. dec(v,7);
  252. v:=v and 15; { in case it's lower case }
  253. rv:=(rv shl 4) or v;
  254. inc(longint(s));
  255. end;
  256. atohex:=rv;
  257. end;
  258. type
  259. arrayword = array [0..255] of word;
  260. var
  261. psp : word;
  262. i,j : longint;
  263. quote : char;
  264. proxy_s : string[50];
  265. al,proxy_argc,proxy_seg,proxy_ofs,lin : longint;
  266. largs : array[0..127] of pchar;
  267. rm_argv : ^arrayword;
  268. argv0len : longint;
  269. useproxy : boolean;
  270. hp : ppchar;
  271. begin
  272. fillchar(largs,sizeof(largs),0);
  273. psp:=stub_info^.psp_selector;
  274. largs[0]:=dos_argv0;
  275. argc := 1;
  276. sysseg_move(psp, 128, get_ds, longint(@doscmd), 128);
  277. {$IfDef SYSTEM_DEBUG_STARTUP}
  278. Writeln(stderr,'Dos command line is #',doscmd,'# size = ',length(doscmd));
  279. {$EndIf }
  280. { setup cmdline variable }
  281. argv0len:=strlen(dos_argv0);
  282. cmdline:=sysgetmem(argv0len+length(doscmd)+1);
  283. move(dos_argv0^,cmdline^,argv0len);
  284. move(doscmd[1],cmdline[argv0len],length(doscmd));
  285. cmdline[argv0len+length(doscmd)]:=#0;
  286. j := 1;
  287. quote := #0;
  288. for i:=1 to length(doscmd) do
  289. Begin
  290. if doscmd[i] = quote then
  291. begin
  292. quote := #0;
  293. if (i>1) and ((doscmd[i-1]='''') or (doscmd[i-1]='"')) then
  294. begin
  295. j := i+1;
  296. doscmd[i] := #0;
  297. continue;
  298. end;
  299. doscmd[i] := #0;
  300. largs[argc]:=@doscmd[j];
  301. inc(argc);
  302. j := i+1;
  303. end
  304. else
  305. if (quote = #0) and ((doscmd[i] = '''') or (doscmd[i]='"')) then
  306. begin
  307. quote := doscmd[i];
  308. j := i + 1;
  309. end else
  310. if (quote = #0) and ((doscmd[i] = ' ')
  311. or (doscmd[i] = #9) or (doscmd[i] = #10) or
  312. (doscmd[i] = #12) or (doscmd[i] = #9)) then
  313. begin
  314. doscmd[i]:=#0;
  315. if j<i then
  316. begin
  317. largs[argc]:=@doscmd[j];
  318. inc(argc);
  319. j := i+1;
  320. end else inc(j);
  321. end else
  322. if (i = length(doscmd)) then
  323. begin
  324. doscmd[i+1]:=#0;
  325. largs[argc]:=@doscmd[j];
  326. inc(argc);
  327. end;
  328. end;
  329. hp:=envp;
  330. useproxy:=false;
  331. while assigned(hp^) do
  332. begin
  333. if (hp^[0]=' ') then
  334. begin
  335. proxy_s:=strpas(hp^);
  336. if Copy(proxy_s,1,7)=' !proxy' then
  337. begin
  338. proxy_s[13]:=#0;
  339. proxy_s[18]:=#0;
  340. proxy_s[23]:=#0;
  341. largs[2]:=@proxy_s[9];
  342. largs[3]:=@proxy_s[14];
  343. largs[4]:=@proxy_s[19];
  344. useproxy:=true;
  345. break;
  346. end;
  347. end;
  348. inc(hp);
  349. end;
  350. if (not useproxy) and
  351. (argc > 1) and (far_strlen(get_ds,longint(largs[1])) = 6) then
  352. begin
  353. move(largs[1]^,proxy_s[1],6);
  354. proxy_s[0] := #6;
  355. if (proxy_s = '!proxy') then
  356. useproxy:=true;
  357. end;
  358. if useproxy then
  359. begin
  360. proxy_argc := atohex(largs[2]);
  361. proxy_seg := atohex(largs[3]);
  362. proxy_ofs := atohex(largs[4]);
  363. {$IfDef SYSTEM_DEBUG_STARTUP}
  364. Writeln(stderr,'proxy command line found');
  365. writeln(stderr,'argc: ',proxy_argc,' seg: ',proxy_seg,' ofs: ',proxy_ofs);
  366. {$EndIf SYSTEM_DEBUG_STARTUP}
  367. if proxy_argc>128 then
  368. proxy_argc:=128;
  369. rm_argv := sysgetmem(proxy_argc*sizeof(word));
  370. sysseg_move(dos_selector,proxy_seg*16+proxy_ofs, get_ds,longint(rm_argv),proxy_argc*sizeof(word));
  371. for i:=0 to proxy_argc - 1 do
  372. begin
  373. lin := proxy_seg*16 + rm_argv^[i];
  374. al :=far_strlen(dos_selector, lin);
  375. largs[i] := sysgetmem(al+1);
  376. sysseg_move(dos_selector, lin, get_ds,longint(largs[i]), al+1);
  377. {$IfDef SYSTEM_DEBUG_STARTUP}
  378. Writeln(stderr,'arg ',i,' #',rm_argv^[i],'#',al,'#',largs[i],'#');
  379. {$EndIf SYSTEM_DEBUG_STARTUP}
  380. end;
  381. sysfreemem(rm_argv);
  382. argc := proxy_argc;
  383. end;
  384. argv := sysgetmem(argc shl 2);
  385. for i := 0 to argc-1 do
  386. argv[i]:=largs[i];
  387. _args:=argv;
  388. end;
  389. function strcopy(dest,source : pchar) : pchar;
  390. begin
  391. asm
  392. cld
  393. movl 12(%ebp),%edi
  394. movl $0xffffffff,%ecx
  395. xorb %al,%al
  396. repne
  397. scasb
  398. not %ecx
  399. movl 8(%ebp),%edi
  400. movl 12(%ebp),%esi
  401. movl %ecx,%eax
  402. shrl $2,%ecx
  403. rep
  404. movsl
  405. movl %eax,%ecx
  406. andl $3,%ecx
  407. rep
  408. movsb
  409. movl 8(%ebp),%eax
  410. leave
  411. ret $8
  412. end;
  413. end;
  414. var
  415. __stubinfo : p_stub_info;external name '__stubinfo';
  416. ___dos_argv0 : pchar;external name '___dos_argv0';
  417. procedure setup_environment;
  418. var env_selector : word;
  419. env_count : longint;
  420. dos_env,cp : pchar;
  421. begin
  422. stub_info:=__stubinfo;
  423. dos_env := sysgetmem(stub_info^.env_size);
  424. env_count:=0;
  425. sysseg_move(stub_info^.psp_selector,$2c, get_ds, longint(@env_selector), 2);
  426. sysseg_move(env_selector, 0, get_ds, longint(dos_env), stub_info^.env_size);
  427. cp:=dos_env;
  428. while cp ^ <> #0 do
  429. begin
  430. inc(env_count);
  431. while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
  432. inc(longint(cp)); { skip to next character }
  433. end;
  434. envp := sysgetmem((env_count+1) * sizeof(pchar));
  435. if (envp = nil) then exit;
  436. cp:=dos_env;
  437. env_count:=0;
  438. while cp^ <> #0 do
  439. begin
  440. envp[env_count] := sysgetmem(strlen(cp)+1);
  441. strcopy(envp[env_count], cp);
  442. {$IfDef SYSTEM_DEBUG_STARTUP}
  443. Writeln(stderr,'env ',env_count,' = "',envp[env_count],'"');
  444. {$EndIf SYSTEM_DEBUG_STARTUP}
  445. inc(env_count);
  446. while (cp^ <> #0) do
  447. inc(longint(cp)); { skip to NUL }
  448. inc(longint(cp)); { skip to next character }
  449. end;
  450. envp[env_count]:=nil;
  451. longint(cp):=longint(cp)+3;
  452. dos_argv0 := sysgetmem(strlen(cp)+1);
  453. if (dos_argv0 = nil) then halt;
  454. strcopy(dos_argv0, cp);
  455. { update ___dos_argv0 also }
  456. ___dos_argv0:=dos_argv0
  457. end;
  458. procedure syscopytodos(addr : longint; len : longint);
  459. begin
  460. if len > tb_size then
  461. HandleError(217);
  462. sysseg_move(get_ds,addr,dos_selector,tb,len);
  463. end;
  464. procedure syscopyfromdos(addr : longint; len : longint);
  465. begin
  466. if len > tb_size then
  467. HandleError(217);
  468. sysseg_move(dos_selector,tb,get_ds,addr,len);
  469. end;
  470. procedure sysrealintr(intnr : word;var regs : trealregs);
  471. begin
  472. regs.realsp:=0;
  473. regs.realss:=0;
  474. asm
  475. movw intnr,%bx
  476. xorl %ecx,%ecx
  477. movl regs,%edi
  478. movw $0x300,%ax
  479. int $0x31
  480. end;
  481. end;
  482. procedure set_pm_interrupt(vector : byte;const intaddr : tseginfo);
  483. begin
  484. asm
  485. movl intaddr,%eax
  486. movl (%eax),%edx
  487. movw 4(%eax),%cx
  488. movl $0x205,%eax
  489. movb vector,%bl
  490. int $0x31
  491. end;
  492. end;
  493. procedure get_pm_interrupt(vector : byte;var intaddr : tseginfo);
  494. begin
  495. asm
  496. movb vector,%bl
  497. movl $0x204,%eax
  498. int $0x31
  499. movl intaddr,%eax
  500. movl %edx,(%eax)
  501. movw %cx,4(%eax)
  502. end;
  503. end;
  504. procedure getinoutres;
  505. var
  506. regs : trealregs;
  507. begin
  508. regs.realeax:=$5900;
  509. regs.realebx:=$0;
  510. sysrealintr($21,regs);
  511. InOutRes:=lo(regs.realeax);
  512. case InOutRes of
  513. 19 : InOutRes:=150;
  514. 21 : InOutRes:=152;
  515. end;
  516. end;
  517. { Keep Track of open files }
  518. const
  519. max_files = 50;
  520. var
  521. openfiles : array [0..max_files-1] of boolean;
  522. {$ifdef SYSTEMDEBUG}
  523. opennames : array [0..max_files-1] of pchar;
  524. const
  525. free_closed_names : boolean = true;
  526. {$endif SYSTEMDEBUG}
  527. {*****************************************************************************
  528. System Dependent Exit code
  529. *****************************************************************************}
  530. procedure ___exit(exitcode:byte);cdecl;external name '___exit';
  531. procedure do_close(handle : longint);forward;
  532. Procedure system_exit;
  533. var
  534. h : byte;
  535. begin
  536. for h:=0 to max_files-1 do
  537. if openfiles[h] then
  538. begin
  539. {$ifdef SYSTEMDEBUG}
  540. writeln(stderr,'file ',opennames[h],' not closed at exit');
  541. {$endif SYSTEMDEBUG}
  542. if h>=5 then
  543. do_close(h);
  544. end;
  545. { halt is not allways called !! }
  546. { not on normal exit !! PM }
  547. set_pm_interrupt($00,old_int00);
  548. set_pm_interrupt($75,old_int75);
  549. ___exit(exitcode);
  550. end;
  551. procedure new_int00;
  552. begin
  553. HandleError(200);
  554. end;
  555. procedure new_int75;
  556. begin
  557. asm
  558. xorl %eax,%eax
  559. outb %al,$0x0f0
  560. movb $0x20,%al
  561. outb %al,$0x0a0
  562. outb %al,$0x020
  563. end;
  564. HandleError(200);
  565. end;
  566. var
  567. __stkbottom : longint;external name '__stkbottom';
  568. procedure int_stackcheck(stack_size:longint);[public,alias:'FPC_STACKCHECK'];
  569. {
  570. called when trying to get local stack if the compiler directive $S
  571. is set this function must preserve esi !!!! because esi is set by
  572. the calling proc for methods it must preserve all registers !!
  573. With a 2048 byte safe area used to write to StdIo without crossing
  574. the stack boundary
  575. }
  576. begin
  577. asm
  578. pushl %eax
  579. pushl %ebx
  580. movl stack_size,%ebx
  581. addl $2048,%ebx
  582. movl %esp,%eax
  583. subl %ebx,%eax
  584. {$ifdef SYSTEMDEBUG}
  585. movl loweststack,%ebx
  586. cmpl %eax,%ebx
  587. jb .L_is_not_lowest
  588. movl %eax,loweststack
  589. .L_is_not_lowest:
  590. {$endif SYSTEMDEBUG}
  591. movl __stkbottom,%ebx
  592. cmpl %eax,%ebx
  593. jae .L__short_on_stack
  594. popl %ebx
  595. popl %eax
  596. leave
  597. ret $4
  598. .L__short_on_stack:
  599. { can be usefull for error recovery !! }
  600. popl %ebx
  601. popl %eax
  602. end['EAX','EBX'];
  603. HandleError(202);
  604. end;
  605. {*****************************************************************************
  606. ParamStr/Randomize
  607. *****************************************************************************}
  608. function paramcount : longint;
  609. begin
  610. paramcount := argc - 1;
  611. end;
  612. function paramstr(l : longint) : string;
  613. begin
  614. if (l>=0) and (l+1<=argc) then
  615. paramstr:=strpas(argv[l])
  616. else
  617. paramstr:='';
  618. end;
  619. procedure randomize;
  620. var
  621. hl : longint;
  622. regs : trealregs;
  623. begin
  624. regs.realeax:=$2c00;
  625. sysrealintr($21,regs);
  626. hl:=regs.realedx and $ffff;
  627. randseed:=hl*$10000+ (regs.realecx and $ffff);
  628. end;
  629. {*****************************************************************************
  630. Heap Management
  631. *****************************************************************************}
  632. var
  633. int_heap : longint;external name 'HEAP';
  634. int_heapsize : longint;external name 'HEAPSIZE';
  635. function getheapstart:pointer;
  636. begin
  637. getheapstart:=@int_heap;
  638. end;
  639. function getheapsize:longint;
  640. begin
  641. getheapsize:=int_heapsize;
  642. end;
  643. function ___sbrk(size:longint):longint;cdecl;external name '___sbrk';
  644. function Sbrk(size : longint):longint;assembler;
  645. asm
  646. {$ifdef SYSTEMDEBUG}
  647. cmpb $1,accept_sbrk
  648. je .Lsbrk
  649. movl $-1,%eax
  650. jmp .Lsbrk_fail
  651. .Lsbrk:
  652. {$endif}
  653. movl size,%eax
  654. pushl %eax
  655. call ___sbrk
  656. addl $4,%esp
  657. {$ifdef SYSTEMDEBUG}
  658. .Lsbrk_fail:
  659. {$endif}
  660. end;
  661. { include standard heap management }
  662. {$I heap.inc}
  663. {****************************************************************************
  664. Low level File Routines
  665. ****************************************************************************}
  666. procedure AllowSlash(p:pchar);
  667. var
  668. i : longint;
  669. begin
  670. { allow slash as backslash }
  671. for i:=0 to strlen(p) do
  672. if p[i]='/' then p[i]:='\';
  673. end;
  674. procedure do_close(handle : longint);
  675. var
  676. regs : trealregs;
  677. begin
  678. if Handle<=4 then
  679. exit;
  680. regs.realebx:=handle;
  681. if handle<max_files then
  682. begin
  683. openfiles[handle]:=false;
  684. {$ifdef SYSTEMDEBUG}
  685. if assigned(opennames[handle]) and free_closed_names then
  686. begin
  687. sysfreememsize(opennames[handle],strlen(opennames[handle])+1);
  688. opennames[handle]:=nil;
  689. end;
  690. {$endif SYSTEMDEBUG}
  691. end;
  692. regs.realeax:=$3e00;
  693. sysrealintr($21,regs);
  694. if (regs.realflags and carryflag) <> 0 then
  695. GetInOutRes;
  696. end;
  697. procedure do_erase(p : pchar);
  698. var
  699. regs : trealregs;
  700. begin
  701. AllowSlash(p);
  702. syscopytodos(longint(p),strlen(p)+1);
  703. regs.realedx:=tb_offset;
  704. regs.realds:=tb_segment;
  705. {$ifndef RTLLITE}
  706. if LFNSupport then
  707. regs.realeax:=$7141
  708. else
  709. {$endif RTLLITE}
  710. regs.realeax:=$4100;
  711. regs.realesi:=0;
  712. regs.realecx:=0;
  713. sysrealintr($21,regs);
  714. if (regs.realflags and carryflag) <> 0 then
  715. GetInOutRes;
  716. end;
  717. procedure do_rename(p1,p2 : pchar);
  718. var
  719. regs : trealregs;
  720. begin
  721. AllowSlash(p1);
  722. AllowSlash(p2);
  723. if strlen(p1)+strlen(p2)+3>tb_size then
  724. HandleError(217);
  725. sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1);
  726. sysseg_move(get_ds,longint(p1),dos_selector,tb+strlen(p2)+2,strlen(p1)+1);
  727. regs.realedi:=tb_offset;
  728. regs.realedx:=tb_offset + strlen(p2)+2;
  729. regs.realds:=tb_segment;
  730. regs.reales:=tb_segment;
  731. {$ifndef RTLLITE}
  732. if LFNSupport then
  733. regs.realeax:=$7156
  734. else
  735. {$endif RTLLITE}
  736. regs.realeax:=$5600;
  737. regs.realecx:=$ff; { attribute problem here ! }
  738. sysrealintr($21,regs);
  739. if (regs.realflags and carryflag) <> 0 then
  740. GetInOutRes;
  741. end;
  742. function do_write(h,addr,len : longint) : longint;
  743. var
  744. regs : trealregs;
  745. size,
  746. writesize : longint;
  747. begin
  748. writesize:=0;
  749. while len > 0 do
  750. begin
  751. if len>tb_size then
  752. size:=tb_size
  753. else
  754. size:=len;
  755. syscopytodos(addr+writesize,size);
  756. regs.realecx:=size;
  757. regs.realedx:=tb_offset;
  758. regs.realds:=tb_segment;
  759. regs.realebx:=h;
  760. regs.realeax:=$4000;
  761. sysrealintr($21,regs);
  762. if (regs.realflags and carryflag) <> 0 then
  763. begin
  764. GetInOutRes;
  765. exit(writesize);
  766. end;
  767. inc(writesize,regs.realeax);
  768. dec(len,regs.realeax);
  769. { stop when not the specified size is written }
  770. if regs.realeax<size then
  771. break;
  772. end;
  773. Do_Write:=WriteSize;
  774. end;
  775. function do_read(h,addr,len : longint) : longint;
  776. var
  777. regs : trealregs;
  778. size,
  779. readsize : longint;
  780. begin
  781. readsize:=0;
  782. while len > 0 do
  783. begin
  784. if len>tb_size then
  785. size:=tb_size
  786. else
  787. size:=len;
  788. regs.realecx:=size;
  789. regs.realedx:=tb_offset;
  790. regs.realds:=tb_segment;
  791. regs.realebx:=h;
  792. regs.realeax:=$3f00;
  793. sysrealintr($21,regs);
  794. if (regs.realflags and carryflag) <> 0 then
  795. begin
  796. GetInOutRes;
  797. do_read:=0;
  798. exit;
  799. end;
  800. syscopyfromdos(addr+readsize,regs.realeax);
  801. inc(readsize,regs.realeax);
  802. dec(len,regs.realeax);
  803. { stop when not the specified size is read }
  804. if regs.realeax<size then
  805. break;
  806. end;
  807. do_read:=readsize;
  808. end;
  809. function do_filepos(handle : longint) : longint;
  810. var
  811. regs : trealregs;
  812. begin
  813. regs.realebx:=handle;
  814. regs.realecx:=0;
  815. regs.realedx:=0;
  816. regs.realeax:=$4201;
  817. sysrealintr($21,regs);
  818. if (regs.realflags and carryflag) <> 0 then
  819. Begin
  820. GetInOutRes;
  821. do_filepos:=0;
  822. end
  823. else
  824. do_filepos:=lo(regs.realedx) shl 16+lo(regs.realeax);
  825. end;
  826. procedure do_seek(handle,pos : longint);
  827. var
  828. regs : trealregs;
  829. begin
  830. regs.realebx:=handle;
  831. regs.realecx:=pos shr 16;
  832. regs.realedx:=pos and $ffff;
  833. regs.realeax:=$4200;
  834. sysrealintr($21,regs);
  835. if (regs.realflags and carryflag) <> 0 then
  836. GetInOutRes;
  837. end;
  838. function do_seekend(handle:longint):longint;
  839. var
  840. regs : trealregs;
  841. begin
  842. regs.realebx:=handle;
  843. regs.realecx:=0;
  844. regs.realedx:=0;
  845. regs.realeax:=$4202;
  846. sysrealintr($21,regs);
  847. if (regs.realflags and carryflag) <> 0 then
  848. Begin
  849. GetInOutRes;
  850. do_seekend:=0;
  851. end
  852. else
  853. do_seekend:=lo(regs.realedx) shl 16+lo(regs.realeax);
  854. end;
  855. function do_filesize(handle : longint) : longint;
  856. var
  857. aktfilepos : longint;
  858. begin
  859. aktfilepos:=do_filepos(handle);
  860. do_filesize:=do_seekend(handle);
  861. do_seek(handle,aktfilepos);
  862. end;
  863. { truncate at a given position }
  864. procedure do_truncate (handle,pos:longint);
  865. var
  866. regs : trealregs;
  867. begin
  868. do_seek(handle,pos);
  869. regs.realecx:=0;
  870. regs.realedx:=tb_offset;
  871. regs.realds:=tb_segment;
  872. regs.realebx:=handle;
  873. regs.realeax:=$4000;
  874. sysrealintr($21,regs);
  875. if (regs.realflags and carryflag) <> 0 then
  876. GetInOutRes;
  877. end;
  878. {$ifndef RTLLITE}
  879. const
  880. FileHandleCount : longint = 20;
  881. function Increase_file_handle_count : boolean;
  882. var
  883. regs : trealregs;
  884. begin
  885. Inc(FileHandleCount,10);
  886. regs.realebx:=FileHandleCount;
  887. regs.realeax:=$6700;
  888. sysrealintr($21,regs);
  889. if (regs.realflags and carryflag) <> 0 then
  890. Increase_file_handle_count:=false
  891. else
  892. Increase_file_handle_count:=true;
  893. end;
  894. {$endif not RTLLITE}
  895. procedure do_open(var f;p:pchar;flags:longint);
  896. {
  897. filerec and textrec have both handle and mode as the first items so
  898. they could use the same routine for opening/creating.
  899. when (flags and $100) the file will be append
  900. when (flags and $1000) the file will be truncate/rewritten
  901. when (flags and $10000) there is no check for close (needed for textfiles)
  902. }
  903. var
  904. regs : trealregs;
  905. action : longint;
  906. begin
  907. AllowSlash(p);
  908. { close first if opened }
  909. if ((flags and $10000)=0) then
  910. begin
  911. case filerec(f).mode of
  912. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  913. fmclosed : ;
  914. else
  915. begin
  916. inoutres:=102; {not assigned}
  917. exit;
  918. end;
  919. end;
  920. end;
  921. { reset file handle }
  922. filerec(f).handle:=UnusedHandle;
  923. action:=$1;
  924. { convert filemode to filerec modes }
  925. case (flags and 3) of
  926. 0 : filerec(f).mode:=fminput;
  927. 1 : filerec(f).mode:=fmoutput;
  928. 2 : filerec(f).mode:=fminout;
  929. end;
  930. if (flags and $1000)<>0 then
  931. action:=$12; {create file function}
  932. { empty name is special }
  933. if p[0]=#0 then
  934. begin
  935. case FileRec(f).mode of
  936. fminput :
  937. FileRec(f).Handle:=StdInputHandle;
  938. fminout, { this is set by rewrite }
  939. fmoutput :
  940. FileRec(f).Handle:=StdOutputHandle;
  941. fmappend :
  942. begin
  943. FileRec(f).Handle:=StdOutputHandle;
  944. FileRec(f).mode:=fmoutput; {fool fmappend}
  945. end;
  946. end;
  947. exit;
  948. end;
  949. { real dos call }
  950. syscopytodos(longint(p),strlen(p)+1);
  951. {$ifndef RTLLITE}
  952. if LFNSupport then
  953. regs.realeax:=$716c
  954. else
  955. {$endif RTLLITE}
  956. regs.realeax:=$6c00;
  957. regs.realedx:=action;
  958. regs.realds:=tb_segment;
  959. regs.realesi:=tb_offset;
  960. regs.realebx:=$2000+(flags and $ff);
  961. regs.realecx:=$20;
  962. sysrealintr($21,regs);
  963. {$ifndef RTLLITE}
  964. if (regs.realflags and carryflag) <> 0 then
  965. if (regs.realeax and $ffff)=4 then
  966. if Increase_file_handle_count then
  967. begin
  968. { Try again }
  969. if LFNSupport then
  970. regs.realeax:=$716c
  971. else
  972. regs.realeax:=$6c00;
  973. regs.realedx:=action;
  974. regs.realds:=tb_segment;
  975. regs.realesi:=tb_offset;
  976. regs.realebx:=$2000+(flags and $ff);
  977. regs.realecx:=$20;
  978. sysrealintr($21,regs);
  979. end;
  980. {$endif RTLLITE}
  981. if (regs.realflags and carryflag) <> 0 then
  982. begin
  983. GetInOutRes;
  984. exit;
  985. end
  986. else
  987. begin
  988. filerec(f).handle:=regs.realeax;
  989. {$ifndef RTLLITE}
  990. { for systems that have more then 20 by default ! }
  991. if regs.realeax>FileHandleCount then
  992. FileHandleCount:=regs.realeax;
  993. {$endif RTLLITE}
  994. end;
  995. if regs.realeax<max_files then
  996. begin
  997. {$ifdef SYSTEMDEBUG}
  998. if openfiles[regs.realeax] and
  999. assigned(opennames[regs.realeax]) then
  1000. begin
  1001. Writeln(stderr,'file ',opennames[regs.realeax],'(',regs.realeax,') not closed but handle reused!');
  1002. sysfreememsize(opennames[regs.realeax],strlen(opennames[regs.realeax])+1);
  1003. end;
  1004. {$endif SYSTEMDEBUG}
  1005. openfiles[regs.realeax]:=true;
  1006. {$ifdef SYSTEMDEBUG}
  1007. opennames[regs.realeax] := sysgetmem(strlen(p)+1);
  1008. move(p^,opennames[regs.realeax]^,strlen(p)+1);
  1009. {$endif SYSTEMDEBUG}
  1010. end;
  1011. { append mode }
  1012. if (flags and $100)<>0 then
  1013. begin
  1014. do_seekend(filerec(f).handle);
  1015. filerec(f).mode:=fmoutput; {fool fmappend}
  1016. end;
  1017. end;
  1018. function do_isdevice(handle:longint):boolean;
  1019. var
  1020. regs : trealregs;
  1021. begin
  1022. regs.realebx:=handle;
  1023. regs.realeax:=$4400;
  1024. sysrealintr($21,regs);
  1025. do_isdevice:=(regs.realedx and $80)<>0;
  1026. if (regs.realflags and carryflag) <> 0 then
  1027. GetInOutRes;
  1028. end;
  1029. {*****************************************************************************
  1030. UnTyped File Handling
  1031. *****************************************************************************}
  1032. {$i file.inc}
  1033. {*****************************************************************************
  1034. Typed File Handling
  1035. *****************************************************************************}
  1036. {$i typefile.inc}
  1037. {*****************************************************************************
  1038. Text File Handling
  1039. *****************************************************************************}
  1040. {$DEFINE EOF_CTRLZ}
  1041. {$i text.inc}
  1042. {*****************************************************************************
  1043. Generic Handling
  1044. *****************************************************************************}
  1045. {$ifdef TEST_GENERIC}
  1046. {$i generic.inc}
  1047. {$endif TEST_GENERIC}
  1048. {*****************************************************************************
  1049. Directory Handling
  1050. *****************************************************************************}
  1051. procedure DosDir(func:byte;const s:string);
  1052. var
  1053. buffer : array[0..255] of char;
  1054. regs : trealregs;
  1055. begin
  1056. move(s[1],buffer,length(s));
  1057. buffer[length(s)]:=#0;
  1058. AllowSlash(pchar(@buffer));
  1059. { True DOS does not like backslashes at end
  1060. Win95 DOS accepts this !!
  1061. but "\" and "c:\" should still be kept and accepted hopefully PM }
  1062. if (length(s)>0) and (buffer[length(s)-1]='\') and
  1063. Not ((length(s)=1) or ((length(s)=3) and (s[2]=':'))) then
  1064. buffer[length(s)-1]:=#0;
  1065. syscopytodos(longint(@buffer),length(s)+1);
  1066. regs.realedx:=tb_offset;
  1067. regs.realds:=tb_segment;
  1068. {$ifndef RTLLITE}
  1069. if LFNSupport then
  1070. regs.realeax:=$7100+func
  1071. else
  1072. {$endif RTLLITE}
  1073. regs.realeax:=func shl 8;
  1074. sysrealintr($21,regs);
  1075. if (regs.realflags and carryflag) <> 0 then
  1076. GetInOutRes;
  1077. end;
  1078. procedure mkdir(const s : string);[IOCheck];
  1079. begin
  1080. If InOutRes <> 0 then
  1081. exit;
  1082. DosDir($39,s);
  1083. end;
  1084. procedure rmdir(const s : string);[IOCheck];
  1085. begin
  1086. If InOutRes <> 0 then
  1087. exit;
  1088. DosDir($3a,s);
  1089. end;
  1090. procedure chdir(const s : string);[IOCheck];
  1091. var
  1092. regs : trealregs;
  1093. begin
  1094. If InOutRes <> 0 then
  1095. exit;
  1096. { First handle Drive changes }
  1097. if (length(s)>=2) and (s[2]=':') then
  1098. begin
  1099. regs.realedx:=(ord(s[1]) and (not 32))-ord('A');
  1100. regs.realeax:=$0e00;
  1101. sysrealintr($21,regs);
  1102. regs.realeax:=$1900;
  1103. sysrealintr($21,regs);
  1104. if byte(regs.realeax)<>byte(regs.realedx) then
  1105. begin
  1106. Inoutres:=15;
  1107. exit;
  1108. end;
  1109. { DosDir($3b,'c:') give Path not found error on
  1110. pure DOS PM }
  1111. if length(s)=2 then
  1112. exit;
  1113. end;
  1114. { do the normal dos chdir }
  1115. DosDir($3b,s);
  1116. end;
  1117. procedure getdir(drivenr : byte;var dir : shortstring);
  1118. var
  1119. temp : array[0..255] of char;
  1120. i : longint;
  1121. regs : trealregs;
  1122. begin
  1123. regs.realedx:=drivenr;
  1124. regs.realesi:=tb_offset;
  1125. regs.realds:=tb_segment;
  1126. {$ifndef RTLLITE}
  1127. if LFNSupport then
  1128. regs.realeax:=$7147
  1129. else
  1130. {$endif RTLLITE}
  1131. regs.realeax:=$4700;
  1132. sysrealintr($21,regs);
  1133. if (regs.realflags and carryflag) <> 0 then
  1134. Begin
  1135. GetInOutRes;
  1136. exit;
  1137. end
  1138. else
  1139. syscopyfromdos(longint(@temp),251);
  1140. { conversion to Pascal string including slash conversion }
  1141. i:=0;
  1142. while (temp[i]<>#0) do
  1143. begin
  1144. if temp[i]='/' then
  1145. temp[i]:='\';
  1146. dir[i+4]:=temp[i];
  1147. inc(i);
  1148. end;
  1149. dir[2]:=':';
  1150. dir[3]:='\';
  1151. dir[0]:=char(i+3);
  1152. { upcase the string }
  1153. if not FileNameCaseSensitive then
  1154. dir:=upcase(dir);
  1155. if drivenr<>0 then { Drive was supplied. We know it }
  1156. dir[1]:=char(65+drivenr-1)
  1157. else
  1158. begin
  1159. { We need to get the current drive from DOS function 19H }
  1160. { because the drive was the default, which can be unknown }
  1161. regs.realeax:=$1900;
  1162. sysrealintr($21,regs);
  1163. i:= (regs.realeax and $ff) + ord('A');
  1164. dir[1]:=chr(i);
  1165. end;
  1166. end;
  1167. {*****************************************************************************
  1168. SystemUnit Initialization
  1169. *****************************************************************************}
  1170. {$ifndef RTLLITE}
  1171. function CheckLFN:boolean;
  1172. var
  1173. regs : TRealRegs;
  1174. RootName : pchar;
  1175. begin
  1176. { Check LFN API on drive c:\ }
  1177. RootName:='C:\';
  1178. syscopytodos(longint(RootName),strlen(RootName)+1);
  1179. { Call 'Get Volume Information' ($71A0) }
  1180. regs.realeax:=$71a0;
  1181. regs.reales:=tb_segment;
  1182. regs.realedi:=tb_offset;
  1183. regs.realecx:=32;
  1184. regs.realds:=tb_segment;
  1185. regs.realedx:=tb_offset;
  1186. regs.realflags:=carryflag;
  1187. sysrealintr($21,regs);
  1188. { If carryflag=0 and LFN API bit in ebx is set then use Long file names }
  1189. CheckLFN:=(regs.realflags and carryflag=0) and (regs.realebx and $4000=$4000);
  1190. end;
  1191. {$endif RTLLITE}
  1192. {$ifdef MT}
  1193. {$I thread.inc}
  1194. {$endif MT}
  1195. { define EXCEPTIONS_IN_SYSTEM}
  1196. {$ifndef RTLLITE}
  1197. {$ifdef EXCEPTIONS_IN_SYSTEM}
  1198. {$define IN_SYSTEM}
  1199. {$i dpmiexcp.pp}
  1200. {$endif EXCEPTIONS_IN_SYSTEM}
  1201. {$endif RTLLITE}
  1202. var
  1203. temp_int : tseginfo;
  1204. Begin
  1205. { save old int 0 and 75 }
  1206. get_pm_interrupt($00,old_int00);
  1207. get_pm_interrupt($75,old_int75);
  1208. temp_int.segment:=get_cs;
  1209. temp_int.offset:=@new_int00;
  1210. set_pm_interrupt($00,temp_int);
  1211. { temp_int.offset:=@new_int75;
  1212. set_pm_interrupt($75,temp_int); }
  1213. { to test stack depth }
  1214. loweststack:=maxlongint;
  1215. { Setup heap }
  1216. InitHeap;
  1217. {$ifdef MT}
  1218. { before this, you can't use thread vars !!!! }
  1219. { threadvarblocksize is calculate before the initialization }
  1220. { of the system unit }
  1221. mainprogramthreadblock := sysgetmem(threadvarblocksize);
  1222. {$endif MT}
  1223. InitExceptions;
  1224. { Setup stdin, stdout and stderr }
  1225. OpenStdIO(Input,fmInput,StdInputHandle);
  1226. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1227. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1228. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1229. { Setup environment and arguments }
  1230. Setup_Environment;
  1231. Setup_Arguments;
  1232. { Use LFNSupport LFN }
  1233. LFNSupport:=CheckLFN;
  1234. if LFNSupport then
  1235. FileNameCaseSensitive:=true;
  1236. { Reset IO Error }
  1237. InOutRes:=0;
  1238. {$ifndef RTLLITE}
  1239. {$ifdef EXCEPTIONS_IN_SYSTEM}
  1240. InitDPMIExcp;
  1241. InstallDefaultHandlers;
  1242. {$endif EXCEPTIONS_IN_SYSTEM}
  1243. {$endif RTLLITE}
  1244. End.
  1245. {
  1246. $Log$
  1247. Revision 1.35 2000-03-09 09:15:10 pierre
  1248. + support for djgpp v2.03 (added some new functions that are in v2.03 ofdpmiexcp.c)
  1249. + code to integrate exception support inside the system unit
  1250. Revision 1.34 2000/03/07 11:05:58 pierre
  1251. * fix for the problem of backslashes at and of directory
  1252. + some code for exception support (far from working :()
  1253. + debug variable accept_sbrk
  1254. Revision 1.33 2000/02/09 16:59:29 peter
  1255. * truncated log
  1256. Revision 1.32 2000/02/09 12:41:14 peter
  1257. * halt moved to system.inc
  1258. Revision 1.31 2000/01/24 11:57:18 daniel
  1259. * !proxy support in environment added (Peter)
  1260. Revision 1.30 2000/01/20 23:38:02 peter
  1261. * support fm_inout as stdoutput for assign(f,'');rewrite(f,1); becuase
  1262. rewrite opens always with filemode 2
  1263. Revision 1.29 2000/01/16 22:25:38 peter
  1264. * check handle for file closing
  1265. Revision 1.28 2000/01/07 16:41:32 daniel
  1266. * copyright 2000
  1267. Revision 1.27 2000/01/07 16:32:23 daniel
  1268. * copyright 2000 added
  1269. Revision 1.26 1999/12/20 22:22:41 pierre
  1270. * better closing of left open files
  1271. Revision 1.25 1999/12/17 23:11:48 pierre
  1272. * fix for bug754 : increase now dynamically max open handles
  1273. Revision 1.24 1999/12/01 22:57:30 peter
  1274. * cmdline support
  1275. Revision 1.23 1999/11/25 16:24:56 pierre
  1276. * avoid a problem with ChDir('c:') on pure DOS
  1277. Revision 1.22 1999/11/06 14:38:24 peter
  1278. * truncated log
  1279. Revision 1.21 1999/10/31 09:34:48 jonas
  1280. * updated for new syntax of sysgetmem
  1281. Revision 1.20 1999/10/28 09:53:19 peter
  1282. * create can also open file in fminout
  1283. Revision 1.19 1999/09/20 12:40:20 pierre
  1284. * adapted to new heaph
  1285. Revision 1.18 1999/09/10 17:14:09 peter
  1286. * better errorcode returning using int21h,5900
  1287. Revision 1.17 1999/09/10 15:40:33 peter
  1288. * fixed do_open flags to be > $100, becuase filemode can be upto 255
  1289. Revision 1.16 1999/09/08 16:09:18 peter
  1290. * do_isdevice not called if already error
  1291. Revision 1.15 1999/08/19 14:03:16 pierre
  1292. * use sysgetmem for startup and debug allocations
  1293. Revision 1.14 1999/07/19 07:57:49 michael
  1294. + Small fix from Michael Baikov in setup_params
  1295. Revision 1.13 1999/05/19 16:54:21 pierre
  1296. * closes all handles >+ 5
  1297. Revision 1.12 1999/05/17 21:52:33 florian
  1298. * most of the Object Pascal stuff moved to the system unit
  1299. }