#include <stdio.h>
#include <stdlib.h>

unsigned *buf;

main(int argc, char *argv[])
{
    FILE *fpi, *fpo;
    int i, nc, n;
    long h, c;

    if(argc < 3)
    {
        printf("Syntax: BIN2ASM <infile> <outfile>\n");
        return 1;
    }

    if((buf = malloc(65280)) == NULL)
    {
        printf("Out of memory\n");
        return 3;
    }
    
    if((fpi = fopen(argv[1], "rb")) == NULL)
    {
        printf("File not found: %s\n", argv[1]);
        return 2;
    }
    fpo = fopen(argv[2], "wt");

    fseek(fpi, 0, SEEK_END);
    h = ftell(fpi);
    if(h > 65280) h = 65280;
    fseek(fpi, 0, SEEK_SET);
    fread(buf, h, 1, fpi);
    fclose(fpi);
    
    fprintf(fpo, "Data dw ", h);
    nc = 0; i = 0;

    while(i < h / 2)
    {
        c = buf[i];
        
        if(i < (h - 4) / 2 && c == buf[i + 1] && c == buf[i + 2] &&
           ((i < (h - 6) / 2 && c == buf[i + 3]) ||
            (c > 99 && c < 65527)) &&
           ((i < (h - 8) / 2 && c == buf[i + 4]) || c > 9))
        {
            n = 0;
            while(c == buf[i + n] && i + n < h / 2) n++;
            if(c < 64537)
                nc += fprintf(fpo, "%u dup(%u)", n, c);
            else nc += fprintf(fpo, "%u dup(%d)", n, c);
            i += n;
        } else {
            if(c < 64537)
                nc += fprintf(fpo, "%u", c);
            else nc += fprintf(fpo, "%d", c);
            i++;
        }
                  
        if(i < h / 2)
        {  
            if(nc >= 60)
            {    
                nc = 0;
                fprintf(fpo, "\n     dw ");
            } else {
                nc++;
                fprintf(fpo, ",");
            }
        }
    }

    if(h & 1)
    {
        c = buf[(h + 1) / 2];
        c >>= 8;
        fprintf(fpo, "\n     db %u", c);
    }
    
    fclose(fpo);
    return 0;
}
