diff options
author | Pavel Vymetálek <pavel@vym.cz> | 2015-07-22 15:39:03 +0200 |
---|---|---|
committer | Pavel Vymetálek <pavel@vym.cz> | 2015-07-22 15:39:03 +0200 |
commit | 262319f218b165d2f483748e0e6b25ff0342ef09 (patch) | |
tree | 1a48993275ed7b300adf2565868ae401f1f4053f | |
parent | 0f4456a3280420cde1814ca3afc73d44ac364da0 (diff) | |
download | taptoserial-262319f218b165d2f483748e0e6b25ff0342ef09.tar.gz |
Ukládá tapky ze ZX přijaté po sériáku, kotroluje XOR CSUM.
-rw-r--r-- | taptoser.c | 145 |
1 files changed, 110 insertions, 35 deletions
@@ -10,6 +10,7 @@ #include <sys/ioctl.h> #include <sys/signal.h> #include <fcntl.h> +#include <poll.h> #define false 0 #define FALSE 0 @@ -25,9 +26,10 @@ int baud_rate = 0; #define FILENAME_LENGTH 400 char output_dump_file[FILENAME_LENGTH]; char tap_file[FILENAME_LENGTH]; -unsigned char in_buff[16386]; +unsigned char in_buff[65538]; unsigned char *p_buff; -unsigned int is_reading = 1; +unsigned int is_continue = 1; +struct pollfd spolfd_serial[1]; // pole descriptoru pro poll static int inp_indx = 0; int serial_fd; @@ -70,6 +72,7 @@ void TestCts(void) { ioctl(serial_fd, TIOCMGET, &status); if (status & 0x20) break; usleep (100); + if (is_continue == 0) return; // printf ("status: %X\n",status); } while (1); } @@ -146,7 +149,7 @@ void tooshort(FILE *fd) exit(2); } -// decode header +// decode header1 void decode(unsigned char *header) { char name[11]; @@ -178,8 +181,8 @@ void decode(unsigned char *header) printf("Type: 3 => screen image\n"); else printf("Type: 3 => bytes\n" - "Start address: %u bytes\n" - "Length: %u\n3rd param: %u\n", + "Start address: %u\n" + "Length: %u bytes\n3rd param: %u\n", n, h_len, getword(header+16)); break; } @@ -187,7 +190,7 @@ void decode(unsigned char *header) } void signal_handler_sigterm (int status) { - is_reading = 0; + is_continue = 0; // if (is_outfile) { // fclose (tapout_fd); // } @@ -213,7 +216,7 @@ void DoProgress(size_t pos, size_t max) { ipercent = percent / 100 * imax; // printf ("\npercent: %f, ipercent: %d\n", percent, ipercent); - printf ("Received bytes: %6d/%6d [", (int) pos, (int)max); + printf ("Proceed bytes: %6d/%6d [", (int) pos, (int)max); for (px = 0; px < imax; px++) { if (px < ipercent) printf ("="); else printf (" "); @@ -221,10 +224,20 @@ void DoProgress(size_t pos, size_t max) { printf ("] %3d %%\r", (int)percent); fflush (stdout); } +#define HEADER_RAW_LEN 21 void RecvTap() { - unsigned int err, len; - size_t total_len = 0, last_len = 0; + unsigned int err; + size_t len; + int result; + size_t block_pos = 0, last_block_pos = 0; + size_t tap_len, block_len = 10000; + size_t block_len_read = 0; + size_t tap_pos = 0; + unsigned char xor_csum; + unsigned char *p_write; + unsigned char block_type; // typ bloku 255 data 0 - hlavicka + unsigned char recv_status = 0; // 0 - zacatek, 1 - hlavicka nactena, 2 - blok se nacita, 3- header less tapout_fd = fopen (output_dump_file, "a"); if (tapout_fd == NULL) { err = errno; @@ -235,21 +248,82 @@ void RecvTap() { // } else { // outfile = stdout; // } - while (is_reading) { - usleep (100000); - len = read (serial_fd, in_buff, 256); - p_buff = in_buff; - total_len += len; - p_buff += len; - while (len) { - fputc(*p_buff, tapout_fd); - p_buff++; - len--; - if (total_len != last_len) { - last_len = total_len; - DoProgress(total_len, 16384); + p_buff = in_buff; + p_write = in_buff; + block_len_read = 0; + while (is_continue) { + result = poll (spolfd_serial, 1, 200); // 200ms timeout + if (result == 0) { + // nic neprislo + continue; + } + if (spolfd_serial[0].revents & POLLIN) { + len = read (serial_fd, p_buff, 256); + block_pos += len; + p_buff += len; + while (len) { + fputc(*p_write, tapout_fd); + p_write++; + len--; + if (block_pos != last_block_pos && recv_status >= 2) { + last_block_pos = block_pos; + DoProgress(block_pos, block_len+2); + } + } + if (block_pos >= HEADER_RAW_LEN && recv_status == 0) { + recv_status = 1; // hlavicka nactena +// block_pos = 0; + 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"); + decode (in_buff + 2); + block_len = 0; + block_pos = 0; + xor_csum = 0; + recv_status = 0; + p_buff = in_buff; + p_write = in_buff; + } else if (block_type == 255) { + // data block + printf ("Data block: len: %d type: %d\n", block_len, block_type); + recv_status = 3; + } + continue; } + if (block_pos > HEADER_RAW_LEN + 3 && recv_status == 1) { + // nactena delka dalsiho bloku + recv_status = 2; + block_len = getword(in_buff + HEADER_RAW_LEN); + block_type = *(in_buff + HEADER_RAW_LEN + 2); + printf ("Block len: %d Block type: %d\n", block_len, block_type); + continue; + } + if (block_len + 2 == block_pos && recv_status > 2) { + printf ("\nBlok komplet nacten cekej novy\n"); + block_len = getword(in_buff); + block_type = *(in_buff + 2); + for (tap_pos = 0; tap_pos < block_len -1; tap_pos++){ + xor_csum ^= *(in_buff + 2 + tap_pos); + } + if (xor_csum == *(in_buff + 2 + block_len - 1)) { + printf ("Checksum OK\n"); + } else { + printf ("Wrong checksum! 0%2.2X\n", xor_csum); + } + block_len = 0; + block_pos = 0; + xor_csum = 0; + recv_status = 0; + p_buff = in_buff; + p_write = in_buff; + continue; + } + } + + } fclose (tapout_fd); @@ -257,12 +331,12 @@ void RecvTap() { } void SendByte(unsigned char *p_dato) { - unsigned char dat; -// TestCts(); +// unsigned char dat; + TestCts(); // write byte to serial port - dat = *p_dato; - printf ("%2.2X ", dat); -// write (serial_fd, p_dato, 1); +// dat = *p_dato; +// printf ("%2.2X ", dat); + write (serial_fd, p_dato, 1); // // tcdrain(serial_fd); usleep (200); } @@ -286,6 +360,7 @@ void SendTap() { } while (pos < st.st_size) { + if (is_continue == 0) break; pos += no = fread(header, 1, 2, tap_fd); if (no != 2) tooshort(tap_fd); @@ -305,7 +380,6 @@ void SendTap() { decode(header); for (out_indx = 0; out_indx < 19; out_indx++) { SendByte(&header[out_indx]); - usleep (3000); } usleep (10000); } else { @@ -316,12 +390,7 @@ void SendTap() { printf("Type: datablock\nLength: %u\n", len - 2); pos += no = fread(header, 1, 1, tap_fd); SendByte(header); - progress_part = h_len / width; - // for (progress_pos = 0; progress_pos < out_indx*progress_part; progress_pos++) { - // printf ("#\r"); - // } - - // usleep (1000); + DoProgress(1, no); if (no != 1) tooshort(tap_fd); printf("Flag: %u\n\n", (int)*header); len--; @@ -340,6 +409,8 @@ void SendTap() { for (out_indx = 0; out_indx < len; out_indx++) { fread(header, 1, 1, tap_fd); SendByte(header); + DoProgress(out_indx+1, len); + if (is_continue == 0) break; // printf ("len: %5d\r", out_indx); // usleep (621); } @@ -395,8 +466,12 @@ int main(int argc, char** argv, char** env) newtio.c_lflag = NOFLSH; newtio.c_cc[VMIN] = 0; newtio.c_cc[VTIME] = 10; - tcflush(serial_fd, TCIOFLUSH); 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 + + Set_DTR(true); if (is_outfile) { |