From 9e6664c2db35fe654f9c0a0437d4eaeede8c0903 Mon Sep 17 00:00:00 2001 From: Pavel Vymetálek Date: Fri, 24 Jul 2015 09:31:57 +0200 Subject: Vyčištění kódu od balastu, oprava helpu, příprava na zveřejnění. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- taptoser.c | 165 +++++++++++++++++++++---------------------------------------- 1 file changed, 57 insertions(+), 108 deletions(-) diff --git a/taptoser.c b/taptoser.c index f85c81b..3e21f4d 100644 --- a/taptoser.c +++ b/taptoser.c @@ -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 \n"); + printf ("Tap file over serial port uploader/downloader. (c)2012-2015 Pavel Vymetálek \n"); + printf ("Based on utility tapheader: http://zeroteam.sk/tapheader.html (c)2012 Michal Jurica \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; -- cgit