summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--taptoser.c85
1 files changed, 59 insertions, 26 deletions
diff --git a/taptoser.c b/taptoser.c
index 70f7561..f85c81b 100644
--- a/taptoser.c
+++ b/taptoser.c
@@ -29,6 +29,7 @@ char tap_file[FILENAME_LENGTH];
unsigned char in_buff[65538];
unsigned char *p_buff;
unsigned int is_continue = 1;
+unsigned int is_binary = 0;
struct pollfd spolfd_serial[1]; // pole descriptoru pro poll
static int inp_indx = 0;
@@ -51,6 +52,7 @@ void usage(void) {
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, --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");
}
@@ -87,11 +89,12 @@ void TestArgs (int argc, char *argv[])
{"outfile", required_argument, NULL, 'o'},
{"device", required_argument, NULL, 'd'},
{"baud", required_argument, NULL, 'b'},
+ {"binary", no_argument, NULL, 'B'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
- c = getopt_long (argc, argv, "o:d:b:vh", long_options, &option_index);
+ c = getopt_long (argc, argv, "o:d:b:Bvh", long_options, &option_index);
if (c == -1)
// konec parametru
break;
@@ -112,6 +115,10 @@ void TestArgs (int argc, char *argv[])
strncpy (output_dump_file, optarg, strlen(optarg));
is_outfile = 1;
break;
+ case 'B':
+ printf ("Running in binary output mode\n");
+ is_binary = 1;
+ break;
case 'v':
printf ("Version 0.0.1\n");
exit(1);
@@ -204,24 +211,37 @@ int GetTerminalWidth(void) {
return (termsize.ws_col);
}
-void DoProgress(size_t pos, size_t max) {
+#define PROGRESS_PERCENT 0
+#define PROGRESS_COMPLETTE 1
+#define PROGRESS_ERROR_CSUM 2
+
+void DoProgress(size_t pos, size_t max, unsigned char csum_ok) {
width = GetTerminalWidth();
float percent, p, m;
int imax = width - 40;
int ipercent;
int px;
+ char progress_char;
p = pos;
m = max;
percent = 100 / m * p;
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 ("=");
- else printf (" ");
+ if (px < ipercent) printf ("%c", progress_char);
+ else printf (" ");
+ }
+ if (csum_ok == 0) {
+ printf ("] %3d %%\r", (int)percent);
+ } else if (csum_ok == 1) {
+ printf ("] OK \r");
+ } else {
+ printf ("] ERR \r");
}
- printf ("] %3d %%\r", (int)percent);
fflush (stdout);
}
#define HEADER_RAW_LEN 21
@@ -231,10 +251,9 @@ void RecvTap() {
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 block_len = 10000;
size_t tap_pos = 0;
- unsigned char xor_csum;
+ unsigned char xor_csum, xor_csum_ok;
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
@@ -250,7 +269,6 @@ void RecvTap() {
// }
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) {
@@ -261,23 +279,26 @@ void RecvTap() {
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 (is_binary == 0) {
+ // ulozeni dat ze seriaku jako tap file
+ 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, PROGRESS_PERCENT);
+ }
+
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");
+// printf ("\nHlavicka komplet\n");
decode (in_buff + 2);
block_len = 0;
block_pos = 0;
@@ -287,7 +308,7 @@ void RecvTap() {
p_write = in_buff;
} else if (block_type == 255) {
// data block
- printf ("Data block: len: %d type: %d\n", block_len, block_type);
+ printf ("Data block len: %6zu\n", block_len-2);
recv_status = 3;
}
continue;
@@ -297,21 +318,33 @@ void RecvTap() {
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);
+ printf ("Block len: %zu 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");
+// 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");
+ xor_csum_ok = *(in_buff + 2 + block_len - 1);
+ if (xor_csum == xor_csum_ok) {
+ DoProgress(block_pos, block_len+2, PROGRESS_COMPLETTE); // vypis jeste OK
+ if (is_binary == 1) {
+ // binarni vystup do souboru
+ for (tap_pos = 0; tap_pos < block_len - 2; tap_pos++){
+ fputc(*(in_buff + 3 + tap_pos), tapout_fd); // uloz do souboru
+ }
+ DoProgress(tap_pos, block_len - 2, PROGRESS_COMPLETTE);
+
+ }
+// printf ("Checksum OK\n");
} else {
- printf ("Wrong checksum! 0%2.2X\n", xor_csum);
+ 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;
@@ -390,7 +423,7 @@ void SendTap() {
printf("Type: datablock\nLength: %u\n", len - 2);
pos += no = fread(header, 1, 1, tap_fd);
SendByte(header);
- DoProgress(1, no);
+ DoProgress(1, no, PROGRESS_PERCENT);
if (no != 1) tooshort(tap_fd);
printf("Flag: %u\n\n", (int)*header);
len--;
@@ -409,7 +442,7 @@ void SendTap() {
for (out_indx = 0; out_indx < len; out_indx++) {
fread(header, 1, 1, tap_fd);
SendByte(header);
- DoProgress(out_indx+1, len);
+ DoProgress(out_indx+1, len, PROGRESS_PERCENT);
if (is_continue == 0) break;
// printf ("len: %5d\r", out_indx);
// usleep (621);