system.pp 35 KB

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