system.pas 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Carl Eric Codere
  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. {$define ATARI}
  13. unit {$ifdef VER1_0}sysatari{$else}{$ifdef VER0_99}sysatari{$ELSE}system{$endif}{$ENDIF};
  14. {--------------------------------------------------------------------}
  15. { LEFT TO DO: }
  16. {--------------------------------------------------------------------}
  17. { o SBrk }
  18. { o Implement truncate }
  19. { o Implement paramstr(0) }
  20. {--------------------------------------------------------------------}
  21. {$I os.inc}
  22. interface
  23. { used for single computations }
  24. const BIAS4 = $7f-1;
  25. {$I systemh.inc}
  26. {$I heaph.inc}
  27. const
  28. UnusedHandle = $ffff;
  29. StdInputHandle = 0;
  30. StdOutputHandle = 1;
  31. StdErrorHandle = $ffff;
  32. implementation
  33. {$I system.inc}
  34. {$I lowmath.inc}
  35. const
  36. argc : longint = 0;
  37. var
  38. errno : integer;
  39. {$S-}
  40. procedure Stack_Check; assembler;
  41. { Check for local variable allocation }
  42. { On Entry -> d0 : size of local stack we are trying to allocate }
  43. asm
  44. XDEF STACKCHECK
  45. move.l sp,d1 { get value of stack pointer }
  46. sub.l d0,d1 { sp - stack_size }
  47. sub.l #2048,d1
  48. cmp.l __BREAK,d1
  49. bgt @st1nosweat
  50. move.l #202,d0
  51. jsr HALT_ERROR
  52. @st1nosweat:
  53. end;
  54. Procedure Error2InOut;
  55. Begin
  56. if (errno <= -2) and (errno >= -11) then
  57. InOutRes:=150-errno { 150+errno }
  58. else
  59. Begin
  60. case errno of
  61. -32 : InOutRes:=1;
  62. -33 : InOutRes:=2;
  63. -34 : InOutRes:=3;
  64. -35 : InOutRes:=4;
  65. -36 : InOutRes:=5;
  66. -37 : InOutRes:=8;
  67. -39 : InOutRes:=8;
  68. -40 : InOutRes:=9;
  69. -46 : InOutRes:=15;
  70. -67..-64 : InOutRes:=153;
  71. -15 : InOutRes:=151;
  72. -13 : InOutRes:=150;
  73. else
  74. InOutres := word(errno);
  75. end;
  76. end;
  77. errno:=0;
  78. end;
  79. procedure halt(errnum : byte);
  80. begin
  81. do_exit;
  82. flush(stderr);
  83. asm
  84. clr.l d0
  85. move.b errnum,d0
  86. move.w d0,-(sp)
  87. move.w #$4c,-(sp)
  88. trap #1
  89. end;
  90. end;
  91. function args : pointer; assembler;
  92. asm
  93. move.l __ARGS,d0
  94. end;
  95. Function GetParamCount(const p: pchar): longint;
  96. var
  97. i: word;
  98. count: word;
  99. Begin
  100. i:=0;
  101. count:=0;
  102. while p[count] <> #0 do
  103. Begin
  104. if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
  105. Begin
  106. i:=i+1;
  107. while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
  108. count:=count+1;
  109. end;
  110. if p[count] = #0 then break;
  111. count:=count+1;
  112. end;
  113. GetParamCount:=longint(i);
  114. end;
  115. Function GetParam(index: word; const p : pchar): string;
  116. { On Entry: index = string index to correct parameter }
  117. { On exit: = correct character index into pchar array }
  118. { Returns correct index to command line argument }
  119. var
  120. count: word;
  121. localindex: word;
  122. l: byte;
  123. temp: string;
  124. Begin
  125. temp:='';
  126. count := 0;
  127. { first index is one }
  128. localindex := 1;
  129. l:=0;
  130. While p[count] <> #0 do
  131. Begin
  132. if (p[count] <> ' ') and (p[count] <> #9) then
  133. Begin
  134. if localindex = index then
  135. Begin
  136. while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
  137. Begin
  138. temp:=temp+p[count];
  139. l:=l+1;
  140. count:=count+1;
  141. end;
  142. temp[0]:=char(l);
  143. GetParam:=temp;
  144. exit;
  145. end;
  146. { Point to next argument in list }
  147. while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
  148. Begin
  149. count:=count+1;
  150. end;
  151. localindex:=localindex+1;
  152. end;
  153. if p[count] = #0 then break;
  154. count:=count+1;
  155. end;
  156. GetParam:=temp;
  157. end;
  158. function paramstr(l : longint) : string;
  159. var
  160. p : pchar;
  161. s1 : string;
  162. begin
  163. if l = 0 then
  164. Begin
  165. s1 := '';
  166. end
  167. else
  168. if (l>0) and (l<=paramcount) then
  169. begin
  170. p:=args;
  171. paramstr:=GetParam(word(l),p);
  172. end
  173. else paramstr:='';
  174. end;
  175. function paramcount : longint;
  176. Begin
  177. paramcount := argc;
  178. end;
  179. procedure randomize;
  180. var
  181. hl : longint;
  182. begin
  183. asm
  184. movem.l d2/d3/a2/a3, -(sp) { save OS registers }
  185. move.w #17,-(sp)
  186. trap #14 { call xbios - random number }
  187. add.l #2,sp
  188. movem.l (sp)+,d2/d3/a2/a3
  189. move.l d0,hl { result in d0 }
  190. end;
  191. randseed:=hl;
  192. end;
  193. function getheapstart:pointer;assembler;
  194. asm
  195. lea.l HEAP,a0
  196. move.l a0,d0
  197. end;
  198. function getheapsize:longint;assembler;
  199. asm
  200. move.l HEAP_SIZE,d0
  201. end ['D0'];
  202. { This routine is used to grow the heap. }
  203. { But here we do a trick, we say that the }
  204. { heap cannot be regrown! }
  205. function sbrk( size: longint): longint;
  206. { on exit -1 = if fails. }
  207. Begin
  208. sbrk:=-1;
  209. end;
  210. {$I heap.inc}
  211. {****************************************************************************
  212. Low Level File Routines
  213. ****************************************************************************}
  214. procedure AllowSlash(p:pchar);
  215. var
  216. i : longint;
  217. begin
  218. { allow slash as backslash }
  219. for i:=0 to strlen(p) do
  220. if p[i]='/' then p[i]:='\';
  221. end;
  222. procedure do_close(h : longint);
  223. begin
  224. asm
  225. movem.l d2/d3/a2/a3,-(sp)
  226. move.l h,d0
  227. move.w d0,-(sp)
  228. move.w #$3e,-(sp)
  229. trap #1
  230. add.l #4,sp { restore stack ... }
  231. movem.l (sp)+,d2/d3/a2/a3
  232. end;
  233. end;
  234. procedure do_erase(p : pchar);
  235. begin
  236. AllowSlash(p);
  237. asm
  238. move.l d2,d6 { save d2 }
  239. movem.l d3/a2/a3,-(sp) { save regs }
  240. move.l p,-(sp)
  241. move.w #$41,-(sp)
  242. trap #1
  243. add.l #6,sp
  244. move.l d6,d2 { restore d2 }
  245. movem.l (sp)+,d3/a2/a3
  246. tst.w d0
  247. beq @doserend
  248. move.w d0,errno
  249. @doserend:
  250. end;
  251. if errno <> 0 then
  252. Error2InOut;
  253. end;
  254. procedure do_rename(p1,p2 : pchar);
  255. begin
  256. AllowSlash(p1);
  257. AllowSlash(p2);
  258. asm
  259. move.l d2,d6 { save d2 }
  260. movem.l d3/a2/a3,-(sp)
  261. move.l p1,-(sp)
  262. move.l p2,-(sp)
  263. clr.w -(sp)
  264. move.w #$56,-(sp)
  265. trap #1
  266. lea 12(sp),sp
  267. move.l d6,d2 { restore d2 }
  268. movem.l (sp)+,d3/a2/a3
  269. tst.w d0
  270. beq @dosreend
  271. move.w d0,errno { error ... }
  272. @dosreend:
  273. end;
  274. if errno <> 0 then
  275. Error2InOut;
  276. end;
  277. function do_isdevice(handle:word):boolean;
  278. begin
  279. if (handle=stdoutputhandle) or (handle=stdinputhandle) or
  280. (handle=stderrorhandle) then
  281. do_isdevice:=FALSE
  282. else
  283. do_isdevice:=TRUE;
  284. end;
  285. function do_write(h,addr,len : longint) : longint;
  286. begin
  287. asm
  288. move.l d2,d6 { save d2 }
  289. movem.l d3/a2/a3,-(sp)
  290. move.l addr,-(sp)
  291. move.l len,-(sp)
  292. move.l h,d0
  293. move.w d0,-(sp)
  294. move.w #$40,-(sp)
  295. trap #1
  296. lea 12(sp),sp
  297. move.l d6,d2 { restore d2 }
  298. movem.l (sp)+,d3/a2/a3
  299. tst.l d0
  300. bpl @doswrend
  301. move.w d0,errno { error ... }
  302. @doswrend:
  303. move.l d0,@RESULT
  304. end;
  305. if errno <> 0 then
  306. Error2InOut;
  307. end;
  308. function do_read(h,addr,len : longint) : longint;
  309. begin
  310. asm
  311. move.l d2,d6 { save d2 }
  312. movem.l d3/a2/a3,-(sp)
  313. move.l addr,-(sp)
  314. move.l len,-(sp)
  315. move.l h,d0
  316. move.w d0,-(sp)
  317. move.w #$3f,-(sp)
  318. trap #1
  319. lea 12(sp),sp
  320. move.l d6,d2 { restore d2 }
  321. movem.l (sp)+,d3/a2/a3
  322. tst.l d0
  323. bpl @dosrdend
  324. move.w d0,errno { error ... }
  325. @dosrdend:
  326. move.l d0,@Result
  327. end;
  328. if errno <> 0 then
  329. Error2InOut;
  330. end;
  331. function do_filepos(handle : longint) : longint;
  332. begin
  333. asm
  334. move.l d2,d6 { save d2 }
  335. movem.l d3/a2/a3,-(sp)
  336. move.w #1,-(sp) { seek from current position }
  337. move.l handle,d0
  338. move.w d0,-(sp)
  339. move.l #0,-(sp) { with a seek offset of zero }
  340. move.w #$42,-(sp)
  341. trap #1
  342. lea 10(sp),sp
  343. move.l d6,d2 { restore d2 }
  344. movem.l (sp)+,d3/a2/a3
  345. move.l d0,@Result
  346. end;
  347. end;
  348. procedure do_seek(handle,pos : longint);
  349. begin
  350. asm
  351. move.l d2,d6 { save d2 }
  352. movem.l d3/a2/a3,-(sp)
  353. move.w #0,-(sp) { seek from start of file }
  354. move.l handle,d0
  355. move.w d0,-(sp)
  356. move.l pos,-(sp)
  357. move.w #$42,-(sp)
  358. trap #1
  359. lea 10(sp),sp
  360. move.l d6,d2 { restore d2 }
  361. movem.l (sp)+,d3/a2/a3
  362. end;
  363. end;
  364. function do_seekend(handle:longint):longint;
  365. var
  366. t: longint;
  367. begin
  368. asm
  369. move.l d2,d6 { save d2 }
  370. movem.l d3/a2/a3,-(sp)
  371. move.w #2,-(sp) { seek from end of file }
  372. move.l handle,d0
  373. move.w d0,-(sp)
  374. move.l #0,-(sp) { with an offset of 0 from end }
  375. move.w #$42,-(sp)
  376. trap #1
  377. lea 10(sp),sp
  378. move.l d6,d2 { restore d2 }
  379. movem.l (sp)+,d3/a2/a3
  380. move.l d0,t
  381. end;
  382. do_seekend:=t;
  383. end;
  384. function do_filesize(handle : longint) : longint;
  385. var
  386. aktfilepos : longint;
  387. begin
  388. aktfilepos:=do_filepos(handle);
  389. do_filesize:=do_seekend(handle);
  390. do_seek(handle,aktfilepos);
  391. end;
  392. procedure do_truncate (handle,pos:longint);
  393. begin
  394. do_seek(handle,pos);
  395. {!!!!!!!!!!!!}
  396. end;
  397. procedure do_open(var f;p:pchar;flags:longint);
  398. {
  399. filerec and textrec have both handle and mode as the first items so
  400. they could use the same routine for opening/creating.
  401. when (flags and $100) the file will be append
  402. when (flags and $1000) the file will be truncate/rewritten
  403. when (flags and $10000) there is no check for close (needed for textfiles)
  404. }
  405. var
  406. i : word;
  407. oflags: longint;
  408. begin
  409. AllowSlash(p);
  410. { close first if opened }
  411. if ((flags and $10000)=0) then
  412. begin
  413. case filerec(f).mode of
  414. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  415. fmclosed : ;
  416. else
  417. begin
  418. inoutres:=102; {not assigned}
  419. exit;
  420. end;
  421. end;
  422. end;
  423. { reset file handle }
  424. filerec(f).handle:=UnusedHandle;
  425. oflags:=$02; { read/write mode }
  426. { convert filemode to filerec modes }
  427. case (flags and 3) of
  428. 0 : begin
  429. filerec(f).mode:=fminput;
  430. oflags:=$00; { read mode only }
  431. end;
  432. 1 : filerec(f).mode:=fmoutput;
  433. 2 : filerec(f).mode:=fminout;
  434. end;
  435. if (flags and $1000)<>0 then
  436. begin
  437. filerec(f).mode:=fmoutput;
  438. oflags:=$04; { read/write with create }
  439. end
  440. else
  441. if (flags and $100)<>0 then
  442. begin
  443. filerec(f).mode:=fmoutput;
  444. oflags:=$02; { read/write }
  445. end;
  446. { empty name is special }
  447. if p[0]=#0 then
  448. begin
  449. case filerec(f).mode of
  450. fminput : filerec(f).handle:=StdInputHandle;
  451. fmappend,
  452. fmoutput : begin
  453. filerec(f).handle:=StdOutputHandle;
  454. filerec(f).mode:=fmoutput; {fool fmappend}
  455. end;
  456. end;
  457. exit;
  458. end;
  459. asm
  460. movem.l d2/d3/a2/a3,-(sp) { save used registers }
  461. cmp.l #4,oflags { check if rewrite mode ... }
  462. bne @opencont2
  463. { rewrite mode - create new file }
  464. move.w #0,-(sp)
  465. move.l p,-(sp)
  466. move.w #$3c,-(sp)
  467. trap #1
  468. add.l #8,sp { restore stack of os call }
  469. bra @end
  470. { reset - open existing files }
  471. @opencont2:
  472. move.l oflags,d0 { use flag as source ... }
  473. @opencont1:
  474. move.w d0,-(sp)
  475. move.l p,-(sp)
  476. move.w #$3d,-(sp)
  477. trap #1
  478. add.l #8,sp { restore stack of os call }
  479. @end:
  480. movem.l (sp)+,d2/d3/a2/a3
  481. tst.w d0
  482. bpl @opennoerr { if positive return values then ok }
  483. cmp.w #-1,d0 { if handle is -1 CON: }
  484. beq @opennoerr
  485. cmp.w #-2,d0 { if handle is -2 AUX: }
  486. beq @opennoerr
  487. cmp.w #-3,d0 { if handle is -3 PRN: }
  488. beq @opennoerr
  489. move.w d0,errno { otherwise normal error }
  490. @opennoerr:
  491. move.w d0,i { get handle as SIGNED VALUE... }
  492. end;
  493. if errno <> 0 then
  494. Error2InOut;
  495. filerec(f).handle:=i;
  496. if (flags and $100)<>0 then
  497. do_seekend(filerec(f).handle);
  498. end;
  499. {*****************************************************************************
  500. UnTyped File Handling
  501. *****************************************************************************}
  502. {$i file.inc}
  503. {*****************************************************************************
  504. Typed File Handling
  505. *****************************************************************************}
  506. {$i typefile.inc}
  507. {*****************************************************************************
  508. Text File Handling
  509. *****************************************************************************}
  510. {$i text.inc}
  511. {*****************************************************************************
  512. Directory Handling
  513. *****************************************************************************}
  514. procedure DosDir(func:byte;const s:string);
  515. var
  516. buffer : array[0..255] of char;
  517. c : word;
  518. begin
  519. move(s[1],buffer,length(s));
  520. buffer[length(s)]:=#0;
  521. AllowSlash(pchar(@buffer));
  522. c:=word(func);
  523. asm
  524. move.l d2,d6 { save d2 }
  525. movem.l d3/a2/a3,-(sp)
  526. pea buffer
  527. move.w c,-(sp)
  528. trap #1
  529. add.l #6,sp
  530. move.l d6,d2 { restore d2 }
  531. movem.l (sp)+,d3/a2/a3
  532. tst.w d0
  533. beq @dosdirend
  534. move.w d0,errno
  535. @dosdirend:
  536. end;
  537. if errno <> 0 then
  538. Error2InOut;
  539. end;
  540. procedure mkdir(const s : string);[IOCheck];
  541. begin
  542. If InOutRes <> 0 then exit;
  543. DosDir($39,s);
  544. end;
  545. procedure rmdir(const s : string);[IOCheck];
  546. begin
  547. If InOutRes <> 0 then exit;
  548. DosDir($3a,s);
  549. end;
  550. procedure chdir(const s : string);[IOCheck];
  551. begin
  552. If InOutRes <> 0 then exit;
  553. DosDir($3b,s);
  554. end;
  555. function GetDirIO (DriveNr: byte; var Dir: ShortString): word;
  556. [public, alias: 'FPC_GETDIRIO'];
  557. var
  558. temp : array[0..255] of char;
  559. i : longint;
  560. j: byte;
  561. drv: word;
  562. begin
  563. GetDirIO := 0;
  564. drv:=word(drivenr);
  565. asm
  566. move.l d2,d6 { save d2 }
  567. movem.l d3/a2/a3,-(sp)
  568. { Get dir from drivenr : 0=default, 1=A etc... }
  569. move.w drv,-(sp)
  570. { put (previously saved) offset in si }
  571. { move.l temp,-(sp)}
  572. pea temp
  573. { call attos function 47H : Get dir }
  574. move.w #$47,-(sp)
  575. { make the call }
  576. trap #1
  577. add.l #8,sp
  578. move.l d6,d2 { restore d2 }
  579. movem.l (sp)+,d3/a2/a3
  580. end;
  581. { conversion to pascal string }
  582. i:=0;
  583. while (temp[i]<>#0) do
  584. begin
  585. if temp[i]='/' then
  586. temp[i]:='\';
  587. dir[i+3]:=temp[i];
  588. inc(i);
  589. end;
  590. dir[2]:=':';
  591. dir[3]:='\';
  592. dir[0]:=char(i+2);
  593. { upcase the string (FPC Pascal function) }
  594. dir:=upcase(dir);
  595. if drivenr<>0 then { Drive was supplied. We know it }
  596. dir[1]:=chr(65+drivenr-1)
  597. else
  598. begin
  599. asm
  600. move.l d2,d6 { save d2 }
  601. movem.l d3/a2/a3,-(sp)
  602. move.w #$19,-(sp)
  603. trap #1
  604. add.l #2,sp
  605. move.w d0,drv
  606. move.l d6,d2 { restore d2 }
  607. movem.l (sp)+,d3/a2/a3
  608. end;
  609. dir[1]:=chr(byte(drv)+ord('A'));
  610. end;
  611. end;
  612. procedure GetDir (DriveNr: byte; var Dir: ShortString);
  613. begin
  614. InOutRes := GetDirIO (DriveNr, Dir);
  615. end;
  616. {*****************************************************************************
  617. System Dependent Exit code
  618. *****************************************************************************}
  619. Procedure system_exit;
  620. begin
  621. end;
  622. {*****************************************************************************
  623. SystemUnit Initialization
  624. *****************************************************************************}
  625. begin
  626. { Initialize ExitProc }
  627. ExitProc:=Nil;
  628. { to test stack depth }
  629. loweststack:=maxlongint;
  630. { Setup heap }
  631. InitHeap;
  632. { Setup stdin, stdout and stderr }
  633. OpenStdIO(Input,fmInput,StdInputHandle);
  634. OpenStdIO(Output,fmOutput,StdOutputHandle);
  635. OpenStdIO(StdOut,fmOutput,StdOutputHandle);
  636. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  637. { Reset IO Error }
  638. InOutRes:=0;
  639. errno := 0;
  640. { Setup command line arguments }
  641. argc:=GetParamCount(args);
  642. end.
  643. {
  644. $Log$
  645. Revision 1.1 2001-03-16 20:01:47 hajny
  646. + system unit name change
  647. Revision 1.2 2000/07/14 10:30:58 michael
  648. +
  649. Revision 1.1 2000/07/13 06:30:30 michael
  650. + Initial import
  651. Revision 1.14 2000/01/07 16:41:29 daniel
  652. * copyright 2000
  653. Revision 1.13 2000/01/07 16:32:23 daniel
  654. * copyright 2000 added
  655. Revision 1.12 1999/09/10 15:40:33 peter
  656. * fixed do_open flags to be > $100, becuase filemode can be upto 255
  657. Revision 1.11 1999/01/18 10:05:48 pierre
  658. + system_exit procedure added
  659. Revision 1.10 1998/12/28 15:50:43 peter
  660. + stdout, which is needed when you write something in the system unit
  661. to the screen. Like the runtime error
  662. Revision 1.9 1998/09/14 10:48:02 peter
  663. * FPC_ names
  664. * Heap manager is now system independent
  665. Revision 1.8 1998/07/15 12:11:59 carl
  666. * hmmm... can't remember! :(...
  667. Revision 1.5 1998/07/13 12:34:13 carl
  668. + Error2InoutRes implemented
  669. * do_read was doing a wrong os call!
  670. * do_open was not pushing the right values
  671. * DosDir was pushing the wrong params on the stack
  672. * do_close would never works, was pushing a longint instead of word
  673. Revision 1.4 1998/07/02 12:39:27 carl
  674. * IOCheck for mkdir,chdir and rmdir, just like in TP
  675. Revision 1.3 1998/07/01 14:40:20 carl
  676. + new stack checking implemented
  677. + IOCheck for chdir , getdir , mkdir and rmdir
  678. Revision 1.1.1.1 1998/03/25 11:18:47 root
  679. * Restored version
  680. Revision 1.8 1998/02/23 02:27:39 carl
  681. * make it link correctly
  682. Revision 1.7 1998/02/06 16:33:02 carl
  683. * oops... commited wrong file
  684. + do_open is now standard with other platforms
  685. Revision 1.5 1998/01/31 19:32:51 carl
  686. - removed incorrect $define
  687. Revision 1.4 1998/01/27 10:55:45 peter
  688. * Word Handles from -1 -> $ffff
  689. Revision 1.3 1998/01/25 22:44:14 peter
  690. * Using uniform layout
  691. }