preparing to do a cp/m cleanup
i wrote most of this up to here on a linux laptop, but some changes need to be made to get it working with CP/M-80.
This commit is contained in:
parent
a43054deec
commit
a60a6a3f59
11
Makefile
11
Makefile
|
@ -1,6 +1,6 @@
|
||||||
TARGETS := test undump
|
TARGETS := test dump undump
|
||||||
LIBS := binary.pas ihex.pas
|
LIBS := binary.pas common.pas ihex.pas
|
||||||
FPC_FLAGS := -g
|
FPC_FLAGS := -g -Mtp
|
||||||
FPC := fpc $(FPC_FLAGS)
|
FPC := fpc $(FPC_FLAGS)
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
|
@ -13,6 +13,9 @@ clean:
|
||||||
test: test.pas $(LIBS)
|
test: test.pas $(LIBS)
|
||||||
$(FPC) $@.pas
|
$(FPC) $@.pas
|
||||||
|
|
||||||
undump: undump.pas binary.pas ihex.pas
|
undump: undump.pas $(LIBS)
|
||||||
|
$(FPC) $@.pas
|
||||||
|
|
||||||
|
dump: dump.pas $(LIBS)
|
||||||
$(FPC) $@.pas
|
$(FPC) $@.pas
|
||||||
|
|
||||||
|
|
20
binary.pas
20
binary.pas
|
@ -1,6 +1,22 @@
|
||||||
|
{
|
||||||
|
binary.pas contains procedures and functions for dealing
|
||||||
|
with binary data.
|
||||||
|
}
|
||||||
|
|
||||||
type
|
type
|
||||||
BStr = String[2]; { String representing a u8. }
|
BStr = String[2]; { String representing a u8. }
|
||||||
WStr = String[4]; { String representing a u16. }
|
WStr = String[4]; { String representing a u16. }
|
||||||
|
BinFile = File of Byte;
|
||||||
|
|
||||||
|
|
||||||
|
Procedure ExpandFile(var fil : BinFile; var pos : Integer; pad : Integer);
|
||||||
|
var
|
||||||
|
i : Integer;
|
||||||
|
begin
|
||||||
|
for i := 1 to pad do Write(fil, Byte(0));
|
||||||
|
pos := FilePos(fil);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
function ValidHexDigit(bval: Byte): Boolean;
|
function ValidHexDigit(bval: Byte): Boolean;
|
||||||
var
|
var
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
common.pas
|
||||||
|
|
||||||
|
Common functionality that's useful across my toolkit.
|
||||||
|
|
||||||
|
TYPES
|
||||||
|
- FilePath is a string used for storing filenames on CP/M.
|
||||||
|
|
||||||
|
Procedures:
|
||||||
|
- Procedure ExpandFile(var fil : BinFile; var pos : Integer; pad : Integer);
|
||||||
|
}
|
||||||
|
|
||||||
|
type
|
||||||
|
FilePath = String[12];
|
||||||
|
|
||||||
|
|
||||||
|
function IMax(a, b : Integer): Integer;
|
||||||
|
begin
|
||||||
|
if a > b then IMax := a else IMax := b;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function BMax(a, b : Byte): Byte;
|
||||||
|
begin
|
||||||
|
if a > b then BMax := a else BMax := b;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function IMin(a, b : Integer): Integer;
|
||||||
|
begin
|
||||||
|
if a > b then IMin := b else IMin := a;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function BMin(a, b : Byte): Byte;
|
||||||
|
begin
|
||||||
|
if a > b then BMin := b else BMin := a;
|
||||||
|
end;
|
|
@ -0,0 +1,50 @@
|
||||||
|
program dump;
|
||||||
|
|
||||||
|
{
|
||||||
|
dump emulates the version of DUMP.COM that comes with some
|
||||||
|
CP/M distributions.
|
||||||
|
}
|
||||||
|
|
||||||
|
{$I 'binary.pas'}
|
||||||
|
{$I 'common.pas'}
|
||||||
|
|
||||||
|
|
||||||
|
procedure DumpChunk(
|
||||||
|
var src : BinFile;
|
||||||
|
var dst : Text;
|
||||||
|
var addr : Integer,
|
||||||
|
var chunk : Byte);
|
||||||
|
var
|
||||||
|
buffer : array [1 .. 16] of Byte;
|
||||||
|
begin
|
||||||
|
Write(dst, WriteWord(addr));
|
||||||
|
Write(dst, ' ');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure DumpFile(var src : BinFile; var dst : Text);
|
||||||
|
var
|
||||||
|
Address : Integer;
|
||||||
|
Size : Integer;
|
||||||
|
Buffer : array [1 .. 16] of Byte;
|
||||||
|
Chunk : Byte;
|
||||||
|
begin
|
||||||
|
Address := 0;
|
||||||
|
Size := FileSize(src);
|
||||||
|
Chunk := IMin($10, Size);
|
||||||
|
|
||||||
|
FillChar(Buffer, $10, $0);
|
||||||
|
WriteLn('Chunk: ', Chunk);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
var
|
||||||
|
inf : BinFile;
|
||||||
|
begin
|
||||||
|
Assign(inf, 'dump.bin');
|
||||||
|
Reset(inf);
|
||||||
|
|
||||||
|
DumpFile(inf, Output);
|
||||||
|
end.
|
|
@ -0,0 +1,84 @@
|
||||||
|
KCPMTK : KYLE'S CP/M TOOLKIT
|
||||||
|
|
||||||
|
This is a collection of programs and source libraries that are
|
||||||
|
useful for working with CP/M.
|
||||||
|
|
||||||
|
|
||||||
|
TOOLS
|
||||||
|
|
||||||
|
- DUMP.COM, UNDUMP.COM
|
||||||
|
|
||||||
|
DUMP outputs a hexadecimal-encoded version of a file along with
|
||||||
|
an address counter. UNDUMP takes this output and can return an
|
||||||
|
Intel hex version or produce a binary file.
|
||||||
|
|
||||||
|
The original purpose of this repository was to write UNDUMP, which
|
||||||
|
reverses the output of the DUMP.COM utility. After working with a
|
||||||
|
CP/M which didn't have DUMP.COM, I wrote my own version.
|
||||||
|
|
||||||
|
- DOWNLOAD.COM, UPLOAD.COM
|
||||||
|
|
||||||
|
A pair of tools that mimics the utility shipped with the RC2014,
|
||||||
|
which comes by way of Grant Searle's tools.
|
||||||
|
|
||||||
|
|
||||||
|
LIBRARIES
|
||||||
|
|
||||||
|
1. COMMON.PAS
|
||||||
|
|
||||||
|
COMMON is a collection of routines that are, you guessed it, commonly
|
||||||
|
useful.
|
||||||
|
|
||||||
|
Types
|
||||||
|
-----
|
||||||
|
|
||||||
|
- FilePath is a string used for storing filenames on CP/M.
|
||||||
|
|
||||||
|
|
||||||
|
2. BINARY.PAS
|
||||||
|
|
||||||
|
BINARY is a collection of routines for handling binary data. It has
|
||||||
|
functions for dealing with digits (e.g. Byte values in the range
|
||||||
|
$0 .. $F), bytes, and words. When dealing with invalid values, the
|
||||||
|
code returns 0 instead of a garbage value. This is an arbitrary
|
||||||
|
choice.
|
||||||
|
|
||||||
|
Types
|
||||||
|
-----
|
||||||
|
|
||||||
|
- BStr ('byte string') defines a string for containing an hex-
|
||||||
|
encoded byte.
|
||||||
|
- WStr ('word string') defines a string for containing a hex-
|
||||||
|
encoded word.
|
||||||
|
- BinFile is a file of bytes.
|
||||||
|
|
||||||
|
Procedures
|
||||||
|
----------
|
||||||
|
|
||||||
|
- Procedure ExpandFile(var fil : BinFile; var pos : Integer; pad : Integer);
|
||||||
|
|
||||||
|
ExpandFile will pad out the file with enough bytes. The `pos` parameter
|
||||||
|
is used to track the file position after expansion.
|
||||||
|
|
||||||
|
- function ValidHexDigit(bval: Byte): Boolean;
|
||||||
|
|
||||||
|
Returns True if the byte is between the range of $0 .. $F.
|
||||||
|
|
||||||
|
- function ReadDigit(bchr: Char): Byte;
|
||||||
|
|
||||||
|
ReadDigit converts a single character representing an octal, decimal,
|
||||||
|
or hexadecimal digit to a byte; the octal and decimal support are
|
||||||
|
incidental.
|
||||||
|
|
||||||
|
- function ReadByte(bstr : BStr): Byte;
|
||||||
|
function ReadWord(bstr : WStr): Integer;
|
||||||
|
|
||||||
|
Given a string that contains a hex-encoded byte or word, return the
|
||||||
|
decoded value.
|
||||||
|
|
||||||
|
- function WriteByte(bval : Byte): BStr;
|
||||||
|
function WriteWord(bval : Integer): WStr;
|
||||||
|
|
||||||
|
Given a byte or word value, return its hex-encoded string
|
||||||
|
representation.
|
||||||
|
|
2
test.pas
2
test.pas
|
@ -13,4 +13,6 @@ begin
|
||||||
begin
|
begin
|
||||||
WriteLn(I, '->', WriteByte(I));
|
WriteLn(I, '->', WriteByte(I));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
LowVideo;
|
||||||
end.
|
end.
|
||||||
|
|
180
undump.pas
180
undump.pas
|
@ -1,82 +1,151 @@
|
||||||
program undump;
|
program undump;
|
||||||
{
|
{
|
||||||
undump is a program to take the output from dump
|
undump is a program to take the output fr
|
||||||
and put it into binary format.
|
and put it into binary format.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{$I 'common.pas'}
|
||||||
{$I 'binary.pas'}
|
{$I 'binary.pas'}
|
||||||
{$I 'ihex.pas'}
|
{$I 'ihex.pas'}
|
||||||
|
|
||||||
type
|
|
||||||
FilePath = String[12];
|
|
||||||
|
|
||||||
Procedure DumpIHex(iname, oname : FilePath);
|
|
||||||
var
|
|
||||||
inf : Text;
|
|
||||||
outf : Text;
|
|
||||||
line : LnStr;
|
|
||||||
rec : IRec;
|
|
||||||
begin
|
|
||||||
if iname <> '' then
|
|
||||||
begin
|
|
||||||
Assign(inf, iname);
|
|
||||||
Reset(inf);
|
|
||||||
end else inf := Input;
|
|
||||||
|
|
||||||
if oname <> '' then
|
|
||||||
begin
|
|
||||||
Assign(outf, oname);
|
|
||||||
Rewrite(outf);
|
|
||||||
end else outf := Output;
|
|
||||||
|
|
||||||
while not EOF(inf) do
|
|
||||||
begin
|
|
||||||
ReadLn(inf, line);
|
|
||||||
if (Line <> '') then
|
|
||||||
begin
|
|
||||||
rec := RdDumpLn(line);
|
|
||||||
WrRec(rec, outf);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Close(inf);
|
|
||||||
Writeln(outf, IRecEOF);
|
|
||||||
Flush(outf);
|
|
||||||
Close(outf);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure PrnHelp;
|
procedure PrnHelp;
|
||||||
begin
|
begin
|
||||||
WriteLn('UNDUMP V1.0');
|
WriteLn('UNDUMP V1.0');
|
||||||
WriteLn('Converts DUMP.COM output to Intel Hex format');
|
WriteLn('Converts DUMP.COM output to Intel Hex format');
|
||||||
WriteLn('');
|
WriteLn('');
|
||||||
WriteLn('Usage:');
|
WriteLn('Usage:');
|
||||||
WriteLn(' UNDUMP.COM INFILE OUTFILE');
|
WriteLn(' UNDUMP.COM [-BH] [INFILE] OUTFILE');
|
||||||
|
WriteLn(' If only one argumet is given, it will be assigned');
|
||||||
|
WriteLn(' to the output file and input will be set to standard');
|
||||||
|
WriteLn(' output.');
|
||||||
|
WriteLn('');
|
||||||
|
WriteLn('Options:');
|
||||||
|
WriteLn(' -B : Write in binary format (the default is Intel');
|
||||||
|
WriteLn(' hex format.');
|
||||||
|
WriteLn(' -H : Show this help message.');
|
||||||
|
|
||||||
Halt;
|
Halt;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Procedure DumpIHex(iname, oname : FilePath);
|
||||||
|
var
|
||||||
|
inf : Text;
|
||||||
|
outf : Text;
|
||||||
|
line : LnStr;
|
||||||
|
rec : IRec;
|
||||||
|
nlc : Byte; { newline count }
|
||||||
|
begin
|
||||||
|
nlc := 0;
|
||||||
|
if iname <> '' then
|
||||||
|
begin
|
||||||
|
Assign(inf, iname);
|
||||||
|
Reset(inf);
|
||||||
|
end else inf := Input;
|
||||||
|
|
||||||
|
if oname <> '' then
|
||||||
|
begin
|
||||||
|
Assign(outf, oname);
|
||||||
|
Rewrite(outf);
|
||||||
|
end else outf := Output;
|
||||||
|
|
||||||
|
while not EOF(inf) do
|
||||||
|
begin
|
||||||
|
ReadLn(inf, line);
|
||||||
|
if (Line <> '') then
|
||||||
|
begin
|
||||||
|
rec := RdDumpLn(line);
|
||||||
|
WrRec(rec, outf);
|
||||||
|
nlc := 0;
|
||||||
|
end else nlc := nlc + 1;
|
||||||
|
|
||||||
|
if nlc > 0 then Exit;
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
Close(inf);
|
||||||
|
Writeln(outf, IRecEOF);
|
||||||
|
Flush(outf);
|
||||||
|
Close(outf);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Procedure DumpBinary(iname, oname : FilePath);
|
||||||
|
var
|
||||||
|
inf : Text;
|
||||||
|
outf : File of Byte;
|
||||||
|
line : LnStr;
|
||||||
|
rec : IRec;
|
||||||
|
nlc : Byte; { newline count }
|
||||||
|
i : Byte;
|
||||||
|
pos : Integer;
|
||||||
|
begin
|
||||||
|
nlc := 0;
|
||||||
|
if iname <> '' then
|
||||||
|
begin
|
||||||
|
Assign(inf, iname);
|
||||||
|
Reset(inf);
|
||||||
|
end else inf := Input;
|
||||||
|
|
||||||
|
if oname = '' then
|
||||||
|
PrnHelp;
|
||||||
|
|
||||||
|
Assign(outf, oname);
|
||||||
|
Rewrite(outf);
|
||||||
|
|
||||||
|
while not EOF(inf) do
|
||||||
|
begin
|
||||||
|
ReadLn(inf, line);
|
||||||
|
if (Line <> '') then
|
||||||
|
begin
|
||||||
|
rec := RdDumpLn(line);
|
||||||
|
pos := FilePos(outf);
|
||||||
|
if pos > rec.Addr then
|
||||||
|
ExpandFile(outf, pos, pos-rec.Addr);
|
||||||
|
if pos <> rec.Addr then Seek(outf, rec.Addr-pos);
|
||||||
|
for i := 1 to rec.Count do
|
||||||
|
Write(outf, rec.Data[i]);
|
||||||
|
nlc := 0;
|
||||||
|
end else nlc := nlc + 1;
|
||||||
|
if nlc > 0 then Exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Close(inf);
|
||||||
|
Close(outf);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
i, argc : Integer;
|
i, argc : Integer;
|
||||||
rec : irec;
|
|
||||||
opts : record
|
opts : record
|
||||||
|
Binary : Boolean;
|
||||||
ShoVer : Boolean;
|
ShoVer : Boolean;
|
||||||
InFile : FilePath;
|
InFile : FilePath;
|
||||||
OutFile : FilePath;
|
OutFile : FilePath;
|
||||||
end;
|
end;
|
||||||
param : String[255];
|
param : String[32];
|
||||||
|
paramc : Char;
|
||||||
begin
|
begin
|
||||||
opts.ShoVer := False;
|
opts.Binary := False;
|
||||||
opts.InFile := '';
|
opts.ShoVer := False;
|
||||||
|
opts.InFile := '';
|
||||||
opts.OutFile := '';
|
opts.OutFile := '';
|
||||||
argc := ParamCount;
|
argc := ParamCount;
|
||||||
|
i := 1;
|
||||||
|
|
||||||
for i := 1 to ParamCount do
|
param := ParamStr(i);
|
||||||
|
while param[1] = '-' do
|
||||||
begin
|
begin
|
||||||
if ParamStr(i) = '-h' or ParamStr(i) = 'H' then
|
paramc := UpCase(param[2]);
|
||||||
begin
|
|
||||||
opts.ShoVer := True;
|
case paramc of
|
||||||
argc := argc - 1;
|
'B': opts.Binary := True;
|
||||||
|
'H': opts.ShoVer := True;
|
||||||
|
else
|
||||||
|
PrnHelp;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
i := i + 1;
|
||||||
|
param := ParamStr(i);
|
||||||
|
argc := argc - 1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if opts.ShoVer then PrnHelp();
|
if opts.ShoVer then PrnHelp();
|
||||||
|
@ -86,9 +155,12 @@ begin
|
||||||
if i = 1 then opts.OutFile := ParamStr(ParamCount);
|
if i = 1 then opts.OutFile := ParamStr(ParamCount);
|
||||||
if i > 1 then
|
if i > 1 then
|
||||||
begin
|
begin
|
||||||
InFile := ParamStr(i);
|
opts.InFile := ParamStr(i);
|
||||||
OutFile := ParamStr(i+1);
|
opts.OutFile := ParamStr(i+1);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
DumpIHex(InFile, OutFile);
|
if opts.Binary then
|
||||||
|
DumpBinary(opts.InFile, opts.OutFile)
|
||||||
|
else
|
||||||
|
DumpIHex(opts.InFile, opts.OutFile);
|
||||||
end.
|
end.
|
||||||
|
|
Loading…
Reference in New Issue