void dump_fw(uint8_t * fw, int fwsz) { int i, j; struct op_code * op; int nlabel=0; /* total number of labels in a FW */ uint8_t label[MAX_LABELS]; /* first run: collect labels */ for (i=0; i<fwsz; i+=2) { op = get_op_code(fw[i]); if (!op) { printf("; !!! internal ERROR :(\n"); exit(1); } if (op->param_type == PARAM_LABEL) label[nlabel++] = fw[i+1]; if (nlabel == MAX_LABELS) { printf("; !!! MAX_LABELS reached.\n"); printf("; !!! aborting current firmware\n"); return; } } /* second run: emit .asm code with labels */ for (i=0; i<fwsz; i+=2) { op = get_op_code(fw[i]); if (!op) { printf("; !!! internal ERROR :(\n"); exit(1); } /* see if we need to label the address */ for (j=0; j<nlabel; j++){ if (i/2 == label[j]) { printf("label_%2.2x:\n", label[j]); goto label_done; } } label_done: printf("\t%s", op->mnemonic); switch (op->param_type) { case PARAM_NONE: break; case PARAM_LABEL: printf("\tlabel_%2.2x", fw[i+1]); break; case PARAM_HEX: printf("\t0x%2.2x", fw[i+1]); break; case PARAM_DEC: printf("\t %3.1d", fw[i+1]); break; default: printf("; !!! internal ERROR :(\n"); exit(1); } printf("\n"); current_CPUs &= op->cpu; } }
void execute_program(UM_state um) { int ra =0; int rb =0; int rc =0; //uint32_t val= 0; bool proceed = true; int num_instructions = get_words_in_seg(um->memory, 0); int i = um->instr_ctr; while (i < num_instructions && proceed) { uint32_t word = get_word(um->memory, 0, i); uint32_t op_code = get_op_code(word); /*if (op_code == 13) { int ra = get_reg_num(word, LOAD_RA_LSB); proceed &= valid_reg(ra); uint32_t val = get_val(word); (void) val; } else {*/ ra = get_reg_num(word, RA_LSB); rb = get_reg_num(word, RB_LSB); rc = get_reg_num(word, RC_LSB); proceed &= valid_reg(ra); proceed &= valid_reg(rb); proceed &= valid_reg(rc); //} if (!proceed) { break; } if (op_code == 0) { /* Conditional move - op code 0 */ if (val_in_reg(um, rc) != 0) { uint32_t val = val_in_reg(um, rb); set_reg_val(um, ra, val); } } else if (op_code == 1) { /* Segmented load - op code 1 */ uint32_t val = get_word(um->memory, val_in_reg(um, rb), val_in_reg(um, rc)); set_reg_val(um, ra, val); } else if (op_code == 2) { /* Segmented store - op code 2 */ uint32_t ID = val_in_reg(um, ra); uint32_t offset = val_in_reg(um, rb); uint32_t val = val_in_reg(um, rc); put_word(um->memory, ID, offset, val); } else if (op_code == 3) { /* Add - op code 3 */ uint32_t val = (val_in_reg(um, rb) + val_in_reg(um, rc)) % UINT_MAX; set_reg_val(um, ra, val); } else if (op_code == 4) { /* Multiply - op code 4 */ uint32_t val = (val_in_reg(um, rb) * val_in_reg(um, rc)) % UINT_MAX; set_reg_val(um, ra, val); } else if (op_code == 5) { /* Divide - op code 5 */ uint32_t val = val_in_reg(um, rb) / val_in_reg(um, rc); set_reg_val(um, ra, val); } else if (op_code == 6) { /* Bitwise NAND - op code 6 */ uint32_t val = ~(val_in_reg(um, rb) & val_in_reg(um, rc)); set_reg_val(um, ra, val); } else if (op_code == 7) { /* Halt */ proceed = false; } else if (op_code == 8) { /* Map segment - op code 8 */ if (Stack_empty(um->unmapped_IDs)) { uint32_t num_words = val_in_reg(um, rc); proceed &= create_segment(um->memory, num_words); set_reg_val(um, rb, (get_num_segs(um->memory) - 1)); } else { uint32_t ID = get_unmapped_ID(um); uint32_t num_words = val_in_reg(um, rc); proceed &= resize(um->memory, ID, num_words); set_reg_val(um, rb, ID); } } else if (op_code == 9) { /* Unmap segment - op code 9 */ uint32_t ID = val_in_reg(um, rc); proceed &= clear_seg(um->memory, ID); proceed &= add_unmapped_ID(um, ID); } else if (op_code == 10) { /* Output - op code 10 */ uint32_t val = val_in_reg(um, rc); if (val < 256) { fprintf(stdout, "%c", (char) val); } else { proceed &= false; } } else if (op_code == 11) { /* Input - op code 11 */ uint32_t val = getc(stdin); if ((int) val == EOF) { val = ~0; } else if (val > 255) { proceed &= false; } set_reg_val(um, rc, val); } else if (op_code == 12) { /* Load program - op code 12 */ uint32_t ID = val_in_reg(um, rb); if (ID != 0) { proceed &= clear_seg(um->memory, 0); int num_words = get_words_in_seg(um->memory, ID); resize(um->memory, 0, num_words); for (int i = 0; i < num_words; i++) { proceed &= put_word(um->memory, 0, i, get_word(um->memory, ID, i)); } } um->instr_ctr = val_in_reg(um, rc); num_instructions = get_words_in_seg(um->memory, 0); i = um->instr_ctr; } else if (op_code == 13) { /* Load value - op code 13 */ ra = get_reg_num(word, LOAD_RA_LSB); proceed &= valid_reg(ra); uint32_t val = get_val(word); set_reg_val(um, ra, val); } else { fprintf(stderr, "op code doesn't exist\n"); proceed = false; } if (op_code != 12) { i++; } } return; }
void handle_mmap(uint8_t * map, int size, char * fname, int fcount) { uint8_t * p = map; int op_count = 0; int rest = size; struct op_code * op; uint8_t * pstart; int FW_count = 0; while (rest>0) { pstart = p; while( (op = get_op_code(*p)) ) { p += OP_CODE_SIZE; op_count++; } if (op_count > THRESHOLD) { current_CPUs = M_14400 | M_14401 | M_14402 | M_14404 | M_14405 | M_14420 | M_14421 | M_14422 | M_14424; printf("; ----------------------------------------\n"); printf("; firmware_%d_%d offset %d size %d bytes\n; file %s\n", fcount, FW_count, pstart - map, op_count * OP_CODE_SIZE, fname); printf("; ----------------------------------------\n"); printf("\n"); dump_fw(pstart, op_count * OP_CODE_SIZE); printf("\n"); printf("; the above firmware is supported by the following CPUs:\n"); int i=0; while (current_CPUs) { printf("; %s\n", cpu_name[i++]); current_CPUs>>=1; } printf("\n"); printf("\n"); FW_count++; } pstart += op_count * OP_CODE_SIZE; rest -= op_count * OP_CODE_SIZE; rest --; p++; op_count = 0; }