/* This is a simple program to deinterleave and byte swap a Classic II
 * image so the resulting output is suitable for programming into 27c400's
 * to replace the system ROM.
 *
 * Rob Braun <bbraun@synack.net> 2016
 */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <getopt.h>

ssize_t readwriteone(int infd, int outfd) {
	char c;
	ssize_t r;

	r = read(infd, &c, 1);
	if (r == 1) {
		write(outfd, &c, 1);
	}

	return r;
}

int main(int argc, char *argv[]) {
	int infd;
	int ofd1;
	int ofd2;
	int ofd3;
	int ofd4;
	uint16_t w;
	int loptind = 0;
	char c;
	int twoorfour = 2;
	struct option o[] = {
		{"tworom", 0, 0, '2'},
		{"fourrom", 0, 0, '4'},
		{0,0,0,0}
	};

	while( (c = getopt_long(argc, argv, "24", o, &loptind)) != -1 ) {
		switch(c) {
		case '2':
			twoorfour = 2;
			break;
		case '4':
			twoorfour = 4;
			break;
		}
	}
	argc -= optind;
	argv += optind;

	infd = open(argv[0], O_RDONLY);
	if(infd == -1) {
		perror("open infd");
		exit(1);
	}

	if (twoorfour == 2) {
		ofd1 = open("341-0261-mod.bin", O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if(ofd1 == -1) {
			perror("open ofd1");
			exit(2);
		}
		ofd2 = open("341-0257-mod.bin", O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if(ofd2 == -1) {
			perror("open ofd2");
			exit(3);
		}
	} else {
		ofd1 = open("341-0867-mod.bin", O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if(ofd1 == -1) {
			perror("open ofd1");
			exit(2);
		}
		ofd2 = open("341-0866-mod.bin", O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if(ofd2 == -1) {
			perror("open ofd2");
			exit(3);
		}
		ofd3 = open("341-0865-mod.bin", O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if(ofd3 == -1) {
			perror("open ofd3");
			exit(2);
		}
		ofd4 = open("341-0864-mod.bin", O_CREAT | O_TRUNC | O_WRONLY, 0644);
		if(ofd4 == -1) {
			perror("open ofd4");
			exit(3);
		}
	}

	while(1) {
		ssize_t r;

		if (twoorfour == 2) {
			r = read(infd, &w, 2);
			if(r < 0) {
				perror("read");
				exit(4);
			}
			if(r < 2) {
				break;
			}
	
			w = htons(w);
			write(ofd1, &w, 2);
	
			r = read(infd, &w, 2);
			if(r < 0) {
				perror("read");
				exit(4);
			}
			if(r < 2) {
				break;
			}

			w = htons(w);
			write(ofd2, &w, 2);
		} else {
			r = readwriteone(infd, ofd1);
			if (r < 0) {
				perror("read 1");
				exit(1);
			}
			if (r < 1) break;

			r = readwriteone(infd, ofd2);
			if (r < 0) {
				perror("read 2");
				exit(1);
			}
			if (r < 1) break;

			r = readwriteone(infd, ofd3);
			if (r < 0) {
				perror("read 3");
				exit(1);
			}
			if (r < 1) break;

			r = readwriteone(infd, ofd4);
			if (r < 0) {
				perror("read 4");
				exit(1);
			}
			if (r < 1) break;

		}
	}

	close(ofd1);
	close(ofd2);
	close(infd);
}
