system.pp 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  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 = 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. { 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. {*****************************************************************************
  709. ParamStr/Randomize
  710. *****************************************************************************}
  711. function paramcount : longint;
  712. begin
  713. paramcount := argc - 1;
  714. end;
  715. function paramstr(l : longint) : string;
  716. begin
  717. if (l>=0) and (l+1<=argc) then
  718. paramstr:=strpas(argv[l])
  719. else
  720. paramstr:='';
  721. end;
  722. procedure randomize;
  723. var
  724. hl : longint;
  725. regs : trealregs;
  726. begin
  727. regs.realeax:=$2c00;
  728. sysrealintr($21,regs);
  729. hl:=lo(regs.realedx);
  730. randseed:=hl*$10000+ lo(regs.realecx);
  731. end;
  732. {*****************************************************************************
  733. Heap Management
  734. *****************************************************************************}
  735. var
  736. int_heap : longint;external name 'HEAP';
  737. int_heapsize : longint;external name 'HEAPSIZE';
  738. function getheapstart:pointer;
  739. begin
  740. getheapstart:=@int_heap;
  741. end;
  742. function getheapsize:longint;
  743. begin
  744. getheapsize:=int_heapsize;
  745. end;
  746. function ___sbrk(size:longint):longint;cdecl;external name '___sbrk';
  747. function Sbrk(size : longint):longint;assembler;
  748. asm
  749. {$ifdef SYSTEMDEBUG}
  750. cmpb $1,accept_sbrk
  751. je .Lsbrk
  752. movl $-1,%eax
  753. jmp .Lsbrk_fail
  754. .Lsbrk:
  755. {$endif}
  756. movl size,%eax
  757. pushl %eax
  758. call ___sbrk
  759. addl $4,%esp
  760. {$ifdef SYSTEMDEBUG}
  761. .Lsbrk_fail:
  762. {$endif}
  763. end;
  764. { include standard heap management }
  765. {$I heap.inc}
  766. {****************************************************************************
  767. Low level File Routines
  768. ****************************************************************************}
  769. procedure AllowSlash(p:pchar);
  770. var
  771. i : longint;
  772. begin
  773. { allow slash as backslash }
  774. for i:=0 to strlen(p) do
  775. if p[i]='/' then p[i]:='\';
  776. end;
  777. procedure do_close(handle : longint);
  778. var
  779. regs : trealregs;
  780. begin
  781. if Handle<=4 then
  782. exit;
  783. regs.realebx:=handle;
  784. if handle<max_files then
  785. begin
  786. openfiles[handle]:=false;
  787. {$ifdef SYSTEMDEBUG}
  788. if assigned(opennames[handle]) and free_closed_names then
  789. begin
  790. sysfreememsize(opennames[handle],strlen(opennames[handle])+1);
  791. opennames[handle]:=nil;
  792. end;
  793. {$endif SYSTEMDEBUG}
  794. end;
  795. regs.realeax:=$3e00;
  796. sysrealintr($21,regs);
  797. if (regs.realflags and carryflag) <> 0 then
  798. GetInOutRes(lo(regs.realeax));
  799. end;
  800. procedure do_erase(p : pchar);
  801. var
  802. regs : trealregs;
  803. begin
  804. AllowSlash(p);
  805. syscopytodos(longint(p),strlen(p)+1);
  806. regs.realedx:=tb_offset;
  807. regs.realds:=tb_segment;
  808. if LFNSupport then
  809. regs.realeax:=$7141
  810. else
  811. regs.realeax:=$4100;
  812. regs.realesi:=0;
  813. regs.realecx:=0;
  814. sysrealintr($21,regs);
  815. if (regs.realflags and carryflag) <> 0 then
  816. GetInOutRes(lo(regs.realeax));
  817. end;
  818. procedure do_rename(p1,p2 : pchar);
  819. var
  820. regs : trealregs;
  821. begin
  822. AllowSlash(p1);
  823. AllowSlash(p2);
  824. if strlen(p1)+strlen(p2)+3>tb_size then
  825. HandleError(217);
  826. sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1);
  827. sysseg_move(get_ds,longint(p1),dos_selector,tb+strlen(p2)+2,strlen(p1)+1);
  828. regs.realedi:=tb_offset;
  829. regs.realedx:=tb_offset + strlen(p2)+2;
  830. regs.realds:=tb_segment;
  831. regs.reales:=tb_segment;
  832. if LFNSupport then
  833. regs.realeax:=$7156
  834. else
  835. regs.realeax:=$5600;
  836. regs.realecx:=$ff; { attribute problem here ! }
  837. sysrealintr($21,regs);
  838. if (regs.realflags and carryflag) <> 0 then
  839. GetInOutRes(lo(regs.realeax));
  840. end;
  841. function do_write(h,addr,len : longint) : longint;
  842. var
  843. regs : trealregs;
  844. size,
  845. writesize : longint;
  846. begin
  847. writesize:=0;
  848. while len > 0 do
  849. begin
  850. if len>tb_size then
  851. size:=tb_size
  852. else
  853. size:=len;
  854. syscopytodos(addr+writesize,size);
  855. regs.realecx:=size;
  856. regs.realedx:=tb_offset;
  857. regs.realds:=tb_segment;
  858. regs.realebx:=h;
  859. regs.realeax:=$4000;
  860. sysrealintr($21,regs);
  861. if (regs.realflags and carryflag) <> 0 then
  862. begin
  863. GetInOutRes(lo(regs.realeax));
  864. exit(writesize);
  865. end;
  866. inc(writesize,lo(regs.realeax));
  867. dec(len,lo(regs.realeax));
  868. { stop when not the specified size is written }
  869. if lo(regs.realeax)<size then
  870. break;
  871. end;
  872. Do_Write:=WriteSize;
  873. end;
  874. function do_read(h,addr,len : longint) : longint;
  875. var
  876. regs : trealregs;
  877. size,
  878. readsize : longint;
  879. begin
  880. readsize:=0;
  881. while len > 0 do
  882. begin
  883. if len>tb_size then
  884. size:=tb_size
  885. else
  886. size:=len;
  887. regs.realecx:=size;
  888. regs.realedx:=tb_offset;
  889. regs.realds:=tb_segment;
  890. regs.realebx:=h;
  891. regs.realeax:=$3f00;
  892. sysrealintr($21,regs);
  893. if (regs.realflags and carryflag) <> 0 then
  894. begin
  895. GetInOutRes(lo(regs.realeax));
  896. do_read:=0;
  897. exit;
  898. end;
  899. syscopyfromdos(addr+readsize,lo(regs.realeax));
  900. inc(readsize,lo(regs.realeax));
  901. dec(len,lo(regs.realeax));
  902. { stop when not the specified size is read }
  903. if lo(regs.realeax)<size then
  904. break;
  905. end;
  906. do_read:=readsize;
  907. end;
  908. function do_filepos(handle : longint) : longint;
  909. var
  910. regs : trealregs;
  911. begin
  912. regs.realebx:=handle;
  913. regs.realecx:=0;
  914. regs.realedx:=0;
  915. regs.realeax:=$4201;
  916. sysrealintr($21,regs);
  917. if (regs.realflags and carryflag) <> 0 then
  918. Begin
  919. GetInOutRes(lo(regs.realeax));
  920. do_filepos:=0;
  921. end
  922. else
  923. do_filepos:=lo(regs.realedx) shl 16+lo(regs.realeax);
  924. end;
  925. procedure do_seek(handle,pos : longint);
  926. var
  927. regs : trealregs;
  928. begin
  929. regs.realebx:=handle;
  930. regs.realecx:=pos shr 16;
  931. regs.realedx:=pos and $ffff;
  932. regs.realeax:=$4200;
  933. sysrealintr($21,regs);
  934. if (regs.realflags and carryflag) <> 0 then
  935. GetInOutRes(lo(regs.realeax));
  936. end;
  937. function do_seekend(handle:longint):longint;
  938. var
  939. regs : trealregs;
  940. begin
  941. regs.realebx:=handle;
  942. regs.realecx:=0;
  943. regs.realedx:=0;
  944. regs.realeax:=$4202;
  945. sysrealintr($21,regs);
  946. if (regs.realflags and carryflag) <> 0 then
  947. Begin
  948. GetInOutRes(lo(regs.realeax));
  949. do_seekend:=0;
  950. end
  951. else
  952. do_seekend:=lo(regs.realedx) shl 16+lo(regs.realeax);
  953. end;
  954. function do_filesize(handle : longint) : longint;
  955. var
  956. aktfilepos : longint;
  957. begin
  958. aktfilepos:=do_filepos(handle);
  959. do_filesize:=do_seekend(handle);
  960. do_seek(handle,aktfilepos);
  961. end;
  962. { truncate at a given position }
  963. procedure do_truncate (handle,pos:longint);
  964. var
  965. regs : trealregs;
  966. begin
  967. do_seek(handle,pos);
  968. regs.realecx:=0;
  969. regs.realedx:=tb_offset;
  970. regs.realds:=tb_segment;
  971. regs.realebx:=handle;
  972. regs.realeax:=$4000;
  973. sysrealintr($21,regs);
  974. if (regs.realflags and carryflag) <> 0 then
  975. GetInOutRes(lo(regs.realeax));
  976. end;
  977. const
  978. FileHandleCount : longint = 20;
  979. function Increase_file_handle_count : boolean;
  980. var
  981. regs : trealregs;
  982. begin
  983. Inc(FileHandleCount,10);
  984. regs.realebx:=FileHandleCount;
  985. regs.realeax:=$6700;
  986. sysrealintr($21,regs);
  987. if (regs.realflags and carryflag) <> 0 then
  988. begin
  989. Increase_file_handle_count:=false;
  990. Dec (FileHandleCount, 10);
  991. end
  992. else
  993. Increase_file_handle_count:=true;
  994. end;
  995. procedure do_open(var f;p:pchar;flags:longint);
  996. {
  997. filerec and textrec have both handle and mode as the first items so
  998. they could use the same routine for opening/creating.
  999. when (flags and $100) the file will be append
  1000. when (flags and $1000) the file will be truncate/rewritten
  1001. when (flags and $10000) there is no check for close (needed for textfiles)
  1002. }
  1003. var
  1004. regs : trealregs;
  1005. action : longint;
  1006. begin
  1007. AllowSlash(p);
  1008. { close first if opened }
  1009. if ((flags and $10000)=0) then
  1010. begin
  1011. case filerec(f).mode of
  1012. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  1013. fmclosed : ;
  1014. else
  1015. begin
  1016. inoutres:=102; {not assigned}
  1017. exit;
  1018. end;
  1019. end;
  1020. end;
  1021. { reset file handle }
  1022. filerec(f).handle:=UnusedHandle;
  1023. action:=$1;
  1024. { convert filemode to filerec modes }
  1025. case (flags and 3) of
  1026. 0 : filerec(f).mode:=fminput;
  1027. 1 : filerec(f).mode:=fmoutput;
  1028. 2 : filerec(f).mode:=fminout;
  1029. end;
  1030. if (flags and $1000)<>0 then
  1031. action:=$12; {create file function}
  1032. { empty name is special }
  1033. if p[0]=#0 then
  1034. begin
  1035. case FileRec(f).mode of
  1036. fminput :
  1037. FileRec(f).Handle:=StdInputHandle;
  1038. fminout, { this is set by rewrite }
  1039. fmoutput :
  1040. FileRec(f).Handle:=StdOutputHandle;
  1041. fmappend :
  1042. begin
  1043. FileRec(f).Handle:=StdOutputHandle;
  1044. FileRec(f).mode:=fmoutput; {fool fmappend}
  1045. end;
  1046. end;
  1047. exit;
  1048. end;
  1049. { real dos call }
  1050. syscopytodos(longint(p),strlen(p)+1);
  1051. if LFNSupport then
  1052. regs.realeax:=$716c
  1053. else
  1054. regs.realeax:=$6c00;
  1055. regs.realedx:=action;
  1056. regs.realds:=tb_segment;
  1057. regs.realesi:=tb_offset;
  1058. regs.realebx:=$2000+(flags and $ff);
  1059. regs.realecx:=$20;
  1060. sysrealintr($21,regs);
  1061. if (regs.realflags and carryflag) <> 0 then
  1062. if lo(regs.realeax)=4 then
  1063. if Increase_file_handle_count then
  1064. begin
  1065. { Try again }
  1066. if LFNSupport then
  1067. regs.realeax:=$716c
  1068. else
  1069. regs.realeax:=$6c00;
  1070. regs.realedx:=action;
  1071. regs.realds:=tb_segment;
  1072. regs.realesi:=tb_offset;
  1073. regs.realebx:=$2000+(flags and $ff);
  1074. regs.realecx:=$20;
  1075. sysrealintr($21,regs);
  1076. end;
  1077. if (regs.realflags and carryflag) <> 0 then
  1078. begin
  1079. GetInOutRes(lo(regs.realeax));
  1080. exit;
  1081. end
  1082. else
  1083. begin
  1084. filerec(f).handle:=lo(regs.realeax);
  1085. { for systems that have more then 20 by default ! }
  1086. if lo(regs.realeax)>FileHandleCount then
  1087. FileHandleCount:=lo(regs.realeax);
  1088. end;
  1089. if lo(regs.realeax)<max_files then
  1090. begin
  1091. {$ifdef SYSTEMDEBUG}
  1092. if openfiles[lo(regs.realeax)] and
  1093. assigned(opennames[lo(regs.realeax)]) then
  1094. begin
  1095. Writeln(stderr,'file ',opennames[lo(regs.realeax)],'(',lo(regs.realeax),') not closed but handle reused!');
  1096. sysfreememsize(opennames[lo(regs.realeax)],strlen(opennames[lo(regs.realeax)])+1);
  1097. end;
  1098. {$endif SYSTEMDEBUG}
  1099. openfiles[lo(regs.realeax)]:=true;
  1100. {$ifdef SYSTEMDEBUG}
  1101. opennames[lo(regs.realeax)] := sysgetmem(strlen(p)+1);
  1102. move(p^,opennames[lo(regs.realeax)]^,strlen(p)+1);
  1103. {$endif SYSTEMDEBUG}
  1104. end;
  1105. { append mode }
  1106. if (flags and $100)<>0 then
  1107. begin
  1108. do_seekend(filerec(f).handle);
  1109. filerec(f).mode:=fmoutput; {fool fmappend}
  1110. end;
  1111. end;
  1112. function do_isdevice(handle:longint):boolean;
  1113. var
  1114. regs : trealregs;
  1115. begin
  1116. regs.realebx:=handle;
  1117. regs.realeax:=$4400;
  1118. sysrealintr($21,regs);
  1119. do_isdevice:=(regs.realedx and $80)<>0;
  1120. if (regs.realflags and carryflag) <> 0 then
  1121. GetInOutRes(lo(regs.realeax));
  1122. end;
  1123. {*****************************************************************************
  1124. UnTyped File Handling
  1125. *****************************************************************************}
  1126. {$i file.inc}
  1127. {*****************************************************************************
  1128. Typed File Handling
  1129. *****************************************************************************}
  1130. {$i typefile.inc}
  1131. {*****************************************************************************
  1132. Text File Handling
  1133. *****************************************************************************}
  1134. {$DEFINE EOF_CTRLZ}
  1135. {$i text.inc}
  1136. {*****************************************************************************
  1137. Generic Handling
  1138. *****************************************************************************}
  1139. {$ifdef TEST_GENERIC}
  1140. {$i generic.inc}
  1141. {$endif TEST_GENERIC}
  1142. {*****************************************************************************
  1143. Directory Handling
  1144. *****************************************************************************}
  1145. procedure DosDir(func:byte;const s:string);
  1146. var
  1147. buffer : array[0..255] of char;
  1148. regs : trealregs;
  1149. begin
  1150. move(s[1],buffer,length(s));
  1151. buffer[length(s)]:=#0;
  1152. AllowSlash(pchar(@buffer));
  1153. { True DOS does not like backslashes at end
  1154. Win95 DOS accepts this !!
  1155. but "\" and "c:\" should still be kept and accepted hopefully PM }
  1156. if (length(s)>0) and (buffer[length(s)-1]='\') and
  1157. Not ((length(s)=1) or ((length(s)=3) and (s[2]=':'))) then
  1158. buffer[length(s)-1]:=#0;
  1159. syscopytodos(longint(@buffer),length(s)+1);
  1160. regs.realedx:=tb_offset;
  1161. regs.realds:=tb_segment;
  1162. if LFNSupport then
  1163. regs.realeax:=$7100+func
  1164. else
  1165. regs.realeax:=func shl 8;
  1166. sysrealintr($21,regs);
  1167. if (regs.realflags and carryflag) <> 0 then
  1168. GetInOutRes(lo(regs.realeax));
  1169. end;
  1170. procedure mkdir(const s : string);[IOCheck];
  1171. begin
  1172. If (s='') or (InOutRes <> 0) then
  1173. exit;
  1174. DosDir($39,s);
  1175. end;
  1176. procedure rmdir(const s : string);[IOCheck];
  1177. begin
  1178. if (s = '.' ) then
  1179. InOutRes := 16;
  1180. If (s='') or (InOutRes <> 0) then
  1181. exit;
  1182. DosDir($3a,s);
  1183. end;
  1184. procedure chdir(const s : string);[IOCheck];
  1185. var
  1186. regs : trealregs;
  1187. begin
  1188. If (s='') or (InOutRes <> 0) then
  1189. exit;
  1190. { First handle Drive changes }
  1191. if (length(s)>=2) and (s[2]=':') then
  1192. begin
  1193. regs.realedx:=(ord(s[1]) and (not 32))-ord('A');
  1194. regs.realeax:=$0e00;
  1195. sysrealintr($21,regs);
  1196. regs.realeax:=$1900;
  1197. sysrealintr($21,regs);
  1198. if byte(regs.realeax)<>byte(regs.realedx) then
  1199. begin
  1200. Inoutres:=15;
  1201. exit;
  1202. end;
  1203. { DosDir($3b,'c:') give Path not found error on
  1204. pure DOS PM }
  1205. if length(s)=2 then
  1206. exit;
  1207. end;
  1208. { do the normal dos chdir }
  1209. DosDir($3b,s);
  1210. end;
  1211. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  1212. var
  1213. temp : array[0..255] of char;
  1214. i : longint;
  1215. regs : trealregs;
  1216. begin
  1217. regs.realedx:=drivenr;
  1218. regs.realesi:=tb_offset;
  1219. regs.realds:=tb_segment;
  1220. if LFNSupport then
  1221. regs.realeax:=$7147
  1222. else
  1223. regs.realeax:=$4700;
  1224. sysrealintr($21,regs);
  1225. if (regs.realflags and carryflag) <> 0 then
  1226. Begin
  1227. GetInOutRes (lo(regs.realeax));
  1228. Dir := char (DriveNr + 64) + ':\';
  1229. exit;
  1230. end
  1231. else
  1232. syscopyfromdos(longint(@temp),251);
  1233. { conversion to Pascal string including slash conversion }
  1234. i:=0;
  1235. while (temp[i]<>#0) do
  1236. begin
  1237. if temp[i]='/' then
  1238. temp[i]:='\';
  1239. dir[i+4]:=temp[i];
  1240. inc(i);
  1241. end;
  1242. dir[2]:=':';
  1243. dir[3]:='\';
  1244. dir[0]:=char(i+3);
  1245. { upcase the string }
  1246. if not FileNameCaseSensitive then
  1247. dir:=upcase(dir);
  1248. if drivenr<>0 then { Drive was supplied. We know it }
  1249. dir[1]:=char(65+drivenr-1)
  1250. else
  1251. begin
  1252. { We need to get the current drive from DOS function 19H }
  1253. { because the drive was the default, which can be unknown }
  1254. regs.realeax:=$1900;
  1255. sysrealintr($21,regs);
  1256. i:= (regs.realeax and $ff) + ord('A');
  1257. dir[1]:=chr(i);
  1258. end;
  1259. end;
  1260. {*****************************************************************************
  1261. SystemUnit Initialization
  1262. *****************************************************************************}
  1263. function CheckLFN:boolean;
  1264. var
  1265. regs : TRealRegs;
  1266. RootName : pchar;
  1267. begin
  1268. { Check LFN API on drive c:\ }
  1269. RootName:='C:\';
  1270. syscopytodos(longint(RootName),strlen(RootName)+1);
  1271. { Call 'Get Volume Information' ($71A0) }
  1272. regs.realeax:=$71a0;
  1273. regs.reales:=tb_segment;
  1274. regs.realedi:=tb_offset;
  1275. regs.realecx:=32;
  1276. regs.realds:=tb_segment;
  1277. regs.realedx:=tb_offset;
  1278. regs.realflags:=carryflag;
  1279. sysrealintr($21,regs);
  1280. { If carryflag=0 and LFN API bit in ebx is set then use Long file names }
  1281. CheckLFN:=(regs.realflags and carryflag=0) and (regs.realebx and $4000=$4000);
  1282. end;
  1283. {$ifdef EXCEPTIONS_IN_SYSTEM}
  1284. {$define IN_SYSTEM}
  1285. {$i dpmiexcp.pp}
  1286. {$endif EXCEPTIONS_IN_SYSTEM}
  1287. procedure SysInitStdIO;
  1288. begin
  1289. OpenStdIO(Input,fmInput,StdInputHandle);
  1290. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1291. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1292. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1293. end;
  1294. var
  1295. temp_int : tseginfo;
  1296. Begin
  1297. StackLength := InitialStkLen;
  1298. StackBottom := __stkbottom;
  1299. { To be set if this is a GUI or console application }
  1300. IsConsole := TRUE;
  1301. { To be set if this is a library and not a program }
  1302. IsLibrary := FALSE;
  1303. { save old int 0 and 75 }
  1304. get_pm_interrupt($00,old_int00);
  1305. get_pm_interrupt($75,old_int75);
  1306. temp_int.segment:=get_cs;
  1307. temp_int.offset:=@new_int00;
  1308. set_pm_interrupt($00,temp_int);
  1309. {$ifndef EXCEPTIONS_IN_SYSTEM}
  1310. temp_int.offset:=@new_int75;
  1311. set_pm_interrupt($75,temp_int);
  1312. {$endif EXCEPTIONS_IN_SYSTEM}
  1313. { Setup heap }
  1314. InitHeap;
  1315. SysInitExceptions;
  1316. { Setup stdin, stdout and stderr }
  1317. SysInitStdIO;
  1318. { Setup environment and arguments }
  1319. Setup_Environment;
  1320. Setup_Arguments;
  1321. { Use LFNSupport LFN }
  1322. LFNSupport:=CheckLFN;
  1323. if LFNSupport then
  1324. FileNameCaseSensitive:=true;
  1325. { Reset IO Error }
  1326. InOutRes:=0;
  1327. {$ifdef EXCEPTIONS_IN_SYSTEM}
  1328. InitDPMIExcp;
  1329. InstallDefaultHandlers;
  1330. {$endif EXCEPTIONS_IN_SYSTEM}
  1331. {$ifdef HASVARIANT}
  1332. initvariantmanager;
  1333. {$endif HASVARIANT}
  1334. End.
  1335. {
  1336. $Log$
  1337. Revision 1.23 2002-10-14 19:39:16 peter
  1338. * threads unit added for thread support
  1339. Revision 1.22 2002/10/13 09:28:44 florian
  1340. + call to initvariantmanager inserted
  1341. Revision 1.21 2002/09/07 21:32:08 carl
  1342. - removed unused defines
  1343. Revision 1.20 2002/09/07 16:01:19 peter
  1344. * old logs removed and tabs fixed
  1345. Revision 1.19 2002/07/01 16:29:05 peter
  1346. * sLineBreak changed to normal constant like Kylix
  1347. Revision 1.18 2002/05/05 10:23:54 peter
  1348. * fixed memw and meml array sizes
  1349. Revision 1.17 2002/04/21 15:52:58 carl
  1350. + initialize some global variables
  1351. Revision 1.16 2002/04/12 17:34:05 carl
  1352. + generic stack checking
  1353. Revision 1.15 2002/03/11 19:10:33 peter
  1354. * Regenerated with updated fpcmake
  1355. }