home *** CD-ROM | disk | FTP | other *** search
- {$X-}
- PROGRAM ComToChn;
- (*
- ** Purpose:
- ** Cut away the runtime library from a Turbo Pascal COM file
- ** thus producing a Turbo Pascal CHN file.
- ** Versions 3.00A and 3.01A are supported.
- *)
-
- CONST
- JumpAdr = $20E2;
- CallAdr = $0364;
- BufSiz = 128; {16 KByte}
-
- TYPE
- FName = STRING[20];
- Str80 = STRING[80];
- Sector = ARRAY[0..127] OF BYTE;
- PrgT = RECORD
- Start : ARRAY[1..9] OF BYTE;
- CallOp : BYTE;
- CallAdr : INTEGER;
- EndOp : BYTE;
- EndAdr : INTEGER
- END;
-
- VAR
- i, p : INTEGER;
- ziel,
- fni, fno : FName;
- fi, fo : FILE;
- Buffer : ARRAY[0..BufSiz] OF Sector; {1 sector more}
- sec : Sector ABSOLUTE Buffer;
- Jump : RECORD Op : BYTE; Adr : INTEGER END ABSOLUTE sec;
- Prg : ^PrgT;
- Vers, FRead, FSize, FChunk : INTEGER;
- OneMore : BOOLEAN;
-
-
- PROCEDURE Help; {no return}
- BEGIN
- WriteLn('usage: COMTOCHN program_name <destination_DU:>');
- WriteLn('Cuts away the runtime library from a Turbo Pascal COM file.');
- WriteLn('Creates <programname>.CHN on the given destination drive');
- Write ('(default = current DU).');
- Halt;
- END; {Help}
-
-
- PROCEDURE NoTP3(s : Str80); {no return}
- BEGIN
- WriteLn(s);
- WriteLn('Either this program is not a Turbo Pascal program');
- WriteLn('or it was not made by version 3.00A or 3.01A');
- Close(fi);
- Halt;
- END; {NoTP3}
-
-
- BEGIN {ComToChn}
- {say hello}
- WriteLn('ComToChn (C) Herbert Oppmann 04-JAN-93');
- {get parameters and check them}
- p := ParamCount;
- IF (p =0) OR (p >2) THEN Help;
- fni := ParamStr(1);
- IF (p =1) AND (fni ='//') THEN Help;
- ziel := ParamStr(2);
- IF (p =2) AND (ziel[Length(ziel)] <>':') THEN Help;
- {compose filenames}
- i := Pos('.',fni);
- IF (i =0) THEN
- BEGIN {no extension specified}
- fno := fni+'.CHN';
- fni := fni+'.COM';
- END
- ELSE
- BEGIN {extension specified}
- IF (Copy(fni,i+1,3) <>'COM') THEN
- BEGIN
- WriteLn('You don''t need to specify an extension.');
- Write ('But if you do, it has to be ''COM''. Nothing done.');
- Halt;
- END;
- fno := Copy(fni,1,i)+'CHN';
- END; {IF}
- i := Pos(':', fno);
- IF (i >0) THEN Delete(fno,1,i); {cut away prefix}
- fno := ziel+fno;
- {open COM file and check}
- Assign(fi, fni);
- {$I-}
- Reset(fi);
- IF (IOResult <>0) THEN
- BEGIN
- Write('COM file not found!');
- Halt;
- END;
- {$I+}
- FSize := FileSize(fi);
- IF (FSize <64) THEN NoTP3('File smaller than 8 KByte');
- BlockRead(fi, sec, 1);
- IF (Jump.Op <>$C3)
- THEN NoTP3('No jump at the beginning of the runtime library');
- IF (Jump.Adr =JumpAdr) THEN Vers := 0
- ELSE BEGIN
- IF (Jump.Adr =Succ(JumpAdr)) THEN Vers := 1
- ELSE NoTP3('Jump address at the beginning of the runtime library did not match');
- END;
- Prg := Ptr(Addr(sec[(JumpAdr+Vers) AND $7F]));
- Seek(fi,63); {Adresse 2080-2100}
- BlockRead(fi, sec, 1);
- IF (Prg^.CallOp <>$CD) OR (Prg^.CallAdr <>(CallAdr+Vers)) OR (Prg^.EndOp <>$21)
- THEN NoTP3('Can''t match beginning of program');
- IF (((Prg^.EndAdr -$81) SHR 7) <> FSize)
- THEN NoTP3('Error in size');
- FRead := FSize-64; (* that's how much sectors we still got to read *)
- OneMore := FRead <> (((Prg^.EndAdr-JumpAdr-Vers)+$7F) SHR 7);
- {create CHN file}
- Write(fni,' (v3.0',Vers,'A) --> ',fno,' ');
- Assign(fo, fno);
- Rewrite(fo);
- WHILE (FRead >0) DO
- BEGIN
- IF (FRead >BufSiz) THEN FChunk := BufSiz ELSE FChunk := FRead;
- BlockRead(fi,Buffer[1],FChunk);
- BlockWrite(fo,Prg^.Start,FChunk);
- Move(Buffer[BufSiz],sec,128);
- FRead := FRead-FChunk;
- END; {WHILE}
- IF OneMore THEN BlockWrite(fo,Prg^.Start,1);
- Close(fi);
- Close(fo);
- Write('- ok');
- END. {ComToChn}