}/* decode_program */ /* decode_routine - Decode a routine from start address to last instruction */ static int decode_routine() { var header = txio.header; ulong old_pc, old_start; tx_h.cref_item_t cref_item; int vars, status, i, locals; if (decode.first_pass) { cref_item = null; if (option_labels > 0) cref_item = current_routine; old_start = start_of_routine; locals = locals_count; old_pc = decode.pc; decode.pc = ROUND_CODE(decode.pc); vars = txio.read_data_byte(ref decode.pc); if (vars >= 0 && vars <= 15) { if (option_labels > 0) add_routine(decode.pc - 1); locals_count = vars; if ((uint)header.version < tx_h.V5) for (; vars > 0; vars--) txio.read_data_word(ref decode.pc); start_of_routine = decode.pc; if (decode_code() == tx_h.END_OF_ROUTINE) return (tx_h.END_OF_ROUTINE); if (option_labels > 0) current_routine = cref_item; start_of_routine = old_start; locals_count = locals; } decode.pc = old_pc; if ((status = decode_code()) != tx_h.END_OF_ROUTINE) { decode.pc = old_pc; } else { pctable[pcindex++] = old_pc; if (pcindex == MAX_PCS) { throw new NotImplementedException("\nFatal: too many orphan code fragments\n"); } } } else { if (decode.pc == start_data_pc) { if (option_dump > 0) { txio.tx_printf("\n[Start of data"); if (option_labels == 0) txio.tx_printf(" at {0:X}", (ulong)start_data_pc); txio.tx_printf("]\n\n"); dump_data(start_data_pc, end_data_pc - 1); txio.tx_printf("\n[End of data"); if (option_labels == 0) txio.tx_printf(" at {0:X}", (ulong)(end_data_pc - 1)); txio.tx_printf("]\n"); } decode.pc = end_data_pc; } for (i = 0; i < pcindex && decode.pc != pctable[i]; i++) ; if (i == pcindex) { decode.pc = ROUND_CODE(decode.pc); start_of_routine = decode.pc; vars = txio.read_data_byte(ref decode.pc); if (option_labels > 0) { txio.tx_printf("{0}outine {1}{2:d4}, {3} local", (decode.pc - 1 == decode.initial_pc) ? "\nMain r" : "\nR", (txio.option_inform) ? 'r' : 'R', (int)lookup_routine(decode.pc - 1, 1), (int)vars); } else { txio.tx_printf("{0}outine {1:X}, {2} local", (decode.pc - 1 == decode.initial_pc) ? "\nMain r" : "\nR", (ulong)(decode.pc - 1), (int)vars); } if (vars != 1) txio.tx_printf("s"); if ((uint)header.version < tx_h.V5) { txio.tx_printf(" ("); txio.tx_fix_margin(1); for (; vars > 0; vars--) { txio.tx_printf("{0:X4}", (uint)txio.read_data_word(ref decode.pc)); if (vars > 1) txio.tx_printf(", "); } txio.tx_fix_margin(0); txio.tx_printf(")"); } txio.tx_printf("\n"); lookup_verb(start_of_routine); txio.tx_printf("\n"); } else txio.tx_printf("\norphan code fragment:\n\n"); status = decode_code(); } return (status); }/* decode_routine */
}/* lookup_label */ static int lookup_routine(ulong addr, int flag) { // cref_item_t *cref_item = routines_base; // while (cref_item != NULL && cref_item->address != addr) // cref_item = cref_item->next; // if (cref_item == NULL) { // if (flag) { // (void) fprintf (stderr, "\nFatal: cannot find routine!\n"); // exit (EXIT_FAILURE); // } else // return (0); // } // if (flag) // current_routine = cref_item; // return (cref_item->number); for (int i = 0; i < routines_base.Count; i++) { if (routines_base[i].address == addr) { if (flag == 1) { current_routine = routines_base[i]; } return routines_base[i].number; } } if (flag == 1) { throw new ArgumentException("\nFatal: Cannot find routine!\n"); } else { return 0; } }/* lookup_routine */
}/* in_dictionary */ internal static void add_label(ulong addr) { // cref_item_t *cref_item, **prev_item, *next_item; if (current_routine == null) return; tx_h.cref_item_t child = new tx_h.cref_item_t(); child.address = addr; child.number = 0; current_routine.child.Add(child); // prev_item = ¤t_routine->child; // next_item = current_routine->child; // while (next_item != NULL && next_item->address < addr) { // prev_item = &(next_item->next); // next_item = next_item->next; // } // if (next_item == NULL || next_item->address != addr) { // cref_item = (cref_item_t *) malloc (sizeof (cref_item_t)); // if (cref_item == NULL) { // (void) fprintf (stderr, "\nFatal: insufficient memory\n"); // exit (EXIT_FAILURE); // } // cref_item->next = next_item; // *prev_item = cref_item; // cref_item->child = NULL; // cref_item->address = addr; // cref_item->number = 0; // } // add_routine(addr); // TODO I'm not sure this is correct }/* add_label */
}/* add_label */ static void add_routine(ulong addr) { // cref_item_t *cref_item, **prev_item, *next_item; // prev_item = &routines_base; // next_item = routines_base; // while (next_item != NULL && next_item->address < addr) { // prev_item = &(next_item->next); // next_item = next_item->next; // } // if (next_item == NULL || next_item->address != addr) { // cref_item = (cref_item_t *) malloc (sizeof (cref_item_t)); // if (cref_item == NULL) { // (void) fprintf (stderr, "\nFatal: insufficient memory\n"); // exit (EXIT_FAILURE); // } // cref_item->next = next_item; // *prev_item = cref_item; // cref_item->child = NULL; // cref_item->address = addr; // cref_item->number = 0; // } else // cref_item = next_item; // current_routine = cref_item; if (routines_base == null) { routines_base = new System.Collections.Generic.List<tx_h.cref_item_t>(); } tx_h.cref_item_t cref_item = new tx_h.cref_item_t(); cref_item.address = addr; cref_item.number = 0; routines_base.Insert(0, cref_item); current_routine = cref_item; }/* add_routine */
}/* decode_strings */ /* scan_strings - build string address table */ internal static void scan_strings(ulong pc) { ulong old_pc; int count = 1; zword_t data; strings_base = new System.Collections.Generic.List<tx_h.cref_item_t>(); pc = ROUND_DATA(pc); old_pc = pc; while (pc < (ulong)txio.file_size) { tx_h.cref_item_t cref_item = new tx_h.cref_item_t(); cref_item.address = pc; cref_item.number = count++; strings_base.Insert(0, cref_item); old_pc = pc; do data = (zword_t)txio.read_data_word(ref pc); while (pc < (ulong)txio.file_size && ((uint)data & 0x8000) == 0); pc = ROUND_CODE(pc); if ((uint)(data & 0x8000) > 0) old_pc = pc; } txio.file_size = (int)old_pc; }/* scan_strings */