DataMuseum.dk

Presents historical artifacts from the history of:

DANOSI

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DANOSI

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦64be3a8b5⟧ TextFile

    Length: 56146 (0xdb52)
    Types: TextFile
    Names: »P450CODE.PAS«

Derivation

└─⟦037c0ce35⟧ Bits:30010524 DVBS1.SW2114.src.2.6-2 RTP compiler source SW2104+SW2114 Disk#2 30/1-92 HHA
    └─⟦this⟧ »RTP\P450CODE.PAS« 
└─⟦828f0d3dd⟧ Bits:30010527 DVBS1.SW2114.src.2.6-5 RTP Compiler Source SW2104+SW2114 Disk 2 92.02.03 HEJ HHA
    └─⟦this⟧ »RTP\P450CODE.PAS« 
└─⟦891417be1⟧ Bits:30010519 DVBS1.SW2114.src.2-1 SW2114 1/4 Real Time Pascal 2.7 92.06.16
    └─⟦this⟧ »RTP\P450CODE.PAS« 
└─⟦a2bcc95d7⟧ Bits:30010511 DVBS1.SW2114.src.2.14-2 SW2114 REAL #2/4 TIME PASCAL SOURCE REL 2.14 92.09.01
    └─⟦this⟧ »RTP\P450CODE.PAS« 

TextFile

{$O+,F+}\r
unit p450code;\r
  (* This module impl. procedure called when generating code *)\r
interface\r
uses pscplm,mpaunit,sthunit,sthcom,p4unit;\r
\r
\r
\r
\r
\r
  (* --------- PUBLIC CODEGENERATOR -----------CODEGENERATOR --*)\r
\r
\r
\r
    CONST\r
      Proc_StackLimit = 8;\r
      Proc_StackOccam = 9;\r
      Proc_exception_offset = 2;\r
\r
      Prog_Descr_Size = 100;\r
\r
\r
      LengthOfSharedType = 12;\r
\r
      LengthOfSemaphore = 12;\r
\r
      SharedCounterOffset = 4;\r
\r
      LockedOffset  = 4;\r
\r
      DataSizeOffset = 8;\r
\r
      OffsetOffset = 12;\r
\r
      DataPartOffset = 0;\r
\r
      TopOffset = 16;\r
\r
      StackBoundOffset = 28;\r
        (* Offset to field StackBound in PI3 type Process_Descriptor *)\r
\r
      NoParamOffset = 29;\r
        (* offset to the field Noparam in the pi3 type program_describtion *)\r
\r
      SubProgsHeadOffset = 74;\r
        (* offset to the SubProgsHead field in pi3 type program_describtion *)\r
\r
      ParamsizeForCreate = 20;\r
        (* no of bytes for the parameter to create *)\r
\r
\r
      (* The following constant gives the interupt parameter to an exception *)\r
\r
\r
      IndexOutOfRangeInt = 50;\r
      IndexOutOfRangeExc = 50;   (* fault 50, Not used  *)\r
\r
      StackOverFlowInt = 12;\r
      StackOverFlowExc = 12;\r
        (* Parametre to interrupt when stack overflow *)\r
\r
      OutOfRangeInt = 52;\r
      OutOfRangeExc = 52;  (* fault 52 , Not used *)\r
\r
      OtherwiseInt = 7;\r
      OtherwiseExc = 7;\r
\r
      LockInt = 1;\r
      LockExc = 1;\r
\r
(*      AccessCheckInt = 15;\r
      AccessCheckExc = 15;\r
        (* Parametre to interupt when accesscheck error *)\r
\r
(*      PointerNilInt = 10;\r
      PointerNilExc = 10; *)\r
\r
      CheckParamInt = 8;\r
      CheckParamExc = 8;\r
\r
      StrucInt =  14;\r
      StrucExc =  14;\r
\r
      WithInt = 6;\r
      WithExc = 6;\r
\r
\r
      (* PI3 constant *)\r
      call_frame = 20;\r
      (* The following gives the number for the predefined external routines *)\r
      RtpLBDR = 1;\r
      Push_Buf = 2;\r
      Pop_Buf = 3;\r
      GetBuf = 4;\r
      GetBufDelay = 5;\r
      Signal = 6;\r
      Wait = 7;\r
      WaitDelay = 8;\r
      PutBuf = 9;\r
      Resume = 10;\r
      AllocPool = 11;\r
      ChainDeQueue = 12;\r
      ChainEnQueue = 13;\r
      Init_Semaphore = 14;\r
      WaitS = 15;\r
      Set_Exception = 16;\r
      Init_Reference = 17;\r
      Init_Chain = 18;\r
      Init_Shared = 19;\r
      Init_Mailbox = 20;\r
      Init_Process = 21;\r
      Init_Internal = 22;\r
      Init_External = 23;\r
      Init_Port = 24;\r
      SignalS = 25;\r
      Init_Pool = 26;\r
      EndProcess = 27;\r
      Mark_LocalRef = 28;\r
      UnChain_LocalRef = 29;\r
      Init_LocalRef = 30;\r
\r
      dynAlloc = 31;\r
      Exchange = 32;\r
\r
\r
      ExcRec = 33;\r
      ExcPack = 34;\r
      Eqrec = 35;\r
      GtRec = 36;\r
      StStr = 37;\r
      ExStr = 38;\r
      GtStr = 39;\r
      EqStr = 40;\r
\r
      NoRoutinesWithStatLink = 32;\r
      NoOfPI3Routines = 40;\r
      NoOfSetRoutines = 10;\r
      NoOfPI3RoutinesAndSetRoutines = NoOfPI3Routines + NoOfSetRoutines;\r
\r
   (* External set Routine *)\r
      AssignSet = NoOfPi3Routines + 1;\r
      AddSet = NoOfPi3Routines + 2;\r
      SubSet = NoOfPi3Routines + 3;\r
      MultSet= NoOfPi3Routines + 4;\r
      GESet = NoOfPi3Routines + 5;\r
      EQSet= NoOfPi3Routines + 6;\r
      NESet= NoOfPi3Routines + 7;\r
      LESet = NoOfPi3Routines + 8;\r
      InSet = NoOfPi3Routines + 9;\r
      MakeSet = NoOfPi3Routines + 10;\r
\r
\r
\r
    Maxbin1Ix  = 40;\r
\r
    TYPE\r
\r
      Pfix_type = RECORD\r
        Prefixes : byte;\r
        Code : ARRAY[1..8] OF Byte;\r
      END;\r
\r
\r
    VAR\r
\r
      (* List contains the  external routines *)\r
      FirstExtDec : St_Address;\r
      ExternalThunksDumped : Boolean;\r
\r
      NoExtDecl, NoPreExtDecl : Word;\r
\r
      LengthOfAllPreExtName, LengthOfAllExtName : Word;\r
\r
\r
      CodeOn : boolean;\r
           (* Symbolic code is generated if true *)\r
\r
      LastNameEntry : St_Address;\r
\r
      LengthOfNameTabel : word;\r
\r
      LineTabel : boolean;\r
\r
      Spacing : word;\r
\r
      CurrentSegNo : Word;\r
  (* Declarations which has to do with pass4_2  TURBO *)\r
\r
    CONST\r
\r
      LengthOfExternalLBDR = 29;\r
\r
      LengthOfInternalLBDR = 8;\r
\r
\r
\r
\r
      Max4Bit = 16;\r
\r
      MaxByte = 256;\r
\r
\r
      (* the following constant gives the type of records on codefile *)\r
      Frstrc = $0B0;  (* First record *)\r
\r
      Lastrc = $0B2;\r
\r
      TypDef = $8E;\r
\r
\r
\r
\r
    TYPE\r
\r
      CodeName = string[5];\r
\r
\r
\r
      TypeExternalLBDR =\r
        RECORD\r
          CASE b : Boolean OF\r
\r
            true : ( EntryPoint : Word;\r
                     LineTable : word;\r
                     GlobalSize : Word;\r
                     Appetite : Word;\r
                     SegSize : Word;\r
                     LinkCount : Byte;\r
                     Next1,Next2 : integer; (* a pointer *)\r
                     BlName : String[12];\r
                     BlKind : Byte );\r
\r
\r
            false : ( Byt :ARRAY[1..LengthOfExternalLBDR] OF Byte);\r
        END;\r
\r
\r
\r
    VAR\r
      MegaInstructionName : ARRAY[mJ..mCWORD] OF CodeName;\r
      MegaInstructionValue: ARRAY[mJ..mCWORD] OF WORD;\r
      iInstTomInst        : ARRAY[iXLAT..iMOD] OF Instruction;\r
\r
      PreExtName : ARRAY[1..NoOfPI3RoutinesAndSetRoutines] of SpixRange;\r
      PreExtCalled : ARRAY[1..NoOfPI3RoutinesAndSetRoutines] of St_Address;\r
\r
      FirstFixUpp, LastFixUpp : St_Address;\r
        (* List of FixUpp *)\r
\r
      NoFixUpp : Word;\r
        (* Number of FixUpp *)\r
\r
\r
      ContextEndOffset : Word;\r
\r
\r
      VersionNumber : Array[1..4] OF Word;\r
\r
\r
      FilePtrToSecSegDef : longint;\r
\r
      InStrucValue : integer;\r
\r
      Strucoffset : Integer;\r
      StrucInExp : boolean;\r
\r
      LastInternalLBDRLabel : St_Address;\r
        (* The offset of the last internalLBDR written to TBinFile *)\r
\r
      LastLabelOffset : Longint;\r
                   (* InternalOffset of the last generated label *)\r
      LastJMPOffset : Longint; (* internaloffset after generating the last\r
                               JMP instruction *)\r
\r
      Offsetstatistic, extthunkstatistic : array[1..8] OF Integer;\r
\r
    (* -------------------------------------------- *)\r
\r
\r
    PROCEDURE InitCodeGenerator;\r
       (* The procedure initialize the codegenerator *)\r
\r
    PROCEDURE DumpExternalThunks;\r
\r
    PROCEDURE MakeExternalLBDR( SymbolPoint : St_Address;\r
                                EntryPoint : St_Address;\r
                                LineTable : integer;\r
                                GlobalSize : Word;\r
                                Appetite : Word;\r
                                BlName : SpixRange;\r
                                BlKind : integer );\r
      (* The procedure makes a external LBDR *)\r
\r
    PROCEDURE MakeInternalLBDR( EntryPoint : St_Address;\r
                                LineTable : integer;\r
                                GlobalSize : Word;\r
                                Appetite : Word ;\r
                                BlName : SpixRange);\r
      (* The procedure makes a internal LBDR *)\r
\r
\r
\r
\r
\r
    PROCEDURE StopBlock;\r
      (* The procedure is called when where is no more code for\r
         that block. The procedure makes the <object block> on file\r
         codefile. That is the 2. pass of the block is made *)\r
\r
    PROCEDURE StopCodeGene;\r
      (* The procedure is called when where is no more code to be\r
         generated. *)\r
\r
    PROCEDURE GenCode(Inst : Instruction);\r
      (* Generate a instruction without parameter *)\r
\r
    PROCEDURE CodeConst(Inst : Instruction; Value : LongInt; spix : spixrange);\r
      (* Generate a instruction with a constant parametre *)\r
\r
    PROCEDURE CallExtern(Addr : ST_address);\r
\r
    PROCEDURE CallRoutine(Spix : SpixRange; Number : word; RKind :\r
                                                             St_DeclareMode);\r
      (* The procedure generates code for an external or open routine call *)\r
\r
    FUNCTION StoreTemp(offset : Word) : Integer;\r
\r
    Procedure StoreTempOK(Index : Integer);\r
\r
    PROCEDURE CodeJump(Inst : Instruction; Lab : St_Address);\r
      (* Generate a instruction with a label as parameter *)\r
\r
     PROCEDURE ReleaseStrucDyn;\r
\r
\r
    PROCEDURE CodeFaultAX( ErrorInt, ErrorExc: WORD);\r
    PROCEDURE CodeFault(ErrorInt, ErrorExc: WORD);\r
\r
\r
\r
    PROCEDURE CodeLoadEffAddr(Lab : St_Address; Offset : Word);\r
      (* Generate code to load Areg with the effectiv address of Lab:+ Offset *)\r
\r
    PROCEDURE GenerateLabel(Lab : St_Address);\r
      (* Generate the label given by Lab *)\r
\r
    PROCEDURE GenAsLabel(Lab1, Lab2 : St_Address);\r
      (* The offset of Lab1 is given by the offset of Lab2\r
         A command is made in the code if Lab2 has been generate *)\r
\r
    PROCEDURE DumpConst(ConstAddr : St_Address );\r
      (* the structured constant given by ConstAddr is dumped in the code *)\r
\r
\r
    PROCEDURE DumpCaseTabel(CaseTab : St_Address; Size : word;\r
	       OtherwiseLab : St_Address; IndJumpLabel : St_Address);\r
      (* The casetabel is generated *)\r
\r
    Procedure MegaAllignCode;\r
\r
    PROCEDURE NewLine(Line : Word);\r
      (* The procedure write the linenumber to codelist if codeon *)\r
\r
    PROCEDURE SetCodeTo(Bool : Boolean);\r
      (* The procedure change the option codeon *)\r
\r
    Procedure ContextStop;\r
      (* The procedure is called when leaving linetabel. Only used when\r
         making linetabel *)\r
\r
\r
    Procedure RoutineDecl(Symbol : St_Address; start : boolean );\r
       (* the routine is called when making a routine, program or a familie\r
          declaration. Only used when making nameentry *)\r
\r
\r
\r
    PROCEDURE MakeLongCall(Symbol : St_Address);\r
      (* Makes a call to an other segment using segment fixup *)\r
\r
    PROCEDURE  DumpRoutineTabel;\r
      (* Dumps the routine tabel . Only used when more than one segment *)\r
\r
    Procedure MakeJumpToNextSegment;\r
      (* Only used when more than one segment *)\r
\r
  (* ----- END PUPLIC CODEGENERATOR --------CODEGENERATOR -- *)\r
\r
\r
IMPLEMENTATION\r
  (* ---------- IMPORTS --------------------IMPORTS ---------*)\r
\r
uses dos,sthp34,files, rtp86mpa;\r
\r
\r
  (* ------------IMPORTS END --------------IMPORTS END --------*)\r
\r
\r
\r
  (* --------PRIVATE CODEGENERATOR ------ CODEGENERATOR -----*)\r
\r
\r
\r
\r
\r
\r
    CONST\r
\r
      MaxLengthOfOpenRoutines = 2000;\r
        (* this constant must be changed if new opernroutins is made *)\r
\r
      LengthOfVersion = 12;\r
      MaxLabInOpen = 2;\r
\r
      OpenCode = 1;\r
      OpenFinish = 2;\r
      OpenPushProc = 3;\r
      OpenJump = 4;\r
      OpenCJump = 5;\r
      OpenLabel = 6;\r
\r
      LabelPos   = 6;\r
                  (* Gives the label pos on CodeList *)\r
\r
      CodePos    = 12;\r
                (* Gives the code pos on CodeList *)\r
      CommentPos = 20;\r
\r
    VAR\r
\r
      InternalOffset, Offset : Longint;\r
\r
\r
\r
      LastLabel : St_Address;  (* pointer to last generated label *)\r
\r
             (* LastJMPOffset, LastLabelOffset and LastLabel is used to\r
                eliminat superflous jumps *)\r
\r
\r
\r
      (* The following variabels are tabels containing opcode for\r
         instructions *)\r
\r
\r
      CodeOfOpenRoutines : ARRAY[ 0 .. MaxLengthOfOpenRoutines ] OF Byte;\r
            (* tabels contains the code for the open routines *)\r
\r
\r
      ShiftFactor : ARRAY[0..7] OF Byte;\r
\r
\r
      WordByte : RECORD\r
                   CASE Int : integer OF\r
                     1 : (i : Integer);\r
                     2 : (Byte1 : 0..255;\r
                          Byte2 : 0..255);\r
                     3 : (w : Word);\r
                 END;\r
               (* Used to convert a integer/Word to two bytes or two bytes\r
                  to a integer/Word *)\r
\r
      Filebufferindex : integer;\r
\r
      CodeOnPass2 : Boolean;\r
           (* Symbolic code is generated if true *)\r
\r
      CheckSum : Word;\r
           (* Used to calculated the checksum for a objectfile\r
              record *)\r
\r
      CurrentPos : integer;\r
         (* Gives the possition for the last char written to\r
            CodeList *)\r
\r
      HexNumber : ARRAY[ 0 .. 15 ] OF Char;\r
\r
      FirstBlock : boolean;\r
\r
      TBinFileptr : byte;\r
\r
      filebufferlast : Integer;\r
      eoftbinfile : boolean;\r
\r
      Nextbin1In, Nextbin1Out, Elonbin1, Bin2codeOut: word;\r
      Tempbin1 : ARRAY[1..Maxbin1ix] OF Tempbin1_record;\r
\r
      FirstTempPage , TempPage : St_Address;\r
      TempIndex : Integer;\r
      JumpRec :  St_elemPtr;\r
    (* -------------------------------------------- *)\r
 procedure newtemppage;\r
  VAR Ptr : St_elemPtr;\r
  BEGIN\r
   IF TempIndex >= JumpRec^.JumpNoElements THEN\r
     BEGIN\r
       ptr := JumpRec;\r
       St_ReserveJump(JumpRec^.JumpListRef,JumpRec);\r
       St_Unlock(Ptr);\r
       St_Lock(JumpRec);\r
       TempIndex := 0;\r
     END;\r
   TempIndex := TempIndex + 1;\r
  END;\r
\r
 procedure nexttemppage;\r
  VAR Ptr : St_elemPtr;\r
  BEGIN\r
   IF TempIndex >= JumpRec^.JumpNoElements THEN\r
     BEGIN\r
       ptr := JumpRec;\r
       St_Get(JumpRec^.JumpListRef,JumpRec);\r
       St_Unlock(Ptr);\r
       St_Lock(JumpRec);\r
       TempIndex := 0;\r
     END;\r
   TempIndex := TempIndex + 1;\r
  END;\r
\r
 function eofTempPage : boolean;\r
 BEGIN\r
   eofTempPage := Equal_Addr(JumpRec^.JumpListRef,St_nillAddr)\r
                 AND (TempIndex = JumpRec^.JumpNoElements);\r
 END;\r
\r
 procedure emptyfilebuffer;\r
 BEGIN\r
  blockwrite(tbinfile,filebufferptr^,filebufferindex);\r
  filebufferindex := 0;\r
 end;\r
\r
 Procedure puttbinfile( x: byte);\r
 BEGIN\r
  if Filebufferindex = Lengthoffilebuffer then\r
    emptyfilebuffer;\r
  filebufferindex := filebufferindex + 1;\r
  filebufferptr^[filebufferindex] := x;\r
  internaloffset := internaloffset + 1;\r
  Bin2codeOut    := Bin2codeOut + 1;\r
 END;\r
\r
 FUNCTION MegaPfixNo(Offset: Longint): Integer;\r
 VAR neg : boolean;\r
     result : integer;\r
 BEGIN\r
   neg := (offset < 0);\r
   IF neg THEN offset := - offset;\r
   result := 1;\r
   while offset > 15 do\r
    BEGIN\r
      result := Result + 1;\r
      offset := offset SHR 4;\r
    END;\r
   if neg and( result = 1) THEN Result := 2;\r
   MegaPFixNo := result;\r
 END;\r
\r
  Procedure Putbin1Code;\r
  VAR Bin1ix : Word;\r
  BEGIN\r
    Bin1ix := NextBin1Out + 1;\r
    IF Bin1ix > Maxbin1ix THEN Bin1ix := 1;\r
    WiTH Tempbin1[Nextbin1Out] DO\r
    IF Bin1Param <> 0 THEN\r
    BEGIN\r
      NewTempPage;\r
      IF Tempindex = Jumprec^.JumpNoElements THEN\r
      IF Bin1Code = AddLabelToDis THEN\r
      BEGIN\r
        JumpRec^.JumpNoElements := JumpRec^.JumpNoElements - 1;\r
        NewTempPage;\r
      END;\r
      JumpRec^.Jump_data[TempIndex] := Tempbin1[Nextbin1Out];\r
    END ELSE\r
    BEGIN\r
      WITH Tempbin1[Bin1ix] DO\r
        Bin2Code := Bin2Code + Tempbin1[Nextbin1Out].Bin2Code;\r
    END;\r
    Nextbin1Out := Bin1ix;\r
  END;\r
\r
  Procedure Putbin1Label(Code: CodeFormat; Labeladdr : St_address;\r
                         VAR Bin1ix : word);\r
  VAR Ptr: St_Elemptr;\r
  BEGIN\r
\r
    Nextbin1In := Nextbin1In + 1;\r
    IF Nextbin1In > Maxbin1ix THEN\r
    BEGIN\r
      Nextbin1In := 1;\r
      Elonbin1   := Elonbin1 + Maxbin1ix;\r
      IF Nextbin1Out <= 0 then Nextbin1Out := 1;\r
    END;\r
    IF Nextbin1Out = Nextbin1In then Putbin1Code;\r
\r
    WITH Tempbin1[Nextbin1In] DO\r
    BEGIN\r
      Bin1Code    := Code;\r
      Bin1Label   := Labeladdr;\r
      Bin2Code    := Bin2codeOut;\r
      Bin2codeOut := 0;\r
      CASE Code OF\r
       TempSTL: Bin1Param := 0;\r
\r
       UnCondJump, CondJump, InternalCall:\r
         BEGIN\r
           St_Retrieve(Labeladdr, Ptr);\r
           WHILE NOT Equal_Addr(Ptr^.DefAsLabel,St_NillAddr) DO\r
             St_Retrieve(Ptr^.DefAsLabel,Ptr);\r
\r
            if Ptr^.MegaLabel_offset = 0 then Bin1Param := 1 else\r
            BEGIN\r
              Bin1Param := MegaPfixNo(Ptr^.MegaLabel_offset-(InternalOffset+1));\r
            END;\r
            InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       ExternalCall :\r
         BEGIN\r
           Bin1Param := 8;\r
           InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       AddLabelToDis :\r
         BEGIN\r
	   Bin1Param := 3;\r
           InternalOffset := InternalOffset + Bin1Param;\r
	 END;\r
\r
       CaseLabList:\r
	 BEGIN\r
	   Bin1Param      := LabelAddr.Va_High*4;\r
	   InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       AllignCode:\r
         BEGIN\r
	   Bin1Param := 3;\r
           InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       LongJump : (* External call Thunks *)\r
         BEGIN\r
           Bin1Param := 8;\r
           InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       ExternalLbdr :\r
         BEGIN\r
           Bin1Param := 40;\r
           InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       InternalLbdr : (* For Routines *)\r
         BEGIN\r
           Bin1Param := 28;\r
           InternalOffset := InternalOffset + Bin1Param;\r
         END;\r
\r
       ELSE Bin1Param := 1;\r
      END;\r
    END;\r
\r
    Bin1ix := Elonbin1 + Nextbin1In;\r
\r
  END;\r
\r
  Procedure Putbin1Value(Code : CodeFormat; CodeValue: WORD;\r
                         VAR  Bin1ix : WORD);\r
  VAR Labeladdr : St_address;\r
  BEGIN\r
    Labeladdr.Va_low  := 0;\r
    Labeladdr.Va_high := CodeValue;\r
    Putbin1Label(Code, Labeladdr, Bin1ix);\r
  END;\r
\r
  FUNCTION InsertBin1ix(Bin1ix: WORD): BOOLEAN;\r
  VAR Lastix : WORD;\r
      ihelp : Integer;\r
  BEGIN\r
    Lastix := Elonbin1 + Nextbin1In;\r
    IF ((Bin1ix <= (Lastix - Maxbin1ix)) AND\r
       (Lastix >= Maxbin1ix)) OR\r
       (Bin1ix = 0) THEN\r
    BEGIN\r
      writeln('1 Insertbin lastix:',lastix,' nextbin1in:',nextbin1in,\r
               ' bin1ix ',Bin1ix,' elonbin1 ',elonbin1);\r
      InsertBin1ix := False;\r
    END ELSE\r
    IF Bin1ix > Lastix THEN\r
    BEGIN\r
      writeln('2 Insertbin lastix:',lastix,' nextbin1in:',nextbin1in,\r
            ' bin1ix ',Bin1ix,' elonbin1 ',elonbin1);\r
      InsertBin1ix := False;\r
    END ELSE\r
    BEGIN\r
      InsertBin1ix := True;\r
      Ihelp := Nextbin1In - (Lastix - Bin1ix);\r
      IF Ihelp < 1 THEN Ihelp := Ihelp + Maxbin1ix;\r
      WITH Tempbin1[Ihelp] DO\r
      IF Bin1Param = 0 THEN\r
      BEGIN\r
        Bin1Param := MegaPfixNo(Bin1Label.Va_high);\r
        InternalOffset := InternalOffset + Bin1Param;\r
      END ELSE\r
        BEGIN\r
      writeln('3 insertbin lastix:',lastix,' nextbin1in:',nextbin1in,\r
                 ' bin1ix ',Bin1ix,' elonbin1 ',elonbin1);\r
         InsertBin1ix := False;\r
        END;\r
    END;\r
  END;\r
\r
\r
    (* ------------------------------------------------------- *)\r
\r
    PROCEDURE MakeFreeCodeBuffer( No : Integer);\r
      (* The procedure makes at least No bytes free in the codebuffer\r
         That is done by writting to the file TBinFile *)\r
     begin\r
     end;\r
\r
   Procedure MegaAllignCode;\r
     VAR\r
       w : word;\r
     BEGIN\r
       PutBin1Value(AllignCode,0,w);\r
     END;\r
\r
    PROCEDURE DumpConst(ConstAddr : St_Address );\r
      (* the structured constant given by ConstAddr is dumped in the code *)\r
      VAR\r
        Ptr : St_elemPtr;\r
        More : boolean;\r
        i , No : word;\r
        Length , index : word;\r
        ch : char;\r
\r
      BEGIN\r
        More := true;\r
        While More Do\r
          BEGIN\r
            St_Retrieve(ConstAddr,Ptr);\r
            Length := Ptr^.St_Size;\r
            More := Not Ptr^.St_ListEnd;\r
            ConstAddr := Ptr^.ListRef;\r
            Index := 0;\r
            WHILE Length > 0 DO\r
              BEGIN\r
                IF Length > 10 THEN No := 10\r
                               ELSE No := Length;\r
                Length := Length - No;\r
                For I:= 1 to no do\r
                  putTBinFile(Ptr^.Data_area[i + index]);\r
                IF CodeOn THEN\r
                  BEGIN\r
                    Write(TSymFile,No,' ');\r
                    FOR i := (index + 1) TO (No + index) DO\r
                      BEGIN\r
                        ch := chr(Ptr^.Data_area[i]);\r
                        IF (( ord(' ') > ord(ch)) OR (ord(ch) > ord('}')))\r
                          THEN ch := '.';\r
\r
                        write(TSymFile,ch)\r
                      END;\r
                    Writeln(TSymFile);\r
                  END;\r
\r
                index := index + No;\r
              END;\r
          END;\r
      END; (* DumpConst *)\r
\r
    (* ---------------------------------------------------------- *)\r
\r
\r
\r
    PROCEDURE DumpCaseTabel(CaseTab : St_Address; Size : Word;\r
		OtherwiseLab : St_Address; IndJumpLabel : St_Address);\r
      (* The casetabel is generated *)\r
\r
      VAR\r
      w : word;\r
      BEGIN\r
        PutBin1Value(AllignCode,0,w);\r
	PutBin1Value(CaseLabList,Size,w);\r
	PutBin1Label(DummyElement,CaseTab,w);\r
	PutBin1Label(DummyElement,OtherwiseLab,w);\r
	PutBin1Label(DummyElement,IndJumpLabel,w);\r
\r
      END;  (* DumpCaseTabel *)\r
\r
\r
\r
\r
    (*------------------------------------------------------------------*)\r
\r
\r
\r
     (*------------------------------------------------------------------- *)\r
\r
\r
\r
    (*------------------------------------------------------------------*)\r
\r
\r
       PROCEDURE NewLine(Line : Word);\r
         BEGIN\r
           IF CodeOn or LineTabel THEN\r
             BEGIN\r
               Putbin1Value(LineNo, Line, Line);\r
             END;\r
         END;\r
\r
\r
     (*------------------------------------------------------------------- *)\r
\r
\r
\r
\r
       PROCEDURE SetCodeTo(Bool : Boolean);\r
         VAR x,xx: WORD;\r
         BEGIN\r
           codeon := bool;\r
           IF bool then xx:= SourceNumber\r
                   else xx := 255;\r
           Putbin1Value(Setcode, xx, x);\r
         END;\r
\r
\r
    Procedure ContextStop;\r
      (* The procedure is called when leaving context. Only used when\r
         making linetabel *)\r
      var ix : word;\r
      BEGIN\r
        PutBin1Value(ContextEnd,0,ix);\r
      END;\r
\r
\r
    Procedure RoutineDecl(Symbol : St_Address; start : boolean );\r
       (* the routine is called when making a routine, program or a familie\r
          declaration. Only used when making nameentry *)\r
      VAR ix : word;\r
      BEGIN\r
       IF start THEN\r
         PutBin1Label(RoutineStart,Symbol,ix)\r
       ELSE\r
         PutBin1Label(RoutineStop,Symbol,ix);\r
\r
\r
      END;\r
\r
\r
   PROCEDURE MakeLongCall(Symbol : St_Address);\r
     BEGIN\r
       writeln('makelongcall');\r
     END;\r
\r
   PROCEDURE DumpRoutineTabel;\r
     VAR Ptr : St_ElemPtr;\r
         Symb : Ptr_Symbol_Chain;\r
         i : integer;\r
     BEGIN\r
     END;\r
\r
\r
   PROCEDURE MakeJumpToNextSegment;\r
     BEGIN\r
     END;\r
\r
\r
\r
\r
    PROCEDURE MakeInternalLBDR(EntryPoint : St_Address;\r
                               LineTable  : integer;\r
                               GlobalSize : Word;\r
                               Appetite   : Word;\r
                               BlName     : SpixRange);\r
      (* The procedure makes a Internal LBDR *)\r
\r
      VAR  Ptr : St_ElemPtr;\r
\r
      BEGIN\r
       megaalligncode;\r
         St_Declaration(CLabel,AnonymousName,\r
                           LastInternalLBDRLabel,Ptr);\r
        GenerateLabel(LastInternalLBDRLabel);\r
\r
        MakeExternalLBDR(EntryPoint, EntryPoint,\r
                         LineTable,GlobalSize,Appetite,BlName,2);\r
      END; (* MakeInternalLBDR *)\r
\r
\r
    PROCEDURE MakeExternalLBDR(SymbolPoint : St_Address;\r
                               EntryPoint : St_Address;\r
                               LineTable : integer;\r
                               GlobalSize : Word;\r
                               Appetite : Word;\r
                               BlName : SpixRange;\r
                               BlKind : integer);\r
      (* The procedure makes a external LBDR *)\r
\r
      VAR\r
        i : integer;\r
        ix : Word;\r
        Str : Ptr_String;\r
        ch : char;\r
\r
      BEGIN\r
\r
        MegaAllignCode;\r
\r
        IF BLkind = 1 THEN Putbin1Label(InternalLBDR,EntryPoint, ix)\r
        ELSE\r
         BEGIN\r
          Putbin1Label(ExternalLBDR,EntryPoint, ix);\r
\r
         END;\r
\r
        (* Put BlKind *)\r
        PutBin1value(DummyElement,BlKind,ix);\r
\r
        (* Put BlName   *)\r
        PutBin1Value(DummyElement,BlName,ix);\r
\r
        IF BLkind <> 1 THEN\r
        (* Appetite is transfere to paragrahps *)\r
        PutBin1Value(DummyElement,(Appetite + 3) Div 4 * 4,ix);\r
\r
\r
      END; (* MakeExternalLBDR *)\r
\r
    PROCEDURE DumpExternalThunks;\r
    VAR Ptr : St_elemPtr;\r
        ListOfExt : St_address;\r
        Bin1ix : Word;\r
        i, j : Integer;\r
        Str : Ptr_string;\r
    BEGIN\r
\r
      For i := 2 to NoOfPi3RoutinesAndSetRoutines DO\r
      IF Not Equal_Addr(PreExtCalled[i],St_Stopaddr) THEN\r
      BEGIN\r
        GenerateLabel(PreExtCalled[i]);\r
        Putbin1Value(Longjump, i - 1, Bin1ix);\r
        IF CodeOn THEN\r
        BEGIN\r
          write(tsymfile,MegaInstructionName[mJ],' ');\r
          St_NameOfSpix(PreExtName[i],Str);\r
          FOR j := 1 TO length(Str^) DO write(tsymfile,Str^[j]);\r
          writeln(tsymfile,' ');\r
        END;\r
      END;\r
\r
      ListOfExt := FirstExtDec;\r
       WHILE Not Equal_Addr(ListOfExt,St_NillAddr) DO\r
         BEGIN\r
           St_Retrieve(ListOfExt,Ptr);\r
           ListOfExt := Ptr^.Ext_Ref;\r
           St_Retrieve(Ptr^.Ext_Owner,Ptr);\r
           IF Not Equal_Addr(Ptr^.St_label,St_Stopaddr) THEN\r
           BEGIN\r
             GenerateLabel(Ptr^.St_label);\r
             Putbin1Value(Longjump, Ptr^.St_Curno - 1, Bin1ix);\r
             IF CodeOn THEN\r
             BEGIN\r
               write(tsymfile,MegaInstructionName[mJ],' ');\r
\r
               St_NameOfSpix(Ptr^.St_Spix,Str);\r
               FOR i := 1 TO length(Str^) DO write(tsymfile,Str^[i]);\r
               writeln(tsymfile,' ');\r
             END;\r
           END;\r
         END;\r
\r
      ExternalThunksDumped := True;\r
    END;\r
\r
   (* -------------------------------------------------------------- *)\r
\r
\r
\r
\r
    PROCEDURE Makepass4_2; FORWARD;\r
    PROCEDURE StopBlock;\r
      (* The procedure is called when there is no more code for\r
         the block. The procedure makes the <Object Block> for the block\r
         That is the secound pass is made *)\r
      VAR x: Word;\r
      BEGIN  (* StopBlock *)\r
      END;  (* StopBlock *)\r
\r
\r
\r
 (* ---------------------------------------------------------- *)\r
\r
\r
\r
\r
\r
    PROCEDURE StopCodeGene;\r
      (* The procedure is called when where is no more code to be\r
         generated. *)\r
\r
      VAR step : word;\r
          checksum : word;\r
          time_used : word;\r
      BEGIN  (* StopCodeGene *)\r
\r
        IF Not ExternalThunksDumped THEN DumpExternalThunks;\r
        MegaAllignCode;\r
        IF Nextbin1Out = 0 THEN\r
        IF Nextbin1in <> 0 THEN Nextbin1out := 1;\r
        WHILE Nextbin1In <> Nextbin1Out DO Putbin1Code;\r
        IF Nextbin1In <> 0 THEN Putbin1Code;\r
\r
        Emptyfilebuffer;\r
\r
        reset(TBinFile,1);\r
        IF Make_Code THEN reset(TSymFile);\r
\r
        JumpRec^.JumpNoElements := TempIndex;\r
\r
        MakePass4_2;\r
\r
        St_Unlock(Jumprec);\r
\r
                   (*\r
        for step := 1 to 8 do writeln('OffsetSize( ', step ,' ) = ',\r
             offsetstatistic[step]);\r
        for step := 1 to 8 do\r
          writeln('External thunk spare( ', step ,' ) = ',\r
             extthunkstatistic[step]);\r
        checksum := 0;\r
        for step := 1 to nopreextdecl do\r
        if preextcalled[step] then checksum := checksum + 1;\r
        writeln('No Of Externals = ', noextdecl + checksum - 1);*)\r
      END; (* StopCodeGene *)\r
\r
\r
\r
\r
  (*-------------------------------------------------------- *)\r
\r
  PROCEDURE MegaPfixCode(Inst: Instruction; Value: LongInt;\r
                         VAR Pfix: Pfix_type; Minlength: Integer);\r
  VAR Startdiv    : Longint;\r
      i           : integer;\r
      FixStarted  : Boolean;\r
\r
\r
      Procedure PutCode(Code: Instruction; Param : byte);\r
      VAR\r
        I_code : RECORD\r
            CASE BOOLEAN OF\r
              TRUE: (W    : WORD);\r
              FALSE:(B1,B2: BYTE);\r
        END;\r
      BEGIN\r
        I_Code.W                 := MegaInstructionValue[Code];\r
        Pfix.prefixes            := Pfix.Prefixes + 1;\r
        Pfix.Code[Pfix.Prefixes] := I_Code.B1 + Param;\r
      END;\r
\r
      Procedure OutPfix;\r
      VAR Val : Byte;\r
      BEGIN\r
        Val := Value DIV Startdiv;\r
        if (Val <> 0) OR (Fixstarted) THEN\r
        BEGIN\r
          PutCode(mPFIX, Val);\r
          Fixstarted := True;\r
        END;\r
        Value := Value MOD Startdiv;\r
        Startdiv := Startdiv DIV 16;\r
      END;\r
\r
    BEGIN\r
      Pfix.Prefixes := 0;\r
      Startdiv      := 16*16*16*16*16*16*16;\r
      FixStarted    := False;\r
\r
      IF MinLength <> 0 THEN\r
      BEGIN\r
        MinLength := MinLength - MegaPfixNo(Value);\r
        WHILE MinLength > 0 DO\r
        BEGIN\r
          MinLength := MinLength - 1;\r
          PutCode(mPFIX, 0);\r
        END;\r
      END;\r
\r
      IF Value < 0 THEN\r
      BEGIN\r
        Value := -Value - 1;\r
        FOR i := 1 TO 6 DO OutPfix;\r
        PutCode(mNFIX, Value DIV Startdiv);\r
        PutCode(Inst, 15 - (Value MOD 16));\r
      END ELSE\r
      BEGIN\r
        FOR i := 1 TO 7 DO OutPfix;\r
        PutCode(Inst, Value MOD 16);\r
      END;\r
\r
    END;\r
\r
    PROCEDURE GenCode(Inst : Instruction);\r
      (* Generate a instruction without parameter *)\r
\r
      VAR\r
        op : Byte;\r
        I_code : RECORD\r
            CASE BOOLEAN OF\r
              TRUE: (W    : WORD);\r
              FALSE:(B1,B2: BYTE);\r
            END;\r
\r
      BEGIN\r
\r
        IF Inst < mJ THEN Inst := iInstTomInst[Inst];\r
\r
        I_Code.W := MegaInstructionValue[Inst];\r
        IF I_code.B2 <> 0 THEN\r
        BEGIN\r
          Puttbinfile(I_code.B2);\r
          op := 2;\r
        END ELSE\r
        BEGIN\r
          op := 1;\r
        END;\r
        Puttbinfile(I_code.B1);\r
\r
\r
        (* Print to TSymFile *)\r
        IF CodeOn THEN writeln(TsymFile,op,' ',MegaInstructionName[Inst]);\r
\r
      END;  (* GenCode *)\r
\r
\r
    (* ---------------------------------------------------- *)\r
\r
\r
    PROCEDURE CodeConst(Inst : Instruction;  Value : longint; spix : spixrange );\r
      (* Generate a instruction with a constant parametre *)\r
\r
      VAR\r
        str : Ptr_String;\r
        i : integer;\r
        Pfix : Pfix_type;\r
\r
      BEGIN\r
\r
        MegaPfixCode(Inst, Value, Pfix, 0);\r
        FOR i := 1 TO Pfix.Prefixes DO Puttbinfile(Pfix.Code[i]);\r
        Case inst of\r
          mstl, mldl, mldnl, mstnl:\r
            Offsetstatistic[pfix.prefixes] :=\r
              Offsetstatistic[pfix.prefixes] + 1;\r
          else;\r
        end;\r
        (* Print to TSymFile *)\r
        IF CodeOn THEN\r
          BEGIN\r
            write(Tsymfile,Pfix.prefixes,' ',MegaInstructionName[Inst]);\r
            if spix = anonymousspix then writeln(Tsymfile,' ',Value)\r
            else\r
              begin\r
                St_NameOfSpix(Spix,Str);\r
                writeln(Tsymfile,' ',str^,' (',Value,')');\r
              end;\r
          END;\r
\r
\r
      END; (* CodeConst *)\r
\r
    PROCEDURE CallExtern(Addr : ST_address);\r
    Var Ptr : St_elemptr;\r
        Spix : Spixrange;\r
    BEGIN\r
      St_Get(Addr, Ptr);\r
      IF Equal_Addr(Ptr^.St_label, St_Stopaddr) THEN\r
      BEGIN\r
        spix := Ptr^.St_Spix;\r
        St_Declaration(cLabel, AnonymousName, Ptr^.St_Label, Ptr);\r
        Ptr^.St_Spix := Spix;\r
      END;\r
    END;\r
\r
    PROCEDURE CallRoutine(Spix : SpixRange; Number : Word;\r
                          RKind : St_DeclareMode);\r
      (* The procedure generates code for an external or an open routine call*)\r
\r
      VAR\r
        i :integer;\r
        Index , Leng : word;\r
        Str : Ptr_String;\r
        Ptr : St_ElemPtr;\r
        Lab : Array[0..MaxLabInOpen] OF\r
          RECORD\r
            Lab : St_Address;\r
            Used : Boolean;\r
          END;\r
      BEGIN\r
\r
          IF Spix = AnonymousSpix THEN Spix := PreExtName[Number];\r
\r
          IF RKind = St_Extern THEN\r
          BEGIN\r
            if (Number <= NoRoutinesWithStatLink) THEN\r
              CodeConst(mLDL,StaOff,AnonymousSpix);\r
            IF Equal_Addr(PreExtCalled[Number], St_Stopaddr) THEN\r
            BEGIN\r
              St_Declaration(cLabel,AnonymousName,PreExtCalled[Number],Ptr);\r
              Ptr^.St_Spix := Spix;\r
            END;\r
            Putbin1Label(InternalCall, PreExtCalled[Number], Index);\r
          END;\r
\r
        IF rkind = St_open THEN\r
            (* An open routine call *)\r
          BEGIN\r
           for i := 0 To MaxLabInOpen DO Lab[i].Used := false;\r
            WordByte.Byte1 := CodeOfOpenRoutines[(Number * 2) + 2];\r
            WordByte.Byte2 := CodeOfOpenRoutines[(Number * 2) + 3];\r
            Index := WordByte.w + 2;\r
\r
            (* The index to the open routines length is in Index *)\r
            while CodeOfOpenRoutines[Index] <> Openfinish DO\r
              BEGIN\r
                 CASE CodeOfOpenRoutines[Index] OF\r
\r
                 OpenCode :\r
                   BEGIN\r
                     Index := Index + 1;\r
                     Leng := CodeOfOpenRoutines[Index];\r
                     IF Codeon THEN\r
                       BEGIN\r
                        write(tsymfile,Leng,' ','///// ');\r
                        St_NameOfSpix(Spix,Str);\r
                        FOR  i := 1 TO length(Str^) DO\r
                             write(tsymfile,Str^[i]);\r
                        writeln(tsymfile,' ');\r
                       END;\r
                     For i := 1 to leng do\r
                      begin\r
                        Index := Index + 1;\r
                        PutTBinFile(CodeOfOpenRoutines[Index]);\r
                      end;\r
                   END;\r
                 OpenPushProc :   CodeConst(mLDL,StaOff,AnonymousSpix);\r
\r
                 OpenJump :\r
                   BEGIN\r
                     Index := Index + 1;\r
                     IF Lab[CodeOfOpenRoutines[Index]].used = false then\r
                        St_Declaration(CLabel,AnonymousName,\r
                              Lab[CodeOfOpenRoutines[Index]].lab,Ptr);\r
                      CodeJump(mJ,Lab[CodeOfOpenRoutines[Index]].Lab);\r
                     Lab[CodeOfOpenRoutines[Index]].used := true;\r
                   END;\r
                 OpenCJump :\r
                   BEGIN\r
                     Index := Index + 1;\r
                     IF Lab[CodeOfOpenRoutines[Index]].used = false then\r
                        St_Declaration(CLabel,AnonymousName,\r
                              Lab[CodeOfOpenRoutines[Index]].lab,Ptr);\r
                      CodeJump(mCJ,Lab[CodeOfOpenRoutines[Index]].Lab);\r
                     Lab[CodeOfOpenRoutines[Index]].used := true;\r
                   END;\r
                 OpenLabel :\r
                   BEGIN\r
                     Index := Index + 1;\r
                     IF Lab[CodeOfOpenRoutines[Index]].used = false then\r
                        St_Declaration(CLabel,AnonymousName,\r
                              Lab[CodeOfOpenRoutines[Index]].lab,Ptr);\r
                      GenerateLabel(Lab[CodeOfOpenRoutines[Index]].Lab);\r
                     Lab[CodeOfOpenRoutines[Index]].used := true;\r
                   END;\r
                 END;\r
               Index := Index + 1;\r
              END;\r
\r
\r
          END;\r
\r
\r
\r
      END;\r
\r
    (* ------------------------------------------------------ *)\r
\r
    FUNCTION StoreTemp(offset : Word) : Integer;\r
     VAR Index : word;\r
      BEGIN\r
        PutBin1Value(TempSTL,Offset,Index);\r
        StoreTemp := Index;\r
      END;\r
\r
    Procedure StoreTempOK(Index : Integer);\r
      BEGIN\r
        if InsertBin1ix(Index) then else\r
        BEGIN\r
          Fatal_error(Pass4,11);\r
        END;\r
      END;\r
\r
\r
    PROCEDURE CodeJump(Inst : Instruction; Lab : St_Address);\r
      (* Generate a instruction with a label as operand *)\r
\r
      VAR\r
        Ptr : st_ElemPtr;\r
        Lab1 : St_Address;\r
        Bool : Boolean;\r
        InstLength : word;\r
\r
      BEGIN\r
        IF Inst = iJMP THEN Inst := mJ;\r
\r
        IF (Inst = mJ) OR (Inst = mCJ) THEN ReleaseStrucDyn;\r
\r
\r
        IF (( Inst = mJ ) AND (LastLabelOffset = InternalOffset)) THEN\r
          BEGIN\r
            (* A superflous is elemined *)\r
            (* Make sure lab is not defined as lastlabel *)\r
            Bool := true;\r
            Lab1 := Lab;\r
            WHILE Bool AND Not Equal_Addr(Lab1,St_Nilladdr) DO\r
              IF Equal_Addr(Lab1,LastLabel)\r
                THEN Bool := false\r
                ELSE\r
                  BEGIN\r
                    ST_Retrieve(Lab1,Ptr);\r
                    Lab1 := Ptr^.DefAsLabel;\r
                  END;\r
\r
            IF Bool THEN\r
              BEGIN\r
                (* The superflous can be elemined *)\r
                St_Get(LastLabel,Ptr);\r
                Ptr^.MegaLabel_Offset := 0;\r
                GenAsLabel(LastLabel,Lab);\r
                LastLabelOffset := 0;\r
              END\r
            ELSE\r
              (* the jmp may not be delete *)\r
              LastJMPOffset := 0;\r
          END;\r
\r
        (* If this is a JMP instruction and the last instruction was a JMP\r
           too this instruction is not generated *)\r
        IF not ((Inst = mJ) AND ( LastJMPOffset = InternalOffset)) THEN\r
          BEGIN   (* generated the instruction *)\r
\r
            CASE Inst OF\r
              mJ : Putbin1Label(UnCondJump, Lab, InstLength);\r
              mCJ : Putbin1Label(CondJump, Lab, InstLength);\r
              mCALL : Putbin1Label(InternalCall, Lab, InstLength);\r
            END;\r
            if inst = mJ then LastJMPOffset := InternalOffset;\r
          END;\r
      END; (* CodeJump *)\r
\r
   PROCEDURE ReleaseStrucDyn;\r
     BEGIN\r
      IF (InStrucValue = 0) AND StrucInExp THEN\r
         BEGIN\r
           CodeConst(mLDL,StrucOffset,Anonymousspix);\r
           CodeConst(mLDL,StaOff,Anonymousspix);\r
           CodeConst(mLDNL,Proc_StackOccam,Anonymousspix);\r
           GenCode(mADD);\r
\r
           CodeConst(mLDL,StaOff,Anonymousspix);\r
           CodeConst(mSTNL,Proc_StackLimit,Anonymousspix);\r
           StrucInExp := false;\r
         END;\r
     END;\r
  (* --------------------------------------------------------- *)\r
\r
\r
\r
    PROCEDURE CodeFault(ErrorInt, ErrorExc: WORD);\r
    BEGIN\r
      codeconst(mLDC,errorInt,AnonymousSpix);\r
      CallRoutine(AnonymousSpix, 0, St_Open);\r
    END;\r
\r
\r
\r
\r
    PROCEDURE CodeFaultAX(ErrorInt, ErrorExc: WORD);\r
    BEGIN\r
    END;\r
\r
\r
  (* --------------------------------------------------------- *)\r
\r
\r
\r
    PROCEDURE CodeLoadEffAddr(Lab : St_Address; Offset : Word);\r
      (* Generate code to load AReg with the effectiv address of Lab: + offset *)\r
\r
      VAR\r
	w : word;\r
      BEGIN\r
       PutBin1Label(AddLabelToDis,Lab,w);\r
       PutBin1Value(DummyElement,Offset,w);\r
      END; (* CodeLoadEffAddr *)\r
\r
\r
  (* --------------------------------------------------------- *)\r
\r
\r
\r
    PROCEDURE GenerateLabel(Lab : St_Address);\r
      (* Generate the label given by Lab *)\r
\r
      VAR Ptr : St_Elemptr;\r
          ix  : WORD;\r
      BEGIN\r
\r
        IF ((LastLabelOffset = InternalOffset) AND\r
            ( NOT Equal_Addr(Lab,LastLabel)))THEN\r
          BEGIN\r
            (* One label has been generated with this offset *)\r
            GenAsLabel(Lab,LastLabel);\r
          END\r
        ELSE\r
          BEGIN\r
            (* generate the label *)\r
            St_Get(Lab,Ptr);\r
\r
            Ptr^.MegaLabel_Offset := InternalOffset;\r
            Ptr^.Label_Scope := $FFFF;\r
            Putbin1Label(DeclareLabel, Lab, ix);\r
\r
            LastLabelOffset := InternalOffset;\r
            LastLabel := Lab;\r
          END;\r
\r
      END;  (* GenerateLabel *)\r
\r
\r
   (* --------------------------------------------------------- *)\r
\r
\r
    PROCEDURE GenAsLabel(Lab1, Lab2 : St_Address);\r
      (* The offset of Lab1 is defined by the offset of Lab2\r
         Lab1 is never generated  *)\r
      VAR\r
        Ptr : St_ElemPtr;\r
        Spix : Spixrange;\r
      BEGIN\r
\r
        St_Get(Lab1,Ptr);\r
        Ptr^.DefAsLabel := Lab2;\r
        Spix := Ptr^.St_Spix;\r
        IF Spix <> AnonymousSpix THEN\r
        Begin\r
          St_Get(Lab2, Ptr);\r
          Ptr^.St_Spix := Spix;\r
        END;\r
\r
      END;  (* GenAsLabel *)\r
\r
\r
\r
      PROCEDURE Init_Pass4_2;\r
      (* The procedure initialize Pass4_2 *)\r
\r
      VAR\r
        i : integer;\r
      BEGIN\r
\r
\r
        FirstExtDec := St_NillAddr;\r
        NoExtDecl := 0;\r
\r
        LengthOfAllPreExtName := 0;\r
        LengthOfAllExtName := 0;\r
\r
        FirstFixUpp := St_NillAddr;\r
        LastFixUpp := St_NillAddr;\r
        NoFixUpp := 0;\r
\r
\r
        CodeOnPass2 := false;\r
\r
        filebufferindex := 0;\r
        filebufferlast := 0;\r
        eoftbinfile := false;\r
\r
        FirstBlock := true;\r
        (* Used when making linetabel *)\r
\r
        FOR i := 0 TO 9 DO\r
          HexNumber[ i ] := chr(ord('0') + i);\r
        FOR i := 0 TO 5 DO\r
          HexNumber[ 10 + i ] := chr(ord('A') + i);\r
\r
      END;  (* InitPass4_2 *)\r
\r
    PROCEDURE InitCodeGenerator;\r
      (* The procedure initialize the codegenerator *)\r
\r
      VAR\r
        i : integer;\r
        PreName : string[16];\r
        Inst : Instruction;\r
      BEGIN\r
\r
        StrucInExp := false;\r
\r
        Filebufferindex := 0;\r
        CodeOn := false;\r
        InternalOffset := 0;\r
\r
        Nextbin1In := 0;\r
        Nextbin1Out:= 0;\r
        Elonbin1   := 0;\r
        Bin2codeOut:= 0;\r
\r
        St_reserveJump(FirstTempPage, JumpRec);\r
        ST_Lock(JumpRec);\r
        TempIndex := 0;\r
\r
        LastLabelOffset := -1;\r
        LastJMPOffset := -1;\r
        LastLabel := St_NillAddr;\r
\r
        Spacing := Call_Options.Spacing;\r
        LineTabel := (Spacing <> 0);\r
        LastNameEntry := St_NillAddr;\r
        LengthOfNameTabel := 0;\r
\r
        CurrentSegNo := 1;\r
\r
        (* reads the code for the open routines *)\r
        i := 0;\r
        WHILE NOT EOF(OpenRoutine) DO\r
          BEGIN\r
            IF i > MaxLengthOfOpenRoutines THEN\r
              Fatal_Error(Pass4,9);\r
\r
            read(OpenRoutine,CodeOfOpenRoutines[i]);\r
            (*\r
            CodeOfOpenRoutines[i] := OpenRoutine^;\r
            get(OpenRoutine);*)\r
            i := i + 1;\r
          END;\r
\r
        Init_Pass4_2;\r
\r
        MegaInstructionName[mJ]     := 'J';\r
        MegaInstructionName[mLDLP]  := 'LDLP';\r
        MegaInstructionName[mPFIX]  := 'PFIX';\r
        MegaInstructionName[mLDNL]  := 'LDNL';\r
        MegaInstructionName[mLDC]   := 'LDC';\r
        MegaInstructionName[mLDNLP] := 'LDNLP';\r
        MegaInstructionName[mNFIX]  := 'NFIX';\r
        MegaInstructionName[mLDL]   := 'LDL';\r
        MegaInstructionName[mADC]   := 'ADC';\r
        MegaInstructionName[mCALL]  := 'CALL';\r
        MegaInstructionName[mCJ]    := 'CJ';\r
        MegaInstructionName[mAJW]   := 'AJW';\r
        MegaInstructionName[mEQC]   := 'EQC';\r
        MegaInstructionName[mSTL]   := 'STL';\r
        MegaInstructionName[mSTNL]  := 'STNL';\r
        MegaInstructionName[mOPR]   := 'OPR';\r
        MegaInstructionName[mREV]   := 'REV';\r
        MegaInstructionName[mLB]    := 'LB';\r
        MegaInstructionName[mBSUB]  := 'BSUB';\r
        MegaInstructionName[mDIFF]  := 'DIFF';\r
        MegaInstructionName[mADD]   := 'ADD';\r
	MegaInstructionName[mGCALL] := 'GCALL';\r
        MegaInstructionName[mPROD]  := 'PROD';\r
        MegaInstructionName[mGT]    := 'GT';\r
        MegaInstructionName[mWSUB]  := 'WSUB';\r
        MegaInstructionName[mSUB]   := 'SUB';\r
        MegaInstructionName[mSETERR]:= 'SETERR';\r
        MegaInstructionName[mCSUB0] := 'CSUB0';\r
        MegaInstructionName[mLDPI]  := 'LDPI';\r
        MegaInstructionName[mXDBLE] := 'XDBLE';\r
        MegaInstructionName[mREM]   := 'REM';\r
        MegaInstructionName[mRET]   := 'RET';\r
        MegaInstructionName[mDIV]   := 'DIV';\r
        MegaInstructionName[mNOT]   := 'NOT';\r
        MegaInstructionName[mXOR]   := 'XOR';\r
        MegaInstructionName[mXWORD] := 'XWORD';\r
        MegaInstructionName[mSB]    := 'SB';\r
        MegaInstructionName[mSHR]   := 'SHR';\r
        MegaInstructionName[mSHL]   := 'SHL';\r
        MegaInstructionName[mAND]   := 'AND';\r
        MegaInstructionName[mMOVE]  := 'MOVE';\r
        MegaInstructionName[mOR]    := 'OR';\r
        MegaInstructionName[mCCNT1] := 'CCNT1';\r
        MegaInstructionName[mMUL]   := 'MUL';\r
        MegaInstructionName[mCWORD] := 'CWORD';\r
\r
        MegaInstructionValue[mJ]     := $0000;\r
        MegaInstructionValue[mLDLP]  := $0010;\r
        MegaInstructionValue[mPFIX]  := $0020;\r
        MegaInstructionValue[mLDNL]  := $0030;\r
        MegaInstructionValue[mLDC]   := $0040;\r
        MegaInstructionValue[mLDNLP] := $0050;\r
        MegaInstructionValue[mNFIX]  := $0060;\r
        MegaInstructionValue[mLDL]   := $0070;\r
        MegaInstructionValue[mADC]   := $0080;\r
        MegaInstructionValue[mCALL]  := $0090;\r
        MegaInstructionValue[mCJ]    := $00a0;\r
        MegaInstructionValue[mAJW]   := $00b0;\r
        MegaInstructionValue[mEQC]   := $00c0;\r
        MegaInstructionValue[mSTL]   := $00d0;\r
        MegaInstructionValue[mSTNL]  := $00e0;\r
        MegaInstructionValue[mOPR]   := $00f0;\r
        MegaInstructionValue[mREV]   := $00f0;\r
        MegaInstructionValue[mLB]    := $00f1;\r
        MegaInstructionValue[mBSUB]  := $00f2;\r
        MegaInstructionValue[mDIFF]  := $00f4;\r
        MegaInstructionValue[mADD]   := $00f5;\r
	MegaInstructionValue[mGCALL] := $00f6;\r
        MegaInstructionValue[mPROD]  := $00f8;\r
        MegaInstructionValue[mGT]    := $00f9;\r
        MegaInstructionValue[mWSUB]  := $00fa;\r
        MegaInstructionValue[mSUB]   := $00fc;\r
        MegaInstructionValue[mSETERR]:= $21f0;\r
        MegaInstructionValue[mCSUB0] := $21f3;\r
        MegaInstructionValue[mLDPI]  := $21fb;\r
        MegaInstructionValue[mXDBLE] := $21fd;\r
        MegaInstructionValue[mREM]   := $21ff;\r
        MegaInstructionValue[mRET]   := $22f0;\r
        MegaInstructionValue[mDIV]   := $22fc;\r
        MegaInstructionValue[mNOT]   := $23f2;\r
        MegaInstructionValue[mXOR]   := $23f3;\r
        MegaInstructionValue[mXWORD] := $23fa;\r
        MegaInstructionValue[mSB]    := $23fb;\r
        MegaInstructionValue[mSHR]   := $24f0;\r
        MegaInstructionValue[mSHL]   := $24f1;\r
        MegaInstructionValue[mAND]   := $24f6;\r
        MegaInstructionValue[mMOVE]  := $24fa;\r
        MegaInstructionValue[mOR]    := $24fb;\r
        MegaInstructionValue[mCCNT1] := $24fd;\r
        MegaInstructionValue[mMUL]   := $25f3;\r
        MegaInstructionValue[mCWORD] := $25f6;\r
\r
        FOR Inst := iXLAT TO iMOD DO iInstTomInst[Inst] := mPFIX;\r
        iInstTomInst[iAND] := mAND;\r
        iInstTomInst[iMUL] := mMUL;\r
        iInstTomInst[iOR]  := mOR;\r
        iInstTomInst[iSUB] := mSUB;\r
        iInstTomInst[iXOR] := mXOR;\r
        iInstTomInst[iADD] := mADD;\r
        iInstTomInst[iDIV] := mDIV;\r
        iInstTomInst[iMOD] := mREM;\r
\r
        NoPreExtDecl := NoOfPi3RoutinesAndSetRoutines;\r
        (* Initialize the the list of External Name  *)\r
        for i := 1 to NoOfPi3RoutinesAndSetRoutines do\r
          PreExtCalled[i] := St_Stopaddr;\r
        PreExtCalled[1] := St_Nilladdr;\r
\r
        PreName := 'RTPLBDR';\r
        PreExtName[Rtplbdr] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 7;\r
\r
        PreName := 'PUSH_BUF';\r
        PreExtName[push_buf] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 8;\r
\r
        PreName := 'POP_BUF';\r
        PreExtName[pop_buf] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 7;\r
\r
        PreName := 'GETBUF';\r
        PreExtName[getbuf] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 6;\r
\r
        PreName := 'GETBUFDELAY';\r
        PreExtName[getbufdelay] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 11;\r
\r
        PreName := 'SIGNAL';\r
        PreExtName[signal] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 6;\r
\r
        PreName := 'WAIT';\r
        PreExtName[wait] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 4;\r
\r
        PreName := 'WAITDELAY';\r
        PreExtName[waitdelay] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'PUTBUF';\r
        PreExtName[putbuf] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 6;\r
\r
        if computer =  Partner then\r
        begin\r
          Prename := 'FAULT';\r
          LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
        end\r
        else\r
        begin\r
          PreName := 'RESUME';\r
          LengthOfAllPreExtName := LengthOfAllPreExtName + 6;\r
        end;\r
        PreExtName[resume] := St_SpixOfName(PreName);\r
\r
\r
\r
        if computer =  Partner  then\r
        begin\r
          Prename := 'FAULT';\r
          LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
        end\r
        else\r
        begin\r
        PreName := 'CHAINDEQUEUE';\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 12;\r
        end;\r
\r
        PreExtName[ChainDeQueue] := St_SpixOfName(PreName);\r
\r
        if computer = Partner then\r
        begin\r
          Prename := 'FAULT';\r
          LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
        end\r
        else\r
        begin\r
        PreName := 'CHAINENQUEUE';\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 12;\r
        end;\r
\r
        PreExtName[ChainEnQueue] := St_SpixOfName(PreName);\r
\r
\r
\r
\r
\r
        PreName := 'ALLOCPOOL';\r
        PreExtName[AllocPool] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
        PreName := 'INIT_SEMAPHORE';\r
        PreExtName[Init_Semaphore] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 14;\r
\r
\r
        PreName := 'WAITS';\r
        PreExtName[WAITS] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
\r
\r
        PreName := 'SET_EXCEPTION';\r
        PreExtName[Set_Exception ] := St_SpixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 13;\r
\r
\r
        PreName := 'INIT_REFERENCE';\r
        PreExtName[Init_Reference] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 14;\r
\r
\r
\r
        PreName := 'INIT_CHAIN';\r
        PreExtName[Init_Chain] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 10;\r
\r
\r
\r
        PreName := 'INIT_SHARED';\r
        PreExtName[Init_Shared] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 11;\r
\r
\r
\r
        PreName := 'INIT_MAILBOX';\r
        PreExtName[Init_MailBox] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 12;\r
\r
\r
\r
        PreName := 'INIT_PROCESS';\r
        PreExtName[Init_Process] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 12;\r
\r
\r
\r
        PreName := 'INIT_INTERNAL';\r
        PreExtName[Init_Internal] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 13;\r
\r
\r
\r
        PreName := 'INIT_EXTERNAL';\r
        PreExtName[Init_External] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 13;\r
\r
\r
\r
        PreName := 'INIT_PORT';\r
        PreExtName[Init_Port] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'SIGNALS';\r
        PreExtName[SignalS] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 7;\r
\r
\r
        PreName := 'INIT_POOL';\r
        PreExtName[Init_Pool] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'ENDPROCESS';\r
        PreExtName[EndProcess] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 10;\r
\r
\r
        PreName := 'MARK_LOCALREF';\r
        PreExtName[Mark_LocalRef] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 13;\r
\r
\r
        PreName := 'UNCHAIN_LOCALREF'; (* EF  insert  *)\r
        PreExtName[UnChain_LocalRef] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 16;\r
\r
\r
        PreName := 'INIT_LOCALREF';\r
        PreExtName[Init_LocalRef] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 13;\r
\r
\r
        PreName := 'EXCHANGE';\r
        PreExtName[Exchange] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 8;\r
\r
\r
        PreName := 'RTP.EXREC';\r
        PreExtName[ExcRec] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
\r
        PreName := 'RTP.EXPACK';\r
        PreExtName[ExcPack] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 10;\r
\r
\r
\r
        PreName := 'RTP.EQREC';\r
        PreExtName[Eqrec] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
\r
        PreName := 'RTP.GTREC';\r
        PreExtName[Gtrec] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'RTP.DYNALLOC';\r
        PreExtName[DynAlloc] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 12;\r
\r
\r
        PreName := 'RTP.STSTR';\r
        PreExtName[StStr] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'RTP.EXSTR';\r
        PreExtName[ExStr] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'RTP.GTSTR';\r
        PreExtName[GtStr] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
        PreName := 'RTP.EQSTR';\r
        PreExtName[EqStr] := St_spixOfName(PreName);\r
        LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
        IF Make_Set THEN\r
          BEGIN\r
\r
            PreName := 'ASSIGNSET';\r
            PreExtName[AssignSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 9;\r
\r
\r
            PreName := 'ADDSET';\r
            PreExtName[AddSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 6;\r
\r
\r
            PreName := 'SUBSET';\r
            PreExtName[SubSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 6;\r
\r
\r
            PreName := 'MULTSET';\r
            PreExtName[MultSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 7;\r
\r
\r
            PreName := 'GESET';\r
            PreExtName[GESet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
\r
\r
            PreName := 'EQSET';\r
            PreExtName[EQSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
\r
\r
            PreName := 'NESET';\r
            PreExtName[NESet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
\r
\r
            PreName := 'LESET';\r
            PreExtName[LESet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
\r
\r
            PreName := 'INSET';\r
            PreExtName[INSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 5;\r
\r
\r
            PreName := 'MAKESET';\r
            PreExtName[MakeSet] := St_spixOfName(PreName);\r
            LengthOfAllPreExtName := LengthOfAllPreExtName + 7;\r
\r
\r
          END;\r
\r
          For i := 1 to 8 do\r
          begin\r
            Offsetstatistic[i] := 0;\r
            extthunkstatistic[i] := 0;\r
          end;\r
\r
          ExternalThunksDumped := False;\r
\r
      END;  (* InitCodeGenerator *)\r
\r
\r
    (* --------------------------------------------------- *)\r
\r
{$I P450}\r
\r
\r
END\r
  .\r
\r
\r
\r
\r
  (* -------- PRIVATE CODEGENERATOR  ----------- CODEGENERATOR --*)\r
\r
\r
\r
\r
\r
«eof»