system.pp 14 KB

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