PROGRAM MAKEINL; {$C-} {$I-} {* Version 2.0 22.11.1985 aus c't 1986,Heft 2 *} Const Left : String[3] = '(* '; Right : String[3] = ' *)'; PRN : String[4] = '.PRN'; INL : String[4] = '.INL'; Leerstrg : String[17] = ' '; Arrow : String[8] = ' -----> '; Header : String[9] = 'InLine'#13#10'('; Tail : String[5] = '$00)'; Syoflow : String[19] = 'Too many Variables'^G; Noexist : String[9] = 'No File !'; Diskerr : String[11] = 'Disk Full !'; Direrr : String[10] = 'Dir Full !'; NoSymbol : String[8] = '????????'; UnKnown : String[22] = 'Error, cause unknown !'; ASEGerr : String[24] = 'Code must be relative !'^G; Warning : String[30] = 'Overwrite Sourcefile ? (Y/N)'^G; Insert : String[19] = 'Make-InLine Utility'; Version : String[39] = 'Version 2.0 - 11/1985 (c) Ulrich Fuchs'; Type String_255 = String[255]; Listpointer = ^List; List = Record ExtrnSymbol : String[20]; Pointer : Listpointer; End; Var PrnText,InlText : Text; TextLine, NewLine, Opcode, Helpask, ASMText, Filename, Inlname, UpcaseLine : String_255; OldLine : Integer; EXTList, StartOfList, SearchPointer : Listpointer; Mustdef, Continue, Skip, Ready, Extern, Quit ,NoError, First : Boolean; Ch : Char; Procedure Help; Begin Writeln('Erzeugen von INLINE-Files aus xxx.PRN-Files des MACRO80-Assemblers.'); Writeln(''); Writeln('Syntax : [DRIVE:] FILENAME [.TYPE] [/] [DRIVE:] [NEUNAME] [.INL]'); Writeln(' [Quelle] [Ziel]'); Writeln(''); Writeln('Das Programm kann mit Argument aufgerufen werden. Dadurch ist die Wahl einiger'); Writeln('Optionen (s.o.) durch die Angabe des Filenamens moeglich.'); Writeln('MAKEINL meldet sich mit dem Stern, wenn es ohne Argument aufgerufen'); Writeln('wird. Es kann dann eine Anweisung entsprechend obiger Syntax gegeben werden.'); Writeln('Die in Klammern angegebenen Teile sind wahlweise. Wird nur der Filename '); Writeln('ohne Extension angegeben, so wird als Type .PRN angenommen.'); Writeln('Das generierte File wird unter FILENAME.INL abgelegt.'); Writeln('--aus c"t 1986, Heft 2, Seite 64-67--'); Writeln('------------------------------------------------------------------------------'); End;(*Help*) Procedure ToUpper(VAR Strg : String_255); Var Count : byte; Begin For Count := 1 to Length(Strg) do Strg[Count] := Upcase(Strg[Count]); End;{*ToUpper*} Procedure Check_for_Err; Var Error : Byte; Begin Error := IOresult; NoError := Error = 0; If Error <> 0 then Begin Writeln(#13#10#10#7); Case Error of $01 : Writeln(Noexist); $F0 : Writeln(Diskerr); $F1 : Writeln(Direrr); Else Writeln(Unknown); End; End; End;{*Check_for_Err*} Procedure Select_Name(Var Name1,Name2 : String_255); Var Laenge2,N :Byte; Begin N := Pos('/',Filename); Laenge2 := Length(Filename) - N; If N > 0 then Begin Name2 := Copy(Filename,N + 1,Laenge2); Name1 := Copy(Filename,1,N - 1); If (Laenge2 = 2) and (Name2[2] = ':') then Begin If Pos(':',Name1)=0 then Name2 := Concat(Name2,Name1) Else Name2 := Concat(Name2,Copy(Name1,3,N - 3)); End; End Else Begin Name1 := Filename; Name2 := Filename; End; End;{*Select_Name*} Procedure Get_Name; Var Count, Punktpos : Byte; Begin If First then Begin Filename := ''; For Count := 1 to Mem[$80] - 1 do Filename := Filename + Char(Mem[$81 + Count]); End; If (Filename = '') or Not First then Begin Write(#10'*'); Readln(Filename); End; First := False; Quit := Filename = ''; ToUpper(Filename); Select_Name(Filename,Inlname); If Pos('.',Filename) = 0 then Filename := Concat(Filename,PRN); If Pos('.',Inlname) = 0 then If Pos(':',Inlname) <> 4 then Inlname := Concat(Inlname,INL); If Filename = Inlname then Begin Write(Warning); Repeat Read(KBD,Ch); Ch :=Upcase(CH); until Ch in ['N','Y']; Writeln; If Ch <> 'Y' then Get_Name; End; End;(*Get_Name*) Procedure Form_NewLine; Var LineLength, Start, ExternalPos, Count : Byte; ASEGerrFound, Comment, Code, Jump, Switch, Special : Boolean; ProgCounter, LabelPosition, Offset, Result : Integer; Firstchar : Char; Switchcode : String[4]; Strg : String[6]; Procedure Fill_up (Var Line : String_255; Spaces : Integer); Var Index : Byte; Begin For Index := 1 to Spaces - Length(Line) do Line := Line + ' '; End;(*Fill_up*) Procedure Insert_Symbol; Var Found :Boolean; Begin Found := False; SearchPointer := StartOfList; While (SearchPointer <> NIL) and Not Found do Begin Found := Pos(SearchPointer^.ExtrnSymbol,UpcaseLine) > 0; If Found then Opcode := Opcode + SearchPointer^.ExtrnSymbol + '/'; SearchPointer := SearchPointer^.Pointer; End; If Not Found then Opcode := Opcode + NoSymbol + '/'; End;(*Insert_Symbol*) Procedure Calculate_Adress; Begin Strg := '$' + Copy(TextLine,14,4); Val(Strg,LabelPosition,Result); Offset := LabelPosition - ProgCounter - 1; Str(Offset,Strg); If Offset <0 then Opcode := Opcode + '*' + Strg + '/' Else Opcode := Opcode + '*+' + Strg + '/'; End;(*Calculate_Adress*) Procedure Define_Space; Var ToDefine, Count : Integer; DefLine : String[80]; Begin ToDefine := ProgCounter - OldLine; Count := 0; While Count < ToDefine do Begin DefLine := ''; Repeat DefLine := DefLine + '$00/'; Count := Count + 1; Until (Count Mod 4 = 0) or (Count = ToDefine); Writeln(DefLine); Writeln(InlText,DefLine); End; Mustdef := False; End; (* Define_Space *) Begin Ready := TextLine = 'Macros:'; LineLength := Length(TextLine); UpcaseLine := TextLine; ToUpper(UpcaseLine); ASEGerrFound := Pos('ASEG',UpcaseLine) > 0; If ASEGerrFound then If (Pos(';',TextLine) > Count) or (Pos(';',TextLine) = 0) then Begin Ready := True; Writeln(ASEGerr); End; ExternalPos := Pos('EXT',UpcaseLine); If ExternalPos >0 then Begin UpcaseLine := Copy(TextLine,ExternalPos,LineLength - ExternalPos +1); Count := Pos(' ',UpcaseLine); UpcaseLine := Copy(UpcaseLine,Count + 1,Length(UpcaseLine) - Count); While UpcaseLine[1] = ' ' do Delete(UpcaseLine,1,1); If (MemAvail > SizeOf(List)) or (MemAvail < 0)then Begin New(EXTList); EXTList^.ExtrnSymbol := UpcaseLine; EXTList^.Pointer := StartOfList; StartOfList := EXTList; End Else Begin NoError := False; Writeln(Syoflow); End; End; Code := (TextLine[7] = #39) or (TextLine[7] = '!'); Count := 1; FirstChar := ^A; While (Count <= LineLength) and (FirstChar <= ' ') do Begin FirstChar := TextLine[Count]; Count := Count + 1; End; Comment := FirstChar = ';'; Skip := Not (Code or Comment); If Comment then Begin ASMText := Left + Copy(TextLine, Count,LineLength - Count + 1); Fill_up (ASMText,59); NewLine := Leerstrg + ASMText + Right; End; If Code then Begin Strg := '$' + Copy(TextLine,3,4); Val(Strg,ProgCounter,Result); NewLine :=Copy(TextLine,11,LineLength - 10); If Mustdef then Define_Space; Switch := (NewLine[1] in ['D','E','F']) and (NewLine[2] = 'D'); If Switch then Begin Switchcode := '$' + Copy(NewLine,1,2) + '/'; Delete(NewLine,1,3); End; Extern := (NewLine[8] = '*'); Jump := (NewLine[8] = #39) or (NewLine[8] = '!'); Special := Jump or Extern; If NewLine[1] > ' ' then Opcode := '$' + Copy(NewLine,1,2) + '/' Else Begin Mustdef := (Pos(' DS ',UpcaseLine) > 0) or (Pos(' DEFS ',UpcaseLine) > 0); OldLine := ProgCounter; Opcode := Leerstrg; End; If not Special then Begin If NewLine[6] <> ' ' then Opcode := Opcode + '$' + Copy(NewLine,6,2) + '/'; If NewLine[4] <> ' ' then Opcode := Opcode + '$' + Copy(NewLine,4,2) + '/'; If NewLine[6] = ' ' then If NewLine[7] > ' ' then Opcode := Opcode + '$' + Copy(NewLine,7,2) + '/'; If NewLine[9] = ' ' then If NewLine[10] > ' ' then Opcode := Opcode + '$' + Copy(NewLine,10,2) + '/'; If NewLine[3] > ' ' then Opcode := '$' + Copy(NewLine,3,2) + '/' + '$' + Copy(NewLine,1,2) + '/'; If NewLine[9] > ' ' then Opcode := Opcode +'$' + Copy(NewLine,8,2) + '/' + '$' + Copy(NewLine,6,2) + '/'; End; If Extern then Insert_Symbol; If Jump then Calculate_Adress; If Switch then Opcode := Switchcode + Opcode; Fill_up(Opcode,17); ASMText := Left + Copy(TextLine,33,LineLength - 32); Fill_up(ASMText,59); NewLine := Opcode + ASMText + Right; End; End;(*Form_NewLine*) (* MAIN *) Begin ClrScr; First := True; Mustdef := False; Write(#10#10,Insert,#13#10,version,#13#10#10); Help; Repeat Ready := False; Continue := True; Get_name; If Not Quit then Begin StartOfList := NIL; Writeln(#10,Filename,Arrow,Inlname,#10); Assign(PrnText,Filename); Assign(InlText,Inlname); Reset(PrnText); Check_for_Err; If NoError then Begin Rewrite(InlText); Check_for_Err; Writeln(InlText,Header); Writeln(Header); While Not Eof(PrnText) and NoError and Not Ready and Continue do Begin ReadLn(PrnText,TextLine); Form_NewLine; If not Skip then Begin Writeln(NewLine); Writeln(InlText,NewLine); Check_for_Err; End; If keypressed then Begin Read(KBD,Ch); Continue := Ch <> ^X; End; End; Writeln(InlText,Tail); Writeln(Tail); End; End; Close(PrnText); Close(InlText); Until Quit End.