summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Vymetálek <pavel@vym.cz>2015-07-22 15:39:03 +0200
committerPavel Vymetálek <pavel@vym.cz>2015-07-22 15:39:03 +0200
commit262319f218b165d2f483748e0e6b25ff0342ef09 (patch)
tree1a48993275ed7b300adf2565868ae401f1f4053f
parent0f4456a3280420cde1814ca3afc73d44ac364da0 (diff)
downloadtaptoserial-262319f218b165d2f483748e0e6b25ff0342ef09.tar.gz
Ukládá tapky ze ZX přijaté po sériáku, kotroluje XOR CSUM.
-rw-r--r--taptoser.c145
1 files changed, 110 insertions, 35 deletions
diff --git a/taptoser.c b/taptoser.c
index 1e0d4e0..70f7561 100644
--- a/taptoser.c
+++ b/taptoser.c
@@ -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) {