FreeCalypso > hg > gsm-net-reveng
comparison d144/edata-input-compile.c @ 52:4681ad8483d6
d144: edata-input-compile program written
| author | Mychaela Falconia <falcon@freecalypso.org> | 
|---|---|
| date | Wed, 25 Sep 2024 03:33:16 +0000 | 
| parents | trau-ul-compile/trau-ul-compile.c@8e9bbb83bd16 | 
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 51:4189abdfeaa4 | 52:4681ad8483d6 | 
|---|---|
| 1 /* | |
| 2 * This program compiles E-data input from our handcrafting format | |
| 3 * into the binary format that will be read by itt-ater-16. | |
| 4 */ | |
| 5 | |
| 6 #include <sys/types.h> | |
| 7 #include <ctype.h> | |
| 8 #include <stdio.h> | |
| 9 #include <stdint.h> | |
| 10 #include <stdlib.h> | |
| 11 #include <string.h> | |
| 12 #include <strings.h> | |
| 13 | |
| 14 #define MAX_FIELDS 8 | |
| 15 | |
| 16 static char *infname, *outfname; | |
| 17 static FILE *inf, *outf; | |
| 18 | |
| 19 static int lineno; | |
| 20 static char linebuf[256]; | |
| 21 static char *fields[MAX_FIELDS]; | |
| 22 static unsigned nfields; | |
| 23 | |
| 24 static uint8_t frame_nibbles[72]; | |
| 25 static unsigned subframe_count; | |
| 26 | |
| 27 static int | |
| 28 get_line() | |
| 29 { | |
| 30 char *cp; | |
| 31 | |
| 32 if (!fgets(linebuf, sizeof linebuf, inf)) | |
| 33 return 1; | |
| 34 lineno++; | |
| 35 if (!index(linebuf, '\n')) { | |
| 36 fprintf(stderr, "%s line %d: too long or missing newline\n", | |
| 37 infname, lineno); | |
| 38 exit(1); | |
| 39 } | |
| 40 nfields = 0; | |
| 41 for (cp = linebuf; ; ) { | |
| 42 while (isspace(*cp)) | |
| 43 cp++; | |
| 44 if (*cp == '\0' || *cp == '#') | |
| 45 break; | |
| 46 if (nfields >= MAX_FIELDS) { | |
| 47 fprintf(stderr, "%s line %d: too many fields\n", | |
| 48 infname, lineno); | |
| 49 exit(1); | |
| 50 } | |
| 51 fields[nfields++] = cp; | |
| 52 while (*cp && !isspace(*cp)) | |
| 53 cp++; | |
| 54 if (*cp) | |
| 55 *cp++ = '\0'; | |
| 56 } | |
| 57 return 0; | |
| 58 } | |
| 59 | |
| 60 static int | |
| 61 get_line_nonempty() | |
| 62 { | |
| 63 int rc; | |
| 64 | |
| 65 for (;;) { | |
| 66 rc = get_line(); | |
| 67 if (rc) | |
| 68 return rc; | |
| 69 if (nfields) | |
| 70 return 0; | |
| 71 } | |
| 72 } | |
| 73 | |
| 74 static int | |
| 75 decode_hex_digit(c) | |
| 76 { | |
| 77 if (isdigit(c)) | |
| 78 return c - '0'; | |
| 79 else if (isupper(c)) | |
| 80 return c - 'A' + 10; | |
| 81 else | |
| 82 return c - 'a' + 10; | |
| 83 } | |
| 84 | |
| 85 static void | |
| 86 bits_line() | |
| 87 { | |
| 88 uint8_t *op; | |
| 89 char *cp; | |
| 90 unsigned n; | |
| 91 | |
| 92 if (nfields != 2) { | |
| 93 fprintf(stderr, "%s line %d: bits command takes one argument\n", | |
| 94 infname, lineno); | |
| 95 exit(1); | |
| 96 } | |
| 97 if (strlen(fields[1]) != 9) { | |
| 98 fprintf(stderr, "%s line %d: bits argument has wrong length\n", | |
| 99 infname, lineno); | |
| 100 exit(1); | |
| 101 } | |
| 102 if (subframe_count >= 8) { | |
| 103 fprintf(stderr, | |
| 104 "%s line %d: 8 subframes already given, can't have more\n", | |
| 105 infname, lineno); | |
| 106 exit(1); | |
| 107 } | |
| 108 op = frame_nibbles + subframe_count * 9; | |
| 109 cp = fields[1]; | |
| 110 for (n = 0; n < 9; n++) { | |
| 111 if (!isxdigit(*cp)) { | |
| 112 fprintf(stderr, | |
| 113 "%s line %d: bits argument is not valid hex\n", | |
| 114 infname, lineno); | |
| 115 exit(1); | |
| 116 } | |
| 117 *op++ = decode_hex_digit(*cp++); | |
| 118 } | |
| 119 subframe_count++; | |
| 120 } | |
| 121 | |
| 122 static void | |
| 123 frame_line() | |
| 124 { | |
| 125 uint8_t bin[38], m_bits[2]; | |
| 126 unsigned n, i; | |
| 127 | |
| 128 if (nfields != 2) { | |
| 129 fprintf(stderr, | |
| 130 "%s line %d: frame command takes one argument\n", | |
| 131 infname, lineno); | |
| 132 exit(1); | |
| 133 } | |
| 134 for (n = 0; n < 2; n++) { | |
| 135 switch (fields[1][n]) { | |
| 136 case '0': | |
| 137 m_bits[n] = 0; | |
| 138 break; | |
| 139 case '1': | |
| 140 m_bits[n] = 1; | |
| 141 break; | |
| 142 default: | |
| 143 bad_arg: | |
| 144 fprintf(stderr, | |
| 145 "%s line %d: invalid M-bits argument \"%s\"\n", | |
| 146 infname, lineno, fields[1]); | |
| 147 exit(1); | |
| 148 } | |
| 149 } | |
| 150 if (fields[1][2]) | |
| 151 goto bad_arg; | |
| 152 | |
| 153 if (subframe_count != 8) { | |
| 154 fprintf(stderr, | |
| 155 "%s line %d: not preceded by exactly 8 subframes\n", | |
| 156 infname, lineno); | |
| 157 exit(1); | |
| 158 } | |
| 159 bin[0] = 0xD4; | |
| 160 bin[1] = (m_bits[0] << 1) | m_bits[1]; | |
| 161 i = 0; | |
| 162 for (n = 0; n < 36; n++) { | |
| 163 bin[n+2] = (frame_nibbles[i] << 4) | frame_nibbles[i+1]; | |
| 164 i += 2; | |
| 165 } | |
| 166 fwrite(bin, 1, 38, outf); | |
| 167 | |
| 168 subframe_count = 0; | |
| 169 } | |
| 170 | |
| 171 main(argc, argv) | |
| 172 char **argv; | |
| 173 { | |
| 174 int rc; | |
| 175 | |
| 176 if (argc != 3) { | |
| 177 fprintf(stderr, "usage: %s input.src output.bin\n", argv[0]); | |
| 178 exit(1); | |
| 179 } | |
| 180 infname = argv[1]; | |
| 181 outfname = argv[2]; | |
| 182 | |
| 183 inf = fopen(infname, "r"); | |
| 184 if (!inf) { | |
| 185 perror(infname); | |
| 186 exit(1); | |
| 187 } | |
| 188 outf = fopen(outfname, "w"); | |
| 189 if (!outf) { | |
| 190 perror(outfname); | |
| 191 exit(1); | |
| 192 } | |
| 193 | |
| 194 for (;;) { | |
| 195 rc = get_line_nonempty(); | |
| 196 if (rc) | |
| 197 break; | |
| 198 if (!strcasecmp(fields[0], "bits")) | |
| 199 bits_line(); | |
| 200 else if (!strcasecmp(fields[0], "frame")) | |
| 201 frame_line(); | |
| 202 else { | |
| 203 fprintf(stderr, | |
| 204 "%s line %d: non-understood keyword \"%s\"\n", | |
| 205 infname, lineno, fields[0]); | |
| 206 exit(1); | |
| 207 } | |
| 208 } | |
| 209 exit(0); | |
| 210 } | 
