system.pp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  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. { system unit for go32v1 }
  13. {$define DOS}
  14. unit system;
  15. {$I os.inc}
  16. interface
  17. { die betriebssystemunabhangigen Deklarationen einfuegen: }
  18. {$I systemh.inc}
  19. {$I heaph.inc}
  20. const
  21. UnusedHandle=$ffff;
  22. StdInputHandle=0;
  23. StdOutputHandle=1;
  24. StdErrorHandle=2;
  25. type
  26. {$PACKRECORDS 1}
  27. t_stub_info = record
  28. magic : array[0..15] of char;
  29. size : longint;
  30. minstack : longint;
  31. memory_handle : longint;
  32. initial_size : longint;
  33. minkeep : word;
  34. ds_selector : word;
  35. ds_segment : word;
  36. psp_selector : word;
  37. cs_selector : word;
  38. env_size : word;
  39. basename : array[0..7] of char;
  40. argv0 : array [0..15] of char;
  41. dpmi_server : array [0..15] of char;
  42. end;
  43. p_stub_info = ^t_stub_info;
  44. t_go32_info_block = record
  45. size_of_this_structure_in_bytes : longint; {offset 0}
  46. linear_address_of_primary_screen : longint; {offset 4}
  47. linear_address_of_secondary_screen : longint; {offset 8}
  48. linear_address_of_transfer_buffer : longint; {offset 12}
  49. size_of_transfer_buffer : longint; {offset 16}
  50. pid : longint; {offset 20}
  51. master_interrupt_controller_base : byte; {offset 24}
  52. slave_interrupt_controller_base : byte; {offset 25}
  53. selector_for_linear_memory : word; {offset 26}
  54. linear_address_of_stub_info_structure : longint; {offset 28}
  55. linear_address_of_original_psp : longint; {offset 32}
  56. run_mode : word; {offset 36}
  57. run_mode_info : word; {offset 38}
  58. end;
  59. {$PACKRECORDS NORMAL}
  60. var
  61. stub_info : p_stub_info;
  62. go32_info_block : t_go32_info_block;
  63. implementation
  64. { include system independent routines }
  65. {$I system.inc}
  66. { type
  67. plongint = ^longint;}
  68. {$S-}
  69. procedure st1(stack_size : longint);[public,alias: 'STACKCHECK'];
  70. begin
  71. { called when trying to get local stack }
  72. { if the compiler directive $S is set }
  73. { this function must preserve esi !!!! }
  74. { because esi is set by the calling }
  75. { proc for methods }
  76. { it must preserve all registers !! }
  77. asm
  78. pushl %eax
  79. pushl %ebx
  80. movl stack_size,%ebx
  81. movl %esp,%eax
  82. subl %ebx,%eax
  83. {$ifdef SYSTEMDEBUG}
  84. movl U_SYSTEM_LOWESTSTACK,%ebx
  85. cmpl %eax,%ebx
  86. jb _is_not_lowest
  87. movl %eax,U_SYSTEM_LOWESTSTACK
  88. _is_not_lowest:
  89. {$endif SYSTEMDEBUG}
  90. movl __stkbottom,%ebx
  91. cmpl %eax,%ebx
  92. jae __short_on_stack
  93. popl %ebx
  94. popl %eax
  95. leave
  96. ret $4
  97. __short_on_stack:
  98. { can be usefull for error recovery !! }
  99. popl %ebx
  100. popl %eax
  101. end['EAX','EBX'];
  102. RunError(202);
  103. { this needs a local variable }
  104. { so the function called itself !! }
  105. { Writeln('low in stack ');
  106. RunError(202); }
  107. end;
  108. procedure halt(errnum : byte);
  109. begin
  110. do_exit;
  111. flush(stderr);
  112. asm
  113. movl $0x4c00,%eax
  114. movb 8(%ebp),%al
  115. int $0x21
  116. end;
  117. end;
  118. function paramcount : longint;
  119. begin
  120. asm
  121. movl _argc,%eax
  122. decl %eax
  123. leave
  124. ret
  125. end ['EAX'];
  126. end;
  127. function paramstr(l : longint) : string;
  128. function args : pointer;
  129. begin
  130. asm
  131. movl _args,%eax
  132. leave
  133. ret
  134. end ['EAX'];
  135. end;
  136. var
  137. p : ^pchar;
  138. begin
  139. if (l>=0) and (l<=paramcount) then
  140. begin
  141. p:=args;
  142. paramstr:=strpas(p[l]);
  143. end
  144. else paramstr:='';
  145. end;
  146. procedure randomize;
  147. var
  148. hl : longint;
  149. begin
  150. asm
  151. movb $0x2c,%ah
  152. int $0x21
  153. movw %cx,-4(%ebp)
  154. movw %dx,-2(%ebp)
  155. end;
  156. randseed:=hl;
  157. end;
  158. { use standard heap management }
  159. { sbrk function of go32v1 }
  160. function Sbrk(size : longint) : longint;
  161. begin
  162. asm
  163. movl size,%ebx
  164. movl $0x4a01,%eax
  165. int $0x21
  166. movl %eax,__RESULT
  167. end;
  168. end;
  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);
  182. begin
  183. asm
  184. movl 8(%ebp),%ebx
  185. movb $0x3e,%ah
  186. pushl %ebp
  187. intl $0x21
  188. popl %ebp
  189. end;
  190. end;
  191. procedure do_erase(p : pchar);
  192. begin
  193. AllowSlash(p);
  194. asm
  195. movl 8(%ebp),%edx
  196. movb $0x41,%ah
  197. pushl %ebp
  198. int $0x21
  199. popl %ebp
  200. jnc .LERASE1
  201. movw %ax,U_SYSTEM_INOUTRES;
  202. .LERASE1:
  203. end;
  204. end;
  205. procedure do_rename(p1,p2 : pchar);
  206. begin
  207. AllowSlash(p1);
  208. AllowSlash(p2);
  209. asm
  210. movl 8(%ebp),%edx
  211. movl 12(%ebp),%edi
  212. movb $0x56,%ah
  213. pushl %ebp
  214. int $0x21
  215. popl %ebp
  216. jnc .LRENAME1
  217. movw %ax,U_SYSTEM_INOUTRES;
  218. .LRENAME1:
  219. end;
  220. end;
  221. function do_write(h,addr,len : longint) : longint;
  222. begin
  223. asm
  224. movl 16(%ebp),%ecx
  225. movl 12(%ebp),%edx
  226. movl 8(%ebp),%ebx
  227. movb $0x40,%ah
  228. int $0x21
  229. jnc .LDOSWRITE1
  230. movw %ax,U_SYSTEM_INOUTRES;
  231. .LDOSWRITE1:
  232. movl %eax,-4(%ebp)
  233. end;
  234. end;
  235. function do_read(h,addr,len : longint) : longint;
  236. begin
  237. asm
  238. movl 16(%ebp),%ecx
  239. movl 12(%ebp),%edx
  240. movl 8(%ebp),%ebx
  241. movb $0x3f,%ah
  242. int $0x21
  243. jnc .LDOSREAD1
  244. movw %ax,U_SYSTEM_INOUTRES;
  245. xorl %eax,%eax
  246. .LDOSREAD1:
  247. leave
  248. ret $12
  249. end;
  250. end;
  251. function do_filepos(handle : longint) : longint;
  252. begin
  253. asm
  254. movb $0x42,%ah
  255. movb $0x1,%al
  256. movl 8(%ebp),%ebx
  257. xorl %ecx,%ecx
  258. xorl %edx,%edx
  259. pushl %ebp
  260. int $0x21
  261. popl %ebp
  262. jnc .LDOSFILEPOS1
  263. movw %ax,U_SYSTEM_INOUTRES;
  264. xorl %eax,%eax
  265. jmp .LDOSFILEPOS2
  266. .LDOSFILEPOS1:
  267. shll $16,%edx
  268. movzwl %ax,%eax
  269. orl %edx,%eax
  270. .LDOSFILEPOS2:
  271. leave
  272. ret $4
  273. end;
  274. end;
  275. procedure do_seek(handle,pos : longint);
  276. begin
  277. asm
  278. movl $0x4200,%eax
  279. movl 8(%ebp),%ebx
  280. movl 12(%ebp),%edx
  281. movl %edx,%ecx
  282. shrl $16,%ecx
  283. pushl %ebp
  284. int $0x21
  285. popl %ebp
  286. jnc .LDOSSEEK1
  287. movw %ax,U_SYSTEM_INOUTRES;
  288. .LDOSSEEK1:
  289. leave
  290. ret $8
  291. end;
  292. end;
  293. function do_seekend(handle : longint) : longint;
  294. begin
  295. asm
  296. movl $0x4202,%eax
  297. movl 8(%ebp),%ebx
  298. xorl %ecx,%ecx
  299. xorl %edx,%edx
  300. pushl %ebp
  301. int $0x21
  302. popl %ebp
  303. jnc .Lset_at_end1
  304. movw %ax,U_SYSTEM_INOUTRES;
  305. xorl %eax,%eax
  306. jmp .Lset_at_end2
  307. .Lset_at_end1:
  308. shll $16,%edx
  309. movzwl %ax,%eax
  310. orl %edx,%eax
  311. .Lset_at_end2:
  312. leave
  313. ret $4
  314. end;
  315. end;
  316. function do_filesize(handle : longint) : longint;
  317. var
  318. aktfilepos : longint;
  319. begin
  320. aktfilepos:=do_filepos(handle);
  321. do_filesize:=do_seekend(handle);
  322. do_seek(handle,aktfilepos);
  323. end;
  324. procedure do_truncate(handle,pos : longint);
  325. begin
  326. asm
  327. movl $0x4200,%eax
  328. movl 8(%ebp),%ebx
  329. movl 12(%ebp),%edx
  330. movl %edx,%ecx
  331. shrl $16,%ecx
  332. pushl %ebp
  333. int $0x21
  334. popl %ebp
  335. jc .LTruncate1
  336. movl 8(%ebp),%ebx
  337. movl 12(%ebp),%edx
  338. movl %ebp,%edx
  339. xorl %ecx,%ecx
  340. movb $0x40,%ah
  341. int $0x21
  342. jnc .LTruncate2
  343. .LTruncate1:
  344. movw %ax,U_SYSTEM_INOUTRES;
  345. .LTruncate2:
  346. leave
  347. ret $8
  348. end;
  349. end;
  350. procedure do_open(var f;p:pchar;flags:longint);
  351. {
  352. filerec and textrec have both handle and mode as the first items so
  353. they could use the same routine for opening/creating.
  354. when (flags and $10) the file will be append
  355. when (flags and $100) the file will be truncate/rewritten
  356. when (flags and $1000) there is no check for close (needed for textfiles)
  357. }
  358. var
  359. oflags : longint;
  360. begin
  361. AllowSlash(p);
  362. { close first if opened }
  363. if ((flags and $1000)=0) then
  364. begin
  365. case filerec(f).mode of
  366. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  367. fmclosed : ;
  368. else
  369. begin
  370. inoutres:=102; {not assigned}
  371. exit;
  372. end;
  373. end;
  374. end;
  375. { reset file handle }
  376. filerec(f).handle:=UnusedHandle;
  377. oflags:=$8404;
  378. { convert filemode to filerec modes }
  379. case (flags and 3) of
  380. 0 : begin
  381. filerec(f).mode:=fminput;
  382. oflags:=$8001;
  383. end;
  384. 1 : filerec(f).mode:=fmoutput;
  385. 2 : filerec(f).mode:=fminout;
  386. end;
  387. if (flags and $100)<>0 then
  388. begin
  389. filerec(f).mode:=fmoutput;
  390. oflags:=$8302;
  391. end
  392. else
  393. if (flags and $10)<>0 then
  394. begin
  395. filerec(f).mode:=fmoutput;
  396. oflags:=$8404;
  397. end;
  398. { empty name is special }
  399. if p[0]=#0 then
  400. begin
  401. case filerec(f).mode of
  402. fminput : filerec(f).handle:=StdInputHandle;
  403. fmappend,
  404. fmoutput : begin
  405. filerec(f).handle:=StdOutputHandle;
  406. filerec(f).mode:=fmoutput; {fool fmappend}
  407. end;
  408. end;
  409. exit;
  410. end;
  411. asm
  412. movl $0xff02,%ax
  413. movl -4(%ebp),%ecx
  414. movl 12(%ebp),%ebx
  415. int $0x21
  416. jnc .LOPEN1
  417. movw %ax,U_SYSTEM_INOUTRES;
  418. movw $0xffff,%ax
  419. .LOPEN1:
  420. movl 8(%ebp),%edx
  421. movw %ax,(%edx)
  422. end;
  423. if (flags and $10)<>0 then
  424. do_seekend(filerec(f).handle);
  425. end;
  426. {*****************************************************************************
  427. UnTyped File Handling
  428. *****************************************************************************}
  429. {$i file.inc}
  430. {*****************************************************************************
  431. Typed File Handling
  432. *****************************************************************************}
  433. {$i typefile.inc}
  434. {*****************************************************************************
  435. Text File Handling
  436. *****************************************************************************}
  437. {$DEFINE EOF_CTRLZ}
  438. {$i text.inc}
  439. {*****************************************************************************
  440. Directory Handling
  441. *****************************************************************************}
  442. procedure DosDir(func:byte;const s:string);
  443. var
  444. buffer : array[0..255] of char;
  445. begin
  446. move(s[1],buffer,length(s));
  447. buffer[length(s)]:=#0;
  448. AllowSlash(pchar(@buffer));
  449. asm
  450. leal buffer,%edx
  451. movb 8(%ebp),%ah
  452. int $0x21
  453. jnc .LDOS_DIRS1
  454. movw %ax,U_SYSTEM_INOUTRES;
  455. .LDOS_DIRS1:
  456. end;
  457. end;
  458. procedure mkdir(const s : string);
  459. begin
  460. DosDir($39,s);
  461. end;
  462. procedure rmdir(const s : string);
  463. begin
  464. DosDir($3a,s);
  465. end;
  466. procedure chdir(const s : string);
  467. begin
  468. DosDir($3b,s);
  469. end;
  470. { thanks to Michael Van Canneyt <[email protected]>, }
  471. { who writes this code }
  472. { her is a problem if the getdir is called with a pathstr var in dos.pp }
  473. procedure getdir(drivenr : byte;var dir : string);
  474. var
  475. temp : array[0..255] of char;
  476. sof : pchar;
  477. i : byte;
  478. begin
  479. sof:=pchar(@dir[4]);
  480. { dir[1..3] will contain '[drivenr]:\', but is not }
  481. { supplied by DOS, so we let dos string start at }
  482. { dir[4] }
  483. { Get dir from drivenr : 0=default, 1=A etc... }
  484. asm
  485. movb drivenr,%dl
  486. movl sof,%esi
  487. mov $0x47,%ah
  488. int $0x21
  489. end;
  490. { Now Dir should be filled with directory in ASCIIZ, }
  491. { starting from dir[4] }
  492. dir[0]:=#3;
  493. dir[2]:=':';
  494. dir[3]:='\';
  495. i:=4;
  496. { conversation to Pascal string }
  497. while (dir[i]<>#0) do
  498. begin
  499. { convert path name to DOS }
  500. if dir[i]='/' then
  501. dir[i]:='\';
  502. dir[0]:=chr(i);
  503. inc(i);
  504. end;
  505. { upcase the string (FPKPascal function) }
  506. dir:=upcase(dir);
  507. if drivenr<>0 then { Drive was supplied. We know it }
  508. dir[1]:=chr(65+drivenr-1)
  509. else
  510. begin
  511. { We need to get the current drive from DOS function 19H }
  512. { because the drive was the default, which can be unknown }
  513. asm
  514. movb $0x19,%ah
  515. int $0x21
  516. addb $65,%al
  517. movb %al,i
  518. end;
  519. dir[1]:=chr(i);
  520. end;
  521. end;
  522. {*****************************************************************************
  523. SystemUnit Initialization
  524. *****************************************************************************}
  525. procedure OpenStdIO(var f:text;mode:word;hdl:longint);
  526. begin
  527. Assign(f,'');
  528. TextRec(f).Handle:=hdl;
  529. TextRec(f).Mode:=mode;
  530. TextRec(f).InOutFunc:=@FileInOutFunc;
  531. TextRec(f).FlushFunc:=@FileInOutFunc;
  532. TextRec(f).Closefunc:=@fileclosefunc;
  533. end;
  534. Begin
  535. { Initialize ExitProc }
  536. ExitProc:=Nil;
  537. { to test stack depth }
  538. loweststack:=maxlongint;
  539. { Setup heap }
  540. InitHeap;
  541. { Setup stdin, stdout and stderr }
  542. OpenStdIO(Input,fmInput,StdInputHandle);
  543. OpenStdIO(Output,fmOutput,StdOutputHandle);
  544. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  545. { Reset IO Error }
  546. InOutRes:=0;
  547. End.
  548. {
  549. $Log$
  550. Revision 1.1.1.1 1998-03-25 11:18:41 root
  551. * Restored version
  552. Revision 1.9 1998/02/14 01:41:35 peter
  553. * fixed unusedhandle bug which was -1
  554. Revision 1.8 1998/01/26 11:57:03 michael
  555. + Added log at the end
  556. Working file: rtl/dos/go32v1/system.pp
  557. description:
  558. ----------------------------
  559. revision 1.7
  560. date: 1998/01/25 21:53:22; author: peter; state: Exp; lines: +12 -8
  561. + Universal Handles support for StdIn/StdOut/StdErr
  562. * Updated layout of sysamiga.pas
  563. ----------------------------
  564. revision 1.6
  565. date: 1998/01/16 23:10:50; author: florian; state: Exp; lines: +2 -2
  566. + some tobject stuff
  567. ----------------------------
  568. revision 1.5
  569. date: 1998/01/11 02:47:31; author: michael; state: Exp; lines: +384 -507
  570. * Changed files to use the new filestructure in /inc directory.
  571. (By Peter Vreman)
  572. ----------------------------
  573. revision 1.4
  574. date: 1998/01/07 00:05:04; author: michael; state: Exp; lines: +189 -184
  575. + Final adjustments for a uniform file handling interface.
  576. (From Peter Vreman)
  577. ----------------------------
  578. revision 1.3
  579. date: 1998/01/05 16:51:04; author: michael; state: Exp; lines: +18 -46
  580. + Moved init of heap to heap.inc: INITheap() (From Peter Vreman)
  581. ----------------------------
  582. revision 1.2
  583. date: 1997/12/01 12:24:06; author: michael; state: Exp; lines: +12 -3
  584. + added copyright reference in header.
  585. ----------------------------
  586. revision 1.1
  587. date: 1997/11/27 08:33:53; author: michael; state: Exp;
  588. Initial revision
  589. ----------------------------
  590. revision 1.1.1.1
  591. date: 1997/11/27 08:33:53; author: michael; state: Exp; lines: +0 -0
  592. FPC RTL CVS start
  593. =============================================================================
  594. }