system.pp 37 KB

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