DEFINITION MODULE M2LM;
(*$ LargeVars:=FALSE NameChk:=FALSE LongAlign:=FALSE *)

FROM SYSTEM IMPORT WORD,BYTE,ADDRESS;
FROM M2DM IMPORT Ident, ConstValue, ObjPtr, StrPtr, KeyPtr, Condition, WidType,
		ExportTypes;

TYPE
 (* nun in M2DM.def
  ExportTypes = (exported,private,closemod,openmod,varref,iniref,charref,
  		 noHead,noDHead,main,mainclose,linkerDB);
  *)
(*
  exported = 'Module_Ident'
  private  = 'Module$nr'
  linkerDB = '_LinkerDB'
  closemod = 'Modul_END'
  openmod  = 'Modul_123456789abc' ODER 'Modul_version'
  noHead   = '_Ident' (underscore kommt IMMER davor!)
  noDHead  = '_Ident' (underscore kommt IMMER davor!)
  main     = '__main'
  mainclose= '__mainEnd'
  varref   = 'Modul_VAR'
  iniref   = 'Modul_IN'
  charref  = 'Modul_BY'
 *)

VAR
 ip:INTEGER; (* instruction pointer, char pointer.  *)
 HunkStart: INTEGER; (* ip des aktuellen Hunks. Nur für M2AM! *)
 AktHunk:CARDINAL;

PROCEDURE PutWord(w{7}:WORD);
PROCEDURE PutLong(l{7}:LONGINT);
(* Put a 16/32-bit word into the code-buffer. *)


(* Wenn debug, dann nichts merken,nur den Code erzeugen!*)
(* VOR dem OpCode, erzeugt Code! *)

PROCEDURE DelLastBranch; (* löscht den bra auf Proc-Start wieder weg! *)
PROCEDURE Define(typ:ExportTypes;id:Ident);
 (* HIER (bei ip) ist id, id kann auch Nummer sein, je nach Typ! *)
PROCEDURE NewRef(mno,pc:INTEGER; name:Ident; typ:ExportTypes; wid:WidType);
 (* NewRef erzeugt nur eine Referenz, keinerlei Code!! *)
PROCEDURE FCondBranch(cc:Condition; VAR to:INTEGER);
PROCEDURE BCondBranch(cc:Condition; to:INTEGER);
PROCEDURE DeadEnd; (* nach rts oder jmp oder bra *)
PROCEDURE SubBranch(ob:ObjPtr); (* immer rückwärts! *)
PROCEDURE PCRel(proc:ObjPtr); (* moduleigene Proc; packt auch word in code! *)
(* Put16(wohin-ip);*)
PROCEDURE AddCodeReloc;

PROCEDURE ConstRel(mno,offs:INTEGER); (* pcrel oder dref auf eigene/fremde *)
(* ACHTUNG: mno=0: word, sonst long!!!!! *)

PROCEDURE DRel(mno,offs:INTEGER); (* drel oder dref auf eigene/fremde *)

PROCEDURE DIniRel(mno,offs:INTEGER); (* drel oder dref auf eigene/fremde *)

PROCEDURE AbsData(mno:INTEGER;offs:LONGINT); (* ref32 auf ext Data *)

PROCEDURE AbsIniData(mno:INTEGER;offs:LONGINT); (* ref32 auf ext Data *)

PROCEDURE AbsCode(mno:INTEGER;id:Ident;etyp:ExportTypes); (* ref32 auf extproc *)

PROCEDURE GetA4; (* macht putlong(0) und extref32 auf _LinkerDB *)
PROCEDURE ExtCall(mno:INTEGER; id:Ident; etyp:ExportTypes);

(* markiert für Löschung oder setzt NOPs*)
PROCEDURE Delete(wo, wievielByte:INTEGER);
PROCEDURE DiffPCRel(lab1,lab2:INTEGER);
(* put16(lab1-lab2) für CaseList *)

(* diese erzeugen keinerlei Code!! nur für Opti und Amiga-Object*)
PROCEDURE PCFix(where,to,from:INTEGER);
PROCEDURE PCRef(where,to,from:INTEGER; add:LONGINT; size:WidType; cond:BYTE);

PROCEDURE PutIniVar(VAR c:ConstValue; VAR offset:LONGINT);
(* Packe Const in IniBuffer, gebe offset für vadr zurück *)

PROCEDURE EatThisConst(VAR c:ConstValue);
(* fremde Konstante wird in MEINEM Constbuffer abgelegt *)

(*
PROCEDURE AllocConst(VAR c:ConstValue; sze:LONGINT; toBuff:BOOLEAN);
(* nur für Strings! *)
*)

PROCEDURE AllocConstHeap(VAR c:ConstValue; size:INTEGER);
(* erzeugt nur einen Buffer in c.A,L *)

PROCEDURE PutConstInConst(VAR dest,with:ConstValue; offset:INTEGER);
(* Packe eine memConst in eine größere memConst!
 *)

PROCEDURE PutValInConst(VAR c:ConstValue; VAR val:ConstValue; size,offset:INTEGER);
PROCEDURE GetConstVal(VAR c:ConstValue; offset:INTEGER):LONGINT;

PROCEDURE AllocString(s: Ident; VAR c:ConstValue; toBuff:BOOLEAN);
(* Copy a string from IdBuf into Heap. s: idBuf index. *)

PROCEDURE PutInBuffer(VAR c:ConstValue);
(* Copy a string from Heap into constB *)

PROCEDURE AppendString(VAR a,b:ConstValue);
(* Append b to a (a:=a+b) *)

PROCEDURE AllocChar(ch: CHAR; VAR c:ConstValue; toBuff:BOOLEAN);
(* Copy char into constB. *)


PROCEDURE fixup(loc: INTEGER);
(* enter 16-bit displacement (ip-loc) at loc. *)

PROCEDURE FixShort(loc: INTEGER);
(* enter 8-bit displacement (ip-loc) at loc+1. loc points to a short branch. *)

PROCEDURE FixShortWith(loc: INTEGER; val:CHAR);
(* enter 8-bit!! value val at loc *)

PROCEDURE FixLink(l: INTEGER);
(* use fixup for an entier link. *)

PROCEDURE FixupWith(loc: INTEGER; val: INTEGER);
(* enter 16-bit value val at loc. *)

PROCEDURE GetWord(loc{0}:INTEGER):WORD;
(* get 16-bit value from loc *)

PROCEDURE FixLinkWith(l, val: INTEGER);
(* fixup an entier link with (val-loc). *)

PROCEDURE MergedLinks(l0, l1: INTEGER): INTEGER;
(* merge chain of the 2 operands of AND and OR. *)

PROCEDURE InitKey(VAR key: KeyPtr);
(* inits the key with an unique identification *)

PROCEDURE OpenCodeFile(progid:Ident); (* init auch MainName *)
PROCEDURE EndHunk(proc:ObjPtr;isimp,fast:BOOLEAN); (* beende diesen Hunk *)

PROCEDURE CloseCodeFile(datasize:LONGINT; merg:BOOLEAN);
(* Write the last Hunks and close and/or delete code file *)

PROCEDURE InitM2LM;
(* Initialize the global variables of M2LM. *)

END M2LM.
