diff options
| author | Pavel Vymetálek <pavel@vym.cz> | 2015-07-24 09:31:57 +0200 | 
|---|---|---|
| committer | Pavel Vymetálek <pavel@vym.cz> | 2015-07-24 09:31:57 +0200 | 
| commit | 9e6664c2db35fe654f9c0a0437d4eaeede8c0903 (patch) | |
| tree | f1bbb0ac1d3d29b54c1a21c1a7d6edf0f060e4b5 | |
| parent | 5e7641a297ed433cb58581006c85e25bdb17aa05 (diff) | |
| download | taptoserial-9e6664c2db35fe654f9c0a0437d4eaeede8c0903.tar.gz | |
Vyčištění kódu od balastu, oprava helpu, příprava na zveřejnění.
| -rw-r--r-- | taptoser.c | 165 | 
1 files changed, 57 insertions, 108 deletions
| @@ -37,23 +37,20 @@ int serial_fd;  size_t out_indx;  struct sigaction saterm;           /* definition of signal action */ - - -// variables for progress bar -unsigned int pos_progress; -float width, progress_pos, progress_part; +float width;		// width of terminal  long pos = 0;  void usage(void) { -	printf ("Tap file serial port uploader/downloader. (c)2012 Pavel Vymetálek <pvymetalek@seznam.cz>\n"); +	printf ("Tap file over serial port uploader/downloader. (c)2012-2015 Pavel Vymetálek <pavel@vym.cz>\n"); +	printf ("Based on utility tapheader: http://zeroteam.sk/tapheader.html (c)2012 Michal Jurica <mike@zeroteam.sk>\n");  	printf ("Usage:\ntaptoser [-v] [-h] [-o filename.tap] [-b|--baud baud_rate] -d /dev/serial tap_file\n"); -	printf ("\t-v, --version\tShow version info (program and protocol)\n"); +	printf ("\t-v, --version\tShow version info\n");  	printf ("\t-h, --help\tShow this text\n");  	printf ("\t-d, --device\tCommunication device\n"); -	printf ("\t-b, --baud\tSet the communication speed. 9600Bd or 19200Bd are supported by ZX Spectrum\n"); +	printf ("\t-b, --baud\tSet the communication speed. 4800Bd, 9600Bd, 19200Bd and 57600Bd (default) are supported\n");  	printf ("\t-B, --binary\tBinary output - received tap from ZX Spectrum will save without all tap's specific mishmash\n"); -	printf ("\t-o, --outfile\tOutput to file, instead of stdout. Without coloring ESC sequences\n"); +	printf ("\t-o, --outfile\tOutput file. Usualy *.tap or *.bin with in --binary mode\n");  }  void Set_DTR(unsigned short level) { @@ -61,8 +58,7 @@ void Set_DTR(unsigned short level) {  	ioctl(serial_fd, TIOCMGET, &status);  	if (level) {  		status |= TIOCM_DTR; -	} -	else { +	} else {  		status &= ~TIOCM_DTR;  	}  	ioctl(serial_fd, TIOCMSET, &status); @@ -95,10 +91,10 @@ void TestArgs (int argc, char *argv[])  			{0, 0, 0, 0}  		};  		c = getopt_long (argc, argv, "o:d:b:Bvh", long_options, &option_index); -		if (c == -1) +		if (c == -1) {  			// konec parametru  			break; - +		}  		switch (c) {  			case 'h':  				usage(); @@ -120,76 +116,65 @@ void TestArgs (int argc, char *argv[])  				is_binary = 1;  				break;  			case 'v': -				printf ("Version 0.0.1\n"); +				printf ("Version 0.9.1 2015-07-22\n");  				exit(1);  				break;  			default:  				break;  		}  	} -//	if (baud_rate != 9600 && baud_rate != 19200) baud_rate = 19200; -/* Done with options.  OPTIND points to first nonoption argument.  */  	if (optind < argc) {  		while (optind < argc){ -			strncpy (&tap_file[0], argv[optind++], 63); +			strncpy (&tap_file[0], argv[optind++], 63);		// input tap file name - without option switch  		}  	}  } - -// TAP - - - +// from tapheader utility  unsigned int h_len; -unsigned int getword(unsigned char* data) -{ +unsigned int getword(unsigned char* data) {  	return *data + 256 * (*(data + 1));  } -void tooshort(FILE *fd) -{ +void tooshort(FILE *fd) {  	printf("Input file too short.\n\n");  	fclose(fd);  	exit(2);  }  // decode header1 -void decode(unsigned char *header) -{ +void decode(unsigned char *header) {  	char name[11];  	unsigned int n; - +	printf("\n");  	strncpy(name, (char*)(header+2), 10);  	name[10] = '\0'; -	printf("Filename: %s\n", name); -	printf("Flag: %u\n", (unsigned int)*header); +	printf("Filename: %12s \n", name); +	printf("Flag: %4u ", (unsigned int)*header);  	n = getword(header+14);  	h_len = getword(header+12); -	switch(*(header+1)) -	{ +	switch(*(header+1)) {  		case '\0': -			printf("Type: 0 => program\nProgram length: %u bytes\n", h_len); -			if (n < 32768)	printf("Runs from line %u\n", n); -			printf("Length without variables: %u bytes\n", -			getword(header+16)); +			printf("Type: 0 => program\nProgram length: %6u bytes ", h_len); +			if (n < 32768)	printf("Runs from line %5u\t", n); +			printf("Length without variables: %5u bytes ", getword(header+16));  			break;  		case '\1': -			printf("Type: 1 => number array\nLength: %u bytes\n", h_len); +			printf("Type: 1 => number array\tLength: %6u bytes", h_len);  			break;  		case '\2': -			printf("Type: 2 => character array\nLength: %u bytes\n", h_len); +			printf("Type: 2 => character array\tLength: %6u bytes", h_len);  			break;  		case '\3':  			if (n == 16384 && h_len == 6912)  				printf("Type: 3 => screen image\n");  			else -				printf("Type: 3 => bytes\n" -					"Start address: %u\n" -					"Length: %u bytes\n3rd param: %u\n", +				printf("Type: 3 => bytes  " +					"Start address: %5u\t" +					"Length: %6u bytes\t3rd param: %4u",  					n, h_len, getword(header+16));  			break;  	} @@ -197,12 +182,8 @@ void decode(unsigned char *header)  }  void signal_handler_sigterm (int status) { -	is_continue = 0; -// 	if (is_outfile) { -// 		fclose (tapout_fd); -// 	} -// 	printf ("\n\nbye...\n"); -// 	exit (0); +	// CTRL+C pressed +	is_continue = 0; 	// do not continue  }  int GetTerminalWidth(void) { @@ -228,8 +209,6 @@ void DoProgress(size_t pos, size_t max, unsigned char csum_ok) {  	ipercent = percent / 100 * imax;   	if (is_binary) progress_char = '#';  	else  progress_char = '='; -	 -// 	printf ("\npercent: %f, ipercent: %d\n", percent, ipercent);  	printf ("Proceed bytes: %6d/%6d [", (int) pos, (int)max);  	for (px = 0; px < imax; px++) {  		if (px < ipercent) printf ("%c", progress_char); @@ -244,6 +223,7 @@ void DoProgress(size_t pos, size_t max, unsigned char csum_ok) {  	}  	fflush (stdout);  } +  #define HEADER_RAW_LEN	21  void RecvTap() { @@ -262,11 +242,7 @@ void RecvTap() {  		err = errno;  		error (1, err, "can't open output file");  	} -// 	if (is_outfile) { -		printf("Output file is: %s\n", output_dump_file); -// 	} else { -// 		outfile = stdout; -// 	} +	printf("Output file is: %s\n", output_dump_file);  	p_buff = in_buff;  	p_write = in_buff;  	while (is_continue) { @@ -291,14 +267,12 @@ void RecvTap() {  				last_block_pos = block_pos;  				DoProgress(block_pos, block_len+2, PROGRESS_PERCENT);  			} -  			if (block_pos >= HEADER_RAW_LEN && recv_status == 0) {  				recv_status = 1;		// hlavicka nactena  				block_len = getword(in_buff);  				block_type = *(in_buff + 2); -// 				printf ("Block len: %d Header type: %d\n", block_len, block_type);  				if (block_type == 0) { -// 					printf ("\nHlavicka komplet\n"); +					// Hlavicka komplet  					decode (in_buff + 2);  					block_len = 0;  					block_pos = 0; @@ -322,10 +296,10 @@ void RecvTap() {  				continue;  			}  			if (block_len + 2 == block_pos && recv_status > 2) { -// 				printf ("\nBlok komplet nacten cekej novy\n"); +				// Blok komplet nacten cekej novy  				block_len = getword(in_buff);  				block_type = *(in_buff + 2); -				for (tap_pos = 0; tap_pos < block_len -1; tap_pos++){ +				for (tap_pos = 0; tap_pos < block_len -1; tap_pos++) {  					xor_csum ^= *(in_buff + 2 + tap_pos);  				}  				xor_csum_ok = *(in_buff + 2 + block_len - 1); @@ -337,14 +311,11 @@ void RecvTap() {  							fputc(*(in_buff + 3 + tap_pos), tapout_fd);	// uloz do souboru  						}  						DoProgress(tap_pos, block_len - 2, PROGRESS_COMPLETTE); -  					}  // 					printf ("Checksum OK\n");  				} else {  					DoProgress(block_pos, block_len+2, PROGRESS_ERROR_CSUM);	// vypis error CSUM -// 					printf ("Wrong checksum! 0%2.2X\n", xor_csum);  				} -  				block_len = 0;  				block_pos = 0;  				xor_csum = 0; @@ -353,25 +324,17 @@ void RecvTap() {  				p_write = in_buff;  				continue;  			} -  		} - -  	}  	fclose (tapout_fd); -	  	printf ("\n\nulozeno...\n");  }  void SendByte(unsigned char *p_dato) { -// 	unsigned char dat;  	TestCts(); -	// write byte to serial port -// 	dat = *p_dato; -// 	printf ("%2.2X ", dat);  	write (serial_fd, p_dato, 1); -// // 	tcdrain(serial_fd); -	usleep (200); +// 	tcdrain(serial_fd);		// better solution, but usleep at the next line is +	usleep (200);			// faster solution, TODO change sleep time according to serial communication speed  200us is for 57600Bd  }  void SendTap() { @@ -391,33 +354,28 @@ void SendTap() {  		err = errno;  		error(1, err, "can't open input file");  	} -	  	while (pos < st.st_size) {  		if (is_continue == 0) break;  		pos += no = fread(header, 1, 2, tap_fd);  		if (no != 2)  			tooshort(tap_fd);  		for (out_indx = 0; out_indx < 2; out_indx++) { -			progress_pos = 0; -			printf("[");  			SendByte(&header[out_indx]);  		} -		  		no = getword(header);  		if (no == 19) /* HEADER */  		{  			pos += no = fread(header, 1, 19, tap_fd);  			if (no != 19)  				tooshort(tap_fd); -			printf ("NO header: %d\n", no); +// 			printf ("Header len: %d\n", no);  			decode(header);  			for (out_indx = 0; out_indx < 19; out_indx++) {  				SendByte(&header[out_indx]);  			} -			usleep (10000); +			usleep (400000);  		} else { -			if (h_len != no - 2) /* zobrazuj iba bloky bez hl. */ -			{ +			if (h_len != no - 2) { /* zobrazuj iba bloky bez hl. */  				len = no;  				printf ("NO datablock without header: %d\n", no);  				printf("Type: datablock\nLength: %u\n", len - 2); @@ -427,25 +385,15 @@ void SendTap() {  				if (no != 1) tooshort(tap_fd);  				printf("Flag: %u\n\n", (int)*header);  				len--; -			} -			else { +			} else {  				len = no;  			}  			pos += len; -			// 			no = fseek(fd, pos, SEEK_SET); -			// 			if (no != 0) -			// 			{ -			// 				err = errno; -			// 				error(1, err, "can't seek in input file"); -			// 			} -			printf ("NO datablock: %d\n\n", len);  			for (out_indx = 0; out_indx < len; out_indx++) {  				fread(header, 1, 1, tap_fd);  				SendByte(header);  				DoProgress(out_indx+1, len, PROGRESS_PERCENT);  				if (is_continue == 0) break; -				//	printf ("len: %5d\r", out_indx); -				// 	usleep (621);  			}  			printf ("\n");  		} @@ -462,17 +410,15 @@ int main(int argc, char** argv, char** env)  	sigaction (SIGINT, &saterm, NULL);  	width = GetTerminalWidth(); +	// nastaveni serioveho portu  	struct termios oldtio, newtio;  	inp_indx = 0;  	if (argc < 3) { -	  printf("You must specify the Serial device and file\n"); -	  usage(); -	  exit(1); +		printf("You must specify the Serial device and file\n"); +		usage(); +		exit(1);  	} -	printf ("tu som... \n");  	TestArgs (argc, argv); -	 -	printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate);  	/* open the device to be non-blocking (read will return immediatly) */  	serial_fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);  	if (serial_fd < 0) { @@ -482,6 +428,9 @@ int main(int argc, char** argv, char** env)  	tcgetattr(serial_fd, &oldtio); /* save current port settings */  	switch (baud_rate){  		default: +			baud_rate = 57600;			// default speed +			newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break;  		case 57600:  			newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS;  			break; @@ -491,8 +440,12 @@ int main(int argc, char** argv, char** env)  		case 9600:  			newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS;  			break; +		case 4800: +			newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break;  	} -	newtio.c_iflag &= ~(IXON | IXOFF | IXANY);	// zrusit XON XOFF +	printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate); +	newtio.c_iflag &= ~(IXON | IXOFF | IXANY);	// vypne XON/XOFF  	newtio.c_iflag = IGNPAR | IXOFF;  	newtio.c_oflag = 0;  	newtio.c_oflag &= ~OPOST; @@ -501,18 +454,14 @@ int main(int argc, char** argv, char** env)  	newtio.c_cc[VTIME] = 10;  	tcsetattr(serial_fd, TCSANOW, &newtio);  	tcflush(serial_fd, TCIOFLUSH); -	spolfd_serial[0].fd = serial_fd;			// nastaveni hlidaneho descriptoru -	spolfd_serial[0].events = POLLIN;	// hlidaji se data na vstupu +	spolfd_serial[0].fd = serial_fd;		// nastaveni hlidaneho descriptoru +	spolfd_serial[0].events = POLLIN;		// hlidaji se data na vstupu - -	Set_DTR(true); -	 +	Set_DTR(true);		// PC can read data from speccy everytime  	if (is_outfile) { -		// cteni souboru ze seriaku -		RecvTap(); +		RecvTap();	// cteni tap souboru ze seriaku a zapis na disk pocitace  	} else { -		// poslat na seriak tap soubor -		SendTap(); +		SendTap();	// poslat na seriak tap soubor do spectra  	}  	close (serial_fd);  	return 0; | 
