
/*****************************************************************************
 *								   puta.c    *
 *****************************************************************************
 * DESCRIPTION: This program sends data to the spectrum over the RS232 link  *
 *									     *
 * REVISIONS:   18 AUG 91 - HDG - Initial setup.			     *
 *****************************************************************************/

#include		<stdio.h>
#include		<string.h>
#include		<signal.h>
#include		"ibmcom.h"
#include		"patch.h"

STARTPATCH
int PORT=1;
ENDPATCH

#define SPEED   9600

extern int tx_chars;

char buf[32768];
int  bufp;

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;
	int i;
	int imgp;

	SETUP;

	if(argc != 2)
	{
		fprintf(stderr,"Usage: puta <in-file>\n");
		return 1;
	}

	convert(argv[1]);
	
	if ((status = com_install(PORT))!=0)
	{
		fprintf(stderr,"com_install() error: %d\n", status);
		return 1;
	}

	signal(SIGINT, catch);

	imgp=0;
	com_set_speed(SPEED);
	com_set_parity(COM_NONE, 1);
	com_raise_dtr();
	printf("file to RS232 -- ",argv[1]);
	printf("Stop with ALT-X\n\n");

	while (1)
	{
		if (kbhit()) 
		{
			status = get_key();
			if (status == 301 /* Alt-X */) 
			{
				com_deinstall();
				return 1;
			}
		}
		if(imgp != bufp)
		{
			com_tx(buf[imgp]);
			imgp++;
		}
		else
			break;
	}
	/* wait until all characters are send... */
	while(tx_chars != 0);
	
	com_deinstall();
	
	return 0;
}

void catch()
{
	printf("\nBREAK - program terminated\n");
	com_deinstall();
	exit(1);
}

union header_u {
	char in[9];
	struct {
		char type;
		unsigned int  length;
		unsigned int  start;
		char var;
		char res1;
		int  line;
	} header;
} h;

union line_u {
	char line[256];
	struct {
		char label[8];
		char opcode[8];
		char opper[240];
	} split;
} l;

convert(name)
char *name;
{
	FILE *sid;
	char *p;
	int  i;
	int  regel_nummer;
	int  line_nr;
	int  end_seen;

	sid=fopen(name,"r");
	if(sid == NULL)
	{
		perror(name);
		exit(1);
	}

	regel_nummer=1;
	line_nr=0;
	end_seen=0;

	bufp=sizeof(h);
	buf[bufp]=0x0d;
	bufp++;

	while((fgets(l.line,255,sid))!=NULL)
	{
		line_nr++;

		p=strchr(l.line,'\n');
		if(p != NULL) *p='\0';

		i=regel_nummer/100;
		i=16*(i/10)+i%10;
		buf[bufp]=(char) i;
		bufp++;

		i=regel_nummer%100;
		i=16*(i/10)+i%10;
		buf[bufp]=(char) i;
		bufp++;

		/* ensure that the opcode and opperand fields are filled */
		if(strlen(l.line)<254)
			strcat(l.line,"\t\t\t");

		untab(l.line,256);

		if(l.split.label[5]!=' ')
		{
			fprintf(stderr,"Label too long at line %d\n",line_nr);
			fprintf(stderr,"line: [%s]\n",l.line);
			exit(1);
		}
		
		if(l.split.opcode[4]!=' ')
		{
			fprintf(stderr,"Opcode error at line %d\n",line_nr);
			fprintf(stderr,"line: [%s]\n",l.line);
			exit(1);
		}
		
		if(strtok(l.line," ")==NULL)
		{
			fprintf(stderr,"Empty line detected at line %d\n",line_nr);
			exit(1);
		}
		
		l.split.label[5]='\0';
		l.split.opcode[4]='\0';
		
		putbuf(" ");
		if(strtok(l.split.label," ")!=NULL)
		{
			for(i=0;i<strlen(l.split.label);i++)
				l.split.label[i]=toupper(l.split.label[i]);
			putbuf(l.split.label);
		}
		putbuf(" ");
		if(strtok(l.split.opcode," ")!=NULL)
		{
			for(i=0;i<strlen(l.split.opcode);i++)
				l.split.opcode[i]=toupper(l.split.opcode[i]);
			putbuf(l.split.opcode);
		}	
		putbuf(" ");

		if((p=strchr(l.split.opper,'"'))!=NULL)
		{
			p++;
			p=strchr(p,'"');
			if(p == NULL)
			{
				fprintf(stderr,"Unmatched \" at line %d\n",line_nr);
				fprintf(stderr,"line: [%s]\n",l.split.opper);
				exit(1);
			}
			p++;
			*p='\0';
			putbuf(l.split.opper);
		}
		else
		{
			if(strtok(l.split.opper," ")!=NULL)
			{
				for(i=0;i<strlen(l.split.opper);i++)
					l.split.opper[i]=toupper(l.split.opper[i]);
				putbuf(l.split.opper);
			}	
		}
		
		buf[bufp]='\r';
		bufp++;
		regel_nummer=regel_nummer+1;

		if(!strcmp(l.split.opcode,"END"))
		{
			end_seen=1;
			break;
		}
	}
	buf[bufp]=0xff;
	bufp++;

	fclose(sid);

	if(end_seen == 0)
	{
		fprintf(stderr,"END missing at end of the file!\n");
		exit(1);
	}

	h.header.type   = 0x03;                         /* CODE block */
	h.header.length = bufp - sizeof(h);             /* lenght of CODE */
							/* start of CODE */
	h.header.start  = 0xdd18 - (unsigned int) bufp - sizeof(h); 
	
	h.header.var    = 0x01;                         /* ???? */
	h.header.res1   = 0x80;                         /* ???? */
	h.header.line   = 0xde98;                       /* ???? */

	for (i=0; i<sizeof(h); i++)
	{
		buf[i]=h.in[i];
	}

	printf("File converted succesfully\n");
}

untab(p,size)
char p[];
{
	int l,i,j,k,d;

	l=strlen(p);

	for(i=0; i<=l; i++)
	{
		if(p[i]=='\t')
		{
			d=7-(i%8);
			l=l+d;
			if(l>=size) l=size-1;
			for(j=l-d,k=l; j>=i; j--,k--)
				p[k]=p[j];
			for(j=i;j <= i+d;j++)
				p[j]=' ';
		}
		if(p[i]=='\0')
			break;
	}
	p[size-1]='\0';
}

putbuf(p)
char *p;
{
	while(*p != '\0')
	{
		buf[bufp]=*p;
		bufp++;
		p++;
	}
}

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");
}
