system.pp 13 KB

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