home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / TP_ADV.ZIP / LIST0415.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1989-07-31  |  8.1 KB  |  317 lines

  1. {$R-,S-,I-,D+,F-,V-,B-,N-,L+ }
  2. {$M 8192,0,0}
  3. Program C2P;
  4. { This program will process the .ASM file that has been       }
  5. { generated by the TC2TP program.  It will construct the file }
  6. { in such a manner as to allow the Turbo Pascal program to    }
  7. { link in the appropriate .OBJ file.                          }
  8.  
  9. Uses
  10.   Tools;
  11.  
  12. Const
  13.   BUFFERSIZE       = 16384;
  14.  
  15. Type
  16.   StrPtr           = ^String;
  17.   Path             = String[70];
  18.   Str20            = String[20];
  19.   Str80            = String[80];
  20.   Str4             = String[4];
  21.   Str8             = String[8];
  22.   TextBuffer       = Array[1..BUFFERSIZE] of Byte;
  23.  
  24. Var
  25.   Line             : String;
  26.   OutFileName      : Path;
  27.   F,OutF           : Text;
  28.   InBuffer,
  29.   OutBuffer        : TextBuffer;
  30.   Code_Seg_Name    : Str20;
  31.  
  32. Const
  33.   NumLines         : Word = 0;
  34.   Proc_Keyword     : Str4      = 'PROC';
  35.   Endp_Keyword     : Str4      = 'ENDP';
  36.   Public_Keyword   : String[6] = 'PUBLIC';
  37.   Extrn_Keyword    : String[5] = 'EXTRN';
  38.   EndS_Keyword     : Str4      = 'ENDS';
  39.   Segment_Keyword  : String[7] = 'SEGMENT';
  40.   Assume_Keyword   : String[6] = 'ASSUME';
  41.   Group_Keyword    : String[5] = 'GROUP';
  42.   DGROUP_Keyword   : String[6] = 'DGROUP:';
  43.   TEXT_Seg_Def     : String[5] = '_TEXT';
  44.   DATA_Seg_Def     : String[5] = '_DATA';
  45.   BSS_Seg_Def      : Str4      = '_BSS';
  46.  
  47.   Cur_Seg_Name     : Str20 = 'CODE';
  48.   InCodeSegment    : Boolean = TRUE;
  49.  
  50. Procedure HaltError( ErrorCode : Integer; S : String );
  51. { Error handler, display error number, display error  }
  52. { message, terminate and set DOS error level to       }
  53. { ErrorCode.      }
  54.  
  55. Begin
  56.   Writeln( 'Error ',ErrorCode );
  57.   Writeln( S );
  58.   Halt( ErrorCode );
  59. End;
  60.  
  61. Procedure OutputLine( Line : String );
  62. { Procedure to output a new line to our assembly file.        }
  63.  
  64. Var
  65.   E : Word;
  66.  
  67. Begin
  68.   Writeln( OutF,Line );
  69.   E := IOResult;
  70.   If E <> 0 Then
  71.     HaltError( E, 'Error writing ' + OutFileName );
  72. End;
  73.  
  74. Procedure EndS_Def;
  75. { Procedure to output an end of segment identifier to the new }
  76. { assembly file being generated.                              }
  77.  
  78. Var
  79.   E : Integer;
  80.   S : Str80;
  81.  
  82. Begin
  83.   S := Cur_Seg_Name + '       ' + 'ENDS';
  84.   OutputLine( S );
  85.   InCodeSegment := FALSE;
  86. End;
  87.  
  88. Procedure BeginS_Def;
  89. { Procedure to output the beginning of a segment to the new   }
  90. { assembly file being generated.                              }
  91. Var
  92.   E : Integer;
  93.   S : String;
  94.   Allignment : Str4;
  95.  
  96. Begin
  97.   If InCodeSegment Then
  98.   Begin
  99.     Allignment := 'BYTE';
  100.     Cur_Seg_Name   := 'CODE';
  101.   End
  102.   Else
  103.   Begin
  104.     Allignment := 'WORD';
  105.     Cur_Seg_Name := 'DATA';
  106.   End;
  107.   S := Cur_Seg_Name + '  SEGMENT ' + Allignment + ' PUBLIC';
  108.   OutputLine( S );
  109. End;
  110.  
  111. Procedure Assume_Def;
  112. { Procedure to output the correct ASSUMEs for the new         }
  113. { assembly file being generated.                              }
  114.  
  115. Var
  116.   E : Integer;
  117.  
  118. Begin
  119.   OutputLine( '          ASSUME CS:CODE,DS:DATA' );
  120. End;
  121.  
  122. Function CompareString( Var S1,S2 : String ) : Boolean;
  123. { if the strings are equal (including length) returns true    }
  124.  
  125. Begin
  126.   CompareString :=
  127.        CompMem( S1,S2,Succ( Length( S1 ) ) ) = _EQUAL_;
  128. End;
  129.  
  130. Procedure Examine( Var S,Orig_Line : String );
  131. { The main logic line processing routine!  This procedure     }
  132. { determines how to translate each line into an assembly      }
  133. { language suitable for a TP4 bound asm module.  Since        }
  134. { there are only two segments we'll be using in the TP4 bound }
  135. { ASP file (the output file), the logic engine toggles        }
  136. { between emitting code (and the associated statements) and   }
  137. { data (and its statements).                                  }
  138. Var
  139.   SS : String;
  140.   FirstWord : Str80;
  141.   E : Integer;
  142.   _Data_,_BSS_,_TEXT_
  143.                    : Boolean;
  144. Begin
  145.   SS := S; { make a copy of the string and work on   }
  146.            { the copy }
  147.  
  148.   { if this is an end segment definition then end    }
  149.   { the current segment and Exit }
  150.  
  151.   If WordOnLine( EndS_Keyword,SS ) Then
  152.   Begin
  153.     Ends_Def;
  154.     Exit;
  155.   End;
  156.  
  157.   { if this is an ASSUME statement, then translate it }
  158.   { and Exit }
  159.  
  160.   If WordOnLine( Assume_Keyword,SS ) Then
  161.   Begin
  162.     Assume_Def;
  163.     Exit;
  164.   End;
  165.  
  166.   { We ignore all GROUP statements }
  167.  
  168.   If WordOnLine( Group_Keyword,SS ) Then
  169.     Exit;
  170.  
  171.   { the following conditional checks for an inline asm}
  172.   { reference to DGROUP. if found, it is changed to   }
  173.   { DATA in the ASP file. }
  174.  
  175.   If Pos( Dgroup_Keyword,SS ) > 0 Then
  176.     ReplaceString( 'DGROUP','DATA',Orig_Line );
  177.  
  178.   { now get the first word on the line.  At this point}
  179.   { all we need to do is check the first word, because}
  180.   { We've already looked for ASSUME, GROUP and ENDS   }
  181.   { statements.  We now decide whether this is a      }
  182.   { segment definition, if so, it is translated       }
  183.   { accordingly.  Otherwise it is either code or data }
  184.   { and it is written out to the ASP output file.     }
  185.  
  186.   If WordOnLine( Segment_Keyword,SS ) Then
  187.   Begin
  188.  
  189.     FirstWord := ParseWord( SS,' ' ); { parse the first word  }
  190.  
  191.     { reset some booleans }
  192.     _Data_  := FALSE;
  193.     _BSS_   := FALSE;
  194.     _TEXT_  := FALSE;
  195.  
  196.     { check to see if this line is a segment definition }
  197.     If CompareString( FirstWord,DATA_Seg_Def ) Then
  198.       _Data_:= TRUE
  199.     Else
  200.       If CompareString(FirstWord,BSS_Seg_Def) Then
  201.         _BSS_ := TRUE
  202.  
  203.     { in case we're in a large memory model, we don't look }
  204.     { for the segment _TEXT explicitly, instead, we look   }
  205.     { for a segment which includes the string _TEXT.       }
  206.  
  207.     Else
  208.       If Pos( TEXT_Seg_Def,FirstWord ) > 0 Then
  209.       Begin
  210.         _TEXT_ := TRUE;
  211.         Code_Seg_Name := FirstWord;
  212.       End;
  213.  
  214.     { if this is a segment, we decide whether it's code }
  215.     { or data, and deal with it.  Otherwise, the line is}
  216.     { either code, comment, or data, and should be      }
  217.     { passed to the ASP file }
  218.  
  219.     If _Data_ or _BSS_ or _TEXT_ Then
  220.     Begin
  221.       If _TEXT_ Then
  222.         InCodeSegment := TRUE
  223.       Else
  224.         InCodeSegment := FALSE;
  225.       BeginS_Def; { start a new segment }
  226.     End
  227.     Else
  228.       OutputLine( Orig_Line );
  229.   End
  230.   Else
  231.     OutputLine(Orig_Line); { code, data,or comment, so     }
  232.                            { output }
  233. End;
  234.  
  235. procedure Process_Line(S : String);
  236.  
  237. Var
  238.   E : Integer;
  239.   Line : String;
  240.  
  241. Begin
  242.   { prepare Line for processing: }
  243.   Line := Trim(Line);      { trim leading and trailing}
  244.                            { white space }
  245.   If Length( Line ) = 0 Then{ if the length of trimed  }
  246.                            { string is 0, then Exit.  }
  247.     Exit;
  248.  
  249.   Line := ExpandTabs( S );   { replace tabs with spaces }
  250.   Line := UpperCase( Line );  { uppercase chars only     }
  251.  
  252.   Examine( Line,S ); { Call main logic. NOTE: This      }
  253.                    { routine takes as parameters both }
  254.                    { the prepared var Line and a copy }
  255.                    { of the original source line.     }
  256.  
  257. End;
  258.  
  259. procedure Process_Asm_File( FPath : Path );
  260.  
  261. Var
  262.   E,
  263.   L : Integer;
  264.  
  265. Begin
  266.   OutFileName := FileExt( FPath,'ASP' );
  267.   Assign( F,FPath );
  268.   SetTextBuf( F,InBuffer );
  269.   Reset( F );
  270.   E := IOResult;
  271.   If E <> 0 Then
  272.     HaltError(E,FPath + ' not found.');
  273.   Assign( OutF,OutFileName );
  274.   SetTextBuf( OutF,OutBuffer );
  275.   Rewrite( OutF );
  276.   E := IOResult;
  277.   If E <> 0 Then
  278.     HaltError(E,'Error opening '+OutFileName);
  279.   Writeln('Creating new file: ',OutFileName);
  280.   Writeln('working...');
  281.   While Not EOF( F ) Do
  282.   Begin
  283.     Inc( NumLines );
  284.     Readln( F,Line );
  285.     E := IOResult;
  286.     If E <> 0 Then
  287.       HaltError( E,'Error reading ' + FPath );
  288.     Process_Line( Line );
  289.   End;
  290.   Close( F );
  291.   E := IOResult;
  292.   Close( OutF );
  293.   E := IOResult;
  294.   If E <> 0 Then
  295.     HaltError( E,'Error closing '+OutFileName );
  296.  
  297. End;
  298.  
  299. Var
  300.   FName : Path;
  301.  
  302. Begin
  303.   If ParamCount < 1 Then
  304.   Begin
  305.     Writeln( 'C2P AsmFileName' );
  306.     Halt(99);
  307.   End;
  308.   FName := ParamStr( 1 );
  309.  
  310.   If Pos( '.',FName ) = 0 Then
  311.     FName := FName + '.ASM';
  312.  
  313.   Process_Asm_File( FName );
  314.   Writeln( NumLines,' lines processed' );
  315.   Writeln( 'Success!' );
  316. End.
  317.