system.pp 37 KB

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