system.pp 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team.
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { no stack check in system }
  12. {$S-}
  13. unit system;
  14. {$I os.inc}
  15. interface
  16. { include system-independent routine headers }
  17. {$I systemh.inc}
  18. { include heap support headers }
  19. {$I heaph.inc}
  20. const
  21. { Default filehandles }
  22. UnusedHandle = $ffff;
  23. StdInputHandle = 0;
  24. StdOutputHandle = 1;
  25. StdErrorHandle = 2;
  26. { Default memory segments (Tp7 compatibility) }
  27. seg0040 = $0040;
  28. segA000 = $A000;
  29. segB000 = $B000;
  30. segB800 = $B800;
  31. var
  32. { Mem[] support }
  33. mem : array[0..$7fffffff] of byte absolute $0;
  34. memw : array[0..$7fffffff] of word absolute $0;
  35. meml : array[0..$7fffffff] of longint absolute $0;
  36. { C-compatible arguments and environment }
  37. argc : longint;
  38. argv : ppchar;
  39. envp : ppchar;
  40. dos_argv0 : pchar;
  41. {$ifndef RTLLITE}
  42. { System info }
  43. Win95 : boolean;
  44. {$endif RTLLITE}
  45. type
  46. { Dos Extender info }
  47. p_stub_info = ^t_stub_info;
  48. t_stub_info = packed record
  49. magic : array[0..15] of char;
  50. size : longint;
  51. minstack : longint;
  52. memory_handle : longint;
  53. initial_size : longint;
  54. minkeep : word;
  55. ds_selector : word;
  56. ds_segment : word;
  57. psp_selector : word;
  58. cs_selector : word;
  59. env_size : word;
  60. basename : array[0..7] of char;
  61. argv0 : array [0..15] of char;
  62. dpmi_server : array [0..15] of char;
  63. end;
  64. p_go32_info_block = ^t_go32_info_block;
  65. t_go32_info_block = packed record
  66. size_of_this_structure_in_bytes : longint; {offset 0}
  67. linear_address_of_primary_screen : longint; {offset 4}
  68. linear_address_of_secondary_screen : longint; {offset 8}
  69. linear_address_of_transfer_buffer : longint; {offset 12}
  70. size_of_transfer_buffer : longint; {offset 16}
  71. pid : longint; {offset 20}
  72. master_interrupt_controller_base : byte; {offset 24}
  73. slave_interrupt_controller_base : byte; {offset 25}
  74. selector_for_linear_memory : word; {offset 26}
  75. linear_address_of_stub_info_structure : longint; {offset 28}
  76. linear_address_of_original_psp : longint; {offset 32}
  77. run_mode : word; {offset 36}
  78. run_mode_info : word; {offset 38}
  79. end;
  80. var
  81. stub_info : p_stub_info;
  82. go32_info_block : t_go32_info_block;
  83. {
  84. necessary for objects.pas, should be removed (at least from the interface
  85. to the implementation)
  86. }
  87. type
  88. trealregs=record
  89. realedi,realesi,realebp,realres,
  90. realebx,realedx,realecx,realeax : longint;
  91. realflags,
  92. reales,realds,realfs,realgs,
  93. realip,realcs,realsp,realss : word;
  94. end;
  95. function do_write(h,addr,len : longint) : longint;
  96. function do_read(h,addr,len : longint) : longint;
  97. procedure syscopyfromdos(addr : longint; len : longint);
  98. procedure syscopytodos(addr : longint; len : longint);
  99. procedure sysrealintr(intnr : word;var regs : trealregs);
  100. function tb : longint;
  101. implementation
  102. { include system independent routines }
  103. {$I system.inc}
  104. const
  105. carryflag = 1;
  106. type
  107. plongint = ^longint;
  108. var
  109. doscmd : string[128]; { Dos commandline copied from PSP, max is 128 chars }
  110. {$ASMMODE DIRECT}
  111. procedure halt(errnum : byte);
  112. begin
  113. do_exit;
  114. flush(stderr);
  115. asm
  116. movzbw errnum,%ax
  117. pushw %ax
  118. call ___exit {frees all dpmi memory !!}
  119. end;
  120. end;
  121. procedure int_stackcheck(stack_size:longint);[public,alias: 'STACKCHECK'];
  122. {
  123. called when trying to get local stack if the compiler directive $S
  124. is set this function must preserve esi !!!! because esi is set by
  125. the calling proc for methods it must preserve all registers !!
  126. }
  127. begin
  128. asm
  129. pushl %eax
  130. pushl %ebx
  131. movl stack_size,%ebx
  132. movl %esp,%eax
  133. subl %ebx,%eax
  134. {$ifdef SYSTEMDEBUG}
  135. movl U_SYSTEM_LOWESTSTACK,%ebx
  136. cmpl %eax,%ebx
  137. jb _is_not_lowest
  138. movl %eax,U_SYSTEM_LOWESTSTACK
  139. _is_not_lowest:
  140. {$endif SYSTEMDEBUG}
  141. movl __stkbottom,%ebx
  142. cmpl %eax,%ebx
  143. jae __short_on_stack
  144. popl %ebx
  145. popl %eax
  146. leave
  147. ret $4
  148. __short_on_stack:
  149. { can be usefull for error recovery !! }
  150. popl %ebx
  151. popl %eax
  152. end['EAX','EBX'];
  153. RunError(202);
  154. end;
  155. function far_strlen(selector : word;linear_address : longint) : longint;
  156. begin
  157. asm
  158. movl linear_address,%edx
  159. movl %edx,%ecx
  160. movw selector,%gs
  161. .Larg19:
  162. movb %gs:(%edx),%al
  163. testb %al,%al
  164. je .Larg20
  165. incl %edx
  166. jmp .Larg19
  167. .Larg20:
  168. movl %edx,%eax
  169. subl %ecx,%eax
  170. movl %eax,__RESULT
  171. end;
  172. end;
  173. {$ASMMODE ATT}
  174. function tb : longint;
  175. begin
  176. tb:=go32_info_block.linear_address_of_transfer_buffer;
  177. end;
  178. function tb_size : longint;
  179. begin
  180. tb_size:=go32_info_block.size_of_transfer_buffer;
  181. end;
  182. function dos_selector : word;
  183. begin
  184. dos_selector:=go32_info_block.selector_for_linear_memory;
  185. end;
  186. function get_ds : word;assembler;
  187. asm
  188. movw %ds,%ax
  189. end;
  190. procedure sysseg_move(sseg : word;source : longint;dseg : word;dest : longint;count : longint);
  191. begin
  192. if count=0 then
  193. exit;
  194. if (sseg<>dseg) or ((sseg=dseg) and (source>dest)) then
  195. asm
  196. pushw %es
  197. pushw %ds
  198. cld
  199. movl count,%ecx
  200. movl source,%esi
  201. movl dest,%edi
  202. movw dseg,%ax
  203. movw %ax,%es
  204. movw sseg,%ax
  205. movw %ax,%ds
  206. movl %ecx,%eax
  207. shrl $2,%ecx
  208. rep
  209. movsl
  210. movl %eax,%ecx
  211. andl $3,%ecx
  212. rep
  213. movsb
  214. popw %ds
  215. popw %es
  216. end ['ESI','EDI','ECX','EAX']
  217. else if (source<dest) then
  218. { copy backward for overlapping }
  219. asm
  220. pushw %es
  221. pushw %ds
  222. std
  223. movl count,%ecx
  224. movl source,%esi
  225. movl dest,%edi
  226. movw dseg,%ax
  227. movw %ax,%es
  228. movw sseg,%ax
  229. movw %ax,%ds
  230. addl %ecx,%esi
  231. addl %ecx,%edi
  232. movl %ecx,%eax
  233. andl $3,%ecx
  234. orl %ecx,%ecx
  235. jz .LSEG_MOVE1
  236. { calculate esi and edi}
  237. decl %esi
  238. decl %edi
  239. rep
  240. movsb
  241. incl %esi
  242. incl %edi
  243. .LSEG_MOVE1:
  244. subl $4,%esi
  245. subl $4,%edi
  246. movl %eax,%ecx
  247. shrl $2,%ecx
  248. rep
  249. movsl
  250. cld
  251. popw %ds
  252. popw %es
  253. end ['ESI','EDI','ECX'];
  254. end;
  255. function atohex(s : pchar) : longint;
  256. var rv : longint;
  257. v : byte;
  258. begin
  259. rv := 0;
  260. while (s^ <>#0) do
  261. begin
  262. v := byte(s^) - byte('0');
  263. if (v > 9) then v := v - 7;
  264. v := v and 15; { in case it's lower case }
  265. rv := rv*16 + v;
  266. inc(longint(s));
  267. end;
  268. atohex := rv;
  269. end;
  270. procedure setup_arguments;
  271. type arrayword = array [0..0] of word;
  272. var psp : word;
  273. i,j : byte;
  274. quote : char;
  275. proxy_s : string[7];
  276. tempargv : ppchar;
  277. al,proxy_argc,proxy_seg,proxy_ofs,lin : longint;
  278. largs : array[0..127] of pchar;
  279. rm_argv : ^arrayword;
  280. begin
  281. for i := 1 to 127 do
  282. largs[i] := nil;
  283. psp:=stub_info^.psp_selector;
  284. largs[0]:=dos_argv0;
  285. argc := 1;
  286. sysseg_move(psp, 128, get_ds, longint(@doscmd), 128);
  287. {$IfDef SYSTEMDEBUG}
  288. Writeln('Dos command line is #',doscmd,'# size = ',length(doscmd));
  289. {$EndIf SYSTEMDEBUG}
  290. j := 1;
  291. quote := #0;
  292. for i:=1 to length(doscmd) do
  293. Begin
  294. if doscmd[i] = quote then
  295. begin
  296. quote := #0;
  297. doscmd[i] := #0;
  298. largs[argc]:=@doscmd[j];
  299. inc(argc);
  300. j := i+1;
  301. end else
  302. if (quote = #0) and ((doscmd[i] = '''') or (doscmd[i]='"')) then
  303. begin
  304. quote := doscmd[i];
  305. j := i + 1;
  306. end else
  307. if (quote = #0) and ((doscmd[i] = ' ')
  308. or (doscmd[i] = #9) or (doscmd[i] = #10) or
  309. (doscmd[i] = #12) or (doscmd[i] = #9)) then
  310. begin
  311. doscmd[i]:=#0;
  312. if j<i then
  313. begin
  314. largs[argc]:=@doscmd[j];
  315. inc(argc);
  316. j := i+1;
  317. end else inc(j);
  318. end else
  319. if (i = length(doscmd)) then
  320. begin
  321. doscmd[i+1]:=#0;
  322. largs[argc]:=@doscmd[j];
  323. inc(argc);
  324. end;
  325. end;
  326. if (argc > 1) and (far_strlen(get_ds,longint(largs[1])) = 6) then
  327. begin
  328. move(largs[1]^,proxy_s[1],6);
  329. proxy_s[0] := #6;
  330. if (proxy_s = '!proxy') then
  331. begin
  332. {$IfDef SYSTEMDEBUG}
  333. Writeln('proxy command line ');
  334. {$EndIf SYSTEMDEBUG}
  335. proxy_argc := atohex(largs[2]);
  336. proxy_seg := atohex(largs[3]);
  337. proxy_ofs := atohex(largs[4]);
  338. getmem(rm_argv,proxy_argc*sizeof(word));
  339. sysseg_move(dos_selector,proxy_seg*16+proxy_ofs, get_ds,longint(rm_argv),proxy_argc*sizeof(word));
  340. for i:=0 to proxy_argc - 1 do
  341. begin
  342. lin := proxy_seg*16 + rm_argv^[i];
  343. al :=far_strlen(dos_selector, lin);
  344. getmem(largs[i],al+1);
  345. sysseg_move(dos_selector, lin, get_ds,longint(largs[i]), al+1);
  346. {$IfDef SYSTEMDEBUG}
  347. Writeln('arg ',i,' #',largs[i],'#');
  348. {$EndIf SYSTEMDEBUG}
  349. end;
  350. argc := proxy_argc;
  351. end;
  352. end;
  353. getmem(argv,argc shl 2);
  354. for i := 0 to argc-1 do
  355. argv[i] := largs[i];
  356. tempargv:=argv;
  357. {$ASMMODE DIRECT}
  358. asm
  359. movl tempargv,%eax
  360. movl %eax,_args
  361. end;
  362. {$ASMMODE ATT}
  363. end;
  364. function strcopy(dest,source : pchar) : pchar;
  365. begin
  366. asm
  367. cld
  368. movl 12(%ebp),%edi
  369. movl $0xffffffff,%ecx
  370. xorb %al,%al
  371. repne
  372. scasb
  373. not %ecx
  374. movl 8(%ebp),%edi
  375. movl 12(%ebp),%esi
  376. movl %ecx,%eax
  377. shrl $2,%ecx
  378. rep
  379. movsl
  380. movl %eax,%ecx
  381. andl $3,%ecx
  382. rep
  383. movsb
  384. movl 8(%ebp),%eax
  385. leave
  386. ret $8
  387. end;
  388. end;
  389. procedure setup_environment;
  390. var env_selector : word;
  391. env_count : longint;
  392. dos_env,cp : pchar;
  393. stubaddr : p_stub_info;
  394. begin
  395. {$ASMMODE DIRECT}
  396. asm
  397. movl __stubinfo,%eax
  398. movl %eax,stubaddr
  399. end;
  400. {$ASMMODE ATT}
  401. stub_info:=stubaddr;
  402. getmem(dos_env,stub_info^.env_size);
  403. env_count:=0;
  404. sysseg_move(stub_info^.psp_selector,$2c, get_ds, longint(@env_selector), 2);
  405. sysseg_move(env_selector, 0, get_ds, longint(dos_env), stub_info^.env_size);
  406. cp:=dos_env;
  407. while cp ^ <> #0 do
  408. begin
  409. inc(env_count);
  410. while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
  411. inc(longint(cp)); { skip to next character }
  412. end;
  413. getmem(envp,(env_count+1) * sizeof(pchar));
  414. if (envp = nil) then exit;
  415. cp:=dos_env;
  416. env_count:=0;
  417. while cp^ <> #0 do
  418. begin
  419. getmem(envp[env_count],strlen(cp)+1);
  420. strcopy(envp[env_count], cp);
  421. {$IfDef SYSTEMDEBUG}
  422. Writeln('env ',env_count,' = "',envp[env_count],'"');
  423. {$EndIf SYSTEMDEBUG}
  424. inc(env_count);
  425. while (cp^ <> #0) do inc(longint(cp)); { skip to NUL }
  426. inc(longint(cp)); { skip to next character }
  427. end;
  428. envp[env_count]:=nil;
  429. longint(cp):=longint(cp)+3;
  430. getmem(dos_argv0,strlen(cp)+1);
  431. if (dos_argv0 = nil) then halt;
  432. strcopy(dos_argv0, cp);
  433. end;
  434. procedure syscopytodos(addr : longint; len : longint);
  435. begin
  436. if len > tb_size then runerror(217);
  437. sysseg_move(get_ds,addr,dos_selector,tb,len);
  438. end;
  439. procedure syscopyfromdos(addr : longint; len : longint);
  440. begin
  441. if len > tb_size then runerror(217);
  442. sysseg_move(dos_selector,tb,get_ds,addr,len);
  443. end;
  444. procedure sysrealintr(intnr : word;var regs : trealregs);
  445. begin
  446. regs.realsp:=0;
  447. regs.realss:=0;
  448. asm
  449. movw intnr,%bx
  450. xorl %ecx,%ecx
  451. movl regs,%edi
  452. movw $0x300,%ax
  453. int $0x31
  454. end;
  455. end;
  456. function paramcount : longint;
  457. begin
  458. paramcount := argc - 1;
  459. end;
  460. function paramstr(l : longint) : string;
  461. begin
  462. if (l>=0) and (l+1<=argc) then
  463. paramstr:=strpas(argv[l])
  464. else
  465. paramstr:='';
  466. end;
  467. procedure randomize;
  468. var
  469. hl : longint;
  470. regs : trealregs;
  471. begin
  472. regs.realeax:=$2c00;
  473. sysrealintr($21,regs);
  474. hl:=regs.realedx and $ffff;
  475. randseed:=hl*$10000+ (regs.realecx and $ffff);
  476. end;
  477. {*****************************************************************************
  478. Heap Management
  479. *****************************************************************************}
  480. {$ASMMODE DIRECT}
  481. function Sbrk(size : longint):longint;assembler;
  482. asm
  483. movl size,%eax
  484. pushl %eax
  485. call ___sbrk
  486. addl $4,%esp
  487. end;
  488. {$ASMMODE ATT}
  489. { include standard heap management }
  490. {$I heap.inc}
  491. {****************************************************************************
  492. Low level File Routines
  493. ****************************************************************************}
  494. procedure AllowSlash(p:pchar);
  495. var
  496. i : longint;
  497. begin
  498. { allow slash as backslash }
  499. for i:=0 to strlen(p) do
  500. if p[i]='/' then p[i]:='\';
  501. end;
  502. {$ifdef SYSTEMDEBUG}
  503. { Keep Track of open files }
  504. const
  505. max_files = 50;
  506. var
  507. opennames : array [0..max_files-1] of pchar;
  508. openfiles : array [0..max_files-1] of boolean;
  509. {$endif SYSTEMDEBUG}
  510. procedure do_close(handle : longint);
  511. var
  512. regs : trealregs;
  513. begin
  514. regs.realebx:=handle;
  515. {$ifdef SYSTEMDEBUG}
  516. if handle<max_files then
  517. openfiles[handle]:=false;
  518. {$endif SYSTEMDEBUG}
  519. regs.realeax:=$3e00;
  520. sysrealintr($21,regs);
  521. end;
  522. procedure do_erase(p : pchar);
  523. var
  524. regs : trealregs;
  525. begin
  526. AllowSlash(p);
  527. syscopytodos(longint(p),strlen(p)+1);
  528. regs.realedx:=tb and 15;
  529. regs.realds:=tb shr 4;
  530. {$ifndef RTLLITE}
  531. if Win95 then
  532. regs.realeax:=$7141
  533. else
  534. {$endif RTLLITE}
  535. regs.realeax:=$4100;
  536. regs.realesi:=0;
  537. regs.realecx:=0;
  538. sysrealintr($21,regs);
  539. if (regs.realflags and carryflag) <> 0 then
  540. InOutRes:=lo(regs.realeax);
  541. end;
  542. procedure do_rename(p1,p2 : pchar);
  543. var
  544. regs : trealregs;
  545. begin
  546. AllowSlash(p1);
  547. AllowSlash(p2);
  548. if strlen(p1)+strlen(p2)+3>tb_size then
  549. RunError(217);
  550. sysseg_move(get_ds,longint(p2),dos_selector,tb,strlen(p2)+1);
  551. sysseg_move(get_ds,longint(p1),dos_selector,tb+strlen(p2)+2,strlen(p1)+1);
  552. regs.realedi:=tb and 15;
  553. regs.realedx:=tb and 15 + strlen(p2)+2;
  554. regs.realds:=tb shr 4;
  555. regs.reales:=regs.realds;
  556. {$ifndef RTLLITE}
  557. if Win95 then
  558. regs.realeax:=$7156
  559. else
  560. {$endif RTLLITE}
  561. regs.realeax:=$5600;
  562. regs.realecx:=$ff; { attribute problem here ! }
  563. sysrealintr($21,regs);
  564. if (regs.realflags and carryflag) <> 0 then
  565. InOutRes:=lo(regs.realeax);
  566. end;
  567. function do_write(h,addr,len : longint) : longint;
  568. var
  569. regs : trealregs;
  570. size,
  571. writesize : longint;
  572. begin
  573. writesize:=0;
  574. while len > 0 do
  575. begin
  576. if len>tb_size then
  577. size:=tb_size
  578. else
  579. size:=len;
  580. syscopytodos(addr+writesize,size);
  581. regs.realecx:=size;
  582. regs.realedx:=tb and 15;
  583. regs.realds:=tb shr 4;
  584. regs.realebx:=h;
  585. regs.realeax:=$4000;
  586. sysrealintr($21,regs);
  587. if (regs.realflags and carryflag) <> 0 then
  588. begin
  589. InOutRes:=lo(regs.realeax);
  590. exit(writesize);
  591. end;
  592. len:=len-size;
  593. writesize:=writesize+size;
  594. end;
  595. Do_Write:=WriteSize
  596. end;
  597. function do_read(h,addr,len : longint) : longint;
  598. var
  599. regs : trealregs;
  600. size,
  601. readsize : longint;
  602. begin
  603. readsize:=0;
  604. while len > 0 do
  605. begin
  606. if len>tb_size then
  607. size:=tb_size
  608. else
  609. size:=len;
  610. regs.realecx:=size;
  611. regs.realedx:=tb and 15;
  612. regs.realds:=tb shr 4;
  613. regs.realebx:=h;
  614. regs.realeax:=$3f00;
  615. sysrealintr($21,regs);
  616. if (regs.realflags and carryflag) <> 0 then
  617. begin
  618. InOutRes:=lo(regs.realeax);
  619. do_read:=0;
  620. exit;
  621. end
  622. else
  623. if regs.realeax<size then
  624. begin
  625. syscopyfromdos(addr+readsize,regs.realeax);
  626. do_read:=readsize+regs.realeax;
  627. exit;
  628. end;
  629. syscopyfromdos(addr+readsize,regs.realeax);
  630. readsize:=readsize+regs.realeax;
  631. len:=len-regs.realeax;
  632. end;
  633. do_read:=readsize;
  634. end;
  635. function do_filepos(handle : longint) : longint;
  636. var
  637. regs : trealregs;
  638. begin
  639. regs.realebx:=handle;
  640. regs.realecx:=0;
  641. regs.realedx:=0;
  642. regs.realeax:=$4201;
  643. sysrealintr($21,regs);
  644. if (regs.realflags and carryflag) <> 0 then
  645. Begin
  646. InOutRes:=lo(regs.realeax);
  647. do_filepos:=0;
  648. end
  649. else
  650. do_filepos:=lo(regs.realedx) shl 16+lo(regs.realeax);
  651. end;
  652. procedure do_seek(handle,pos : longint);
  653. var
  654. regs : trealregs;
  655. begin
  656. regs.realebx:=handle;
  657. regs.realecx:=pos shr 16;
  658. regs.realedx:=pos and $ffff;
  659. regs.realeax:=$4200;
  660. sysrealintr($21,regs);
  661. if (regs.realflags and carryflag) <> 0 then
  662. InOutRes:=lo(regs.realeax);
  663. end;
  664. function do_seekend(handle:longint):longint;
  665. var
  666. regs : trealregs;
  667. begin
  668. regs.realebx:=handle;
  669. regs.realecx:=0;
  670. regs.realedx:=0;
  671. regs.realeax:=$4202;
  672. sysrealintr($21,regs);
  673. if (regs.realflags and carryflag) <> 0 then
  674. Begin
  675. InOutRes:=lo(regs.realeax);
  676. do_seekend:=0;
  677. end
  678. else
  679. do_seekend:=lo(regs.realedx) shl 16+lo(regs.realeax);
  680. end;
  681. function do_filesize(handle : longint) : longint;
  682. var
  683. aktfilepos : longint;
  684. begin
  685. aktfilepos:=do_filepos(handle);
  686. do_filesize:=do_seekend(handle);
  687. do_seek(handle,aktfilepos);
  688. end;
  689. { truncate at a given position }
  690. procedure do_truncate (handle,pos:longint);
  691. var
  692. regs : trealregs;
  693. begin
  694. do_seek(handle,pos);
  695. regs.realecx:=0;
  696. regs.realedx:=tb and 15;
  697. regs.realds:=tb shr 4;
  698. regs.realebx:=handle;
  699. regs.realeax:=$4000;
  700. sysrealintr($21,regs);
  701. if (regs.realflags and carryflag) <> 0 then
  702. InOutRes:=lo(regs.realeax);
  703. end;
  704. procedure do_open(var f;p:pchar;flags:longint);
  705. {
  706. filerec and textrec have both handle and mode as the first items so
  707. they could use the same routine for opening/creating.
  708. when (flags and $10) the file will be append
  709. when (flags and $100) the file will be truncate/rewritten
  710. when (flags and $1000) there is no check for close (needed for textfiles)
  711. }
  712. var
  713. regs : trealregs;
  714. action : longint;
  715. begin
  716. AllowSlash(p);
  717. { close first if opened }
  718. if ((flags and $1000)=0) then
  719. begin
  720. case filerec(f).mode of
  721. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  722. fmclosed : ;
  723. else
  724. begin
  725. inoutres:=102; {not assigned}
  726. exit;
  727. end;
  728. end;
  729. end;
  730. { reset file handle }
  731. filerec(f).handle:=UnusedHandle;
  732. action:=$1;
  733. { convert filemode to filerec modes }
  734. case (flags and 3) of
  735. 0 : filerec(f).mode:=fminput;
  736. 1 : filerec(f).mode:=fmoutput;
  737. 2 : filerec(f).mode:=fminout;
  738. end;
  739. if (flags and $100)<>0 then
  740. begin
  741. filerec(f).mode:=fmoutput;
  742. action:=$12; {create file function}
  743. end;
  744. { empty name is special }
  745. if p[0]=#0 then
  746. begin
  747. case filerec(f).mode of
  748. fminput : filerec(f).handle:=StdInputHandle;
  749. fmappend,
  750. fmoutput : begin
  751. filerec(f).handle:=StdOutputHandle;
  752. filerec(f).mode:=fmoutput; {fool fmappend}
  753. end;
  754. end;
  755. exit;
  756. end;
  757. { real dos call }
  758. syscopytodos(longint(p),strlen(p)+1);
  759. {$ifndef RTLLITE}
  760. if Win95 then
  761. regs.realeax:=$716c
  762. else
  763. {$endif RTLLITE}
  764. regs.realeax:=$6c00;
  765. regs.realedx:=action;
  766. regs.realds:=tb shr 4;
  767. regs.realesi:=tb and 15;
  768. regs.realebx:=$2000+(flags and $ff);
  769. regs.realecx:=$20;
  770. sysrealintr($21,regs);
  771. if (regs.realflags and carryflag) <> 0 then
  772. begin
  773. InOutRes:=lo(regs.realeax);
  774. exit;
  775. end
  776. else
  777. filerec(f).handle:=regs.realeax;
  778. {$ifdef SYSTEMDEBUG}
  779. if regs.realeax<max_files then
  780. begin
  781. openfiles[regs.realeax]:=true;
  782. getmem(opennames[regs.realeax],strlen(p)+1);
  783. opennames[regs.realeax]:=p;
  784. end;
  785. {$endif SYSTEMDEBUG}
  786. { append mode }
  787. if (flags and $10)<>0 then
  788. begin
  789. do_seekend(filerec(f).handle);
  790. filerec(f).mode:=fmoutput; {fool fmappend}
  791. end;
  792. end;
  793. function do_isdevice(handle:longint):boolean;
  794. var
  795. regs : trealregs;
  796. begin
  797. regs.realebx:=handle;
  798. regs.realeax:=$4400;
  799. sysrealintr($21,regs);
  800. do_isdevice:=(regs.realedx and $80)<>0;
  801. if (regs.realflags and carryflag) <> 0 then
  802. InOutRes:=lo(regs.realeax);
  803. end;
  804. {*****************************************************************************
  805. UnTyped File Handling
  806. *****************************************************************************}
  807. {$i file.inc}
  808. {*****************************************************************************
  809. Typed File Handling
  810. *****************************************************************************}
  811. {$i typefile.inc}
  812. {*****************************************************************************
  813. Text File Handling
  814. *****************************************************************************}
  815. {$DEFINE EOF_CTRLZ}
  816. {$i text.inc}
  817. {*****************************************************************************
  818. Directory Handling
  819. *****************************************************************************}
  820. procedure DosDir(func:byte;const s:string);
  821. var
  822. buffer : array[0..255] of char;
  823. regs : trealregs;
  824. begin
  825. move(s[1],buffer,length(s));
  826. buffer[length(s)]:=#0;
  827. AllowSlash(pchar(@buffer));
  828. syscopytodos(longint(@buffer),length(s)+1);
  829. regs.realedx:=tb and 15;
  830. regs.realds:=tb shr 4;
  831. {$ifndef RTLLITE}
  832. if Win95 then
  833. regs.realeax:=$7100+func
  834. else
  835. {$endif RTLLITE}
  836. regs.realeax:=func shl 8;
  837. sysrealintr($21,regs);
  838. if (regs.realflags and carryflag) <> 0 then
  839. InOutRes:=lo(regs.realeax);
  840. end;
  841. procedure mkdir(const s : string);[IOCheck];
  842. begin
  843. If InOutRes <> 0 then exit;
  844. DosDir($39,s);
  845. end;
  846. procedure rmdir(const s : string);[IOCheck];
  847. begin
  848. If InOutRes <> 0 then exit;
  849. DosDir($3a,s);
  850. end;
  851. procedure chdir(const s : string);[IOCheck];
  852. begin
  853. If InOutRes <> 0 then exit;
  854. DosDir($3b,s);
  855. end;
  856. procedure getdir(drivenr : byte;var dir : string);
  857. var
  858. temp : array[0..255] of char;
  859. i : longint;
  860. regs : trealregs;
  861. begin
  862. regs.realedx:=drivenr;
  863. regs.realesi:=tb and 15;
  864. regs.realds:=tb shr 4;
  865. {$ifndef RTLLITE}
  866. if Win95 then
  867. regs.realeax:=$7147
  868. else
  869. {$endif RTLLITE}
  870. regs.realeax:=$4700;
  871. sysrealintr($21,regs);
  872. if (regs.realflags and carryflag) <> 0 then
  873. Begin
  874. InOutRes:=lo(regs.realeax);
  875. exit;
  876. end
  877. else
  878. syscopyfromdos(longint(@temp),251);
  879. { conversation to Pascal string including slash conversion }
  880. i:=0;
  881. while (temp[i]<>#0) do
  882. begin
  883. if temp[i]='/' then
  884. temp[i]:='\';
  885. dir[i+4]:=temp[i];
  886. inc(i);
  887. end;
  888. dir[2]:=':';
  889. dir[3]:='\';
  890. dir[0]:=char(i+3);
  891. { upcase the string }
  892. dir:=upcase(dir);
  893. if drivenr<>0 then { Drive was supplied. We know it }
  894. dir[1]:=char(65+drivenr-1)
  895. else
  896. begin
  897. { We need to get the current drive from DOS function 19H }
  898. { because the drive was the default, which can be unknown }
  899. regs.realeax:=$1900;
  900. sysrealintr($21,regs);
  901. i:= (regs.realeax and $ff) + ord('A');
  902. dir[1]:=chr(i);
  903. end;
  904. end;
  905. {*****************************************************************************
  906. SystemUnit Initialization
  907. *****************************************************************************}
  908. {$ifndef RTLLITE}
  909. function CheckWin95:boolean;
  910. var
  911. regs : TRealRegs;
  912. begin
  913. regs.realeax:=$160a;
  914. sysrealintr($2f,regs);
  915. CheckWin95:=(regs.realeax=0) and ((regs.realebx and $ff00)=$400);
  916. end;
  917. {$endif RTLLITE}
  918. Begin
  919. { to test stack depth }
  920. loweststack:=maxlongint;
  921. { Setup heap }
  922. InitHeap;
  923. { Setup stdin, stdout and stderr }
  924. OpenStdIO(Input,fmInput,StdInputHandle);
  925. OpenStdIO(Output,fmOutput,StdOutputHandle);
  926. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  927. { Setup environment and arguments }
  928. Setup_Environment;
  929. Setup_Arguments;
  930. { Use Win95 LFN }
  931. Win95:=CheckWin95;
  932. { Reset IO Error }
  933. InOutRes:=0;
  934. End.
  935. {
  936. $Log$
  937. Revision 1.10 1998-07-02 12:29:20 carl
  938. * IOCheck for rmdir,chdir and mkdir as in TP
  939. NOTE: I'm pretty SURE this will not compile and link correctly with FPC
  940. 0.99.5
  941. Revision 1.9 1998/07/01 15:29:57 peter
  942. * better readln/writeln
  943. Revision 1.8 1998/06/26 08:19:10 pierre
  944. + all debug in ifdef SYSTEMDEBUG
  945. + added local arrays :
  946. opennames names of opened files
  947. fileopen boolean array to know if still open
  948. usefull with gdb if you get problems about too
  949. many open files !!
  950. Revision 1.7 1998/06/15 15:17:08 daniel
  951. * RTLLITE conditional added to produce smaller RTL.
  952. Revision 1.6 1998/05/31 14:18:29 peter
  953. * force att or direct assembling
  954. * cleanup of some files
  955. Revision 1.5 1998/05/21 19:30:52 peter
  956. * objects compiles for linux
  957. + assign(pchar), assign(char), rename(pchar), rename(char)
  958. * fixed read_text_as_array
  959. + read_text_as_pchar which was not yet in the rtl
  960. Revision 1.4 1998/05/04 17:58:41 peter
  961. * fix for smartlinking with _ARGS
  962. Revision 1.3 1998/05/04 16:21:54 florian
  963. + win95 flag to the interface moved
  964. }