X-Git-Url: http://git.subgeniuskitty.com/pdp11-bin2load/.git/blobdiff_plain/485c483c3876774c4499f01eb849043ac3ae505e..f63b1e81c8b4ca50e2d6570af584b87dd4c1e342:/bin2load.c diff --git a/bin2load.c b/bin2load.c index baf98a2..f28c6de 100644 --- a/bin2load.c +++ b/bin2load.c @@ -10,7 +10,7 @@ #include #include -#define VERSION 1 +#define VERSION 2 void print_usage( char ** argv ) @@ -91,25 +91,87 @@ main( int argc, char ** argv) * the starting PC. */ - uint16_t size = 6; + uint32_t checksum = 0; + uint32_t size = 6; + uint8_t data; - uint16_t header[] = {1,0,01000}; - fwrite(header,6,1,dst); + /* Write header for data block. */ + for (int i = 0; i < size; i++) { + switch (i) { + case 0: data = 0001; break; + case 1: data = 0000; break; + case 2: data = 0000; break; /* Size will be populated later */ + case 3: data = 0000; break; /* Size will be populated later */ + case 4: data = address & 0xff; break; + case 5: data = (address >> 8) & 0xff; break; + } + if (!fwrite(&data, 1, 1, dst)) { + fprintf(stderr, "ERROR: Failed to write block header.\n"); + exit(EXIT_FAILURE); + } + checksum += data; + } - 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); + /* Write contents of data block. */ + while (1) { + if (fread(&data, 1, 1, src)) { + if (!fwrite(&data, 1, 1, dst)) { + fprintf(stderr, "ERROR: Failed to write block data.\n"); + exit(EXIT_FAILURE); + } + size++; + checksum += data; + } else { + break; + } + } + fclose(src); - uint16_t footer[] = {0,1,6,01000,0}; - fwrite(footer,10,1,dst); + /* Now that block size is known, update block header. */ + if (fseek(dst, 2, SEEK_SET)) { + fprintf(stderr, "ERROR: Failed seek back to header of data block.\n"); + exit(EXIT_FAILURE); + } + for (int i = 0; i < 2; i++) { + switch (i) { + case 0: data = size & 0xff; break; + case 1: data = (size >> 8) & 0xff; break; + } + if (!fwrite(&data, 1, 1, dst)) { + fprintf(stderr, "ERROR: Failed to write block size into header.\n"); + exit(EXIT_FAILURE); + } + checksum += data; // Header is included in checksum. + } + if (fseek(dst, 0, SEEK_END)) { + fprintf(stderr, "ERROR: Failed seek to end of data block.\n"); + exit(EXIT_FAILURE); + } - fseek(dst,2,SEEK_SET); - fwrite(&size,2,1,dst); + /* Write checksum for data block. */ + checksum = (~checksum) + 1; + data = checksum & 0xff; + if (!fwrite(&data, 1, 1, dst)) { + fprintf(stderr, "ERROR: Failed to write checksum.\n"); + exit(EXIT_FAILURE); + } - fclose(src); + /* Write empty block to indicate end-of-tape. */ + for (int i = 0; i < 8; i++) { + switch (i) { + case 0: data = 0001; break; + case 1: data = 0000; break; + case 2: data = 0006; break; + case 3: data = 0000; break; + case 4: data = address & 0xff; break; + case 5: data = (address >> 8) & 0xff; break; + case 6: data = 0000; break; + case 7: data = 0000; break; + } + if (!fwrite(&data, 1, 1, dst)) { + fprintf(stderr, "ERROR: Failed to write end-of-tape block.\n"); + exit(EXIT_FAILURE); + } + } fclose(dst); }