system.pp 37 KB

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