mirror of
https://github.com/open-simh/simtools.git
synced 2026-01-13 23:36:03 +00:00
Added RSX-11 format .obj file reader (as default), set BIN format as default output
This commit is contained in:
parent
5015ea60c5
commit
114ceaf32c
67
README.md
67
README.md
@ -3,16 +3,18 @@
|
||||
If run with no options, it prints a usage screen:
|
||||
|
||||
```
|
||||
obj2bin.pl v2.0 by Don North (perl 5.022)
|
||||
obj2bin.pl v2.1 by Don North (perl 5.03)
|
||||
Usage: ./obj2bin.pl [options...] arguments
|
||||
--help output manpage and exit
|
||||
--debug enable debug mode
|
||||
--verbose verbose status reporting
|
||||
--boot M9312 boot prom
|
||||
--console M9312 console/diagnostic prom
|
||||
--binary binary program load image
|
||||
--ascii ascii m9312 program load image
|
||||
--bytes=N bytes per block on output
|
||||
--boot M9312 boot prom .hex
|
||||
--console M9312 console/diagnostic prom .hex
|
||||
--binary binary program load image .bin [default]
|
||||
--ascii ascii m9312 program load image .txt
|
||||
--rt11 read .obj files in RT11 format
|
||||
--rsx11 read .obj files in RSX11 format [default]
|
||||
--bytes=N bytes per block on output hex format
|
||||
--nocrc inhibit output of CRC-16 in hex format
|
||||
--logfile=LOGFILE logging message file
|
||||
--outfile=OUTFILE output .hex/.txt/.bin file
|
||||
@ -28,14 +30,19 @@ NAME
|
||||
|
||||
SYNOPSIS
|
||||
obj2bin.pl [--help] [--debug] [--verbose] [--boot] [--console] [--binary]
|
||||
[--ascii] [--bytes=N] [--nocrc] [--logfile=LOGFILE] --outfile=BINFILE
|
||||
OBJFILE...
|
||||
[--ascii] [--rt11] [--rsx11] [--bytes=N] [--nocrc] [--logfile=LOGFILE]
|
||||
--outfile=BINFILE OBJFILE
|
||||
|
||||
DESCRIPTION
|
||||
Converts a Macro-11 object file to various output formats, including M9312
|
||||
boot and console PROM, straight binary records, ASCII format for M9312
|
||||
console load commands, and loadable absolute binary program images (.BIN)
|
||||
files.
|
||||
Converts a Macro-11 object files to various output formats, including
|
||||
M9312 boot and console PROM, straight binary records, ASCII format for
|
||||
M9312 console load commands, and loadable absolute binary program images
|
||||
(.BIN) files.
|
||||
|
||||
Multiple .psect/.asect ops are supported, as well as all local
|
||||
(non-global) relocation directory entries.
|
||||
|
||||
Supports either RT-11 or RSX-11 format object files.
|
||||
|
||||
OPTIONS
|
||||
The following options are available:
|
||||
@ -57,19 +64,29 @@ OPTIONS
|
||||
Generate a hex PROM file image suitable for programming into an M9312
|
||||
console/diagnostic prom (1024x4 geometry).
|
||||
|
||||
--ascii
|
||||
Generate a a sequence of 'L addr' / 'D data' commands for downloading
|
||||
a program via a terminal emulator thru the M9312 user command
|
||||
interface. Suitable only for really small test programs.
|
||||
|
||||
--binary
|
||||
Generate binary format load records of the program image (paper tape
|
||||
format) for loading into SIMH or compatible simulators. These files
|
||||
can also be copied onto XXDP filesystems to generate runnable program
|
||||
images (used to write custom diaqnostics).
|
||||
|
||||
--ascii
|
||||
Generate a a sequence of 'L addr' / 'D data' commands for downloading
|
||||
a program via a terminal emulator thru the M9312 user command
|
||||
interface. Suitable only for really small test programs.
|
||||
Binary format is the default if no other option is specified. If more
|
||||
than one option is specified the last one takes effect.
|
||||
|
||||
Exactly ONE of --boot, --console, --binary, or --ascii must be
|
||||
specified.
|
||||
--rt11
|
||||
Read input object files in RT-11 format.
|
||||
|
||||
--rsx11
|
||||
Read input object files in RSX-11 format.
|
||||
|
||||
RSX-11 object file format is the default if no other option is
|
||||
specified. If more than one option is specified the last one takes
|
||||
effect.
|
||||
|
||||
--bytes=N
|
||||
For hex format output files, output N bytes per line (default 16).
|
||||
@ -95,10 +112,10 @@ ERRORS
|
||||
|
||||
"Can't open input file '$file'" -- bad filename or unreadable file
|
||||
|
||||
"Error: Improper object file format (1)" -- valid record must start with
|
||||
0x01
|
||||
"Error: Improper object file format (1)" -- valid RT-11 record must start
|
||||
with 0x01
|
||||
|
||||
"Error: Improper object file format (2)" -- second byte must be 0x00
|
||||
"Error: Improper object file format (2)" -- second RT-11 byte must be 0x00
|
||||
|
||||
"Error: Improper object file format (3)" -- third byte is low byte of
|
||||
record length
|
||||
@ -109,7 +126,7 @@ ERRORS
|
||||
"Error: Improper object file format (5)" -- bytes five thru end-1 are data
|
||||
bytes
|
||||
|
||||
"Error: Improper object file format (6)" -- last byte is checksum
|
||||
"Error: Improper object file format (6)" -- last RT-11 byte is checksum
|
||||
|
||||
"Error: Bad checksum exp=0x%02X rcv=0x%02X" -- compare rcv'ed checksum vs
|
||||
exp'ed checksum
|
||||
@ -121,9 +138,9 @@ EXAMPLES
|
||||
|
||||
obj2bin.pl --verbose --boot --out 23-751A9.hex 23-751A9.obj
|
||||
|
||||
obj2bin.pl --verbose --binary --out memtest.bin memtest.obj
|
||||
obj2bin.pl --verbose --binary --rt11 --out memtest.bin memtest.obj
|
||||
|
||||
obj2bin.pl --verbose --binary --out prftst.bin prftst.obj mac/printf.obj
|
||||
obj2bin.pl --verbose --binary --rsx11 --out prftst.bin prftst.obj mac/printf.obj
|
||||
|
||||
AUTHOR
|
||||
Don North - donorth <ak6dn _at_ mindspring _dot_ com>
|
||||
@ -140,4 +157,6 @@ HISTORY
|
||||
2017-04-01 v1.9 donorth - Renamed from obj2hex.pl to obj2bin.pl
|
||||
2017-05-04 v1.95 donorth - Updated capability to read multiple input .obj files.
|
||||
2020-03-06 v2.0 donorth - Updated help documentation and README.md file.
|
||||
2020-03-10 v2.1 donorth - Broke down and added RSX-11 input format option.
|
||||
|
||||
```
|
||||
|
||||
191
obj2bin.pl
191
obj2bin.pl
@ -47,6 +47,8 @@ S<[--boot]>
|
||||
S<[--console]>
|
||||
S<[--binary]>
|
||||
S<[--ascii]>
|
||||
S<[--rt11]>
|
||||
S<[--rsx11]>
|
||||
S<[--bytes=N]>
|
||||
S<[--nocrc]>
|
||||
S<[--logfile=LOGFILE]>
|
||||
@ -63,6 +65,8 @@ binary program images (.BIN) files.
|
||||
Multiple .psect/.asect ops are supported, as well as all local
|
||||
(non-global) relocation directory entries.
|
||||
|
||||
Supports either RT-11 or RSX-11 format object files.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
The following options are available:
|
||||
@ -91,6 +95,12 @@ an M9312 boot prom (512x4 geometry, only low half used).
|
||||
Generate a hex PROM file image suitable for programming into
|
||||
an M9312 console/diagnostic prom (1024x4 geometry).
|
||||
|
||||
=item B<--ascii>
|
||||
|
||||
Generate a a sequence of 'L addr' / 'D data' commands for downloading
|
||||
a program via a terminal emulator thru the M9312 user command interface.
|
||||
Suitable only for really small test programs.
|
||||
|
||||
=item B<--binary>
|
||||
|
||||
Generate binary format load records of the program image (paper
|
||||
@ -98,14 +108,19 @@ tape format) for loading into SIMH or compatible simulators.
|
||||
These files can also be copied onto XXDP filesystems to generate
|
||||
runnable program images (used to write custom diaqnostics).
|
||||
|
||||
=item B<--ascii>
|
||||
Binary format is the default if no other option is specified.
|
||||
If more than one option is specified the last one takes effect.
|
||||
|
||||
Generate a a sequence of 'L addr' / 'D data' commands for downloading
|
||||
a program via a terminal emulator thru the M9312 user command interface.
|
||||
Suitable only for really small test programs.
|
||||
=item B<--rt11>
|
||||
|
||||
Exactly ONE of B<--boot>, B<--console>, B<--binary>, or B<--ascii>
|
||||
must be specified.
|
||||
Read input object files in RT-11 format.
|
||||
|
||||
=item B<--rsx11>
|
||||
|
||||
Read input object files in RSX-11 format.
|
||||
|
||||
RSX-11 object file format is the default if no other option is specified.
|
||||
If more than one option is specified the last one takes effect.
|
||||
|
||||
=item B<--bytes=N>
|
||||
|
||||
@ -139,9 +154,9 @@ C<Aborted due to command line errors> -- bad option or missing file(s)
|
||||
|
||||
C<Can't open input file '$file'> -- bad filename or unreadable file
|
||||
|
||||
C<Error: Improper object file format (1)> -- valid record must start with 0x01
|
||||
C<Error: Improper object file format (1)> -- valid RT-11 record must start with 0x01
|
||||
|
||||
C<Error: Improper object file format (2)> -- second byte must be 0x00
|
||||
C<Error: Improper object file format (2)> -- second RT-11 byte must be 0x00
|
||||
|
||||
C<Error: Improper object file format (3)> -- third byte is low byte of record length
|
||||
|
||||
@ -149,7 +164,7 @@ C<Error: Improper object file format (4)> -- fourth byte is high byte of record
|
||||
|
||||
C<Error: Improper object file format (5)> -- bytes five thru end-1 are data bytes
|
||||
|
||||
C<Error: Improper object file format (6)> -- last byte is checksum
|
||||
C<Error: Improper object file format (6)> -- last RT-11 byte is checksum
|
||||
|
||||
C<Error: Bad checksum exp=0x%02X rcv=0x%02X> -- compare rcv'ed checksum vs exp'ed checksum
|
||||
|
||||
@ -161,9 +176,9 @@ Some examples of common usage:
|
||||
|
||||
obj2bin.pl --verbose --boot --out 23-751A9.hex 23-751A9.obj
|
||||
|
||||
obj2bin.pl --verbose --binary --out memtest.bin memtest.obj
|
||||
obj2bin.pl --verbose --binary --rt11 --out memtest.bin memtest.obj
|
||||
|
||||
obj2bin.pl --verbose --binary --out prftst.bin prftst.obj mac/printf.obj
|
||||
obj2bin.pl --verbose --binary --rsx11 --out prftst.bin prftst.obj mac/printf.obj
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
@ -182,6 +197,7 @@ Modification history:
|
||||
2017-04-01 v1.9 donorth - Renamed from obj2hex.pl to obj2bin.pl
|
||||
2017-05-04 v1.95 donorth - Updated capability to read multiple input .obj files.
|
||||
2020-03-06 v2.0 donorth - Updated help documentation and README.md file.
|
||||
2020-03-10 v2.1 donorth - Broke down and added RSX-11 input format option.
|
||||
|
||||
=cut
|
||||
|
||||
@ -202,7 +218,7 @@ BEGIN { unshift(@INC, $FindBin::Bin);
|
||||
# external local modules
|
||||
|
||||
# generic defaults
|
||||
my $VERSION = 'v2.0'; # version of code
|
||||
my $VERSION = 'v2.1'; # version of code
|
||||
my $HELP = 0; # set to 1 for man page output
|
||||
my $DEBUG = 0; # set to 1 for debug messages
|
||||
my $VERBOSE = 0; # set to 1 for verbose messages
|
||||
@ -215,7 +231,8 @@ my %excaddr; # words to be skipped in rom crc calc
|
||||
my $rombase; # base address of rom image
|
||||
my $romsize; # number of rom addresses
|
||||
my $romfill; # rom fill pattern
|
||||
my $romtype = 'NONE'; # default rom type
|
||||
my $romtype = 'BINA'; # default rom type is BINARY
|
||||
my $objtype = 'RSX11'; # default object file format is RSX11
|
||||
my $bytesper = -1; # bytes per block in output file
|
||||
my $nocrc = 0; # output CRC16 as last word unless set
|
||||
my $outfile = undef; # output filename
|
||||
@ -229,6 +246,8 @@ my $NOERROR = GetOptions( "help" => \$HELP,
|
||||
"console" => sub { $romtype = 'DIAG'; },
|
||||
"binary" => sub { $romtype = 'BINA'; },
|
||||
"ascii" => sub { $romtype = 'ASC9'; },
|
||||
"rt11" => sub { $objtype = 'RT11'; },
|
||||
"rsx11" => sub { $objtype = 'RSX11'; },
|
||||
"bytes=i" => \$bytesper,
|
||||
"nocrc" => \$nocrc,
|
||||
"outfile=s" => \$outfile,
|
||||
@ -264,11 +283,13 @@ unless ($NOERROR
|
||||
--help output manpage and exit
|
||||
--debug enable debug mode
|
||||
--verbose verbose status reporting
|
||||
--boot M9312 boot prom
|
||||
--console M9312 console/diagnostic prom
|
||||
--binary binary program load image
|
||||
--ascii ascii m9312 program load image
|
||||
--bytes=N bytes per block on output
|
||||
--boot M9312 boot prom .hex
|
||||
--console M9312 console/diagnostic prom .hex
|
||||
--binary binary program load image .bin [default]
|
||||
--ascii ascii m9312 program load image .txt
|
||||
--rt11 read .obj files in RT11 format
|
||||
--rsx11 read .obj files in RSX11 format [default]
|
||||
--bytes=N bytes per block on output hex format
|
||||
--nocrc inhibit output of CRC-16 in hex format
|
||||
--logfile=LOGFILE logging message file
|
||||
--outfile=OUTFILE output .hex/.txt/.bin file
|
||||
@ -627,53 +648,99 @@ sub read_rec ($) {
|
||||
my @dat = ();
|
||||
my @suf = ();
|
||||
|
||||
# Object file format consists of blocks, optionally preceded, separated, and
|
||||
# followed by zeroes. Each block consists of:
|
||||
#
|
||||
# 001 ---
|
||||
# 000 |
|
||||
# lo(length) |
|
||||
# hi(length) > 'length' bytes
|
||||
# databyte1 |
|
||||
# : |
|
||||
# databyteN ---
|
||||
# checksum
|
||||
#
|
||||
if ($objtype eq 'RT11') {
|
||||
|
||||
# skip over strings of 0x00; exit OK if hit EOF
|
||||
do { return () unless $cnt = read($fh, $buf, 1); } while (ord($buf) == 0);
|
||||
# RT-11 object file format consists of blocks, optionally preceded, separated, and
|
||||
# followed by zeroes. Each block consists of:
|
||||
#
|
||||
# 001 ---
|
||||
# 000 |
|
||||
# lo(length) |
|
||||
# hi(length) > 'length' bytes
|
||||
# databyte1 |
|
||||
# : |
|
||||
# databyteN ---
|
||||
# checksum
|
||||
#
|
||||
|
||||
# valid record starts with (1)
|
||||
$err = 1 unless $cnt == 1 && ord($buf) == 1;
|
||||
push(@pre, ord($buf));
|
||||
# skip over strings of 0x00; exit OK if hit EOF
|
||||
do { return () unless $cnt = read($fh, $buf, 1); } while (ord($buf) == 0);
|
||||
|
||||
# second byte must be (0)
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 2 unless $cnt == 1 && ord($buf) == 0;
|
||||
push(@pre, ord($buf));
|
||||
# valid record starts with (1)
|
||||
$err = 1 unless $cnt == 1 && ord($buf) == 1;
|
||||
push(@pre, ord($buf));
|
||||
|
||||
# third byte is low byte of record length
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 3 unless $cnt == 1;
|
||||
$len = ord($buf);
|
||||
push(@pre, ord($buf));
|
||||
# second byte must be (0)
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 2 unless $cnt == 1 && ord($buf) == 0;
|
||||
push(@pre, ord($buf));
|
||||
|
||||
# fourth byte is high byte of record length
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 4 unless $cnt == 1;
|
||||
$len += ord($buf)<<8;
|
||||
push(@pre, ord($buf));
|
||||
# third byte is low byte of record length
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 3 unless $cnt == 1;
|
||||
$len = ord($buf);
|
||||
push(@pre, ord($buf));
|
||||
|
||||
# bytes five thru end-1 are data bytes
|
||||
$cnt = read($fh, $buf, $len-4);
|
||||
$err = 5 unless $cnt == $len-4 && $len >= 4;
|
||||
@dat = unpack("C*", $buf);
|
||||
# fourth byte is high byte of record length
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 4 unless $cnt == 1;
|
||||
$len += ord($buf)<<8;
|
||||
push(@pre, ord($buf));
|
||||
|
||||
# last byte is checksum
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 6 unless $cnt == 1;
|
||||
my $rcv = ord($buf);
|
||||
push(@suf, ord($buf));
|
||||
# bytes five thru end-1 are data bytes
|
||||
$cnt = read($fh, $buf, $len-4);
|
||||
$err = 5 unless $cnt == $len-4 && $len >= 4;
|
||||
@dat = unpack("C*", $buf);
|
||||
|
||||
# last byte is checksum
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 6 unless $cnt == 1;
|
||||
my $rcv = ord($buf);
|
||||
push(@suf, ord($buf));
|
||||
|
||||
# compare rcv'ed checksum vs exp'ed checksum
|
||||
my $exp = &chksum(0x01, $len>>0, $len>>8, @dat);
|
||||
warn sprintf("Warning: Bad checksum exp=0x%02X rcv=0x%02X", $exp, $rcv) unless $exp == $rcv;
|
||||
|
||||
} elsif ($objtype eq 'RSX11') {
|
||||
|
||||
# RSX-11 object file format consists of blocks of data in the following format.
|
||||
# Each block consists of:
|
||||
#
|
||||
# lo(length)
|
||||
# hi(length)
|
||||
# databyte1 ---
|
||||
# : |
|
||||
# : > 'length' bytes
|
||||
# : |
|
||||
# databyteN ---
|
||||
# zeroFill present if length is ODD; else not present
|
||||
#
|
||||
|
||||
# first byte is low byte of record length
|
||||
$cnt = read($fh, $buf, 1);
|
||||
# but exit OK if hit EOF
|
||||
return () if $cnt == 0;
|
||||
$err = 10 unless $cnt == 1;
|
||||
$len = ord($buf);
|
||||
push(@pre, ord($buf));
|
||||
|
||||
# second byte is high byte of record length
|
||||
$cnt = read($fh, $buf, 1);
|
||||
$err = 11 unless $cnt == 1;
|
||||
$len += ord($buf)<<8;
|
||||
push(@pre, ord($buf));
|
||||
|
||||
# bytes three thru end are data bytes
|
||||
$cnt = read($fh, $buf, $len);
|
||||
$err = 12 unless $cnt == $len && $len >= 0;
|
||||
@dat = unpack("C*", $buf);
|
||||
|
||||
# optional pad byte if length is odd
|
||||
$cnt = ($len & 1) ? read($fh, $buf, 1) : 2;
|
||||
$err = 13 unless $cnt == 1 && ord($buf) == 0 || $cnt == 2;
|
||||
|
||||
}
|
||||
|
||||
# output the record if debugging
|
||||
if ($DEBUG >= 2) {
|
||||
@ -691,11 +758,7 @@ sub read_rec ($) {
|
||||
}
|
||||
|
||||
# check we have a well formatted record
|
||||
warn sprintf("Warning: invalid object file record format (%d)", $err) if $err;
|
||||
|
||||
# compare rcv'ed checksum vs exp'ed checksum
|
||||
my $exp = &chksum(0x01, $len>>0, $len>>8, @dat);
|
||||
warn sprintf("Warning: Bad checksum exp=0x%02X rcv=0x%02X", $exp, $rcv) unless $exp == $rcv;
|
||||
warn sprintf("Warning: invalid %s object file record format (%d)", $objtype, $err) if $err;
|
||||
|
||||
# all is well, return the record
|
||||
return @dat;
|
||||
@ -820,7 +883,7 @@ sub parse_rec ($$$) {
|
||||
printf $LOG "..ENDGSD\n\n" if $DEBUG;
|
||||
|
||||
$program{END}{ADDRESS} = 0;
|
||||
foreach my $nam (sort({$psect{$a}{START} == $psect{$b}{START} ? $psect{$a}{LENGTH} <=> $psect{$b}{LENGTH} : $psect{$a}{START} <=> $psect{$b}{START}} keys(%psect))) {
|
||||
foreach my $nam (sort({$psect{$a}{START} == $psect{$b}{START} ? $psect{$a}{NUMBER} <=> $psect{$b}{NUMBER} : $psect{$a}{START} <=> $psect{$b}{START}} keys(%psect))) {
|
||||
my $start = $psect{$nam}{START};
|
||||
my $length = $psect{$nam}{LENGTH};
|
||||
my $end = $length ? $start + $length - 1 : $start;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user