// // Copyright (C) 2016 Clifford Wolf // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // #include #include #include #include #include #include #include #include #include using std::map; using std::vector; using std::string; using std::ifstream; using std::getline; void parse_hexfile_line(const char *filename, int linenr, vector> &hexfile, string &line) { vector digits; for (char c : line) { if ('0' <= c && c <= '9') digits.push_back(c - '0'); else if ('a' <= c && c <= 'f') digits.push_back(10 + c - 'a'); else if ('A' <= c && c <= 'F') digits.push_back(10 + c - 'A'); else goto error; } hexfile.push_back(vector(digits.size() * 4)); for (int i = 0; i < digits.size() * 4; i++) if ((digits.at(digits.size() - i/4 -1) & (1 << (i%4))) != 0) hexfile.back().at(i) = true; return; error: fprintf(stderr, "Can't parse line %d of %s: %s\n", linenr, filename, line.c_str()); exit(1); } void help(const char *cmd) { printf("\n"); printf("Usage: %s [options] from_hexfile to_hexfile \n", cmd); printf("\n"); // printf(" -S\n"); // printf(" Disable SIMPLE feedback path mode\n"); // printf("\n"); exit(1); } int main(int argc, char **argv) { int opt; while ((opt = getopt(argc, argv, "")) != -1) { switch (opt) { // case 'i': // f_pllin = atof(optarg); // break; default: help(argv[0]); } } if (optind+2 != argc) help(argv[0]); const char *from_hexfile_n = argv[optind]; ifstream from_hexfile_f(from_hexfile_n); vector> from_hexfile; const char *to_hexfile_n = argv[optind+1]; ifstream to_hexfile_f(to_hexfile_n); vector> to_hexfile; string line; for (int i = 1; getline(from_hexfile_f, line); i++) parse_hexfile_line(from_hexfile_n, i, from_hexfile, line); for (int i = 1; getline(to_hexfile_f, line); i++) parse_hexfile_line(to_hexfile_n, i, to_hexfile, line); if (from_hexfile.size() != to_hexfile.size()) { fprintf(stderr, "Hexfiles have different number of words! (%d vs. %d)\n", int(from_hexfile.size()), int(to_hexfile.size())); exit(1); } if (from_hexfile.size() % 256 != 0) { fprintf(stderr, "Hexfile number of words (%d) is not divisible by 256!\n", int(from_hexfile.size())); exit(1); } for (size_t i = 1; i < from_hexfile.size(); i++) if (from_hexfile.at(i-1).size() != from_hexfile.at(i).size()) { fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i), from_hexfile_n); exit(1); } for (size_t i = 1; i < to_hexfile.size(); i++) if (to_hexfile.at(i-1).size() != to_hexfile.at(i).size()) { fprintf(stderr, "Inconsistent word width at line %d of %s!\n", int(i+1), to_hexfile_n); exit(1); } vector ascfile_lines; map>> ascfile_hexdata; for (int i = 1; getline(std::cin, line); i++) { next_asc_stmt: ascfile_lines.push_back(line); if (line.substr(0, 9) == ".ram_data") { auto &hexdata = ascfile_hexdata[line]; for (; getline(std::cin, line); i++) { if (line.substr(0, 1) == ".") goto next_asc_stmt; parse_hexfile_line("stdin", i, hexdata, line); } } } // FIXME: Do the actual thing for (size_t i = 0; i < ascfile_lines.size(); i++) { auto &line = ascfile_lines.at(i); std::cout << line << std::endl; if (ascfile_hexdata.count(line)) { for (auto &word : ascfile_hexdata.at(line)) { for (int k = word.size()-4; k >= 0; k -= 4) { int digit = (word[k+3] ? 8 : 0) + (word[k+2] ? 4 : 0) + (word[k+1] ? 2 : 0) + (word[k] ? 1 : 0); std::cout << "0123456789abcdef"[digit]; } std::cout << std::endl; } } } return 0; }