sysamiga.pas 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,97 by the Free Pascal development team.
  5. Some parts taken from
  6. Marcel Timmermans - Modula 2 Compiler
  7. Nils Sjoholm - Amiga porter
  8. See the file COPYING.FPC, included in this distribution,
  9. for details about the copyright.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. **********************************************************************}
  14. unit sysamiga;
  15. {--------------------------------------------------------------------}
  16. { LEFT TO DO: }
  17. {--------------------------------------------------------------------}
  18. { o ChDir('..') }
  19. { o SBrk }
  20. { o GetDir with different drive numbers }
  21. {--------------------------------------------------------------------}
  22. {$I os.inc}
  23. { AmigaOS uses character #10 as eoln only }
  24. {$DEFINE SHORT_LINEBREAK}
  25. interface
  26. { used for single computations }
  27. const BIAS4 = $7f-1;
  28. {$I systemh.inc}
  29. {$I heaph.inc}
  30. const
  31. UnusedHandle : longint = -1;
  32. StdInputHandle : longint = 0;
  33. StdOutputHandle : longint = 0;
  34. StdErrorHandle : longint = 0;
  35. argc : longint = 0;
  36. _ExecBase:longint = $4;
  37. _WorkbenchMsg : longint = 0;
  38. intuitionname : pchar = 'intuition.library';
  39. dosname : pchar = 'dos.library';
  40. utilityname : pchar = 'utility.library';
  41. _IntuitionBase : pointer = nil; { intuition library pointer }
  42. _DosBase : pointer = nil; { DOS library pointer }
  43. _UtilityBase : pointer = nil; { utiity library pointer }
  44. { Required for crt unit }
  45. function do_read(h,addr,len : longint) : longint;
  46. function do_write(h,addr,len : longint) : longint;
  47. var
  48. OrigDir : Longint;
  49. implementation
  50. {$I exec.inc}
  51. TYPE
  52. TDateStamp = packed record
  53. ds_Days : Longint; { Number of days since Jan. 1, 1978 }
  54. ds_Minute : Longint; { Number of minutes past midnight }
  55. ds_Tick : Longint; { Number of ticks past minute }
  56. end;
  57. PDateStamp = ^TDateStamp;
  58. PFileInfoBlock = ^TfileInfoBlock;
  59. TFileInfoBlock = packed record
  60. fib_DiskKey : Longint;
  61. fib_DirEntryType : Longint;
  62. { Type of Directory. If < 0, then a plain file.
  63. If > 0 a directory }
  64. fib_FileName : Array [0..107] of Char;
  65. { Null terminated. Max 30 chars used for now }
  66. fib_Protection : Longint;
  67. { bit mask of protection, rwxd are 3-0. }
  68. fib_EntryType : Longint;
  69. fib_Size : Longint; { Number of bytes in file }
  70. fib_NumBlocks : Longint; { Number of blocks in file }
  71. fib_Date : TDateStamp; { Date file last changed }
  72. fib_Comment : Array [0..79] of Char;
  73. { Null terminated comment associated with file }
  74. fib_Reserved : Array [0..35] of Char;
  75. end;
  76. TProcess = packed record
  77. pr_Task : TTask;
  78. pr_MsgPort : TMsgPort; { This is BPTR address from DOS functions }
  79. {126} pr_Pad : Word; { Remaining variables on 4 byte boundaries }
  80. {128} pr_SegList : Pointer; { Array of seg lists used by this process }
  81. {132} pr_StackSize : Longint; { Size of process stack in bytes }
  82. {136} pr_GlobVec : Pointer; { Global vector for this process (BCPL) }
  83. {140} pr_TaskNum : Longint; { CLI task number of zero if not a CLI }
  84. {144} pr_StackBase : BPTR; { Ptr to high memory end of process stack }
  85. {148} pr_Result2 : Longint; { Value of secondary result from last call }
  86. {152} pr_CurrentDir : BPTR; { Lock associated with current directory }
  87. {156} pr_CIS : BPTR; { Current CLI Input Stream }
  88. {160} pr_COS : BPTR; { Current CLI Output Stream }
  89. {164} pr_ConsoleTask : Pointer; { Console handler process for current window}
  90. {168} pr_FileSystemTask : Pointer; { File handler process for current drive }
  91. {172} pr_CLI : BPTR; { pointer to ConsoleLineInterpreter }
  92. pr_ReturnAddr : Pointer; { pointer to previous stack frame }
  93. pr_PktWait : Pointer; { Function to be called when awaiting msg }
  94. pr_WindowPtr : Pointer; { Window for error printing }
  95. { following definitions are new with 2.0 }
  96. pr_HomeDir : BPTR; { Home directory of executing program }
  97. pr_Flags : Longint; { flags telling dos about process }
  98. pr_ExitCode : Pointer; { code to call on exit of program OR NULL }
  99. pr_ExitData : Longint; { Passed as an argument to pr_ExitCode. }
  100. pr_Arguments : PChar; { Arguments passed to the process at start }
  101. pr_LocalVars : TMinList; { Local environment variables }
  102. pr_ShellPrivate : Longint; { for the use of the current shell }
  103. pr_CES : BPTR; { Error stream - IF NULL, use pr_COS }
  104. end;
  105. PProcess = ^TProcess;
  106. Const
  107. _LVOFindTask = -294;
  108. _LVOWaitPort = -384;
  109. _LVOGetMsg = -372;
  110. _LVOOpenLibrary = -552;
  111. _LVOCloseLibrary = -414;
  112. _LVOClose = -36;
  113. _LVOOpen = -30;
  114. _LVOIoErr = -132;
  115. _LVOSeek = -66;
  116. _LVODeleteFile = -72;
  117. _LVORename = -78;
  118. _LVOWrite = -48;
  119. _LVORead = -42;
  120. _LVOCreateDir = -120;
  121. _LVOSetCurrentDirName = -558;
  122. _LVOGetCurrentDirName = -564;
  123. _LVOInput = -54;
  124. _LVOOutput = -60;
  125. _LVOUnLock = -90;
  126. _LVOLock = -84;
  127. _LVOCurrentDir = -126;
  128. _LVONameFromLock = -402;
  129. _LVONameFromFH = -408;
  130. _LVOGetProgramName = -576;
  131. _LVOGetProgramDir = -600;
  132. _LVODupLock = -96;
  133. _LVOExamine = -102;
  134. _LVOParentDir = -210;
  135. _LVOSetFileSize = -456;
  136. { Errors from IoErr(), etc. }
  137. ERROR_NO_FREE_STORE = 103;
  138. ERROR_TASK_TABLE_FULL = 105;
  139. ERROR_BAD_TEMPLATE = 114;
  140. ERROR_BAD_NUMBER = 115;
  141. ERROR_REQUIRED_ARG_MISSING = 116;
  142. ERROR_KEY_NEEDS_ARG = 117;
  143. ERROR_TOO_MANY_ARGS = 118;
  144. ERROR_UNMATCHED_QUOTES = 119;
  145. ERROR_LINE_TOO_LONG = 120;
  146. ERROR_FILE_NOT_OBJECT = 121;
  147. ERROR_INVALID_RESIDENT_LIBRARY = 122;
  148. ERROR_NO_DEFAULT_DIR = 201;
  149. ERROR_OBJECT_IN_USE = 202;
  150. ERROR_OBJECT_EXISTS = 203;
  151. ERROR_DIR_NOT_FOUND = 204;
  152. ERROR_OBJECT_NOT_FOUND = 205;
  153. ERROR_BAD_STREAM_NAME = 206;
  154. ERROR_OBJECT_TOO_LARGE = 207;
  155. ERROR_ACTION_NOT_KNOWN = 209;
  156. ERROR_INVALID_COMPONENT_NAME = 210;
  157. ERROR_INVALID_LOCK = 211;
  158. ERROR_OBJECT_WRONG_TYPE = 212;
  159. ERROR_DISK_NOT_VALIDATED = 213;
  160. ERROR_DISK_WRITE_PROTECTED = 214;
  161. ERROR_RENAME_ACROSS_DEVICES = 215;
  162. ERROR_DIRECTORY_NOT_EMPTY = 216;
  163. ERROR_TOO_MANY_LEVELS = 217;
  164. ERROR_DEVICE_NOT_MOUNTED = 218;
  165. ERROR_SEEK_ERROR = 219;
  166. ERROR_COMMENT_TOO_BIG = 220;
  167. ERROR_DISK_FULL = 221;
  168. ERROR_DELETE_PROTECTED = 222;
  169. ERROR_WRITE_PROTECTED = 223;
  170. ERROR_READ_PROTECTED = 224;
  171. ERROR_NOT_A_DOS_DISK = 225;
  172. ERROR_NO_DISK = 226;
  173. ERROR_NO_MORE_ENTRIES = 232;
  174. { added for 1.4 }
  175. ERROR_IS_SOFT_LINK = 233;
  176. ERROR_OBJECT_LINKED = 234;
  177. ERROR_BAD_HUNK = 235;
  178. ERROR_NOT_IMPLEMENTED = 236;
  179. ERROR_RECORD_NOT_LOCKED = 240;
  180. ERROR_LOCK_COLLISION = 241;
  181. ERROR_LOCK_TIMEOUT = 242;
  182. ERROR_UNLOCK_ERROR = 243;
  183. var
  184. Initial: boolean;
  185. errno : word;
  186. {$I system.inc}
  187. {$I lowmath.inc}
  188. { ************************ AMIGAOS STUB ROUTINES ************************* }
  189. procedure DateStamp(var ds : tDateStamp);
  190. begin
  191. asm
  192. MOVE.L A6,-(A7)
  193. MOVE.L ds,d1
  194. { LAST THING TO SETUP SHOULD BE A6, otherwise you can }
  195. { not accept local variable, nor any parameters! :) }
  196. MOVE.L _DOSBase,A6
  197. JSR -192(A6)
  198. MOVE.L (A7)+,A6
  199. end;
  200. end;
  201. { UNLOCK the BPTR pointed to in L }
  202. Procedure Unlock(alock: longint);
  203. Begin
  204. asm
  205. move.l alock,d1
  206. move.l a6,d6 { save base pointer }
  207. move.l _DosBase,a6
  208. jsr _LVOUnlock(a6)
  209. move.l d6,a6 { restore base pointer }
  210. end;
  211. end;
  212. { Change to the directory pointed to in the lock }
  213. Function CurrentDir(alock : longint) : longint;
  214. Begin
  215. asm
  216. move.l alock,d1
  217. move.l a6,d6 { save base pointer }
  218. move.l _DosBase,a6
  219. jsr _LVOCurrentDir(a6)
  220. move.l d6,a6 { restore base pointer }
  221. move.l d0,@Result
  222. end;
  223. end;
  224. { Duplicate a lock }
  225. Function DupLock(alock: longint): Longint;
  226. Begin
  227. asm
  228. move.l alock,d1
  229. move.l a6,d6 { save base pointer }
  230. move.l _DosBase,a6
  231. jsr _LVODupLock(a6)
  232. move.l d6,a6 { restore base pointer }
  233. move.l d0,@Result
  234. end;
  235. end;
  236. { Returns a lock on the directory was loaded from }
  237. Function GetProgramLock: longint;
  238. Begin
  239. asm
  240. move.l a6,d6 { save base pointer }
  241. move.l _DosBase,a6
  242. jsr _LVOGetProgramDir(a6)
  243. move.l d6,a6 { restore base pointer }
  244. move.l d0,@Result
  245. end;
  246. end;
  247. Function Examine(alock :longint; var fib: TFileInfoBlock) : Boolean;
  248. Begin
  249. asm
  250. move.l d2,-(sp)
  251. move.l fib,d2 { pointer to FIB }
  252. move.l alock,d1
  253. move.l a6,d6 { save base pointer }
  254. move.l _DosBase,a6
  255. jsr _LVOExamine(a6)
  256. move.l d6,a6 { restore base pointer }
  257. tst.l d0
  258. bne @success
  259. bra @end
  260. @success:
  261. move.b #1,d0
  262. @end:
  263. move.b d0,@Result
  264. move.l (sp)+,d2
  265. end;
  266. end;
  267. { Returns the parent directory of a lock }
  268. Function ParentDir(alock : longint): longint;
  269. Begin
  270. asm
  271. move.l alock,d1
  272. move.l a6,d6 { save base pointer }
  273. move.l _DosBase,a6
  274. jsr _LVOParentDir(a6)
  275. move.l d6,a6 { restore base pointer }
  276. move.l d0,@Result
  277. end;
  278. end;
  279. Function FindTask(p : PChar): PProcess;
  280. Begin
  281. asm
  282. move.l a6,d6 { Save base pointer }
  283. move.l p,d0
  284. move.l d0,a1
  285. move.l _ExecBase,a6
  286. jsr _LVOFindTask(a6)
  287. move.l d6,a6 { Restore base pointer }
  288. move.l d0,@Result
  289. end;
  290. end;
  291. {$S-}
  292. Procedure stack_check; assembler;
  293. { Check for local variable allocation }
  294. { On Entry -> d0 : size of local stack we are trying to allocate }
  295. asm
  296. XDEF STACKCHECK
  297. move.l sp,d1 { get value of stack pointer }
  298. { We must add some security, because Writing the RunError strings }
  299. { requires a LOT of stack space (at least 1030 bytes!) }
  300. add.l #2048,d0
  301. sub.l d0,d1 { sp - stack_size }
  302. move.l _ExecBase,a0
  303. move.l 276(A0),A0 { ExecBase.thisTask }
  304. { if allocated stack_pointer - splower <= 0 then stack_ovf }
  305. cmp.l 58(A0),D1 { Task.SpLower }
  306. bgt @Ok
  307. move.l #202,d0
  308. jsr HALT_ERROR { stack overflow }
  309. @Ok:
  310. end;
  311. { Converts an AMIGAOS error code to a TP compatible error code }
  312. Procedure Error2InOut;
  313. Begin
  314. case errno of
  315. ERROR_BAD_NUMBER,
  316. ERROR_ACTION_NOT_KNOWN,
  317. ERROR_NOT_IMPLEMENTED : InOutRes := 1;
  318. ERROR_OBJECT_NOT_FOUND : InOutRes := 2;
  319. ERROR_DIR_NOT_FOUND : InOutRes := 3;
  320. ERROR_DISK_WRITE_PROTECTED : InOutRes := 150;
  321. ERROR_OBJECT_WRONG_TYPE : InOutRes := 151;
  322. ERROR_OBJECT_EXISTS,
  323. ERROR_DELETE_PROTECTED,
  324. ERROR_WRITE_PROTECTED,
  325. ERROR_READ_PROTECTED,
  326. ERROR_OBJECT_IN_USE,
  327. ERROR_DIRECTORY_NOT_EMPTY : InOutRes := 5;
  328. ERROR_NO_MORE_ENTRIES : InOutRes := 18;
  329. ERROR_RENAME_ACROSS_DEVICES : InOutRes := 17;
  330. ERROR_DISK_FULL : InOutRes := 101;
  331. ERROR_INVALID_RESIDENT_LIBRARY : InoutRes := 153;
  332. ERROR_BAD_HUNK : InOutRes := 153;
  333. ERROR_NOT_A_DOS_DISK : InOutRes := 157;
  334. ERROR_NO_DISK,
  335. ERROR_DISK_NOT_VALIDATED,
  336. ERROR_DEVICE_NOT_MOUNTED : InOutRes := 152;
  337. ERROR_SEEK_ERROR : InOutRes := 156;
  338. ERROR_LOCK_COLLISION,
  339. ERROR_LOCK_TIMEOUT,
  340. ERROR_UNLOCK_ERROR,
  341. ERROR_INVALID_LOCK,
  342. ERROR_INVALID_COMPONENT_NAME,
  343. ERROR_BAD_STREAM_NAME,
  344. ERROR_FILE_NOT_OBJECT : InOutRes := 6;
  345. else
  346. InOutres := errno;
  347. end;
  348. errno:=0;
  349. end;
  350. procedure CloseLibrary(lib : pointer);
  351. { Close the library pointed to in lib }
  352. Begin
  353. asm
  354. MOVE.L A6,-(A7)
  355. MOVE.L lib,a1
  356. MOVE.L _ExecBase,A6
  357. JSR _LVOCloseLibrary(A6)
  358. MOVE.L (A7)+,A6
  359. end;
  360. end;
  361. Function KickVersion: word; assembler;
  362. asm
  363. move.l _ExecBase, a0 { Get Exec Base }
  364. move.w 20(a0), d0 { Return version - version at this offset }
  365. end;
  366. procedure halt(errnum : byte);
  367. begin
  368. { WE can only FLUSH the stdio }
  369. { if the handles have correctly }
  370. { been set. }
  371. { No exit procedures exist }
  372. { if in initial state }
  373. If NOT Initial then
  374. Begin
  375. do_exit;
  376. flush(stderr);
  377. end;
  378. if (OrigDir <> 0) then
  379. Begin
  380. Unlock(CurrentDir(OrigDir));
  381. OrigDir := 0;
  382. end;
  383. { close the libraries }
  384. If _UtilityBase <> nil then
  385. Begin
  386. CloseLibrary(_UtilityBase);
  387. end;
  388. If _DosBase <> nil then
  389. Begin
  390. CloseLibrary(_DosBase);
  391. end;
  392. If _IntuitionBase <> nil then
  393. Begin
  394. CloseLibrary(_IntuitionBase);
  395. end;
  396. asm
  397. clr.l d0
  398. move.b errnum,d0
  399. move.l STKPTR,sp
  400. rts
  401. end;
  402. end;
  403. { ************************ PARAMCOUNT/PARAMSTR *************************** }
  404. function paramcount : longint;
  405. Begin
  406. paramcount := argc;
  407. end;
  408. function args : pointer; assembler;
  409. asm
  410. move.l __ARGS,d0
  411. end;
  412. Function GetParamCount(const p: pchar): longint;
  413. var
  414. i: word;
  415. count: word;
  416. Begin
  417. i:=0;
  418. count:=0;
  419. while p[count] <> #0 do
  420. Begin
  421. if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
  422. Begin
  423. i:=i+1;
  424. while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
  425. count:=count+1;
  426. end;
  427. if p[count] = #0 then break;
  428. count:=count+1;
  429. end;
  430. GetParamCount:=longint(i);
  431. end;
  432. Function GetParam(index: word; const p : pchar): string;
  433. { On Entry: index = string index to correct parameter }
  434. { On exit: = correct character index into pchar array }
  435. { Returns correct index to command line argument }
  436. var
  437. count: word;
  438. localindex: word;
  439. l: byte;
  440. temp: string;
  441. Begin
  442. temp:='';
  443. count := 0;
  444. { first index is one }
  445. localindex := 1;
  446. l:=0;
  447. While p[count] <> #0 do
  448. Begin
  449. if (p[count] <> ' ') and (p[count] <> #9) then
  450. Begin
  451. if localindex = index then
  452. Begin
  453. while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
  454. Begin
  455. temp:=temp+p[count];
  456. l:=l+1;
  457. count:=count+1;
  458. end;
  459. temp[0]:=char(l);
  460. GetParam:=temp;
  461. exit;
  462. end;
  463. { Point to next argument in list }
  464. while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
  465. Begin
  466. count:=count+1;
  467. end;
  468. localindex:=localindex+1;
  469. end;
  470. if p[count] = #0 then break;
  471. count:=count+1;
  472. end;
  473. GetParam:=temp;
  474. end;
  475. Function GetProgramDir : String;
  476. var
  477. s1: string;
  478. alock: longint;
  479. counter : byte;
  480. Begin
  481. FillChar(@s1,255,#0);
  482. { GetLock of program directory }
  483. asm
  484. move.l a6,d6 { save a6 }
  485. move.l _DOSBase,a6
  486. jsr _LVOGetProgramDir(a6)
  487. move.l d6,a6 { restore a6 }
  488. move.l d0,alock { save the lock }
  489. end;
  490. if alock <> 0 then
  491. Begin
  492. { Get the name from the lock! }
  493. asm
  494. movem.l d2/d3,-(sp) { save used registers }
  495. move.l alock,d1
  496. lea s1,a0 { Get pointer to string! }
  497. move.l a0,d2
  498. add.l #1,d2 { let us point past the length byte! }
  499. move.l #255,d3
  500. move.l a6,d6 { save a6 }
  501. move.l _DOSBase,a6
  502. jsr _LVONameFromLock(a6)
  503. move.l d6,a6 { restore a6 }
  504. movem.l (sp)+,d2/d3
  505. end;
  506. { no check out the length of the string }
  507. counter := 1;
  508. while s1[counter] <> #0 do
  509. Inc(counter);
  510. s1[0] := char(counter-1);
  511. GetProgramDir := s1;
  512. end
  513. else
  514. GetProgramDir := '';
  515. end;
  516. Function GetProgramName : string;
  517. { Returns ONLY the program name }
  518. { There seems to be a bug in v39 since if the program is not }
  519. { called from its home directory the program name will also }
  520. { contain the path! }
  521. var
  522. s1: string;
  523. counter : byte;
  524. Begin
  525. FillChar(@s1,255,#0);
  526. asm
  527. move.l d2,-(sp) { Save used register }
  528. lea s1,a0 { Get pointer to string! }
  529. move.l a0,d1
  530. add.l #1,d1 { point to correct offset }
  531. move.l #255,d2
  532. move.l a6,d6 { save a6 }
  533. move.l _DOSBase,a6
  534. jsr _LVOGetProgramName(a6)
  535. move.l d6,a6 { restore a6 }
  536. move.l (sp)+,d2 { restore saved register }
  537. end;
  538. { no check out and assign the length of the string }
  539. counter := 1;
  540. while s1[counter] <> #0 do
  541. Inc(counter);
  542. s1[0] := char(counter-1);
  543. { now remove any component path which should not be there }
  544. for counter:=length(s1) downto 1 do
  545. if (s1[counter] = '/') or (s1[counter] = ':') then break;
  546. { readjust counterv to point to character }
  547. if counter <> 1 then
  548. Inc(counter);
  549. GetProgramName:=copy(s1,counter,length(s1));
  550. end;
  551. function paramstr(l : longint) : string;
  552. var
  553. p : pchar;
  554. s1 : string;
  555. begin
  556. { -> Call AmigaOS GetProgramName }
  557. if l = 0 then
  558. Begin
  559. s1 := GetProgramDir;
  560. { If this is a root, then simply don't add '/' }
  561. if s1[length(s1)] = ':' then
  562. paramstr:=s1+GetProgramName
  563. else
  564. { add backslash directory }
  565. paramstr:=s1+'/'+GetProgramName
  566. end
  567. else
  568. if (l>0) and (l<=paramcount) then
  569. begin
  570. p:=args;
  571. paramstr:=GetParam(word(l),p);
  572. end
  573. else paramstr:='';
  574. end;
  575. { ************************************************************************ }
  576. procedure randomize;
  577. var
  578. hl : longint;
  579. time : TDateStamp;
  580. begin
  581. DateStamp(time);
  582. randseed:=time.ds_tick;
  583. end;
  584. { This routine is used to grow the heap. }
  585. { But here we do a trick, we say that the }
  586. { heap cannot be regrown! }
  587. function sbrk( size: longint): longint;
  588. { on exit -1 = if fails. }
  589. Begin
  590. sbrk:=-1;
  591. end;
  592. {$I heap.inc}
  593. {****************************************************************************
  594. Low Level File Routines
  595. ****************************************************************************}
  596. procedure do_close(h : longint);
  597. begin
  598. asm
  599. move.l h,d1
  600. move.l a6,d6 { save a6 }
  601. move.l _DOSBase,a6
  602. jsr _LVOClose(a6)
  603. move.l d6,a6 { restore a6 }
  604. end;
  605. end;
  606. function do_isdevice(handle:longint):boolean;
  607. begin
  608. if (handle=stdoutputhandle) or (handle=stdinputhandle) or
  609. (handle=stderrorhandle) then
  610. do_isdevice:=TRUE
  611. else
  612. do_isdevice:=FALSE;
  613. end;
  614. procedure do_erase(p : pchar);
  615. begin
  616. asm
  617. move.l a6,d6 { save a6 }
  618. move.l p,d1
  619. move.l _DOSBase,a6
  620. jsr _LVODeleteFile(a6)
  621. tst.l d0 { zero = failure }
  622. bne @noerror
  623. jsr _LVOIoErr(a6)
  624. move.w d0,errno
  625. @noerror:
  626. move.l d6,a6 { restore a6 }
  627. end;
  628. if errno <> 0 then
  629. Error2InOut;
  630. end;
  631. procedure do_rename(p1,p2 : pchar);
  632. begin
  633. asm
  634. move.l a6,d6 { save a6 }
  635. move.l d2,-(sp) { save d2 }
  636. move.l p1,d1
  637. move.l p2,d2
  638. move.l _DOSBase,a6
  639. jsr _LVORename(a6)
  640. move.l (sp)+,d2 { restore d2 }
  641. tst.l d0
  642. bne @dosreend { if zero = error }
  643. jsr _LVOIoErr(a6)
  644. move.w d0,errno
  645. @dosreend:
  646. move.l d6,a6 { restore a6 }
  647. end;
  648. if errno <> 0 then
  649. Error2InOut;
  650. end;
  651. function do_write(h,addr,len : longint) : longint;
  652. begin
  653. if len <= 0 then
  654. Begin
  655. do_write:=0;
  656. exit;
  657. end;
  658. asm
  659. move.l a6,d6
  660. movem.l d2/d3,-(sp)
  661. move.l h,d1 { we must of course set up the }
  662. move.l addr,d2 { parameters BEFORE getting }
  663. move.l len,d3 { _DOSBase }
  664. move.l _DOSBase,a6
  665. jsr _LVOWrite(a6)
  666. movem.l (sp)+,d2/d3
  667. cmp.l #-1,d0
  668. bne @doswrend { if -1 = error }
  669. jsr _LVOIoErr(a6)
  670. move.w d0,errno
  671. bra @doswrend2
  672. @doswrend:
  673. { we must restore the base pointer before setting the result }
  674. move.l d6,a6
  675. move.l d0,@RESULT
  676. bra @end
  677. @doswrend2:
  678. move.l d6,a6
  679. @end:
  680. end;
  681. If errno <> 0 then
  682. Error2InOut;
  683. end;
  684. function do_read(h,addr,len : longint) : longint;
  685. begin
  686. if len <= 0 then
  687. Begin
  688. do_read:=0;
  689. exit;
  690. end;
  691. asm
  692. move.l a6,d6
  693. movem.l d2/d3,-(sp)
  694. move.l h,d1 { we must set up aparamters BEFORE }
  695. move.l addr,d2 { setting up a6 for the OS call }
  696. move.l len,d3
  697. move.l _DOSBase,a6
  698. jsr _LVORead(a6)
  699. movem.l (sp)+,d2/d3
  700. cmp.l #-1,d0
  701. bne @doswrend { if -1 = error }
  702. jsr _LVOIoErr(a6)
  703. move.w d0,errno
  704. bra @doswrend2
  705. @doswrend:
  706. { to store a result for the function }
  707. { we must of course first get back the}
  708. { base pointer! }
  709. move.l d6,a6
  710. move.l d0,@RESULT
  711. bra @end
  712. @doswrend2:
  713. move.l d6,a6
  714. @end:
  715. end;
  716. If errno <> 0 then
  717. Error2InOut;
  718. end;
  719. function do_filepos(handle : longint) : longint;
  720. begin
  721. asm
  722. move.l a6,d6
  723. move.l handle,d1
  724. move.l d2,-(sp)
  725. move.l d3,-(sp) { save registers }
  726. clr.l d2 { offset 0 }
  727. move.l #0,d3 { OFFSET_CURRENT }
  728. move.l _DOSBase,a6
  729. jsr _LVOSeek(a6)
  730. move.l (sp)+,d3 { restore registers }
  731. move.l (sp)+,d2
  732. cmp.l #-1,d0 { is there a file access error? }
  733. bne @noerr
  734. jsr _LVOIoErr(a6)
  735. move.w d0,errno
  736. bra @fposend
  737. @noerr:
  738. move.l d6,a6 { restore a6 }
  739. move.l d0,@Result
  740. bra @end
  741. @fposend:
  742. move.l d6,a6 { restore a6 }
  743. @end:
  744. end;
  745. If errno <> 0 then
  746. Error2InOut;
  747. end;
  748. procedure do_seek(handle,pos : longint);
  749. begin
  750. asm
  751. move.l a6,d6
  752. move.l handle,d1
  753. move.l d2,-(sp)
  754. move.l d3,-(sp) { save registers }
  755. move.l pos,d2
  756. { -1 }
  757. move.l #$ffffffff,d3 { OFFSET_BEGINNING }
  758. move.l _DOSBase,a6
  759. jsr _LVOSeek(a6)
  760. move.l (sp)+,d3 { restore registers }
  761. move.l (sp)+,d2
  762. cmp.l #-1,d0 { is there a file access error? }
  763. bne @noerr
  764. jsr _LVOIoErr(a6)
  765. move.w d0,errno
  766. bra @seekend
  767. @noerr:
  768. @seekend:
  769. move.l d6,a6 { restore a6 }
  770. end;
  771. If errno <> 0 then
  772. Error2InOut;
  773. end;
  774. function do_seekend(handle:longint):longint;
  775. begin
  776. asm
  777. { seek from end of file }
  778. move.l a6,d6
  779. move.l handle,d1
  780. move.l d2,-(sp)
  781. move.l d3,-(sp) { save registers }
  782. clr.l d2
  783. move.l #1,d3 { OFFSET_END }
  784. move.l _DOSBase,a6
  785. jsr _LVOSeek(a6)
  786. move.l (sp)+,d3 { restore registers }
  787. move.l (sp)+,d2
  788. cmp.l #-1,d0 { is there a file access error? }
  789. bne @noerr
  790. jsr _LVOIoErr(a6)
  791. move.w d0,errno
  792. bra @seekend
  793. @noerr:
  794. move.l d6,a6 { restore a6 }
  795. move.l d0,@Result
  796. bra @end
  797. @seekend:
  798. move.l d6,a6 { restore a6 }
  799. @end:
  800. end;
  801. If Errno <> 0 then
  802. Error2InOut;
  803. end;
  804. function do_filesize(handle : longint) : longint;
  805. var
  806. aktfilepos : longint;
  807. begin
  808. aktfilepos:=do_filepos(handle);
  809. { We have to do this two times, because seek returns the }
  810. { OLD position }
  811. do_filesize:=do_seekend(handle);
  812. do_filesize:=do_seekend(handle);
  813. do_seek(handle,aktfilepos);
  814. end;
  815. procedure do_truncate (handle,pos:longint);
  816. begin
  817. { Point to the end of the file }
  818. { with the new size }
  819. asm
  820. @noerr_one: { Seek a second time }
  821. move.l a6,d6 { Save base pointer }
  822. move.l handle,d1
  823. move.l d2,-(sp)
  824. move.l d3,-(sp) { save registers }
  825. move.l pos,d2
  826. move.l #-1,d3 { Setup correct move type }
  827. move.l _DOSBase,a6 { from beginning of file }
  828. jsr _LVOSetFileSize(a6)
  829. move.l (sp)+,d3 { restore registers }
  830. move.l (sp)+,d2
  831. cmp.l #-1,d0 { is there a file access error? }
  832. bne @noerr
  833. jsr _LVOIoErr(a6)
  834. move.w d0,errno { Global variable, so no need }
  835. @noerr: { to restore base pointer now }
  836. move.l d6,a6 { Restore base pointer }
  837. end;
  838. If Errno <> 0 then
  839. Error2InOut;
  840. end;
  841. procedure do_open(var f;p:pchar;flags:longint);
  842. {
  843. filerec and textrec have both handle and mode as the first items so
  844. they could use the same routine for opening/creating.
  845. when (flags and $10) the file will be append
  846. when (flags and $100) the file will be truncate/rewritten
  847. when (flags and $1000) there is no check for close (needed for textfiles)
  848. }
  849. var
  850. i : longint;
  851. oflags: longint;
  852. begin
  853. { close first if opened }
  854. if ((flags and $1000)=0) then
  855. begin
  856. case filerec(f).mode of
  857. fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
  858. fmclosed : ;
  859. else
  860. begin
  861. inoutres:=102; {not assigned}
  862. exit;
  863. end;
  864. end;
  865. end;
  866. { reset file handle }
  867. filerec(f).handle:=UnusedHandle;
  868. { convert filemode to filerec modes }
  869. { READ/WRITE on existing file }
  870. { RESET/APPEND }
  871. oflags := 1005;
  872. case (flags and 3) of
  873. 0 : begin
  874. filerec(f).mode:=fminput;
  875. end;
  876. 1 : filerec(f).mode:=fmoutput;
  877. 2 : filerec(f).mode:=fminout;
  878. end;
  879. { READ/WRITE mode, create file in all cases }
  880. { REWRITE }
  881. if (flags and $100)<>0 then
  882. begin
  883. filerec(f).mode:=fmoutput;
  884. oflags := 1006;
  885. end
  886. else
  887. { READ/WRITE mode on existing file }
  888. { APPEND }
  889. if (flags and $10)<>0 then
  890. begin
  891. filerec(f).mode:=fmoutput;
  892. oflags := 1005;
  893. end;
  894. { empty name is special }
  895. if p[0]=#0 then
  896. begin
  897. case filerec(f).mode of
  898. fminput : filerec(f).handle:=StdInputHandle;
  899. fmappend,
  900. fmoutput : begin
  901. filerec(f).handle:=StdOutputHandle;
  902. filerec(f).mode:=fmoutput; {fool fmappend}
  903. end;
  904. end;
  905. exit;
  906. end;
  907. asm
  908. move.l a6,d6 { save a6 }
  909. move.l p,d1
  910. move.l oflags,d2 { MODE_READWRITE }
  911. move.l _DOSBase,a6
  912. jsr _LVOOpen(a6)
  913. tst.l d0
  914. bne @noopenerror { on zero an error occured }
  915. jsr _LVOIoErr(a6)
  916. move.w d0,errno
  917. bra @openend
  918. @noopenerror:
  919. move.l d6,a6 { restore a6 }
  920. move.l d0,i { we need the base pointer to access this variable }
  921. bra @end
  922. @openend:
  923. move.l d6,a6 { restore a6 }
  924. @end:
  925. end;
  926. If Errno <> 0 then
  927. Error2InOut;
  928. filerec(f).handle:=i;
  929. if (flags and $10)<>0 then
  930. do_seekend(filerec(f).handle);
  931. end;
  932. {*****************************************************************************
  933. UnTyped File Handling
  934. *****************************************************************************}
  935. {$i file.inc}
  936. {*****************************************************************************
  937. Typed File Handling
  938. *****************************************************************************}
  939. {$i typefile.inc}
  940. {*****************************************************************************
  941. Text File Handling
  942. *****************************************************************************}
  943. {$i text.inc}
  944. {*****************************************************************************
  945. Directory Handling
  946. *****************************************************************************}
  947. procedure mkdir(const s : string);[IOCheck];
  948. var
  949. buffer : array[0..255] of char;
  950. begin
  951. If InOutRes <> 0 then exit;
  952. move(s[1],buffer,length(s));
  953. buffer[length(s)]:=#0;
  954. asm
  955. move.l a6,d6
  956. { we must load the parameters BEFORE setting up the }
  957. { OS call with a6 }
  958. lea buffer,a0
  959. move.l a0,d1
  960. move.l _DosBase,a6
  961. jsr _LVOCreateDir(a6)
  962. tst.l d0
  963. bne @noerror
  964. jsr _LVOIoErr(a6)
  965. move.w d0,errno
  966. bra @end
  967. @noerror:
  968. { Now we must unlock the directory }
  969. { d0 = lock returned by create dir }
  970. move.l d0,d1
  971. jsr _LVOUnlock(a6)
  972. @end:
  973. { restore base pointer }
  974. move.l d6,a6
  975. end;
  976. If errno <> 0 then
  977. Error2InOut;
  978. end;
  979. procedure rmdir(const s : string);[IOCheck];
  980. var
  981. buffer : array[0..255] of char;
  982. begin
  983. If InOutRes <> 0 then exit;
  984. move(s[1],buffer,length(s));
  985. buffer[length(s)]:=#0;
  986. do_erase(buffer);
  987. end;
  988. procedure chdir(const s : string);[IOCheck];
  989. var
  990. buffer : array[0..255] of char;
  991. alock : longint;
  992. FIB :pFileInfoBlock;
  993. begin
  994. If InOutRes <> 0 then exit;
  995. if s = '..' then
  996. Begin
  997. end;
  998. alock := 0;
  999. fib:=nil;
  1000. new(fib);
  1001. move(s[1],buffer,length(s));
  1002. buffer[length(s)]:=#0;
  1003. { Changing the directory is a pretty complicated affair }
  1004. { 1) Obtain a lock on the directory }
  1005. { 2) CurrentDir the lock }
  1006. asm
  1007. lea buffer,a0
  1008. move.l a0,d1 { pointer to buffer in d1 }
  1009. move.l d2,-(sp) { save d2 register }
  1010. move.l #-2,d2 { ACCESS_READ lock }
  1011. move.l a6,d6 { Save base pointer }
  1012. move.l _DosBase,a6
  1013. jsr _LVOLock(a6){ Lock the directory }
  1014. move.l (sp)+,d2 { Restore d2 register }
  1015. tst.l d0 { zero = error! }
  1016. bne @noerror
  1017. jsr _LVOIoErr(a6)
  1018. move.w d0,errno
  1019. move.l d6,a6 { reset base pointer }
  1020. bra @End
  1021. @noerror:
  1022. move.l d6,a6 { reset base pointer }
  1023. move.l d0,alock { save the lock }
  1024. @End:
  1025. end;
  1026. If errno <> 0 then
  1027. Begin
  1028. Error2InOut;
  1029. exit;
  1030. end;
  1031. if (Examine(alock, fib^) = TRUE) AND (fib^.fib_DirEntryType > 0) then
  1032. Begin
  1033. alock := CurrentDir(alock);
  1034. if OrigDir = 0 then
  1035. Begin
  1036. OrigDir := alock;
  1037. alock := 0;
  1038. end;
  1039. end;
  1040. if alock <> 0 then
  1041. Unlock(alock);
  1042. if assigned(fib) then dispose(fib);
  1043. end;
  1044. Procedure GetCwd(var path: string);
  1045. var
  1046. lock: longint;
  1047. fib: PfileInfoBlock;
  1048. len : integer;
  1049. newlock : longint;
  1050. elen : integer;
  1051. Process : PProcess;
  1052. Begin
  1053. len := 0;
  1054. path := '';
  1055. fib := nil;
  1056. { By using a pointer instead of a local variable}
  1057. { we are assured that the pointer is aligned on }
  1058. { a dword boundary. }
  1059. new(fib);
  1060. Process := FindTask(nil);
  1061. if (process^.pr_Task.tc_Node.ln_Type = NT_TASK) then
  1062. Begin
  1063. path:='';
  1064. exit;
  1065. end;
  1066. lock := DupLock(process^.pr_CurrentDir);
  1067. if (Lock = 0) then
  1068. Begin
  1069. path:='';
  1070. exit;
  1071. end;
  1072. While (lock <> 0) and (Examine(lock,FIB^) = TRUE) do
  1073. Begin
  1074. elen := strlen(fib^.fib_FileName);
  1075. if (len + elen + 2 > 255) then
  1076. break;
  1077. newlock := ParentDir(lock);
  1078. if (len <> 0) then
  1079. Begin
  1080. if (newlock <> 0) then
  1081. path:='/'+path
  1082. else
  1083. path:=':'+path;
  1084. path:=strpas(fib^.fib_FileName)+path;
  1085. Inc(len);
  1086. end
  1087. else
  1088. Begin
  1089. path:=strpas(fib^.fib_Filename);
  1090. if (newlock = 0) then
  1091. path:=path+':';
  1092. end;
  1093. len := len + elen;
  1094. UnLock(lock);
  1095. lock := newlock;
  1096. end;
  1097. if (lock <> 0) then
  1098. Begin
  1099. UnLock(lock);
  1100. path := '';
  1101. end;
  1102. if assigned(fib) then dispose(fib);
  1103. end;
  1104. procedure getdir(drivenr : byte;var dir : string);
  1105. begin
  1106. GetCwd(dir);
  1107. If errno <> 0 then
  1108. Error2InOut;
  1109. end;
  1110. {*****************************************************************************
  1111. SystemUnit Initialization
  1112. *****************************************************************************}
  1113. Procedure Startup; Assembler;
  1114. asm
  1115. move.l a6,d6 { save a6 }
  1116. move.l (4),a6 { get ExecBase pointer }
  1117. move.l a6,_ExecBase
  1118. suba.l a1,a1
  1119. jsr _LVOFindTask(a6)
  1120. move.l d0,a0
  1121. { Check the stack value }
  1122. { are we running from a CLI? }
  1123. tst.l 172(a0) { 172 = pr_CLI }
  1124. bne @fromCLI
  1125. { we do not support Workbench yet .. }
  1126. move.l d6,a6 { restore a6 }
  1127. move.l #1,d0
  1128. jsr HALT_ERROR
  1129. @fromCLI:
  1130. { Open the following libraries: }
  1131. { Intuition.library }
  1132. { dos.library }
  1133. moveq.l #0,d0
  1134. move.l intuitionname,a1 { directly since it is a pchar }
  1135. jsr _LVOOpenLibrary(a6)
  1136. move.l d0,_IntuitionBase
  1137. beq @exitprg
  1138. moveq.l #0,d0
  1139. move.l utilityname,a1 { directly since it is a pchar }
  1140. jsr _LVOOpenLibrary(a6)
  1141. move.l d0,_UtilityBase
  1142. beq @exitprg
  1143. moveq.l #0,d0
  1144. move.l dosname,a1 { directly since it is a pchar }
  1145. jsr _LVOOpenLibrary(a6)
  1146. move.l d0,_DOSBase
  1147. beq @exitprg
  1148. { Find standard input and output }
  1149. { for CLI }
  1150. @OpenFiles:
  1151. move.l _DOSBase,a6
  1152. jsr _LVOInput(a6) { get standard in }
  1153. move.l d0, StdInputHandle { save standard Input handle }
  1154. { move.l d0,d1 }{ set up for next call }
  1155. { jsr _LVOIsInteractive(a6)}{ is it interactive? }
  1156. { move.l #_Input,a0 }{ get file record again }
  1157. { move.b d0,INTERACTIVE(a0) }{ set flag }
  1158. { beq StdInNotInteractive }{ skip this if not interactive }
  1159. { move.l BUFFER(a0),a1 }{ get buffer address }
  1160. { add.l #1,a1 }{ make end one byte further on }
  1161. { move.l a1,MAX(a0) }{ set buffer size }
  1162. { move.l a1,CURRENT(a0) }{ will need a read }
  1163. bra @OpenStdOutput
  1164. @StdInNotInteractive
  1165. { jsr _p%FillBuffer } { fill the buffer }
  1166. @OpenStdOutput
  1167. jsr _LVOOutput(a6) { get ouput file handle }
  1168. move.l d0,StdOutputHandle { get file record }
  1169. bra @startupend
  1170. { move.l d0,d1 } { set up for call }
  1171. { jsr _LVOIsInteractive(a6) } { is it interactive? }
  1172. { move.l #_Output,a0 } { get file record }
  1173. { move.b d0,INTERACTIVE(a0)} { set flag }
  1174. @exitprg:
  1175. move.l d6,a6 { restore a6 }
  1176. move.l #219,d0
  1177. jsr HALT_ERROR
  1178. @startupend:
  1179. move.l d6,a6 { restore a6 }
  1180. end;
  1181. begin
  1182. errno:= 0;
  1183. { Initial state is on -- in case of RunErrors before the i/o handles are }
  1184. { ok. }
  1185. Initial:=TRUE;
  1186. { Initialize ExitProc }
  1187. ExitProc:=Nil;
  1188. Startup;
  1189. { to test stack depth }
  1190. loweststack:=maxlongint;
  1191. { Setup heap }
  1192. InitHeap;
  1193. { Setup stdin, stdout and stderr }
  1194. OpenStdIO(Input,fmInput,StdInputHandle);
  1195. OpenStdIO(Output,fmOutput,StdOutputHandle);
  1196. { The Amiga does not seem to have a StdError }
  1197. { handle, therefore make the StdError handle }
  1198. { equal to the StdOutputHandle. }
  1199. StdErrorHandle := StdOutputHandle;
  1200. OpenStdIO(StdErr,fmOutput,StdErrorHandle);
  1201. { Now Handles and function handlers are setup }
  1202. { correctly. }
  1203. Initial:=FALSE;
  1204. { Reset IO Error }
  1205. InOutRes:=0;
  1206. { Startup }
  1207. { Only AmigaOS v2.04 or greater is supported }
  1208. If KickVersion < 36 then
  1209. Begin
  1210. WriteLn('v36 or greater of Kickstart required.');
  1211. Halt(1);
  1212. end;
  1213. argc:=GetParamCount(args);
  1214. OrigDir := 0;
  1215. end.
  1216. {
  1217. $Log$
  1218. Revision 1.8 1998-07-13 12:32:18 carl
  1219. * do_truncate works, some cleanup
  1220. Revision 1.6 1998/07/02 12:37:52 carl
  1221. * IOCheck for chdir,rmdir and mkdir as in TP
  1222. Revision 1.5 1998/07/01 14:30:56 carl
  1223. * forgot that includes are case sensitive
  1224. Revision 1.4 1998/07/01 14:13:50 carl
  1225. * do_open bugfix
  1226. * correct conversion of Amiga error codes to TP error codes
  1227. * InoutRes word bugfix
  1228. * parameter counting fixed
  1229. * new stack checking implemented
  1230. + IOCheck for chdir,rmdir,getdir and rmdir
  1231. * do_filepos was wrong
  1232. + chdir correctly implemented
  1233. * getdir correctly implemented
  1234. Revision 1.1.1.1 1998/03/25 11:18:47 root
  1235. * Restored version
  1236. Revision 1.14 1998/03/21 04:20:09 carl
  1237. * correct ExecBase pointer (from Nils Sjoholm)
  1238. * correct OpenLibrary vector (from Nils Sjoholm)
  1239. Revision 1.13 1998/03/14 21:34:32 carl
  1240. * forgot to save a6 in Startup routine
  1241. Revision 1.12 1998/02/24 21:19:42 carl
  1242. *** empty log message ***
  1243. Revision 1.11 1998/02/23 02:22:49 carl
  1244. * bugfix if linking problems
  1245. Revision 1.9 1998/02/06 16:34:32 carl
  1246. + do_open is now standard with other platforms
  1247. Revision 1.8 1998/02/02 15:01:45 carl
  1248. * fixed bug with opening library versions (from Nils Sjoholm)
  1249. Revision 1.7 1998/01/31 19:35:19 carl
  1250. + added opening of utility.library
  1251. Revision 1.6 1998/01/29 23:20:54 peter
  1252. - Removed Backslash convert
  1253. Revision 1.5 1998/01/27 10:55:04 peter
  1254. * Amiga uses / not \, so change AllowSlash -> AllowBackSlash
  1255. Revision 1.4 1998/01/25 21:53:20 peter
  1256. + Universal Handles support for StdIn/StdOut/StdErr
  1257. * Updated layout of sysamiga.pas
  1258. Revision 1.3 1998/01/24 21:09:53 carl
  1259. + added missing input/output function pointers
  1260. Revision 1.2 1998/01/24 14:08:25 carl
  1261. * RunError 217 --> RunError 219 (cannot open lib)
  1262. + Standard Handle names implemented
  1263. Revision 1.1 1998/01/24 05:12:15 carl
  1264. + initial revision, some stuff still missing though.
  1265. (and as you might imagine ... untested :))
  1266. }