/*	PiIni.c - Edit 1

	LoadICE Version 4
	Copyright (C) 1990-99 Grammar Engine, Inc.
	All rights reserved
	
	NOTICE:  This software source is a licensed copy of Grammar Engine's
	property.  It is supplied to you as part of support and maintenance
	of some Grammar Engine products that you may have purchased.  Use of
	this software is strictly limited to use with such products.  Any
	other use constitutes a violation of this license to you.
*/
#ifdef UNIX
#include <stdio.h>
long addialog;
void pisetup(void)
	{
	printf("\nFeature is not implemented under UNIX\n");
	}
#else
#ifdef WIN32
#include <windows.h>
#endif
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifdef UNIX
#include <curses.h>
#else
#include <conio.h>
#include <dos.h>
#endif
#include "piconfig.h"
#include "pierror.h"
#include "piscript.h"
#include "pistruct.h"
#include "pidriver.h"
#include "pisetup.h"
#include "pidata.h"

extern void (*psynf[])(void);
extern void pcinit(void);
void piuser(void);
void piwrini(void);
void pilod(void);
void piemu(void);
void pifile(long map);
long pimenu(char **menu, long index);

extern unsigned long maps[];
extern unsigned long mape[];
extern long mapi;

long xmm=0, xhm=0, xcp=0, xpp=0, xbr=5, xrm=0, xrz=0;
long xbo=0, xfm=0, xft=0, xfo=0, xfi=0, xxm=0, xwz=0;
long xfro=0, xfwz=0, xsz=0, xfd=0, xal=0, xab=0, xad=0;
long yabr=0, xabr=0, xabk=0, xaxp=0, xaisp=0;
long addialog = 0;
long local, killkey = 0;
char locals[PIC_FN];
char locals2[PIC_FN];
char locals3[PIC_FN];
char locals31[PIC_FN];
char locals4[PIC_FN];
char locals5[PIC_FN];
char locals6[PIC_FN];
long addai = 0;
long addaic = 0;
long addburst = 0;
long addirt = 0;
long addfill = 0;

/* something broke in WINDOWS 98 */

char *pigets(char *buf)
{
	char c;

	c = getch();
	ungetch(c);
	return(gets(buf));
}

/* `pisetup` - help the user setup his PromICE and stuff */

void pisetup(void)
{
	printf("\n\n\t\tWelcome to PromICE/LoadICE Setup\n");
	printf("\n Use the <UP ARROW> and <DOWN AARROW> keys to scroll through the choices");
	printf("\n\tThen Use the <ENTER> key to make your selection");
	printf("\n\tUse <ESC> key to exit without making a selection");

	local = 0;
	locals[0] = 0;
	locals2[0] = 0;
	locals3[0] = 0;
	locals31[0] = 0;
	locals4[0] = 0;
	locals5[0] = 0;
	locals6[0] = 0;
	addialog = 0;
	do
	{
		if (kbhit()) (void)getch();
		piuser();
		if (pxerror)
			pierror();
		if (killkey) break;
		if (++xmm == 8) xmm = 0;
	} while (!local);
}

/* `piuser` - help the user do setup */

void piuser(void)
{
	long i,ybr,local1,local3,local4;
	unsigned char lstr[PIC_FN];
	char *file = 0;
	char *uinp = 0;
	long foffset = 0;
	long roffset = 0;
	long fwordsize = 0;
	long fix = 0;
	long tflags;

	printf("\n\n\nGENERAL-SETUP:\t\t");
	xmm = pimenu(pxmm,xmm);
	if (killkey) return;
	switch (xmm)
	{
	case 0:
	local1 = 0;
		while (!local1)
		{
			if (pxerror) pierror();
			printf("\n\nHost<->PromICE:\t\t");
			xhm = pimenu(pxhm,xhm);
			if (killkey) break;
			switch (xhm)
			{
			case 0:
				printf("\nSerialLink:\t\t");
				xcp = pimenu(pxgcp,xcp);
				break;
			case 1:
				printf("\nParallelLink:\t\t");
				xpp = pimenu(pxgpp,xpp);
				break;
			case 2:
				printf("\nSerialLink:\t\t");
				xcp = pimenu(pxgcp,xcp);
				printf("\nParallelLink:\t\t");
				xpp = pimenu(pxgpp,xpp);
				break;
			case 3:
			case 4:
				printf("\n\nEthernetHostName: ");
				pigets(lstr);
				break;
			case 5:
				pcinit();
				break;
			case 6:
				local1++;
				break;
			default:
				pxerror = PGE_BAA;
				break;
			}
			if (killkey) continue;
			if (xhm > 4) break;
			if (!pxerror)
			{
				if (xhm == 0 || xhm == 2)
				{
					printf("\nSerialBaudRate:\t\t");
					xbr = pimenu(pxgbr,xbr);
					if (killkey) continue;
					switch (xbr)
					{
					case 0:
						ybr = 1200;
						break;
					case 1:
						ybr = 2400;
						break;
					case 2:
						ybr = 4800;
						break;
					case 3:
						ybr = 9600;
						break;
					case 4:
						ybr = 19200;
						break;
					case 5:
						ybr = 57600;
						break;
					default:
						pxerror = PGE_BAA;
						break;
					}
				sprintf(pxuline,"baud %d",ybr);
				pisyn(pxuline,pcmfsyn,psynf);
				}
			}
			if (!pxerror)
				switch (xhm)
				{
				case 0:
					sprintf(pxuline,"output COM%d",xcp+1);
					pisyn(pxuline,pcmfsyn,psynf);
					break;
				case 1:
					sprintf(pxuline,"pponly LPT%d",xpp+1);
					pisyn(pxuline,pcmfsyn,psynf);
					break;
				case 2:
					sprintf(pxuline,"output COM%d",xcp+1);
					pisyn(pxuline,pcmfsyn,psynf);
					sprintf(pxuline,"ppbus LPT%d",xpp+1);
					pisyn(pxuline,pcmfsyn,psynf);
					break;
				case 3:
					sprintf(pxuline,"fastport %s",lstr);
					pisyn(pxuline,pcmfsyn,psynf);
					break;
				case 4:
					sprintf(pxuline,"fastport %s",lstr);
					pisyn(pxuline,pcmfsyn,psynf);
					sprintf(pxuline,"ppbus null");
					pisyn(pxuline,pcmfsyn,psynf);
					break;
				default:
					pxerror = PGE_BAA;
					break;
				}
		if (xhm < 5) xhm = 5;
		}
		break;

	case 1:
		local3 = 0;
		while (!local3)
		{
			printf("\n\nROM Configuration:\t");
			xrm = pimenu(pxrm,xrm);
			if (killkey) break;
			switch (xrm)
			{
			case 0:
				printf("\n\nSelect GenericPart:\t");
				if (piflags&PiUP)
					for (i=0; i<12; i++)
						if (pxrom[0].size == pxroms[i])
						{
							xrz = i-1;
							break;
						}
				xrz = pimenu(pxrrz,xrz);
				if (xrz > 10) xwz = 1;
				sprintf(pxuline,"rom %s",pxrrt[xrz]);
				pisyn(pxuline,pcmfsyn,psynf);
				if (pxerror)
				{
					pierror();
					--xrm;
				}
				break;
			case 1:
				printf("\nSelect SocketSize:\t");
				xsz = pimenu(pxrsz, xsz);
				if (xsz)
				{
					sprintf(pxuline,"socket %s\n",pxrrt[xsz+4]);
   					pisyn(pxuline,pcmfsyn,psynf);
				}
				break;
			case 2:
				printf("\nSelect WordSize:\t");
				xwz = pimenu(pxrwz,xwz);
				if (xwz == 0)
					xrm++;
				break;
			case 3:
				printf("\nSelect ByteOrder:\t");
				xbo = pimenu(pxrbo,xbo);
				sprintf(pxuline,"word %d ",(1<<xwz)*8);
				if (xwz == 1 && xbo == 1)
					if (pxprom < 3)
						strcat(pxuline, pxru2);
					else
						 strcat(pxuline, pxru4);
				if (xwz == 2 && xbo == 1)
					strcat(pxuline, pxr32);
				if (xwz == 3 && xbo == 1)
					strcat(pxuline, pxr64);
				if (xbo == 2)
				{
					printf("\nEnter IDs for Custom Configurations:");
					uinp = pigets(locals);
					strcat(pxuline,uinp);
				}
 				pisyn(pxuline,pcmfsyn,psynf);
				break;
			case 4:
				printf("\nSelect Fill Data:\t");
				xfd = pimenu(pxrfd,xfd);
				if (killkey) break;
				sprintf(pxuline,"fill ");
				if (xfd)
				{
					printf("\n\nEnter as follows (default DATA is treated as word_size wide:");
					printf("\n arg1\t-\t-\t-\t- new fill DATA");
					printf("\n arg1, arg2\t-\t-\t- START END - fill with FFs");
					printf("\n arg1, arg2, arg3\t-\t- START END DATA");
					printf("\n arg1, arg2, arg3, arg4\t-\t- START END DATA SIZE_OF_DATA(<=4)");
					printf("\n arg1, arg2, arg3, arg4, arg5\t- START END DATA DATA2 SIZE_OF_DATA(>4)");
					printf("\n\nEnter 1 or 2 or 3 or 4 or 5, args: ");
 					pigets(locals4);
					strcat(pxuline,locals4);
				}
				if (tflags = piflags&(PiII|PiiX))
					piflags &= ~(PiII|PiiX);
 				pisyn(pxuline,pcmfsyn,psynf);
				piflags |= tflags;
				strcpy(locals4,pxuline);
				addfill++;
				break;
			case 5:
				local3++;
				break;
			default:
				pxerror = PGE_BAA;
				break;
			}
			if (killkey) continue;
			if (++xrm > 5) xrm=0;
		}
		break;

	case 2:
		printf("\n\nEnter FileName: ");
		file = pigets(lstr);
		if (strlen(file))
		{
			printf("\nSelect FileType:\t");
			xft = pimenu(pxfty,xft);
			if (killkey) break;
			printf("\nSelect DataConfig:\t");
			xfi = pimenu(pxfwz,xfi);
			if (xfi)
			{
				printf("\nEnter WordSize followed by the IDs: ");
				uinp = pigets(locals2);
			}

			if (xft)
			{
					sprintf(pxuline,"image %s 0=0 ",file);
			}
			else
			{
					sprintf(pxuline,"file %s 0=0 ",file);
			}
			if (xfi)
				strcat(pxuline,uinp);
			pisyn(pxuline,pusrsyn,psynf);
			pifile(1);
			if (!pxerror)
			{
				pxnfile--;
				printf("\n\nFile Data Spans from 0x%08X to 0x%08X",maps[0],mape[mapi-1]);
				if (pxpcfg)
					printf("\n ROM Space Spans from 0x00000000 to 0x%08X",pxcfg->max); 
				printf("\n\nWhere in ROM would you like to load it (Hex offset): ");
				cscanf("%x",&roffset);
				if (xft)
				{
					printf("\nEnter bytes to skip from binary file (0 if none): ");
					cscanf("%x",&foffset);
					sprintf(pxuline,"image %s %x=%x ",file,foffset,roffset);
				}
				else
				{
					sprintf(pxuline,"file %s %x=%x ",file,maps[0],roffset);
				}
				if (xfi)
					strcat(pxuline,uinp);
				pisyn(pxuline,pusrsyn,psynf);
			}
			else
			{
				pxnfile--;
				xmm--;
			}
		}
		break;

	case 3:	/* AI */
		local4 = 0;
		while (!local4)
		{
			printf("\n\nAI Configuration:\t");
			xal = pimenu(pxaim,xal);
			if (killkey) break;
			switch (xal)
			{
			case 0:
				printf("\n\nEnter AILOC offset in ROM space: ");
				pigets(locals3);
				sscanf(locals3,"%x",&pxailoc);
				sprintf(pxuline,"ailoc %x ",pxailoc);
				printf("\n\nSelect AI Link:\t\t");
				xaisp = pimenu(pxaisp,xaisp);
				if (xaisp)
				{
					printf("\nParallelLink:\t\t");
					xpp = pimenu(pxgpp,xpp);
					yabr = 0;
				}
				else
				{
					printf("\nSerialLink:\t\t");
					xcp = pimenu(pxgcp,xcp);
					printf("\nSerialBaudRate:\t\t");
					xbr = pimenu(pxgbr,xbr);
					if (killkey) continue;
					switch (xbr)
					{
					case 0:
						yabr = 1200;
						break;
					case 1:
						yabr = 2400;
						break;
					case 2:
						yabr = 4800;
						break;
					case 3:
						yabr = 9600;
						break;
					case 4:
						yabr = 19200;
						break;
					case 5:
						yabr = 57600;
						break;
					default:
						pxerror = PGE_BAA;
						break;
					}
				}
				sprintf(locals31,"output=COM%d",xcp+1);
				sprintf(locals3,"%d ",yabr);
				strcat(pxuline,locals3);
				printf("\n\nSelect Communicaton Mode: ");
				xaxp = pimenu(pxaxp,xaxp);
				if (xaxp)
				{
					printf("\n\nEnter the Break Character(Hex): ");
					pigets(locals3);
					sscanf(locals3,"%x",&pxaibchr);
					strcat(pxuline,locals3);
				}
				else
					strcat(pxuline,"-1 "); 
				printf("\n\nSelect How Host can break the link: ");
				xabk = pimenu(pxabk,xabk);
				pxhints = (char)0xff;
				if (xabk)
				{
					if (xabk == 2)
					{
						printf("\n\nEnter the Number of Interrupts to ignore: ");
						pigets(locals3);
						sscanf(locals3,"%d",&pxhints);
					}
					else
						pxhints = 0;
				}
				sprintf(locals3," %d",pxhints);
				strcat(pxuline,locals3);
				strcpy(locals3,pxuline);
				pisyn(pxuline,pcmfsyn,psynf);
				if (!pxerror)
					addai++;
				break;
			case 1:
				printf("\n\nSelect BurstAccess:\t");
				if (pxrom[0].res&TRACE)
				{
					xab = pimenu(pxaib2,xab);
					if (killkey) break;
					switch (xab)
					{
					case 0:
						pxburst = 0;
						break;
					case 1:
						pxburst = 2;
						break;
					case 2:
						pxburst = 4;
						break;
					case 3:
						pxburst = 8;
						break;
					case 4:
						pxburst = 16;
						break;
					case 5:
						pxburst = 32;
						break;
					default:
						pxerror = PGE_BAA;
						break;
					}
				}
				else
				{
					xab = pimenu(pxaib1,xab);
					if (killkey) break;
					switch (xab)
					{
					case 0:
						pxburst = 0;
						break;
					case 1:
						pxburst = 4;
						break;
					case 2:
						pxburst = 8;
						break;
					case 3:
						pxburst = 16;
						break;
					default:
						pxerror = PGE_BAA;
						break;
					}
				}
				if (!pxerror)
				{
					sprintf(pxuline,"burst %d",pxburst);
					pisyn(pxuline,pcmfsyn,psynf);
					strcpy(locals5,pxuline);
					if (!pxerror)
						addburst++;
				}
				break;
			case 2:
				printf("\n\nSelect ClockDeskew:\t");
				if (pxrom[0].res&TRACE)
					xad = pimenu(pxaid2,xad);
				else
					xad = pimenu(pxaid1,xad);
				if (!killkey)
				{
					sprintf(pxuline,"aicontrol %d",xad);
					pisyn(pxuline,pcmfsyn,psynf);
					strcpy(locals6,pxuline);
					if (!pxerror)
						addaic++;
				}
				break;
			case 3:
				if (pxrom[0].res&TRACE)
				{
					printf("\n\nDirect Write Selected");
					pxaictl |= AIC_AIDIRT;
				}
				else
					printf("\n\nSorry, you need AI2 to do that");
				break;
			case 4:
				local4++;
				break;
			default:
				pxerror = PGE_BAA;
				break;
			}
			if (killkey) continue;
			if (++xal > 4) xal = 4;
		}
		break;
	case 4:
		printf("\nMisc. Configuration:\t");
		xxm = pimenu(pxxm,xxm);
		if (killkey) break;
		switch (xxm)
		{
		case 0:
			if (piflags&PiUP)
			{
				pilod();
				sprintf(pxuline,"l");
				pisyn(pxuline,pusrsyn,psynf);
				piemu();
			}
			pisyn("x",pusrsyn,psynf);
			local++;
			break;
		case 1:
			addialog++;
			break;
		default:
			pxerror = PGE_BAA;
			break;
		}
		break;

	case 5:
		piwrini();
		local++;
		break;

	case 6:
		i = -1;
		printf("\n");
		while (pxmh[++i])
			printf("\n\t%s",pxmh[i]);
		break;

	case 7:
		local++;
		break;

	default:
		break;
	}
	if (killkey)
	{
		killkey = 0;
		xmm--;
	}
}

/* `pimenu` - get user selection from menu list */

long pimenu(char *menu[],long index)
{
	unsigned char c = 0;
	long i,j, lindex = index;

	killkey = 0;
	for (;;)
	{
		printf("%s",menu[index]);
#ifdef WIN32
		while (!(c = kbhit()))
			Sleep(100);
#endif
		c = (unsigned char)getch();

		if (c == '\r')
		{
			break;
		}

		if ((c == 0) || (c == 0x0E0) || (c == 0x1b))
		{
			if (c != 0x1b)
				c = (unsigned char)getch();
			if (c == 0x1b)			/* ESC key - switch mode */
			{
				killkey++;
				break;
			};
			if (c<0x45 && c>0x3a)
				c -= 0x3b;
			else
				if (c<0x72 && c>0x67)
					c -= 0x5c;
				else
					if (c<0x08d && c>0x084)
						{
						c -= 0x085;
						if (c<2)
							c += 10;
						else
							c += 16;
						}
		}
		if (c>23)	/* if not function keys then list keys */
		{
			switch(c)
			{
			case 0x47:	// Home
				break;
			case 0x48:	// Up Arrow
				if (--index<0) index=0;
				break;
			case 0x49:	// Page Up
				break;
			case 0x4B:	// Left Arrow
				break;
			case 0x4D:	// Right Arrow
				break;
			case 0x4F:	// End
				break;
			case 0x50:	// Down Arrow
				if (menu[++index]==0) index--;
				break;
			case 0x51:	// Page Down
				break;
			case 0x52:	// Insert
				break;
			case 0x53:	// Delete
				break;
			default:
				break;
			}
		}
		j = strlen(menu[lindex]);
		for (i=0; i<j; i++)
			printf("\b");
		for (i=0; i<j; i++)
			printf(" ");
		for (i=0; i<j; i++)
			printf("\b");
		lindex = index;
	}
	return(index);
}

/* `piwrini` - write the ini file out */

void piwrini(void)
{
	FILE *cf;
	PIFILE *pf;
	PICONFIG *cx;
	long i,j;

	remove("loadice.old");
	rename("loadice.ini","loadice.old");

	if ((cf = fopen("loadice.ini","w")) == NULL)
	{
		pxerror = PGE_FNM;
		return;
	}

	if (piflags&PiNE)
	{
		sprintf(pxuline,"fastport %s\n",pxhost);
		fwrite(pxuline,1,strlen(pxuline),cf);
		if (pxlink.flags&(PLPP|PLPB))
		{
			sprintf(pxuline,"ppbus %s\n",pxlink.pname);
			fwrite(pxuline,1,strlen(pxuline),cf);
		}
	}
	else
	{
		if (pxlink.flags&PLPQ)
		{
			sprintf(pxuline,"pponly %s\n",pxlink.pname);
			fwrite(pxuline,1,strlen(pxuline),cf);
		}
		else
		{
			if (pxlink.flags&PLSE)
			{
				sprintf(pxuline,"output %s\n",pxlink.name);
				fwrite(pxuline,1,strlen(pxuline),cf);
				sprintf(pxuline,"baud %d\n",pxlink.brate);
				fwrite(pxuline,1,strlen(pxuline),cf);
			}
			if (pxlink.flags&(PLPP|PLPB))
			{
				sprintf(pxuline,"ppbus %s\n",pxlink.pname);
				fwrite(pxuline,1,strlen(pxuline),cf);
			}
		}
	}
	if (xrz >=0 )
	{
		sprintf(pxuline,"rom %s\n",pxrrt[xrz]);
		fwrite(pxuline,1,strlen(pxuline),cf);
	}
	if (xsz)
	{
		sprintf(pxuline,"socket %s\n",pxrrt[xsz+4]);
		fwrite(pxuline,1,strlen(pxuline),cf);
	}
	sprintf(pxuline,"word %d ",(1<<xwz)*8);
	if (locals[0])
		strcat(pxuline,locals);
	strcat(pxuline,"\n");
	fwrite(pxuline,1,strlen(pxuline),cf);
	if (addfill)
	{
		strcat(locals4,"\n");
		fwrite(locals4,1,strlen(locals4),cf);
	}
	for (i=0; i<pxnfile; i++)
	{
		pf = &pxfile[i];
		if (pf->type == PFHEX)
			sprintf(pxuline,"file %s %x=0 ",pf->name,-pf->offset);
		else
			sprintf(pxuline,"image %s %x=%x ",pf->name,pf->skip,pf->offset);
		if (pf->pfcfg && (pf->pfcfg != pxpcfg))
		{
			cx = pf->pfcfg;
			sprintf(locals2,"%d ",(1<<(cx->words-1))*8);
			strcat(pxuline,locals2);
			while (cx)
			{
				for (j=0; j<cx->words; j++)
				{
					sprintf(locals2,"%d ",cx->uid[j]);
					strcat(pxuline,locals2);
				}
				cx = cx->next;
			}
		}
		strcat(pxuline,"\n");
		fwrite(pxuline,1,strlen(pxuline),cf);
	}
	if (addai)
	{
		if (locals31[0])
		{
			strcat(locals31,"\n");
			fwrite(locals31,1,strlen(locals31),cf);
		}
		strcat(locals3,"\n");
		fwrite(locals3,1,strlen(locals3),cf);
	}
	if (addburst)
	{
		strcat(locals5,"\n");
		fwrite(locals5,1,strlen(locals5),cf);
	}
	if (addaic)
	{
		strcat(locals6,"\n");
		fwrite(locals6,1,strlen(locals6),cf);
	}
	if (pxaictl&AIC_AIDIRT)
	{
		strcpy(pxuline,"aidirt\n");
		fwrite(pxuline,1,strlen(pxuline),cf);
	}
	if (addialog)
	{
		sprintf(pxuline,"dialog\n");
		fwrite(pxuline,1,strlen(pxuline),cf);
	}
	fclose(cf);
}
#endif
