Added misc file 'custom_bitstream.c' that creates paper tape with repeating memory...
[pdp11-bin2load] / bin2load.c
/*
* © 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
* See LICENSE.txt file for copyright and license details.
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#define VERSION 1
void
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"
, VERSION, argv[0]
);
}
int
main( int argc, char ** argv)
{
int c;
FILE * src = NULL;
FILE * dst = NULL;
uint16_t address = 01000; /* Default address to load tape contents. */
while ((c = getopt(argc, argv, "i:o:a:h")) != -1) {
switch (c) {
case 'i':
if ((src = fopen(optarg, "r")) == NULL ) {
fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
}
break;
case 'o':
if ((dst = fopen(optarg, "w+")) == NULL ) {
fprintf(stderr, "ERROR: %s: %s\n", optarg, strerror(errno));
}
break;
case 'a':
address = (uint16_t) strtol(optarg, NULL, 0);
break;
case 'h':
print_usage(argv);
exit(EXIT_FAILURE);
break;
default:
break;
}
}
if (src == NULL || dst == NULL) {
print_usage(argv);
exit(EXIT_FAILURE);
}
printf("Paper tape will load at address 0%o.\n", address);
/*
* Paper tape format(bytes, not words):
* 01
* 00
* Low byte of packet length (binary length + 6 for header)
* High byte of packet length
* Low byte of address to load binary data at
* High byte of address
* DataBegin
* |
* |
* DataEnd
* Checksum
*
* I am unsure of the checksum format and need to check the SIMH source.
* In the meantime a zero checksum still functions, albeit with a warning.
*/
uint16_t size = 6;
uint16_t header[] = {1,0,01000};
fwrite(header,6,1,dst);
uint8_t byte;
int read;
do {
read = fread(&byte,1,1,src);
if(read == 1) fwrite(&byte,1,1,dst);
size += read;
} while (read == 1);
uint16_t footer[] = {0,1,6,01000,0};
fwrite(footer,10,1,dst);
fseek(dst,2,SEEK_SET);
fwrite(&size,2,1,dst);
fclose(src);
fclose(dst);
}