system.pp 27 KB

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