system.pp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Florian Klaempfl,
  5. member of the Free Pascal development team.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. unit system;
  13. interface
  14. { include system-independent routine headers }
  15. {$I systemh.inc}
  16. { include heap support headers }
  17. {$I heaph.inc}
  18. const
  19. { Default filehandles }
  20. UnusedHandle = $ffff;
  21. StdInputHandle = 0;
  22. StdOutputHandle = 1;
  23. StdErrorHandle = 2;
  24. { Default memory segments (Tp7 compatibility) }
  25. seg0040 = $0040;
  26. segA000 = $A000;
  27. segB000 = $B000;
  28. segB800 = $B800;
  29. var
  30. { C-compatible arguments and environment }
  31. argc : longint;
  32. argv : ppchar;
  33. envp : ppchar;
  34. type
  35. { Dos Extender info }
  36. p_stub_info = ^t_stub_info;
  37. t_stub_info = packed record
  38. magic : array[0..15] of char;
  39. size : longint;
  40. minstack : longint;
  41. memory_handle : longint;
  42. initial_size : longint;
  43. minkeep : word;
  44. ds_selector : word;
  45. ds_segment : word;
  46. psp_selector : word;
  47. cs_selector : word;
  48. env_size : word;
  49. basename : array[0..7] of char;
  50. argv0 : array [0..15] of char;
  51. dpmi_server : array [0..15] of char;
  52. end;
  53. t_go32_info_block = packed record
  54. size_of_this_structure_in_bytes : longint; {offset 0}
  55. linear_address_of_primary_screen : longint; {offset 4}
  56. linear_address_of_secondary_screen : longint; {offset 8}
  57. linear_address_of_transfer_buffer : longint; {offset 12}
  58. size_of_transfer_buffer : longint; {offset 16}
  59. pid : longint; {offset 20}
  60. master_interrupt_controller_base : byte; {offset 24}
  61. slave_interrupt_controller_base : byte; {offset 25}
  62. selector_for_linear_memory : word; {offset 26}
  63. linear_address_of_stub_info_structure : longint; {offset 28}
  64. linear_address_of_original_psp : longint; {offset 32}
  65. run_mode : word; {offset 36}
  66. run_mode_info : word; {offset 38}
  67. end;
  68. var
  69. stub_info : p_stub_info;
  70. go32_info_block : t_go32_info_block;
  71. LFNSupport : boolean;
  72. { Needed for CRT unit }
  73. function do_read(h,addr,len : longint) : longint;
  74. implementation
  75. { include system independent routines }
  76. {$I system.inc}
  77. {$ASMMODE DIRECT}
  78. procedure int_stackcheck(stack_size:longint);[public,alias:'FPC_STACKCHECK'];
  79. begin
  80. { called when trying to get local stack
  81. if the compiler directive $S is set
  82. this function must preserve esi !!!!
  83. because esi is set by the calling
  84. proc for methods
  85. it must preserve all registers !!
  86. With a 2048 byte safe area used to write to StdIo without crossing
  87. the stack boundary
  88. }
  89. asm
  90. pushl %eax
  91. pushl %ebx
  92. movl stack_size,%ebx
  93. addl $2048,%ebx
  94. movl %esp,%eax
  95. subl %ebx,%eax
  96. {$ifdef SYSTEMDEBUG}
  97. movl U_SYSTEM_LOWESTSTACK,%ebx
  98. cmpl %eax,%ebx
  99. jb _is_not_lowest
  100. movl %eax,U_SYSTEM_LOWESTSTACK
  101. _is_not_lowest:
  102. {$endif SYSTEMDEBUG}
  103. movl __stkbottom,%ebx
  104. cmpl %eax,%ebx
  105. jae __short_on_stack
  106. popl %ebx
  107. popl %eax
  108. leave
  109. ret $4
  110. __short_on_stack:
  111. { can be usefull for error recovery !! }
  112. popl %ebx
  113. popl %eax
  114. end['EAX','EBX'];
  115. HandleError(202);
  116. end;
  117. function paramcount : longint;
  118. begin
  119. paramcount := argc - 1;
  120. end;
  121. function paramstr(l : longint) : string;
  122. begin
  123. if (l>=0) and (l+1<=argc) then
  124. paramstr:=strpas(argv[l])
  125. else
  126. paramstr:='';
  127. end;
  128. procedure randomize;
  129. Begin
  130. asm
  131. movb $0x2c,%ah
  132. int $0x21
  133. shll $16,%ecx
  134. movw %dx,%cx
  135. movl %ecx,randseed
  136. end;
  137. end;
  138. {*****************************************************************************
  139. Heap Management
  140. *****************************************************************************}
  141. function getheapstart:pointer;assembler;
  142. asm
  143. leal HEAP,%eax
  144. end ['EAX'];
  145. function getheapsize:longint;assembler;
  146. asm
  147. movl HEAPSIZE,%eax
  148. end ['EAX'];
  149. function Sbrk(size : longint) : longint;assembler;
  150. asm
  151. movl size,%ebx
  152. movl $0x4a01,%eax
  153. int $0x21
  154. end;
  155. { include standard heap management }
  156. {$I heap.inc}
  157. {****************************************************************************
  158. Low Level File Routines
  159. ****************************************************************************}
  160. procedure AllowSlash(p:pchar);
  161. var
  162. i : longint;
  163. begin
  164. { allow slash as backslash }
  165. for i:=0 to strlen(p) do
  166. if p[i]='/' then p[i]:='\';
  167. end;
  168. procedure do_close(h : longint);assembler;
  169. asm
  170. movl h,%ebx
  171. movb $0x3e,%ah
  172. pushl %ebp
  173. int $0x21
  174. popl %ebp
  175. jnc .LCLOSE1
  176. movw %ax,inoutres
  177. .LCLOSE1:
  178. end;
  179. procedure do_erase(p : pchar);
  180. begin
  181. AllowSlash(p);
  182. asm
  183. movl p,%edx
  184. movb $0x41,%ah
  185. pushl %ebp
  186. int $0x21
  187. popl %ebp
  188. jnc .LERASE1
  189. movw %ax,inoutres
  190. .LERASE1:
  191. end;
  192. end;
  193. procedure do_rename(p1,p2 : pchar);
  194. begin
  195. AllowSlash(p1);
  196. AllowSlash(p2);
  197. asm
  198. movl p1,%edx
  199. movl p2,%edi
  200. movb $0x56,%ah
  201. pushl %ebp
  202. int $0x21
  203. popl %ebp
  204. jnc .LRENAME1
  205. movw %ax,inoutres
  206. .LRENAME1:
  207. end;
  208. end;
  209. function do_write(h,addr,len : longint) : longint;assembler;
  210. asm
  211. movl len,%ecx
  212. movl addr,%edx
  213. movl h,%ebx
  214. movb $0x40,%ah
  215. int $0x21
  216. jnc .LDOSWRITE1
  217. movw %ax,inoutres
  218. xorl %eax,%eax
  219. .LDOSWRITE1:
  220. end;
  221. function do_read(h,addr,len : longint) : longint;assembler;
  222. asm
  223. movl len,%ecx
  224. movl addr,%edx
  225. movl h,%ebx
  226. movb $0x3f,%ah
  227. int $0x21
  228. jnc .LDOSREAD1
  229. movw %ax,inoutres
  230. xorl %eax,%eax
  231. .LDOSREAD1:
  232. end;
  233. function do_filepos(handle : longint) : longint;assembler;
  234. asm
  235. movl $0x4201,%eax
  236. movl handle,%ebx
  237. xorl %ecx,%ecx
  238. xorl %edx,%edx
  239. pushl %ebp
  240. int $0x21
  241. popl %ebp
  242. jnc .LDOSFILEPOS1
  243. movw %ax,inoutres
  244. xorl %eax,%eax
  245. jmp .LDOSFILEPOS2
  246. .LDOSFILEPOS1:
  247. shll $16,%edx
  248. movzwl %ax,%eax
  249. orl %edx,%eax
  250. .LDOSFILEPOS2:
  251. end;
  252. procedure do_seek(handle,pos : longint);assembler;
  253. asm
  254. movl $0x4200,%eax
  255. movl handle,%ebx
  256. movl pos,%edx
  257. movl %edx,%ecx
  258. shrl $16,%ecx
  259. pushl %ebp
  260. int $0x21
  261. popl %ebp
  262. jnc .LDOSSEEK1
  263. movw %ax,inoutres
  264. .LDOSSEEK1:
  265. end;
  266. function do_seekend(handle : longint) : longint;assembler;
  267. asm
  268. movl $0x4202,%eax
  269. movl handle,%ebx
  270. xorl %ecx,%ecx
  271. xorl %edx,%edx
  272. pushl %ebp
  273. int $0x21
  274. popl %ebp
  275. jnc .Lset_at_end1
  276. movw %ax,inoutres
  277. xorl %eax,%eax
  278. jmp .Lset_at_end2
  279. .Lset_at_end1:
  280. shll $16,%edx
  281. movzwl %ax,%eax
  282. orl %edx,%eax
  283. .Lset_at_end2:
  284. end;
  285. function do_filesize(handle : longint) : longint;
  286. var
  287. aktfilepos : longint;
  288. begin
  289. aktfilepos:=do_filepos(handle);
  290. do_filesize:=do_seekend(handle);
  291. do_seek(handle,aktfilepos);
  292. end;
  293. procedure do_truncate(handle,pos : longint);assembler;
  294. asm
  295. movl $0x4200,%eax
  296. movl handle,%ebx
  297. movl pos,%edx
  298. movl %edx,%ecx
  299. shrl $16,%ecx
  300. pushl %ebp
  301. int $0x21
  302. popl %ebp
  303. jc .LTruncate1
  304. movl handle,%ebx
  305. movl %ebp,%edx
  306. xorl %ecx,%ecx
  307. movb $0x40,%ah
  308. int $0x21
  309. jnc .LTruncate2
  310. .LTruncate1:
  311. movw %ax,inoutres
  312. .LTruncate2:
  313. end;
  314. procedure do_open(var f;p:pchar;flags:longint);
  315. {
  316. filerec and textrec have both handle and mode as the first items so
  317. they could use the same routine for opening/creating.
  318. when (flags and $100) the file will be append
  319. when (flags and $1000) the file will be truncate/rewritten
  320. when (flags and $10000) there is no check for close (needed for textfiles)
  321. }
  322. var
  323. oflags : longint;
  324. begin
  325. AllowSlash(p);
  326. { close first if opened }
  327. if ((flags and $10000)=0) then
  328. begin
  329. case filerec(f).mode of
  330. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  331. fmclosed : ;
  332. else
  333. begin
  334. inoutres:=102; {not assigned}
  335. exit;
  336. end;
  337. end;
  338. end;
  339. { reset file handle }
  340. filerec(f).handle:=UnusedHandle;
  341. oflags:=$8404;
  342. { convert filemode to filerec modes }
  343. case (flags and 3) of
  344. 0 : begin
  345. filerec(f).mode:=fminput;
  346. oflags:=$8001;
  347. end;
  348. 1 : filerec(f).mode:=fmoutput;
  349. 2 : filerec(f).mode:=fminout;
  350. end;
  351. if (flags and $1000)<>0 then
  352. begin
  353. filerec(f).mode:=fmoutput;
  354. oflags:=$8302;
  355. end
  356. else
  357. if (flags and $100)<>0 then
  358. begin
  359. filerec(f).mode:=fmoutput;
  360. oflags:=$8404;
  361. end;
  362. { empty name is special }
  363. if p[0]=#0 then
  364. begin
  365. case FileRec(f).mode of
  366. fminput :
  367. FileRec(f).Handle:=StdInputHandle;
  368. fminout, { this is set by rewrite }
  369. fmoutput :
  370. FileRec(f).Handle:=StdOutputHandle;
  371. fmappend :
  372. begin
  373. FileRec(f).Handle:=StdOutputHandle;
  374. FileRec(f).mode:=fmoutput; {fool fmappend}
  375. end;
  376. end;
  377. exit;
  378. end;
  379. asm
  380. movl $0xff02,%eax
  381. movl oflags,%ecx
  382. movl p,%ebx
  383. int $0x21
  384. jnc .LOPEN1
  385. movw %ax,inoutres
  386. movw $0xffff,%ax
  387. .LOPEN1:
  388. movl f,%edx
  389. movw %ax,(%edx)
  390. end;
  391. if (flags and $100)<>0 then
  392. do_seekend(filerec(f).handle);
  393. end;
  394. function do_isdevice(handle : longint):boolean;assembler;
  395. asm
  396. movl $0x4400,%eax
  397. movl handle,%ebx
  398. pushl %ebp
  399. int $0x21
  400. popl %ebp
  401. jnc .LDOSDEVICE
  402. movw %ax,inoutres
  403. xorl %edx,%edx
  404. .LDOSDEVICE:
  405. movl %edx,%eax
  406. shrl $7,%eax
  407. andl $1,%eax
  408. end;
  409. {*****************************************************************************
  410. UnTyped File Handling
  411. *****************************************************************************}
  412. {$i file.inc}
  413. {*****************************************************************************
  414. Typed File Handling
  415. *****************************************************************************}
  416. {$i typefile.inc}
  417. {*****************************************************************************
  418. Text File Handling
  419. *****************************************************************************}
  420. {$DEFINE EOF_CTRLZ}
  421. {$i text.inc}
  422. {*****************************************************************************
  423. Directory Handling
  424. *****************************************************************************}
  425. procedure DosDir(func:byte;const s:string);
  426. var
  427. buffer : array[0..255] of char;
  428. begin
  429. move(s[1],buffer,length(s));
  430. buffer[length(s)]:=#0;
  431. AllowSlash(pchar(@buffer));
  432. asm
  433. leal buffer,%edx
  434. movb func,%ah
  435. int $0x21
  436. jnc .LDOS_DIRS1
  437. movw %ax,inoutres
  438. .LDOS_DIRS1:
  439. end;
  440. end;
  441. procedure mkdir(const s : string);[IOCheck];
  442. begin
  443. If InOutRes <> 0 then exit;
  444. DosDir($39,s);
  445. end;
  446. procedure rmdir(const s : string);[IOCheck];
  447. begin
  448. If InOutRes <> 0 then exit;
  449. DosDir($3a,s);
  450. end;
  451. procedure chdir(const s : string);[IOCheck];
  452. begin
  453. If InOutRes <> 0 then exit;
  454. DosDir($3b,s);
  455. end;
  456. procedure getdir(drivenr : byte;var dir : shortstring);
  457. var
  458. temp : array[0..255] of char;
  459. sof : pchar;
  460. i : byte;
  461. begin
  462. sof:=pchar(@dir[4]);
  463. { dir[1..3] will contain '[drivenr]:\', but is not supplied by DOS,
  464. so we let dos string start at dir[4]
  465. Get dir from drivenr : 0=default, 1=A etc }
  466. asm
  467. movb drivenr,%dl
  468. movl sof,%esi
  469. mov $0x47,%ah
  470. int $0x21
  471. end;
  472. { Now Dir should be filled with directory in ASCIIZ starting from dir[4] }
  473. dir[0]:=#3;
  474. dir[2]:=':';
  475. dir[3]:='\';
  476. i:=4;
  477. { conversation to Pascal string }
  478. while (dir[i]<>#0) do
  479. begin
  480. { convert path name to DOS }
  481. if dir[i]='/' then
  482. dir[i]:='\';
  483. dir[0]:=chr(i);
  484. inc(i);
  485. end;
  486. { upcase the string }
  487. dir:=upcase(dir);
  488. if drivenr<>0 then { Drive was supplied. We know it }
  489. dir[1]:=chr(65+drivenr-1)
  490. else
  491. begin
  492. { We need to get the current drive from DOS function 19H }
  493. { because the drive was the default, which can be unknown }
  494. asm
  495. movb $0x19,%ah
  496. int $0x21
  497. addb $65,%al
  498. movb %al,i
  499. end;
  500. dir[1]:=chr(i);
  501. end;
  502. end;
  503. {*****************************************************************************
  504. System Dependent Exit code
  505. *****************************************************************************}
  506. Procedure system_exit;
  507. var
  508. err : byte;
  509. begin
  510. flush(stderr);
  511. err:=exitcode and $ff;
  512. asm
  513. movl $0x4c00,%eax
  514. movb err,%al
  515. int $0x21
  516. end;
  517. end;
  518. {*****************************************************************************
  519. SystemUnit Initialization
  520. *****************************************************************************}
  521. Begin
  522. { to test stack depth }
  523. loweststack:=maxlongint;
  524. { Setup heap }
  525. InitHeap;
  526. { Setup stdin, stdout and stderr }
  527. OpenStdIO(Input,fmInput,StdInputHandle);
  528. OpenStdIO(Output,fmOutput,StdOutputHandle);
  529. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  530. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  531. { Reset IO Error }
  532. InOutRes:=0;
  533. End.
  534. {
  535. $Log$
  536. Revision 1.2 2000-07-13 11:33:38 michael
  537. + removed logs
  538. }