system.pp 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561
  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. Watcom
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit system;
  13. INTERFACE
  14. {$ifndef NO_EXCEPTIONS_IN_SYSTEM}
  15. {$define EXCEPTIONS_IN_SYSTEM}
  16. {$endif NO_EXCEPTIONS_IN_SYSTEM}
  17. { include system-independent routine headers }
  18. {$include systemh.inc}
  19. { include heap support headers }
  20. {$include heaph.inc}
  21. {Platform specific information}
  22. type
  23. THandle = Longint;
  24. TThreadID = THandle;
  25. const
  26. LineEnding = #13#10;
  27. { LFNSupport is a variable here, defined below!!! }
  28. DirectorySeparator = '\';
  29. DriveSeparator = ':';
  30. PathSeparator = ';';
  31. { FileNameCaseSensitive is defined separately below!!! }
  32. maxExitCode = 255;
  33. MaxPathLen = 256;
  34. const
  35. { Default filehandles }
  36. UnusedHandle = -1;
  37. StdInputHandle = 0;
  38. StdOutputHandle = 1;
  39. StdErrorHandle = 2;
  40. FileNameCaseSensitive : boolean = false;
  41. CtrlZMarksEOF: boolean = true; (* #26 is considered as end of file *)
  42. sLineBreak = LineEnding;
  43. DefaultTextLineBreakStyle : TTextLineBreakStyle = tlbsCRLF;
  44. { Default memory segments (Tp7 compatibility) }
  45. seg0040 = $0040;
  46. segA000 = $A000;
  47. segB000 = $B000;
  48. segB800 = $B800;
  49. var
  50. { Mem[] support }
  51. mem : array[0..$7fffffff] of byte absolute $0:$0;
  52. memw : array[0..$7fffffff div sizeof(word)] of word absolute $0:$0;
  53. meml : array[0..$7fffffff div sizeof(longint)] of longint absolute $0:$0;
  54. { C-compatible arguments and environment }
  55. argc : longint;
  56. argv : ppchar;
  57. envp : ppchar;
  58. dos_argv0 : pchar;
  59. {$ifndef RTLLITE}
  60. { System info }
  61. LFNSupport : boolean;
  62. {$ELSE RTLLITE}
  63. Const
  64. LFNSupport = false;
  65. {$endif RTLLITE}
  66. {
  67. necessary for objects.pas, should be removed (at least from the interface
  68. to the implementation)
  69. }
  70. type
  71. trealregs=record
  72. realedi,realesi,realebp,realres,
  73. realebx,realedx,realecx,realeax : longint;
  74. realflags,
  75. reales,realds,realfs,realgs,
  76. realip,realcs,realsp,realss : word;
  77. end;
  78. function do_write(h:longint;addr:pointer;len : longint) : longint;
  79. function do_read(h:longint;addr:pointer;len : longint) : longint;
  80. procedure syscopyfromdos(addr : sizeuint; len : longint);
  81. procedure syscopytodos(addr : sizeuint; len : longint);
  82. procedure sysrealintr(intnr : word;var regs : trealregs);
  83. var tb:longint;
  84. tb_segment:word;
  85. const tb_offset=0;
  86. tb_size=8192;
  87. IMPLEMENTATION
  88. { include system independent routines }
  89. {$include system.inc}
  90. const
  91. carryflag = 1;
  92. type
  93. tseginfo=packed record
  94. offset : pointer;
  95. segment : word;
  96. end;
  97. var
  98. old_int00 : tseginfo;cvar;
  99. old_int75 : tseginfo;cvar;
  100. {$asmmode ATT}
  101. {*****************************************************************************
  102. Watcom Helpers
  103. *****************************************************************************}
  104. function far_strlen(selector : word;linear_address : sizeuint) : longint;assembler;
  105. asm
  106. movl linear_address,%edx
  107. movl %edx,%ecx
  108. movw selector,%gs
  109. .Larg19:
  110. movb %gs:(%edx),%al
  111. testb %al,%al
  112. je .Larg20
  113. incl %edx
  114. jmp .Larg19
  115. .Larg20:
  116. movl %edx,%eax
  117. subl %ecx,%eax
  118. end;
  119. function get_ds : word;assembler;
  120. asm
  121. movw %ds,%ax
  122. end;
  123. function get_cs : word;assembler;
  124. asm
  125. movw %cs,%ax
  126. end;
  127. function dos_selector : word; assembler;
  128. asm
  129. movw %ds,%ax { no separate selector needed }
  130. end;
  131. procedure alloc_tb; assembler;
  132. { allocate 8kB real mode transfer buffer }
  133. asm
  134. pushl %ebx
  135. movw $0x100,%ax
  136. movw $512,%bx
  137. int $0x31
  138. movw %ax,tb_segment
  139. shll $16,%eax
  140. shrl $12,%eax
  141. movl %eax,tb
  142. popl %ebx
  143. end;
  144. procedure sysseg_move(sseg : word;source : sizeuint;dseg : word;dest : sizeuint;count : longint);
  145. begin
  146. if count=0 then
  147. exit;
  148. if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
  149. asm
  150. pushl %esi
  151. pushl %edi
  152. pushw %es
  153. pushw %ds
  154. cld
  155. movl count,%ecx
  156. movl source,%esi
  157. movl dest,%edi
  158. movw dseg,%ax
  159. movw %ax,%es
  160. movw sseg,%ax
  161. movw %ax,%ds
  162. movl %ecx,%eax
  163. shrl $2,%ecx
  164. rep
  165. movsl
  166. movl %eax,%ecx
  167. andl $3,%ecx
  168. rep
  169. movsb
  170. popw %ds
  171. popw %es
  172. popl %edi
  173. popl %esi
  174. end
  175. else if (source<dest) then
  176. { copy backward for overlapping }
  177. asm
  178. pushl %esi
  179. pushl %edi
  180. pushw %es
  181. pushw %ds
  182. std
  183. movl count,%ecx
  184. movl source,%esi
  185. movl dest,%edi
  186. movw dseg,%ax
  187. movw %ax,%es
  188. movw sseg,%ax
  189. movw %ax,%ds
  190. addl %ecx,%esi
  191. addl %ecx,%edi
  192. movl %ecx,%eax
  193. andl $3,%ecx
  194. orl %ecx,%ecx
  195. jz .LSEG_MOVE1
  196. { calculate esi and edi}
  197. decl %esi
  198. decl %edi
  199. rep
  200. movsb
  201. incl %esi
  202. incl %edi
  203. .LSEG_MOVE1:
  204. subl $4,%esi
  205. subl $4,%edi
  206. movl %eax,%ecx
  207. shrl $2,%ecx
  208. rep
  209. movsl
  210. cld
  211. popw %ds
  212. popw %es
  213. popl %edi
  214. popl %esi
  215. end;
  216. end;
  217. var psp_selector:word; external name 'PSP_SELECTOR';
  218. procedure setup_arguments;
  219. type
  220. arrayword = array [0..255] of word;
  221. var
  222. proxy_s : string[50];
  223. proxy_argc,proxy_seg,proxy_ofs,lin : longint;
  224. rm_argv : ^arrayword;
  225. argv0len : longint;
  226. useproxy : boolean;
  227. hp : ppchar;
  228. doscmd : string[129]; { Dos commandline copied from PSP, max is 128 chars +1 for terminating zero }
  229. arglen,
  230. count : longint;
  231. argstart,
  232. pc,arg : pchar;
  233. quote : char;
  234. argvlen : longint;
  235. function atohex(s : pchar) : longint;
  236. var
  237. rv : longint;
  238. v : byte;
  239. begin
  240. rv:=0;
  241. while (s^<>#0) do
  242. begin
  243. v:=byte(s^)-byte('0');
  244. if (v > 9) then
  245. dec(v,7);
  246. v:=v and 15; { in case it's lower case }
  247. rv:=(rv shl 4) or v;
  248. inc(longint(s));
  249. end;
  250. atohex:=rv;
  251. end;
  252. procedure allocarg(idx,len:longint);
  253. var oldargvlen:longint;
  254. begin
  255. if idx>=argvlen then
  256. begin
  257. oldargvlen:=argvlen;
  258. argvlen:=(idx+8) and (not 7);
  259. sysreallocmem(argv,argvlen*sizeof(pointer));
  260. fillchar(argv[oldargvlen],(argvlen-oldargvlen)*sizeof(pointer),0);
  261. argv[idx]:=nil;
  262. end;
  263. ArgV [Idx] := SysAllocMem (Succ (Len));
  264. end;
  265. begin
  266. count:=0;
  267. argc:=1;
  268. argv:=nil;
  269. argvlen:=0;
  270. { load commandline from psp }
  271. sysseg_move(psp_selector, 128, get_ds, longint(@doscmd), 128);
  272. doscmd[length(doscmd)+1]:=#0;
  273. {$IfDef SYSTEM_DEBUG_STARTUP}
  274. Writeln(stderr,'Dos command line is #',doscmd,'# size = ',length(doscmd));
  275. {$EndIf }
  276. { create argv[0] }
  277. argv0len:=strlen(dos_argv0);
  278. allocarg(count,argv0len);
  279. move(dos_argv0^,argv[count]^,argv0len);
  280. inc(count);
  281. { setup cmdline variable }
  282. cmdline:=Getmem(argv0len+length(doscmd)+2);
  283. move(dos_argv0^,cmdline^,argv0len);
  284. cmdline[argv0len]:=' ';
  285. inc(argv0len);
  286. move(doscmd[1],cmdline[argv0len],length(doscmd));
  287. cmdline[argv0len+length(doscmd)+1]:=#0;
  288. { parse dos commandline }
  289. pc:=@doscmd[1];
  290. while pc^<>#0 do
  291. begin
  292. { skip leading spaces }
  293. while pc^ in [#1..#32] do
  294. inc(pc);
  295. if pc^=#0 then
  296. break;
  297. { calc argument length }
  298. quote:=' ';
  299. argstart:=pc;
  300. arglen:=0;
  301. while (pc^<>#0) do
  302. begin
  303. case pc^ of
  304. #1..#32 :
  305. begin
  306. if quote<>' ' then
  307. inc(arglen)
  308. else
  309. break;
  310. end;
  311. '"' :
  312. begin
  313. if quote<>'''' then
  314. begin
  315. if pchar(pc+1)^<>'"' then
  316. begin
  317. if quote='"' then
  318. quote:=' '
  319. else
  320. quote:='"';
  321. end
  322. else
  323. inc(pc);
  324. end
  325. else
  326. inc(arglen);
  327. end;
  328. '''' :
  329. begin
  330. if quote<>'"' then
  331. begin
  332. if pchar(pc+1)^<>'''' then
  333. begin
  334. if quote='''' then
  335. quote:=' '
  336. else
  337. quote:='''';
  338. end
  339. else
  340. inc(pc);
  341. end
  342. else
  343. inc(arglen);
  344. end;
  345. else
  346. inc(arglen);
  347. end;
  348. inc(pc);
  349. end;
  350. { copy argument }
  351. allocarg(count,arglen);
  352. quote:=' ';
  353. pc:=argstart;
  354. arg:=argv[count];
  355. while (pc^<>#0) do
  356. begin
  357. case pc^ of
  358. #1..#32 :
  359. begin
  360. if quote<>' ' then
  361. begin
  362. arg^:=pc^;
  363. inc(arg);
  364. end
  365. else
  366. break;
  367. end;
  368. '"' :
  369. begin
  370. if quote<>'''' then
  371. begin
  372. if pchar(pc+1)^<>'"' then
  373. begin
  374. if quote='"' then
  375. quote:=' '
  376. else
  377. quote:='"';
  378. end
  379. else
  380. inc(pc);
  381. end
  382. else
  383. begin
  384. arg^:=pc^;
  385. inc(arg);
  386. end;
  387. end;
  388. '''' :
  389. begin
  390. if quote<>'"' then
  391. begin
  392. if pchar(pc+1)^<>'''' then
  393. begin
  394. if quote='''' then
  395. quote:=' '
  396. else
  397. quote:='''';
  398. end
  399. else
  400. inc(pc);
  401. end
  402. else
  403. begin
  404. arg^:=pc^;
  405. inc(arg);
  406. end;
  407. end;
  408. else
  409. begin
  410. arg^:=pc^;
  411. inc(arg);
  412. end;
  413. end;
  414. inc(pc);
  415. end;
  416. arg^:=#0;
  417. {$IfDef SYSTEM_DEBUG_STARTUP}
  418. Writeln(stderr,'dos arg ',count,' #',arglen,'#',argv[count],'#');
  419. {$EndIf SYSTEM_DEBUG_STARTUP}
  420. inc(count);
  421. end;
  422. argc:=count;
  423. { check for !proxy for long commandlines passed using environment }
  424. hp:=envp;
  425. useproxy:=false;
  426. while assigned(hp^) do
  427. begin
  428. if (hp^[0]=' ') then
  429. begin
  430. proxy_s:=strpas(hp^);
  431. if Copy(proxy_s,1,7)=' !proxy' then
  432. begin
  433. proxy_s[13]:=#0;
  434. proxy_s[18]:=#0;
  435. proxy_s[23]:=#0;
  436. argv[2]:=@proxy_s[9];
  437. argv[3]:=@proxy_s[14];
  438. argv[4]:=@proxy_s[19];
  439. useproxy:=true;
  440. break;
  441. end;
  442. end;
  443. inc(hp);
  444. end;
  445. { check for !proxy for long commandlines passed using commandline }
  446. if (not useproxy) and
  447. (argc > 1) and (far_strlen(get_ds,longint(argv[1])) = 6) then
  448. begin
  449. move(argv[1]^,proxy_s[1],6);
  450. proxy_s[0] := #6;
  451. if (proxy_s = '!proxy') then
  452. useproxy:=true;
  453. end;
  454. { use proxy when found }
  455. if useproxy then
  456. begin
  457. proxy_argc:=atohex(argv[2]);
  458. proxy_seg:=atohex(argv[3]);
  459. proxy_ofs:=atohex(argv[4]);
  460. {$IfDef SYSTEM_DEBUG_STARTUP}
  461. Writeln(stderr,'proxy command line found');
  462. writeln(stderr,'argc: ',proxy_argc,' seg: ',proxy_seg,' ofs: ',proxy_ofs);
  463. {$EndIf SYSTEM_DEBUG_STARTUP}
  464. rm_argv:=SysGetmem(proxy_argc*sizeof(word));
  465. sysseg_move(dos_selector,proxy_seg*16+proxy_ofs, get_ds,longint(rm_argv),proxy_argc*sizeof(word));
  466. for count:=0 to proxy_argc - 1 do
  467. begin
  468. lin:=proxy_seg*16+rm_argv^[count];
  469. arglen:=far_strlen(dos_selector,lin);
  470. allocarg(count,arglen);
  471. sysseg_move(dos_selector,lin,get_ds,longint(argv[count]),arglen+1);
  472. {$IfDef SYSTEM_DEBUG_STARTUP}
  473. Writeln(stderr,'arg ',count,' #',rm_argv^[count],'#',arglen,'#',argv[count],'#');
  474. {$EndIf SYSTEM_DEBUG_STARTUP}
  475. end;
  476. SysFreemem(rm_argv);
  477. argc:=proxy_argc;
  478. end;
  479. { create an nil entry }
  480. allocarg(argc,0);
  481. { free unused memory }
  482. sysreallocmem(argv,(argc+1)*sizeof(pointer));
  483. end;
  484. function strcopy(dest,source : pchar) : pchar;assembler;
  485. var
  486. saveeax,saveesi,saveedi : longint;
  487. asm
  488. movl %edi,saveedi
  489. movl %esi,saveesi
  490. {$ifdef REGCALL}
  491. movl %eax,saveeax
  492. movl %edx,%edi
  493. {$else}
  494. movl source,%edi
  495. {$endif}
  496. testl %edi,%edi
  497. jz .LStrCopyDone
  498. leal 3(%edi),%ecx
  499. andl $-4,%ecx
  500. movl %edi,%esi
  501. subl %edi,%ecx
  502. {$ifdef REGCALL}
  503. movl %eax,%edi
  504. {$else}
  505. movl dest,%edi
  506. {$endif}
  507. jz .LStrCopyAligned
  508. .LStrCopyAlignLoop:
  509. movb (%esi),%al
  510. incl %edi
  511. incl %esi
  512. testb %al,%al
  513. movb %al,-1(%edi)
  514. jz .LStrCopyDone
  515. decl %ecx
  516. jnz .LStrCopyAlignLoop
  517. .balign 16
  518. .LStrCopyAligned:
  519. movl (%esi),%eax
  520. movl %eax,%edx
  521. leal 0x0fefefeff(%eax),%ecx
  522. notl %edx
  523. addl $4,%esi
  524. andl %edx,%ecx
  525. andl $0x080808080,%ecx
  526. jnz .LStrCopyEndFound
  527. movl %eax,(%edi)
  528. addl $4,%edi
  529. jmp .LStrCopyAligned
  530. .LStrCopyEndFound:
  531. testl $0x0ff,%eax
  532. jz .LStrCopyByte
  533. testl $0x0ff00,%eax
  534. jz .LStrCopyWord
  535. testl $0x0ff0000,%eax
  536. jz .LStrCopy3Bytes
  537. movl %eax,(%edi)
  538. jmp .LStrCopyDone
  539. .LStrCopy3Bytes:
  540. xorb %dl,%dl
  541. movw %ax,(%edi)
  542. movb %dl,2(%edi)
  543. jmp .LStrCopyDone
  544. .LStrCopyWord:
  545. movw %ax,(%edi)
  546. jmp .LStrCopyDone
  547. .LStrCopyByte:
  548. movb %al,(%edi)
  549. .LStrCopyDone:
  550. {$ifdef REGCALL}
  551. movl saveeax,%eax
  552. {$else}
  553. movl dest,%eax
  554. {$endif}
  555. movl saveedi,%edi
  556. movl saveesi,%esi
  557. end;
  558. var
  559. env_selector:word; external name 'ENV_SELECTOR';
  560. env_size:longint; external name 'ENV_SIZE';
  561. procedure setup_environment;
  562. var env_count : longint;
  563. dos_env,cp : pchar;
  564. begin
  565. env_count:=0;
  566. dos_env:=getmem(env_size);
  567. sysseg_move(env_selector,$0, get_ds, longint(dos_env), 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. end;
  597. procedure syscopytodos(addr : sizeuint; len : longint);
  598. begin
  599. if len > tb_size then
  600. HandleError(217);
  601. sysseg_move(get_ds,addr,dos_selector,tb,len);
  602. end;
  603. procedure syscopyfromdos(addr : sizeuint; len : longint);
  604. begin
  605. if len > tb_size then
  606. HandleError(217);
  607. sysseg_move(dos_selector,tb,get_ds,addr,len);
  608. end;
  609. procedure sysrealintr(intnr : word;var regs : trealregs);
  610. begin
  611. regs.realsp:=0;
  612. regs.realss:=0;
  613. asm
  614. pushl %edi
  615. pushl %ebx
  616. pushw %fs
  617. movw intnr,%bx
  618. xorl %ecx,%ecx
  619. movl regs,%edi
  620. movw $0x300,%ax
  621. int $0x31
  622. popw %fs
  623. popl %ebx
  624. popl %edi
  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 : pointer;//###########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. OS Memory allocation / deallocation
  750. ****************************************************************************}
  751. function ___sbrk(size:longint):pointer;cdecl; external name '___sbrk';
  752. function SysOSAlloc(size: ptrint): pointer;assembler;
  753. asm
  754. {$ifdef SYSTEMDEBUG}
  755. cmpb $1,accept_sbrk
  756. je .Lsbrk
  757. movl $0,%eax
  758. jmp .Lsbrk_fail
  759. .Lsbrk:
  760. {$endif}
  761. movl size,%eax
  762. pushl %eax
  763. call ___sbrk
  764. addl $4,%esp
  765. {$ifdef SYSTEMDEBUG}
  766. .Lsbrk_fail:
  767. {$endif}
  768. end;
  769. { define HAS_SYSOSFREE}
  770. procedure SysOSFree(p: pointer; size: ptrint);
  771. begin
  772. end;
  773. { include standard heap management }
  774. {$include heap.inc}
  775. {****************************************************************************
  776. Low level File Routines
  777. ****************************************************************************}
  778. procedure AllowSlash(p:pchar);
  779. var
  780. i : longint;
  781. begin
  782. { allow slash as backslash }
  783. for i:=0 to strlen(p) do
  784. if p[i]='/' then p[i]:='\';
  785. end;
  786. procedure do_close(handle : longint);
  787. var
  788. regs : trealregs;
  789. begin
  790. if Handle<=4 then
  791. exit;
  792. regs.realebx:=handle;
  793. if handle<max_files then
  794. begin
  795. openfiles[handle]:=false;
  796. {$ifdef SYSTEMDEBUG}
  797. if assigned(opennames[handle]) and free_closed_names then
  798. begin
  799. sysfreememsize(opennames[handle],strlen(opennames[handle])+1);
  800. opennames[handle]:=nil;
  801. end;
  802. {$endif SYSTEMDEBUG}
  803. end;
  804. regs.realeax:=$3e00;
  805. sysrealintr($21,regs);
  806. if (regs.realflags and carryflag) <> 0 then
  807. GetInOutRes(lo(regs.realeax));
  808. end;
  809. procedure do_erase(p : pchar);
  810. var
  811. regs : trealregs;
  812. begin
  813. AllowSlash(p);
  814. syscopytodos(longint(p),strlen(p)+1);
  815. regs.realedx:=tb_offset;
  816. regs.realds:=tb_segment;
  817. if LFNSupport then
  818. regs.realeax:=$7141
  819. else
  820. regs.realeax:=$4100;
  821. regs.realesi:=0;
  822. regs.realecx:=0;
  823. sysrealintr($21,regs);
  824. if (regs.realflags and carryflag) <> 0 then
  825. GetInOutRes(lo(regs.realeax));
  826. end;
  827. procedure do_rename(p1,p2 : pchar);
  828. var
  829. regs : trealregs;
  830. begin
  831. AllowSlash(p1);
  832. AllowSlash(p2);
  833. if strlen(p1)+strlen(p2)+3>tb_size then
  834. HandleError(217);
  835. sysseg_move(get_ds,sizeuint(p2),dos_selector,tb,strlen(p2)+1);
  836. sysseg_move(get_ds,sizeuint(p1),dos_selector,tb+strlen(p2)+2,strlen(p1)+1);
  837. regs.realedi:=tb_offset;
  838. regs.realedx:=tb_offset + strlen(p2)+2;
  839. regs.realds:=tb_segment;
  840. regs.reales:=tb_segment;
  841. if LFNSupport then
  842. regs.realeax:=$7156
  843. else
  844. regs.realeax:=$5600;
  845. regs.realecx:=$ff; { attribute problem here ! }
  846. sysrealintr($21,regs);
  847. if (regs.realflags and carryflag) <> 0 then
  848. GetInOutRes(lo(regs.realeax));
  849. end;
  850. function do_write(h:longint;addr:pointer;len : longint) : longint;
  851. var
  852. regs : trealregs;
  853. size,
  854. writesize : longint;
  855. begin
  856. writesize:=0;
  857. while len > 0 do
  858. begin
  859. if len>tb_size then
  860. size:=tb_size
  861. else
  862. size:=len;
  863. syscopytodos(ptrint(addr)+writesize,size);
  864. regs.realecx:=size;
  865. regs.realedx:=tb_offset;
  866. regs.realds:=tb_segment;
  867. regs.realebx:=h;
  868. regs.realeax:=$4000;
  869. sysrealintr($21,regs);
  870. if (regs.realflags and carryflag) <> 0 then
  871. begin
  872. GetInOutRes(lo(regs.realeax));
  873. exit(writesize);
  874. end;
  875. inc(writesize,lo(regs.realeax));
  876. dec(len,lo(regs.realeax));
  877. { stop when not the specified size is written }
  878. if lo(regs.realeax)<size then
  879. break;
  880. end;
  881. Do_Write:=WriteSize;
  882. end;
  883. function do_read(h:longint;addr:pointer;len : longint) : longint;
  884. var
  885. regs : trealregs;
  886. size,
  887. readsize : longint;
  888. begin
  889. readsize:=0;
  890. while len > 0 do
  891. begin
  892. if len>tb_size then
  893. size:=tb_size
  894. else
  895. size:=len;
  896. regs.realecx:=size;
  897. regs.realedx:=tb_offset;
  898. regs.realds:=tb_segment;
  899. regs.realebx:=h;
  900. regs.realeax:=$3f00;
  901. sysrealintr($21,regs);
  902. if (regs.realflags and carryflag) <> 0 then
  903. begin
  904. GetInOutRes(lo(regs.realeax));
  905. do_read:=0;
  906. exit;
  907. end;
  908. syscopyfromdos(ptrint(addr)+readsize,lo(regs.realeax));
  909. inc(readsize,lo(regs.realeax));
  910. dec(len,lo(regs.realeax));
  911. { stop when not the specified size is read }
  912. if lo(regs.realeax)<size then
  913. break;
  914. end;
  915. do_read:=readsize;
  916. end;
  917. function do_filepos(handle : longint) : longint;
  918. var
  919. regs : trealregs;
  920. begin
  921. regs.realebx:=handle;
  922. regs.realecx:=0;
  923. regs.realedx:=0;
  924. regs.realeax:=$4201;
  925. sysrealintr($21,regs);
  926. if (regs.realflags and carryflag) <> 0 then
  927. Begin
  928. GetInOutRes(lo(regs.realeax));
  929. do_filepos:=0;
  930. end
  931. else
  932. do_filepos:=lo(regs.realedx) shl 16+lo(regs.realeax);
  933. end;
  934. procedure do_seek(handle,pos : longint);
  935. var
  936. regs : trealregs;
  937. begin
  938. regs.realebx:=handle;
  939. regs.realecx:=pos shr 16;
  940. regs.realedx:=pos and $ffff;
  941. regs.realeax:=$4200;
  942. sysrealintr($21,regs);
  943. if (regs.realflags and carryflag) <> 0 then
  944. GetInOutRes(lo(regs.realeax));
  945. end;
  946. function do_seekend(handle:longint):longint;
  947. var
  948. regs : trealregs;
  949. begin
  950. regs.realebx:=handle;
  951. regs.realecx:=0;
  952. regs.realedx:=0;
  953. regs.realeax:=$4202;
  954. sysrealintr($21,regs);
  955. if (regs.realflags and carryflag) <> 0 then
  956. Begin
  957. GetInOutRes(lo(regs.realeax));
  958. do_seekend:=0;
  959. end
  960. else
  961. do_seekend:=lo(regs.realedx) shl 16+lo(regs.realeax);
  962. end;
  963. function do_filesize(handle : longint) : longint;
  964. var
  965. aktfilepos : longint;
  966. begin
  967. aktfilepos:=do_filepos(handle);
  968. do_filesize:=do_seekend(handle);
  969. do_seek(handle,aktfilepos);
  970. end;
  971. { truncate at a given position }
  972. procedure do_truncate (handle,pos:longint);
  973. var
  974. regs : trealregs;
  975. begin
  976. do_seek(handle,pos);
  977. regs.realecx:=0;
  978. regs.realedx:=tb_offset;
  979. regs.realds:=tb_segment;
  980. regs.realebx:=handle;
  981. regs.realeax:=$4000;
  982. sysrealintr($21,regs);
  983. if (regs.realflags and carryflag) <> 0 then
  984. GetInOutRes(lo(regs.realeax));
  985. end;
  986. const
  987. FileHandleCount : longint = 20;
  988. function Increase_file_handle_count : boolean;
  989. var
  990. regs : trealregs;
  991. begin
  992. Inc(FileHandleCount,10);
  993. regs.realebx:=FileHandleCount;
  994. regs.realeax:=$6700;
  995. sysrealintr($21,regs);
  996. if (regs.realflags and carryflag) <> 0 then
  997. begin
  998. Increase_file_handle_count:=false;
  999. Dec (FileHandleCount, 10);
  1000. end
  1001. else
  1002. Increase_file_handle_count:=true;
  1003. end;
  1004. function dos_version : word;
  1005. var
  1006. regs : trealregs;
  1007. begin
  1008. regs.realeax := $3000;
  1009. sysrealintr($21,regs);
  1010. dos_version := regs.realeax
  1011. end;
  1012. procedure do_open(var f;p:pchar;flags:longint);
  1013. {
  1014. filerec and textrec have both handle and mode as the first items so
  1015. they could use the same routine for opening/creating.
  1016. when (flags and $100) the file will be append
  1017. when (flags and $1000) the file will be truncate/rewritten
  1018. when (flags and $10000) there is no check for close (needed for textfiles)
  1019. }
  1020. var
  1021. regs : trealregs;
  1022. action : longint;
  1023. Avoid6c00 : boolean;
  1024. begin
  1025. AllowSlash(p);
  1026. { check if Extended Open/Create API is safe to use }
  1027. Avoid6c00 := lo(dos_version) < 7;
  1028. { close first if opened }
  1029. if ((flags and $10000)=0) then
  1030. begin
  1031. case filerec(f).mode of
  1032. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  1033. fmclosed : ;
  1034. else
  1035. begin
  1036. inoutres:=102; {not assigned}
  1037. exit;
  1038. end;
  1039. end;
  1040. end;
  1041. { reset file handle }
  1042. filerec(f).handle:=UnusedHandle;
  1043. action:=$1;
  1044. { convert filemode to filerec modes }
  1045. case (flags and 3) of
  1046. 0 : filerec(f).mode:=fminput;
  1047. 1 : filerec(f).mode:=fmoutput;
  1048. 2 : filerec(f).mode:=fminout;
  1049. end;
  1050. if (flags and $1000)<>0 then
  1051. action:=$12; {create file function}
  1052. { empty name is special }
  1053. if p[0]=#0 then
  1054. begin
  1055. case FileRec(f).mode of
  1056. fminput :
  1057. FileRec(f).Handle:=StdInputHandle;
  1058. fminout, { this is set by rewrite }
  1059. fmoutput :
  1060. FileRec(f).Handle:=StdOutputHandle;
  1061. fmappend :
  1062. begin
  1063. FileRec(f).Handle:=StdOutputHandle;
  1064. FileRec(f).mode:=fmoutput; {fool fmappend}
  1065. end;
  1066. end;
  1067. exit;
  1068. end;
  1069. { real dos call }
  1070. syscopytodos(longint(p),strlen(p)+1);
  1071. {$ifndef RTLLITE}
  1072. if LFNSupport then
  1073. regs.realeax := $716c { Use LFN Open/Create API }
  1074. else
  1075. regs.realeax:=$6c00;
  1076. {$endif RTLLITE}
  1077. if Avoid6c00 then
  1078. regs.realeax := $3d00 + (flags and $ff) { For now, map to Open API }
  1079. else
  1080. regs.realeax := $6c00; { Use Extended Open/Create API }
  1081. if byte(regs.realeax shr 8) = $3d then
  1082. begin { Using the older Open or Create API's }
  1083. if (action and $00f0) <> 0 then
  1084. regs.realeax := $3c00; { Map to Create/Replace API }
  1085. regs.realds := tb_segment;
  1086. regs.realedx := tb_offset;
  1087. end
  1088. else
  1089. begin { Using LFN or Extended Open/Create API }
  1090. regs.realedx := action; { action if file does/doesn't exist }
  1091. regs.realds := tb_segment;
  1092. regs.realesi := tb_offset;
  1093. regs.realebx := $2000 + (flags and $ff); { file open mode }
  1094. end;
  1095. regs.realecx := $20; { file attributes }
  1096. sysrealintr($21,regs);
  1097. {$ifndef RTLLITE}
  1098. if (regs.realflags and carryflag) <> 0 then
  1099. if lo(regs.realeax)=4 then
  1100. if Increase_file_handle_count then
  1101. begin
  1102. { Try again }
  1103. if LFNSupport then
  1104. regs.realeax := $716c {Use LFN Open/Create API}
  1105. else
  1106. if Avoid6c00 then
  1107. regs.realeax := $3d00+(flags and $ff) {For now, map to Open API}
  1108. else
  1109. regs.realeax := $6c00; {Use Extended Open/Create API}
  1110. if byte(regs.realeax shr 8) = $3d then
  1111. begin { Using the older Open or Create API's }
  1112. if (action and $00f0) <> 0 then
  1113. regs.realeax := $3c00; {Map to Create/Replace API}
  1114. regs.realds := tb_segment;
  1115. regs.realedx := tb_offset;
  1116. end
  1117. else
  1118. begin { Using LFN or Extended Open/Create API }
  1119. regs.realedx := action; {action if file does/doesn't exist}
  1120. regs.realds := tb_segment;
  1121. regs.realesi := tb_offset;
  1122. regs.realebx := $2000+(flags and $ff); {file open mode}
  1123. end;
  1124. regs.realecx := $20; {file attributes}
  1125. sysrealintr($21,regs);
  1126. end;
  1127. {$endif RTLLITE}
  1128. if (regs.realflags and carryflag) <> 0 then
  1129. begin
  1130. GetInOutRes(lo(regs.realeax));
  1131. exit;
  1132. end
  1133. else
  1134. begin
  1135. filerec(f).handle:=lo(regs.realeax);
  1136. {$ifndef RTLLITE}
  1137. { for systems that have more then 20 by default ! }
  1138. if lo(regs.realeax)>FileHandleCount then
  1139. FileHandleCount:=lo(regs.realeax);
  1140. {$endif RTLLITE}
  1141. end;
  1142. if lo(regs.realeax)<max_files then
  1143. begin
  1144. {$ifdef SYSTEMDEBUG}
  1145. if openfiles[lo(regs.realeax)] and
  1146. assigned(opennames[lo(regs.realeax)]) then
  1147. begin
  1148. Writeln(stderr,'file ',opennames[lo(regs.realeax)],'(',lo(regs.realeax),') not closed but handle reused!');
  1149. sysfreememsize(opennames[lo(regs.realeax)],strlen(opennames[lo(regs.realeax)])+1);
  1150. end;
  1151. {$endif SYSTEMDEBUG}
  1152. openfiles[lo(regs.realeax)]:=true;
  1153. {$ifdef SYSTEMDEBUG}
  1154. opennames[lo(regs.realeax)] := sysgetmem(strlen(p)+1);
  1155. move(p^,opennames[lo(regs.realeax)]^,strlen(p)+1);
  1156. {$endif SYSTEMDEBUG}
  1157. end;
  1158. { append mode }
  1159. if ((flags and $100) <> 0) and
  1160. (FileRec (F).Handle <> UnusedHandle) then
  1161. begin
  1162. do_seekend(filerec(f).handle);
  1163. filerec(f).mode:=fmoutput; {fool fmappend}
  1164. end;
  1165. end;
  1166. function do_isdevice(handle:THandle):boolean;
  1167. var
  1168. regs : trealregs;
  1169. begin
  1170. regs.realebx:=handle;
  1171. regs.realeax:=$4400;
  1172. sysrealintr($21,regs);
  1173. do_isdevice:=(regs.realedx and $80)<>0;
  1174. if (regs.realflags and carryflag) <> 0 then
  1175. GetInOutRes(lo(regs.realeax));
  1176. end;
  1177. {*****************************************************************************
  1178. UnTyped File Handling
  1179. *****************************************************************************}
  1180. {$i file.inc}
  1181. {*****************************************************************************
  1182. Typed File Handling
  1183. *****************************************************************************}
  1184. {$i typefile.inc}
  1185. {*****************************************************************************
  1186. Text File Handling
  1187. *****************************************************************************}
  1188. {$i text.inc}
  1189. {*****************************************************************************
  1190. Generic Handling
  1191. *****************************************************************************}
  1192. {$ifdef TEST_GENERIC}
  1193. {$i generic.inc}
  1194. {$endif TEST_GENERIC}
  1195. {*****************************************************************************
  1196. Directory Handling
  1197. *****************************************************************************}
  1198. procedure DosDir(func:byte;const s:string);
  1199. var
  1200. buffer : array[0..255] of char;
  1201. regs : trealregs;
  1202. begin
  1203. move(s[1],buffer,length(s));
  1204. buffer[length(s)]:=#0;
  1205. AllowSlash(pchar(@buffer));
  1206. { True DOS does not like backslashes at end
  1207. Win95 DOS accepts this !!
  1208. but "\" and "c:\" should still be kept and accepted hopefully PM }
  1209. if (length(s)>0) and (buffer[length(s)-1]='\') and
  1210. Not ((length(s)=1) or ((length(s)=3) and (s[2]=':'))) then
  1211. buffer[length(s)-1]:=#0;
  1212. syscopytodos(longint(@buffer),length(s)+1);
  1213. regs.realedx:=tb_offset;
  1214. regs.realds:=tb_segment;
  1215. if LFNSupport then
  1216. regs.realeax:=$7100+func
  1217. else
  1218. regs.realeax:=func shl 8;
  1219. sysrealintr($21,regs);
  1220. if (regs.realflags and carryflag) <> 0 then
  1221. GetInOutRes(lo(regs.realeax));
  1222. end;
  1223. procedure mkdir(const s : string);[IOCheck];
  1224. begin
  1225. If (s='') or (InOutRes <> 0) then
  1226. exit;
  1227. DosDir($39,s);
  1228. end;
  1229. procedure rmdir(const s : string);[IOCheck];
  1230. begin
  1231. if (s = '.' ) then
  1232. InOutRes := 16;
  1233. If (s='') or (InOutRes <> 0) then
  1234. exit;
  1235. DosDir($3a,s);
  1236. end;
  1237. procedure chdir(const s : string);[IOCheck];
  1238. var
  1239. regs : trealregs;
  1240. begin
  1241. If (s='') or (InOutRes <> 0) then
  1242. exit;
  1243. { First handle Drive changes }
  1244. if (length(s)>=2) and (s[2]=':') then
  1245. begin
  1246. regs.realedx:=(ord(s[1]) and (not 32))-ord('A');
  1247. regs.realeax:=$0e00;
  1248. sysrealintr($21,regs);
  1249. regs.realeax:=$1900;
  1250. sysrealintr($21,regs);
  1251. if byte(regs.realeax)<>byte(regs.realedx) then
  1252. begin
  1253. Inoutres:=15;
  1254. exit;
  1255. end;
  1256. { DosDir($3b,'c:') give Path not found error on
  1257. pure DOS PM }
  1258. if length(s)=2 then
  1259. exit;
  1260. end;
  1261. { do the normal dos chdir }
  1262. DosDir($3b,s);
  1263. end;
  1264. procedure getdir(drivenr : byte;var dir : shortstring);
  1265. var
  1266. temp : array[0..255] of char;
  1267. i : longint;
  1268. regs : trealregs;
  1269. begin
  1270. regs.realedx:=drivenr;
  1271. regs.realesi:=tb_offset;
  1272. regs.realds:=tb_segment;
  1273. if LFNSupport then
  1274. regs.realeax:=$7147
  1275. else
  1276. regs.realeax:=$4700;
  1277. sysrealintr($21,regs);
  1278. if (regs.realflags and carryflag) <> 0 then
  1279. Begin
  1280. GetInOutRes(lo(regs.realeax));
  1281. Dir := char (DriveNr + 64) + ':\';
  1282. exit;
  1283. end
  1284. else
  1285. syscopyfromdos(longint(@temp),251);
  1286. { conversion to Pascal string including slash conversion }
  1287. i:=0;
  1288. while (temp[i]<>#0) do
  1289. begin
  1290. if temp[i]='/' then
  1291. temp[i]:='\';
  1292. dir[i+4]:=temp[i];
  1293. inc(i);
  1294. end;
  1295. dir[2]:=':';
  1296. dir[3]:='\';
  1297. dir[0]:=char(i+3);
  1298. { upcase the string }
  1299. if not FileNameCaseSensitive then
  1300. dir:=upcase(dir);
  1301. if drivenr<>0 then { Drive was supplied. We know it }
  1302. dir[1]:=char(65+drivenr-1)
  1303. else
  1304. begin
  1305. { We need to get the current drive from DOS function 19H }
  1306. { because the drive was the default, which can be unknown }
  1307. regs.realeax:=$1900;
  1308. sysrealintr($21,regs);
  1309. i:= (regs.realeax and $ff) + ord('A');
  1310. dir[1]:=chr(i);
  1311. end;
  1312. end;
  1313. {*****************************************************************************
  1314. SystemUnit Initialization
  1315. *****************************************************************************}
  1316. function CheckLFN:boolean;
  1317. var
  1318. regs : TRealRegs;
  1319. RootName : pchar;
  1320. begin
  1321. { Check LFN API on drive c:\ }
  1322. RootName:='C:\';
  1323. syscopytodos(longint(RootName),strlen(RootName)+1);
  1324. { Call 'Get Volume Information' ($71A0) }
  1325. regs.realeax:=$71a0;
  1326. regs.reales:=tb_segment;
  1327. regs.realedi:=tb_offset;
  1328. regs.realecx:=32;
  1329. regs.realds:=tb_segment;
  1330. regs.realedx:=tb_offset;
  1331. regs.realflags:=carryflag;
  1332. sysrealintr($21,regs);
  1333. { If carryflag=0 and LFN API bit in ebx is set then use Long file names }
  1334. CheckLFN:=(regs.realflags and carryflag=0) and (regs.realebx and $4000=$4000);
  1335. end;
  1336. {$ifdef EXCEPTIONS_IN_SYSTEM}
  1337. {$define IN_SYSTEM}
  1338. {$i dpmiexcp.pp}
  1339. {$endif EXCEPTIONS_IN_SYSTEM}
  1340. procedure SysInitStdIO;
  1341. begin
  1342. OpenStdIO(Input,fmInput,StdInputHandle);
  1343. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1344. OpenStdIO(ErrOutput,fmOutput,StdErrorHandle);
  1345. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  1346. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1347. end;
  1348. function GetProcessID: SizeUInt;
  1349. begin
  1350. GetProcessID := 1;
  1351. end;
  1352. var
  1353. temp_int : tseginfo;
  1354. Begin
  1355. alloc_tb;
  1356. StackLength := InitialStkLen;
  1357. StackBottom := __stkbottom;
  1358. { To be set if this is a GUI or console application }
  1359. IsConsole := TRUE;
  1360. { To be set if this is a library and not a program }
  1361. IsLibrary := FALSE;
  1362. { save old int 0 and 75 }
  1363. get_pm_interrupt($00,old_int00);
  1364. get_pm_interrupt($75,old_int75);
  1365. temp_int.segment:=get_cs;
  1366. temp_int.offset:=@new_int00;
  1367. set_pm_interrupt($00,temp_int);
  1368. {$ifndef EXCEPTIONS_IN_SYSTEM}
  1369. temp_int.offset:=@new_int75;
  1370. set_pm_interrupt($75,temp_int);
  1371. {$endif EXCEPTIONS_IN_SYSTEM}
  1372. { Setup heap }
  1373. InitHeap;
  1374. SysInitExceptions;
  1375. { Setup stdin, stdout and stderr }
  1376. SysInitStdIO;
  1377. { Setup environment and arguments }
  1378. Setup_Environment;
  1379. Setup_Arguments;
  1380. { Use LFNSupport LFN }
  1381. LFNSupport:=CheckLFN;
  1382. if LFNSupport then
  1383. FileNameCaseSensitive:=true;
  1384. { Reset IO Error }
  1385. InOutRes:=0;
  1386. ThreadID := 1;
  1387. {$ifdef EXCEPTIONS_IN_SYSTEM}
  1388. InitDPMIExcp;
  1389. InstallDefaultHandlers;
  1390. {$endif EXCEPTIONS_IN_SYSTEM}
  1391. {$ifdef HASVARIANT}
  1392. initvariantmanager;
  1393. {$endif HASVARIANT}
  1394. {$ifdef HASWIDESTRING}
  1395. initwidestringmanager;
  1396. {$endif HASWIDESTRING}
  1397. End.
  1398. {
  1399. $Log$
  1400. Revision 1.24 2005-05-12 20:29:04 michael
  1401. + Added maxpathlen constant (maximum length of filename path)
  1402. Revision 1.23 2005/05/10 21:45:08 hajny
  1403. * fix for potential SIGSEGV during argv allocation
  1404. Revision 1.22 2005/04/13 20:10:50 florian
  1405. + TThreadID
  1406. Revision 1.21 2005/04/03 21:10:59 hajny
  1407. * EOF_CTRLZ conditional define replaced with CtrlZMarksEOF, #26 handling made more consistent (fix for bug 2453)
  1408. Revision 1.20 2005/02/14 17:13:32 peter
  1409. * truncate log
  1410. Revision 1.19 2005/02/01 20:22:50 florian
  1411. * improved widestring infrastructure manager
  1412. }