system.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  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: {$ifdef FPCNAMES}'FPC_'+{$endif}'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. HandleError(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 getheapstart:pointer;assembler;
  155. asm
  156. leal HEAP,%eax
  157. end ['EAX'];
  158. function getheapsize:longint;assembler;
  159. asm
  160. movl HEAPSIZE,%eax
  161. end ['EAX'];
  162. function Sbrk(size : longint) : longint;assembler;
  163. asm
  164. movl size,%ebx
  165. movl $0x4a01,%eax
  166. int $0x21
  167. end;
  168. { include standard heap management }
  169. {$I heap.inc}
  170. {****************************************************************************
  171. Low Level File Routines
  172. ****************************************************************************}
  173. procedure AllowSlash(p:pchar);
  174. var
  175. i : longint;
  176. begin
  177. { allow slash as backslash }
  178. for i:=0 to strlen(p) do
  179. if p[i]='/' then p[i]:='\';
  180. end;
  181. procedure do_close(h : longint);assembler;
  182. asm
  183. movl h,%ebx
  184. movb $0x3e,%ah
  185. pushl %ebp
  186. intl $0x21
  187. popl %ebp
  188. end;
  189. procedure do_erase(p : pchar);
  190. begin
  191. AllowSlash(p);
  192. asm
  193. movl p,%edx
  194. movb $0x41,%ah
  195. pushl %ebp
  196. int $0x21
  197. popl %ebp
  198. jnc .LERASE1
  199. movw %ax,inoutres
  200. .LERASE1:
  201. end;
  202. end;
  203. procedure do_rename(p1,p2 : pchar);
  204. begin
  205. AllowSlash(p1);
  206. AllowSlash(p2);
  207. asm
  208. movl p1,%edx
  209. movl p2,%edi
  210. movb $0x56,%ah
  211. pushl %ebp
  212. int $0x21
  213. popl %ebp
  214. jnc .LRENAME1
  215. movw %ax,inoutres
  216. .LRENAME1:
  217. end;
  218. end;
  219. function do_write(h,addr,len : longint) : longint;assembler;
  220. asm
  221. movl len,%ecx
  222. movl addr,%edx
  223. movl h,%ebx
  224. movb $0x40,%ah
  225. int $0x21
  226. jnc .LDOSWRITE1
  227. movw %ax,inoutres
  228. xorl %eax,%eax
  229. .LDOSWRITE1:
  230. end;
  231. function do_read(h,addr,len : longint) : longint;assembler;
  232. asm
  233. movl len,%ecx
  234. movl addr,%edx
  235. movl h,%ebx
  236. movb $0x3f,%ah
  237. int $0x21
  238. jnc .LDOSREAD1
  239. movw %ax,inoutres
  240. xorl %eax,%eax
  241. .LDOSREAD1:
  242. end;
  243. function do_filepos(handle : longint) : longint;assembler;
  244. asm
  245. movl $0x4201,%eax
  246. movl handle,%ebx
  247. xorl %ecx,%ecx
  248. xorl %edx,%edx
  249. pushl %ebp
  250. int $0x21
  251. popl %ebp
  252. jnc .LDOSFILEPOS1
  253. movw %ax,inoutres
  254. xorl %eax,%eax
  255. jmp .LDOSFILEPOS2
  256. .LDOSFILEPOS1:
  257. shll $16,%edx
  258. movzwl %ax,%eax
  259. orl %edx,%eax
  260. .LDOSFILEPOS2:
  261. end;
  262. procedure do_seek(handle,pos : longint);assembler;
  263. asm
  264. movl $0x4200,%eax
  265. movl handle,%ebx
  266. movl pos,%edx
  267. movl %edx,%ecx
  268. shrl $16,%ecx
  269. pushl %ebp
  270. int $0x21
  271. popl %ebp
  272. jnc .LDOSSEEK1
  273. movw %ax,inoutres
  274. .LDOSSEEK1:
  275. end;
  276. function do_seekend(handle : longint) : longint;assembler;
  277. asm
  278. movl $0x4202,%eax
  279. movl handle,%ebx
  280. xorl %ecx,%ecx
  281. xorl %edx,%edx
  282. pushl %ebp
  283. int $0x21
  284. popl %ebp
  285. jnc .Lset_at_end1
  286. movw %ax,inoutres
  287. xorl %eax,%eax
  288. jmp .Lset_at_end2
  289. .Lset_at_end1:
  290. shll $16,%edx
  291. movzwl %ax,%eax
  292. orl %edx,%eax
  293. .Lset_at_end2:
  294. end;
  295. function do_filesize(handle : longint) : longint;
  296. var
  297. aktfilepos : longint;
  298. begin
  299. aktfilepos:=do_filepos(handle);
  300. do_filesize:=do_seekend(handle);
  301. do_seek(handle,aktfilepos);
  302. end;
  303. procedure do_truncate(handle,pos : longint);assembler;
  304. asm
  305. movl $0x4200,%eax
  306. movl handle,%ebx
  307. movl pos,%edx
  308. movl %edx,%ecx
  309. shrl $16,%ecx
  310. pushl %ebp
  311. int $0x21
  312. popl %ebp
  313. jc .LTruncate1
  314. movl handle,%ebx
  315. movl %ebp,%edx
  316. xorl %ecx,%ecx
  317. movb $0x40,%ah
  318. int $0x21
  319. jnc .LTruncate2
  320. .LTruncate1:
  321. movw %ax,inoutres
  322. .LTruncate2:
  323. end;
  324. procedure do_open(var f;p:pchar;flags:longint);
  325. {
  326. filerec and textrec have both handle and mode as the first items so
  327. they could use the same routine for opening/creating.
  328. when (flags and $10) the file will be append
  329. when (flags and $100) the file will be truncate/rewritten
  330. when (flags and $1000) there is no check for close (needed for textfiles)
  331. }
  332. var
  333. oflags : longint;
  334. begin
  335. AllowSlash(p);
  336. { close first if opened }
  337. if ((flags and $1000)=0) then
  338. begin
  339. case filerec(f).mode of
  340. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  341. fmclosed : ;
  342. else
  343. begin
  344. inoutres:=102; {not assigned}
  345. exit;
  346. end;
  347. end;
  348. end;
  349. { reset file handle }
  350. filerec(f).handle:=UnusedHandle;
  351. oflags:=$8404;
  352. { convert filemode to filerec modes }
  353. case (flags and 3) of
  354. 0 : begin
  355. filerec(f).mode:=fminput;
  356. oflags:=$8001;
  357. end;
  358. 1 : filerec(f).mode:=fmoutput;
  359. 2 : filerec(f).mode:=fminout;
  360. end;
  361. if (flags and $100)<>0 then
  362. begin
  363. filerec(f).mode:=fmoutput;
  364. oflags:=$8302;
  365. end
  366. else
  367. if (flags and $10)<>0 then
  368. begin
  369. filerec(f).mode:=fmoutput;
  370. oflags:=$8404;
  371. end;
  372. { empty name is special }
  373. if p[0]=#0 then
  374. begin
  375. case filerec(f).mode of
  376. fminput : filerec(f).handle:=StdInputHandle;
  377. fmappend,
  378. fmoutput : begin
  379. filerec(f).handle:=StdOutputHandle;
  380. filerec(f).mode:=fmoutput; {fool fmappend}
  381. end;
  382. end;
  383. exit;
  384. end;
  385. asm
  386. movl $0xff02,%eax
  387. movl oflags,%ecx
  388. movl p,%ebx
  389. int $0x21
  390. jnc .LOPEN1
  391. movw %ax,inoutres
  392. movw $0xffff,%ax
  393. .LOPEN1:
  394. movl f,%edx
  395. movw %ax,(%edx)
  396. end;
  397. if (flags and $10)<>0 then
  398. do_seekend(filerec(f).handle);
  399. end;
  400. function do_isdevice(handle : longint):boolean;assembler;
  401. asm
  402. movl $0x4400,%eax
  403. movl handle,%ebx
  404. pushl %ebp
  405. int $0x21
  406. popl %ebp
  407. jnc .LDOSDEVICE
  408. movw %ax,inoutres
  409. xorl %edx,%edx
  410. .LDOSDEVICE:
  411. movl %edx,%eax
  412. shrl $7,%eax
  413. andl $1,%eax
  414. end;
  415. {*****************************************************************************
  416. UnTyped File Handling
  417. *****************************************************************************}
  418. {$i file.inc}
  419. {*****************************************************************************
  420. Typed File Handling
  421. *****************************************************************************}
  422. {$i typefile.inc}
  423. {*****************************************************************************
  424. Text File Handling
  425. *****************************************************************************}
  426. {$DEFINE EOF_CTRLZ}
  427. {$i text.inc}
  428. {*****************************************************************************
  429. Directory Handling
  430. *****************************************************************************}
  431. procedure DosDir(func:byte;const s:string);
  432. var
  433. buffer : array[0..255] of char;
  434. begin
  435. move(s[1],buffer,length(s));
  436. buffer[length(s)]:=#0;
  437. AllowSlash(pchar(@buffer));
  438. asm
  439. leal buffer,%edx
  440. movb func,%ah
  441. int $0x21
  442. jnc .LDOS_DIRS1
  443. movw %ax,inoutres
  444. .LDOS_DIRS1:
  445. end;
  446. end;
  447. procedure mkdir(const s : string);[IOCheck];
  448. begin
  449. If InOutRes <> 0 then exit;
  450. DosDir($39,s);
  451. end;
  452. procedure rmdir(const s : string);[IOCheck];
  453. begin
  454. If InOutRes <> 0 then exit;
  455. DosDir($3a,s);
  456. end;
  457. procedure chdir(const s : string);[IOCheck];
  458. begin
  459. If InOutRes <> 0 then exit;
  460. DosDir($3b,s);
  461. end;
  462. procedure getdir(drivenr : byte;var dir : string);
  463. var
  464. temp : array[0..255] of char;
  465. sof : pchar;
  466. i : byte;
  467. begin
  468. sof:=pchar(@dir[4]);
  469. { dir[1..3] will contain '[drivenr]:\', but is not supplied by DOS,
  470. so we let dos string start at dir[4]
  471. Get dir from drivenr : 0=default, 1=A etc }
  472. asm
  473. movb drivenr,%dl
  474. movl sof,%esi
  475. mov $0x47,%ah
  476. int $0x21
  477. end;
  478. { Now Dir should be filled with directory in ASCIIZ starting from dir[4] }
  479. dir[0]:=#3;
  480. dir[2]:=':';
  481. dir[3]:='\';
  482. i:=4;
  483. { conversation to Pascal string }
  484. while (dir[i]<>#0) do
  485. begin
  486. { convert path name to DOS }
  487. if dir[i]='/' then
  488. dir[i]:='\';
  489. dir[0]:=chr(i);
  490. inc(i);
  491. end;
  492. { upcase the string }
  493. dir:=upcase(dir);
  494. if drivenr<>0 then { Drive was supplied. We know it }
  495. dir[1]:=chr(65+drivenr-1)
  496. else
  497. begin
  498. { We need to get the current drive from DOS function 19H }
  499. { because the drive was the default, which can be unknown }
  500. asm
  501. movb $0x19,%ah
  502. int $0x21
  503. addb $65,%al
  504. movb %al,i
  505. end;
  506. dir[1]:=chr(i);
  507. end;
  508. end;
  509. {*****************************************************************************
  510. SystemUnit Initialization
  511. *****************************************************************************}
  512. Begin
  513. { to test stack depth }
  514. loweststack:=maxlongint;
  515. { Setup heap }
  516. InitHeap;
  517. { Setup stdin, stdout and stderr }
  518. OpenStdIO(Input,fmInput,StdInputHandle);
  519. OpenStdIO(Output,fmOutput,StdOutputHandle);
  520. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  521. { Reset IO Error }
  522. InOutRes:=0;
  523. End.
  524. {
  525. $Log$
  526. Revision 1.9 1998-09-14 10:48:03 peter
  527. * FPC_ names
  528. * Heap manager is now system independent
  529. Revision 1.8 1998/07/30 13:28:33 michael
  530. + Added support for errorproc. Changed runerror to HandleError
  531. Revision 1.7 1998/07/07 12:30:20 carl
  532. * 2k buffer for stack shecking to permimt correct io
  533. Revision 1.6 1998/07/02 12:26:55 carl
  534. * do_open was WRONG! Fixed!
  535. * do_isdevice small fix with ATT parser
  536. * I386_ATT put back , otherwise would NOT link!
  537. * IoCheck for rmdir,chdir,mkdir
  538. Revision 1.5 1998/07/01 15:29:56 peter
  539. * better readln/writeln
  540. Revision 1.4 1998/05/31 14:18:19 peter
  541. * force att or direct assembling
  542. * cleanup of some files
  543. Revision 1.3 1998/05/22 00:39:33 peter
  544. * go32v1, go32v2 recompiles with the new objects
  545. * remake3 works again with go32v2
  546. - removed some "optimizes" from daniel which were wrong
  547. }