(*                _____________________________________________
 *         //    /                                             \         //
 *        //     \          Amiga Run Time System              /        //
 *    \\ //      /           2.0 / 30.07.88 / ms               \    \\ //
 *     \X/       \_____________________________________________/     \X/
 *)
(* $N- *)
DEFINITION MODULE Arts;

FROM SYSTEM IMPORT
 ADDRESS,LONGSET;

CONST
 maxModName=32; maxKeys=3;

TYPE
 ErrorType=(trap,exception,system,assertion,breakPoint,explicit);
 SysErr=(halt,illCase,fctReturn,stkOvl,illCall);
 ErrorFrame=RECORD
  pc: ADDRESS;
  dRegs: ARRAY [0..7] OF LONGINT;
  aRegs: ARRAY [8..15] OF ADDRESS;
  CASE error: ErrorType OF
  | trap: trapNr: INTEGER;
  | exception: exceptionMask: LONGSET
  | system: sysErr: SysErr
  | assertion,breakPoint,explicit:
  END;
  header,body: ADDRESS
 END;
(*
 * ModuleInfo is the definition of the info structure produced by the Linker
 * This definitons are used by the Linker, the Loader and Arts.
 * You, instead, should not use it!
 *)
 ModType=(none,mod,lib,noImp,optLib,rsc);
 ModName=ARRAY [0..maxModName-1] OF CHAR;
 ModKeys=ARRAY [0..maxKeys-1] OF CARDINAL;
 ModuleId=RECORD
  type: INTEGER; (* ORD(ModType) *)
  name: ModName;
  CASE :ModType OF
  | lib,optLib:
   pad: INTEGER;
   libVersion: LONGINT;
  | mod, noImp:
   keys: ModKeys;
  | rsc:
  END
 END;  
 ModuleInfo=RECORD
  id: ModuleId;
  CASE :ModType OF
  | lib,optLib:
   libPtr: ADDRESS;
   fixup: ADDRESS;
  | mod:
   modPtr: ADDRESS;
   dataPtr: ADDRESS;
  | rsc:
   rscSeg: ADDRESS;
   rscPtr: ADDRESS;
  END;
 END;
 ModuleInfoPtr=POINTER TO ModuleInfo;

VAR
(*
 * environment values. these are copied into these variables to have them
 * at a save place. to crash the program just change these values.
 * Note: not all of these values are valid. it depends on the program
 * startup if workbench or CLI values are valid. see wbStarted.
 * Here come the initial CLI arguments and CLI result value, it is init to 0,
 * set your return value before program exit
 *)
 stackSize: LONGINT;
 dosCmdBuf: ADDRESS; (* {a0} *)
 dosCmdLen: LONGINT; (* {d0} *)
 returnVal: LONGINT;
(*
 * we run from workbench if wbStarted is TRUE
 *)
 wbStarted: BOOLEAN;
 startupMsg: ADDRESS;
(*
 * Modula-2 environment variables. errorFrame is filled with the 
 * processor/program state when an an error, an exception, a trap
 * or a user interrupt occurs.
 * moduleInfo is used to open and close Amiga-libraries and of
 * course to know which modules are linked into this program.
 *)
 stackTop: ADDRESS;
 errorFrame: ErrorFrame;
 moduleInfo: ModuleInfoPtr; (* {d7} *)

(*
 * PROCEDURE Startup(proc{a1+adir}: PROC; modInfo{d7}: ModuleInfoPtr): LONGINT;
 * is the real declaration for Startup, the definition below is
 * just a dummy declaration to access older values on the stack.
 *)
PROCEDURE Startup(base,stk: LONGINT): LONGINT;

(* Compiler Support *)
PROCEDURE StkChk(need{0}: LONGINT);
PROCEDURE SystemError(err{0}: SysErr); (* SystemError(halt) = HALT *)
PROCEDURE Mulu32(x{0},y{1}: LONGINT): LONGINT;
PROCEDURE Divu32(x{0},y{1}: LONGINT): LONGINT;
PROCEDURE Muls32(x{0},y{1}: LONGINT): LONGINT;
PROCEDURE Divs32(x{0},y{1}: LONGINT): LONGINT;

(* Run Time Support *)
PROCEDURE Assert(condition: BOOLEAN; msg: ADDRESS);
PROCEDURE BreakPoint(msg: ADDRESS);
PROCEDURE Call(p: PROC);
PROCEDURE CurrentLevel(): INTEGER;
PROCEDURE DebugProcedure(debugger: PROC);
PROCEDURE DetectCtrlC(on{0}: BOOLEAN);
PROCEDURE Error(header,body: ADDRESS);
PROCEDURE RemoveDebugProc(debugger: PROC);
PROCEDURE RemoveTermProc(p: PROC);
PROCEDURE Requester(header,body,pos,neg: ADDRESS): BOOLEAN;
PROCEDURE Terminate(level: INTEGER);
PROCEDURE TermProcedure(p: PROC);

END Arts.
