
/*****************************************************************************
 *								 sload.c     *
 *****************************************************************************
 * DESCRIPTION: This program loads data from the spectrum over the RS232 link*
 *									     *
 * REVISIONS:   18 AUG 91 - HDG - Initial setup.			     *
 *****************************************************************************/

#include		<stdio.h>
#include		<signal.h>
#include		<string.h>
#include		"ibmcom.h"
#include		"patch.h"

STARTPATCH
int PORT=1;
ENDPATCH

#define VARNAME(i)	((i & 0x1f) + 0x60)
#define SPEED   9600

union header_u {
	char in[9];
	struct {
		char type;
		unsigned int  length;
		unsigned int  start;
		char var;
		char res1;
		int  line;
	} header;
} h;

FILE * sid;

void catch();

get_key()
{
	int		 c;
	if ((c = getch())!=0) return c;
	else return getch() + 256;
}

main(argc,argv) 
int argc;
char *argv[];
{
	int status;
	unsigned int i,js;
	int f_header = 1;

	SETUP;

	if(((argc != 2) && (argc != 3)) ||
	  ((argc==3) && (strcmp(argv[1],"-h"))) ||
	  ((argc==2) && !(strcmp(argv[1],"-h"))))
	{
		fprintf(stderr,"Usage: sload [-h] <file>\n");
		fprintf(stderr,"       -h: don't store header in destination file\n");
		return 1;
	}

	if ((status = com_install(PORT))!=0)
	{
		printf("com_install() error: %d\n", status);
		return 1;
	}

	signal(SIGINT,catch);

	if(argc==2)
		sid = fopen(argv[1],"wb");
	else
	{
		sid = fopen(argv[2],"wb");
		f_header = 0;
	}
	if(sid == NULL)
	{
		if(argc==2)
			perror(argv[1]);
		else
			perror(argv[2]);
		return 1;
	}
	
	com_set_speed(SPEED);
	com_set_parity(COM_NONE, 1);
	com_raise_dtr();
	if(argc==2)
		printf("Load from ZX Spectrum to file %s -- ",argv[1]);
	else
		printf("Load from ZX Spectrum to file %s -- ",argv[2]);
	printf("Stop with ALT-X\n\n");
	
	i=0;
	js=0;
	while(i<9)
	{
		if (kbhit())
		{
			status = get_key();
			if (status == 301 /* Alt-X */) 
			{
				fclose(sid);
				com_deinstall();
				return 1;
			}
		}
		if ((status = com_rx()) != -1)
		{
			if(f_header == 1) fputc((char) status,sid);
			h.in[i] = (char) status;
			/* this fixes the failure that would occur if there */
			/* is a junk character left in the UART (not 100%)  */
			/* "js" will prevent a second call of the fix       */
			if((js==0) && (i==0) && ((unsigned int) h.in[0] >= 4))
			{	
				js=1;	
			}	
			else
				i++;
		}
	}

	switch(h.header.type)
	{
	case 0:	if(h.header.line != -1)
		{
			printf("Basic program, autostart at line %u\n",
				h.header.line);
		}
		else
		{
			printf("Basic program\n");
		}
		break;
	case 1: 	
		printf("Numeric variabele %c()\n",VARNAME(h.header.var));
		break;
	case 2: 	
		printf("String variabele %c$()\n",VARNAME(h.header.var));
		break;
	case 3: 
		printf("Code - start %u - length %u\n",
			h.header.start,h.header.length);
		break;	
	default:
		printf("Unknown header type %u\n",h.header.type);
		break;
	}		

	i = 0;
	while (i < h.header.length) 
	{
		if (kbhit()) 
		{
			status = get_key();
			if (status == 301 /* Alt-X */) 
			{
				fclose(sid);
				com_deinstall();
				return 1;
			}
		}
		if ((status = com_rx()) != -1)
		{
			fputc((char) status,sid);
			i++;
		}
	}
	fclose(sid);
	com_deinstall();
	
	return 0;
}

void catch()
{
	printf("\nBREAK - program terminated\n");
	fclose(sid);
	com_deinstall();
	exit(1);
}

void setup()
{
	printf("Setup\n\n");
	printf("Port    Address    IRQ\n");
	printf("COM1      3f8       4\n");
	printf("COM2      2f8       3\n");
	printf("COM3      3e8       4\n");
	printf("COM4      2e8       3\n\n");
	printf("Attention if you want to use COM3 or COM4:\n\n");
	printf("COM1 and COM3 cannot be used simultaneously\n");
	printf("COM2 and COM4 cannot be used simultaneously\n");
	printf("If your mouse is connected to COM1 you should not use COM3\n");
	printf("If your mouse is connected to COM2 you should not use COM4\n\n");
	printf("If your modem is connected to COM1 you can use COM3 if this program\n");
	printf("and the communication program are not running at the same time\n\n");
	printf("If your modem is connected to COM2 you can use COM4 if this program\n");
	printf("and the communication program are not running at the same time\n\n");
	printf("Give comport number: ");
	fflush(stdout);
	scanf("%d",&PORT);
	printf("\n\nSetup finished\n\n");
}
