A large commit.
[pdp8.git] / sw / dumprest / original / dumptd8e.c
1 /* This program receives an td8e Dectape image from the serial port from the
2 PDP8 dump program. It will prompt for the file to receive or use first
3 command line argument. It needs a config file dumprest.cfg or
4 $HOME/.dumprest.cfg with the format defined in config.c
5
6 This program should be running before the PDP8 end is started.
7
8 On the PC ctrl-break will terminate the program
9 */
10 #ifdef PC
11 #include "encom.h"
12 #else
13 #include <termios.h>
14 #include <unistd.h>
15 #include <memory.h>
16 #endif
17
18 #include <stdio.h>
19 #include <fcntl.h>
20 #include <time.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
26
27 int terminate = 0;
28
29 #include "config.c"
30 #include "comm.c"
31
32 main(argc,argv)
33 int argc;
34 char *argv[];
35 {
36 int fd,c,i;
37 FILE *out;
38 char filename[256];
39 char serial_dev[256];
40 long baud;
41 int two_stop;
42 unsigned char buf[200];
43 unsigned short temp;
44 int count,block,byte;
45 int chksum = 0;
46
47 setup_config(&baud,&two_stop,serial_dev);
48
49 if (argc > 1) {
50 strcpy(filename,argv[1]);
51 } else {
52 printf("Enter file name to receive\n");
53 fflush(stdout);
54 scanf("%s",filename);
55 }
56
57 #ifdef PC
58 out = fopen(filename,"wb");
59 #else
60 out = fopen(filename,"w");
61 #endif
62 if (out < 0) {
63 fprintf(stderr,"On file %s ",filename);
64 perror("open failed");
65 exit(1);
66 }
67
68 #if 0
69 /* For testing read from file, only works in unix version */
70 fd = open("dat",O_RDONLY,0666);
71 if (fd < 0) {
72 perror("Open failed on dat");
73 exit(1);
74 }
75 #else
76 fd = init_comm(serial_dev,baud,two_stop);
77 #endif
78 count = -1;
79 block = 0;
80 byte = 0;
81 while(!terminate) {
82 c = ser_read(fd,(char *)buf,sizeof(buf));
83 if (c < 0) {
84 perror("Serial read failed");
85 exit(1);
86 }
87 for (i = 0; i < c; i++) {
88 if (count < 0 ) {
89 /* -2 = waiting for checksum */
90 if (count == -2) {
91 if (byte == 0) {
92 temp = buf[i];
93 byte = 1;
94 } else {
95 fclose(out);
96 temp = temp | (buf[i] << 8);
97 if (((temp + chksum) & 0xfff) != 0) {
98 printf("\nChecksum mismatch %x %x\n",temp,chksum);
99 exit(1);
100 }
101 printf("\nDone, wait for program to exit\n");
102 exit(0);
103 }
104 } else {
105 /* -1 = waiting for block flag */
106 if (buf[i] != 0xff && buf[i] != 0xfd) {
107 /* End of data flag */
108 if (buf[i] == 0xfe) {
109 count = -2;
110 byte = 0;
111 } else {
112 printf("\nMissing start of block flag\n");
113 exit(1);
114 }
115 } else {
116 count = 0;
117 if (buf[i] == 0xfd)
118 printf("\nblock %d bad\n", block);
119 }
120 }
121 } else {
122 /* Count >= 0 is word count in block */
123 /* Byte is byte in 3 byte sequence for 2 words */
124 if (byte == 0) {
125 temp = buf[i];
126 byte++;
127 } else
128 if (byte == 1) {
129 temp = (temp | (buf[i] << 8)) & 0xfff;
130 fwrite(&temp,2,1,out);
131 chksum = chksum + temp;
132 temp = buf[i] >> 4;
133 byte++;
134 count++;
135 } else
136 if (byte == 2) {
137 temp = (temp | (buf[i] << 4)) & 0xfff;
138 fwrite(&temp,2,1,out);
139 chksum = chksum + temp;
140 byte = 0;
141 count++;
142 }
143 /* If at end of block setup for next */
144 if (count == 129) {
145 count = -1;
146 block++;
147 byte = 0;
148 if (block % 5 == 0) {
149 printf("Block %d\r",block);
150 fflush(stdout);
151 }
152 }
153 }
154 }
155 }
156 return 1;
157 }