From 06f04fb66784a047c534c58d01f7c0c7ba70cab5 Mon Sep 17 00:00:00 2001 From: Leo C Date: Mon, 17 Jun 2019 23:12:03 +0200 Subject: [PATCH] New utility prl2offz: Make .com from .prl and convert prl reloc bitmap to compressed list of offsets --- .gitignore | 1 + prl2offz.c | 208 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 prl2offz.c diff --git a/.gitignore b/.gitignore index a6a06c2..8d65030 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ autorevision.cache version.inc config.inc ddt180.180 +prl2offz diff --git a/prl2offz.c b/prl2offz.c new file mode 100644 index 0000000..7e0a6bf --- /dev/null +++ b/prl2offz.c @@ -0,0 +1,208 @@ +/* + * (C) Copyright 2019 Leo C. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include +#include +#include +#include +#include +#include + +char *progname; +FILE *prlfile; +char *prlfilename; +FILE *outfile; +char *outfilename; +uint16_t progsize; + +void die(int status, const char *format, ...) +{ + va_list arg; + + fflush(stdout); + va_start(arg, format); + fprintf(stderr, "%s: ", progname); + vfprintf(stderr, format, arg); + va_end(arg); + + exit(status); +} + +static +int get_bit(void) +{ + static unsigned bitpos; + static int bytebuf; + int retval; + + if (bitpos == progsize) { + return -2; + } + if (bitpos%8 == 0) { + bytebuf = fgetc(prlfile); + if (bytebuf == EOF) { + return -1; + } + } + retval = (bytebuf & 0x80) !=0; + bytebuf <<= 1; + bitpos++; + + return retval; +} + +static +int get_nr_of_bits(void) +{ + int bits = 0; + int bit; + + do { + bits++; + } while ((bit = get_bit()) == 0); + + if (bit >= 0) + return bits; + + if (bit == -2) + return 0; + + return bit; +} + +static +void put_bits(int width, unsigned val) +{ + static unsigned bytebuf; + static int bitcount = 8; + + while (width--) { + bytebuf <<= 1; + if (val & (1 << width)) + bytebuf += 1; + bitcount--; + if (bitcount == 0) { + if (fputc(bytebuf, outfile) == EOF) + die(1,"Error writing output file %s: %s\n", + outfilename, strerror(errno)); + bitcount = 8; + } + } +} + +static +void fill_sector(void) +{ + long curpos; + + if ((curpos = ftell(outfile)) == -1) + die(1,"File error %s: %s\n", outfilename, strerror(errno)); + + for (int i = 0; i < 128 - curpos % 128; i++) + if (fputc(0, outfile) == EOF) + die(1,"Error writing output file %s: %s\n", + outfilename, strerror(errno)); + + return; +} + + +static +int process_prlfile(void) +{ + fgetc(prlfile); + progsize = fgetc(prlfile) + (fgetc(prlfile) << 8); + + /* skip header */ + fseek(prlfile, 0x100, SEEK_SET); + + for (unsigned i = 0; i < progsize; i++) { + int c = fgetc(prlfile); + if (c == EOF) + die(1,"Unexpected end of prl file %s\n", prlfilename); + if (fputc(c, outfile) == EOF) + die(1,"Error writing output file %s: %s\n", + outfilename, strerror(errno)); + } + + + int bits; + while ((bits = get_nr_of_bits()) >= 2) { + unsigned off = bits - 2; + if (off < (1<<2)) { + put_bits(0 + 2 + 1, off); + } else if (off < (1<<4) + (1<<2)) { + off -= (1<<2); + off += (1<<(4+1)); + put_bits(1 + 4 + 1, off); + } else if (off < (1<<8) + (1<<4) + (1<<2)) { + off -= (1<<4) + (1<<2); + off += (1<<(8+1)); + off += (1<<(8+2)); + put_bits(2 + 8 + 1, off); + } else { + off -= (1<<8) + (1<<4) + (1<<2); + off += (1<<(16+1)); + off += (1<<(16+2)); + off += (1<<(16+3)); + put_bits(3 + 16 + 1, off); + } + } + + if (bits == 1) + die(1,"Bitmap error"); + + if (bits < 0) + die(1,"Error while reading bitmap from prl file %s\n", prlfilename); + + /* end mark */ + put_bits(4, 0xf); + + /* flush output bit buffer */ + put_bits(7, 0); + + fill_sector(); + + return 0; +} + +static +void usage(void) +{ + fprintf(stderr, +"Usage:\n" +"%s prlfile outfile\n", progname); + +} + +int main(int argc, char **argv) +{ + progname = argv[0]; + + if (argc != 3) { + usage(); + die(1, ""); + } + + prlfilename = argv[1]; + prlfile=fopen(prlfilename,"rb"); + if (prlfile==NULL) + die(1,"Cannot open prl file %s: %s\n", + prlfilename, strerror(errno)); + + outfilename = argv[2]; + outfile=fopen(outfilename,"wb"); + if (outfile==NULL) + die(1,"Cannot open output file %s: %s\n", + outfilename, strerror(errno)); + + process_prlfile(); + fclose(prlfile); + fclose(outfile); + + return 0; +} -- 2.39.2