  %routine Dump String(%string(255) S)
         %integer J, L
         L = Length(S)
         Printsymbol(L)
         Printsymbol(Charno(S, J)) %for J = 1, 1, L
      %end

      %routine Dump Object File Header

         %routine Dump4(%integer N)
            Printsymbol(N&255)
            Printsymbol(N>>8&255)
            Printsymbol(N>>16&255)
            Printsymbol(N>>24&255)
         %end

         %routine Dump Definitions
            %record(Usefm)%name U == Total Uses
            %record(Xfm)%name X
            Dump4(Definitions)
            %while U ## NIL %cycle
               X == U_X
               %if X ## NIL %and X_Flags&Ext Defn # 0 -
                            %and X_Flags&Ext Prim = 0 %start
                  %if X_Flags&(Ext Dumped!Ext Local Def) = 0 %start
                     X_Flags = X_Flags ! Ext Dumped
                     Dump4(X_Flags>>8)
                     %if X_Flags&Ext Code # 0 %start
                        X_Value = X_Value+Pair Base;  Dump4(X_Value)
                     %else
                        Dump4(X_Disp-Min SB)
                     %finish
                     Definitions = Definitions-1
                  %finish
               %finish
               U == U_Link
            %repeat
            CSR("Wrong number of definitions") %if Definitions # 0
         %end

         %routine Dump References
            %integer N = 1      {0=code, 1=data}
            %record(Usefm)%name U == Total Uses
            %record(Xfm)%name X
            Dump4(References)
            %while U ## NIL %cycle
               X == U_X
               %if X ## NIL %and X_Flags&(Ext Defn ! Ext Prim) = 0 %start
                  %if X_Flags&(Ext Dumped!Ext Local Ref) = 0 %start
                     X_Flags = X_Flags ! Ext Dumped
                     Dump4(X_Flags>>8)
                     N = N+1;  X_Flags = X_Flags&255 ! N<<8
                     References = References-1
                  %finish
               %finish
               U == U_Link
            %repeat
            CSR("Wrong reference count") %if References # 0
         %end

         %routine Dump Strings
            %integer P = 0
            %record(Usefm)%name U
            %record(Xfm)%name X
            U == Total Uses
            %while U ## NIL %cycle
               X == U_X
               %if X ## NIL %start
                  CSR("shuffled strings") %unless P = X_Flags>>8
                  P = P+(Length(X_Text)+4)&(\3)
                  Dump String(X_Text)
               %finish
               U == U_Link
            %repeat
         %end

         %integer Len, Pad, N, Spad
         %string(63) Compiler = ProductCode.":".Version.".".Release.".".Revision

         Pad = Length(Module)+Length(Compiler)+Length(Date) -
                             +Length(Time)    +Length(Source File) +5
         Len = (Pad+3)&(\3)
         Pad = Len-Pad
         Len = Len+10*4
         Spad = String Size
         String Size = (String Size+3)&(\3)
         Spad = String Size-Spad
         N = Area Size(Code Area) + Area Size(Info Area)     -
                                  + Area Size(Recovery Area) -
                                  + Area Size(Block Area)    -
                                  + Area Size(Line Area)     -
                                  + Area Size(Diag Area)     -
                                  + Area Size(Record Area)   -
                                  + Area Size(Constant Area)

         CSR("Bad alignment") %if N&3 # 0
{1}      Dump4(Object File)                              {object file indicator}
{2}      Dump4(1)                                        {object format version}
{3}      Dump4(0)                                        {entry point}
{4}      Dump4(N)                                        {code size}
{5}      Dump4(Area Size(Code Area))                     {instruction size}
{6}      Dump4(Area Size(Global Area)   -
             + Area Size(Global Array Area))             {data size}
{7}      Dump4(String Size)                              {string size}
{8}      Dump4(Len)                                      {start of string table}
{9}      Dump4(Len+String Size)                          {start of definitions}
{10}     Dump4(Len+String Size+Definitions*8+4)          {start of references}

         Dump String(Module)
         Dump String(Compiler)                           {compiler ID}
         Dump String(Date)
         Dump String(Time)
         Dump String(Source File)
         Pad = Pad-1 %and Printsymbol(0) %while Pad # 0
         Dump Strings
         Spad = Spad-1 %and Printsymbol(0) %while Spad # 0
         Dump Definitions
         Dump References
      %end

      %constinteger Max BufP = 512
      %owninteger BufP = 0
      %ownbytearray Buffer(1:Max BufP+4)

      %routine Flush Buffer
         %integer J
         %return %if BufP = 0
         Dump Encoded(Object Dump BLock)
         Dump Encoded(BufP)
         Printsymbol(Buffer(J)) %for J = 1, 1, BufP
         BufP = 0
      %end

      %routine Actually Select Area
         %if Pending Area # This Area %or Pending Offset # This Offset %start
            This Area   = Pending Area
            This Offset = Pending Offset
            Flush Buffer
            %if Pending Area = Global Area %or -
                Pending Area = Global Array Area %start
               Dump Encoded(Object Select Data Area)
            %else
               Dump Encoded(Object Select Code Area)
            %finish
            Dump Encoded(Pending Offset+Area Base(Pending Area))
         %finish
         Pending Area = -1
      %end

      %routine Dump(%integer N)
         Actually Select Area %if Pending Area >= 0
         BufP = BufP+1;  Buffer(BufP) = N&255
         Ca = Ca+1
         This Offset = This Offset+1
         Flush Buffer %if BufP >= Max BufP
      %end

      %routine Dump2(%integer N)
         Actually Select Area %if Pending Area >= 0
         BufP = BufP+1;  Buffer(BufP) = N&255
         BufP = BufP+1;  Buffer(BufP) = N>>8&255
         Ca = Ca+2
         This Offset = This Offset+2
         Flush Buffer %if BufP >= Max BufP
      %end


      %routine Dump4(%integer N)
         Enter Line Diagnostic %if Line Info_Pending # 0 -
                              %and Line Info_Ca = Ca     -
                              %and Ca == Local Code Base
         Actually Select Area %if Pending Area >= 0
         %if Set CC # 0 %and Ca == Local Code Base %start
            CSR("Bad cc to change") %unless N>>28 = 16_E
            N = N !! (Set CC<<24)
         %finish
         BufP = BufP+1;  Buffer(BufP) = N&255
         BufP = BufP+1;  Buffer(BufP) = N>>8&255
         BufP = BufP+1;  Buffer(BufP) = N>>16&255
         BufP = BufP+1;  Buffer(BufP) = N>>24
         Ca = Ca+4
         This Offset = This Offset+4
         Flush Buffer %if BufP >= Max BufP
      %end
    

  %routine Relocate(%integer At, By)
         {At is relative to SB, NOT the start of the global area}
         Flush Buffer
         Dump Encoded(Object Relocate)
         Dump Encoded(At-Min SB)        {relative to start of area}
         Dump Encoded(By)
      %end

      %routine Set Address(%integer Area, Offset)
         Pending Area   = Area
         Pending Offset = Offset
      %end

   
      %routine Off
         Flush Buffer
         Dump Encoded(Object Off)
      %end

      %routine On
         Flush Buffer
         Dump Encoded(Object On)
      %end
