#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#include <string.h>
/* #include <ctype.h>  Needed for DOS compilers	*/
/* As of 11-10-2004 this program reads files, edits header and saves to new file */
/* As of 11-14-2004 started the function codes - first 2 complete */
/* As of 04-20-2005 write function for 8 channel version working  */
/* As of 09-14-2008 Minor bug fixes and code formatting */
/* As of 09-22-2008 80 channel edit functions missing	*/
/* As of 11-03-2008 improve input function and finish Scan and Function sections */
/* As of 11-05-2008 80 channel frequency edit working need last channel byte and center freq	*/
/* As of 11-06-2008 Nearly complete. Center frequency edit not complete	*/
/*** 11-06-2008 debugging 	*/
/*	Frequencies are repeated at +0x200 for TalkAround	*/
/*	First byte of TalkAround channels unknown	*/
/*	It may be possible to have 160 channels using Talk Around (ground pin6 J361 */
/*	Band byte must be present	*/
/*	Compiling on DOS failed!	*/
/* As of 11-08-2008 Seems to be working for UHF and VHF. No code for other bands	*/
/* 12-25-2008 Bug found in 8 ch transmit freq. display */
/* 02-27-2011 minor display formatting changes	*/
/* 04-15-2011 Max channel number is not updated on 8 channel version! still needs fixing!	*/
/* 04-23-2011 Low band radios have two dummy bits	*/
unsigned char scan_a[64],scan_b[64];
/* 80 ch scan A starts at 0x0000, every 4th byte. scan B starts at 0x0100, every 4th byte */
unsigned char eprom[0x800],func[9];
int band=0,type=0,max_ch=0;
unsigned int ref=12500,min_rx,min_tx,max_rx,max_tx;
int rx_if=21400,tx_if,color;
struct channel_bytes {
	unsigned int rx_parity  :1;
	unsigned int rx_ctcss   :5;
	unsigned int tx_parity  :1;
	unsigned int tx_ctcss   :5;
	unsigned int rx_div    :16;
	unsigned int tx_div    :16;
        };
char tone[32][6]={{" 71.9"},{" 77.0"},{" 82.5"},{" 88.5"},{" 94.8"},{"100.0"},
		{"103.5"},{"107.2"},{"110.9"},{"114.8"},{"118.8"},{"123.0"},
		{"127.3"},{"131.8"},{"136.5"},{"141.3"},{"146.2"},{"151.4"},
		{"156.7"},{"162.2"},{"167.9"},{"173.8"},{"179.9"},{"186.2"},
		{"192.8"},{"203.5"},{"210.7"},{"218.1"},{"225.7"},{"233.6"},
		{"241.8"},{"C-Sql"}};

unsigned char head[64];
struct channel_bytes ch[80];

int menu(void);
void create_eprom(void);
void existing_eprom(void);
void z383(void);	/* 8 channel version	*/
void z273(void);	/* 80 channel version	*/
int ch_addr(int);
unsigned char find_parity(long int);
void edit_8channels(void);
void edit_80channels(void);
void edit_header(void);
void edit_center(void);
void update_header(void);
void edit_scan(void);
void edit_functions(void);
void clear_kb(void);
void head_383(void);
void head_273(void);
void save_eprom(void);
void print_functions(void);
void display_channel(struct channel_bytes*);
void find_last_ch(void);
void edit_reference(void);
int int_input(void);
int main() {
	int i;
	char * temp_ptr;
	char choice[10],temp[255];
	extern unsigned char eprom[0x800];
	extern int band,type,rx_if,tx_if,color;
	extern unsigned int ref;
	color=0;	
        temp_ptr=getenv("TERM");
        if (temp_ptr!=NULL) {
                strcpy(temp,temp_ptr);
                printf("Found terminal type: %s\n",temp);
                if (strncmp(temp,"xterm",5)==0)
                        color=1;
                if (strncmp(temp,"linux",5)==0)
                        color=1;
        }
        if(color)
                printf("\033[1;34m");
        printf("\v\v\tMidland 2716 based radio Programming\n");
        if (color)
                printf("\033[1;31m");
        printf("\tVersion 1.0 April, 2011\n\n");
        if (color)
                printf("\033[0;m");

	printf("\n\t\tMidland EPROM image creator by N7HYV\n\n");
	printf("\tThis program will read and write binary image files "
							"for a 2716 EPROM.\n");
	printf("\tThe info was gathered through experimentation and "
							"hints from the\n");
	printf("\tprogramming manual. Any bugs can be sent to n7hyv@arrl.net\n\n");
	printf("The following chart shows the normal IF configurations:\n");

	printf("\n\t\t\tRX IF\tTX IF\tReference\n");
	printf("Band\tRange\tMHz\tMHz\tMHz\tKHz\tInjection\n");
	for (i=1;i<58;i++)
		printf("-");
	printf("\n");

	printf("  50\tA\t29-37\t 10.7\t10.24\t5.0\tHigh\n");
	printf("\tB\t35-44\n");
	printf("\tC\t40-54\n");
	for (i=1;i<53;i++)
        	/*printf("%c",196);*/printf("-");
	printf("\n");

	printf("  80\tA\t66-77\t 21.4\t20.48\t5.0\tHigh\n");
	printf("\tB\t77-88\n");
	for (i=1;i<53;i++)
        	printf("-");
	printf("\n");

	printf(" 150\tA\t136-156\t 21.4\t20.48\t5.0\tLow\n");
	printf("\tB\t148-174\n");
	for (i=1;i<53;i++)
        	printf("-");
	printf("\n");

	printf(" 400\tA\t406-430\t 21.4\t19.2\t12.5\tLow\n");
	printf("\tB\t450-470\n");
	printf("\tC\t470-494\n");
	printf("\tD\t494-512\n");
	printf("\tE\t430-450\n");
	for (i=1;i<53;i++)
        	printf("-");
	printf("\n");

	printf(" 800\t\t806-866\t 47.0\t19.2\t12.5\tLow\n");
	for (i=1;i<58;i++)
        	printf("-");
	printf("\n\n");

	printf("Optional TX IF frequencies: 9.6, 10.24, 19.2 or 20.48 MHz.\n");
	printf("Reference frequency options are 2.5, 5.0, 10.0 and 12.5 KHz.\n");

	printf("The mobiles with the Z-273 eprom board have 80 channels.\n");
	printf("The mobiles with the Z-383 eprom board have 8 channels.\n"); 

	switch (menu()) {
		case 1: existing_eprom(); break;
		case 2: create_eprom(); break;
		default: printf("An unknown error occurred!\n\n"); return(1);
	}
	if (eprom[0x410]!=0xff) {
		printf("\nData from EPROM shows 80 channel ");
		type=80;
		switch (0x07&eprom[0x410]) {
			case 0: printf("LOW, 50 MHz band\n");
				rx_if=10700; band=50; break;
			case 1: printf("LOW, 80 MHz band\n"); break;
			case 2: printf("VHF, 150 MHz band\n"); band=150; break;
			case 3: printf("UHF, 400 MHz band\n"); band=400; break;
			case 4: printf("800 MHz band\n");
				rx_if=47000; band=800; break;
			default: break;
		}
		switch (eprom[0x410]) {
			case 0x02: ref=5000; tx_if=20480; break;
			case 0x03: ref=12500; tx_if=19200; break;
			case 0x32: ref=2500; tx_if=20480; break;

			/* Low band -not sure-	*/
			case 0x40: ref=5000; tx_if=-10240; rx_if=-10700; break;

			case 0x42: ref=5000; tx_if=20480; rx_if=-21400; break;
			case 0x12: ref=12500; tx_if=19200; break;
			case 0x52: ref=12500; tx_if=-19200; rx_if=-21400; break;
			case 0x4a: ref=2500; tx_if=20480; rx_if=-21400; break;
			case 0x53: ref=12500; tx_if=19200; rx_if=-21400; break;

			case 0x23: ref=10000; tx_if=20480; break;
			case 0x73: ref=10000; tx_if=20480; rx_if=-21400; break;
			case 0x0b: ref=5000; tx_if=20480; break;
			case 0x4b: ref=5000; tx_if=20480; rx_if=-21400; break;
			default: edit_reference(); break;
		}
	}
	if (eprom[0x410]==0xff) {
		switch (eprom[0x418]) {
			case 2: printf("EPROM shows VHF, 8 channel radio\n");
				band=150;
				type=8;
				break;
			case 3: printf("EPROM shows UHF, 8 channel radio\n");
				band=400;
				type=8;
				break;
			default: printf("Radio type unknown\n"); break;
		}
	}
	while (band==0) {
		printf("\nSelect the band: 50\t80\t150\t400\t800\n\t--> ");

		band=int_input();
		switch (band) {
			case 50: break;
			case 80: break;
			case 150: break;
			case 400: break;
			case 800: break;
			default: band=0;
		}
	}

/* This will print the contents of the eprom 
printf("current eprom data:\n\n");
for (i=0;i<0x800;i++)
	{
	if (!(i%4)) printf("|");
	if (!(i%32)) printf("\n");
	printf("%02X ",eprom[i]);
	}
*/
	while (type==0) {
		printf("\nSelect the type of radio: 8 or 80 channel\n\t--> ");
		type=int_input();

        	switch (type) {
                	case 8: if (eprom[0x418]==0xff) {
					if (band==150) {
						eprom[0x00]=0xf2;
						eprom[0x418]=0x02;
					}
					if (band==400) {
						eprom[0x00]=0xf3;
						eprom[0x418]=0x03;
					}
				}
				break;
                	case 80: if (eprom[0x410]==0xff) {
					edit_reference();
/*					if (band==150)
						eprom[0x410]=0x02;
					if (band==400)
						eprom[0x410]=0x03;
*/
				}	
				break;
                	default: type=0; break;
               	}
       	}

	if (color==1) {
		printf("\033[2J"); /*clears screen*/
		printf("\033[0;0f"); /*place cursor in top left*/
	}

	printf("%d channel %d MHz radio\n\n",type,band);

	if (type==8) {
		head_383();
		z383();
	}

	if (type==80) {
		head_273();
		z273();
	}

	/* ----- What do we do?? ----------------------------- */
	i=0;
	while ((i!=120)&(i!=88)) {
		printf("\n");
		for (i=0;i<64;i++) printf("_");printf("\n");
		printf("H - Enter header information\n");
		printf("E - Edit channels\n");
		printf("F - Function and timing settings\n");
		if (type==80) {
			printf("C - Enter Center Frequencies\n");
			printf("R - Change Reference Frequency\n");
		}
		printf("S - Scan list\n");
		printf("D - Display channels\n");
		printf("W - Write EPROM data to disk\n");
		printf("X - eXit the program\n");
		printf("Enter an option --> ");
		temp_ptr=fgets(choice,3,stdin);
		if (temp_ptr==NULL) {
			printf("\nUnknown error/n/n");
			continue;
		}
		i=strlen(choice);
		if (choice[i-1]!='\n') { /* clear keyboard buffer */
			i=0;
			while (i!='\n')
				i=getchar();
		}
		printf("\n");
		i=choice[0];
		if ((i==69) | (i==101)) {
			if (type==8) edit_8channels();
			if (type==80) edit_80channels();
		}
		if ((i==72) | (i==104)) edit_header();
		if ((i==70) | (i==102)) edit_functions();
		if ((i==87) | (i==119)) save_eprom();
		if ((i==83) | (i==115)) edit_scan();
		if ((i==67) | (i==99)) edit_center();
		if ((i==82) | (i==114)) edit_reference();
		if ((i==68) | (i==100)) {
			if (type==8) {
				head_383();
				z383();
			}
			if (type==80) {
				head_273();
				z273();
			}
		}
	}

	return(0);	/* End of main() */
}

/* ============ Start of functions ============= */
int menu() {
	int i;
	char choice[5];
	char *temp_ptr;
	printf("\nEPROM image Menu\n");
	for (i=1;i<40;i++)
	        printf("_");
	printf("\n");
	printf("Enter an ( R ) to read from a disk file\n");
	printf("Enter any other key for a new file --> ");
	temp_ptr=fgets(choice,3,stdin);
	if (temp_ptr==NULL) {
		printf("Unknown error/n/n");
		return(3);
	}
	i=strlen(choice);
	if (choice[i-1]!='\n') { /* clear keyboard buffer */
		i=0;
		while (i!='\n')
			i=getchar();
	}
	printf("\n");
	if ((choice[0]==82) | (choice[0]==114))
		return (1);
	else
		return (2);
}

void create_eprom(void) {
	int i;
	extern unsigned char eprom[0x800];
	printf("A new eprom file will be created.\n");
	for (i=0;i<0x800;i++)
		eprom[i]=0xff;
	eprom[0x0400]=0x00; /* unknown */
	eprom[0x0404]=0x72; /* switch debounce */
	eprom[0x040c]=0x56; /* memory options */
}

void update_header(void) {
	struct tm now;
	int i;
	time_t elapsed;
	char new_date[7];
	extern unsigned char eprom[0x800];
	extern int type;
	extern unsigned char head[64];
	elapsed=time(NULL);
	now=*localtime(&elapsed);
	sprintf(new_date,"%02d%02d%02d",now.tm_mon+1,now.tm_mday,now.tm_year-100);
	head[24]=(unsigned char) (int)(new_date[0]-48);
	head[25]=(unsigned char) (int)(new_date[1]-48);
	head[26]=(unsigned char) (int)(new_date[2]-48);
	head[27]=(unsigned char) (int)(new_date[3]-48);
	head[28]=(unsigned char) (int)(new_date[4]-48);
	head[29]=(unsigned char) (int)(new_date[5]-48);
	if (type==8)
	        for (i=0;i<30;i++)
        	        eprom[i+0x96]=head[i];
	else if (type==80) {
		for (i=0;i<15;i++)
			eprom[0x5f0+i]=(head[i*2]<<4)|head[i*2+1];
		eprom[0x5ff]=7;
	}
}

void existing_eprom(void) {
	FILE *eprom_data;
	char *temp_ptr;
	char choice[128],code_file[128];
	DIR *dir_p;
	struct dirent *dirent_p;
	int i,width=0;
	extern unsigned char eprom[0x800];
	printf("\nListing of current directory:\n");
	dir_p=opendir(".");

	while (NULL !=(dirent_p=readdir(dir_p))) {
		printf(" %s\t\t",dirent_p -> d_name);
		width++; if (width%2==0) printf("\n");
	}
	closedir(dir_p);
	printf("\n");
	/* --------------------------------------------------------------*/
	codeplug:
	printf("\n\nEnter file to read:\n\t-->  ");
	temp_ptr=fgets(choice,125,stdin);
	if (temp_ptr==NULL) {
		printf("Unknown error/n/n");
		goto codeplug;
	}
	i=strlen(choice);
	if (choice[i-1]!='\n') { /* clear keyboard buffer */
		i=0;
		while (i!='\n')
			i=getchar();
	}
	sscanf(choice,"%s",code_file);
	printf("\nOpening %s\t",code_file);
	eprom_data = fopen (code_file,"rb");
	if (!eprom_data) {
		printf("Error opening %s!\n",code_file);
		goto codeplug;
	}
	fread(eprom,0x800,1,eprom_data);
	fclose(eprom_data);
	printf("%s read into buffer\n",code_file);
}

/* ======================= 8 channel Z-383B radios ========================== */
void z383(void) {	/* 8 channel version */
	int i;
	unsigned long int x;
	extern unsigned char scan_a[64],scan_b[64],eprom[0x800],func[9];
	extern int max_ch;
	extern char tone[32][6];
	extern struct channel_bytes ch[80];
        func[1]=eprom[0x02]; func[1]&=0x0f;
        func[2]=eprom[0x03]; func[2]&=0x0f;
        func[3]=eprom[0x04]; func[3]&=0x0f;
        func[4]=eprom[0x05]; func[4]&=0x0f;
        func[5]=eprom[0x06]; func[5]&=0x0f;
        func[6]=eprom[0x07]; func[6]&=0x0f;
        func[7]=eprom[0x08]; func[7]&=0x0f;
        func[8]=eprom[0x09]; func[8]&=0x0f;

	if (func[1]==0x0f)
		printf("BCLO default: Disabled\n");
        else {
	 	printf("BCLO\t\t\t%d\t",func[1]);
		/*Busy Channel Lockout-
			0=BCLO without alert, 2=BCLO with alert, 3=disabled */
        	switch (func[1]) {
                	case 0: printf("Active without alert\n"); break;
                	case 2: printf("Active with alert\n"); break;
                	case 3: printf("Disabled\n");
		}
        	printf("\tInstall JP107 for BCLO on busy -or- "
			"JP108 for BCLO on CTCSS\n");
	}
        if (func[2]==0x0f) printf("TOT default: Disabled\n");
        else printf("TOT\t\t\t%d\t%d seconds\n",func[2],30*func[2]);
        /* TOT of 0 disables, 30 to 210 seconds in 30 second steps */

        printf("Interval A (Noise Sq)\t%X",func[3]);
		if(func[3]==15)
			printf("\n");
		else
			printf("\t%d milliseconds\n",func[3]*25);
        printf("Interval B (Code Sq)\t%X",func[4]);
		if(func[4]==15)
			printf("\n");
		else
			printf("\t%d milliseconds\n",func[4]*100);
        printf("Scan hold\t\t%X",func[5]);
		switch(func[5]) {
			case 0: printf("\t0.3 seconds\n"); break;
			case 1: printf("\t2.5 seconds\n"); break;
			case 2: printf("\t5.0 seconds\n"); break;
			case 3: printf("\tInfinite\n"); break;
			default: printf("\n");
		}
        printf("Scan hold PTT\t\t%X",func[6]);
		switch(func[6]) {
			case 0: printf("\t0.3 seconds\n"); break;
			case 1: printf("\t2.5 seconds\n"); break;
			case 2: printf("\t5.0 seconds\n"); break;
			case 3: printf("\tInfinite\n"); break;
			default: printf("\n");
		}
        printf("Pri Mon\t\t\t%X\t",func[7]);
	/* 0=4ch/1sec, 1=8ch/1sec, 2=4ch/2sec, 3=8ch/2sec, 4=Priority disabled */
        switch (func[7]) {
                case 0: printf("Priority checked every 4th channel\n"
			"\t\t\t\tand once each second while stopped\n"); break;
                case 1: printf("Priority checked every 8th channel\n"
			"\t\t\t\tand once each second while stopped\n"); break;
                case 2: printf("Priority checked every 4th channel\n"
			"\t\t\t\tand once every 2 seconds while stopped\n"); break;
                case 3: printf("Priority checked every 8th channel\n"
			"\t\t\t\tand once every 2 seconds while stopped\n"); break;
                case 4: printf("Priority monitoring disabled\n");
        }
        if (func[7]==0x0f) printf("default: 8 channels/1 second\n");

        printf("Scan Format:\t\t%X\t",func[8]);
        switch (func[8]) {
                case 0: printf("Normal, stop on carrier\n"); break;
                case 1: printf("Normal, stop with proper CTCSS\n"); break;
                case 2: printf("Normal, stopped by absence of carrier\n"); break;
                case 3: printf("Normal, carrier without proper CTCSS\n"); break;
                case 4: printf("Modified, stop on carrier\n"); break;
                case 5: printf("Modified, stop with proper CTCSS\n"); break;
                case 6: printf("Modified, stopped by absence of carrier\n"); break;
                case 7: printf("Modified, carrier without proper CTCSS\n"); break;
                case 8: printf("Secondary, stop on carrier\n"); break;
                case 9: printf("Secondary,stop with proper CTCSS\n"); break;
                case 0x0a: printf("Secondary, stopped by absence of carrier\n");break;
                case 0x0b: printf("Secondary, carrier without proper CTCSS\n"); break;
                case 0x0f: printf("default: NORMAL with CTCSS\n"); break;
                default: break;
        }

	if (eprom[0x0a]!=0xff)
		printf("TX to RX delay: %d mS\n",(0x07&eprom[0x0a])*50);
	for (i=0x10;i<56;i+=5) {
       /*rx divisor */ x=eprom[i];
                        x<<=15;
                        x=x|((eprom[i+1]&0x0f)<<11);
                        x=x|((eprom[i+2]&0x0f)<<7);
                        x=x|((eprom[i+3]&0x08)<<3);
			x=x|((eprom[i+3]&0x03)<<4);
			x=x|(eprom[i+4]&0x0f);
                        ch[i/5-2].rx_div=x;

       /*tx divisor */ x=eprom[i+40];
                        x<<=15;
                        x=x|((eprom[i+41]&0x0f)<<11);
                        x=x|((eprom[i+42]&0x0f)<<7);
                        x=x|((eprom[i+43]&0x08)<<3);
                        x=x|((eprom[i+43]&0x03)<<4);
                        x=x|(eprom[i+44]&0x0f);
                        ch[i/5-2].tx_div=x;
	}
	for (i=0x60;i<0x70;i+=2) {
		/*rx CTCSS */
		x=eprom[i];
		x <<= 3;
		x = x | (0x07&(eprom[i+1]>>1));
		ch[(i-0x5e)/2].rx_ctcss=x^0x1f;

		/* tx_ctcss */
		x=eprom[i+16];
		x<<=3;
		x=x | (0x7&(eprom[i+17]>>1));
		ch[(i-0x5e)/2].tx_ctcss=x^0x1f;
	}

	for (i=0x80;i<0x8a;i++) {
		scan_a[i-0x80]=eprom[i];
		scan_a[i-0x80]&=0x0f;
	}

	for (i=0x8a;i<0x90;i++) {
		scan_b[i-0x8a]=eprom[i];
		scan_b[i-0x8a]&=0x0f;
	}

	printf("\nScan list A\t\t\tScan list B\n");
	for (i=0;i<10;i++)
		if (scan_a[i]!=15) printf("%d ",scan_a[i]+1);

	printf("\t\t\t\t");
	for (i=0;i<6;i++)
		if (scan_b[i]!=15) printf("%d ",scan_b[i]+1);
	printf("\n\n");
	find_last_ch();
	printf("Last channel is %d\n",max_ch+1);
        printf("\nChannel\t Receive     RX CTCSS\tTransmit     TX CTCSS\n");
        for (i=1;i<57;i++) printf("-"); printf("\n");
 
	for (i=1;i<9;i++) {
		if(!(ch[i].rx_div==0xffff)) {
			printf("  %d\t",i);
			printf("%.4f\t%s\t",((float)ch[i].rx_div*12500)/1000000+21.4,
							tone[ch[i].rx_ctcss]);
			printf("%.4f\t%s\n",((float)ch[i].tx_div*12500)/1000000,
							tone[ch[i].tx_ctcss]);
		}

	}
}

/* ================= 80 channel Z-273 radios ================================ */
void z273(void) {
	/* 80 channel radios with Z-273 EPROM module */
	int i,j,inj;
	unsigned int addr;
	unsigned long int x;
	float freq;
	extern unsigned char scan_a[64],scan_b[64],eprom[0x800],func[9];
	extern int band,max_ch,rx_if,tx_if;
	extern unsigned int ref,min_rx,max_rx,min_tx,max_tx;
	extern char tone[32][6];
	extern struct channel_bytes ch[80];
	if ((eprom[0x410]&0xf8)!=0) {
		printf("EPROM indicates non-standard reference or injection.\n");
	}
	for (i=0;i<64;i++) {
		scan_a[i]=eprom[i*4];
		scan_b[i]=eprom[i*4+0x100]; /* Need to check if this tracks channel addresses */
	}

	func[1]=eprom[0x3f0]; func[1]>>=4;
	func[2]=eprom[0x3f0]; func[2]&=0x0f;
	func[3]=eprom[0x3f1]; func[3]>>=4;
	func[4]=eprom[0x3f1]; func[4]&=0x0f;
	func[5]=eprom[0x3f2]; func[5]>>=4;
	func[6]=eprom[0x3f2]; func[6]&=0x0f;
	func[7]=eprom[0x3f3]; func[7]>>=4;
	func[8]=eprom[0x3f3]; func[8]&=0x0f;


	printf("\nPLL reference = %.2f KHz\t",(float)ref/1000);
	if(rx_if>0) printf("Low injection\n"); else printf("High injection\n");

	if (func[1]==0x0f) printf("BCLO default: Disabled\n");
	else printf("BCLO\t%d\t",func[1]);
	/* Busy Channel Lockout - 0=BCLO without alert, 2=BCLO with alert, 3=disabled */
	switch (func[1]) {
		case 0: printf("active without alert\t"); break;
		case 2: printf("active with alert\t"); break;
		case 3: printf("Disabled\t");
	}
	printf("JP107 installed for BCLO on busy, JP108 for BCLO on CTCSS\n");
	if (func[2]==0x0f) printf("TOT default: Disabled\n");
	else printf("TOT\t%d\t%d seconds\n",func[2],30*func[2]);
	/* TOT of 0 disables, 30 to 210 seconds in 30 second steps */

	printf("Interval A\t%X",func[3]);
		if(func[3]==15)
			printf("\n");
		else
			printf("\t%d milliseconds\n",func[3]*25);
	printf("Interval B\t%X",func[4]);
		if(func[4]==15)
			printf("\n");
		else
			printf("\t%d milliseconds\n",func[3]*100);
	printf("Scan hold\t%X",func[5]);
		switch(func[5]) {
			case 0: printf("\t0.3 seconds\n"); break;
			case 1: printf("\t2.5 seconds\n"); break;
			case 2: printf("\t5.0 seconds\n"); break;
			case 3: printf("\tInfinite\n"); break;
			default: printf("\n");
		}
	printf("Scan hold PTT\t%X",func[6]);
		switch(func[6]) {
			case 0: printf("\t0.3 seconds\n"); break;
			case 1: printf("\t2.5 seconds\n"); break;
			case 2: printf("\t5.0 seconds\n"); break;
			case 3: printf("\tInfinite\n"); break;
			default: printf("\n");
		}

	printf("Pri Mon\t\t%X\t",func[7]);
		/* 0=4ch/1sec, 1=8ch/1sec, 2=4ch/2sec, 3=8ch/2sec, 4=Priority disabled */
		switch (func[7]) {
			case 0: printf("Priority checked each 4 channels and once each second when stopped\n"); break;
			case 1: printf("Priority checked each 8 channels and once each second when stopped\n"); break;
			case 2: printf("Priority checked each 4 channels and once every 2 seconds when stopped\n"); break;
			case 3: printf("Priority checked each 8 channels and once every 2 seconds when stopped\n"); break;
			case 4: printf("Priority monitoring disabled\n");
			default: break;
		}
		if (func[7]==0x0f) printf("default: 8 channels/1 second\n");

	printf("Scan Format:\t%X\t",func[8]);
		switch (func[8]) {
			case 0: printf("Normal, stop on carrier\n"); break;
			case 1: printf("Normal, stop with proper CTCSS\n"); break;
			case 2: printf("Normal, stopped by absence of carrier\n"); break;
			case 3: printf("Normal, carrier without proper CTCSS\n"); break;
			case 4:	printf("Modified, stop on carrier\n"); break;
			case 5: printf("Modified, stop with proper CTCSS\n"); break;
			case 6: printf("Modified, stopped by absence of carrier\n"); break;
			case 7: printf("Modified, carrier without proper CTCSS\n"); break;
			case 8: printf("Secondary, stop on carrier\n"); break;
			case 9: printf("Secondary,stop with proper CTCSS\n"); break;
			case 0x0a: printf("Secondary, stopped by absence of carrier\n"); break;
                	case 0x0b: printf("Secondary, carrier without proper CTCSS\n"); break;
			case 0x0f: printf("default: NORMAL with CTCSS\n"); break;
			default: break;
		}

/*	========= Portable option ==================		*/
/*	printf("Channel change delay (Portables only) ");
		switch (eprom[0x404]) {
			case 0x72: printf("16 ms (default)\n"); break;
			case 0x7f: printf("30 ms\n"); break;
			case 0x7c: printf("40 ms\n"); break;
			case 0x79: printf("52 ms\n"); break;
			case 0x76: printf("66 ms\n"); break;
			default: break;
		}
*/
	printf("Transmit to receive delay: ");
		if (eprom[0x3f4]==0xff) printf("default 0\n");
		else printf("%d ms\n",eprom[0x3f4]*50);

	for (i=0;i<80;i++) {
		addr=ch_addr(i);
		ch[i].rx_parity=(eprom[addr+1]&0x40)>>6;
		ch[i].rx_ctcss=(eprom[addr+1]&0x3e)>>1;
		ch[i].rx_ctcss=ch[i].rx_ctcss^0x1f;
		ch[i].tx_parity=(eprom[addr+1]&0x40)>>6;
		ch[i].tx_ctcss=(eprom[addr+0x401]&0x3e)>>1;
		ch[i].tx_ctcss=ch[i].tx_ctcss^0x1f;
			
		/*rx divisor */
		x=eprom[addr+1];
		x&=0x01;
		x=x<<8;
		x=x|(eprom[addr+2]);
		x=x<<1;
		x=x|((eprom[addr+3]&0x80)>>7);
		/* Dummy bits	*/
		if (band==50){
			x=x<<5;
			x=x|(eprom[addr+3]&0x1f);

			/* MSB bit on low band unknown	*/
	/*		x&=0x7fff;*/
		}
		else {
			x=x<<6;
			x=x|(eprom[addr+3]&0x3f);
		}
		ch[i].rx_div=x;


		/*tx divisor */
		x=eprom[addr+0x401];
		x&=0x01;
                x<<=8;
                x=x|(eprom[addr+0x402]);
                x<<=1;
                x=x|((eprom[addr+0x403]&0x80)>>7);
		/* Dummy bits	*/
		if (band==50) {
			x<<=5;
			x=x|(eprom[addr+0x403]&0x1f);

			/* MSB bit unknown on low band	*/
		/*	x&=0x7fff; */
		}
		else {
                	x<<=6;
                	x=x|(eprom[addr+0x403]&0x3f);
		}
                ch[i].tx_div=x;
	}

	printf("\nScan list A\n");
	x=0;
	for (i=0;i<64;i++)
		if (scan_a[i]!=0xff){
			printf("%02X ",scan_a[i]);
			x++;
			if (x==16) {
				x=0;
				printf("\n");
			}
		}
	printf("\n");

	x=0;
        printf("\nScan list B\n");
        for (i=0;i<64;i++)
                if (scan_b[i]!=0xff) {
			printf("%02X ",scan_b[i]);
			x++;
			if (x==16) {
				x=0;
				printf("\n");
			}
		}
        printf("\n\n");
	find_last_ch();
	printf("Ch  RX Freq RX tone  TX Freq TX tone    Ch  RX Freq RX tone  TX Freq  TX tone\n");
	j=(max_ch/2)+1;
	for (i=0;i<j;i++) {
		if ((ch[i].rx_div&0x7fff)!=0x7fff) {
			freq=(float)(ref*ch[i].rx_div)/1000+rx_if;
			printf("%2d  %8.4f  ",i,freq/1000);
			printf("%s  ",tone[ch[i].rx_ctcss]);
                        freq=(float)(ref*ch[i].tx_div)/1000+tx_if;
                        if ((ch[i].tx_div&0x7fff)!=0x7fff) printf("%8.4f  %s    ",freq/1000,tone[ch[i].tx_ctcss]);
			
			else {
				if (color==1) printf("\033[32m");
				printf("rx only            ");
				if (color==1) printf("\033[0m");
			}
		}
		else printf(" -                                      ");

		if ((ch[i+j].rx_div&0x7fff)!=0x7fff) {
			freq=(float)(ref*ch[i+j].rx_div)/1000+rx_if;
			printf("%2d  %8.4f  ",i+j,freq/1000);	
			printf("%s  ",tone[ch[i+j].rx_ctcss]);
                        freq=(float)(ref*ch[i+j].tx_div)/1000+tx_if;
                        if ((ch[i+j].tx_div&0x7fff)!=0x7fff) printf("%8.4f  %s\n",freq/1000,tone[ch[i+j].tx_ctcss]);
			else {
				if (color==1) printf("\033[32m");
				printf("rx only\n");
				if (color==1) printf("\033[0m");
			}
		}
		else printf(" -\n");
	}

	/* ------- center freqs ------------------------------------- */
	printf("\nCenter Frequencies for dual-VCO wide-band version\n");
	addr=0x3f9;
        /*rx divisor */
	x=eprom[addr+1];
        x=x<<8;
        x=x|(eprom[addr+2]);
        x=x<<1;
        x=x|((eprom[addr+3]&0x80)>>7);
        x=x<<6;
        x=x|(eprom[addr+3]&0x3f);
	x=x&0xffff;
	if (x!=0xffff) {
		freq=(ref*x/1000)+rx_if;
		printf("RX=%.4f\t",freq/1000);
	}
	else printf("empty\t");

	addr=0x3fc;
        /*tx divisor */
	x=eprom[addr+1];
        x<<=8;
        x=x|(eprom[addr+2]);
        x<<=1;
        x=x|((eprom[addr+3]&0x80)>>7);
        x<<=6;
        x=x|(eprom[addr+3]&0x3f);
	x=x&0xffff;
	if (x!=0xffff) {
		freq=ref*x/1000+tx_if;
		printf("TX=%.4f\n",freq/1000);
	}
	else printf("empty\n");
	/* -------------------------------------------------- */

printf("Last channel is %d\n",max_ch);
printf("RX frequency spread is %.4f - ",(float)(min_rx*ref+(rx_if*1000))/1000000);
	printf("%.4f\n",(float)(max_rx*ref+(rx_if*1000))/1000000);
printf("TX frequency spread is %.4f - ",(float)(min_tx*ref+(tx_if*1000))/1000000);
	printf("%.4f\n",(float)(max_tx*ref+(tx_if*1000))/1000000);

printf("Calculated center frequencies are RX: %.4f\t",(float)(((min_rx+max_rx)/2)*ref+(rx_if*1000))/1000000);
	printf("TX: %.4f\n",(float)(((min_tx+max_tx)/2)*ref+(tx_if*1000))/1000000);
}

int ch_addr(int ch) { /* z273 channel to EPROM address map	*/
	int address,y;
	y=ch%10;
	address=(ch-y)/10;
	address=address<<6;
	address=address|(y<<2);
	return(address);
}

unsigned char find_parity(long int div) {
	/* parity bit set to make even number of '1' bits in frequency and CTCSS */
	int i;
	unsigned char parity,count=0;
	for (i=0;i<21;i++) {
		if(div&0x01) count++;
		div >>=1;
	}
	if (count&0x01)
		parity=1;
	else
		parity=0;
	return (parity);
}

void edit_8channels() {
	char choice[10];
	int i,new_freq,y,c,new_channel;
	unsigned long int x;
	struct channel_bytes temp_channel;
	extern unsigned char eprom[0x800];
	extern int band,rx_if,tx_if;
	extern unsigned int ref;
	extern char tone[32][6];
	printf("\nYou are working with an 8 channel radio\n");
	printf("\nChannel to edit -> ");
	new_channel=int_input();
	if ((new_channel<1) | (new_channel>8)) return;
	printf ("\nCurrently channel %d:\n",new_channel);

	y=new_channel*5+11;
	x=eprom[y];
	x<<=15;
	x=x|((eprom[y+1]&0x0f)<<11);
	x=x|((eprom[y+2]&0x0f)<<7);
	x=x|((eprom[y+3]&0x08)<<3);
	x=x|((eprom[y+3]&0x03)<<4);
	x=x|(eprom[y+4]&0x0f);
	temp_channel.rx_div=x;

        x=eprom[y+40];
        x<<=15;
        x=x|((eprom[y+41]&0x0f)<<11);
        x=x|((eprom[y+42]&0x0f)<<7);
        x=x|((eprom[y+43]&0x08)<<3);
        x=x|((eprom[y+43]&0x03)<<4);
        x=x|(eprom[y+44]&0x0f);
        temp_channel.tx_div=x;

	y=new_channel*2+94;
	x=eprom[y];
        x<<=3;
        x=x|(0x07&(eprom[y+1]>>1));
	temp_channel.rx_ctcss=x^0x1f;

        x=eprom[y+16];
        x<<=3;
        x=x|(0x07&(eprom[y+17]>>1));
        temp_channel.tx_ctcss=x^0x1f;



	printf("Receive     RX CTCSS\tTransmit\tTX CTCSS\n");

	display_channel(&temp_channel);

	printf("\nEnter new receive frequency -> ");
	i=0; c=0;
	while(c!=10) {
		c=getchar();
		if(isdigit(c)) {
			choice[i]=c;
			i++;
		}
	}
	choice[i]=0;
	new_freq=atoi(choice);
	if (i>6)
		new_freq*=100;
	else
		new_freq*=1000;

	printf("You entered %d\n",new_freq);

	printf("old: ");
	display_channel(&temp_channel);

	temp_channel.rx_div=(long)(new_freq-(rx_if*1000))/ref;

	printf("new: ");
	display_channel(&temp_channel);

	printf("\n");
	for (i=0;i<28;i+=3) printf("%2d - %s\t\t%2d - %s\t\t%2d - %s\n",i,tone[i],i+1,tone[i+1],i+2,tone[i+2]);
	printf("30 - %s\t\t31 - Carrier\n",tone[30]);
        printf("\nEnter new receive CTCSS (0-31) ");

        i=0; c=0;
        while(c!=10) {
                c=getchar();
                if(isdigit(c)) {
                        choice[i]=c;
                        i++;
                }
        }
        choice[i]=0;
        new_freq=atoi(choice);
	printf("You entered %s\n",tone[new_freq]);
	temp_channel.rx_ctcss=new_freq;

	printf("Enter new transmit frequency -> ");

        i=0; c=0;
        while(c!=10) {
                c=getchar();
                if(isdigit(c)) {
                        choice[i]=c;
                        i++;
                }
        }
        choice[i]=0;
        new_freq=atoi(choice);
        if (i>6)
                new_freq*=100;
        else
                new_freq*=1000;

        printf("You entered %d\n",new_freq);

	printf("old: ");
	display_channel(&temp_channel);

	temp_channel.tx_div=new_freq/ref;

        printf("\nEnter new transmit CTCSS (0-31) ");

        i=0; c=0;
        while(c!=10) {
                c=getchar();
                if(isdigit(c)) {
                        choice[i]=c;
                        i++;
                }
        }
        choice[i]=0;
        new_freq=atoi(choice);
	printf("You entered %s\n",tone[new_freq]);
	temp_channel.tx_ctcss=new_freq;

	printf("new: ");
	display_channel(&temp_channel);

	/*--------- store new temp channel into eprom ---------------*/
		y=new_channel*5+11;
		x=temp_channel.rx_div;
		eprom[y+4]=(unsigned char)(x&0x0f);
		x>>=3;
		eprom[y+3]=(unsigned char)(x&0x08);
		x>>=1;
		eprom[y+3]|=(unsigned char)(x&0x03);
		x>>=3;
		eprom[y+2]=(unsigned char)(x&0x0f);
		x>>=4;
		eprom[y+1]=(unsigned char)(x&0x0f);
		x>>=4;
		eprom[y]=(unsigned char)(x&0x01);
		for(x=0;x<5;x++)
			eprom[y+x]|=0xf0;

        	y=new_channel*5+51;
	        x=temp_channel.tx_div;
        	eprom[y+4]=(unsigned char)(x&0x0f);
	        x>>=3;
        	eprom[y+3]=(unsigned char)(x&0x08);
	        x>>=1;
        	eprom[y+3]|=(unsigned char)(x&0x03);
	        x>>=3;
        	eprom[y+2]=(unsigned char)(x&0x0f);
	        x>>=4;
        	eprom[y+1]=(unsigned char)(x&0x0f);
        	x>>=4;
        	eprom[y]=(unsigned char)(x&0x01);
	        for(x=0;x<5;x++)
        	        eprom[y+x]|=0xf0;

		y=new_channel*2+0x5e;
		eprom[y]=(unsigned char)((temp_channel.rx_ctcss>>3)^0xff);
		eprom[y+1]=(unsigned char)(((temp_channel.rx_ctcss<<1)&0x0e) ^0xff);

		eprom[y+16]=(unsigned char)((temp_channel.tx_ctcss>>3)^0xff);
		eprom[y+17]=(unsigned char)(((temp_channel.tx_ctcss<<1)&0x0e) ^0xff);
		if (band==400) {
			eprom[0]=0xf3;	/* Band?	*/
		}
	update_header();
	z383();
	find_last_ch();
}

void edit_80channels() {
	int k,addr,new_channel;
	unsigned int i;
	long int new_freq,new_freq2;
	long int par;
	float freq;
	unsigned char c;
	char entry[15];
	char temp[15];
	char *success;
	struct channel_bytes temp_channel;
	extern unsigned char eprom[0x800];
	extern int rx_if,tx_if;
	extern unsigned int ref;
	extern char tone[32][6];
	extern struct channel_bytes ch[80];
	get_chan:
	printf("\nYou are working with an 80 channel radio (0-79)\n");
	printf("Which channel to edit? -> ");
	new_channel=int_input();
	if ((new_channel<0)|(new_channel>79))
		goto get_chan;
	printf("Editing channel %02d\n",new_channel);
		i=new_channel;
		if (ch[i].rx_div!=0xffff) {
			freq=(ref*ch[i].rx_div)/1000+rx_if;
			printf("%2d\t%8.4f\t",i,freq/1000);
			printf("%s\t\t",tone[ch[i].rx_ctcss]);
                        freq=(ref*ch[i].tx_div)/1000+tx_if;
                        if (ch[i].tx_div!=0xffff) printf("%8.4f\t%s\n",freq/1000,tone[ch[i].tx_ctcss]);
			else printf("rx only\n");
		}
	printf("Enter new Receive frequency xxx.xxxx -> ");
        success=fgets(entry,14,stdin);
        if (success==NULL) {
                printf("\nUnknown Error\n");
                return;
        }
        i=sscanf(entry,"%ld%s",&new_freq,temp);
	if (i==-1) { /* Delete channel */
		printf("Delete Channel\n");
		printf("This function not working\n");
		return;
	}
        if (i!=2) {
                printf("\nUnknown Error\n");
                return;
        }

	if (strncmp(temp,".",1)==0) {
		new_freq*=10000;
		i=strlen(temp);
		new_freq2=atoi(temp+1);
		switch (i){
			case 2:
				new_freq2*=1000; break;
			case 3:
				new_freq2*=100; break;
			case 4:
				new_freq2*=10;
			case 5:
				break;
			default:
				return;
		}
		new_freq+=new_freq2;
	}
	new_freq*=100;	
	temp_channel.rx_div=(long)(new_freq-(rx_if*1000))/ref;
	
	printf("Enter new Transmit frequency xxx.xxxx\n");
	printf("Just press Enter for RX Only		-> ");
        success=fgets(entry,14,stdin);
        if (success==NULL) {
                printf("\nUnknown Error\n");
                return;
        }
        i=sscanf(entry,"%ld%s",&new_freq,temp);
	if (i==-1) {
		temp_channel.tx_div=0xffff;
		temp_channel.tx_ctcss=0x1f;
		goto rx_only;
	}
        if (i!=2) {
                printf("\nUnknown Error\n");
                return;
        }

	if (strncmp(temp,".",1)==0) {
		new_freq*=10000;
		i=strlen(temp);
		new_freq2=atoi(temp+1);
		switch (i){
			case 2:
				new_freq2*=1000; break;
			case 3:
				new_freq2*=100; break;
			case 4:
				new_freq2*=10;
			case 5:
				break;
			default:
				return;
		}
		new_freq+=new_freq2;
	}
	new_freq*=100;	
	temp_channel.tx_div=(long)((new_freq-(tx_if*1000))/ref);
	rx_only:
	for (i=0;i<28;i+=3) printf("%2d - %s\t\t%2d - %s\t\t%2d - %s\n",i,tone[i],i+1,tone[i+1],i+2,tone[i+2]);
	printf("30 - %s\t\t31 - Carrier\n",tone[30]);
	k=32;
	while ((k>31)||(k<0)) {
        	printf("\nEnter new receive CTCSS (0-31) ");
		k=int_input();
	}
	temp_channel.rx_ctcss=k;
	if (temp_channel.tx_div==0xffff)
		goto no_tx;
	k=32;
	while ((k>31)||(k<0)) {
        	printf("Enter new Transmit CTCSS (0-31) ");
		k=int_input();
	}
	temp_channel.tx_ctcss=k;

		/*	freq=(ref*temp_channel.rx_div)/1000+rx_if;
			printf("%2d\t%8.4f\t",new_channel,freq/1000);
			printf("%s\t\t",tone[temp_channel.rx_ctcss]);
                        freq=(ref*temp_channel.tx_div)/1000+tx_if;
                        if (temp_channel.tx_div!=0xffff) printf("%8.4f\t%s\n",freq/1000,tone[temp_channel.tx_ctcss]);
		*/
	no_tx:
	par=temp_channel.rx_ctcss;
	par^=0x1f;
	par<<=16;
	par|=temp_channel.rx_div;
	temp_channel.rx_parity=find_parity(par);
	par=temp_channel.tx_ctcss;
	par^=0x1f;
	par<<=16;
	par|=temp_channel.tx_div;
	temp_channel.tx_parity=find_parity(par);
	ch[new_channel]=temp_channel;
	printf ("\nCh %2d\t",new_channel);
	display_channel(&ch[new_channel]);

	/* write change to eprom	*/
	addr=ch_addr(new_channel);
	if(ch[new_channel].rx_parity==1)
		eprom[addr+1]=64;
	else
		eprom[addr+1]=0;
	c=(unsigned char)ch[new_channel].rx_ctcss;
	c<<=1;
	eprom[addr+1]|=(unsigned char)(c^0x3e);

	if (band==50) {
		if (ch[new_channel].rx_div > 0x3fff)
			eprom[addr+1]|=0x01;
		i=ch[new_channel].rx_div>>6;
		eprom[addr+2]=(unsigned char)(i&0xff);

		i=ch[new_channel].rx_div;
		c=(unsigned char)(i&0x3f);
		c<<=2;
		c&=0x80;
		eprom[addr+3]=c;
		c=(unsigned char)(i&0x1f);
		eprom[addr+3]|=c;

	}
	else {
		if (ch[new_channel].rx_div>0x7fff)
			eprom[addr+1]|=0x01;

		i=ch[new_channel].rx_div>>7;
		eprom[addr+2]=(unsigned char)(i&0xff);

		i=ch[new_channel].rx_div;
		c=(unsigned char)(i&0x7f);
		c=c<<1;
		c&=0x80;
		eprom[addr+3]=c;
		c=(unsigned char)(i&0x03f);
		eprom[addr+3]|=c;
	}
	/* TalkAround RX data	*/
	eprom[addr+0x201]=eprom[addr+1];
	eprom[addr+0x202]=eprom[addr+2];
	eprom[addr+0x203]=eprom[addr+3];

	/* Transmit EPROM bytes	*/
	if(ch[new_channel].tx_parity==1)
		eprom[addr+0x401]=64;
	else
		eprom[addr+0x401]=0;
	c=ch[new_channel].tx_ctcss;
	c<<=1;
	eprom[addr+0x401]|=(unsigned char)(c^0x3e);

	if(band==50) {
		if (ch[new_channel].tx_div > 0x3fff)
			eprom[addr+0x401]|=0x01;
		i=ch[new_channel].tx_div>>6;
		eprom[addr+0x402]=(unsigned char)(i&0xff);

		i=ch[new_channel].tx_div;
		c=(unsigned char)(i&0x3f);
		c<<=2;
		c&=0x80;
		eprom[addr+0x403]=c;
		c=(unsigned char)(i&0x1f);
		eprom[addr+0x403]|=c;
	}
	else {
		if (ch[new_channel].tx_div>0x7fff)
			eprom[addr+0x401]|=0x01;

		i=ch[new_channel].tx_div>>7;
		eprom[addr+0x402]=(unsigned char)(i&0xff);

		i=ch[new_channel].tx_div;
		c=(unsigned char)(i&0x7f);
		c=c<<1;
		c&=0x80;
		eprom[addr+0x403]=c;
		c=(unsigned char)(i&0x03f);
		eprom[addr+0x403]|=c;
	}
	/* TalkAround TX data	*/
	/*** Needs work! must calculate new transmit ***/
	eprom[addr+0x601]=eprom[addr+0x401];
	eprom[addr+0x602]=eprom[addr+0x402];
	eprom[addr+0x603]=eprom[addr+0x403];

	return;
}

void edit_header() {
	char c=0;
	int i=0,offset=0x96;
	extern unsigned char eprom[0x800];
	extern int type;
	extern unsigned char head[64];
	if (type==80) offset=0x5f0;
	printf("\n\nEnter only HEX digits (0-9 and A-F) for the header.\n");
	printf("\nEnter 4 digit model #: ");
	while (c!=10) {
		c=toupper(getchar());
		if (isxdigit(c)&&c>64)
			head[i]=(unsigned char)(c-55);
		else
			head[i]=(unsigned char)atoi(&c);
		i++;
	}

	printf("\nEnter 8 digit serial #: ");
	i=4;c=0;
	while (c!=10) {
                c=toupper(getchar());
                if (isxdigit(c)&&c>64)
                        head[i]=(unsigned char)(c-55);
                else
                        head[i]=(unsigned char)atoi(&c);
                i++;
        }
        printf("\nEnter 3 digit area code: ");
        i=13;c=0;
        while (c!=10) {
                c=toupper(getchar());
                if (isxdigit(c)&&c>64)
                        head[i]=(unsigned char)(c-55);
                else
                        head[i]=(unsigned char)atoi(&c);
                i++;
        }

        printf("\nEnter 7 digit phone #: ");
        i=17;c=0;
        while (c!=10) {
                c=toupper(getchar());
                if (isxdigit(c)&&c>64)
                        head[i]=(unsigned char)(c-55);
                else
                        head[i]=(unsigned char)atoi(&c);
                i++;
        }

	update_header();
	if (type==8)
	        for (i=0;i<30;i++)
        	        eprom[i+offset]=head[i];
	else
		for (i=0;i<15;i++)
			eprom[offset+i]=(head[i*2]<<4)|head[i*2+1];

	if (type==8)
		head_383();
	else
		head_273();

}

void head_383() {
	unsigned char temp_c;
	extern unsigned char eprom[0x800],head[64];
	printf("Header information:\n\n");
	head[0]=eprom[0x96]; head[0]<<=4; temp_c=eprom[0x97]; temp_c &=0x0f; head[0]|=temp_c;
	head[1]=eprom[0x98]; head[1]<<=4; temp_c=eprom[0x99]; temp_c &=0x0f; head[1]|=temp_c;
	head[2]=eprom[0x9a]; head[2]<<=4; temp_c=eprom[0x9b]; temp_c &=0x0f; head[2]|=temp_c;
	head[3]=eprom[0x9c]; head[3]<<=4; temp_c=eprom[0x9d]; temp_c &=0x0f; head[3]|=temp_c;
	head[4]=eprom[0x9e]; head[4]<<=4; temp_c=eprom[0x9f]; temp_c &=0x0f; head[4]|=temp_c;
	head[5]=eprom[0xa0]; head[5]<<=4; temp_c=eprom[0xa1]; temp_c &=0x0f; head[5]|=temp_c;
	printf("%02X%02X\t%X%X%X%X\n",head[0],head[1],head[2],head[3],head[4],head[5]);

        head[0]=eprom[0xa2]; head[0]<<=4; temp_c=eprom[0xa3]; temp_c &=0x0f; head[0]|=temp_c;
        head[1]=eprom[0xa4]; head[1]<<=4; temp_c=eprom[0xa5]; temp_c &=0x0f; head[1]|=temp_c;
        head[2]=eprom[0xa6]; head[2]<<=4; temp_c=eprom[0xa7]; temp_c &=0x0f; head[2]|=temp_c;
        head[3]=eprom[0xa8]; head[3]<<=4; temp_c=eprom[0xa9]; temp_c &=0x0f; head[3]|=temp_c;
        head[4]=eprom[0xaa]; head[4]<<=4; temp_c=eprom[0xab]; temp_c &=0x0f; head[4]|=temp_c;
        head[5]=eprom[0xac]; head[5]<<=4; temp_c=eprom[0xad]; temp_c &=0x0f; head[5]|=temp_c;
	printf("%X%02X %X%02X %02X%02X\t",head[0],head[1],head[2],head[3],head[4],head[5]);

        head[0]=eprom[0xae]; head[0]<<=4; temp_c=eprom[0xaf]; temp_c &=0x0f; head[0]|=temp_c;
        head[1]=eprom[0xb0]; head[1]<<=4; temp_c=eprom[0xb1]; temp_c &=0x0f; head[1]|=temp_c;
        head[2]=eprom[0xb2]; head[2]<<=4; temp_c=eprom[0xb3]; temp_c &=0x0f; head[2]|=temp_c;
	printf("%02X-%02X-%02X\n\n",head[0],head[1],head[2]); 
}

void head_273() {
	extern unsigned char eprom[0x800];
        printf("Header information:\n\n");
        printf("%X%X\t%X%X%X%X\n",eprom[0x5f0],eprom[0x5f1],eprom[0x5f2],eprom[0x5f3],eprom[0x5f4],eprom[0x5f5]);
        printf("%X%X %X%02X %02X%02X\t",eprom[0x5f6],eprom[0x5f7],eprom[0x5f8],eprom[0x5f9],eprom[0x5fa],eprom[0x5fb]);
        printf("%02X-%02X-%02X\n",eprom[0x5fc],eprom[0x5fd],eprom[0x5fe]);
}

void save_eprom() {
	char save_file[255];
	int c;
	FILE *plug;
	extern unsigned char eprom[0x800];
	extern int type,max_ch;
	find_last_ch();
	if (type==80) {
		c=max_ch/10;
		c*=16;
		eprom[0x408]=(unsigned char)(c+(max_ch%10));
	}
	if (type==8) {
		eprom[1]=max_ch;
		eprom[1]|=0xf0;
	}
	printf("\nEnter name of file to be saved.  Remember 8.3 naming for DOS compatability.\n\n\t--> ");
	for (c=0;c<255;c++) {
		save_file[c]=getchar();
		if (save_file[c]==10) {save_file[c]=0; break;}
	}
	printf("Saving to file %s\n",save_file);
	plug=fopen(save_file,"wb");
	fwrite(eprom,0x800,1,plug);
	fclose(plug);
}

void edit_scan() {
	int i,k,max_a,max_b;
	unsigned char y=0;
	extern unsigned char scan_a[64],scan_b[64],eprom[0x800];
	extern int type;
	if (type==8) {
		z383();
		max_a=10;
		max_b=6;
		y=1;
	}
	else {
		z273();
		max_a=64;
		max_b=64;
	}
	
	for (i=0;i<max_a;i++) scan_a[i]=255;
	for (i=0;i<max_b;i++) scan_b[i]=255;

	printf("\nEnter new Priority scan list \"A\"\t(Enter non digit to end)\n");
	for (i=0;i<max_a;i++) {
		printf("Scan A #%d: ",i+1);
		k=int_input();
		if (k<0) break;
		if (k>79) {
			i--;
			continue;
		}
		if ((type==8)&&(k>8)) {
			i--;
			continue;
		}
        	scan_a[i]=(unsigned char)(k-y);
	}

        printf("\nEnter new scan list \"B\"\t(Enter non digit to end)\n");
        for (i=0;i<max_b;i++)
                {
                printf("Scan B #%d: ",i+1);
		k=int_input();
                if (k<0) break;
		if (k>79) {
			i--;
			continue;
		}
		if ((type==8)&&(k>8)) {
			i--;
			continue;
		}
                scan_b[i]=(unsigned char)(k-y);
                }


	for (i=0;i<max_a;i++) {
		if (type==8) eprom[0x80+i]=scan_a[i]|0xf0;
		if ((type==80)&&(scan_a[i]!=255)) {
			k=scan_a[i]/10;
			k*=16;
			eprom[i*4]=k+(scan_a[i]%10);
		}
	}
	for (i=0;i<max_b;i++) {
		if (type==8) eprom[0x8a+i]=scan_b[i]|0xf0;
		if ((type==80)&&(scan_b[i]!=255)) {
			k=scan_b[i]/10;
			k*=16;
			eprom[i*4+0x100]=k+(scan_b[i]%10);
		} 

	}
}

void edit_functions() {
	int i;
	extern unsigned char eprom[0x800],func[9];
	extern int type;
	printf("\nCurrently the Functions are:\n");
	print_functions();

	printf("\n0=BCLO without alert, 2=BCLO with alert, 3=disabled\nEnter BCLO code -> ");
	i=int_input();

	switch (i) {
		case 0: func[1]=0; break;
		case 1: func[1]=1; break;
		case 3: func[1]=3; break;
		default: func[1]=15;
	}
	printf("\n0=TOT disabled, 30 second steps\nEnter TOT multiplier value (0-7) -> ");
	i=int_input();
	if ((i<8)&&(i>=0))
		func[2]=(unsigned char)i;
	else
		func[2]=15;
	printf("Scan interval A (channel sample time) 25mS steps\n");	/* func[3]	*/
	printf("\tEnter multiplier (1-4) -> ");
	i=int_input();
	if ((i<5) & (i>0))
		func[3]=(unsigned char)i;
	else
		func[3]=1;
	printf("Scan interval B (CTCSS decode time) 100 mS steps\n");	/* func[4]	*/
	printf("\tEnter multiplier (1-4) ->");
	i=int_input();
	if ((i>0) & (i<5))
		func[4]=(unsigned char)i;
	else
		func[4]=3;
	printf("Scan hold times:\n");
	printf("\t\t0.3 Seconds - 0\n\t\t2.5 Seconds - 1\n");
	printf("\t\t5.0 Seconds - 2\n\t\t Infinite  -  3\n");
	printf("Scan hold time -> ");			/* func[5]	*/
	i=int_input();
	if ((i>=0)&&(i<4))
		func[5]=(unsigned char)i;
	else
		func[5]=15;
	printf("Scan hold time after PTT -> ");		/* func[6]	*/
	i=int_input();
	if ((i>=0)&&(i<4))
		func[6]=(unsigned char)i;
	else
		func[6]=15;
	printf("\nPriority:\n");
	printf("\nNo Function\t\t4 \n4 channels/1 sec\t0 \n8 channels/1 sec\t1\n");
	printf("4 channels/2 sec\t2\n8 channels/2 sec\t3\n");
	printf("Priority Monitor -> : ");
	func[7]=1;
	i=int_input();
	switch (i) {
		case 1: func[7]=0; break;
		case 2: func[7]=1; break;
		case 3: func[7]=2; break;
		case 4: func[7]=3; break;
		case 5: func[7]=4; break;
	}

	printf("\nScan Mode:\n");
	printf("\"NORMAL\"\n");
	printf("\tNoise Squelch/Busy\t0\n");
	printf("\tCTCSS/Busy\t\t1\n");
	printf("\tNoise Squelch/Open\t2\n");
	printf("\tCTCSS/Open\t\t3\n");

        printf("\"MODIFIED\"\n");
        printf("\tNoise Squelch/Busy\t4\n");
        printf("\tCTCSS/Busy\t\t5\n");
        printf("\tNoise Squelch/Open\t6\n");
        printf("\tCTCSS/Open\t\t7\n");

        printf("\"SECONDARY\"\n");
        printf("\tNoise Squelch/Busy\t8\n");
        printf("\tCTCSS/Busy\t\t9\n");
        printf("\tNoise Squelch/Open\t10\n");
        printf("\tCTCSS/Open\t\t11\n");

	printf("Enter Scan mode: -> ");
        func[8]=1;
	i=int_input();
	if ((i>=0) && (i<12))
		func[8]=(unsigned char)i;
			
	if (type==8) {
		/* store function data to 8 channel eprom */
		for (i=1;i<9;i++)
			eprom[i+1]=func[i]|0xf0;
	}
	else {
		/* store function data to 80 channel eprom */
		for (i=0;i<4;i++)
		eprom[i+0x3f0]=(func[i*2+1]<<4)|func[i*2+2];
	}
}

void edit_center() {
	unsigned int addr;
	unsigned long int x,rx_center,tx_center;
	long int par, new_freq,new_freq2;
	char * success;
	unsigned char c;
	float freq;
	int i;
	char entry[15],temp[15];
	extern unsigned char eprom[0x800];
	extern int type,rx_if,tx_if;
	extern unsigned int ref,min_rx,max_rx,min_tx,max_tx;
	if (type==8)
		return;

	printf("\nCurrent Center Frequencies for dual-VCO wide-band version\n");
	addr=0x3f9;
        /*rx divisor */
	x=eprom[addr+1];
        x=x<<8;
        x=x|(eprom[addr+2]);
        x=x<<1;
        x=x|((eprom[addr+3]&0x80)>>7);
        x=x<<6;
        x=x|(eprom[addr+3]&0x3f);
	x=x&0xffff;
	if (x!=0xffff) {
		freq=(ref*x/1000)+rx_if;
		printf("RX=%.4f\t",freq/1000);
	}
	else printf("empty\t");

	addr=0x3fc;
        /*tx divisor */
	x=eprom[addr+1];
        x<<=8;
        x=x|(eprom[addr+2]);
        x<<=1;
        x=x|((eprom[addr+3]&0x80)>>7);
        x<<=6;
        x=x|(eprom[addr+3]&0x3f);
	x=x&0xffff;
	if (x!=0xffff) {
		freq=ref*x/1000+tx_if;
		printf("TX=%.4f\n",freq/1000);
	}
	else printf("empty\n");
	printf("Calculated center RX frequency is %.4f\n",(float)(((min_rx+max_rx)/2)*ref+(rx_if*1000))/1000000);
	printf("Calculated center TX frequency is %.4f\n",(float)(((min_tx+max_tx)/2)*ref+(tx_if*1000))/1000000);
	printf("Enter new Receive center frequency xxx.xxxx -> ");
        success=fgets(entry,14,stdin);
        if (success==NULL) {
                printf("\nUnknown Error\n");
                return;
        }
        i=sscanf(entry,"%ld%s",&new_freq,temp);
        if (i!=2) {
                printf("\nUnknown Error\n");
                return;
        }

	if (strncmp(temp,".",1)==0) {
		new_freq*=10000;
		i=strlen(temp);
		new_freq2=atoi(temp+1);
		switch (i){
			case 2:
				new_freq2*=1000; break;
			case 3:
				new_freq2*=100; break;
			case 4:
				new_freq2*=10;
			case 5:
				break;
			default:
				return;
		}
		new_freq+=new_freq2;
	}
	new_freq*=100;	
	rx_center=(long)(new_freq-(rx_if*1000))/ref;
	
	printf("Enter new Transmit center frequency xxx.xxxx -> ");
        success=fgets(entry,14,stdin);
        if (success==NULL) {
                printf("\nUnknown Error\n");
                return;
        }
        i=sscanf(entry,"%ld%s",&new_freq,temp);
        if (i!=2) {
                printf("\nUnknown Error\n");
                return;
        }

	if (strncmp(temp,".",1)==0) {
		new_freq*=10000;
		i=strlen(temp);
		new_freq2=atoi(temp+1);
		switch (i){
			case 2:
				new_freq2*=1000; break;
			case 3:
				new_freq2*=100; break;
			case 4:
				new_freq2*=10;
			case 5:
				break;
			default:
				return;
		}
		new_freq+=new_freq2;
	}
	new_freq*=100;	
	tx_center=(long)((new_freq-(tx_if*1000))/ref);

	/* Write to eprom	*/
	if (rx_center>0x7fff)
		eprom[0x3fa]=0x01;
	else eprom[0x3fa]=0x00;

	i=rx_center>>7;
	eprom[0x3fb]=(unsigned char)(i&0xff);
	i=rx_center;
	c=(unsigned char)(i&0x7f);
	c=c<<1;
	c&=0x80;
	eprom[0x3fc]=c;
	c=(unsigned char)(i&0x03f);
	eprom[0x3fc]|=c;
	par=find_parity(rx_center);
	if (par==1)
		eprom[0x3fa]|=0x40;

	if (tx_center>0x7fff)
		eprom[0x3fd]=0x01;
	else eprom[0x3fd]=0x00;

	i=tx_center>>7;
	eprom[0x3fe]=(unsigned char)(i&0xff);
	i=tx_center;
	c=(unsigned char)(i&0x7f);
	c=c<<1;
	c&=0x80;
	eprom[0x3ff]=c;
	c=(unsigned char)(i&0x03f);
	eprom[0x3ff]|=c;
	par=find_parity(tx_center);
	if (par==1)
		eprom[0x3fd]|=0x40;
	return;
}

void print_functions()
	{
	extern unsigned char eprom[0x800],func[9];
        if (func[1]==0x0f)
		printf("BCLO default: Disabled\n");
        else printf("BCLO\t%d\t",func[1]);    /* Busy Channel Lockout - 0=BCLO without alert, 2=BCLO with alert, 3=disabled */
        switch (func[1]) {
        	case 0: printf("active without alert\t"); break;
                case 2: printf("active with alert\t"); break;
                case 3: printf("Disabled\t");
		default: break;
        }
        printf("JP107 installed for BCLO on busy, JP108 for BCLO on CTCSS\n");
        if (func[2]==0x0f)
		printf("TOT default: Disabled\n");
        else printf("TOT\t%d\t%d seconds\n",func[2],30*func[2]); /* TOT of 0 disables, 30 to 210 seconds in 30 second steps */

        if (func[3]==15)
		printf("Interval A Default - 25 mS\n");
	else
		if (func[3]!=5) printf("Interval A - channel scan sample rate\t%d mS\n",func[3]*25);
		else printf("Portables only - 12.5 mS\n");
        if (func[4]==15)
		printf("Interval B Default - 300 mS\n");
	else
		printf("Interval B - CTCSS decode time\t%d mS\n",func[4]*100);

        printf("Scan hold\t%X\n",func[5]);
        printf("Scan hold PTT\t%X\n",func[6]);

        printf("Pri Mon\t\t%X\t",func[7]);  /* 0=4ch/1sec, 1=8ch/1sec, 2=4ch/2sec, 3=8ch/2sec, 4=Priority disabled */
        switch (func[7]) {
                case 0: printf("Priority checked each 4 channels and once each second when stopped\n"); break;
                case 1: printf("Priority checked each 8 channels and once each second when stopped\n"); break;
                case 2: printf("Priority checked each 4 channels and once every 2 seconds when stopped\n"); break;
                case 3: printf("Priority checked each 8 channels and once every 2 seconds when stopped\n"); break;
                case 4: printf("Priority monitoring disabled\n");
		default: break;
        }
        if (func[7]==0x0f) printf("default: 8 channels/1 second\n");

        printf("Scan Format:\t%X\t",func[8]);
        switch (func[8]) {
                case 0: printf("Normal, stop on carrier\n"); break;
                case 1: printf("Normal, stop with proper CTCSS\n"); break;
                case 2: printf("Normal, stopped by absence of carrier\n"); break;
                case 3: printf("Normal, carrier without proper CTCSS\n"); break;
                case 4: printf("Modified, stop on carrier\n"); break;
                case 5: printf("Modified, stop with proper CTCSS\n"); break;
                case 6: printf("Modified, stopped by absence of carrier\n"); break;
                case 7: printf("Modified, carrier without proper CTCSS\n"); break;
                case 8: printf("Secondary, stop on carrier\n"); break;
                case 9: printf("Secondary,stop with proper CTCSS\n"); break;
                case 0x0a: printf("Secondary, stopped by absence of carrier\n"); break;
                case 0x0b: printf("Secondary, carrier without proper CTCSS\n"); break;
                case 0x0f: printf("default: NORMAL with CTCSS\n"); break;
                default: break;
        }
        printf("Channel change delay (Portables only) ");
        switch (eprom[0x404]) {
                case 0x72: printf("16 ms (default)\n"); break;
                case 0x7f: printf("30 ms\n"); break;
                case 0x7c: printf("40 ms\n"); break;
                case 0x79: printf("52 ms\n"); break;
                case 0x76: printf("66 ms\n"); break;
                default: break;
        }

        printf("Transmit to receive delay: ");
        if (eprom[0x3f4]==0xff)
		printf("default 0\n");
	else
		printf("%d ms\n",eprom[0x3f4]*50);
}

void display_channel (struct channel_bytes *ch) {
	extern int type,rx_if,tx_if;
	extern unsigned int ref;
	extern char tone[32][6];
	if (type==8) {
		/* 8 channel */ 
		printf("%.4f\t%s\t",((float)ch->rx_div*ref)/1000000+21.4,tone[ch->rx_ctcss]);
        	printf("%.4f\t%s\n",((float)ch->tx_div*ref)/1000000,tone[ch->tx_ctcss]);	
	}
	else {
		/* 80 channel */
		printf("%.4f\t%s\t",(float) ( (ch->rx_div*ref) + (rx_if*1000) ) /1000000,tone[ch->rx_ctcss]);
        	if (ch->tx_div !=0xffff)
		       printf("%.4f\t%s\n",(float) ( (ch->tx_div*ref) + (tx_if*1000) ) /1000000,tone[ch->tx_ctcss]);
		else
			printf("RX Only\n");
	}
}

void find_last_ch() {
	int i,j;
	extern int type,max_ch;
	extern unsigned int min_rx,max_rx,min_tx,max_tx;
	extern struct channel_bytes ch[80];
	max_ch=0;
	min_rx=0xffff;
	min_tx=0xffff;
	max_rx=0;
	max_tx=0;
	if (type==80)
		j=80;
	else
		j=8;
	for (i=0;i<j;i++) {
		if ((ch[i].rx_div&0x7fff) != 0x7fff) {
			max_ch=i;
			if (ch[i].rx_div>max_rx)
				max_rx=ch[i].rx_div;
			if (ch[i].rx_div<min_rx)
				min_rx=ch[i].rx_div;
		}
		if ((ch[i].tx_div&0x7fff) != 0x7fff) {
			if (ch[i].tx_div>max_tx)
				max_tx=ch[i].tx_div;
			if (ch[i].tx_div<min_tx)
				min_tx=ch[i].tx_div;
		}
	}
	return;
}

void edit_reference() {
	int i;
	extern unsigned char eprom[0x800];
	extern int band,type,rx_if,tx_if;
	extern unsigned int ref;
	printf("Current Reference is %d Hz (%.1f KHz)\n",ref,(float)ref/1000);
	printf("RX IF=%.2f MHz\t TX IF=%.2f MHz\t",(float)rx_if/1000,(float)tx_if/1000);
	if (rx_if<0)
		printf("High Injection\n");
	else
		printf("Low Injection\n");
	if (type==8)
		return;
		ref=0;
		while (ref==0) {
			printf("Enter a PLL reference freq. / injection\n");
			if (band<400) {
				printf("1 - 2.5 KHz / Low injection\n");
				printf("2 - 2.5 KHz / High injection\n");
			}
			if (band<800) {
				printf("3 - 5.0 KHz / Low injection\n");
				printf("4 - 5.0 KHz / High injection\n");
			}
			if (band==400) {
				printf("5 - 10.0 KHz / Low injection\n");
				printf("6 - 10.0 KHz / High injection\n");
			}
			printf("7 - 12.5 Khz / Low injection\n");
			printf("8 - 12.5 Khz / High injection\n");

			printf("Enter choice --> ");

			i=int_input();
			switch (i) {
				case 1: ref=2500; rx_if=21400;
					tx_if=20480;
					if (band==50) {
						rx_if=10700;
						tx_if=10240;
					}
					if (band==150)
						eprom[0x410]=0x32;
					 break;
				case 2: ref=2500; rx_if=-21400;
					tx_if=-20480;
					if (band==50) {
						rx_if=-10700;
						tx_if=-10240;
					}
					if (band==150)
						eprom[0x410]=0x4a;
					break;
				case 3: ref=5000; rx_if=21400;
					tx_if=20480;
					if (band==50) {
						rx_if=10700;
						tx_if=10240;
                                        }
					if (band==150)
						eprom[0x410]=0x02;
					if (band==400)
						eprom[0x410]=0x0b;
					break;
				case 4: ref=5000; rx_if=-21400;
					tx_if=-20480;
					if (band==50) {
                                        	rx_if=-10700;
                                                tx_if=-10240;
						eprom[0x410]=0x40;
                                        }
					if (band==150)
						eprom[0x410]=0x42;
					if (band==400)
						eprom[0x410]=0x4b;
					break;
				case 5: ref=10000; rx_if=21400;
					tx_if=20480; eprom[0x410]=0x23;
					break;
				case 6: ref=10000; rx_if=-21400;
					tx_if=-20480; eprom[0x410]=0x73;
					break;
				case 7: ref=12500;rx_if=21400;tx_if=19200;
						if (band==800) rx_if=47000;
						if (band==50) {
							rx_if=10700;
                                                        tx_if=9600;
                                                }
						if (band==150)
							eprom[0x410]=0x12;
						if (band==400)
							eprom[0x410]=0x03;
						break;
				case 8: ref=12500;rx_if=-21400;tx_if=-19200;
						if (band==800) rx_if=-47000;
						if (band==50) {
							rx_if=-10700;
							tx_if=-9600;
						}
						if (band==150)
							eprom[0x410]=0x52;
						if (band==400)
							eprom[0x410]=0x53;
						break;
				default: break; 
			}
		}
	return;
}

/* Linux integer sizes larger than DOS	*/
/* This is scaled to smaller integer sizes	*/
int int_input(void) {
	char * temp_ptr;
	char temp_buf[8], choice[8];
	int i,result;
	get_input:
	temp_ptr=fgets(choice,7,stdin);
	if (temp_ptr==NULL) {
		printf("error, try again: ");
		goto get_input;
	}
	i=strlen(choice);
	if (choice[i-1]!='\n') { /* clear buffer */
		i=0;
		while (i!='\n')
			i=getchar();
	}
	i=sscanf(choice,"%d%s",&result,temp_buf);
	if (i<1)
		result=-1; 
	return (result);
}

