system.pp 36 KB

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