/* TAPSPLIT: Split a .TAP file into several +3DOS files
    Copyright (C) 1999,2000  John Elliott

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdio.h>
#include <stdlib.h>

typedef unsigned char byte;

byte header[18];
FILE *fpi;
unsigned int blklen;
byte blktype;
byte p3hdr[128];
byte p3sig[] = "PLUS3DOS\032\001";
int uctr = 1;
int nctr = 1;

char lfname[100];

void x_header(void)
{
	if (fread(header, 1, 18, fpi) < 18)	/* 17 data & 1 checksum */
	{
		fclose(fpi);
		fprintf(stderr, "Unexpected EOF\n");
		exit(1);
	}
	sprintf(lfname, "%-10.10s", header + 1); 
	lfname[10] = 0;

	memset(p3hdr, 0, sizeof(p3hdr));
	memcpy(p3hdr, p3sig, sizeof(p3sig));

	p3hdr[15] = header[0];
	memcpy(p3hdr + 16, header + 11, 6);
}

void x_data(void)
{
	unsigned long blk2 = blklen + 0x7E;	/* +80h for +3dos header */
	FILE *fpo;				/* -2 for type & checksum*/
	int n;
	byte csum;
	
	p3hdr[11] =  blk2        & 0xFF;
	p3hdr[12] = (blk2 >>  8) & 0xFF;	
	p3hdr[13] = (blk2 >> 16) & 0xFF;
	p3hdr[14] = 0;

	for (n = csum = 0; n < 127; n++) csum += p3hdr[n];
	p3hdr[n] = csum;

	if (lfname[0])
	{
		if (lfname[0] < 32) sprintf(lfname, "unnamed.%d", nctr++);
			
		do
		{
			fpo = fopen(lfname, "r");
			if (fpo == NULL) break;
			strcat(lfname, ".1");
			fclose(fpo);
		} while(1);

                printf("Writing %s\n", lfname);

		fpo = fopen(lfname, "wb");
		fwrite(p3hdr, 1, 128, fpo);
	}
	else
	{
		sprintf(lfname, "Block%d", uctr++);
		printf("Writing headerless %s\n", lfname);
		fpo = fopen(lfname, "wb");
	}
	while (blklen > 2)	/* 2 extra bytes counted in blklen - */
	{			/* block type & checksum */
		byte b = fgetc(fpi);
		fputc(b, fpo);
		--blklen;
	}
	fclose(fpo);
	fgetc(fpi);	/* Checksum */
	lfname[0] = 0;
}


int main(int argc, char **argv)
{
	if (argc < 2) fpi = stdin;
	else          fpi = fopen(argv[1], "rb");

	if (!fpi) 
	{
		fprintf(stderr, "Can't open %s\n", argv[1]);
		exit(1);
	}
	lfname[0] = 0;

	/* Check for a +3DOS header on the tapefile, and if there is
         * then go past it */
	if (fread(p3hdr, 1, 128, fpi) == 128)
	{
		byte cksum = 0;
		int n;

		for (n = 0; n < 127; n++) cksum += p3hdr[n];
		if ((p3hdr[n] != cksum) || memcmp(p3hdr, p3sig, sizeof(p3sig)))
			fseek(fpi, 0L, SEEK_SET);
	
	}
	else fseek(fpi, 0L, SEEK_SET);

	while (!feof(fpi))
	{
		blklen = fgetc(fpi);          if (feof(fpi)) break;
		blklen += 256 * fgetc(fpi);   if (feof(fpi)) break;
		blktype = fgetc(fpi);         if (feof(fpi)) break;

		if (blklen == 0x13 && blktype == 0) x_header();
		else                                x_data();
	}
	if (fpi != stdin) fclose(fpi);
	return 0;
}

