summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Vymetálek <pavel@vym.cz>2019-01-09 16:59:07 +0100
committerPavel Vymetálek <pavel@vym.cz>2019-01-09 16:59:07 +0100
commita6ddb2c4314ff0647630a611b3d4d22c88c7c7f5 (patch)
tree035bfb8a30110742869f91a52267cbea78bdf92a
parent2d85f0135ab0dbfb788606fc6987203bd4239611 (diff)
downloadtaptoserial-a6ddb2c4314ff0647630a611b3d4d22c88c7c7f5.tar.gz
Přidáno vysílání scp - včetně vytvoření fileinfo tabulky
- default mezera mezi bloky je 800ms
-rw-r--r--taptoser.c108
1 files changed, 106 insertions, 2 deletions
diff --git a/taptoser.c b/taptoser.c
index 87c9f15..bf6e061 100644
--- a/taptoser.c
+++ b/taptoser.c
@@ -25,6 +25,7 @@ FILE *tapout_fd = NULL;
int is_outfile = 0;
int baud_rate = 0;
int wait_us = 200;
+int wait_ms = 800;
#define FILENAME_LENGTH 400
char output_dump_file[FILENAME_LENGTH];
char tap_file[FILENAME_LENGTH];
@@ -75,6 +76,10 @@ void usage(void) {
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 file. Usualy *.tap or *.bin with in --binary mode\n");
+ printf ("SCP mode -----\n");
+ printf ("\t-s, --scp\tSCP mode - sent files with fileinfo 1109bytes\n");
+ printf ("\t-r, --read\tread file\n");
+ printf ("\t-w, --wait\tWaiting in milliseconds between transmitted blocks. Default is -w 800 milliseconds\n");
}
void Set_DTR(unsigned short level) {
@@ -132,6 +137,7 @@ void TestArgs (int argc, char *argv[])
break;
case 'w':
wait_us = atoi(optarg);
+ wait_ms = atoi(optarg);
break;
case 's':
printf ("Serial CP mode is activated\n");
@@ -458,6 +464,22 @@ int CheckFileInfo(FILEINFO* p_fi) {
return -1;
}
+void CountFileInfoChecksum(FILEINFO* p_fi) {
+ unsigned char *p_fiinfo = (unsigned char*)p_fi;
+ uint16_t fi_len;
+ uint8_t fi_xor = 0;
+ uint8_t fi_sum = 0;
+ fi_len = p_fi->length;
+ p_fiinfo += 4; // suma se bude pocitat od offsetu 4
+ for (uint16_t indx = 0; indx < (fi_len-4); indx++) {
+ fi_xor ^= *p_fiinfo;
+ fi_sum += *p_fiinfo;
+ p_fiinfo++;
+ }
+ p_fi->h_xor = fi_xor;
+ p_fi->h_sum = fi_sum;
+}
+
int CheckSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer) {
uint16_t block_len;
uint8_t b_xor = 0;
@@ -478,6 +500,20 @@ int CheckSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer) {
return -1; // vrat se s chybou bloku
}
+void CountSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer, uint16_t block_len) {
+ uint8_t block_xor = 0;
+ uint8_t block_sum = 0;
+ for (uint16_t indx = 0; indx < block_len; indx++) {
+ block_xor ^= *p_buffer;
+ block_sum += *p_buffer;
+ p_buffer++;
+ }
+ p_fi->fi_blocks[block_indx].block_len = block_len;
+ p_fi->fi_blocks[block_indx].block_sum = block_sum;
+ p_fi->fi_blocks[block_indx].block_xor = block_xor;
+}
+
+
unsigned char buff[32768];
uint32_t GetOverallLen(FILEINFO *p_fi) {
@@ -591,7 +627,75 @@ void RecvSCP(void) {
}
void SendSCP(void) {
+ FILE *tap_fd;
+ unsigned int err, no, len;
+ struct stat st;
+ FILEINFO *p_fileinfo = &fileinfo;
+ unsigned char *p_buff = buff;
+ uint32_t file_len;
+ uint8_t num_blocks = 0;
+ ssize_t odeslano;
+ uint32_t len_sent;
+ uint16_t sent_size;
+ uint32_t overall_sent;
+
+
+ no = stat(tap_file, &st);
+ if (no != 0) {
+ err = errno;
+ error(1, err, "can't stat input file");
+ }
+ tap_fd = fopen(tap_file, "r");
+ if (tap_fd == NULL) {
+ err = errno;
+ error(1, err, "can't open input file");
+ }
+ printf ("Soubor %s delky: %ld\n", tap_file, st.st_size);
+ memset (p_fileinfo, 0, sizeof(fileinfo)); // smazat fileinfo
+
+ memcpy(p_fileinfo->fi_name, tap_file, strlen(tap_file));
+ file_len = (uint32_t) st.st_size;
+ while (file_len) {
+ len = fread(buff, 1, 16384, tap_fd); // precti 16kiB dat
+ CountSumBlock(p_fileinfo, num_blocks, buff, len);
+// printf ("Blok c. %d, delka: %d\n", num_blocks, len);
+ file_len -= len;
+ num_blocks++;
+ }
+ p_fileinfo->fi_numblocks = num_blocks;
+ p_fileinfo->length = num_blocks*4 + 85;
+ CountFileInfoChecksum(p_fileinfo);
+ odeslano = write (serial_fd, (void*)p_fileinfo, sizeof(fileinfo));
+ tcdrain(serial_fd);
+ printf("Fileinfo sent...\n");
+ // TODO Cekat pauzu mezi bloky
+ usleep (wait_ms * 1000);
+
+ rewind(tap_fd); // prenaseny soubor na zacatek
+ file_len = (uint32_t) st.st_size;
+ overall_sent = 0;
+ while (file_len && is_continue) {
+ len = fread(buff, 1, 16384, tap_fd); // precti 16kiB dat
+ p_buff = buff;
+ sent_size = 256;
+ len_sent = len;
+ while (len_sent && is_continue) {
+ odeslano = write (serial_fd, (void*)p_buff, sent_size);
+ tcdrain(serial_fd);
+ p_buff += odeslano;
+ overall_sent += odeslano;
+ len_sent -= odeslano;
+ if (len_sent < 256) {
+ sent_size = len_sent;
+ }
+ DoProgress(overall_sent, st.st_size, PROGRESS_PERCENT);
+ }
+ usleep (wait_ms * 1000);
+ file_len -= len;
+ }
+ printf("\nFile sent...\n");
+ fclose(tap_fd);
}
int main(int argc, char** argv, char** env)
@@ -630,7 +734,7 @@ int main(int argc, char** argv, char** env)
newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS;
break;
case 38400:
- newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD | CRTSCTS; // dva stopbity jsou nastaveny vsude
+ newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD;// | CRTSCTS; // dva stopbity jsou nastaveny vsude
break;
case 19200:
newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS;
@@ -650,7 +754,7 @@ int main(int argc, char** argv, char** env)
}
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 = 0;IGNPAR | IXOFF;
+ newtio.c_iflag = 0; //IGNPAR | IXOFF;
newtio.c_oflag = 0;
// newtio.c_oflag &= ~OPOST;
newtio.c_lflag = 0; //NOFLSH;