* © 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
* See LICENSE.txt file for copyright and license details.
print_usage( char ** argv
)
printf( "bin2load v%d (www.subgeniuskitty.com)\n"
"Usage: %s i <file> -o <file> [-a <address>]\n"
" -i <file> Binary file to be written to tape.\n"
" For example, binary executable from 'pdp11-aout-objdump'.\n"
" -o <file> New paper tape image for use with SIMH.\n"
" -a <address> Address on PDP-11 at which to load paper tape contents.\n"
main( int argc
, char ** argv
)
uint16_t address
= 01000; /* Default address to load tape contents. */
while ((c
= getopt(argc
, argv
, "i:o:a:h")) != -1) {
if ((src
= fopen(optarg
, "r")) == NULL
) {
fprintf(stderr
, "ERROR: %s: %s\n", optarg
, strerror(errno
));
if ((dst
= fopen(optarg
, "w+")) == NULL
) {
fprintf(stderr
, "ERROR: %s: %s\n", optarg
, strerror(errno
));
address
= (uint16_t) strtol(optarg
, NULL
, 0);
if (src
== NULL
|| dst
== NULL
) {
printf("Paper tape will load at address 0%o.\n", address
);
* SIMH Binary Loader Format
* Loader format consists of blocks, optionally preceded, separated, and
* followed by zeroes. Each block consists of the following entries. Note
* that all entries are one byte.
* Low byte of block length (data byte count + 6 for header, excludes checksum)
* High byte of block length
* Low byte of load address
* High byte of load address
* The 8-bit checksum for a block is the twos-complement of the lower eight
* sum bits for all six header bytes and all data bytes.
* If the block length is exactly six bytes (i.e. only header, no data),
* then the block marks the end-of-tape. The checksum should be zero. If
* the load address of this final block is not 000001, then it is used as
uint16_t header
[] = {1,0,01000};
read
= fread(&byte
,1,1,src
);
if(read
== 1) fwrite(&byte
,1,1,dst
);
uint16_t footer
[] = {0,1,6,01000,0};