static int sym_find_handle_89(const char *dirname, const char *filename) { uint32_t fa, va; uint16_t fs, vs; int nfolders, nvars; int i, j; int handle = 0x08; if(tihw.calc_type == TI92) return -1; // handle: names and handles of all folders (including "main") if(strcmp(img_infos.version, "2.00") >= 0) handle = get_folder_list_handle(); // AMS2 (dynamic) else handle = 0x08; // AMS1 (static) if(handle == -1) return 0; else heap_get_block_addr_and_size(handle, &fa, &fs); // skip maximum number of folders before handle #$B needs to be resized // and actual number of folders nfolders = mem_rd_word(fa+2); fa += 4; // now, we read a list of SYM_ENTRY structs (list of folders) for(i=0; i<nfolders; i++) { TI89_SYM_ENTRY se; // read struct memcpy(&se, ti68k_get_real_address(fa + i * sizeof(TI89_SYM_ENTRY)), sizeof(TI89_SYM_ENTRY)); se.handle = GUINT16_FROM_BE(se.handle); if (strncmp (se.name, dirname, 8)) continue; // handle xxxx: names and handles of all variables heap_get_block_addr_and_size(se.handle, &va, &vs); // skip max num and actual num of vars nvars = mem_rd_word(va+2); va += 4; for(j=0; j<nvars; j++) { // read struct memcpy(&se, ti68k_get_real_address(va + j * sizeof(TI89_SYM_ENTRY)), sizeof(TI89_SYM_ENTRY)); se.handle = GUINT16_FROM_BE(se.handle); // add node if (strncmp (se.name, filename, 8)) continue; return se.handle; } } return 0; }
// tested: OK. static int parse_vat_92(GNode *node_top) { uint32_t fa, va, pa; uint16_t fs, vs, ps; int nfolders, nvars; int i, j; VatSymEntry *vse; GNode *node_fol, *node_var; if(tihw.calc_type != TI92) return -1; // handle 000B: names and handles of all folders (including "main") heap_get_block_addr_and_size(0xb, &fa, &fs); // skip maximum number of folders before handle #$B needs to be resized // and actual number of folders nfolders = mem_rd_word(fa+2); fa += 4; // now, we read a list of SYM_ENTRY structs (list of folders) for(i=0; i<nfolders; i++) { TI92_SYM_ENTRY se; // read struct memcpy(&se, ti68k_get_real_address(fa + i * sizeof(TI92_SYM_ENTRY)), sizeof(TI92_SYM_ENTRY)); se.handle = GUINT16_FROM_BE(se.handle); // add node vse = g_malloc0(sizeof(VatSymEntry)); strcpy(vse->name, se.name); vse->handle = se.handle; g_node_append(node_top, node_fol = g_node_new(vse)); // handle xxxx: names and handles of all variables heap_get_block_addr_and_size(se.handle, &va, &vs); // skip max num and actual num of vars nvars = mem_rd_word(va+2); va += 4; for(j=0; j<nvars; j++) { // read struct memcpy(&se, ti68k_get_real_address(va + j * sizeof(TI92_SYM_ENTRY)), sizeof(TI92_SYM_ENTRY)); se.handle = GUINT16_FROM_BE(se.handle); // add node vse = g_malloc0(sizeof(VatSymEntry)); strcpy(vse->name, se.name); vse->handle = se.handle; g_node_append(node_fol, node_var = g_node_new(vse)); // handle: variable content heap_get_block_addr_and_size(se.handle, &pa, &ps); } } return 0; }
static int sym_find_handle_92(const char *dirname, const char *filename) { uint32_t fa, va; uint16_t fs, vs; int nfolders, nvars; int i, j; if(tihw.calc_type != TI92) return 0; // handle 000B: names and handles of all folders (including "main") heap_get_block_addr_and_size(0xb, &fa, &fs); // skip maximum number of folders before handle #$B needs to be resized // and actual number of folders nfolders = mem_rd_word(fa+2); fa += 4; // now, we read a list of SYM_ENTRY structs (list of folders) for(i=0; i<nfolders; i++) { TI92_SYM_ENTRY se; // read struct memcpy(&se, ti68k_get_real_address(fa + i * sizeof(TI92_SYM_ENTRY)), sizeof(TI92_SYM_ENTRY)); se.handle = GUINT16_FROM_BE(se.handle); if (strncmp (se.name, dirname, 8)) continue; // handle xxxx: names and handles of all variables heap_get_block_addr_and_size(se.handle, &va, &vs); // skip max num and actual num of vars nvars = mem_rd_word(va+2); va += 4; for(j=0; j<nvars; j++) { // read struct memcpy(&se, ti68k_get_real_address(va + j * sizeof(TI92_SYM_ENTRY)), sizeof(TI92_SYM_ENTRY)); se.handle = GUINT16_FROM_BE(se.handle); // add node if (strncmp (se.name, filename, 8)) continue; return se.handle; } } return 0; }
static int get_folder_list_handle(void) { int h, i; // search for memory blocks which have a string at [5] for(h = 1; h < HEAP_MAX_SIZE; h++) { uint32_t addr; uint16_t size; heap_get_block_addr_and_size(h, &addr, &size); if(is_varname(ti68k_get_real_address(addr + 4))) { // next, be sure we have found the folder list by comparing the number of (possible) // folders with the number of identified folders int nfolders = mem_rd_word(addr+2); // The folder list always contains at least the main folder. if(nfolders == 0) continue; for(i = 0; i < nfolders; i++) if(!is_varname(ti68k_get_real_address(addr + 4 + i*sizeof(TI89_SYM_ENTRY)))) break; // not valid, so try the next handle if(i < nfolders) continue; printf("handle $%i, #folders = %i\n", h, nfolders); return h; } } return -1; }
uint32_t ti68k_debug_disassemble(uint32_t addr, char **line) { uint8_t *mem; char output[256]; uint32_t offset; gchar **split; gchar *p; mem = (uint8_t *)ti68k_get_real_address(addr); offset = Dasm68000(mem, output, addr); split = g_strsplit(output, " ", 2); //printf("<%06x: %s>\n", addr, output); if(split[1]) for(p = split[1]; *p == ' '; p++); else p = ""; *line = g_strdup_printf("%06x: %s %s", addr, split[0] ? split[0] : "", p); g_strfreev(split); return offset; }