system.pp 26 KB

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