// ----------------------------------------------------------------------- int log_init(struct cfg_em400 *cfg) { int res; int ret = E_ALLOC; log_file = strdup(cfg->log_file); if (!log_file) { ret = E_ALLOC; goto cleanup; } if (cfg->log_enabled) { ret = log_enable(); if (ret != E_OK) { goto cleanup; } } // set up thresholds res = log_setup_levels(cfg->log_levels); if (res < 0) { ret = E_LEVELS; goto cleanup; } pthread_mutex_init(&log_mutex, NULL); // initialize deassembler emd = emdas_create(cfg->cpu_mod ? EMD_ISET_MX16 : EMD_ISET_MERA400, (emdas_getfun) mem_get); if (!emd) { ret = E_DASM; goto cleanup; } emdas_set_nl(emd, '\0'); emdas_set_features(emd, EMD_FEAT_NONE); emdas_set_tabs(emd, 0, 0, 0, 0); dasm_buf = emdas_get_buf(emd); log_initialized = 1; return E_OK; cleanup: if (log_f) fclose(log_f); free(log_file); emdas_destroy(emd); return ret; }
// ----------------------------------------------------------------------- struct emdas *emdas_create(int iset_type, emdas_getfun getfun) { struct emdas *emd = NULL; if (!getfun) { emdas_error = EMD_E_GETFUN_MISSING; goto cleanup; } emd = malloc(sizeof(struct emdas)); if (!emd) { emdas_error = EMD_E_ALLOC; goto cleanup; } for (int i=0 ; i<16 ; i++) { emd->cellinfo[i] = NULL; } emd->ops = emdas_iset_create(iset_type); if (!emd->ops) { goto cleanup; } emd->dbuf = emdas_buf_create(EMD_DASM_BUF_SIZE); if (!emd->dbuf) { goto cleanup; } emd->memget = getfun; emdas_set_features(emd, EMD_FEAT_DEFAULTS); emdas_set_tabs(emd, EMD_TAB_LABEL, EMD_TAB_MNEMO, EMD_TAB_ARG, EMD_TAB_ALT); return emd; cleanup: emdas_destroy(emd); return NULL; }
// ----------------------------------------------------------------------- int main(int argc, char **argv) { FILE *fi, *fo; int res; int ret = -1; struct emdas *emd = NULL; struct emelf *e = NULL; struct stat sb; res = parse_args(argc, argv); if (res) { // wrong usage, parse_args() prints the error goto cleanup; } if (stat(input_file, &sb) == -1) { fprintf(stderr, "Cannot stat file '%s'.\n", input_file); goto cleanup; } if (sb.st_size > 2*(0x10000-base_addr)) { fprintf(stderr, "Warning: File is bigger than available address space (%li bytes > %i words). Output will be truncated.\n", sb.st_size, 0x10000-base_addr); } fi = fopen(input_file, "r"); if (!fi) { fprintf(stderr, "Cannot open input file '%s'.\n", input_file); goto cleanup; } emd = emdas_create(iset, memget); if (!emd) { fprintf(stderr, "Cannot setup disassembler: %s\n", emdas_get_error(emdas_error)); goto cleanup; } res = emdas_set_tabs(emd, TAB_LABEL, TAB_MNEMO, TAB_ARG, TAB_COMMENT); if (res != EMD_E_OK) { fprintf(stderr, "Cannot set tabulators: %s\n", emdas_get_error(res)); goto cleanup; } res = emdas_set_features(emd, features); if (res) { fprintf(stderr, "Cannot set disassembler features: %s\n", emdas_get_error(res)); goto cleanup; } // try as emelf first e = emelf_load(fi); if (e) { bin_size = e->image_size; mem = e->image; } else { mem = calloc(0x10000, sizeof(uint16_t)); if (!mem) { fclose(fi); fprintf(stderr, "Memory allocation error\n"); goto cleanup; } rewind(fi); bin_size = fread(mem+base_addr, sizeof(uint16_t), 0x10000-base_addr, fi); for (int i=base_addr ; i<base_addr+bin_size ; i++) { mem[i] = ntohs(mem[i]); } } if (bin_size < 0) { fprintf(stderr, "Cannot read input file '%s'.\n", input_file); fclose(fi); goto cleanup; } fclose(fi); if (output_file) { fo = fopen(output_file, "w"); } else { fo = stdout; } if (!fo) { fprintf(stderr, "Cannot open output file '%s' for writing.\n", output_file); goto cleanup; } // print CPU type fprintf(fo, "%*s.cpu%*s%s\n\n", TAB_MNEMO, "", TAB_ARG-TAB_MNEMO-4, "", iset == EMD_ISET_MX16 ? "mx16" : "mera400"); // disassemble and write output if (use_labels) { res = emdas_analyze(emd, 0, base_addr, bin_size); if (res != EMD_E_OK) { fprintf(stderr, "Cannot assign labels: %s\n", emdas_get_error(res)); goto cleanup; } } int ic = base_addr; int words; while (ic < base_addr+bin_size) { words = emdas_dasm(emd, 0, ic); if (words <= 0) { fprintf(stderr, "Disassembly error: %s\n", emdas_get_error(emdas_error)); } fprintf(fo, "%s", emdas_get_buf(emd)); ic += words; } if (output_file) { fclose(fo); } ret = 0; cleanup: if (e) emelf_destroy(e); else free(mem); emdas_destroy(emd); free(output_file); return ret; }