浏览代码

+ system unit name change

Tomas Hajny 24 年之前
父节点
当前提交
e4aa3afcbb
共有 5 个文件被更改,包括 2835 次插入2716 次删除
  1. 1 1912
      rtl/amiga/sysamiga.pas
  2. 1915 0
      rtl/amiga/system.pas
  3. 1 804
      rtl/atari/sysatari.pas
  4. 815 0
      rtl/atari/system.pas
  5. 103 0
      rtl/palmos/system.pp

+ 1 - 1912
rtl/amiga/sysamiga.pas

@@ -1,1912 +1 @@
-{
-    $Id$
-    This file is part of the Free Pascal run time library.
-    Copyright (c) 1999-2000 by Carl Eric Codere
-    Some parts taken from
-       Marcel Timmermans - Modula 2 Compiler
-       Nils Sjoholm - Amiga porter
-       Matthew Dillon - Dice C (with his kind permission)
-          [email protected]
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- **********************************************************************}
-unit sysamiga;
-
-{--------------------------------------------------------------------}
-{ LEFT TO DO:                                                        }
-{--------------------------------------------------------------------}
-{ o GetDir with different drive numbers                              }
-{--------------------------------------------------------------------}
-
-{$I os.inc}
-
-{ AmigaOS uses character #10 as eoln only }
-{$DEFINE SHORT_LINEBREAK}
-
-  interface
-
-    { used for single computations }
-    const BIAS4 = $7f-1;
-
-    {$I systemh.inc}
-
-    {$I heaph.inc}
-
-const
-  UnusedHandle    : longint = -1;
-  StdInputHandle  : longint = 0;
-  StdOutputHandle : longint = 0;
-  StdErrorHandle  : longint = 0;
-
- _ExecBase:longint = $4;
- _WorkbenchMsg : longint = 0;
-
- _IntuitionBase : pointer = nil;       { intuition library pointer }
- _DosBase       : pointer = nil;       { DOS library pointer       }
- _UtilityBase   : pointer = nil;       { utiity library pointer    }
-
- { Required for crt unit }
-  function do_read(h,addr,len : longint) : longint;
-  function do_write(h,addr,len : longint) : longint;
-
-
-
-
-
-  implementation
-
- const
-
-   intuitionname : pchar = 'intuition.library';
-   dosname : pchar = 'dos.library';
-   utilityname : pchar = 'utility.library';
-   argc : longint = 0;
-   { AmigaOS does not autoamtically deallocate memory on program termination }
-   { therefore we have to handle this manually. This is a list of allocated  }
-   { pointers from the OS, we cannot use a linked list, because the linked   }
-   { list itself uses the HEAP!                                              }
-   pointerlist : array[1..8] of longint =
-    (0,0,0,0,0,0,0,0);
-
-
-    {$I exec.inc}
-
-  TYPE
-    TDateStamp = packed record
-        ds_Days         : Longint;      { Number of days since Jan. 1, 1978 }
-        ds_Minute       : Longint;      { Number of minutes past midnight }
-        ds_Tick         : Longint;      { Number of ticks past minute }
-    end;
-    PDateStamp = ^TDateStamp;
-
-
-    PFileInfoBlock = ^TfileInfoBlock;
-    TFileInfoBlock = packed record
-        fib_DiskKey     : Longint;
-        fib_DirEntryType : Longint;
-                        { Type of Directory. If < 0, then a plain file.
-                          If > 0 a directory }
-        fib_FileName    : Array [0..107] of Char;
-                        { Null terminated. Max 30 chars used for now }
-        fib_Protection  : Longint;
-                        { bit mask of protection, rwxd are 3-0. }
-        fib_EntryType   : Longint;
-        fib_Size        : Longint;      { Number of bytes in file }
-        fib_NumBlocks   : Longint;      { Number of blocks in file }
-        fib_Date        : TDateStamp; { Date file last changed }
-        fib_Comment     : Array [0..79] of Char;
-                        { Null terminated comment associated with file }
-        fib_Reserved    : Array [0..35] of Char;
-    end;
-
-
-    TProcess = packed record
-        pr_Task         : TTask;
-        pr_MsgPort      : TMsgPort;      { This is BPTR address from DOS functions  }
-{126}   pr_Pad          : Word;         { Remaining variables on 4 byte boundaries }
-{128}   pr_SegList      : Pointer;      { Array of seg lists used by this process  }
-{132}   pr_StackSize    : Longint;      { Size of process stack in bytes            }
-{136}   pr_GlobVec      : Pointer;      { Global vector for this process (BCPL)    }
-{140}   pr_TaskNum      : Longint;      { CLI task number of zero if not a CLI      }
-{144}   pr_StackBase    : BPTR;         { Ptr to high memory end of process stack  }
-{148}   pr_Result2      : Longint;      { Value of secondary result from last call }
-{152}   pr_CurrentDir   : BPTR;         { Lock associated with current directory   }
-{156}   pr_CIS          : BPTR;         { Current CLI Input Stream                  }
-{160}   pr_COS          : BPTR;         { Current CLI Output Stream                 }
-{164}   pr_ConsoleTask  : Pointer;      { Console handler process for current window}
-{168}   pr_FileSystemTask : Pointer;    { File handler process for current drive   }
-{172}   pr_CLI          : BPTR;         { pointer to ConsoleLineInterpreter         }
-        pr_ReturnAddr   : Pointer;      { pointer to previous stack frame           }
-        pr_PktWait      : Pointer;      { Function to be called when awaiting msg  }
-        pr_WindowPtr    : Pointer;      { Window for error printing }
-        { following definitions are new with 2.0 }
-        pr_HomeDir      : BPTR;         { Home directory of executing program      }
-        pr_Flags        : Longint;      { flags telling dos about process          }
-        pr_ExitCode     : Pointer;      { code to call on exit of program OR NULL  }
-        pr_ExitData     : Longint;      { Passed as an argument to pr_ExitCode.    }
-        pr_Arguments    : PChar;        { Arguments passed to the process at start }
-        pr_LocalVars    : TMinList;      { Local environment variables             }
-        pr_ShellPrivate : Longint;      { for the use of the current shell         }
-        pr_CES          : BPTR;         { Error stream - IF NULL, use pr_COS       }
-    end;
-    PProcess = ^TProcess;
-
-  { AmigaOS does not automatically close opened files on exit back to  }
-  { the operating system, therefore as a precuation we close all files }
-  { manually on exit.                                                  }
-  PFileList = ^TFileList;
-  TFileList = record { no packed, must be correctly aligned }
-   Handle: longint;      { Handle to file    }
-   next: pfilelist;      { Next file in list }
-   closed: boolean;      { TRUE=file already closed }
-  end;
-
-
-
-
-    Const
-     CTRL_C               = 20;      { Error code on CTRL-C press }
-     SIGBREAKF_CTRL_C     = $1000;   { CTRL-C signal flags }
-
-    _LVOFindTask          = -294;
-    _LVOWaitPort          = -384;
-    _LVOGetMsg            = -372;
-    _LVOOpenLibrary       = -552;
-    _LVOCloseLibrary      = -414;
-    _LVOClose             = -36;
-    _LVOOpen              = -30;
-    _LVOIoErr             = -132;
-    _LVOSeek              = -66;
-    _LVODeleteFile        = -72;
-    _LVORename            = -78;
-    _LVOWrite             = -48;
-    _LVORead              = -42;
-    _LVOCreateDir         = -120;
-    _LVOSetCurrentDirName = -558;
-    _LVOGetCurrentDirName = -564;
-    _LVOInput             = -54;
-    _LVOOutput            = -60;
-    _LVOUnLock            = -90;
-    _LVOLock              = -84;
-    _LVOCurrentDir        = -126;
-
-    _LVONameFromLock      = -402;
-    _LVONameFromFH        = -408;
-    _LVOGetProgramName    = -576;
-    _LVOGetProgramDir     = -600;
-    _LVODupLock           =  -96;
-    _LVOExamine           = -102;
-    _LVOParentDir         = -210;
-    _LVOSetFileSize       = -456;
-    _LVOSetSignal         = -306;
-    _LVOAllocVec          = -684;
-    _LVOFreeVec           = -690;
-
-
-      { Errors from IoErr(), etc. }
-      ERROR_NO_FREE_STORE              = 103;
-      ERROR_TASK_TABLE_FULL            = 105;
-      ERROR_BAD_TEMPLATE               = 114;
-      ERROR_BAD_NUMBER                 = 115;
-      ERROR_REQUIRED_ARG_MISSING       = 116;
-      ERROR_KEY_NEEDS_ARG              = 117;
-      ERROR_TOO_MANY_ARGS              = 118;
-      ERROR_UNMATCHED_QUOTES           = 119;
-      ERROR_LINE_TOO_LONG              = 120;
-      ERROR_FILE_NOT_OBJECT            = 121;
-      ERROR_INVALID_RESIDENT_LIBRARY   = 122;
-      ERROR_NO_DEFAULT_DIR             = 201;
-      ERROR_OBJECT_IN_USE              = 202;
-      ERROR_OBJECT_EXISTS              = 203;
-      ERROR_DIR_NOT_FOUND              = 204;
-      ERROR_OBJECT_NOT_FOUND           = 205;
-      ERROR_BAD_STREAM_NAME            = 206;
-      ERROR_OBJECT_TOO_LARGE           = 207;
-      ERROR_ACTION_NOT_KNOWN           = 209;
-      ERROR_INVALID_COMPONENT_NAME     = 210;
-      ERROR_INVALID_LOCK               = 211;
-      ERROR_OBJECT_WRONG_TYPE          = 212;
-      ERROR_DISK_NOT_VALIDATED         = 213;
-      ERROR_DISK_WRITE_PROTECTED       = 214;
-      ERROR_RENAME_ACROSS_DEVICES      = 215;
-      ERROR_DIRECTORY_NOT_EMPTY        = 216;
-      ERROR_TOO_MANY_LEVELS            = 217;
-      ERROR_DEVICE_NOT_MOUNTED         = 218;
-      ERROR_SEEK_ERROR                 = 219;
-      ERROR_COMMENT_TOO_BIG            = 220;
-      ERROR_DISK_FULL                  = 221;
-      ERROR_DELETE_PROTECTED           = 222;
-      ERROR_WRITE_PROTECTED            = 223;
-      ERROR_READ_PROTECTED             = 224;
-      ERROR_NOT_A_DOS_DISK             = 225;
-      ERROR_NO_DISK                    = 226;
-      ERROR_NO_MORE_ENTRIES            = 232;
-      { added for 1.4 }
-      ERROR_IS_SOFT_LINK               = 233;
-      ERROR_OBJECT_LINKED              = 234;
-      ERROR_BAD_HUNK                   = 235;
-      ERROR_NOT_IMPLEMENTED            = 236;
-      ERROR_RECORD_NOT_LOCKED          = 240;
-      ERROR_LOCK_COLLISION             = 241;
-      ERROR_LOCK_TIMEOUT               = 242;
-      ERROR_UNLOCK_ERROR               = 243;
-
-
-
-    var
-      Initial: boolean;           { Have successfully opened Std I/O   }
-      errno : word;               { AmigaOS IO Error number            }
-      FileList : pFileList;       { Linked list of opened files        }
-      {old_exit: Pointer; not needed anymore }
-      FromHalt : boolean;
-      OrigDir : Longint;   { Current lock on original startup directory }
-
-    {$I system.inc}
-    {$I lowmath.inc}
-
-
-
-
-  { ************************ AMIGAOS STUB ROUTINES ************************* }
-
-  procedure DateStamp(var ds : tDateStamp);
-  begin
-   asm
-      MOVE.L  A6,-(A7)
-      MOVE.L  ds,d1
-      { LAST THING TO SETUP SHOULD BE A6, otherwise you can }
-      { not accept local variable, nor any parameters! :)   }
-      MOVE.L  _DOSBase,A6
-      JSR -192(A6)
-      MOVE.L  (A7)+,A6
-  end;
- end;
-
-
-
-  { UNLOCK the BPTR pointed to in L }
-  Procedure Unlock(alock: longint);
-  Begin
-    asm
-     move.l  alock,d1
-     move.l  a6,d6           { save base pointer    }
-     move.l   _DosBase,a6
-     jsr     _LVOUnlock(a6)
-     move.l  d6,a6           { restore base pointer }
-    end;
-  end;
-
-  { Change to the directory pointed to in the lock }
-  Function CurrentDir(alock : longint) : longint;
-  Begin
-    asm
-      move.l  alock,d1
-      move.l  a6,d6           { save base pointer    }
-      move.l  _DosBase,a6
-      jsr     _LVOCurrentDir(a6)
-      move.l  d6,a6           { restore base pointer }
-      move.l  d0,@Result
-    end;
-  end;
-
-  { Duplicate a lock }
-  Function DupLock(alock: longint): Longint;
-   Begin
-     asm
-       move.l  alock,d1
-       move.l  a6,d6           { save base pointer    }
-       move.l  _DosBase,a6
-       jsr     _LVODupLock(a6)
-       move.l  d6,a6           { restore base pointer }
-       move.l  d0,@Result
-     end;
-   end;
-
-  { Returns a lock on the directory was loaded from }
-  Function GetProgramLock: longint;
-  Begin
-   asm
-       move.l  a6,d6           { save base pointer    }
-       move.l  _DosBase,a6
-       jsr     _LVOGetProgramDir(a6)
-       move.l  d6,a6           { restore base pointer }
-       move.l  d0,@Result
-   end;
-  end;
-
-
-
-  Function Examine(alock :longint; var fib: TFileInfoBlock) : Boolean;
-  Begin
-    asm
-       move.l  d2,-(sp)
-       move.l  fib,d2         { pointer to FIB        }
-       move.l  alock,d1
-       move.l  a6,d6           { save base pointer    }
-       move.l  _DosBase,a6
-       jsr     _LVOExamine(a6)
-       move.l  d6,a6           { restore base pointer }
-       tst.l   d0
-       bne     @success
-       bra     @end
-    @success:
-       move.b  #1,d0
-    @end:
-       move.b  d0,@Result
-       move.l  (sp)+,d2
-    end;
-  end;
-
-  { Returns the parent directory of a lock }
-  Function ParentDir(alock : longint): longint;
-   Begin
-     asm
-       move.l  alock,d1
-       move.l  a6,d6           { save base pointer    }
-       move.l  _DosBase,a6
-       jsr     _LVOParentDir(a6)
-       move.l  d6,a6           { restore base pointer }
-       move.l  d0,@Result
-     end;
-   end;
-
-
-   Function FindTask(p : PChar): PProcess;
-   Begin
-    asm
-         move.l  a6,d6              { Save base pointer    }
-         move.l  p,d0
-         move.l  d0,a1
-         move.l  _ExecBase,a6
-         jsr     _LVOFindTask(a6)
-         move.l  d6,a6              { Restore base pointer }
-         move.l  d0,@Result
-    end;
-   end;
-
-
-{$S-}
-    Procedure stack_check; assembler;
-    { Check for local variable allocation }
-    { On Entry -> d0 : size of local stack we are trying to allocate }
-     asm
-      XDEF STACKCHECK
-        move.l  sp,d1            { get value of stack pointer            }
-
-        { We must add some security, because Writing the RunError strings }
-        { requires a LOT of stack space (at least 1030 bytes!)            }
-        add.l   #2048,d0
-        sub.l   d0,d1            {  sp - stack_size                      }
-
-        move.l  _ExecBase,a0
-        move.l  276(A0),A0       { ExecBase.thisTask }
-        { if allocated stack_pointer - splower <= 0 then stack_ovf       }
-        cmp.l   58(A0),D1        { Task.SpLower      }
-        bgt     @Ok
-        move.l  #202,d0
-        jsr     HALT_ERROR       { stack overflow    }
-    @Ok:
-   end;
-
-
-   { This routine from EXEC determines if the Ctrl-C key has }
-   { been used since the last call to I/O routines.          }
-   { Use to halt the program.                                }
-   { Returns the state of the old signals.                   }
-   Function SetSignal(newSignal: longint; SignalMask: longint): longint;
-   Begin
-     asm
-       move.l  newSignal,d0
-       move.l  SignalMask,d1
-       move.l  a6,d6          { save Base pointer into scratch register }
-       move.l  _ExecBase,a6
-       jsr     _LVOSetSignal(a6)
-       move.l  d6,a6
-       move.l  d0,@Result
-     end;
-   end;
-
-
-   Function AllocVec(bytesize: longint; attributes: longint):longint;
-   Begin
-     asm
-       move.l  bytesize,d0
-       move.l  attributes,d1
-       move.l  a6,d6          { save Base pointer into scratch register }
-       move.l  _ExecBase,a6
-       jsr     _LVOAllocVec(a6)
-       move.l  d6,a6
-       move.l  d0,@Result
-     end;
-   end;
-
-
-   Procedure FreeVec(p: longint);
-   Begin
-     asm
-       move.l  p,a1
-       move.l  a6,d6          { save Base pointer into scratch register }
-       move.l  _ExecBase,a6
-       jsr     _LVOFreeVec(a6)
-       move.l  d6,a6
-     end;
-   end;
-
-
-   { Converts an AMIGAOS error code to a TP compatible error code }
-   Procedure Error2InOut;
-   Begin
-     case errno of
-       ERROR_BAD_NUMBER,
-       ERROR_ACTION_NOT_KNOWN,
-       ERROR_NOT_IMPLEMENTED : InOutRes := 1;
-
-       ERROR_OBJECT_NOT_FOUND : InOutRes := 2;
-       ERROR_DIR_NOT_FOUND :  InOutRes := 3;
-
-       ERROR_DISK_WRITE_PROTECTED : InOutRes := 150;
-
-       ERROR_OBJECT_WRONG_TYPE : InOutRes := 151;
-
-       ERROR_OBJECT_EXISTS,
-       ERROR_DELETE_PROTECTED,
-       ERROR_WRITE_PROTECTED,
-       ERROR_READ_PROTECTED,
-       ERROR_OBJECT_IN_USE,
-       ERROR_DIRECTORY_NOT_EMPTY : InOutRes := 5;
-
-       ERROR_NO_MORE_ENTRIES : InOutRes := 18;
-
-       ERROR_RENAME_ACROSS_DEVICES : InOutRes := 17;
-
-       ERROR_DISK_FULL : InOutRes := 101;
-
-       ERROR_INVALID_RESIDENT_LIBRARY : InoutRes := 153;
-       ERROR_BAD_HUNK : InOutRes := 153;
-
-       ERROR_NOT_A_DOS_DISK : InOutRes := 157;
-
-       ERROR_NO_DISK,
-       ERROR_DISK_NOT_VALIDATED,
-       ERROR_DEVICE_NOT_MOUNTED : InOutRes := 152;
-
-       ERROR_SEEK_ERROR : InOutRes := 156;
-
-       ERROR_LOCK_COLLISION,
-       ERROR_LOCK_TIMEOUT,
-       ERROR_UNLOCK_ERROR,
-       ERROR_INVALID_LOCK,
-       ERROR_INVALID_COMPONENT_NAME,
-       ERROR_BAD_STREAM_NAME,
-       ERROR_FILE_NOT_OBJECT : InOutRes := 6;
-     else
-       InOutres := errno;
-     end;
-     errno:=0;
-   end;
-
-
-    procedure CloseLibrary(lib : pointer);
-    {  Close the library pointed to in lib }
-    Begin
-      asm
-         MOVE.L  A6,-(A7)
-         MOVE.L  lib,a1
-         MOVE.L  _ExecBase,A6
-         JSR     _LVOCloseLibrary(A6)
-         MOVE.L  (A7)+,A6
-      end;
-    end;
-
-
-   Function KickVersion: word; assembler;
-   asm
-     move.l  _ExecBase, a0       { Get Exec Base                           }
-     move.w  20(a0), d0          { Return version - version at this offset }
-   end;
-
-
-  { ************************ AMIGAOS SUPP ROUTINES ************************* }
-
-(*  Procedure CloseList(p: pFileList);*)
-  (***********************************************************************)
-  (* PROCEDURE CloseList                                                 *)
-  (*  Description: This routine each time the program is about to        *)
-  (*  terminate, it closes all opened file handles, as this is not       *)
-  (*  handled by the operating system.                                   *)
-  (*   p -> Start of linked list of opened files                         *)
-  (***********************************************************************)
-(*  var
-   hp: pFileList;
-   hp1: pFileList;
-   h: longint;
-  Begin
-   hp:=p;
-   while Assigned(hp) do
-    Begin
-      if NOT hp^.closed then
-       Begin
-        h:=hp^.handle;
-        if (h <> StdInputHandle) and (h <> StdOutputHandle) and (h <> StdErrorHandle) then
-        Begin
-          { directly close file here, it is faster then doing }
-          { it do_close.                                      }
-          asm
-            move.l  h,d1
-            move.l  a6,d6              { save a6 }
-            move.l  _DOSBase,a6
-            jsr     _LVOClose(a6)
-            move.l  d6,a6              { restore a6 }
-          end;
-        end;
-       end;
-      hp1:=hp;
-      hp:=hp^.next;
-      dispose(hp1);
-    end;
-  end;*)
-
-
-(* Procedure AddToList(var p: pFileList; h: longint);*)
-  (***********************************************************************)
-  (* PROCEDURE AddToList                                                 *)
-  (*  Description: Adds a node to the linked list of files.              *)
-  (*                                                                     *)
-  (*   p -> Start of File list linked list, if not allocated allocates   *)
-  (*        it for you.                                                  *)
-  (*   h -> handle of file to add                                        *)
-  (***********************************************************************)
-(*  var
-   hp: pFileList;
-   hp1: pFileList;
-  Begin
-    if p = nil then
-     Begin
-       new(p);
-       p^.handle:=h;
-       p^.closed := FALSE;
-       p^.next := nil;
-       exit;
-     end;
-     hp:=p;
-    { Find last list in entry }
-    while assigned(hp) do
-     Begin
-        if hp^.next = nil then break;
-        hp:=hp^.next;
-     end;
-    { Found last list in entry then add it to the list }
-    new(hp1);
-    hp^.next:=hp1;
-    hp1^.next:=nil;
-    hp1^.handle:=h;
-    hp1^.closed:=FALSE;
-  end;
-
-
-  Procedure SetClosedList(var p: pFileList; h: longint);
-  { Set the file flag to closed if the file is being closed }
-  var
-   hp: pFileList;
-  Begin
-    hp:=p;
-    while assigned(hp) do
-     Begin
-        if hp^.handle = h then
-         Begin
-           hp^.closed:=TRUE;
-           break;
-         end;
-        hp:=hp^.next;
-     end;
-  end;*)
-
-
-{*****************************************************************************
-                         System Dependent Exit code
-*****************************************************************************}
-  Procedure system_exit;
-    var
-     i: byte;
-    Begin
-        { We must remove the CTRL-C FALG here because halt }
-        { may call I/O routines, which in turn might call  }
-        { halt, so a recursive stack crash                 }
-        IF (SetSignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 THEN
-           SetSignal(0,SIGBREAKF_CTRL_C);
-         { Close remaining opened files }
-{         CloseList(FileList); }
-        if (OrigDir <> 0) then
-         Begin
-            Unlock(CurrentDir(OrigDir));
-            OrigDir := 0;
-         end;
-         { Is this a normal exit - YES, close libs }
-         IF NOT FromHalt then
-           Begin
-             { close the libraries }
-             If _UtilityBase <> nil then
-                 CloseLibrary(_UtilityBase);
-             If _DosBase <> nil then
-                 CloseLibrary(_DosBase);
-             If _IntuitionBase <> nil then
-                 CloseLibrary(_IntuitionBase);
-             _UtilityBase := nil;
-             _DosBase := nil;
-             _IntuitionBase := nil;
-           end;
-         { Dispose of extraneous allocated pointers }
-         for I:=1 to 8 do
-           Begin
-             if pointerlist[i] <> 0 then FreeVec(pointerlist[i]);
-           end;
-         { exitproc:=old_exit;obsolete }
-    end;
-
-
-    procedure halt(errnum : byte);
-      begin
-        { Indicate to the SYSTEM EXIT procedure that we are calling it }
-        { from halt, and that its library will be closed HERE and not  }
-        { in the exit procedure.                                       }
-        FromHalt:=TRUE;
-        { We must remove the CTRL-C FALG here because halt }
-        { may call I/O routines, which in turn might call  }
-        { halt, so a recursive stack crash                 }
-        IF (SetSignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 THEN
-           SetSignal(0,SIGBREAKF_CTRL_C);
-        { WE can only FLUSH the stdio   }
-        { if the handles have correctly }
-        { been set.                     }
-        { No exit procedures exist      }
-        { if in initial state           }
-        If NOT Initial then
-        Begin
-          do_exit;
-          flush(stderr);
-        end;
-        { close the libraries }
-        If _UtilityBase <> nil then
-           CloseLibrary(_UtilityBase);
-        If _DosBase <> nil then
-           CloseLibrary(_DosBase);
-        If _IntuitionBase <> nil then
-           CloseLibrary(_IntuitionBase);
-        _UtilityBase := nil;
-        _DosBase := nil;
-        _IntuitionBase := nil;
-         asm
-            clr.l   d0
-            move.b  errnum,d0
-            move.l  STKPTR,sp
-            rts
-         end;
-      end;
-
-
-
-  { ************************ PARAMCOUNT/PARAMSTR *************************** }
-
-      function paramcount : longint;
-      Begin
-        paramcount := argc;
-      end;
-
-
-      function args : pointer; assembler;
-      asm
-         move.l __ARGS,d0
-      end;
-
-   Function GetParamCount(const p: pchar): longint;
-   var
-    i: word;
-    count: word;
-   Begin
-    i:=0;
-    count:=0;
-    while p[count] <> #0 do
-     Begin
-       if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
-       Begin
-          i:=i+1;
-          while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
-           count:=count+1;
-       end;
-       if p[count] = #0 then break;
-       count:=count+1;
-     end;
-     GetParamCount:=longint(i);
-   end;
-
-
-   Function GetParam(index: word; const p : pchar): string;
-   { On Entry: index = string index to correct parameter  }
-   { On exit:  = correct character index into pchar array }
-   { Returns correct index to command line argument }
-   var
-    count: word;
-    localindex: word;
-    l: byte;
-    temp: string;
-   Begin
-     temp:='';
-     count := 0;
-     { first index is one }
-     localindex := 1;
-     l:=0;
-     While p[count] <> #0 do
-       Begin
-         if (p[count] <> ' ') and (p[count] <> #9) then
-           Begin
-             if localindex = index then
-              Begin
-               while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
-                Begin
-                  temp:=temp+p[count];
-                  l:=l+1;
-                  count:=count+1;
-                end;
-                temp[0]:=char(l);
-                GetParam:=temp;
-                exit;
-              end;
-             { Point to next argument in list }
-             while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
-               Begin
-                 count:=count+1;
-               end;
-             localindex:=localindex+1;
-           end;
-         if p[count] = #0 then break;
-         count:=count+1;
-       end;
-     GetParam:=temp;
-   end;
-
-
-    Function GetProgramDir : String;
-    var
-     s1: string;
-     alock: longint;
-     counter : byte;
-    Begin
-     FillChar(@s1,255,#0);
-     { GetLock of program directory }
-     asm
-            move.l  a6,d6              { save a6 }
-            move.l  _DOSBase,a6
-            jsr     _LVOGetProgramDir(a6)
-            move.l  d6,a6              { restore a6 }
-            move.l  d0,alock           { save the lock }
-     end;
-     if alock <> 0 then
-      Begin
-        { Get the name from the lock! }
-        asm
-            movem.l d2/d3,-(sp)        { save used registers             }
-            move.l  alock,d1
-            lea     s1,a0              { Get pointer to string!          }
-            move.l  a0,d2
-            add.l   #1,d2              { let  us point past the length byte! }
-            move.l  #255,d3
-            move.l  a6,d6              { save a6 }
-            move.l  _DOSBase,a6
-            jsr     _LVONameFromLock(a6)
-            move.l  d6,a6              { restore a6 }
-            movem.l (sp)+,d2/d3
-        end;
-        { no check out the length of the string }
-        counter := 1;
-        while s1[counter] <> #0 do
-           Inc(counter);
-        s1[0] := char(counter-1);
-        GetProgramDir := s1;
-      end
-     else
-      GetProgramDir := '';
-    end;
-
-
-    Function GetProgramName : string;
-    { Returns ONLY the program name }
-    { There seems to be a bug in v39 since if the program is not }
-    { called from its home directory the program name will also  }
-    { contain the path!                                          }
-    var
-     s1: string;
-     counter : byte;
-    Begin
-      FillChar(@s1,255,#0);
-      asm
-            move.l  d2,-(sp)           { Save used register      }
-            lea     s1,a0              { Get pointer to string!  }
-            move.l  a0,d1
-            add.l   #1,d1              { point to correct offset }
-            move.l  #255,d2
-            move.l  a6,d6              { save a6 }
-            move.l  _DOSBase,a6
-            jsr     _LVOGetProgramName(a6)
-            move.l  d6,a6              { restore a6 }
-            move.l  (sp)+,d2           { restore saved register }
-      end;
-        { no check out and assign the length of the string }
-        counter := 1;
-        while s1[counter] <> #0 do
-           Inc(counter);
-        s1[0] := char(counter-1);
-        { now remove any component path which should not be there }
-        for counter:=length(s1) downto 1 do
-          if (s1[counter] = '/') or (s1[counter] = ':') then break;
-        { readjust counterv to point to character }
-        if counter <> 1 then
-          Inc(counter);
-        GetProgramName:=copy(s1,counter,length(s1));
-    end;
-
-
-    function paramstr(l : longint) : string;
-      var
-       p : pchar;
-       s1 : string;
-      begin
-         {   -> Call AmigaOS GetProgramName                             }
-         if l = 0 then
-         Begin
-           s1 := GetProgramDir;
-           { If this is a root, then simply don't add '/' }
-           if s1[length(s1)] = ':' then
-              paramstr:=s1+GetProgramName
-           else
-              { add backslash directory }
-              paramstr:=s1+'/'+GetProgramName
-         end
-         else
-         if (l>0) and (l<=paramcount) then
-           begin
-             p:=args;
-             paramstr:=GetParam(word(l),p);
-           end
-         else paramstr:='';
-      end;
-
-  { ************************************************************************ }
-
-    procedure randomize;
-
-      var
-         hl : longint;
-         time : TDateStamp;
-      begin
-         DateStamp(time);
-         randseed:=time.ds_tick;
-      end;
-
-function getheapstart:pointer;assembler;
-asm
-        lea.l   HEAP,a0
-        move.l  a0,d0
-end;
-
-
-function getheapsize:longint;assembler;
-asm
-       move.l   HEAP_SIZE,d0
-end ['D0'];
-
-  { This routine is used to grow the heap.  }
-  { But here we do a trick, we say that the }
-  { heap cannot be regrown!                 }
-  function sbrk( size: longint): longint;
-  var
-  { on exit -1 = if fails.               }
-   p: longint;
-   i: byte;
-  Begin
-    p:=0;
-    { Is the pointer list full }
-    if pointerlist[8] <> 0 then
-    begin
-     { yes, then don't allocate and simply exit }
-     sbrk:=-1;
-     exit;
-    end;
-    { Allocate best available memory }
-    p:=AllocVec(size,0);
-    if p = 0 then
-     sbrk:=-1
-    else
-    Begin
-       i:=1;
-       { add it to the list of allocated pointers }
-       { first find the last pointer in the list  }
-       while (i < 8) and (pointerlist[i] <> 0) do
-         i:=i+1;
-       pointerlist[i]:=p;
-       sbrk:=p;
-    end;
-  end;
-
-
-
-{$I heap.inc}
-
-
-{****************************************************************************
-                          Low Level File Routines
- ****************************************************************************}
-
-procedure do_close(h : longint);
-{ We cannot check for CTRL-C because this routine will be called }
-{ on HALT to close all remaining opened files. Therefore no      }
-{ CTRL-C checking otherwise a recursive call might result!       }
-{$ifdef debug}
-var
-  buffer: array[0..255] of char;
-{$endif}
-begin
-  { check if the file handle is in the list }
-  { if so the put its field to closed       }
-{  SetClosedList(FileList,h);}
-{$ifdef debug}
-  asm
-     move.l  h,d1
-     move.l  a6,d6
-     move.l  d2,-(sp)
-     move.l  d3,-(sp)
-     lea     buffer,a0
-     move.l  a0,d2
-     move.l  #255,d3
-     move.l  _DosBase,a6
-     jsr     _LVONameFromFH(a6)
-     move.l  d6,a6
-     move.l  (sp)+,d3
-     move.l  (sp)+,d2
-  end;
-  WriteLn(Buffer);
-{$endif debug}
-  asm
-     move.l  h,d1
-     move.l  a6,d6              { save a6 }
-     move.l  _DOSBase,a6
-     jsr     _LVOClose(a6)
-     move.l  d6,a6              { restore a6 }
-  end;
-end;
-
-
-function do_isdevice(handle:longint):boolean;
-begin
-  if (handle=stdoutputhandle) or (handle=stdinputhandle) or
-  (handle=stderrorhandle) then
-    do_isdevice:=TRUE
-  else
-    do_isdevice:=FALSE;
-end;
-
-
-
-procedure do_erase(p : pchar);
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  asm
-           move.l  a6,d6               { save a6 }
-
-           move.l  p,d1
-           move.l  _DOSBase,a6
-           jsr     _LVODeleteFile(a6)
-           tst.l   d0                  { zero = failure }
-           bne     @noerror
-
-           jsr     _LVOIoErr(a6)
-           move.w  d0,errno
-
-         @noerror:
-           move.l  d6,a6               { restore a6 }
-  end;
-  if errno <> 0 then
-     Error2InOut;
-end;
-
-
-procedure do_rename(p1,p2 : pchar);
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  asm
-           move.l  a6,d6                  { save a6 }
-           move.l  d2,-(sp)               { save d2 }
-
-           move.l  p1,d1
-           move.l  p2,d2
-           move.l  _DOSBase,a6
-           jsr     _LVORename(a6)
-           move.l  (sp)+,d2               { restore d2 }
-           tst.l   d0
-           bne     @dosreend              { if zero = error }
-           jsr     _LVOIoErr(a6)
-           move.w  d0,errno
-         @dosreend:
-           move.l  d6,a6                  { restore a6 }
-  end;
-  if errno <> 0 then
-    Error2InOut;
-end;
-
-
-function do_write(h,addr,len : longint) : longint;
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  if len <= 0 then
-   Begin
-    do_write:=0;
-    exit;
-   end;
-  asm
-            move.l  a6,d6
-
-            movem.l d2/d3,-(sp)
-            move.l  h,d1             { we must of course set up the }
-            move.l  addr,d2          { parameters BEFORE getting    }
-            move.l  len,d3           { _DOSBase                     }
-            move.l  _DOSBase,a6
-            jsr     _LVOWrite(a6)
-            movem.l (sp)+,d2/d3
-
-            cmp.l   #-1,d0
-            bne     @doswrend              { if -1 = error }
-            jsr     _LVOIoErr(a6)
-            move.w  d0,errno
-            bra     @doswrend2
-          @doswrend:
-            { we must restore the base pointer before setting the result }
-            move.l  d6,a6
-            move.l  d0,@RESULT
-            bra     @end
-          @doswrend2:
-            move.l  d6,a6
-          @end:
-  end;
-  If errno <> 0 then
-    Error2InOut;
-end;
-
-
-function do_read(h,addr,len : longint) : longint;
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  if len <= 0 then
-  Begin
-     do_read:=0;
-     exit;
-  end;
-  asm
-            move.l  a6,d6
-
-            movem.l d2/d3,-(sp)
-            move.l  h,d1         { we must set up aparamters BEFORE }
-            move.l  addr,d2      { setting up a6 for the OS call    }
-            move.l  len,d3
-            move.l  _DOSBase,a6
-            jsr     _LVORead(a6)
-            movem.l (sp)+,d2/d3
-
-            cmp.l   #-1,d0
-            bne     @doswrend              { if -1 = error }
-            jsr     _LVOIoErr(a6)
-            move.w  d0,errno
-            bra     @doswrend2
-          @doswrend:
-            { to store a result for the function  }
-            { we must of course first get back the}
-            { base pointer!                       }
-            move.l  d6,a6
-            move.l  d0,@RESULT
-            bra     @end
-          @doswrend2:
-            move.l  d6,a6
-          @end:
-  end;
-  If errno <> 0 then
-    Error2InOut;
-end;
-
-
-function do_filepos(handle : longint) : longint;
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  asm
-             move.l  a6,d6
-
-             move.l  handle,d1
-             move.l  d2,-(sp)
-             move.l  d3,-(sp)              { save registers              }
-
-             clr.l   d2                    { offset 0 }
-             move.l  #0,d3                 { OFFSET_CURRENT }
-             move.l  _DOSBase,a6
-             jsr    _LVOSeek(a6)
-
-             move.l  (sp)+,d3              { restore registers }
-             move.l  (sp)+,d2
-             cmp.l   #-1,d0                { is there a file access error? }
-             bne     @noerr
-             jsr     _LVOIoErr(a6)
-             move.w  d0,errno
-             bra     @fposend
-      @noerr:
-             move.l  d6,a6                 { restore a6 }
-             move.l  d0,@Result
-             bra     @end
-      @fposend:
-             move.l  d6,a6                 { restore a6 }
-      @end:
-  end;
-  If errno <> 0 then
-    Error2InOut;
-end;
-
-
-procedure do_seek(handle,pos : longint);
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  asm
-             move.l  a6,d6
-
-             move.l  handle,d1
-             move.l  d2,-(sp)
-             move.l  d3,-(sp)              { save registers              }
-
-             move.l  pos,d2
-             { -1 }
-             move.l  #$ffffffff,d3          { OFFSET_BEGINNING }
-             move.l  _DOSBase,a6
-             jsr    _LVOSeek(a6)
-
-             move.l  (sp)+,d3              { restore registers }
-             move.l  (sp)+,d2
-             cmp.l   #-1,d0                { is there a file access error? }
-             bne     @noerr
-             jsr     _LVOIoErr(a6)
-             move.w  d0,errno
-             bra     @seekend
-      @noerr:
-      @seekend:
-             move.l  d6,a6                 { restore a6 }
-  end;
-  If errno <> 0 then
-    Error2InOut;
-end;
-
-
-function do_seekend(handle:longint):longint;
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  asm
-             { seek from end of file }
-             move.l  a6,d6
-
-             move.l  handle,d1
-             move.l  d2,-(sp)
-             move.l  d3,-(sp)              { save registers              }
-
-             clr.l   d2
-             move.l  #1,d3                 { OFFSET_END }
-             move.l  _DOSBase,a6
-             jsr    _LVOSeek(a6)
-
-             move.l  (sp)+,d3              { restore registers }
-             move.l  (sp)+,d2
-             cmp.l   #-1,d0                { is there a file access error? }
-             bne     @noerr
-             jsr     _LVOIoErr(a6)
-             move.w  d0,errno
-             bra     @seekend
-      @noerr:
-             move.l  d6,a6                 { restore a6 }
-             move.l  d0,@Result
-             bra     @end
-      @seekend:
-             move.l  d6,a6                 { restore a6 }
-      @end:
-  end;
-  If Errno <> 0 then
-    Error2InOut;
-end;
-
-
-function do_filesize(handle : longint) : longint;
-var
-  aktfilepos : longint;
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-    Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-    end;
-   aktfilepos:=do_filepos(handle);
-   { We have to do this two times, because seek returns the }
-   { OLD position                                           }
-   do_filesize:=do_seekend(handle);
-   do_filesize:=do_seekend(handle);
-   do_seek(handle,aktfilepos);
-end;
-
-
-procedure do_truncate (handle,pos:longint);
-begin
-      { Point to the end of the file }
-      { with the new size            }
-      asm
-      @noerr_one:                          { Seek a second time            }
-             move.l  a6,d6                 { Save base pointer             }
-
-             move.l  handle,d1
-             move.l  d2,-(sp)
-             move.l  d3,-(sp)              { save registers                }
-
-             move.l  pos,d2
-             move.l  #-1,d3                { Setup correct move type     }
-             move.l  _DOSBase,a6           { from beginning of file      }
-             jsr    _LVOSetFileSize(a6)
-
-             move.l  (sp)+,d3              { restore registers }
-             move.l  (sp)+,d2
-             cmp.l   #-1,d0                { is there a file access error? }
-             bne     @noerr
-             jsr     _LVOIoErr(a6)
-             move.w  d0,errno              { Global variable, so no need    }
-      @noerr:                              { to restore base pointer now    }
-             move.l  d6,a6                 { Restore base pointer           }
-      end;
-  If Errno <> 0 then
-    Error2InOut;
-end;
-
-
-procedure do_open(var f;p:pchar;flags:longint);
-{
-  filerec and textrec have both handle and mode as the first items so
-  they could use the same routine for opening/creating.
-  when (flags and $100)   the file will be append
-  when (flags and $1000)  the file will be truncate/rewritten
-  when (flags and $10000) there is no check for close (needed for textfiles)
-}
-var
-  i,j : longint;
-  oflags: longint;
-  path : string;
-  buffer : array[0..255] of char;
-  index : integer;
-  s : string;
-begin
- path:=strpas(p);
- for index:=1 to length(path) do
-   if path[index]='\' then path[index]:='/';
- { remove any dot characters and replace by their current }
- { directory equivalent.                                  }
- if pos('../',path) = 1 then
- { look for parent directory }
-    Begin
-       delete(path,1,3);
-       getdir(0,s);
-       j:=length(s);
-       while (s[j] <> '/') AND (s[j] <> ':') AND (j > 0 ) do
-         dec(j);
-       if j > 0 then
-         s:=copy(s,1,j);
-       path:=s+path;
-    end
- else
- if pos('./',path) = 1 then
- { look for current directory }
-    Begin
-       delete(path,1,2);
-       getdir(0,s);
-       if (s[length(s)] <> '/') and (s[length(s)] <> ':') then
-          s:=s+'/';
-       path:=s+path;
-    end;
-  move(path[1],buffer,length(path));
-  buffer[length(path)]:=#0;
- { close first if opened }
-  if ((flags and $10000)=0) then
-   begin
-     case filerec(f).mode of
-      fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
-      fmclosed : ;
-     else
-      begin
-        inoutres:=102; {not assigned}
-        exit;
-      end;
-     end;
-   end;
-{ reset file handle }
-  filerec(f).handle:=UnusedHandle;
-{ convert filemode to filerec modes }
-  { READ/WRITE on existing file }
-  { RESET/APPEND                }
-  oflags := 1005;
-  case (flags and 3) of
-   0 : begin
-         filerec(f).mode:=fminput;
-       end;
-   1 : filerec(f).mode:=fmoutput;
-   2 : filerec(f).mode:=fminout;
-  end;
-  { READ/WRITE mode, create file in all cases }
-  { REWRITE                                   }
-  if (flags and $1000)<>0 then
-   begin
-     filerec(f).mode:=fmoutput;
-     oflags := 1006;
-   end
-  else
-  { READ/WRITE mode on existing file }
-  { APPEND                           }
-   if (flags and $100)<>0 then
-    begin
-      filerec(f).mode:=fmoutput;
-      oflags := 1005;
-    end;
-{ empty name is special }
-  if p[0]=#0 then
-   begin
-     case filerec(f).mode of
-       fminput : filerec(f).handle:=StdInputHandle;
-      fmappend,
-      fmoutput : begin
-                   filerec(f).handle:=StdOutputHandle;
-                   filerec(f).mode:=fmoutput; {fool fmappend}
-                 end;
-     end;
-     exit;
-   end;
-         asm
-             move.l  a6,d6                  { save a6 }
-             move.l  d2,-(sp)
-             lea     buffer,a0
-             move.l  a0,d1
-             move.l  oflags,d2               { MODE_READWRITE }
-             move.l  _DOSBase,a6
-             jsr     _LVOOpen(a6)
-             tst.l   d0
-             bne     @noopenerror           { on zero an error occured }
-             jsr     _LVOIoErr(a6)
-             move.w  d0,errno
-             bra     @openend
-          @noopenerror:
-             move.l  (sp)+,d2
-             move.l  d6,a6                 { restore a6 }
-             move.l  d0,i                  { we need the base pointer to access this variable }
-             bra     @end
-          @openend:
-             move.l  d6,a6                 { restore a6 }
-             move.l  (sp)+,d2
-          @end:
-         end;
-(*    if Errno = 0 then*)
-    { No error, add file handle to linked list }
-    { this must be checked before the call to  }
-    { Error2InIOut since it resets Errno to 0  }
-(*      AddToList(FileList,i);*)
-    If Errno <> 0 then
-       Error2InOut;
-
-    filerec(f).handle:=i;
-    if (flags and $100)<>0 then
-       do_seekend(filerec(f).handle);
-
-end;
-
-{*****************************************************************************
-                           UnTyped File Handling
-*****************************************************************************}
-
-{$i file.inc}
-
-{*****************************************************************************
-                           Typed File Handling
-*****************************************************************************}
-
-{$i typefile.inc}
-
-{*****************************************************************************
-                           Text File Handling
-*****************************************************************************}
-
-{$i text.inc}
-
-{*****************************************************************************
-                           Directory Handling
-*****************************************************************************}
-
-procedure mkdir(const s : string);[IOCheck];
-var
-  buffer : array[0..255] of char;
-  j: Integer;
-  temp : string;
-begin
-  { We must check the Ctrl-C before IOChecking of course! }
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  If InOutRes <> 0 then exit;
-  temp:=s;
-  for j:=1 to length(temp) do
-    if temp[j] = '\' then temp[j] := '/';
-  move(temp[1],buffer,length(temp));
-  buffer[length(temp)]:=#0;
-  asm
-        move.l  a6,d6
-        { we must load the parameters BEFORE setting up the }
-        { OS call with a6                                   }
-        lea     buffer,a0
-        move.l  a0,d1
-        move.l  _DosBase,a6
-        jsr     _LVOCreateDir(a6)
-        tst.l   d0
-        bne     @noerror
-        jsr     _LVOIoErr(a6)
-        move.w  d0,errno
-        bra     @end
-@noerror:
-        { Now we must unlock the directory }
-        { d0 = lock returned by create dir }
-        move.l  d0,d1
-        jsr     _LVOUnlock(a6)
-@end:
-        { restore base pointer }
-        move.l  d6,a6
-  end;
-  If errno <> 0 then
-    Error2InOut;
-end;
-
-
-procedure rmdir(const s : string);[IOCheck];
-var
-  buffer : array[0..255] of char;
-  j : Integer;
-  temp : string;
-begin
-  { We must check the Ctrl-C before IOChecking of course! }
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  If InOutRes <> 0 then exit;
-  temp:=s;
-  for j:=1 to length(temp) do
-    if temp[j] = '\' then temp[j] := '/';
-  move(temp[1],buffer,length(temp));
-  buffer[length(temp)]:=#0;
-  do_erase(buffer);
-end;
-
-
-
-procedure chdir(const s : string);[IOCheck];
-var
-  buffer : array[0..255] of char;
-  alock : longint;
-  FIB :pFileInfoBlock;
-  j: integer;
-  temp : string;
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-   Begin
-     { Clear CTRL-C signal }
-     SetSignal(0,SIGBREAKF_CTRL_C);
-     Halt(CTRL_C);
-   end;
-  If InOutRes <> 0 then exit;
-  temp:=s;
-  for j:=1 to length(temp) do
-    if temp[j] = '\' then temp[j] := '/';
-  { Return parent directory }
-  if s = '..' then
-  Begin
-       getdir(0,temp);
-       j:=length(temp);
-       { Look through the previous paths }
-       while (temp[j] <> '/') AND (temp[j] <> ':') AND (j > 0 ) do
-         dec(j);
-       if j > 0 then
-         temp:=copy(temp,1,j);
-  end;
-  alock := 0;
-  fib:=nil;
-  new(fib);
-
-  move(temp[1],buffer,length(temp));
-  buffer[length(temp)]:=#0;
-  { Changing the directory is a pretty complicated affair }
-  {   1) Obtain a lock on the directory                   }
-  {   2) CurrentDir the lock                              }
-  asm
-    lea      buffer,a0
-    move.l   a0,d1      { pointer to buffer in d1  }
-    move.l   d2,-(sp)   { save d2 register         }
-    move.l   #-2,d2     { ACCESS_READ lock         }
-    move.l   a6,d6      { Save base pointer        }
-    move.l   _DosBase,a6
-    jsr      _LVOLock(a6){ Lock the directory      }
-    move.l   (sp)+,d2   { Restore d2 register      }
-    tst.l    d0         { zero = error!            }
-    bne      @noerror
-    jsr      _LVOIoErr(a6)
-    move.w   d0,errno
-    move.l   d6,a6       { reset base pointer       }
-    bra      @End
-  @noerror:
-    move.l   d6,a6       { reset base pointer       }
-    move.l   d0,alock    { save the lock            }
-  @End:
-  end;
-  If errno <> 0 then
-   Begin
-     Error2InOut;
-     exit;
-   end;
-  if (Examine(alock, fib^) = TRUE) AND (fib^.fib_DirEntryType > 0) then
-    Begin
-      alock := CurrentDir(alock);
-      if OrigDir = 0 then
-        Begin
-          OrigDir := alock;
-          alock := 0;
-        end;
-    end;
-  if alock <> 0 then
-    Unlock(alock);
-  if assigned(fib) then dispose(fib);
-end;
-
-
-
-
-  Procedure GetCwd(var path: string);
-   var
-     lock: longint;
-     fib: PfileInfoBlock;
-     len : integer;
-     newlock : longint;
-     elen : integer;
-     Process : PProcess;
-    Begin
-     len := 0;
-     path := '';
-     fib := nil;
-     { By using a pointer instead of a local variable}
-     { we are assured that the pointer is aligned on }
-     { a dword boundary.                             }
-     new(fib);
-     Process := FindTask(nil);
-     if (process^.pr_Task.tc_Node.ln_Type = NT_TASK) then
-       Begin
-         path:='';
-         exit;
-       end;
-     lock := DupLock(process^.pr_CurrentDir);
-     if (Lock = 0) then
-       Begin
-         path:='';
-         exit;
-       end;
-
-    While (lock <> 0) and (Examine(lock,FIB^) = TRUE) do
-    Begin
-         elen := strlen(fib^.fib_FileName);
-         if (len + elen + 2 > 255) then
-            break;
-         newlock := ParentDir(lock);
-         if (len <> 0) then
-          Begin
-            if (newlock <> 0) then
-               path:='/'+path
-            else
-               path:=':'+path;
-            path:=strpas(fib^.fib_FileName)+path;
-            Inc(len);
-          end
-         else
-          Begin
-            path:=strpas(fib^.fib_Filename);
-            if (newlock = 0) then
-             path:=path+':';
-          end;
-
-               len := len + elen;
-
-               UnLock(lock);
-               lock := newlock;
-    end;
-    if (lock <> 0) then
-    Begin
-            UnLock(lock);
-            path := '';
-    end;
-    if assigned(fib) then dispose(fib);
- end;
-
-
-procedure getdir(drivenr : byte;var dir : string);
-begin
-  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
-    Begin
-      { Clear CTRL-C signal }
-      SetSignal(0,SIGBREAKF_CTRL_C);
-      Halt(CTRL_C);
-    end;
-  GetCwd(dir);
-  If errno <> 0 then
-     Error2InOut;
-end;
-
-
-{*****************************************************************************
-                         SystemUnit Initialization
-*****************************************************************************}
-
-Procedure Startup; Assembler;
-asm
-    move.l  a6,d6         { save a6             }
-
-    move.l  (4),a6        { get ExecBase pointer }
-    move.l  a6,_ExecBase
-    suba.l  a1,a1
-    jsr     _LVOFindTask(a6)
-    move.l  d0,a0
-    { Check the stack value }
-
-    {   are we running from a CLI?             }
-
-    tst.l   172(a0)         { 172 = pr_CLI     }
-    bne     @fromCLI
-
-    { we do not support Workbench yet ..       }
-    move.l  d6,a6           { restore a6       }
-    move.l  #1,d0
-    jsr     HALT_ERROR
-
-@fromCLI:
-    {  Open the following libraries:            }
-    {   Intuition.library                       }
-    {   dos.library                             }
-
-    moveq.l  #0,d0
-    move.l   intuitionname,a1      { directly since it is a pchar }
-    jsr      _LVOOpenLibrary(a6)
-    move.l   d0,_IntuitionBase
-    beq      @exitprg
-
-    moveq.l  #0,d0
-    move.l   utilityname,a1        { directly since it is a pchar }
-    jsr      _LVOOpenLibrary(a6)
-    move.l   d0,_UtilityBase
-    beq      @exitprg
-
-    moveq.l  #0,d0
-    move.l   dosname,a1            { directly since it is a pchar }
-    jsr      _LVOOpenLibrary(a6)
-    move.l   d0,_DOSBase
-    beq      @exitprg
-
-    { Find standard input and output               }
-    { for CLI                                      }
-@OpenFiles:
-    move.l  _DOSBase,a6
-    jsr     _LVOInput(a6)        { get standard in                   }
-    move.l  d0, StdInputHandle   { save standard Input handle        }
-{    move.l  d0,d1               }{ set up for next call              }
-{   jsr     _LVOIsInteractive(a6)}{ is it interactive?             }
-{   move.l  #_Input,a0          }{ get file record again             }
-{   move.b  d0,INTERACTIVE(a0)  }{ set flag                          }
-{   beq     StdInNotInteractive }{ skip this if not interactive    }
-{   move.l  BUFFER(a0),a1       }{ get buffer address                }
-{   add.l   #1,a1               }{ make end one byte further on      }
-{   move.l  a1,MAX(a0)          }{ set buffer size                   }
-{   move.l  a1,CURRENT(a0)      }{ will need a read                  }
-    bra     @OpenStdOutput
-@StdInNotInteractive
-{    jsr _p%FillBuffer     }      { fill the buffer                   }
-@OpenStdOutput
-    jsr     _LVOOutput(a6)      { get ouput file handle             }
-    move.l  d0,StdOutputHandle  { get file record                   }
-    bra     @startupend
-{    move.l  d0,d1             }  { set up for call                   }
-{    jsr _LVOIsInteractive(a6) }  { is it interactive?                }
-{    move.l  #_Output,a0       }  { get file record                   }
-{    move.b  d0,INTERACTIVE(a0)}  { set flag                          }
-@exitprg:
-     move.l d6,a6                 { restore a6                        }
-     move.l #219,d0
-     jsr    HALT_ERROR
-@startupend:
-     move.l d6,a6                 { restore a6                        }
-end;
-
-
-
-begin
-  errno:= 0;
-  FromHalt := FALSE;
-{  Initial state is on -- in case of RunErrors before the i/o handles are }
-{  ok.                                                                    }
-  Initial:=TRUE;
-{ Initialize ExitProc }
-  ExitProc:=Nil;
-  Startup;
-{ to test stack depth }
-  loweststack:=maxlongint;
-{ Setup heap }
-  InitHeap;
-{ Setup stdin, stdout and stderr }
-  OpenStdIO(Input,fmInput,StdInputHandle);
-  OpenStdIO(Output,fmOutput,StdOutputHandle);
-  OpenStdIO(StdOut,fmOutput,StdOutputHandle);
-  { The Amiga does not seem to have a StdError }
-  { handle, therefore make the StdError handle }
-  { equal to the StdOutputHandle.              }
-  StdErrorHandle := StdOutputHandle;
-  OpenStdIO(StdErr,fmOutput,StdErrorHandle);
-{ Now Handles and function handlers are setup }
-{ correctly.                                  }
-  Initial:=FALSE;
-{ Reset IO Error }
-  InOutRes:=0;
-{ Startup }
-  { Only AmigaOS v2.04 or greater is supported }
-  If KickVersion < 36 then
-   Begin
-     WriteLn('v36 or greater of Kickstart required.');
-     Halt(1);
-   end;
-   argc:=GetParamCount(args);
-   OrigDir := 0;
-   FileList := nil;
-end.
-
-
-{
-  $Log$
-  Revision 1.1  2000-07-13 06:30:29  michael
-  + Initial import
-
-  Revision 1.15  2000/01/07 16:41:29  daniel
-    * copyright 2000
-
-  Revision 1.14  2000/01/07 16:32:22  daniel
-    * copyright 2000 added
-
-  Revision 1.13  1999/09/10 15:40:32  peter
-    * fixed do_open flags to be > $100, becuase filemode can be upto 255
-
-  Revision 1.12  1999/01/18 10:05:47  pierre
-   + system_exit procedure added
-
-  Revision 1.11  1998/12/28 15:50:42  peter
-    + stdout, which is needed when you write something in the system unit
-      to the screen. Like the runtime error
-
-  Revision 1.10  1998/09/14 10:48:00  peter
-    * FPC_ names
-    * Heap manager is now system independent
-
-  Revision 1.9  1998/08/17 12:34:22  carl
-    * chdir accepts .. characters
-    + added ctrl-c checking
-    + implemented sbrk
-    * exit code was never called if no error was found on exit!
-    * register was not saved in do_open
-
-  Revision 1.8  1998/07/13 12:32:18  carl
-    * do_truncate works, some cleanup
-
-  Revision 1.6  1998/07/02 12:37:52  carl
-    * IOCheck for chdir,rmdir and mkdir as in TP
-
-  Revision 1.5  1998/07/01 14:30:56  carl
-    * forgot that includes are case sensitive
-
-  Revision 1.4  1998/07/01 14:13:50  carl
-    * do_open bugfix
-    * correct conversion of Amiga error codes to TP error codes
-    * InoutRes word bugfix
-    * parameter counting fixed
-    * new stack checking implemented
-    + IOCheck for chdir,rmdir,getdir and rmdir
-    * do_filepos was wrong
-    + chdir correctly implemented
-    * getdir correctly implemented
-
-  Revision 1.1.1.1  1998/03/25 11:18:47  root
-  * Restored version
-
-  Revision 1.14  1998/03/21 04:20:09  carl
-    * correct ExecBase pointer (from Nils Sjoholm)
-    * correct OpenLibrary vector (from Nils Sjoholm)
-
-  Revision 1.13  1998/03/14 21:34:32  carl
-    * forgot to save a6 in Startup routine
-
-  Revision 1.12  1998/02/24 21:19:42  carl
-  *** empty log message ***
-
-  Revision 1.11  1998/02/23 02:22:49  carl
-    * bugfix if linking problems
-
-  Revision 1.9  1998/02/06 16:34:32  carl
-    + do_open is now standard with other platforms
-
-  Revision 1.8  1998/02/02 15:01:45  carl
-    * fixed bug with opening library versions (from Nils Sjoholm)
-
-  Revision 1.7  1998/01/31 19:35:19  carl
-    + added opening of utility.library
-
-  Revision 1.6  1998/01/29 23:20:54  peter
-    - Removed Backslash convert
-
-  Revision 1.5  1998/01/27 10:55:04  peter
-    * Amiga uses / not \, so change AllowSlash -> AllowBackSlash
-
-  Revision 1.4  1998/01/25 21:53:20  peter
-    + Universal Handles support for StdIn/StdOut/StdErr
-    * Updated layout of sysamiga.pas
-
-  Revision 1.3  1998/01/24 21:09:53  carl
-    + added missing input/output function pointers
-
-  Revision 1.2  1998/01/24 14:08:25  carl
-    * RunError 217 --> RunError 219 (cannot open lib)
-    + Standard Handle names implemented
-
-  Revision 1.1  1998/01/24 05:12:15  carl
-    + initial revision, some stuff still missing though.
-      (and as you might imagine ... untested :))
-}
+{$i system.pp}

+ 1915 - 0
rtl/amiga/system.pas

@@ -0,0 +1,1915 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Carl Eric Codere
+    Some parts taken from
+       Marcel Timmermans - Modula 2 Compiler
+       Nils Sjoholm - Amiga porter
+       Matthew Dillon - Dice C (with his kind permission)
+          [email protected]
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+unit {$ifdef VER1_0}sysamiga{$else}{$ifdef VER0_99}sysamiga{$ELSE}system{$endif}{$ENDIF};
+
+{--------------------------------------------------------------------}
+{ LEFT TO DO:                                                        }
+{--------------------------------------------------------------------}
+{ o GetDir with different drive numbers                              }
+{--------------------------------------------------------------------}
+
+{$I os.inc}
+
+{ AmigaOS uses character #10 as eoln only }
+{$DEFINE SHORT_LINEBREAK}
+
+  interface
+
+    { used for single computations }
+    const BIAS4 = $7f-1;
+
+    {$I systemh.inc}
+
+    {$I heaph.inc}
+
+const
+  UnusedHandle    : longint = -1;
+  StdInputHandle  : longint = 0;
+  StdOutputHandle : longint = 0;
+  StdErrorHandle  : longint = 0;
+
+ _ExecBase:longint = $4;
+ _WorkbenchMsg : longint = 0;
+
+ _IntuitionBase : pointer = nil;       { intuition library pointer }
+ _DosBase       : pointer = nil;       { DOS library pointer       }
+ _UtilityBase   : pointer = nil;       { utiity library pointer    }
+
+ { Required for crt unit }
+  function do_read(h,addr,len : longint) : longint;
+  function do_write(h,addr,len : longint) : longint;
+
+
+
+
+
+  implementation
+
+ const
+
+   intuitionname : pchar = 'intuition.library';
+   dosname : pchar = 'dos.library';
+   utilityname : pchar = 'utility.library';
+   argc : longint = 0;
+   { AmigaOS does not autoamtically deallocate memory on program termination }
+   { therefore we have to handle this manually. This is a list of allocated  }
+   { pointers from the OS, we cannot use a linked list, because the linked   }
+   { list itself uses the HEAP!                                              }
+   pointerlist : array[1..8] of longint =
+    (0,0,0,0,0,0,0,0);
+
+
+    {$I exec.inc}
+
+  TYPE
+    TDateStamp = packed record
+        ds_Days         : Longint;      { Number of days since Jan. 1, 1978 }
+        ds_Minute       : Longint;      { Number of minutes past midnight }
+        ds_Tick         : Longint;      { Number of ticks past minute }
+    end;
+    PDateStamp = ^TDateStamp;
+
+
+    PFileInfoBlock = ^TfileInfoBlock;
+    TFileInfoBlock = packed record
+        fib_DiskKey     : Longint;
+        fib_DirEntryType : Longint;
+                        { Type of Directory. If < 0, then a plain file.
+                          If > 0 a directory }
+        fib_FileName    : Array [0..107] of Char;
+                        { Null terminated. Max 30 chars used for now }
+        fib_Protection  : Longint;
+                        { bit mask of protection, rwxd are 3-0. }
+        fib_EntryType   : Longint;
+        fib_Size        : Longint;      { Number of bytes in file }
+        fib_NumBlocks   : Longint;      { Number of blocks in file }
+        fib_Date        : TDateStamp; { Date file last changed }
+        fib_Comment     : Array [0..79] of Char;
+                        { Null terminated comment associated with file }
+        fib_Reserved    : Array [0..35] of Char;
+    end;
+
+
+    TProcess = packed record
+        pr_Task         : TTask;
+        pr_MsgPort      : TMsgPort;      { This is BPTR address from DOS functions  }
+{126}   pr_Pad          : Word;         { Remaining variables on 4 byte boundaries }
+{128}   pr_SegList      : Pointer;      { Array of seg lists used by this process  }
+{132}   pr_StackSize    : Longint;      { Size of process stack in bytes            }
+{136}   pr_GlobVec      : Pointer;      { Global vector for this process (BCPL)    }
+{140}   pr_TaskNum      : Longint;      { CLI task number of zero if not a CLI      }
+{144}   pr_StackBase    : BPTR;         { Ptr to high memory end of process stack  }
+{148}   pr_Result2      : Longint;      { Value of secondary result from last call }
+{152}   pr_CurrentDir   : BPTR;         { Lock associated with current directory   }
+{156}   pr_CIS          : BPTR;         { Current CLI Input Stream                  }
+{160}   pr_COS          : BPTR;         { Current CLI Output Stream                 }
+{164}   pr_ConsoleTask  : Pointer;      { Console handler process for current window}
+{168}   pr_FileSystemTask : Pointer;    { File handler process for current drive   }
+{172}   pr_CLI          : BPTR;         { pointer to ConsoleLineInterpreter         }
+        pr_ReturnAddr   : Pointer;      { pointer to previous stack frame           }
+        pr_PktWait      : Pointer;      { Function to be called when awaiting msg  }
+        pr_WindowPtr    : Pointer;      { Window for error printing }
+        { following definitions are new with 2.0 }
+        pr_HomeDir      : BPTR;         { Home directory of executing program      }
+        pr_Flags        : Longint;      { flags telling dos about process          }
+        pr_ExitCode     : Pointer;      { code to call on exit of program OR NULL  }
+        pr_ExitData     : Longint;      { Passed as an argument to pr_ExitCode.    }
+        pr_Arguments    : PChar;        { Arguments passed to the process at start }
+        pr_LocalVars    : TMinList;      { Local environment variables             }
+        pr_ShellPrivate : Longint;      { for the use of the current shell         }
+        pr_CES          : BPTR;         { Error stream - IF NULL, use pr_COS       }
+    end;
+    PProcess = ^TProcess;
+
+  { AmigaOS does not automatically close opened files on exit back to  }
+  { the operating system, therefore as a precuation we close all files }
+  { manually on exit.                                                  }
+  PFileList = ^TFileList;
+  TFileList = record { no packed, must be correctly aligned }
+   Handle: longint;      { Handle to file    }
+   next: pfilelist;      { Next file in list }
+   closed: boolean;      { TRUE=file already closed }
+  end;
+
+
+
+
+    Const
+     CTRL_C               = 20;      { Error code on CTRL-C press }
+     SIGBREAKF_CTRL_C     = $1000;   { CTRL-C signal flags }
+
+    _LVOFindTask          = -294;
+    _LVOWaitPort          = -384;
+    _LVOGetMsg            = -372;
+    _LVOOpenLibrary       = -552;
+    _LVOCloseLibrary      = -414;
+    _LVOClose             = -36;
+    _LVOOpen              = -30;
+    _LVOIoErr             = -132;
+    _LVOSeek              = -66;
+    _LVODeleteFile        = -72;
+    _LVORename            = -78;
+    _LVOWrite             = -48;
+    _LVORead              = -42;
+    _LVOCreateDir         = -120;
+    _LVOSetCurrentDirName = -558;
+    _LVOGetCurrentDirName = -564;
+    _LVOInput             = -54;
+    _LVOOutput            = -60;
+    _LVOUnLock            = -90;
+    _LVOLock              = -84;
+    _LVOCurrentDir        = -126;
+
+    _LVONameFromLock      = -402;
+    _LVONameFromFH        = -408;
+    _LVOGetProgramName    = -576;
+    _LVOGetProgramDir     = -600;
+    _LVODupLock           =  -96;
+    _LVOExamine           = -102;
+    _LVOParentDir         = -210;
+    _LVOSetFileSize       = -456;
+    _LVOSetSignal         = -306;
+    _LVOAllocVec          = -684;
+    _LVOFreeVec           = -690;
+
+
+      { Errors from IoErr(), etc. }
+      ERROR_NO_FREE_STORE              = 103;
+      ERROR_TASK_TABLE_FULL            = 105;
+      ERROR_BAD_TEMPLATE               = 114;
+      ERROR_BAD_NUMBER                 = 115;
+      ERROR_REQUIRED_ARG_MISSING       = 116;
+      ERROR_KEY_NEEDS_ARG              = 117;
+      ERROR_TOO_MANY_ARGS              = 118;
+      ERROR_UNMATCHED_QUOTES           = 119;
+      ERROR_LINE_TOO_LONG              = 120;
+      ERROR_FILE_NOT_OBJECT            = 121;
+      ERROR_INVALID_RESIDENT_LIBRARY   = 122;
+      ERROR_NO_DEFAULT_DIR             = 201;
+      ERROR_OBJECT_IN_USE              = 202;
+      ERROR_OBJECT_EXISTS              = 203;
+      ERROR_DIR_NOT_FOUND              = 204;
+      ERROR_OBJECT_NOT_FOUND           = 205;
+      ERROR_BAD_STREAM_NAME            = 206;
+      ERROR_OBJECT_TOO_LARGE           = 207;
+      ERROR_ACTION_NOT_KNOWN           = 209;
+      ERROR_INVALID_COMPONENT_NAME     = 210;
+      ERROR_INVALID_LOCK               = 211;
+      ERROR_OBJECT_WRONG_TYPE          = 212;
+      ERROR_DISK_NOT_VALIDATED         = 213;
+      ERROR_DISK_WRITE_PROTECTED       = 214;
+      ERROR_RENAME_ACROSS_DEVICES      = 215;
+      ERROR_DIRECTORY_NOT_EMPTY        = 216;
+      ERROR_TOO_MANY_LEVELS            = 217;
+      ERROR_DEVICE_NOT_MOUNTED         = 218;
+      ERROR_SEEK_ERROR                 = 219;
+      ERROR_COMMENT_TOO_BIG            = 220;
+      ERROR_DISK_FULL                  = 221;
+      ERROR_DELETE_PROTECTED           = 222;
+      ERROR_WRITE_PROTECTED            = 223;
+      ERROR_READ_PROTECTED             = 224;
+      ERROR_NOT_A_DOS_DISK             = 225;
+      ERROR_NO_DISK                    = 226;
+      ERROR_NO_MORE_ENTRIES            = 232;
+      { added for 1.4 }
+      ERROR_IS_SOFT_LINK               = 233;
+      ERROR_OBJECT_LINKED              = 234;
+      ERROR_BAD_HUNK                   = 235;
+      ERROR_NOT_IMPLEMENTED            = 236;
+      ERROR_RECORD_NOT_LOCKED          = 240;
+      ERROR_LOCK_COLLISION             = 241;
+      ERROR_LOCK_TIMEOUT               = 242;
+      ERROR_UNLOCK_ERROR               = 243;
+
+
+
+    var
+      Initial: boolean;           { Have successfully opened Std I/O   }
+      errno : word;               { AmigaOS IO Error number            }
+      FileList : pFileList;       { Linked list of opened files        }
+      {old_exit: Pointer; not needed anymore }
+      FromHalt : boolean;
+      OrigDir : Longint;   { Current lock on original startup directory }
+
+    {$I system.inc}
+    {$I lowmath.inc}
+
+
+
+
+  { ************************ AMIGAOS STUB ROUTINES ************************* }
+
+  procedure DateStamp(var ds : tDateStamp);
+  begin
+   asm
+      MOVE.L  A6,-(A7)
+      MOVE.L  ds,d1
+      { LAST THING TO SETUP SHOULD BE A6, otherwise you can }
+      { not accept local variable, nor any parameters! :)   }
+      MOVE.L  _DOSBase,A6
+      JSR -192(A6)
+      MOVE.L  (A7)+,A6
+  end;
+ end;
+
+
+
+  { UNLOCK the BPTR pointed to in L }
+  Procedure Unlock(alock: longint);
+  Begin
+    asm
+     move.l  alock,d1
+     move.l  a6,d6           { save base pointer    }
+     move.l   _DosBase,a6
+     jsr     _LVOUnlock(a6)
+     move.l  d6,a6           { restore base pointer }
+    end;
+  end;
+
+  { Change to the directory pointed to in the lock }
+  Function CurrentDir(alock : longint) : longint;
+  Begin
+    asm
+      move.l  alock,d1
+      move.l  a6,d6           { save base pointer    }
+      move.l  _DosBase,a6
+      jsr     _LVOCurrentDir(a6)
+      move.l  d6,a6           { restore base pointer }
+      move.l  d0,@Result
+    end;
+  end;
+
+  { Duplicate a lock }
+  Function DupLock(alock: longint): Longint;
+   Begin
+     asm
+       move.l  alock,d1
+       move.l  a6,d6           { save base pointer    }
+       move.l  _DosBase,a6
+       jsr     _LVODupLock(a6)
+       move.l  d6,a6           { restore base pointer }
+       move.l  d0,@Result
+     end;
+   end;
+
+  { Returns a lock on the directory was loaded from }
+  Function GetProgramLock: longint;
+  Begin
+   asm
+       move.l  a6,d6           { save base pointer    }
+       move.l  _DosBase,a6
+       jsr     _LVOGetProgramDir(a6)
+       move.l  d6,a6           { restore base pointer }
+       move.l  d0,@Result
+   end;
+  end;
+
+
+
+  Function Examine(alock :longint; var fib: TFileInfoBlock) : Boolean;
+  Begin
+    asm
+       move.l  d2,-(sp)
+       move.l  fib,d2         { pointer to FIB        }
+       move.l  alock,d1
+       move.l  a6,d6           { save base pointer    }
+       move.l  _DosBase,a6
+       jsr     _LVOExamine(a6)
+       move.l  d6,a6           { restore base pointer }
+       tst.l   d0
+       bne     @success
+       bra     @end
+    @success:
+       move.b  #1,d0
+    @end:
+       move.b  d0,@Result
+       move.l  (sp)+,d2
+    end;
+  end;
+
+  { Returns the parent directory of a lock }
+  Function ParentDir(alock : longint): longint;
+   Begin
+     asm
+       move.l  alock,d1
+       move.l  a6,d6           { save base pointer    }
+       move.l  _DosBase,a6
+       jsr     _LVOParentDir(a6)
+       move.l  d6,a6           { restore base pointer }
+       move.l  d0,@Result
+     end;
+   end;
+
+
+   Function FindTask(p : PChar): PProcess;
+   Begin
+    asm
+         move.l  a6,d6              { Save base pointer    }
+         move.l  p,d0
+         move.l  d0,a1
+         move.l  _ExecBase,a6
+         jsr     _LVOFindTask(a6)
+         move.l  d6,a6              { Restore base pointer }
+         move.l  d0,@Result
+    end;
+   end;
+
+
+{$S-}
+    Procedure stack_check; assembler;
+    { Check for local variable allocation }
+    { On Entry -> d0 : size of local stack we are trying to allocate }
+     asm
+      XDEF STACKCHECK
+        move.l  sp,d1            { get value of stack pointer            }
+
+        { We must add some security, because Writing the RunError strings }
+        { requires a LOT of stack space (at least 1030 bytes!)            }
+        add.l   #2048,d0
+        sub.l   d0,d1            {  sp - stack_size                      }
+
+        move.l  _ExecBase,a0
+        move.l  276(A0),A0       { ExecBase.thisTask }
+        { if allocated stack_pointer - splower <= 0 then stack_ovf       }
+        cmp.l   58(A0),D1        { Task.SpLower      }
+        bgt     @Ok
+        move.l  #202,d0
+        jsr     HALT_ERROR       { stack overflow    }
+    @Ok:
+   end;
+
+
+   { This routine from EXEC determines if the Ctrl-C key has }
+   { been used since the last call to I/O routines.          }
+   { Use to halt the program.                                }
+   { Returns the state of the old signals.                   }
+   Function SetSignal(newSignal: longint; SignalMask: longint): longint;
+   Begin
+     asm
+       move.l  newSignal,d0
+       move.l  SignalMask,d1
+       move.l  a6,d6          { save Base pointer into scratch register }
+       move.l  _ExecBase,a6
+       jsr     _LVOSetSignal(a6)
+       move.l  d6,a6
+       move.l  d0,@Result
+     end;
+   end;
+
+
+   Function AllocVec(bytesize: longint; attributes: longint):longint;
+   Begin
+     asm
+       move.l  bytesize,d0
+       move.l  attributes,d1
+       move.l  a6,d6          { save Base pointer into scratch register }
+       move.l  _ExecBase,a6
+       jsr     _LVOAllocVec(a6)
+       move.l  d6,a6
+       move.l  d0,@Result
+     end;
+   end;
+
+
+   Procedure FreeVec(p: longint);
+   Begin
+     asm
+       move.l  p,a1
+       move.l  a6,d6          { save Base pointer into scratch register }
+       move.l  _ExecBase,a6
+       jsr     _LVOFreeVec(a6)
+       move.l  d6,a6
+     end;
+   end;
+
+
+   { Converts an AMIGAOS error code to a TP compatible error code }
+   Procedure Error2InOut;
+   Begin
+     case errno of
+       ERROR_BAD_NUMBER,
+       ERROR_ACTION_NOT_KNOWN,
+       ERROR_NOT_IMPLEMENTED : InOutRes := 1;
+
+       ERROR_OBJECT_NOT_FOUND : InOutRes := 2;
+       ERROR_DIR_NOT_FOUND :  InOutRes := 3;
+
+       ERROR_DISK_WRITE_PROTECTED : InOutRes := 150;
+
+       ERROR_OBJECT_WRONG_TYPE : InOutRes := 151;
+
+       ERROR_OBJECT_EXISTS,
+       ERROR_DELETE_PROTECTED,
+       ERROR_WRITE_PROTECTED,
+       ERROR_READ_PROTECTED,
+       ERROR_OBJECT_IN_USE,
+       ERROR_DIRECTORY_NOT_EMPTY : InOutRes := 5;
+
+       ERROR_NO_MORE_ENTRIES : InOutRes := 18;
+
+       ERROR_RENAME_ACROSS_DEVICES : InOutRes := 17;
+
+       ERROR_DISK_FULL : InOutRes := 101;
+
+       ERROR_INVALID_RESIDENT_LIBRARY : InoutRes := 153;
+       ERROR_BAD_HUNK : InOutRes := 153;
+
+       ERROR_NOT_A_DOS_DISK : InOutRes := 157;
+
+       ERROR_NO_DISK,
+       ERROR_DISK_NOT_VALIDATED,
+       ERROR_DEVICE_NOT_MOUNTED : InOutRes := 152;
+
+       ERROR_SEEK_ERROR : InOutRes := 156;
+
+       ERROR_LOCK_COLLISION,
+       ERROR_LOCK_TIMEOUT,
+       ERROR_UNLOCK_ERROR,
+       ERROR_INVALID_LOCK,
+       ERROR_INVALID_COMPONENT_NAME,
+       ERROR_BAD_STREAM_NAME,
+       ERROR_FILE_NOT_OBJECT : InOutRes := 6;
+     else
+       InOutres := errno;
+     end;
+     errno:=0;
+   end;
+
+
+    procedure CloseLibrary(lib : pointer);
+    {  Close the library pointed to in lib }
+    Begin
+      asm
+         MOVE.L  A6,-(A7)
+         MOVE.L  lib,a1
+         MOVE.L  _ExecBase,A6
+         JSR     _LVOCloseLibrary(A6)
+         MOVE.L  (A7)+,A6
+      end;
+    end;
+
+
+   Function KickVersion: word; assembler;
+   asm
+     move.l  _ExecBase, a0       { Get Exec Base                           }
+     move.w  20(a0), d0          { Return version - version at this offset }
+   end;
+
+
+  { ************************ AMIGAOS SUPP ROUTINES ************************* }
+
+(*  Procedure CloseList(p: pFileList);*)
+  (***********************************************************************)
+  (* PROCEDURE CloseList                                                 *)
+  (*  Description: This routine each time the program is about to        *)
+  (*  terminate, it closes all opened file handles, as this is not       *)
+  (*  handled by the operating system.                                   *)
+  (*   p -> Start of linked list of opened files                         *)
+  (***********************************************************************)
+(*  var
+   hp: pFileList;
+   hp1: pFileList;
+   h: longint;
+  Begin
+   hp:=p;
+   while Assigned(hp) do
+    Begin
+      if NOT hp^.closed then
+       Begin
+        h:=hp^.handle;
+        if (h <> StdInputHandle) and (h <> StdOutputHandle) and (h <> StdErrorHandle) then
+        Begin
+          { directly close file here, it is faster then doing }
+          { it do_close.                                      }
+          asm
+            move.l  h,d1
+            move.l  a6,d6              { save a6 }
+            move.l  _DOSBase,a6
+            jsr     _LVOClose(a6)
+            move.l  d6,a6              { restore a6 }
+          end;
+        end;
+       end;
+      hp1:=hp;
+      hp:=hp^.next;
+      dispose(hp1);
+    end;
+  end;*)
+
+
+(* Procedure AddToList(var p: pFileList; h: longint);*)
+  (***********************************************************************)
+  (* PROCEDURE AddToList                                                 *)
+  (*  Description: Adds a node to the linked list of files.              *)
+  (*                                                                     *)
+  (*   p -> Start of File list linked list, if not allocated allocates   *)
+  (*        it for you.                                                  *)
+  (*   h -> handle of file to add                                        *)
+  (***********************************************************************)
+(*  var
+   hp: pFileList;
+   hp1: pFileList;
+  Begin
+    if p = nil then
+     Begin
+       new(p);
+       p^.handle:=h;
+       p^.closed := FALSE;
+       p^.next := nil;
+       exit;
+     end;
+     hp:=p;
+    { Find last list in entry }
+    while assigned(hp) do
+     Begin
+        if hp^.next = nil then break;
+        hp:=hp^.next;
+     end;
+    { Found last list in entry then add it to the list }
+    new(hp1);
+    hp^.next:=hp1;
+    hp1^.next:=nil;
+    hp1^.handle:=h;
+    hp1^.closed:=FALSE;
+  end;
+
+
+  Procedure SetClosedList(var p: pFileList; h: longint);
+  { Set the file flag to closed if the file is being closed }
+  var
+   hp: pFileList;
+  Begin
+    hp:=p;
+    while assigned(hp) do
+     Begin
+        if hp^.handle = h then
+         Begin
+           hp^.closed:=TRUE;
+           break;
+         end;
+        hp:=hp^.next;
+     end;
+  end;*)
+
+
+{*****************************************************************************
+                         System Dependent Exit code
+*****************************************************************************}
+  Procedure system_exit;
+    var
+     i: byte;
+    Begin
+        { We must remove the CTRL-C FALG here because halt }
+        { may call I/O routines, which in turn might call  }
+        { halt, so a recursive stack crash                 }
+        IF (SetSignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 THEN
+           SetSignal(0,SIGBREAKF_CTRL_C);
+         { Close remaining opened files }
+{         CloseList(FileList); }
+        if (OrigDir <> 0) then
+         Begin
+            Unlock(CurrentDir(OrigDir));
+            OrigDir := 0;
+         end;
+         { Is this a normal exit - YES, close libs }
+         IF NOT FromHalt then
+           Begin
+             { close the libraries }
+             If _UtilityBase <> nil then
+                 CloseLibrary(_UtilityBase);
+             If _DosBase <> nil then
+                 CloseLibrary(_DosBase);
+             If _IntuitionBase <> nil then
+                 CloseLibrary(_IntuitionBase);
+             _UtilityBase := nil;
+             _DosBase := nil;
+             _IntuitionBase := nil;
+           end;
+         { Dispose of extraneous allocated pointers }
+         for I:=1 to 8 do
+           Begin
+             if pointerlist[i] <> 0 then FreeVec(pointerlist[i]);
+           end;
+         { exitproc:=old_exit;obsolete }
+    end;
+
+
+    procedure halt(errnum : byte);
+      begin
+        { Indicate to the SYSTEM EXIT procedure that we are calling it }
+        { from halt, and that its library will be closed HERE and not  }
+        { in the exit procedure.                                       }
+        FromHalt:=TRUE;
+        { We must remove the CTRL-C FALG here because halt }
+        { may call I/O routines, which in turn might call  }
+        { halt, so a recursive stack crash                 }
+        IF (SetSignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 THEN
+           SetSignal(0,SIGBREAKF_CTRL_C);
+        { WE can only FLUSH the stdio   }
+        { if the handles have correctly }
+        { been set.                     }
+        { No exit procedures exist      }
+        { if in initial state           }
+        If NOT Initial then
+        Begin
+          do_exit;
+          flush(stderr);
+        end;
+        { close the libraries }
+        If _UtilityBase <> nil then
+           CloseLibrary(_UtilityBase);
+        If _DosBase <> nil then
+           CloseLibrary(_DosBase);
+        If _IntuitionBase <> nil then
+           CloseLibrary(_IntuitionBase);
+        _UtilityBase := nil;
+        _DosBase := nil;
+        _IntuitionBase := nil;
+         asm
+            clr.l   d0
+            move.b  errnum,d0
+            move.l  STKPTR,sp
+            rts
+         end;
+      end;
+
+
+
+  { ************************ PARAMCOUNT/PARAMSTR *************************** }
+
+      function paramcount : longint;
+      Begin
+        paramcount := argc;
+      end;
+
+
+      function args : pointer; assembler;
+      asm
+         move.l __ARGS,d0
+      end;
+
+   Function GetParamCount(const p: pchar): longint;
+   var
+    i: word;
+    count: word;
+   Begin
+    i:=0;
+    count:=0;
+    while p[count] <> #0 do
+     Begin
+       if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
+       Begin
+          i:=i+1;
+          while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
+           count:=count+1;
+       end;
+       if p[count] = #0 then break;
+       count:=count+1;
+     end;
+     GetParamCount:=longint(i);
+   end;
+
+
+   Function GetParam(index: word; const p : pchar): string;
+   { On Entry: index = string index to correct parameter  }
+   { On exit:  = correct character index into pchar array }
+   { Returns correct index to command line argument }
+   var
+    count: word;
+    localindex: word;
+    l: byte;
+    temp: string;
+   Begin
+     temp:='';
+     count := 0;
+     { first index is one }
+     localindex := 1;
+     l:=0;
+     While p[count] <> #0 do
+       Begin
+         if (p[count] <> ' ') and (p[count] <> #9) then
+           Begin
+             if localindex = index then
+              Begin
+               while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
+                Begin
+                  temp:=temp+p[count];
+                  l:=l+1;
+                  count:=count+1;
+                end;
+                temp[0]:=char(l);
+                GetParam:=temp;
+                exit;
+              end;
+             { Point to next argument in list }
+             while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
+               Begin
+                 count:=count+1;
+               end;
+             localindex:=localindex+1;
+           end;
+         if p[count] = #0 then break;
+         count:=count+1;
+       end;
+     GetParam:=temp;
+   end;
+
+
+    Function GetProgramDir : String;
+    var
+     s1: string;
+     alock: longint;
+     counter : byte;
+    Begin
+     FillChar(@s1,255,#0);
+     { GetLock of program directory }
+     asm
+            move.l  a6,d6              { save a6 }
+            move.l  _DOSBase,a6
+            jsr     _LVOGetProgramDir(a6)
+            move.l  d6,a6              { restore a6 }
+            move.l  d0,alock           { save the lock }
+     end;
+     if alock <> 0 then
+      Begin
+        { Get the name from the lock! }
+        asm
+            movem.l d2/d3,-(sp)        { save used registers             }
+            move.l  alock,d1
+            lea     s1,a0              { Get pointer to string!          }
+            move.l  a0,d2
+            add.l   #1,d2              { let  us point past the length byte! }
+            move.l  #255,d3
+            move.l  a6,d6              { save a6 }
+            move.l  _DOSBase,a6
+            jsr     _LVONameFromLock(a6)
+            move.l  d6,a6              { restore a6 }
+            movem.l (sp)+,d2/d3
+        end;
+        { no check out the length of the string }
+        counter := 1;
+        while s1[counter] <> #0 do
+           Inc(counter);
+        s1[0] := char(counter-1);
+        GetProgramDir := s1;
+      end
+     else
+      GetProgramDir := '';
+    end;
+
+
+    Function GetProgramName : string;
+    { Returns ONLY the program name }
+    { There seems to be a bug in v39 since if the program is not }
+    { called from its home directory the program name will also  }
+    { contain the path!                                          }
+    var
+     s1: string;
+     counter : byte;
+    Begin
+      FillChar(@s1,255,#0);
+      asm
+            move.l  d2,-(sp)           { Save used register      }
+            lea     s1,a0              { Get pointer to string!  }
+            move.l  a0,d1
+            add.l   #1,d1              { point to correct offset }
+            move.l  #255,d2
+            move.l  a6,d6              { save a6 }
+            move.l  _DOSBase,a6
+            jsr     _LVOGetProgramName(a6)
+            move.l  d6,a6              { restore a6 }
+            move.l  (sp)+,d2           { restore saved register }
+      end;
+        { no check out and assign the length of the string }
+        counter := 1;
+        while s1[counter] <> #0 do
+           Inc(counter);
+        s1[0] := char(counter-1);
+        { now remove any component path which should not be there }
+        for counter:=length(s1) downto 1 do
+          if (s1[counter] = '/') or (s1[counter] = ':') then break;
+        { readjust counterv to point to character }
+        if counter <> 1 then
+          Inc(counter);
+        GetProgramName:=copy(s1,counter,length(s1));
+    end;
+
+
+    function paramstr(l : longint) : string;
+      var
+       p : pchar;
+       s1 : string;
+      begin
+         {   -> Call AmigaOS GetProgramName                             }
+         if l = 0 then
+         Begin
+           s1 := GetProgramDir;
+           { If this is a root, then simply don't add '/' }
+           if s1[length(s1)] = ':' then
+              paramstr:=s1+GetProgramName
+           else
+              { add backslash directory }
+              paramstr:=s1+'/'+GetProgramName
+         end
+         else
+         if (l>0) and (l<=paramcount) then
+           begin
+             p:=args;
+             paramstr:=GetParam(word(l),p);
+           end
+         else paramstr:='';
+      end;
+
+  { ************************************************************************ }
+
+    procedure randomize;
+
+      var
+         hl : longint;
+         time : TDateStamp;
+      begin
+         DateStamp(time);
+         randseed:=time.ds_tick;
+      end;
+
+function getheapstart:pointer;assembler;
+asm
+        lea.l   HEAP,a0
+        move.l  a0,d0
+end;
+
+
+function getheapsize:longint;assembler;
+asm
+       move.l   HEAP_SIZE,d0
+end ['D0'];
+
+  { This routine is used to grow the heap.  }
+  { But here we do a trick, we say that the }
+  { heap cannot be regrown!                 }
+  function sbrk( size: longint): longint;
+  var
+  { on exit -1 = if fails.               }
+   p: longint;
+   i: byte;
+  Begin
+    p:=0;
+    { Is the pointer list full }
+    if pointerlist[8] <> 0 then
+    begin
+     { yes, then don't allocate and simply exit }
+     sbrk:=-1;
+     exit;
+    end;
+    { Allocate best available memory }
+    p:=AllocVec(size,0);
+    if p = 0 then
+     sbrk:=-1
+    else
+    Begin
+       i:=1;
+       { add it to the list of allocated pointers }
+       { first find the last pointer in the list  }
+       while (i < 8) and (pointerlist[i] <> 0) do
+         i:=i+1;
+       pointerlist[i]:=p;
+       sbrk:=p;
+    end;
+  end;
+
+
+
+{$I heap.inc}
+
+
+{****************************************************************************
+                          Low Level File Routines
+ ****************************************************************************}
+
+procedure do_close(h : longint);
+{ We cannot check for CTRL-C because this routine will be called }
+{ on HALT to close all remaining opened files. Therefore no      }
+{ CTRL-C checking otherwise a recursive call might result!       }
+{$ifdef debug}
+var
+  buffer: array[0..255] of char;
+{$endif}
+begin
+  { check if the file handle is in the list }
+  { if so the put its field to closed       }
+{  SetClosedList(FileList,h);}
+{$ifdef debug}
+  asm
+     move.l  h,d1
+     move.l  a6,d6
+     move.l  d2,-(sp)
+     move.l  d3,-(sp)
+     lea     buffer,a0
+     move.l  a0,d2
+     move.l  #255,d3
+     move.l  _DosBase,a6
+     jsr     _LVONameFromFH(a6)
+     move.l  d6,a6
+     move.l  (sp)+,d3
+     move.l  (sp)+,d2
+  end;
+  WriteLn(Buffer);
+{$endif debug}
+  asm
+     move.l  h,d1
+     move.l  a6,d6              { save a6 }
+     move.l  _DOSBase,a6
+     jsr     _LVOClose(a6)
+     move.l  d6,a6              { restore a6 }
+  end;
+end;
+
+
+function do_isdevice(handle:longint):boolean;
+begin
+  if (handle=stdoutputhandle) or (handle=stdinputhandle) or
+  (handle=stderrorhandle) then
+    do_isdevice:=TRUE
+  else
+    do_isdevice:=FALSE;
+end;
+
+
+
+procedure do_erase(p : pchar);
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  asm
+           move.l  a6,d6               { save a6 }
+
+           move.l  p,d1
+           move.l  _DOSBase,a6
+           jsr     _LVODeleteFile(a6)
+           tst.l   d0                  { zero = failure }
+           bne     @noerror
+
+           jsr     _LVOIoErr(a6)
+           move.w  d0,errno
+
+         @noerror:
+           move.l  d6,a6               { restore a6 }
+  end;
+  if errno <> 0 then
+     Error2InOut;
+end;
+
+
+procedure do_rename(p1,p2 : pchar);
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  asm
+           move.l  a6,d6                  { save a6 }
+           move.l  d2,-(sp)               { save d2 }
+
+           move.l  p1,d1
+           move.l  p2,d2
+           move.l  _DOSBase,a6
+           jsr     _LVORename(a6)
+           move.l  (sp)+,d2               { restore d2 }
+           tst.l   d0
+           bne     @dosreend              { if zero = error }
+           jsr     _LVOIoErr(a6)
+           move.w  d0,errno
+         @dosreend:
+           move.l  d6,a6                  { restore a6 }
+  end;
+  if errno <> 0 then
+    Error2InOut;
+end;
+
+
+function do_write(h,addr,len : longint) : longint;
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  if len <= 0 then
+   Begin
+    do_write:=0;
+    exit;
+   end;
+  asm
+            move.l  a6,d6
+
+            movem.l d2/d3,-(sp)
+            move.l  h,d1             { we must of course set up the }
+            move.l  addr,d2          { parameters BEFORE getting    }
+            move.l  len,d3           { _DOSBase                     }
+            move.l  _DOSBase,a6
+            jsr     _LVOWrite(a6)
+            movem.l (sp)+,d2/d3
+
+            cmp.l   #-1,d0
+            bne     @doswrend              { if -1 = error }
+            jsr     _LVOIoErr(a6)
+            move.w  d0,errno
+            bra     @doswrend2
+          @doswrend:
+            { we must restore the base pointer before setting the result }
+            move.l  d6,a6
+            move.l  d0,@RESULT
+            bra     @end
+          @doswrend2:
+            move.l  d6,a6
+          @end:
+  end;
+  If errno <> 0 then
+    Error2InOut;
+end;
+
+
+function do_read(h,addr,len : longint) : longint;
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  if len <= 0 then
+  Begin
+     do_read:=0;
+     exit;
+  end;
+  asm
+            move.l  a6,d6
+
+            movem.l d2/d3,-(sp)
+            move.l  h,d1         { we must set up aparamters BEFORE }
+            move.l  addr,d2      { setting up a6 for the OS call    }
+            move.l  len,d3
+            move.l  _DOSBase,a6
+            jsr     _LVORead(a6)
+            movem.l (sp)+,d2/d3
+
+            cmp.l   #-1,d0
+            bne     @doswrend              { if -1 = error }
+            jsr     _LVOIoErr(a6)
+            move.w  d0,errno
+            bra     @doswrend2
+          @doswrend:
+            { to store a result for the function  }
+            { we must of course first get back the}
+            { base pointer!                       }
+            move.l  d6,a6
+            move.l  d0,@RESULT
+            bra     @end
+          @doswrend2:
+            move.l  d6,a6
+          @end:
+  end;
+  If errno <> 0 then
+    Error2InOut;
+end;
+
+
+function do_filepos(handle : longint) : longint;
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  asm
+             move.l  a6,d6
+
+             move.l  handle,d1
+             move.l  d2,-(sp)
+             move.l  d3,-(sp)              { save registers              }
+
+             clr.l   d2                    { offset 0 }
+             move.l  #0,d3                 { OFFSET_CURRENT }
+             move.l  _DOSBase,a6
+             jsr    _LVOSeek(a6)
+
+             move.l  (sp)+,d3              { restore registers }
+             move.l  (sp)+,d2
+             cmp.l   #-1,d0                { is there a file access error? }
+             bne     @noerr
+             jsr     _LVOIoErr(a6)
+             move.w  d0,errno
+             bra     @fposend
+      @noerr:
+             move.l  d6,a6                 { restore a6 }
+             move.l  d0,@Result
+             bra     @end
+      @fposend:
+             move.l  d6,a6                 { restore a6 }
+      @end:
+  end;
+  If errno <> 0 then
+    Error2InOut;
+end;
+
+
+procedure do_seek(handle,pos : longint);
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  asm
+             move.l  a6,d6
+
+             move.l  handle,d1
+             move.l  d2,-(sp)
+             move.l  d3,-(sp)              { save registers              }
+
+             move.l  pos,d2
+             { -1 }
+             move.l  #$ffffffff,d3          { OFFSET_BEGINNING }
+             move.l  _DOSBase,a6
+             jsr    _LVOSeek(a6)
+
+             move.l  (sp)+,d3              { restore registers }
+             move.l  (sp)+,d2
+             cmp.l   #-1,d0                { is there a file access error? }
+             bne     @noerr
+             jsr     _LVOIoErr(a6)
+             move.w  d0,errno
+             bra     @seekend
+      @noerr:
+      @seekend:
+             move.l  d6,a6                 { restore a6 }
+  end;
+  If errno <> 0 then
+    Error2InOut;
+end;
+
+
+function do_seekend(handle:longint):longint;
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  asm
+             { seek from end of file }
+             move.l  a6,d6
+
+             move.l  handle,d1
+             move.l  d2,-(sp)
+             move.l  d3,-(sp)              { save registers              }
+
+             clr.l   d2
+             move.l  #1,d3                 { OFFSET_END }
+             move.l  _DOSBase,a6
+             jsr    _LVOSeek(a6)
+
+             move.l  (sp)+,d3              { restore registers }
+             move.l  (sp)+,d2
+             cmp.l   #-1,d0                { is there a file access error? }
+             bne     @noerr
+             jsr     _LVOIoErr(a6)
+             move.w  d0,errno
+             bra     @seekend
+      @noerr:
+             move.l  d6,a6                 { restore a6 }
+             move.l  d0,@Result
+             bra     @end
+      @seekend:
+             move.l  d6,a6                 { restore a6 }
+      @end:
+  end;
+  If Errno <> 0 then
+    Error2InOut;
+end;
+
+
+function do_filesize(handle : longint) : longint;
+var
+  aktfilepos : longint;
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+    Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+    end;
+   aktfilepos:=do_filepos(handle);
+   { We have to do this two times, because seek returns the }
+   { OLD position                                           }
+   do_filesize:=do_seekend(handle);
+   do_filesize:=do_seekend(handle);
+   do_seek(handle,aktfilepos);
+end;
+
+
+procedure do_truncate (handle,pos:longint);
+begin
+      { Point to the end of the file }
+      { with the new size            }
+      asm
+      @noerr_one:                          { Seek a second time            }
+             move.l  a6,d6                 { Save base pointer             }
+
+             move.l  handle,d1
+             move.l  d2,-(sp)
+             move.l  d3,-(sp)              { save registers                }
+
+             move.l  pos,d2
+             move.l  #-1,d3                { Setup correct move type     }
+             move.l  _DOSBase,a6           { from beginning of file      }
+             jsr    _LVOSetFileSize(a6)
+
+             move.l  (sp)+,d3              { restore registers }
+             move.l  (sp)+,d2
+             cmp.l   #-1,d0                { is there a file access error? }
+             bne     @noerr
+             jsr     _LVOIoErr(a6)
+             move.w  d0,errno              { Global variable, so no need    }
+      @noerr:                              { to restore base pointer now    }
+             move.l  d6,a6                 { Restore base pointer           }
+      end;
+  If Errno <> 0 then
+    Error2InOut;
+end;
+
+
+procedure do_open(var f;p:pchar;flags:longint);
+{
+  filerec and textrec have both handle and mode as the first items so
+  they could use the same routine for opening/creating.
+  when (flags and $100)   the file will be append
+  when (flags and $1000)  the file will be truncate/rewritten
+  when (flags and $10000) there is no check for close (needed for textfiles)
+}
+var
+  i,j : longint;
+  oflags: longint;
+  path : string;
+  buffer : array[0..255] of char;
+  index : integer;
+  s : string;
+begin
+ path:=strpas(p);
+ for index:=1 to length(path) do
+   if path[index]='\' then path[index]:='/';
+ { remove any dot characters and replace by their current }
+ { directory equivalent.                                  }
+ if pos('../',path) = 1 then
+ { look for parent directory }
+    Begin
+       delete(path,1,3);
+       getdir(0,s);
+       j:=length(s);
+       while (s[j] <> '/') AND (s[j] <> ':') AND (j > 0 ) do
+         dec(j);
+       if j > 0 then
+         s:=copy(s,1,j);
+       path:=s+path;
+    end
+ else
+ if pos('./',path) = 1 then
+ { look for current directory }
+    Begin
+       delete(path,1,2);
+       getdir(0,s);
+       if (s[length(s)] <> '/') and (s[length(s)] <> ':') then
+          s:=s+'/';
+       path:=s+path;
+    end;
+  move(path[1],buffer,length(path));
+  buffer[length(path)]:=#0;
+ { close first if opened }
+  if ((flags and $10000)=0) then
+   begin
+     case filerec(f).mode of
+      fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
+      fmclosed : ;
+     else
+      begin
+        inoutres:=102; {not assigned}
+        exit;
+      end;
+     end;
+   end;
+{ reset file handle }
+  filerec(f).handle:=UnusedHandle;
+{ convert filemode to filerec modes }
+  { READ/WRITE on existing file }
+  { RESET/APPEND                }
+  oflags := 1005;
+  case (flags and 3) of
+   0 : begin
+         filerec(f).mode:=fminput;
+       end;
+   1 : filerec(f).mode:=fmoutput;
+   2 : filerec(f).mode:=fminout;
+  end;
+  { READ/WRITE mode, create file in all cases }
+  { REWRITE                                   }
+  if (flags and $1000)<>0 then
+   begin
+     filerec(f).mode:=fmoutput;
+     oflags := 1006;
+   end
+  else
+  { READ/WRITE mode on existing file }
+  { APPEND                           }
+   if (flags and $100)<>0 then
+    begin
+      filerec(f).mode:=fmoutput;
+      oflags := 1005;
+    end;
+{ empty name is special }
+  if p[0]=#0 then
+   begin
+     case filerec(f).mode of
+       fminput : filerec(f).handle:=StdInputHandle;
+      fmappend,
+      fmoutput : begin
+                   filerec(f).handle:=StdOutputHandle;
+                   filerec(f).mode:=fmoutput; {fool fmappend}
+                 end;
+     end;
+     exit;
+   end;
+         asm
+             move.l  a6,d6                  { save a6 }
+             move.l  d2,-(sp)
+             lea     buffer,a0
+             move.l  a0,d1
+             move.l  oflags,d2               { MODE_READWRITE }
+             move.l  _DOSBase,a6
+             jsr     _LVOOpen(a6)
+             tst.l   d0
+             bne     @noopenerror           { on zero an error occured }
+             jsr     _LVOIoErr(a6)
+             move.w  d0,errno
+             bra     @openend
+          @noopenerror:
+             move.l  (sp)+,d2
+             move.l  d6,a6                 { restore a6 }
+             move.l  d0,i                  { we need the base pointer to access this variable }
+             bra     @end
+          @openend:
+             move.l  d6,a6                 { restore a6 }
+             move.l  (sp)+,d2
+          @end:
+         end;
+(*    if Errno = 0 then*)
+    { No error, add file handle to linked list }
+    { this must be checked before the call to  }
+    { Error2InIOut since it resets Errno to 0  }
+(*      AddToList(FileList,i);*)
+    If Errno <> 0 then
+       Error2InOut;
+
+    filerec(f).handle:=i;
+    if (flags and $100)<>0 then
+       do_seekend(filerec(f).handle);
+
+end;
+
+{*****************************************************************************
+                           UnTyped File Handling
+*****************************************************************************}
+
+{$i file.inc}
+
+{*****************************************************************************
+                           Typed File Handling
+*****************************************************************************}
+
+{$i typefile.inc}
+
+{*****************************************************************************
+                           Text File Handling
+*****************************************************************************}
+
+{$i text.inc}
+
+{*****************************************************************************
+                           Directory Handling
+*****************************************************************************}
+
+procedure mkdir(const s : string);[IOCheck];
+var
+  buffer : array[0..255] of char;
+  j: Integer;
+  temp : string;
+begin
+  { We must check the Ctrl-C before IOChecking of course! }
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  If InOutRes <> 0 then exit;
+  temp:=s;
+  for j:=1 to length(temp) do
+    if temp[j] = '\' then temp[j] := '/';
+  move(temp[1],buffer,length(temp));
+  buffer[length(temp)]:=#0;
+  asm
+        move.l  a6,d6
+        { we must load the parameters BEFORE setting up the }
+        { OS call with a6                                   }
+        lea     buffer,a0
+        move.l  a0,d1
+        move.l  _DosBase,a6
+        jsr     _LVOCreateDir(a6)
+        tst.l   d0
+        bne     @noerror
+        jsr     _LVOIoErr(a6)
+        move.w  d0,errno
+        bra     @end
+@noerror:
+        { Now we must unlock the directory }
+        { d0 = lock returned by create dir }
+        move.l  d0,d1
+        jsr     _LVOUnlock(a6)
+@end:
+        { restore base pointer }
+        move.l  d6,a6
+  end;
+  If errno <> 0 then
+    Error2InOut;
+end;
+
+
+procedure rmdir(const s : string);[IOCheck];
+var
+  buffer : array[0..255] of char;
+  j : Integer;
+  temp : string;
+begin
+  { We must check the Ctrl-C before IOChecking of course! }
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  If InOutRes <> 0 then exit;
+  temp:=s;
+  for j:=1 to length(temp) do
+    if temp[j] = '\' then temp[j] := '/';
+  move(temp[1],buffer,length(temp));
+  buffer[length(temp)]:=#0;
+  do_erase(buffer);
+end;
+
+
+
+procedure chdir(const s : string);[IOCheck];
+var
+  buffer : array[0..255] of char;
+  alock : longint;
+  FIB :pFileInfoBlock;
+  j: integer;
+  temp : string;
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+   Begin
+     { Clear CTRL-C signal }
+     SetSignal(0,SIGBREAKF_CTRL_C);
+     Halt(CTRL_C);
+   end;
+  If InOutRes <> 0 then exit;
+  temp:=s;
+  for j:=1 to length(temp) do
+    if temp[j] = '\' then temp[j] := '/';
+  { Return parent directory }
+  if s = '..' then
+  Begin
+       getdir(0,temp);
+       j:=length(temp);
+       { Look through the previous paths }
+       while (temp[j] <> '/') AND (temp[j] <> ':') AND (j > 0 ) do
+         dec(j);
+       if j > 0 then
+         temp:=copy(temp,1,j);
+  end;
+  alock := 0;
+  fib:=nil;
+  new(fib);
+
+  move(temp[1],buffer,length(temp));
+  buffer[length(temp)]:=#0;
+  { Changing the directory is a pretty complicated affair }
+  {   1) Obtain a lock on the directory                   }
+  {   2) CurrentDir the lock                              }
+  asm
+    lea      buffer,a0
+    move.l   a0,d1      { pointer to buffer in d1  }
+    move.l   d2,-(sp)   { save d2 register         }
+    move.l   #-2,d2     { ACCESS_READ lock         }
+    move.l   a6,d6      { Save base pointer        }
+    move.l   _DosBase,a6
+    jsr      _LVOLock(a6){ Lock the directory      }
+    move.l   (sp)+,d2   { Restore d2 register      }
+    tst.l    d0         { zero = error!            }
+    bne      @noerror
+    jsr      _LVOIoErr(a6)
+    move.w   d0,errno
+    move.l   d6,a6       { reset base pointer       }
+    bra      @End
+  @noerror:
+    move.l   d6,a6       { reset base pointer       }
+    move.l   d0,alock    { save the lock            }
+  @End:
+  end;
+  If errno <> 0 then
+   Begin
+     Error2InOut;
+     exit;
+   end;
+  if (Examine(alock, fib^) = TRUE) AND (fib^.fib_DirEntryType > 0) then
+    Begin
+      alock := CurrentDir(alock);
+      if OrigDir = 0 then
+        Begin
+          OrigDir := alock;
+          alock := 0;
+        end;
+    end;
+  if alock <> 0 then
+    Unlock(alock);
+  if assigned(fib) then dispose(fib);
+end;
+
+
+
+
+  Procedure GetCwd(var path: string);
+   var
+     lock: longint;
+     fib: PfileInfoBlock;
+     len : integer;
+     newlock : longint;
+     elen : integer;
+     Process : PProcess;
+    Begin
+     len := 0;
+     path := '';
+     fib := nil;
+     { By using a pointer instead of a local variable}
+     { we are assured that the pointer is aligned on }
+     { a dword boundary.                             }
+     new(fib);
+     Process := FindTask(nil);
+     if (process^.pr_Task.tc_Node.ln_Type = NT_TASK) then
+       Begin
+         path:='';
+         exit;
+       end;
+     lock := DupLock(process^.pr_CurrentDir);
+     if (Lock = 0) then
+       Begin
+         path:='';
+         exit;
+       end;
+
+    While (lock <> 0) and (Examine(lock,FIB^) = TRUE) do
+    Begin
+         elen := strlen(fib^.fib_FileName);
+         if (len + elen + 2 > 255) then
+            break;
+         newlock := ParentDir(lock);
+         if (len <> 0) then
+          Begin
+            if (newlock <> 0) then
+               path:='/'+path
+            else
+               path:=':'+path;
+            path:=strpas(fib^.fib_FileName)+path;
+            Inc(len);
+          end
+         else
+          Begin
+            path:=strpas(fib^.fib_Filename);
+            if (newlock = 0) then
+             path:=path+':';
+          end;
+
+               len := len + elen;
+
+               UnLock(lock);
+               lock := newlock;
+    end;
+    if (lock <> 0) then
+    Begin
+            UnLock(lock);
+            path := '';
+    end;
+    if assigned(fib) then dispose(fib);
+ end;
+
+
+procedure getdir(drivenr : byte;var dir : string);
+begin
+  if (Setsignal(0,0) AND SIGBREAKF_CTRL_C) <> 0 then
+    Begin
+      { Clear CTRL-C signal }
+      SetSignal(0,SIGBREAKF_CTRL_C);
+      Halt(CTRL_C);
+    end;
+  GetCwd(dir);
+  If errno <> 0 then
+     Error2InOut;
+end;
+
+
+{*****************************************************************************
+                         SystemUnit Initialization
+*****************************************************************************}
+
+Procedure Startup; Assembler;
+asm
+    move.l  a6,d6         { save a6             }
+
+    move.l  (4),a6        { get ExecBase pointer }
+    move.l  a6,_ExecBase
+    suba.l  a1,a1
+    jsr     _LVOFindTask(a6)
+    move.l  d0,a0
+    { Check the stack value }
+
+    {   are we running from a CLI?             }
+
+    tst.l   172(a0)         { 172 = pr_CLI     }
+    bne     @fromCLI
+
+    { we do not support Workbench yet ..       }
+    move.l  d6,a6           { restore a6       }
+    move.l  #1,d0
+    jsr     HALT_ERROR
+
+@fromCLI:
+    {  Open the following libraries:            }
+    {   Intuition.library                       }
+    {   dos.library                             }
+
+    moveq.l  #0,d0
+    move.l   intuitionname,a1      { directly since it is a pchar }
+    jsr      _LVOOpenLibrary(a6)
+    move.l   d0,_IntuitionBase
+    beq      @exitprg
+
+    moveq.l  #0,d0
+    move.l   utilityname,a1        { directly since it is a pchar }
+    jsr      _LVOOpenLibrary(a6)
+    move.l   d0,_UtilityBase
+    beq      @exitprg
+
+    moveq.l  #0,d0
+    move.l   dosname,a1            { directly since it is a pchar }
+    jsr      _LVOOpenLibrary(a6)
+    move.l   d0,_DOSBase
+    beq      @exitprg
+
+    { Find standard input and output               }
+    { for CLI                                      }
+@OpenFiles:
+    move.l  _DOSBase,a6
+    jsr     _LVOInput(a6)        { get standard in                   }
+    move.l  d0, StdInputHandle   { save standard Input handle        }
+{    move.l  d0,d1               }{ set up for next call              }
+{   jsr     _LVOIsInteractive(a6)}{ is it interactive?             }
+{   move.l  #_Input,a0          }{ get file record again             }
+{   move.b  d0,INTERACTIVE(a0)  }{ set flag                          }
+{   beq     StdInNotInteractive }{ skip this if not interactive    }
+{   move.l  BUFFER(a0),a1       }{ get buffer address                }
+{   add.l   #1,a1               }{ make end one byte further on      }
+{   move.l  a1,MAX(a0)          }{ set buffer size                   }
+{   move.l  a1,CURRENT(a0)      }{ will need a read                  }
+    bra     @OpenStdOutput
+@StdInNotInteractive
+{    jsr _p%FillBuffer     }      { fill the buffer                   }
+@OpenStdOutput
+    jsr     _LVOOutput(a6)      { get ouput file handle             }
+    move.l  d0,StdOutputHandle  { get file record                   }
+    bra     @startupend
+{    move.l  d0,d1             }  { set up for call                   }
+{    jsr _LVOIsInteractive(a6) }  { is it interactive?                }
+{    move.l  #_Output,a0       }  { get file record                   }
+{    move.b  d0,INTERACTIVE(a0)}  { set flag                          }
+@exitprg:
+     move.l d6,a6                 { restore a6                        }
+     move.l #219,d0
+     jsr    HALT_ERROR
+@startupend:
+     move.l d6,a6                 { restore a6                        }
+end;
+
+
+
+begin
+  errno:= 0;
+  FromHalt := FALSE;
+{  Initial state is on -- in case of RunErrors before the i/o handles are }
+{  ok.                                                                    }
+  Initial:=TRUE;
+{ Initialize ExitProc }
+  ExitProc:=Nil;
+  Startup;
+{ to test stack depth }
+  loweststack:=maxlongint;
+{ Setup heap }
+  InitHeap;
+{ Setup stdin, stdout and stderr }
+  OpenStdIO(Input,fmInput,StdInputHandle);
+  OpenStdIO(Output,fmOutput,StdOutputHandle);
+  OpenStdIO(StdOut,fmOutput,StdOutputHandle);
+  { The Amiga does not seem to have a StdError }
+  { handle, therefore make the StdError handle }
+  { equal to the StdOutputHandle.              }
+  StdErrorHandle := StdOutputHandle;
+  OpenStdIO(StdErr,fmOutput,StdErrorHandle);
+{ Now Handles and function handlers are setup }
+{ correctly.                                  }
+  Initial:=FALSE;
+{ Reset IO Error }
+  InOutRes:=0;
+{ Startup }
+  { Only AmigaOS v2.04 or greater is supported }
+  If KickVersion < 36 then
+   Begin
+     WriteLn('v36 or greater of Kickstart required.');
+     Halt(1);
+   end;
+   argc:=GetParamCount(args);
+   OrigDir := 0;
+   FileList := nil;
+end.
+
+
+{
+  $Log$
+  Revision 1.1  2001-03-16 20:01:47  hajny
+    + system unit name change
+
+  Revision 1.1  2000/07/13 06:30:29  michael
+  + Initial import
+
+  Revision 1.15  2000/01/07 16:41:29  daniel
+    * copyright 2000
+
+  Revision 1.14  2000/01/07 16:32:22  daniel
+    * copyright 2000 added
+
+  Revision 1.13  1999/09/10 15:40:32  peter
+    * fixed do_open flags to be > $100, becuase filemode can be upto 255
+
+  Revision 1.12  1999/01/18 10:05:47  pierre
+   + system_exit procedure added
+
+  Revision 1.11  1998/12/28 15:50:42  peter
+    + stdout, which is needed when you write something in the system unit
+      to the screen. Like the runtime error
+
+  Revision 1.10  1998/09/14 10:48:00  peter
+    * FPC_ names
+    * Heap manager is now system independent
+
+  Revision 1.9  1998/08/17 12:34:22  carl
+    * chdir accepts .. characters
+    + added ctrl-c checking
+    + implemented sbrk
+    * exit code was never called if no error was found on exit!
+    * register was not saved in do_open
+
+  Revision 1.8  1998/07/13 12:32:18  carl
+    * do_truncate works, some cleanup
+
+  Revision 1.6  1998/07/02 12:37:52  carl
+    * IOCheck for chdir,rmdir and mkdir as in TP
+
+  Revision 1.5  1998/07/01 14:30:56  carl
+    * forgot that includes are case sensitive
+
+  Revision 1.4  1998/07/01 14:13:50  carl
+    * do_open bugfix
+    * correct conversion of Amiga error codes to TP error codes
+    * InoutRes word bugfix
+    * parameter counting fixed
+    * new stack checking implemented
+    + IOCheck for chdir,rmdir,getdir and rmdir
+    * do_filepos was wrong
+    + chdir correctly implemented
+    * getdir correctly implemented
+
+  Revision 1.1.1.1  1998/03/25 11:18:47  root
+  * Restored version
+
+  Revision 1.14  1998/03/21 04:20:09  carl
+    * correct ExecBase pointer (from Nils Sjoholm)
+    * correct OpenLibrary vector (from Nils Sjoholm)
+
+  Revision 1.13  1998/03/14 21:34:32  carl
+    * forgot to save a6 in Startup routine
+
+  Revision 1.12  1998/02/24 21:19:42  carl
+  *** empty log message ***
+
+  Revision 1.11  1998/02/23 02:22:49  carl
+    * bugfix if linking problems
+
+  Revision 1.9  1998/02/06 16:34:32  carl
+    + do_open is now standard with other platforms
+
+  Revision 1.8  1998/02/02 15:01:45  carl
+    * fixed bug with opening library versions (from Nils Sjoholm)
+
+  Revision 1.7  1998/01/31 19:35:19  carl
+    + added opening of utility.library
+
+  Revision 1.6  1998/01/29 23:20:54  peter
+    - Removed Backslash convert
+
+  Revision 1.5  1998/01/27 10:55:04  peter
+    * Amiga uses / not \, so change AllowSlash -> AllowBackSlash
+
+  Revision 1.4  1998/01/25 21:53:20  peter
+    + Universal Handles support for StdIn/StdOut/StdErr
+    * Updated layout of sysamiga.pas
+
+  Revision 1.3  1998/01/24 21:09:53  carl
+    + added missing input/output function pointers
+
+  Revision 1.2  1998/01/24 14:08:25  carl
+    * RunError 217 --> RunError 219 (cannot open lib)
+    + Standard Handle names implemented
+
+  Revision 1.1  1998/01/24 05:12:15  carl
+    + initial revision, some stuff still missing though.
+      (and as you might imagine ... untested :))
+}

+ 1 - 804
rtl/atari/sysatari.pas

@@ -1,804 +1 @@
-{
-    $Id$
-    This file is part of the Free Pascal run time library.
-    Copyright (c) 1999-2000 by Carl Eric Codere
-    member of the Free Pascal development team
-
-    See the file COPYING.FPC, included in this distribution,
-    for details about the copyright.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- **********************************************************************}
-{$define ATARI}
-unit sysatari;
-
-{--------------------------------------------------------------------}
-{ LEFT TO DO:                                                        }
-{--------------------------------------------------------------------}
-{ o SBrk                                                             }
-{ o Implement truncate                                               }
-{ o Implement paramstr(0)                                            }
-{--------------------------------------------------------------------}
-
-
-{$I os.inc}
-
-  interface
-
-    { used for single computations }
-    const BIAS4 = $7f-1;
-
-    {$I systemh.inc}
-
-    {$I heaph.inc}
-
-const
-  UnusedHandle    = $ffff;
-  StdInputHandle  = 0;
-  StdOutputHandle = 1;
-  StdErrorHandle  = $ffff;
-
-
-
-  implementation
-
-    {$I system.inc}
-    {$I lowmath.inc}
-
-
-    const
-      argc : longint = 0;
-
-
-    var
-      errno : integer;
-
-{$S-}
-    procedure Stack_Check; assembler;
-    { Check for local variable allocation }
-    { On Entry -> d0 : size of local stack we are trying to allocate }
-         asm
-          XDEF STACKCHECK
-           move.l  sp,d1            { get value of stack pointer            }
-           sub.l   d0,d1            {  sp - stack_size                      }
-           sub.l   #2048,d1
-           cmp.l   __BREAK,d1
-           bgt     @st1nosweat
-           move.l  #202,d0
-           jsr     HALT_ERROR
-         @st1nosweat:
-         end;
-
-
-    Procedure Error2InOut;
-    Begin
-     if (errno <= -2) and (errno >= -11) then
-       InOutRes:=150-errno  { 150+errno }
-     else
-      Begin
-        case errno of
-          -32 : InOutRes:=1;
-          -33 : InOutRes:=2;
-          -34 : InOutRes:=3;
-          -35 : InOutRes:=4;
-          -36 : InOutRes:=5;
-          -37 : InOutRes:=8;
-          -39 : InOutRes:=8;
-          -40 : InOutRes:=9;
-          -46 : InOutRes:=15;
-          -67..-64 : InOutRes:=153;
-          -15 : InOutRes:=151;
-          -13 : InOutRes:=150;
-        else
-           InOutres := word(errno);
-         end;
-     end;
-     errno:=0;
-    end;
-
-
-
-    procedure halt(errnum : byte);
-
-      begin
-         do_exit;
-         flush(stderr);
-         asm
-            clr.l   d0
-            move.b  errnum,d0
-            move.w  d0,-(sp)
-            move.w  #$4c,-(sp)
-            trap    #1
-         end;
-      end;
-
-
-      function args : pointer; assembler;
-      asm
-         move.l __ARGS,d0
-      end;
-
-
-
-
-   Function GetParamCount(const p: pchar): longint;
-   var
-    i: word;
-    count: word;
-   Begin
-    i:=0;
-    count:=0;
-    while p[count] <> #0 do
-     Begin
-       if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
-       Begin
-          i:=i+1;
-          while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
-           count:=count+1;
-       end;
-       if p[count] = #0 then break;
-       count:=count+1;
-     end;
-     GetParamCount:=longint(i);
-   end;
-
-
-   Function GetParam(index: word; const p : pchar): string;
-   { On Entry: index = string index to correct parameter  }
-   { On exit:  = correct character index into pchar array }
-   { Returns correct index to command line argument }
-   var
-    count: word;
-    localindex: word;
-    l: byte;
-    temp: string;
-   Begin
-     temp:='';
-     count := 0;
-     { first index is one }
-     localindex := 1;
-     l:=0;
-     While p[count] <> #0 do
-       Begin
-         if (p[count] <> ' ') and (p[count] <> #9) then
-           Begin
-             if localindex = index then
-              Begin
-               while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
-                Begin
-                  temp:=temp+p[count];
-                  l:=l+1;
-                  count:=count+1;
-                end;
-                temp[0]:=char(l);
-                GetParam:=temp;
-                exit;
-              end;
-             { Point to next argument in list }
-             while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
-               Begin
-                 count:=count+1;
-               end;
-             localindex:=localindex+1;
-           end;
-         if p[count] = #0 then break;
-         count:=count+1;
-       end;
-     GetParam:=temp;
-   end;
-
-
-    function paramstr(l : longint) : string;
-      var
-       p : pchar;
-       s1 : string;
-      begin
-         if l = 0 then
-         Begin
-           s1 := '';
-         end
-         else
-         if (l>0) and (l<=paramcount) then
-           begin
-             p:=args;
-             paramstr:=GetParam(word(l),p);
-           end
-         else paramstr:='';
-      end;
-
-      function paramcount : longint;
-      Begin
-        paramcount := argc;
-      end;
-
-
-
-
-    procedure randomize;
-
-      var
-         hl : longint;
-
-      begin
-         asm
-           movem.l d2/d3/a2/a3, -(sp)     { save OS registers }
-           move.w #17,-(sp)
-           trap   #14         { call xbios - random number }
-           add.l  #2,sp
-           movem.l (sp)+,d2/d3/a2/a3
-           move.l d0,hl       { result in d0 }
-         end;
-         randseed:=hl;
-      end;
-
-function getheapstart:pointer;assembler;
-asm
-        lea.l   HEAP,a0
-        move.l  a0,d0
-end;
-
-
-function getheapsize:longint;assembler;
-asm
-       move.l   HEAP_SIZE,d0
-end ['D0'];
-
-  { This routine is used to grow the heap.  }
-  { But here we do a trick, we say that the }
-  { heap cannot be regrown!                 }
-  function sbrk( size: longint): longint;
-  { on exit -1 = if fails.               }
-  Begin
-   sbrk:=-1;
-  end;
-
-{$I heap.inc}
-
-
-{****************************************************************************
-                          Low Level File Routines
- ****************************************************************************}
-
-procedure AllowSlash(p:pchar);
-var
-  i : longint;
-begin
-{ allow slash as backslash }
-  for i:=0 to strlen(p) do
-   if p[i]='/' then p[i]:='\';
-end;
-
-
-procedure do_close(h : longint);
-begin
-  asm
-        movem.l d2/d3/a2/a3,-(sp)
-        move.l  h,d0
-        move.w  d0,-(sp)
-        move.w  #$3e,-(sp)
-        trap    #1
-        add.l   #4,sp      { restore stack ... }
-        movem.l (sp)+,d2/d3/a2/a3
-  end;
-end;
-
-
-procedure do_erase(p : pchar);
-begin
-  AllowSlash(p);
-  asm
-        move.l  d2,d6            { save d2   }
-        movem.l d3/a2/a3,-(sp)   { save regs }
-        move.l  p,-(sp)
-        move.w #$41,-(sp)
-        trap   #1
-        add.l  #6,sp
-        move.l d6,d2       { restore d2 }
-        movem.l (sp)+,d3/a2/a3
-        tst.w  d0
-        beq    @doserend
-        move.w d0,errno
-        @doserend:
-  end;
-  if errno <> 0 then
-     Error2InOut;
-end;
-
-
-procedure do_rename(p1,p2 : pchar);
-begin
-  AllowSlash(p1);
-  AllowSlash(p2);
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-            move.l  p1,-(sp)
-            move.l  p2,-(sp)
-            clr.w   -(sp)
-            move.w  #$56,-(sp)
-            trap    #1
-            lea     12(sp),sp
-            move.l  d6,d2       { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-            tst.w   d0
-            beq     @dosreend
-            move.w  d0,errno    { error ... }
-         @dosreend:
-  end;
-  if errno <> 0 then
-     Error2InOut;
-end;
-
-function do_isdevice(handle:word):boolean;
-begin
-  if (handle=stdoutputhandle) or (handle=stdinputhandle) or
-  (handle=stderrorhandle) then
-    do_isdevice:=FALSE
-  else
-    do_isdevice:=TRUE;
-end;
-
-
-function do_write(h,addr,len : longint) : longint;
-begin
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-            move.l  addr,-(sp)
-            move.l  len,-(sp)
-            move.l  h,d0
-            move.w  d0,-(sp)
-            move.w  #$40,-(sp)
-            trap    #1
-            lea     12(sp),sp
-            move.l d6,d2       { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-            tst.l   d0
-            bpl     @doswrend
-            move.w  d0,errno    { error ... }
-          @doswrend:
-            move.l  d0,@RESULT
-  end;
-  if errno <> 0 then
-     Error2InOut;
-end;
-
-
-function do_read(h,addr,len : longint) : longint;
-begin
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-            move.l addr,-(sp)
-            move.l len,-(sp)
-            move.l h,d0
-            move.w d0,-(sp)
-            move.w #$3f,-(sp)
-            trap   #1
-            lea    12(sp),sp
-            move.l d6,d2       { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-            tst.l   d0
-            bpl     @dosrdend
-            move.w  d0,errno    { error ... }
-          @dosrdend:
-            move.l  d0,@Result
-  end;
-  if errno <> 0 then
-     Error2InOut;
-end;
-
-
-function do_filepos(handle : longint) : longint;
-begin
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-            move.w #1,-(sp)     { seek from current position }
-            move.l handle,d0
-            move.w d0,-(sp)
-            move.l #0,-(sp)     { with a seek offset of zero }
-            move.w #$42,-(sp)
-            trap   #1
-            lea    10(sp),sp
-            move.l d6,d2       { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-            move.l d0,@Result
-  end;
-end;
-
-
-procedure do_seek(handle,pos : longint);
-begin
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-            move.w #0,-(sp)     { seek from start of file    }
-            move.l handle,d0
-            move.w d0,-(sp)
-            move.l pos,-(sp)
-            move.w #$42,-(sp)
-            trap   #1
-            lea    10(sp),sp
-            move.l d6,d2       { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-  end;
-end;
-
-
-function do_seekend(handle:longint):longint;
-var
- t: longint;
-begin
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-            move.w #2,-(sp)     { seek from end of file        }
-            move.l handle,d0
-            move.w d0,-(sp)
-            move.l #0,-(sp)     { with an offset of 0 from end }
-            move.w #$42,-(sp)
-            trap   #1
-            lea    10(sp),sp
-            move.l d6,d2       { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-            move.l d0,t
-  end;
-   do_seekend:=t;
-end;
-
-
-function do_filesize(handle : longint) : longint;
-var
-   aktfilepos : longint;
-begin
-   aktfilepos:=do_filepos(handle);
-   do_filesize:=do_seekend(handle);
-   do_seek(handle,aktfilepos);
-end;
-
-
-procedure do_truncate (handle,pos:longint);
-begin
-  do_seek(handle,pos);
-  {!!!!!!!!!!!!}
-end;
-
-
-procedure do_open(var f;p:pchar;flags:longint);
-{
-  filerec and textrec have both handle and mode as the first items so
-  they could use the same routine for opening/creating.
-  when (flags and $100)   the file will be append
-  when (flags and $1000)  the file will be truncate/rewritten
-  when (flags and $10000) there is no check for close (needed for textfiles)
-}
-var
-  i : word;
-  oflags: longint;
-begin
-  AllowSlash(p);
- { close first if opened }
-  if ((flags and $10000)=0) then
-   begin
-     case filerec(f).mode of
-      fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
-      fmclosed : ;
-     else
-      begin
-        inoutres:=102; {not assigned}
-        exit;
-      end;
-     end;
-   end;
-{ reset file handle }
-  filerec(f).handle:=UnusedHandle;
-  oflags:=$02; { read/write mode }
-{ convert filemode to filerec modes }
-  case (flags and 3) of
-   0 : begin
-         filerec(f).mode:=fminput;
-         oflags:=$00; { read mode only }
-       end;
-   1 : filerec(f).mode:=fmoutput;
-   2 : filerec(f).mode:=fminout;
-  end;
-  if (flags and $1000)<>0 then
-   begin
-     filerec(f).mode:=fmoutput;
-     oflags:=$04;  { read/write with create }
-   end
-  else
-   if (flags and $100)<>0 then
-    begin
-      filerec(f).mode:=fmoutput;
-      oflags:=$02;  { read/write             }
-    end;
-{ empty name is special }
-  if p[0]=#0 then
-   begin
-     case filerec(f).mode of
-       fminput : filerec(f).handle:=StdInputHandle;
-      fmappend,
-      fmoutput : begin
-                   filerec(f).handle:=StdOutputHandle;
-                   filerec(f).mode:=fmoutput; {fool fmappend}
-                 end;
-     end;
-     exit;
-   end;
-   asm
-      movem.l d2/d3/a2/a3,-(sp)    { save used registers }
-
-      cmp.l   #4,oflags    { check if rewrite mode ... }
-      bne     @opencont2
-      { rewrite mode - create new file }
-      move.w  #0,-(sp)
-      move.l  p,-(sp)
-      move.w  #$3c,-(sp)
-      trap    #1
-      add.l   #8,sp       { restore stack of os call }
-      bra     @end
-      { reset - open existing files     }
-    @opencont2:
-      move.l  oflags,d0    { use flag as source  ...    }
-    @opencont1:
-      move.w  d0,-(sp)
-      move.l  p,-(sp)
-      move.w  #$3d,-(sp)
-      trap    #1
-      add.l   #8,sp       { restore stack of os call }
-   @end:
-      movem.l (sp)+,d2/d3/a2/a3
-
-      tst.w   d0
-      bpl     @opennoerr  { if positive return values then ok }
-      cmp.w   #-1,d0      { if handle is -1 CON:              }
-      beq     @opennoerr
-      cmp.w   #-2,d0      { if handle is -2 AUX:              }
-      beq     @opennoerr
-      cmp.w   #-3,d0      { if handle is -3 PRN:              }
-      beq     @opennoerr
-      move.w  d0,errno    { otherwise normal error            }
-    @opennoerr:
-      move.w  d0,i        { get handle as SIGNED VALUE...     }
-    end;
-  if errno <> 0 then
-     Error2InOut;
-  filerec(f).handle:=i;
-  if (flags and $100)<>0 then
-   do_seekend(filerec(f).handle);
-end;
-
-{*****************************************************************************
-                           UnTyped File Handling
-*****************************************************************************}
-
-{$i file.inc}
-
-{*****************************************************************************
-                           Typed File Handling
-*****************************************************************************}
-
-{$i typefile.inc}
-
-{*****************************************************************************
-                           Text File Handling
-*****************************************************************************}
-
-{$i text.inc}
-
-{*****************************************************************************
-                           Directory Handling
-*****************************************************************************}
-
-procedure DosDir(func:byte;const s:string);
-var
-  buffer : array[0..255] of char;
-  c : word;
-begin
-  move(s[1],buffer,length(s));
-  buffer[length(s)]:=#0;
-  AllowSlash(pchar(@buffer));
-  c:=word(func);
-  asm
-        move.l  d2,d6      { save d2 }
-        movem.l d3/a2/a3,-(sp)
-        pea     buffer
-        move.w  c,-(sp)
-        trap    #1
-        add.l   #6,sp
-        move.l  d6,d2       { restore d2 }
-        movem.l (sp)+,d3/a2/a3
-        tst.w   d0
-        beq     @dosdirend
-        move.w  d0,errno
-     @dosdirend:
-  end;
-  if errno <> 0 then
-     Error2InOut;
-end;
-
-
-procedure mkdir(const s : string);[IOCheck];
-begin
-  If InOutRes <> 0 then exit;
-  DosDir($39,s);
-end;
-
-
-procedure rmdir(const s : string);[IOCheck];
-begin
-  If InOutRes <> 0 then exit;
-  DosDir($3a,s);
-end;
-
-
-procedure chdir(const s : string);[IOCheck];
-begin
-  If InOutRes <> 0 then exit;
-  DosDir($3b,s);
-end;
-
-
-procedure getdir(drivenr : byte;var dir : string);
-var
-  temp : array[0..255] of char;
-  i    : longint;
-  j: byte;
-  drv: word;
-begin
-  drv:=word(drivenr);
-  asm
-            move.l  d2,d6      { save d2 }
-            movem.l d3/a2/a3,-(sp)
-
-            { Get dir from drivenr : 0=default, 1=A etc... }
-            move.w drv,-(sp)
-
-            { put (previously saved) offset in si }
-{            move.l temp,-(sp)}
-             pea   temp
-
-            { call attos function 47H : Get dir }
-            move.w #$47,-(sp)
-
-            { make the call }
-            trap   #1
-            add.l  #8,sp
-
-            move.l d6,d2         { restore d2 }
-            movem.l (sp)+,d3/a2/a3
-  end;
-  { conversion to pascal string }
-  i:=0;
-  while (temp[i]<>#0) do
-   begin
-     if temp[i]='/' then
-      temp[i]:='\';
-     dir[i+3]:=temp[i];
-     inc(i);
-   end;
-  dir[2]:=':';
-  dir[3]:='\';
-  dir[0]:=char(i+2);
-{ upcase the string (FPC Pascal function) }
-  dir:=upcase(dir);
-  if drivenr<>0 then   { Drive was supplied. We know it }
-   dir[1]:=chr(65+drivenr-1)
-  else
-   begin
-      asm
-        move.l  d2,d6      { save d2 }
-        movem.l d3/a2/a3,-(sp)
-        move.w #$19,-(sp)
-        trap   #1
-        add.l  #2,sp
-        move.w d0,drv
-        move.l d6,d2        { restore d2 }
-        movem.l (sp)+,d3/a2/a3
-     end;
-     dir[1]:=chr(byte(drv)+ord('A'));
-   end;
-end;
-
-
-{*****************************************************************************
-                         System Dependent Exit code
-*****************************************************************************}
-Procedure system_exit;
-begin
-end;
-
-{*****************************************************************************
-                         SystemUnit Initialization
-*****************************************************************************}
-
-
-begin
-{ Initialize ExitProc }
-  ExitProc:=Nil;
-{ to test stack depth }
-  loweststack:=maxlongint;
-{ Setup heap }
-  InitHeap;
-{ Setup stdin, stdout and stderr }
-  OpenStdIO(Input,fmInput,StdInputHandle);
-  OpenStdIO(Output,fmOutput,StdOutputHandle);
-  OpenStdIO(StdOut,fmOutput,StdOutputHandle);
-  OpenStdIO(StdErr,fmOutput,StdErrorHandle);
-{ Reset IO Error }
-  InOutRes:=0;
-  errno := 0;
-{ Setup command line arguments }
- argc:=GetParamCount(args);
-end.
-
-{
-  $Log$
-  Revision 1.2  2000-07-14 10:30:58  michael
-  +
-
-  Revision 1.1  2000/07/13 06:30:30  michael
-  + Initial import
-
-  Revision 1.14  2000/01/07 16:41:29  daniel
-    * copyright 2000
-
-  Revision 1.13  2000/01/07 16:32:23  daniel
-    * copyright 2000 added
-
-  Revision 1.12  1999/09/10 15:40:33  peter
-    * fixed do_open flags to be > $100, becuase filemode can be upto 255
-
-  Revision 1.11  1999/01/18 10:05:48  pierre
-   + system_exit procedure added
-
-  Revision 1.10  1998/12/28 15:50:43  peter
-    + stdout, which is needed when you write something in the system unit
-      to the screen. Like the runtime error
-
-  Revision 1.9  1998/09/14 10:48:02  peter
-    * FPC_ names
-    * Heap manager is now system independent
-
-  Revision 1.8  1998/07/15 12:11:59  carl
-    * hmmm... can't remember! :(...
-
-  Revision 1.5  1998/07/13 12:34:13  carl
-    + Error2InoutRes implemented
-    * do_read was doing a wrong os call!
-    * do_open was not pushing the right values
-    * DosDir was pushing the wrong params on the stack
-    * do_close would never works, was pushing a longint instead of word
-
-  Revision 1.4  1998/07/02 12:39:27  carl
-    * IOCheck for mkdir,chdir and rmdir, just like in TP
-
-  Revision 1.3  1998/07/01 14:40:20  carl
-    + new stack checking implemented
-    + IOCheck for chdir , getdir , mkdir and rmdir
-
-  Revision 1.1.1.1  1998/03/25 11:18:47  root
-  * Restored version
-
-  Revision 1.8  1998/02/23 02:27:39  carl
-    * make it link correctly
-
-  Revision 1.7  1998/02/06 16:33:02  carl
-    * oops... commited wrong file
-    + do_open is now standard with other platforms
-
-  Revision 1.5  1998/01/31 19:32:51  carl
-    - removed incorrect $define
-
-  Revision 1.4  1998/01/27 10:55:45  peter
-    * Word Handles from -1 -> $ffff
-
-  Revision 1.3  1998/01/25 22:44:14  peter
-    * Using uniform layout
-
-}
+{$i system.pp}

+ 815 - 0
rtl/atari/system.pas

@@ -0,0 +1,815 @@
+{
+    $Id$
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Carl Eric Codere
+    member of the Free Pascal development team
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+{$define ATARI}
+unit {$ifdef VER1_0}sysatari{$else}{$ifdef VER0_99}sysatari{$ELSE}system{$endif}{$ENDIF};
+
+{--------------------------------------------------------------------}
+{ LEFT TO DO:                                                        }
+{--------------------------------------------------------------------}
+{ o SBrk                                                             }
+{ o Implement truncate                                               }
+{ o Implement paramstr(0)                                            }
+{--------------------------------------------------------------------}
+
+
+{$I os.inc}
+
+  interface
+
+    { used for single computations }
+    const BIAS4 = $7f-1;
+
+    {$I systemh.inc}
+
+    {$I heaph.inc}
+
+const
+  UnusedHandle    = $ffff;
+  StdInputHandle  = 0;
+  StdOutputHandle = 1;
+  StdErrorHandle  = $ffff;
+
+
+
+  implementation
+
+    {$I system.inc}
+    {$I lowmath.inc}
+
+
+    const
+      argc : longint = 0;
+
+
+    var
+      errno : integer;
+
+{$S-}
+    procedure Stack_Check; assembler;
+    { Check for local variable allocation }
+    { On Entry -> d0 : size of local stack we are trying to allocate }
+         asm
+          XDEF STACKCHECK
+           move.l  sp,d1            { get value of stack pointer            }
+           sub.l   d0,d1            {  sp - stack_size                      }
+           sub.l   #2048,d1
+           cmp.l   __BREAK,d1
+           bgt     @st1nosweat
+           move.l  #202,d0
+           jsr     HALT_ERROR
+         @st1nosweat:
+         end;
+
+
+    Procedure Error2InOut;
+    Begin
+     if (errno <= -2) and (errno >= -11) then
+       InOutRes:=150-errno  { 150+errno }
+     else
+      Begin
+        case errno of
+          -32 : InOutRes:=1;
+          -33 : InOutRes:=2;
+          -34 : InOutRes:=3;
+          -35 : InOutRes:=4;
+          -36 : InOutRes:=5;
+          -37 : InOutRes:=8;
+          -39 : InOutRes:=8;
+          -40 : InOutRes:=9;
+          -46 : InOutRes:=15;
+          -67..-64 : InOutRes:=153;
+          -15 : InOutRes:=151;
+          -13 : InOutRes:=150;
+        else
+           InOutres := word(errno);
+         end;
+     end;
+     errno:=0;
+    end;
+
+
+
+    procedure halt(errnum : byte);
+
+      begin
+         do_exit;
+         flush(stderr);
+         asm
+            clr.l   d0
+            move.b  errnum,d0
+            move.w  d0,-(sp)
+            move.w  #$4c,-(sp)
+            trap    #1
+         end;
+      end;
+
+
+      function args : pointer; assembler;
+      asm
+         move.l __ARGS,d0
+      end;
+
+
+
+
+   Function GetParamCount(const p: pchar): longint;
+   var
+    i: word;
+    count: word;
+   Begin
+    i:=0;
+    count:=0;
+    while p[count] <> #0 do
+     Begin
+       if (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) then
+       Begin
+          i:=i+1;
+          while (p[count] <> ' ') and (p[count] <> #9) and (p[count] <> #0) do
+           count:=count+1;
+       end;
+       if p[count] = #0 then break;
+       count:=count+1;
+     end;
+     GetParamCount:=longint(i);
+   end;
+
+
+   Function GetParam(index: word; const p : pchar): string;
+   { On Entry: index = string index to correct parameter  }
+   { On exit:  = correct character index into pchar array }
+   { Returns correct index to command line argument }
+   var
+    count: word;
+    localindex: word;
+    l: byte;
+    temp: string;
+   Begin
+     temp:='';
+     count := 0;
+     { first index is one }
+     localindex := 1;
+     l:=0;
+     While p[count] <> #0 do
+       Begin
+         if (p[count] <> ' ') and (p[count] <> #9) then
+           Begin
+             if localindex = index then
+              Begin
+               while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) and (l < 256) do
+                Begin
+                  temp:=temp+p[count];
+                  l:=l+1;
+                  count:=count+1;
+                end;
+                temp[0]:=char(l);
+                GetParam:=temp;
+                exit;
+              end;
+             { Point to next argument in list }
+             while (p[count] <> #0) and (p[count] <> ' ') and (p[count] <> #9) do
+               Begin
+                 count:=count+1;
+               end;
+             localindex:=localindex+1;
+           end;
+         if p[count] = #0 then break;
+         count:=count+1;
+       end;
+     GetParam:=temp;
+   end;
+
+
+    function paramstr(l : longint) : string;
+      var
+       p : pchar;
+       s1 : string;
+      begin
+         if l = 0 then
+         Begin
+           s1 := '';
+         end
+         else
+         if (l>0) and (l<=paramcount) then
+           begin
+             p:=args;
+             paramstr:=GetParam(word(l),p);
+           end
+         else paramstr:='';
+      end;
+
+      function paramcount : longint;
+      Begin
+        paramcount := argc;
+      end;
+
+
+
+
+    procedure randomize;
+
+      var
+         hl : longint;
+
+      begin
+         asm
+           movem.l d2/d3/a2/a3, -(sp)     { save OS registers }
+           move.w #17,-(sp)
+           trap   #14         { call xbios - random number }
+           add.l  #2,sp
+           movem.l (sp)+,d2/d3/a2/a3
+           move.l d0,hl       { result in d0 }
+         end;
+         randseed:=hl;
+      end;
+
+function getheapstart:pointer;assembler;
+asm
+        lea.l   HEAP,a0
+        move.l  a0,d0
+end;
+
+
+function getheapsize:longint;assembler;
+asm
+       move.l   HEAP_SIZE,d0
+end ['D0'];
+
+  { This routine is used to grow the heap.  }
+  { But here we do a trick, we say that the }
+  { heap cannot be regrown!                 }
+  function sbrk( size: longint): longint;
+  { on exit -1 = if fails.               }
+  Begin
+   sbrk:=-1;
+  end;
+
+{$I heap.inc}
+
+
+{****************************************************************************
+                          Low Level File Routines
+ ****************************************************************************}
+
+procedure AllowSlash(p:pchar);
+var
+  i : longint;
+begin
+{ allow slash as backslash }
+  for i:=0 to strlen(p) do
+   if p[i]='/' then p[i]:='\';
+end;
+
+
+procedure do_close(h : longint);
+begin
+  asm
+        movem.l d2/d3/a2/a3,-(sp)
+        move.l  h,d0
+        move.w  d0,-(sp)
+        move.w  #$3e,-(sp)
+        trap    #1
+        add.l   #4,sp      { restore stack ... }
+        movem.l (sp)+,d2/d3/a2/a3
+  end;
+end;
+
+
+procedure do_erase(p : pchar);
+begin
+  AllowSlash(p);
+  asm
+        move.l  d2,d6            { save d2   }
+        movem.l d3/a2/a3,-(sp)   { save regs }
+        move.l  p,-(sp)
+        move.w #$41,-(sp)
+        trap   #1
+        add.l  #6,sp
+        move.l d6,d2       { restore d2 }
+        movem.l (sp)+,d3/a2/a3
+        tst.w  d0
+        beq    @doserend
+        move.w d0,errno
+        @doserend:
+  end;
+  if errno <> 0 then
+     Error2InOut;
+end;
+
+
+procedure do_rename(p1,p2 : pchar);
+begin
+  AllowSlash(p1);
+  AllowSlash(p2);
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+            move.l  p1,-(sp)
+            move.l  p2,-(sp)
+            clr.w   -(sp)
+            move.w  #$56,-(sp)
+            trap    #1
+            lea     12(sp),sp
+            move.l  d6,d2       { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+            tst.w   d0
+            beq     @dosreend
+            move.w  d0,errno    { error ... }
+         @dosreend:
+  end;
+  if errno <> 0 then
+     Error2InOut;
+end;
+
+function do_isdevice(handle:word):boolean;
+begin
+  if (handle=stdoutputhandle) or (handle=stdinputhandle) or
+  (handle=stderrorhandle) then
+    do_isdevice:=FALSE
+  else
+    do_isdevice:=TRUE;
+end;
+
+
+function do_write(h,addr,len : longint) : longint;
+begin
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+            move.l  addr,-(sp)
+            move.l  len,-(sp)
+            move.l  h,d0
+            move.w  d0,-(sp)
+            move.w  #$40,-(sp)
+            trap    #1
+            lea     12(sp),sp
+            move.l d6,d2       { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+            tst.l   d0
+            bpl     @doswrend
+            move.w  d0,errno    { error ... }
+          @doswrend:
+            move.l  d0,@RESULT
+  end;
+  if errno <> 0 then
+     Error2InOut;
+end;
+
+
+function do_read(h,addr,len : longint) : longint;
+begin
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+            move.l addr,-(sp)
+            move.l len,-(sp)
+            move.l h,d0
+            move.w d0,-(sp)
+            move.w #$3f,-(sp)
+            trap   #1
+            lea    12(sp),sp
+            move.l d6,d2       { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+            tst.l   d0
+            bpl     @dosrdend
+            move.w  d0,errno    { error ... }
+          @dosrdend:
+            move.l  d0,@Result
+  end;
+  if errno <> 0 then
+     Error2InOut;
+end;
+
+
+function do_filepos(handle : longint) : longint;
+begin
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+            move.w #1,-(sp)     { seek from current position }
+            move.l handle,d0
+            move.w d0,-(sp)
+            move.l #0,-(sp)     { with a seek offset of zero }
+            move.w #$42,-(sp)
+            trap   #1
+            lea    10(sp),sp
+            move.l d6,d2       { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+            move.l d0,@Result
+  end;
+end;
+
+
+procedure do_seek(handle,pos : longint);
+begin
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+            move.w #0,-(sp)     { seek from start of file    }
+            move.l handle,d0
+            move.w d0,-(sp)
+            move.l pos,-(sp)
+            move.w #$42,-(sp)
+            trap   #1
+            lea    10(sp),sp
+            move.l d6,d2       { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+  end;
+end;
+
+
+function do_seekend(handle:longint):longint;
+var
+ t: longint;
+begin
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+            move.w #2,-(sp)     { seek from end of file        }
+            move.l handle,d0
+            move.w d0,-(sp)
+            move.l #0,-(sp)     { with an offset of 0 from end }
+            move.w #$42,-(sp)
+            trap   #1
+            lea    10(sp),sp
+            move.l d6,d2       { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+            move.l d0,t
+  end;
+   do_seekend:=t;
+end;
+
+
+function do_filesize(handle : longint) : longint;
+var
+   aktfilepos : longint;
+begin
+   aktfilepos:=do_filepos(handle);
+   do_filesize:=do_seekend(handle);
+   do_seek(handle,aktfilepos);
+end;
+
+
+procedure do_truncate (handle,pos:longint);
+begin
+  do_seek(handle,pos);
+  {!!!!!!!!!!!!}
+end;
+
+
+procedure do_open(var f;p:pchar;flags:longint);
+{
+  filerec and textrec have both handle and mode as the first items so
+  they could use the same routine for opening/creating.
+  when (flags and $100)   the file will be append
+  when (flags and $1000)  the file will be truncate/rewritten
+  when (flags and $10000) there is no check for close (needed for textfiles)
+}
+var
+  i : word;
+  oflags: longint;
+begin
+  AllowSlash(p);
+ { close first if opened }
+  if ((flags and $10000)=0) then
+   begin
+     case filerec(f).mode of
+      fminput,fmoutput,fminout : Do_Close(filerec(f).handle);
+      fmclosed : ;
+     else
+      begin
+        inoutres:=102; {not assigned}
+        exit;
+      end;
+     end;
+   end;
+{ reset file handle }
+  filerec(f).handle:=UnusedHandle;
+  oflags:=$02; { read/write mode }
+{ convert filemode to filerec modes }
+  case (flags and 3) of
+   0 : begin
+         filerec(f).mode:=fminput;
+         oflags:=$00; { read mode only }
+       end;
+   1 : filerec(f).mode:=fmoutput;
+   2 : filerec(f).mode:=fminout;
+  end;
+  if (flags and $1000)<>0 then
+   begin
+     filerec(f).mode:=fmoutput;
+     oflags:=$04;  { read/write with create }
+   end
+  else
+   if (flags and $100)<>0 then
+    begin
+      filerec(f).mode:=fmoutput;
+      oflags:=$02;  { read/write             }
+    end;
+{ empty name is special }
+  if p[0]=#0 then
+   begin
+     case filerec(f).mode of
+       fminput : filerec(f).handle:=StdInputHandle;
+      fmappend,
+      fmoutput : begin
+                   filerec(f).handle:=StdOutputHandle;
+                   filerec(f).mode:=fmoutput; {fool fmappend}
+                 end;
+     end;
+     exit;
+   end;
+   asm
+      movem.l d2/d3/a2/a3,-(sp)    { save used registers }
+
+      cmp.l   #4,oflags    { check if rewrite mode ... }
+      bne     @opencont2
+      { rewrite mode - create new file }
+      move.w  #0,-(sp)
+      move.l  p,-(sp)
+      move.w  #$3c,-(sp)
+      trap    #1
+      add.l   #8,sp       { restore stack of os call }
+      bra     @end
+      { reset - open existing files     }
+    @opencont2:
+      move.l  oflags,d0    { use flag as source  ...    }
+    @opencont1:
+      move.w  d0,-(sp)
+      move.l  p,-(sp)
+      move.w  #$3d,-(sp)
+      trap    #1
+      add.l   #8,sp       { restore stack of os call }
+   @end:
+      movem.l (sp)+,d2/d3/a2/a3
+
+      tst.w   d0
+      bpl     @opennoerr  { if positive return values then ok }
+      cmp.w   #-1,d0      { if handle is -1 CON:              }
+      beq     @opennoerr
+      cmp.w   #-2,d0      { if handle is -2 AUX:              }
+      beq     @opennoerr
+      cmp.w   #-3,d0      { if handle is -3 PRN:              }
+      beq     @opennoerr
+      move.w  d0,errno    { otherwise normal error            }
+    @opennoerr:
+      move.w  d0,i        { get handle as SIGNED VALUE...     }
+    end;
+  if errno <> 0 then
+     Error2InOut;
+  filerec(f).handle:=i;
+  if (flags and $100)<>0 then
+   do_seekend(filerec(f).handle);
+end;
+
+{*****************************************************************************
+                           UnTyped File Handling
+*****************************************************************************}
+
+{$i file.inc}
+
+{*****************************************************************************
+                           Typed File Handling
+*****************************************************************************}
+
+{$i typefile.inc}
+
+{*****************************************************************************
+                           Text File Handling
+*****************************************************************************}
+
+{$i text.inc}
+
+{*****************************************************************************
+                           Directory Handling
+*****************************************************************************}
+
+procedure DosDir(func:byte;const s:string);
+var
+  buffer : array[0..255] of char;
+  c : word;
+begin
+  move(s[1],buffer,length(s));
+  buffer[length(s)]:=#0;
+  AllowSlash(pchar(@buffer));
+  c:=word(func);
+  asm
+        move.l  d2,d6      { save d2 }
+        movem.l d3/a2/a3,-(sp)
+        pea     buffer
+        move.w  c,-(sp)
+        trap    #1
+        add.l   #6,sp
+        move.l  d6,d2       { restore d2 }
+        movem.l (sp)+,d3/a2/a3
+        tst.w   d0
+        beq     @dosdirend
+        move.w  d0,errno
+     @dosdirend:
+  end;
+  if errno <> 0 then
+     Error2InOut;
+end;
+
+
+procedure mkdir(const s : string);[IOCheck];
+begin
+  If InOutRes <> 0 then exit;
+  DosDir($39,s);
+end;
+
+
+procedure rmdir(const s : string);[IOCheck];
+begin
+  If InOutRes <> 0 then exit;
+  DosDir($3a,s);
+end;
+
+
+procedure chdir(const s : string);[IOCheck];
+begin
+  If InOutRes <> 0 then exit;
+  DosDir($3b,s);
+end;
+
+
+function GetDirIO (DriveNr: byte; var Dir: ShortString): word;
+                                               [public, alias: 'FPC_GETDIRIO'];
+var
+  temp : array[0..255] of char;
+  i    : longint;
+  j: byte;
+  drv: word;
+begin
+  GetDirIO := 0;
+  drv:=word(drivenr);
+  asm
+            move.l  d2,d6      { save d2 }
+            movem.l d3/a2/a3,-(sp)
+
+            { Get dir from drivenr : 0=default, 1=A etc... }
+            move.w drv,-(sp)
+
+            { put (previously saved) offset in si }
+{            move.l temp,-(sp)}
+             pea   temp
+
+            { call attos function 47H : Get dir }
+            move.w #$47,-(sp)
+
+            { make the call }
+            trap   #1
+            add.l  #8,sp
+
+            move.l d6,d2         { restore d2 }
+            movem.l (sp)+,d3/a2/a3
+  end;
+  { conversion to pascal string }
+  i:=0;
+  while (temp[i]<>#0) do
+   begin
+     if temp[i]='/' then
+      temp[i]:='\';
+     dir[i+3]:=temp[i];
+     inc(i);
+   end;
+  dir[2]:=':';
+  dir[3]:='\';
+  dir[0]:=char(i+2);
+{ upcase the string (FPC Pascal function) }
+  dir:=upcase(dir);
+  if drivenr<>0 then   { Drive was supplied. We know it }
+   dir[1]:=chr(65+drivenr-1)
+  else
+   begin
+      asm
+        move.l  d2,d6      { save d2 }
+        movem.l d3/a2/a3,-(sp)
+        move.w #$19,-(sp)
+        trap   #1
+        add.l  #2,sp
+        move.w d0,drv
+        move.l d6,d2        { restore d2 }
+        movem.l (sp)+,d3/a2/a3
+     end;
+     dir[1]:=chr(byte(drv)+ord('A'));
+   end;
+end;
+
+procedure GetDir (DriveNr: byte; var Dir: ShortString);
+
+begin
+  InOutRes := GetDirIO (DriveNr, Dir);
+end;
+
+
+{*****************************************************************************
+                         System Dependent Exit code
+*****************************************************************************}
+Procedure system_exit;
+begin
+end;
+
+{*****************************************************************************
+                         SystemUnit Initialization
+*****************************************************************************}
+
+
+begin
+{ Initialize ExitProc }
+  ExitProc:=Nil;
+{ to test stack depth }
+  loweststack:=maxlongint;
+{ Setup heap }
+  InitHeap;
+{ Setup stdin, stdout and stderr }
+  OpenStdIO(Input,fmInput,StdInputHandle);
+  OpenStdIO(Output,fmOutput,StdOutputHandle);
+  OpenStdIO(StdOut,fmOutput,StdOutputHandle);
+  OpenStdIO(StdErr,fmOutput,StdErrorHandle);
+{ Reset IO Error }
+  InOutRes:=0;
+  errno := 0;
+{ Setup command line arguments }
+ argc:=GetParamCount(args);
+end.
+
+{
+  $Log$
+  Revision 1.1  2001-03-16 20:01:47  hajny
+    + system unit name change
+
+  Revision 1.2  2000/07/14 10:30:58  michael
+  +
+
+  Revision 1.1  2000/07/13 06:30:30  michael
+  + Initial import
+
+  Revision 1.14  2000/01/07 16:41:29  daniel
+    * copyright 2000
+
+  Revision 1.13  2000/01/07 16:32:23  daniel
+    * copyright 2000 added
+
+  Revision 1.12  1999/09/10 15:40:33  peter
+    * fixed do_open flags to be > $100, becuase filemode can be upto 255
+
+  Revision 1.11  1999/01/18 10:05:48  pierre
+   + system_exit procedure added
+
+  Revision 1.10  1998/12/28 15:50:43  peter
+    + stdout, which is needed when you write something in the system unit
+      to the screen. Like the runtime error
+
+  Revision 1.9  1998/09/14 10:48:02  peter
+    * FPC_ names
+    * Heap manager is now system independent
+
+  Revision 1.8  1998/07/15 12:11:59  carl
+    * hmmm... can't remember! :(...
+
+  Revision 1.5  1998/07/13 12:34:13  carl
+    + Error2InoutRes implemented
+    * do_read was doing a wrong os call!
+    * do_open was not pushing the right values
+    * DosDir was pushing the wrong params on the stack
+    * do_close would never works, was pushing a longint instead of word
+
+  Revision 1.4  1998/07/02 12:39:27  carl
+    * IOCheck for mkdir,chdir and rmdir, just like in TP
+
+  Revision 1.3  1998/07/01 14:40:20  carl
+    + new stack checking implemented
+    + IOCheck for chdir , getdir , mkdir and rmdir
+
+  Revision 1.1.1.1  1998/03/25 11:18:47  root
+  * Restored version
+
+  Revision 1.8  1998/02/23 02:27:39  carl
+    * make it link correctly
+
+  Revision 1.7  1998/02/06 16:33:02  carl
+    * oops... commited wrong file
+    + do_open is now standard with other platforms
+
+  Revision 1.5  1998/01/31 19:32:51  carl
+    - removed incorrect $define
+
+  Revision 1.4  1998/01/27 10:55:45  peter
+    * Word Handles from -1 -> $ffff
+
+  Revision 1.3  1998/01/25 22:44:14  peter
+    * Using uniform layout
+
+}

+ 103 - 0
rtl/palmos/system.pp

@@ -0,0 +1,103 @@
+{
+    $Id$
+
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Florian Klaempfl
+    member of the Free Pascal development team
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{$define PALMOS}
+{$ASMMODE DIRECT}
+unit system;
+
+{$I os.inc}
+
+  Interface
+
+    Type
+       { type and constant declartions doesn't hurt }
+       LongInt  = $80000000..$7fffffff;
+       Integer  = -32768..32767;
+       ShortInt = -128..127;
+       Byte     = 0..255;
+       Word     = 0..65535;
+
+       { !!!!
+       DWord    = Cardinal;
+       LongWord = Cardinal;
+       }
+
+       { The Cardinal data type isn't currently implemented for the m68k }
+       DWord    = LongInt;
+       LongWord = LongInt;
+
+       { Zero - terminated strings }
+       PChar    = ^Char;
+       PPChar   = ^PChar;
+
+       { procedure type }
+       TProcedure = Procedure;
+
+    const
+       { max. values for longint and int }
+       MaxLongint = High(LongInt);
+       MaxInt = High(Integer);
+
+       { Must be determined at startup for both }
+       Test68000 : byte = 0;
+       Test68881 : byte = 0;
+
+    { Palm specific data types }
+    type
+       Ptr    = ^Char;
+
+    var
+       ExitCode : DWord;
+       { this variables are passed to PilotMain by the PalmOS }
+       cmd : Word;
+       cmdPBP : Ptr;
+       launchFlags : Word;
+
+  implementation
+
+    { mimic the C start code }
+    function PilotMain(_cmd : Word;_cmdPBP : Ptr;_launchFlags : Word) : DWord;cdecl;public;
+
+      begin
+         cmd:=_cmd;
+         cmdPBP:=_cmdPBP;
+         launchFlags:=_launchFlags;
+         asm
+            bsr PASCALMAIN
+         end;
+         PilotMain:=ExitCode;
+      end;
+
+{*****************************************************************************
+                         System Dependent Exit code
+*****************************************************************************}
+Procedure system_exit;
+begin
+end;
+
+begin
+   ExitCode:=0;
+end.
+
+{
+  $Log$
+  Revision 1.1  2001-03-16 20:01:48  hajny
+    + system unit name change
+
+  Revision 1.2  2000/07/13 11:33:54  michael
+  + removed logs
+ 
+}