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; }
// return value as string static char* rd_mem_as_str(IO_DEF *t) { switch(t->size) { case 1: return g_strdup_printf("%02x", mem_rd_byte(t->addr)); break; case 2: return g_strdup_printf("%04x", mem_rd_word(t->addr)); break; case 4: return g_strdup_printf("%08x", mem_rd_long(t->addr)); break; default: return g_strdup("???"); break; } return g_strdup(""); }
static int rd_bit(IO_DEF *s, int bit_num) { switch(s->size) { case 1: return mem_rd_byte(s->addr) & (1 << bit_num); break; case 2: return mem_rd_word(s->addr) & (1 << bit_num); break; case 4: return mem_rd_long(s->addr) & (1 << bit_num); break; } return -1; }
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; }
// called when a check button has been toggled static void renderer_toggled(GtkCellRendererToggle *cell, gchar *path_string, gpointer user_data) { GtkWidget *tree = user_data; GtkTreeView *view = GTK_TREE_VIEW(tree); GtkTreeModel *model = gtk_tree_view_get_model(view); GtkTreeStore *store = GTK_TREE_STORE(model); GtkTreePath *path; GtkTreeIter parent, iter; IO_DEF *s; gboolean state, result; gchar* bit_str; gint bit_num; gchar* str; path = gtk_tree_path_new_from_string(path_string); if (!gtk_tree_model_get_iter(model, &iter, path)) return; if (!gtk_tree_model_get_iter(model, &iter, path)) return; gtk_tree_model_get(model, &iter, COL_BTNACT, &state, COL_S, &s, COL_ADDR, &bit_str, -1); // change button state state = !state; sscanf(bit_str, "%i", &bit_num); // change value in memory switch(s->size) { case 1: if(state) mem_wr_byte(s->addr, (uint8_t)(mem_rd_byte(s->addr) | (1 << bit_num))); else mem_wr_byte(s->addr, (uint8_t)(mem_rd_byte(s->addr) & ~(1 << bit_num))); break; case 2: if(state) mem_wr_word(s->addr, (uint16_t)(mem_rd_word(s->addr) | (1 << bit_num))); else mem_wr_word(s->addr, (uint16_t)(mem_rd_word(s->addr) & ~(1 << bit_num))); break; case 4: if(state) mem_wr_long(s->addr, mem_rd_long(s->addr) | (1 << bit_num)); else mem_wr_long(s->addr, mem_rd_long(s->addr) & ~(1 << bit_num)); break; } // and change displayed value (parent node) gtk_tree_store_set(store, &iter, COL_BTNACT, state, -1); g_free(bit_str); result = gtk_tree_model_iter_parent(model, &parent, &iter); if(result) { str = rd_mem_as_str(s); gtk_tree_store_set(store, &parent, COL_VALUE, str, -1); g_free(str); } }