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

⟦ea76cc3fe⟧ TextFile

    Length: 45378 (0xb142)
    Types: TextFile
    Names: »P435CODE.PAS«

Derivation

└─⟦037c0ce35⟧ Bits:30010524 DVBS1.SW2114.src.2.6-2 RTP compiler source SW2104+SW2114 Disk#2 30/1-92 HHA
    └─⟦this⟧ »RTP\P435CODE.PAS« 
└─⟦828f0d3dd⟧ Bits:30010527 DVBS1.SW2114.src.2.6-5 RTP Compiler Source SW2104+SW2114 Disk 2 92.02.03 HEJ HHA
    └─⟦this⟧ »RTP\P435CODE.PAS« 
└─⟦891417be1⟧ Bits:30010519 DVBS1.SW2114.src.2-1 SW2114 1/4 Real Time Pascal 2.7 92.06.16
    └─⟦this⟧ »RTP\P435CODE.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\P435CODE.PAS« 

TextFile

{$O+,F+}\r
unit p435code;\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
\r
      MaxStack = 16;\r
      BonAppetite = 42;\r
      ExopCode = 8;\r
      ExPoint = 13;\r
      ExitAppetite = 0;\r
      ExCode = 6;\r
      exic = 9;\r
\r
      mfirst = 0;\r
      mlast = 2;\r
      msize = 10;\r
      mstart = 12;\r
\r
      Proc_StackLimit = 8;\r
      Proc_StackOccam = 9;\r
      Proc_exception_offset = 2;\r
\r
      Prog_Descr_Size = 100;\r
      Proc3502_Descr_Size = 80;\r
\r
      LengthOfSharedType = 10;\r
      LengthOfSemaphore = 8;\r
      SharedCounterOffset = 4;\r
      LockedOffset  = 4;\r
      DataSizeOffset = 8;\r
      OffsetOffset = 12;\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
      RefLockExc = 3;\r
\r
      IndexOutOfRangeInt = 5;\r
      IndexOutOfRangeExc = 50;   (* fault 50 *)\r
                     (*\r
      StackOverFlowInt = 30;\r
      StackOverFlowExc = 51;  (* fault 51 *)\r
        (* Parametre to interrupt when stack overflow *)\r
\r
      OutOfRangeInt = 0;\r
      OutOfRangeExc = 52;  (* fault 52 *)\r
\r
      OtherwiseInt = 36;\r
      OtherwiseExc = 53;  (* 53 *)\r
                       (*\r
      LockInt = 27;\r
      LockExc = 54;  (* 54 *)\r
                         (*\r
      AccessCheckInt = 26;\r
      AccessCheckExc = 55;  (* 55 *)\r
        (* Parametre to interupt when accesscheck error *)\r
                            (*\r
      PointerNilInt = 25;\r
      PointerNilExc = 56;   (* 56 *)\r
\r
      CheckParamInt = 43;\r
      CheckParamExc = 57;  (* 57 *)\r
\r
      StrucInt =  23;\r
      StrucExc =  58;  (* 58  *)\r
                        (*\r
      SubRangeInt = 22;\r
      SubRangeExc = 59;  (* 59 *)\r
\r
      WithInt = 39;\r
      WithExc = 60;  (* 60 *)\r
                  (*\r
      IntOnFault = 31;\r
\r
      DynArrayExc = 64;\r
\r
      DynRecordExc = 64;\r
                    *)\r
\r
\r
\r
      (* PI3 constant *)\r
      call_frame = 20;\r
      (* The following gives the number for the predefined external routines *)\r
      Exception = 1;\r
      shift = 2;\r
      Init_Reference = 3;\r
      Init_Chain = 4;\r
      Init_Shared = 5;\r
      Init_Mailbox = 6;\r
      Init_Process = 7;\r
      Init_Internal = 8;\r
      Init_External = 9;\r
      Init_Port = 10;\r
      Init_Pool = Init_Mailbox;\r
      UnChain_LocalRef = 11;\r
      Init_LocalRef = Init_Reference;\r
\r
      AllocPool = 12;\r
      ChainDeQueue = 13;\r
      ChainEnQueue = 14;\r
      Init_Semaphore = 15;\r
      waits = 16;\r
      Signals = 17;\r
\r
\r
      ExcRec = 18;\r
      ExcProcess = 19;\r
      ExcPack = 20;\r
      Eqrec = 21;\r
      StStr = 22;\r
      ExStr = 23;\r
      GtStr = 24;\r
      LtStr = 25;\r
      EqStr = 26;\r
      ExcRecPack = 27;\r
      ExcPackRec = 28;\r
      heapref = 29;\r
\r
      NoOfPI3Routines = 29;\r
      NoOfSetRoutines = 11;\r
      NoOfPI3RoutinesAndSetRoutines = NoOfPI3Routines + NoOfSetRoutines;\r
\r
   (* External set Routine *)\r
      AssignSet = NoOfPi3Routines + 1;\r
      PushSet = NoOfPi3Routines + 2;\r
      AddSet = NoOfPi3Routines + 3;\r
      SubSet = NoOfPi3Routines + 4;\r
      MultSet= NoOfPi3Routines + 5;\r
      GESet = NoOfPi3Routines + 6;\r
      EQSet= NoOfPi3Routines + 7;\r
      NESet= NoOfPi3Routines + 8;\r
      LESet = NoOfPi3Routines + 9;\r
      InSet = NoOfPi3Routines + 10;\r
      MakeSet = NoOfPi3Routines + 11;\r
\r
\r
    VAR\r
      CodeSize : Word ; (* to be removed at sometime *)\r
      (* List contains the  external routines *)\r
      FirstExtDec : St_Address;\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
      ExceptionLab : 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
\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[6];\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
      InstructionName : ARRAY[rRENPB..rMTRS] OF CodeName;\r
      InstructionValue: ARRAY[rRENPB..rMTRS] OF WORD;\r
      InstructionStack: ARRAY[rRENPB..rMTRS] OF Byte;\r
      iInstTorInst    : ARRAY[iXLAT..iMOD] OF Instruction;\r
\r
      InStack : Integer;\r
      RelativeCondJumpInst : Integer;\r
\r
      PreExtName : ARRAY[1..NoOfPI3RoutinesAndSetRoutines] of SpixRange;\r
      PreExtCalled : ARRAY[1..NoOfPI3RoutinesAndSetRoutines] of Integer;\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
      Offsetstatistic, extthunkstatistic : array[1..8] OF Integer;\r
\r
    (* -------------------------------------------- *)\r
\r
\r
    PROCEDURE InitCodeGenerator;\r
       (* The procedure initialize the codegenerator *)\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
    PROCEDURE MakeInternalLBDR( SymbolPoint : St_Address;\r
                                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
\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
    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 GenerateEntryPoint(Lab : St_Address);\r
      (* Generate the Entry Point 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; low,high : integer;\r
	       OtherwiseLab : St_Address);\r
      (* The casetabel is generated *)\r
\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
      StackAbs = 128;\r
      StackNeg = 64;\r
      StackPar = 8;\r
\r
      MaxLengthOfOpenRoutines = 2000;\r
        (* this constant must be changed if new opernroutins is made *)\r
\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
      NoOfOutPageJumps : Integer;\r
      NewPageCounter   : Integer;\r
      LineTabSize      : Integer;\r
      LastLineTabSize  : Integer;\r
      LastLinenumber   : Integer;\r
\r
      InternalStartList, InternalEndList,\r
      ExternalStartList, ExternalEndList : St_Address;\r
      St_LineTable, St_RoutineName : St_Address;\r
\r
      InternalOffset, Offset : Longint;\r
\r
      LastJMPOffset : Longint; (* internaloffset after generating the last\r
                               JMP instruction *)\r
\r
      LastLabelOffset : Longint;\r
                   (* InternalOffset of the last generated label *)\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
      FirstLine  : Integer;\r
\r
      TBinFileptr : byte;\r
\r
      filebufferlast : Integer;\r
      eoftbinfile : boolean;\r
\r
      Bin2codeOut: word;\r
\r
      FirstTempPage , TempPage : St_Address;\r
      TempIndex : Integer;\r
      JumpRec :  St_elemPtr;\r
      LastJumprec : Tempbin1_Record;\r
      JumpToNextPage : Integer;\r
      InternalLinkEntries : Word;\r
      maxcodeblock : word;\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 Putbin1Value(Code : CodeFormat; CodeValue: WORD); FORWARD;\r
\r
 Procedure CheckRoomOnPage(Size : Integer);\r
 BEGIN\r
   IF (InternalOffset DIV CodeSize) <> ((InternalOffset + Size + LineTabSize\r
           + (NoOfOutPageJumps+JumpToNextPage)*4) DIV CodeSize) THEN\r
   BEGIN\r
      InternalOffset   := ((InternalOffset DIV CodeSize)+1)*CodeSize;\r
      NoOfOutPageJumps := 0;\r
   END;\r
 END;\r
\r
 Procedure AddInternal(Addition : Integer);\r
 BEGIN\r
   CheckRoomOnPage(Addition);\r
   internaloffset := internaloffset + Addition;\r
 END;\r
\r
 PROCEDURE ChangeCodeSize(Val : Word);\r
 BEGIN\r
   CodeSize := Val + ord(odd(val)) + 18; (* room for entrypoint *)\r
   CodeSize := CodeSize + ((5+1+1) + CodeSize DIV Spacing)*2;\r
   LineTabSize := (5+1+1) + CodeSize DIV Spacing;\r
   maxcodeblock := CodeSize -linetabsize - 4 - 18;\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
  AddInternal(1);\r
  Bin2codeOut    := Bin2codeOut + 1;\r
 END;\r
\r
    PROCEDURE RegisterStackAdjust(Inst : Instruction);\r
    VAR InstStack, Wanted, StackAdd : Integer;\r
    BEGIN\r
      InstStack := InstructionStack[Inst];\r
      Wanted := (InstStack SHR 3) AND 7;\r
      IF InStack < Wanted THEN\r
      BEGIN\r
        CodeConst(rRESTA, 2*Wanted, AnonymousSpix);\r
      END;\r
      StackAdd := InstStack AND 7;\r
      IF (InstStack AND StackAbs) <> 0 THEN\r
      BEGIN\r
        InStack   := StackAdd;\r
        StackAdd  := 0;\r
      END;\r
\r
      IF (InstStack AND StackNeg) <> 0 THEN StackAdd := -StackAdd;\r
      InStack := Instack + StackAdd;\r
      IF Instack > 8 THEN\r
      BEGIN\r
        IF 2*Wanted < 8 THEN CodeConst(rRESTA, 8, Anonymousspix)\r
                        ELSE CodeConst(rRESTA, 2*Wanted, AnonymousSpix);\r
        InStack := Instack + StackAdd;\r
      END ELSE\r
      IF Instack < 0 THEN\r
      BEGIN\r
        Instack := 0;\r
      END;\r
    END;\r
\r
  Procedure Putbin1Code(Var Trec : Tempbin1_record);\r
  BEGIN\r
    NewTempPage;\r
    IF Tempindex = Jumprec^.JumpNoElements THEN\r
    IF Trec.Bin1Code = AddLabelToDis THEN\r
    BEGIN\r
      JumpRec^.JumpNoElements := JumpRec^.JumpNoElements - 1;\r
      NewTempPage;\r
    END;\r
    JumpRec^.Jump_data[TempIndex] := Trec;\r
  END;\r
\r
  Procedure Putbin1Label(Code: CodeFormat; Labeladdr : St_address);\r
  VAR Ptr: St_Elemptr;\r
      Trec : TempBin1_record;\r
      Help : Integer;\r
  BEGIN\r
    WITH Trec DO\r
    BEGIN\r
      Bin1Code    := Code;\r
      Bin1Label   := Labeladdr;\r
      CASE Code OF\r
\r
       UnCondJump:\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\r
           BEGIN\r
             AddInternal(4);\r
             Bin1Param := 4 * 3;\r
           END ELSE\r
           IF  (Ptr^.MegaLabel_Offset DIV CodeSize)\r
            <> (InternalOffset DIV CodeSize) THEN\r
           BEGIN\r
             AddInternal(4);\r
             Bin1Param := 4 * 3;\r
           END ELSE\r
           BEGIN\r
             AddInternal(3);\r
             Bin1Param := 3 * 3;\r
           END;\r
           RegisterStackAdjust(rJMPRW);\r
         END;\r
\r
       CondJump:\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
           Bin1Param := RelativeCondJumpInst * 3;\r
           AddInternal(3);\r
           IF Ptr^.MegaLabel_offset = 0 then\r
           BEGIN\r
             NoOfOutPageJumps := NoOfOutPageJumps + 1;\r
           END ELSE\r
           IF  (Ptr^.MegaLabel_Offset DIV CodeSize)\r
            <> (InternalOffset DIV CodeSize) THEN\r
           BEGIN\r
             NoOfOutPageJumps := NoOfOutPageJumps + 1;\r
           END;\r
           RegisterStackAdjust(rJMZEQ);\r
         END;\r
\r
       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
           Bin1Param := RelativeCondJumpInst * 3;\r
           AddInternal(4);\r
           IF RelativeCondJumpInst = ord(rJMCHT) THEN\r
             RegisterStackAdjust(rJMCHT)\r
           ELSE\r
             RegisterStackAdjust(rPCALS0);\r
         END;\r
\r
       AddLabelToDis :\r
         BEGIN\r
           Bin1Param := 4 * 3;\r
           AddInternal(4);\r
           RegisterStackAdjust(rREARD);\r
         END;\r
\r
       CaseLabList:\r
         BEGIN\r
           Help := LabelAddr.Va_High * 3 + 7;\r
           IF Help > maxcodeblock THEN ChangeCodeSize(Help);\r
           AddInternal(Help);\r
         END;\r
\r
       ExternalLbdr:\r
         AddInternal(16);\r
\r
       InternalLbdr:\r
         AddInternal(10);\r
\r
       RoutineEntryPoint : (* For Program and Routine Entry Points *)\r
         BEGIN\r
           Bin1Param := 18 * 3;\r
           AddInternal(18);\r
         END;\r
\r
\r
       ELSE Bin1Param := 0;\r
      END;\r
    END;\r
\r
    LastJumpRec.Bin2Code := Bin2codeOut;\r
    IF Bin2codeOut > maxcodeblock THEN ChangeCodeSize(Bin2codeOut);\r
    Bin2codeOut := 0;\r
    Putbin1Code(LastJumpRec);\r
    LastJumpRec := Trec;\r
\r
  END;\r
\r
  Procedure Putbin1Value(Code : CodeFormat; CodeValue: WORD);\r
  VAR Labeladdr : St_address;\r
  BEGIN\r
    Labeladdr.Va_low  := 0;\r
    Labeladdr.Va_high := CodeValue;\r
    Putbin1Label(Code, Labeladdr);\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 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
        JumpToNextPage := 0;\r
        LastJumpRec.Bin1Code := DeclareLabelConst;\r
        While More Do\r
          BEGIN\r
            St_Retrieve(ConstAddr,Ptr);\r
            Length := Ptr^.St_Size;\r
            IF Length > maxcodeblock THEN ChangeCodeSize(Length);\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; Low,High : Integer;\r
		OtherwiseLab : St_Address);\r
      (* The casetabel is generated *)\r
      VAR nolabels : integer;\r
      BEGIN\r
        IF high < low then nolabels := 0 else nolabels := high - low + 1;\r
        LastJumpRec.Bin1Param := (nolabels + 1) * 3;\r
	PutBin1Value(CaseLabList,nolabels);\r
	PutBin1Value(DummyElement,low);\r
	PutBin1Value(DummyElement,high);\r
	PutBin1Label(DummyElement,CaseTab);\r
	PutBin1Label(DummyElement,OtherwiseLab);\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) and not incontext THEN\r
             BEGIN\r
               Putbin1Value(LineNo, Line);\r
             END;\r
         END;\r
\r
\r
     (*------------------------------------------------------------------- *)\r
\r
\r
\r
\r
       PROCEDURE SetCodeTo(Bool : Boolean);\r
         VAR xx: WORD;\r
         BEGIN\r
           codeon := bool;\r
           IF bool then xx:= SourceNumber\r
                   else xx := 255;\r
           Putbin1Value(Setcode, xx);\r
         END;\r
\r
\r
    Procedure ContextStop;\r
      (* The procedure is called when leaving context. Only used when\r
         making linetabel *)\r
      BEGIN\r
        PutBin1Value(ContextEnd,0);\r
        if internaloffset >= codesize then changecodesize(internaloffset);\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
      BEGIN\r
       IF start THEN\r
         PutBin1Label(RoutineStart,Symbol)\r
       ELSE\r
         PutBin1Label(RoutineStop,Symbol);\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(SymbolPoint : St_Address;\r
                               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
         St_Declaration(CLabel,AnonymousName,\r
                           LastInternalLBDRLabel,Ptr);\r
        GenerateLabel(LastInternalLBDRLabel);\r
\r
        Putbin1Label(InternalLBDR,SymbolPoint);\r
\r
\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
        Str : Ptr_String;\r
        ch : char;\r
\r
      BEGIN\r
\r
        Putbin1Label(ExternalLBDR,SymbolPoint);\r
\r
      END; (* MakeExternalLBDR *)\r
\r
\r
    PROCEDURE Makepass4_2; FORWARD;\r
    PROCEDURE Init_pass4_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
          i: integer;\r
      BEGIN  (* StopBlock *)\r
\r
        Putbin1Value(AllignCode, NoOfOutPageJumps);\r
\r
        Emptyfilebuffer;\r
\r
        reset(TBinFile,1);\r
        IF Make_Code THEN reset(TSymFile);\r
\r
        JumpRec^.JumpNoElements := TempIndex;\r
\r
        InternalStartList := St_nilladdr;\r
        InternalEndList   := St_nilladdr;\r
        ExternalStartList := St_nilladdr;\r
        ExternalEndList   := St_nilladdr;\r
        St_LineTable:= IntegerType;\r
        St_RoutineName := BooleanType;\r
\r
        i := lastlinenumber;\r
        LastLineNumber := LineNumber;\r
        linenumber := i;\r
\r
        MakePass4_2;\r
        St_Unlock(Jumprec);\r
\r
        NoOfOutPageJumps := 0;\r
\r
        StrucInExp := false;\r
\r
        FirstExtDec := St_NillAddr;\r
        NoExtDecl   := 0;\r
        Filebufferindex := 0;\r
        CodeOn := false;\r
        InternalOffset := 0;\r
\r
        Bin2codeOut:= 0;\r
        LastJumpRec.Bin1Code := DummyElement;\r
        JumpToNextPage := 1;\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
        ChangeCodeSize(pagesize3502); (* To be removed at sometime *)\r
        IF CodeSize < Spacing THEN ChangeCodeSize(Spacing);\r
\r
        NoPreExtDecl := NoOfPi3RoutinesAndSetRoutines;\r
        (* Initialize the the list of External Name  *)\r
        for i := 1 to NoOfPi3RoutinesAndSetRoutines do\r
          PreExtCalled[i] := 0;\r
\r
        CurrentSegNo := 1;\r
\r
        Init_Pass4_2;\r
\r
        rewrite(TBinFile,1);\r
        IF Make_Code THEN rewrite(TSymFile);\r
       END;  (* StopBlock *)\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
       Put_byte(0); Put_byte(0); (* End Of File *)\r
\r
      END; (* StopCodeGene *)\r
\r
    PROCEDURE GenCode(Inst : Instruction);\r
      (* Generate a instruction without parameter *)\r
\r
      BEGIN\r
        IF Inst < rRENPB THEN Inst := iInstTorInst[Inst];\r
\r
        RegisterStackAdjust(Inst);\r
        Puttbinfile(InstructionValue[Inst]);\r
\r
        (* Print to TSymFile *)\r
        IF CodeOn THEN writeln(TsymFile,1,' ',InstructionName[Inst]);\r
      END;  (* GenCode *)\r
\r
    PROCEDURE CodeConst(Inst:Instruction; Value:LongInt; spix:spixrange );\r
      (* Generate a instruction with a constant parametre *)\r
      VAR\r
        str : Ptr_String;\r
        InstSpecial : Byte;\r
        Opcodes : Byte;\r
        InstCode, i, IValue : Integer;\r
        InstSave : ARRAY[1..5] OF Byte;\r
\r
      PROCEDURE PutByte(B : Byte);\r
      BEGIN\r
        Opcodes := Opcodes + 1;\r
        InstSave[Opcodes] := B;\r
      END;\r
\r
      PROCEDURE PutInteger(Valeur : Integer);\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 := Valeur;\r
        PutByte(I_code.B2);\r
        PutByte(I_code.B1);\r
      END;\r
\r
      BEGIN\r
        InstCode    := InstructionValue[Inst];\r
        InstSpecial := InstCode SHR 8;\r
        InstCode    := InstCode AND 255;\r
        Opcodes     := 0;\r
        Ivalue      := Value;\r
\r
        IF Inst = rRESTA THEN InStack := Value DIV 2 ELSE\r
         RegisterStackAdjust(Inst);\r
\r
        IF InstSpecial = 0 THEN\r
        BEGIN\r
          PutByte(Instcode);\r
          PutInteger(IValue);\r
        END ELSE\r
        BEGIN\r
          CASE InstSpecial OF\r
           1: (* RECHW *)\r
              IF (IValue < 0) OR (IValue > 255) THEN\r
              BEGIN\r
                PutByte(Instcode);\r
                PutInteger(IValue);\r
              END ELSE\r
              IF IValue = 0 THEN PutByte($88) ELSE\r
              BEGIN\r
                IF IValue > 15 THEN PutByte($c8);\r
                PutByte(IValue);\r
              END;\r
           2: (* RECHD *)\r
              BEGIN\r
                PutByte(InstCode);\r
                PutInteger(Value SHR 16);\r
                PutInteger(Value AND $ffff);\r
              END;\r
           3, 4, 11, 12, 13, 14, 19, 20, 21, 22:\r
              (* REALD, REAGD, REVGB, REVGW, REVGA, REVGD,\r
                 STVLB, STVLW, STVLA, STVLD *)\r
              IF (IValue < 0) OR (IValue > 255) THEN\r
              BEGIN\r
                PutByte(Instcode);\r
                PutInteger(IValue);\r
              END ELSE\r
              BEGIN\r
                CASE InstSpecial OF\r
                  3: PutByte($cf);\r
                  4: PutByte($ce);\r
                  11:PutByte($89);\r
                  12:Putbyte($a9);\r
                  13:PutByte($c9);\r
                  14:PutByte($e9);\r
                  19:PutByte($8a);\r
                  20:PutByte($aa);\r
                  21:PutByte($ca);\r
                  22:PutByte($ea);\r
                END;\r
                PutByte(IValue);\r
              END;\r
           5: (* BYTE PARAMETER: REAID, RESTA *)\r
              BEGIN\r
                PutByte(Instcode);\r
                PutByte(IValue);\r
              END;\r
           6: (* REASD *)\r
              IF IValue = 1 THEN PutByte($30) ELSE\r
              BEGIN\r
                PutByte(Instcode);\r
                PutInteger(IValue);\r
              END;\r
           7,8,9,10: (* REVLB, REVLW, REVLA, REVLD *)\r
              IF (IValue < -255) OR (IValue > 255) THEN\r
              BEGIN\r
                PutByte(Instcode);\r
                PutInteger(IValue);\r
              END ELSE\r
              BEGIN\r
                IF IValue < 0 THEN\r
                BEGIN\r
                  CASE InstSpecial OF\r
                    7: PutByte($da);\r
                    8: PutByte($db);\r
                    9: PutByte($dc);\r
                    10:PutByte($dd);\r
                  END;\r
                  IValue := -IValue;\r
                END ELSE\r
                BEGIN\r
                  CASE InstSpecial OF\r
                    7: PutByte($8b);\r
                    8: PutByte($ab);\r
                    9: PutByte($cb);\r
                    10:PutByte($eb);\r
                  END;\r
                END;\r
                PutByte(IValue);\r
              END;\r
           15, 23:(* REVSB, STVSB *)\r
              IF (IValue > 7) OR (IValue < 0) THEN\r
              BEGIN\r
                PutByte(Instcode);\r
                PutInteger(IValue);\r
              END ELSE\r
              IF InstSpecial = 15 THEN\r
              BEGIN\r
                CASE IValue OF\r
                  0: PutByte($f0);\r
                  1: PutByte($B9);\r
                  2: PutByte($83);\r
                  3: PutByte($bb);\r
                  4: PutByte($85);\r
                  5: PutByte($bd);\r
                  6: PutByte($87);\r
                  7: PutByte($bf);\r
                END;\r
              END ELSE\r
              BEGIN\r
                CASE IValue OF\r
                  0: PutByte($f1);\r
                  1: PutByte($99);\r
                  2: PutByte($82);\r
                  3: PutByte($9b);\r
                  4: PutByte($84);\r
                  5: PutByte($9d);\r
                  6: PutByte($86);\r
                  7: PutByte($9f);\r
                END;\r
              END;\r
           16, 17, 18, 24, 25 :\r
              (* REVSW, REVSA, REVSD, STVSW, STVSA *)\r
              CASE IValue OF\r
                0: Case InstSpecial OF\r
                    16: PutByte($f2);\r
                    17: PutByte($f4);\r
                    18: PutByte($f6);\r
                    24: PutByte($f3);\r
                    25: PutByte($f5);\r
                   End;\r
                2: Case InstSpecial OF\r
                    16: PutByte($a3);\r
                    17: PutByte($c3);\r
                    18: PutByte($e3);\r
                    24: PutByte($a2);\r
                    25: PutByte($c2);\r
                   End;\r
                4: Case InstSpecial OF\r
                    16: PutByte($a5);\r
                    17: PutByte($c5);\r
                    18: PutByte($e5);\r
                    24: PutByte($a4);\r
                    25: PutByte($c4);\r
                   End;\r
                6: Case InstSpecial OF\r
                    16: PutByte($a7);\r
                    17: PutByte($c7);\r
                    18: PutByte($e7);\r
                    24: PutByte($a6);\r
                    25: PutByte($c6);\r
                   End;\r
                ELSE\r
                   BEGIN\r
                     PutByte(Instcode);\r
                     PutInteger(IValue);\r
                   END;\r
              END;\r
           26, 27: (* INDH0, INDH1 *)\r
              CASE Value AND $ffff OF\r
               1: BEGIN\r
                    IF InstSpecial = 26 THEN PutByte($8d) ELSE PutByte($cd);\r
                    PutInteger(Value SHR 16);\r
                  END;\r
               2: BEGIN\r
                    IF InstSpecial = 26 THEN PutByte($ad) ELSE PutByte($ed);\r
                    PutInteger(Value SHR 16);\r
                  END;\r
               ELSE\r
                  BEGIN\r
                    PutByte(InstCode);\r
                    PutInteger(Value SHR 16);\r
                    PutInteger(Value AND $ffff);\r
                  END;\r
              END;\r
           28: (* PCALS *)\r
              BEGIN\r
                PutByte(InstCode);\r
                PutByte(0);\r
                PutInteger(IValue);\r
              END;\r
          END;\r
        END;\r
\r
        CheckRoomOnPage(Opcodes);\r
        FOR i:=1 TO Opcodes DO Puttbinfile(InstSave[i]);\r
\r
        (* Print to TSymFile *)\r
        IF CodeOn THEN\r
          BEGIN\r
            write(Tsymfile, Opcodes, ' ', InstructionName[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
      END; (* CodeConst *)\r
\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
        Lable : St_Address;\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
            Lable.Va_high := Spix;\r
            Lable.Va_low  := Number;\r
            Putbin1Label(ExternalCall, Lable);\r
            CodeConst(rPCALS0, 0, Spix);\r
            IF Number <= NoPreextDecl THEN\r
            BEGIN\r
              PreextCalled[Number] := PreextCalled[Number]+1;\r
            END ELSE\r
            BEGIN\r
              Lable := FirstExtDec;\r
              WHILE Not Equal_Addr(Lable,St_NillAddr) DO\r
              BEGIN\r
                St_Retrieve(Lable,Ptr);\r
                St_Retrieve(Ptr^.Ext_Owner,Ptr);\r
                IF Ptr^.St_CurNo = Number THEN\r
                BEGIN\r
                  St_Get(Lable, Ptr);\r
                  Ptr^.Fixup_no := Ptr^.Fixup_no + 1;\r
                  Lable := St_Nilladdr;\r
                END ELSE\r
                BEGIN\r
                  St_Retrieve(Lable, Ptr);\r
                  Lable := Ptr^.Ext_Ref;\r
                END;\r
              END;\r
            END;\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(rJMPRW,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
\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
        InstType : Instruction;\r
      BEGIN\r
        InstType := Inst;\r
        IF Inst = iJMP THEN Insttype := rJMPRW ELSE\r
          IF (Inst >= rJMZEQ) AND (Inst <= rJMZGE) THEN Insttype := rJMZEQ;\r
\r
        IF (Insttype = rJMPRW) OR (Insttype = rJMZEQ) THEN ReleaseStrucdyn;\r
\r
        IF   ((Insttype=rJMPRW) 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 ((Insttype=rJMPRW) AND ( LastJMPOffset = InternalOffset)) THEN\r
          BEGIN   (* generate the instruction *)\r
\r
            RelativeCondJumpInst := Ord(Inst);\r
            CASE Insttype OF\r
              rJMPRW : Putbin1Label(UnCondJump, Lab);\r
              rJMZEQ : Putbin1Label(CondJump, Lab);\r
              ELSE     Putbin1Label(InternalCall, Lab);\r
            END;\r
            if insttype = rJMPRW then LastJMPOffset := InternalOffset;\r
          END;\r
      END; (* CodeJump *)\r
\r
   PROCEDURE ReleaseStrucDyn;\r
     BEGIN\r
      IF (InStrucValue = 0) AND StrucInExp THEN\r
         BEGIN\r
           StrucInExp := false;\r
         END;\r
     END;\r
  (* --------------------------------------------------------- *)\r
\r
\r
\r
    PROCEDURE CodeFault(ErrorInt, ErrorExc: WORD);\r
    BEGIN\r
      codeconst(rRECHW,errorInt,AnonymousSpix);\r
      GenCode(rMTRS);\r
    END;\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
      BEGIN\r
       PutBin1Label(AddLabelToDis,Lab);\r
       PutBin1Value(DummyElement,Offset);\r
      END; (* CodeLoadEffAddr *)\r
\r
    PROCEDURE GenerateEntryPoint(Lab : St_Address);\r
      (* Generate the Entry Point given by Lab *)\r
    BEGIN\r
      Putbin1Label(RoutineEntryPoint, Lab);\r
      GenerateLabel(Lab);\r
    END;\r
\r
    PROCEDURE GenerateLabel(Lab : St_Address);\r
      (* Generate the label given by Lab *)\r
\r
      VAR Ptr : St_Elemptr;\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);\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
        LengthOfAllPreExtName := 0;\r
        LengthOfAllExtName := 0;\r
\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
{$I P435INIT}\r
{$I P435}\r
\r
END.\r
\r
\r
\r
\r
\r
«eof»