| 1 | #include <stdio.h> |
| 2 | #include <unistd.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <fcntl.h> |
| 5 | #include <stdarg.h> |
| 6 | #include <sys/select.h> |
| 7 | #include "hw_types.h" |
| 8 | #include "hw_helpers.h" |
| 9 | #define XON 0x11 |
| 10 | #define XOFF 0x13 |
| 11 | #define CHAR_START 0x81 |
| 12 | // 0x93 |
| 13 | #define CHAR_END1 0223 |
| 14 | #define CHAR_END2 0223 |
| 15 | #define CHAR_END3 0223 |
| 16 | #define MAX_BLOCK_SIZE 500 |
| 17 | |
| 18 | //#define DEBUG |
| 19 | #define DEBUG_CHECKSUM |
| 20 | #define DEBUG_STRUCTURE |
| 21 | #define DEBUG_COMBINE |
| 22 | //#define IGNORE_CHECKSUM |
| 23 | #define HARDCORE_DEBUG |
| 24 | /********************************************************/ |
| 25 | void output (char *string, int length); |
| 26 | datablock *get_block (); |
| 27 | |
| 28 | /********************************************************/ |
| 29 | char ends[3] = { CHAR_END1, CHAR_END2, CHAR_END3 }; |
| 30 | int errflag = 0; // Global error flag |
| 31 | int tapemode = 0; |
| 32 | int inputfd; |
| 33 | int ignore = 0; |
| 34 | int dosplit = 0; |
| 35 | int splitnum = 0; |
| 36 | int silent = 0; |
| 37 | int read_pos = -5; |
| 38 | int block_pos= -5; |
| 39 | /********************************************************/ |
| 40 | |
| 41 | |
| 42 | /********************************************************/ |
| 43 | void dump_data (void *data, int count) |
| 44 | { |
| 45 | int fd = open ("dump", O_RDWR | O_CREAT | O_APPEND, 0666); |
| 46 | write (fd, "***", 3); |
| 47 | write (fd, data, count); |
| 48 | close (fd); |
| 49 | } |
| 50 | |
| 51 | /********************************************************/ |
| 52 | void endwarn (int ret) |
| 53 | { |
| 54 | if (ret < 1) { |
| 55 | err ("Unexpected problem in input"); |
| 56 | exit (3); |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | /********************************************************/ |
| 61 | /* Small output things */ |
| 62 | void err (char *string) |
| 63 | { |
| 64 | printf ("Error: --> %s\n", string); |
| 65 | errflag++; |
| 66 | } |
| 67 | |
| 68 | void msg (char *string) |
| 69 | { |
| 70 | #ifdef DEBUG |
| 71 | printf ("** %s\n", string); |
| 72 | #endif |
| 73 | } |
| 74 | |
| 75 | void msgf (char *format, ...) |
| 76 | { |
| 77 | va_list ag; |
| 78 | va_start (ag, format); |
| 79 | char ms[100]; |
| 80 | vsprintf (ms, format, ag); |
| 81 | msg (ms); |
| 82 | va_end (ag); |
| 83 | } |
| 84 | |
| 85 | void errf (char *format, ...) |
| 86 | { |
| 87 | va_list ag; |
| 88 | va_start (ag, format); |
| 89 | char ms[100]; |
| 90 | vsprintf (ms, format, ag); |
| 91 | err (ms); |
| 92 | va_end (ag); |
| 93 | } |
| 94 | |
| 95 | void say (char *string) |
| 96 | { |
| 97 | if (!silent) printf ("%s\n", string); |
| 98 | } |
| 99 | |
| 100 | void sayf (char *format, ...) |
| 101 | { |
| 102 | va_list ag; |
| 103 | va_start (ag, format); |
| 104 | char ms[100]; |
| 105 | vsprintf (ms, format, ag); |
| 106 | say (ms); |
| 107 | va_end (ag); |
| 108 | } |
| 109 | |
| 110 | |
| 111 | /********************************************************/ |
| 112 | /********************************************************/ |
| 113 | |
| 114 | /********************************************************/ |
| 115 | /*Block input routines*/ |
| 116 | |
| 117 | unsigned char decode (unsigned char in) |
| 118 | { |
| 119 | if (in & 64) |
| 120 | switch (in) { |
| 121 | case 0174: |
| 122 | return 05; |
| 123 | break; |
| 124 | case 0374: |
| 125 | return 045; |
| 126 | break; |
| 127 | case 0175: |
| 128 | return 012; |
| 129 | break; |
| 130 | case 0375: |
| 131 | return 052; |
| 132 | break; |
| 133 | case 0176: |
| 134 | return 021; |
| 135 | break; |
| 136 | case 0376: |
| 137 | return 061; |
| 138 | break; |
| 139 | case 0177: |
| 140 | return 023; |
| 141 | break; |
| 142 | case 0377: |
| 143 | return 063; |
| 144 | break; |
| 145 | default: |
| 146 | err ("decode(): Impossible case!!!\n"); |
| 147 | return 0; |
| 148 | break; |
| 149 | } else { |
| 150 | if (in & 128) |
| 151 | in |= 32; |
| 152 | return in; |
| 153 | } |
| 154 | |
| 155 | return 0; |
| 156 | } |
| 157 | |
| 158 | /********************************************************/ |
| 159 | /********************************************************/ |
| 160 | |
| 161 | void combine466 (unsigned char *raw, unsigned char *data) |
| 162 | { |
| 163 | hw16 *result = (hw16 *) data; |
| 164 | |
| 165 | // result->tape.low = 077; |
| 166 | unsigned char r1, r2, r3; |
| 167 | |
| 168 | r1 = decode ((raw)[0]) & 017; |
| 169 | r2 = decode ((raw)[1]) & 077; |
| 170 | r3 = decode ((raw)[2]) & 077; |
| 171 | |
| 172 | result->tape.high = r1; |
| 173 | result->tape.mid = r2; |
| 174 | result->tape.low = r3; |
| 175 | |
| 176 | #ifdef DEBUG_COMBINE |
| 177 | msgf ("combine466 (data) : %02x %02x %02x",r1,r2,r3, 6); |
| 178 | // msgf ("combine466 (rawmem) : %s%s", bin2str (data[1], 8), |
| 179 | // bin2str (data[0], 8)); |
| 180 | msgf ("combine466 (structure): %s", bin2str (result->value, 16)); |
| 181 | #endif |
| 182 | } |
| 183 | |
| 184 | /*********************************************************************/ |
| 185 | /*********************************************************************/ |
| 186 | int checksum_error (hw16 * data, int size) |
| 187 | { |
| 188 | unsigned short int checksumme = 0; |
| 189 | int c; |
| 190 | for (c = 0; c < (size - 1); c++) { |
| 191 | checksumme ^= data[c].value; |
| 192 | #ifdef DEBUG_CHECKSUM |
| 193 | msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x", |
| 194 | data[c + 1].value, checksumme); |
| 195 | if (data[c + 1].value == checksumme) |
| 196 | msg ("checksum_error (): Treffer."); |
| 197 | #endif |
| 198 | } |
| 199 | #ifdef DEBUG_CHECKSUM |
| 200 | msgf ("checksum_error(): Gelesen:%04x Berechnet:%04x", |
| 201 | data[size - 1].value, checksumme); |
| 202 | #endif |
| 203 | if (data[size - 1].value != checksumme) |
| 204 | return 1; |
| 205 | return 0; |
| 206 | } |
| 207 | |
| 208 | /********************************************************/ |
| 209 | datablock *get_block() |
| 210 | { |
| 211 | int blk_size, round, ret, found, complete; |
| 212 | unsigned char buffer[3]; |
| 213 | hw16 *blk_data; |
| 214 | unsigned char *raw_data; |
| 215 | |
| 216 | if (tapemode) |
| 217 | tapestart (); |
| 218 | do { |
| 219 | read_pos+=ret=read (inputfd, buffer, 1); |
| 220 | |
| 221 | #ifdef HARDCORE_DEBUG |
| 222 | msgf ("READ : (hex)%02x (bin)%s (dec)%3i (oct)%3o", |
| 223 | buffer[0], bin2str (buffer[0], 8), buffer[0], buffer[0]); |
| 224 | #endif |
| 225 | if (ret < 1) { |
| 226 | msg ("get_block(): Nichts mehr zu lesen"); |
| 227 | return NULL; |
| 228 | } |
| 229 | |
| 230 | if (buffer[0]==0x83){ |
| 231 | datablock *result = (datablock *) malloc (sizeof (datablock)); |
| 232 | result->type = BT_STOP; |
| 233 | result->data = NULL; |
| 234 | result->raw_data = NULL; |
| 235 | result->size = 0; |
| 236 | return result; |
| 237 | } |
| 238 | |
| 239 | } while (*buffer != (unsigned char) CHAR_START); |
| 240 | |
| 241 | block_pos=read_pos; |
| 242 | msg ("get_block(): Blockstart erkannt"); |
| 243 | |
| 244 | // blk_data = (hw16 *) malloc (MAX_BLOCK_SIZE * sizeof (hw16)); |
| 245 | blk_data=NULL; |
| 246 | raw_data=NULL; |
| 247 | round = 0; |
| 248 | blk_size = 0; |
| 249 | |
| 250 | do { |
| 251 | complete = 0; |
| 252 | ret = read (inputfd, buffer + round, 1); |
| 253 | read_pos+=ret; |
| 254 | #ifdef HARDCORE_DEBUG |
| 255 | static int lochzahl = 0; |
| 256 | char *bin = bin2str (buffer[round], 8); |
| 257 | int a; |
| 258 | for (a = 0; a < 8; a++) |
| 259 | if (bin[a] == '1') |
| 260 | lochzahl++; |
| 261 | msgf ("READ (round %i): (hex)%02x (bin)%s (dec)%3i " |
| 262 | " (oct)%3o Lochzahl:%4i", |
| 263 | round, buffer[round], bin, buffer[round], buffer[round], lochzahl); |
| 264 | |
| 265 | // msgf ("READ(round %i) (hex)%02x", round, buffer[round]); |
| 266 | #endif |
| 267 | endwarn (ret); |
| 268 | round++; |
| 269 | found = 0; |
| 270 | if (buffer[round - 1] == CHAR_END1) |
| 271 | found++; |
| 272 | if (buffer[round - 1] == CHAR_END2) |
| 273 | found++; |
| 274 | |
| 275 | if (found) { |
| 276 | complete++; |
| 277 | } else { |
| 278 | if (round == 3) { |
| 279 | //if (blk_size == MAX_BLOCK_SIZE) { |
| 280 |