system.pp 38 KB

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