system.pp 14 KB

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