home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
TURBOPAS
/
PMLINK.LBR
/
PMLINK.PQS
/
PMLINK.PAS
Wrap
Pascal/Delphi Source File
|
2000-06-30
|
7KB
|
227 lines
Program PMLINK;
Const MaxInd = $1500; MaxSym = 255;
type PrgInd =0 .. MaxInd; SymInd = 1..MaxSym;
SymString = string[6]; Fname = string[14];
AnyString = string[127];
Bits = 0..8; ItemT = 0..15;
FlagT = (Norm,Rel,Ext,NegOffs,PosOffs);
ByteRec = record Low,High: byte end;
Var Prog: array[PrgInd] of
record Flag:FlagT; Cont: byte end;
PC: integer; OffsPtr: byte;
SymTab: array[SymInd] of SymString;
OffsTab: array[1..255] of record OPC, Value: integer end;
Finis,ErrFlag,EoPrg,EoFile: boolean;
RelFile: file; InlFile: text;
BytePtr: 0..128; BitCnt: Bits;
Buffer: array[0..127] of byte;
WB: ByteRec; WW: integer absolute WB;
PrgName: SymString;
PrgLen: integer; SymPtr: SymInd;
AField: integer; BField: string[7];
{$I F:pmlink.bit} {Bit-Management}
{$I F:pmlink.utl} {Utilities}
function RetrWd (N: integer): integer; {fetches 16-bit word from WB:}
Var WB: ByteRec; WW: integer absolute WB;
Begin
with WB do
Begin Low := Prog[N].Cont; High := Prog[Succ(N)].Cont End;
RetrWd := WW
End;
Procedure FirstPass;
Procedure RelErr (Mess: Symstring);
Begin Writeln ('PC = ',Hex(PC),', Modul: ',PrgName,
', ',Mess,' relative; Argument: ',Hex(GetWord)) End;
Procedure SpLErr (Item: ItemT);
Begin Writeln ('PC = ',Hex(PC),', Modul: ',PrgName,', Item: ',Item:2,
', AField: ',Hex(AField),', BField: ',BField) End;
Procedure Store (Bt: byte; F: FlagT);
Begin
With Prog[PC] do Begin FLAG := F; Cont := Bt End;
PC := Succ(PC)
End;
Procedure GetAField;
Begin
case GetBits(2) of
0,1: AField := GetWord;
2: RelErr ('Data');
3: RelErr ('Common')
End
End;
Procedure GetBField; var N: 1..6;
Begin
BField[0] := Chr(GetBits(3));
For N:=1 to Length(BField) do BField[N] := Chr(GetByte)
End;
Procedure SetExtern; var Next: integer;
Begin
SymTab[SymPtr] := BField;
repeat
Next := RetrWd(AField);
with Prog[AField] do Begin Cont := SymPtr; Flag := Ext End;
Prog[Succ(AField)].Cont := 0; {starting with No Offset}
AField := Next
until Next=0;
SymPtr := Succ(SymPtr)
End;
Procedure SetOffs; var N: byte;
Begin
For N := 1 to Pred(OffsPtr) do
Prog[Succ(OffsTab[N].OPC)].Cont := N {Pointer to entry in Offset-table}
End;
Procedure ExtLink; var N: 1..7;
Begin
BField[0] := Chr(Max(Succ(GetBits(3)),2));
For N:=1 to Length(BField) do BField[N] := Chr(GetByte)
End;
Procedure DefOffs (Offset: integer);
Begin
with OffsTab[OffsPtr] do Begin OPC := PC; Value := Offset End;
OffsPtr := Succ(OffsPtr)
End;
Procedure StoreWd (Word: integer; F:FlagT);
Begin Store (Lo(Word),F); Store (Hi(Word),F) End;
Procedure SpLink; var Item: ItemT;
Begin
Item := GetBits(4); AField :=0; BField := '';
if Item in [5..14] then GetAField;
if Item in [0..3,5..7] then GetBField
else case Item of
4: ExtLink; {Extension link item}
15: EoFile := true
End;
case Item of
1,3..5,11,12: SpLErr (Item); {Error - no processing}
2: PrgName := BField;
6: SetExtern;
8: DefOffs (-AField);
9: DefOffs (AField);
14,15: Begin PrgLen := PC; BitCnt :=0; EoPrg := true End
End {Program or File end}
End; {SpLink}
Begin {FirstPass}
PC :=0; SymPtr := 1; OffsPtr := 1; EoPrg := false;
repeat
if GetBits(1)=0 then Store(GetByte,Norm)
else case GetBits(2) of
0: SpLink; {special Link Item}
1: StoreWd (GetWord,Rel);
2: RelErr ('Data');
3: RelErr ('Common')
End
until EoPrg;
SetOffs
End; {FirstPass}
Procedure SecPass;
Procedure Header;
Begin
Writeln (InlFile); Write (InlFile,' begin');
If PrgName <>'' then Write (InlFile,' {Modul ',PrgName,'}');
Writeln (InlFile); Write (InlFile,' InLine (')
End;
Procedure WriteLine;
Var EndLine: boolean; ItemCnt: 0..15; LPos: 0..70;
Procedure AdjustLpos; var K,N: 0..7;
Begin
K := ItemCnt * 4 - LPos -1; LPos := LPos + K;
For N:=1 to K do Write (InlFile,' ')
End;
Procedure WriteItem;
Procedure WriteNorm;
Begin
Write (InlFile,'$',Copy(Hex(Prog[PC].Cont),3,2));
PC := Succ(PC); LPos := LPos + 3; ItemCnt := Succ(ItemCnt)
End;
Procedure WriteRel; var Item: string[5]; Value: integer;
Begin
Value := RetrWd(PC) - PC; Str(Value,Item);
If Value >=0 then Item := '+' + Item;
Write (InlFile,'*',Item);
PC := Succ(Succ(PC)); ItemCnt := ItemCnt + 2;
LPos := Lpos + Succ(Length(Item))
End;
Procedure WriteExtern;
Var Name: SymString;
OP: byte; Offset: integer; OffStr: string[6];
Begin
Name := SymTab[Prog[PC].Cont]; PC := Succ(PC);
OP := Prog[PC].Cont; PC := Succ(PC);
if OP>0 then
Begin Offset := OffsTab[OP].Value; Str(Offset,OffStr);
if Offset>0 then Name := Name + '+';
Name := Name + OffStr End;
Write (InlFile,Name);
ItemCnt := ItemCnt + 2; LPos := LPos + Length(Name)
End;
Begin {WriteItem}
case Prog[PC].Flag of
Norm: WriteNorm;
Rel: WriteRel;
Ext: WriteExtern
End;
End; {WriteItem}
Begin {WriteLine}
Writeln (InlFile); Write (InlFile,' {',Hex(PC),'} ');
If Odd(PC) then
Begin Write (InlFile,' '); ItemCnt :=1; LPos := 4 End
else Begin ItemCnt :=0; LPos :=0 End;
repeat
WriteItem;
EoPrg := (PC>=PrgLen); EndLine := (ItemCnt>15); AdjustLPos;
if not EoPrg then Begin Write (InlFile,'/'); LPos := Succ(LPos) End;
until (EndLine or EoPrg)
End; {WriteLine}
Procedure ClosePrg;
Begin
Writeln (InlFile,')'); Write (InlFIle,' end;');
If PrgNAme<>'' then Write (InlFile,' {',PrgName,'}');
Writeln (InlFile)
End;
Begin {SecPass}
PC := 0; EoPrg := false; Header;
repeat WriteLine until EoPrg;
ClosePrg
End; {SecPass}
Begin {PMLink}
repeat
OpenFiles; Writeln;
If not (Finis or ErrFlag) then
Begin
repeat
FirstPass; if not EoFile then SecPass
until EoFile;
Close (InlFile)
End
until Finis
End.
as