system.pp 14 KB

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