//---------------------------------------------------------------------- static void apply_symbols(void) { free_mappings(); if ( dataseg != BADADDR ) { for ( int i=0; i < numports; i++ ) { ea_t ea = calc_data_mem(ports[i].address); segment_t *s = getseg(ea); if ( s == NULL || s->type != SEG_IMEM ) continue; doByte(ea, 1); const char *name = ports[i].name; if ( !set_name(ea, name, SN_NOWARN) ) set_cmt(ea, name, 0); } ea_t ea = dataseg; segment_t *d = getseg(dataseg); if ( d != NULL ) { ea_t dataend = d->endEA; while ( 1 ) { ea = next_unknown(ea, dataend); if ( ea == BADADDR ) break; ea_t end = nextthat(ea, dataend, f_isHead, NULL); if ( end == BADADDR ) end = dataend; doByte(ea, end-ea); } create_mappings(); } } }
//----------------------------------------------------------------------- static void show_segdefs(linput_t *li, uint32 offset, uint32 length) { if ( offset == 0 || length == 0 ) return; qlseek(li, offset); int n = 0; for ( int i=0; i < length; ) { segdef s; const int size = offsetof(segdef, combine_name); lread(li, &s, size); int nlen = read_pstring(li, s.combine_name, sizeof(s.combine_name)); i += size + 1 + nlen; n++; const char *sname = s.combine_name; const char *sclas = sname; if ( strnicmp(sname, "CODE", 4) == 0 ) sclas = "CODE"; if ( strnicmp(sname, "DATA", 4) == 0 ) sclas = "DATA"; if ( strnicmp(sname, "CONST", 5) == 0 ) sclas = "CONST"; if ( stricmp(sname, "STACK") == 0 ) sclas = "STACK"; if ( strchr(sname, ':') != NULL ) continue; int segsize = s.slimit + 1; if ( strcmp(sname, "DATA") == 0 ) dsel = n; set_selector(n, 0); ea_t ea = freechunk(inf.maxEA, segsize, -(1<<s.align)); add_segm(n, ea, ea+segsize, sname, sclas); set_segm_addressing(getseg(ea), true); if ( strcmp(sclas, "STACK") == 0 ) doByte(ea, segsize); } }
bool find_parse_ip(ea_t ea, bool parsecode) { char id[16]; // Attempt to identify program start from ip get_many_bytes(ea, id, 16); if (memcmp(id, "SEGA SEGASATURN ", 16) != 0) return false; make_ascii_string(ea, 16, ASCSTR_C); make_ascii_string(ea+0x10, 16, ASCSTR_C); make_ascii_string(ea+0x20, 10, ASCSTR_C); make_ascii_string(ea+0x2A, 6, ASCSTR_C); make_ascii_string(ea+0x30, 8, ASCSTR_C); make_ascii_string(ea+0x38, 8, ASCSTR_C); make_ascii_string(ea+0x40, 10, ASCSTR_C); make_ascii_string(ea+0x4A, 6, ASCSTR_C); make_ascii_string(ea+0x50, 16, ASCSTR_C); make_ascii_string(ea+0x60, 0x70, ASCSTR_C); doByte(ea+0xD0, 16); doDwrd(ea+0xE0, 4); doDwrd(ea+0xE4, 4); doDwrd(ea+0xE8, 4); doDwrd(ea+0xEC, 4); doDwrd(ea+0xF0, 4); add_func(get_long(ea+0xF0), BADADDR); doDwrd(ea+0xF4, 4); doDwrd(ea+0xF8, 4); doDwrd(ea+0xFC, 4); if (parsecode) add_func(ea+0x100, BADADDR); return true; }
//---------------------------------------------------------------------- static void destroy_if_unnamed_array(ea_t ea) { flags_t F = get_flags_novalue(ea); if ( isTail(F) && segtype(ea) == SEG_IMEM ) { ea_t head = prev_not_tail(ea); if ( !has_user_name(get_flags_novalue(head)) ) { do_unknown(head, DOUNK_SIMPLE); doByte(head, ea-head); ea_t end = nextthat(ea, inf.maxEA, f_isHead, NULL); if ( end == BADADDR ) end = getseg(ea)->endEA; doByte(ea+1, end-ea-1); } } }
// emulate an instruction int emu(void) { uint32 feature = cmd.get_canon_feature(); flow = ((feature & CF_STOP) == 0); if (cmd.Op1.type != o_void) handle_operand(cmd.Op1); if (cmd.Op2.type != o_void) handle_operand(cmd.Op2); if (cmd.Op3.type != o_void) handle_operand(cmd.Op3); /* we can't use this code if (feature & CF_USE1) handle_operand(cmd.Op1, 1); if (feature & CF_USE2) handle_operand(cmd.Op2, 1); if (feature & CF_USE3) handle_operand(cmd.Op3, 1); */ // we don't use CF_JUMP //if (feature & CF_JUMP) switch (cmd.itype) { case m740_jmp: case m740_jsr: if (cmd.Op1.type != o_void && is_addr_ind(cmd.Op1)) QueueMark(Q_jumps, cmd.ea); break; } /* if (feature & CF_CHG1) handle_operand(cmd.Op1, 0); if (feature & CF_CHG2) handle_operand(cmd.Op2, 0); if (feature & CF_CHG3) handle_operand(cmd.Op3, 0); */ if (flow) { // skip the next byte if the current insn is brk if (cmd.itype == m740_brk) { ua_add_cref(0, cmd.ea + cmd.size + 1, fl_JN); doByte(cmd.ea + cmd.size, 1); } else { ua_add_cref(0, cmd.ea + cmd.size, fl_F); } } return 1; }
static void load_symbols(int _respect_info) { if ( cfgname != NULL ) { deviceparams[0] = '\0'; respect_info = _respect_info; if ( !inf.like_binary() ) respect_info &= ~2; free_ioports(ports, numports); ports = read_ioports(&numports, cfgname, device, sizeof(device), callback); if ( respect_info ) { for ( int i=0; i < numports; i++ ) { ea_t ea = ports[i].address; doByte(ea, 1); const char *name = ports[i].name; if ( !set_name(ea, name, SN_NOWARN) ) set_cmt(ea, name, 0); else set_cmt(ea, ports[i].cmt, true); } } } }
static int notify(processor_t::idp_notify msgid, ...) // Various messages { va_list va; va_start(va, msgid); // A well behaving processor module should call invoke_callbacks() // in his notify() function. If this function returns 0, then // the processor module should process the notification itself // Otherwise the code should be returned to the caller: int code = invoke_callbacks(HT_IDP, msgid, va); if ( code ) return code; switch ( msgid ) { case processor_t::newfile: { // ig: вообще у меня теперь такая точка зрения: // не надо в коде задавать вид имен. // при желании это можно сделать в ida.cfg: // #ifdef __80196__ // DUMMY_NAMES_TYPE = NM_SHORT // #endif segment_t *sptr = get_first_seg(); if( sptr != NULL ) set_segm_class( sptr, "CODE" ); ea_t ea, ea1; for( int i = 0; i < qnumber(entries); i++ ) { ea = toEA( inf.baseaddr, entries[i].off ); if( isEnabled(ea) ) { switch( entries[i].type ) { case I196F_BTS: doByte( ea, entries[i+1].off-entries[i].off ); set_cmt( ea, entries[i].cmt, 0 ); break; case I196F_CMT: if( entries[i].cmt ) add_long_cmt( ea, 1, "%s", entries[i].cmt ); else describe( ea, 1, "" ); break; case I196F_OFF: doWord( ea, 2 ); set_offset( ea, 0, toEA( inf.baseaddr, 0 ) ); ea1 = toEA( inf.baseaddr, get_word( ea ) ); auto_make_proc( ea1 ); //dash: long_cmt здесь не смотрится, так как рисуется до заголовка // хорошо бы поставить func_cmt, но к этому моменту функций еще нет // как быть? //ig: воспользоваться простым комментарием // при создании функции комментарий перетащится set_cmt( ea1, entries[i].cmt, 1 ); } set_name( ea, entries[i].name ); } } ea = toEA( inf.baseaddr, 0x2080 ); if( isEnabled( ea ) ) { inf.beginEA = ea; inf.startIP = 0x2080; } segment_t s; s.startEA = toEA( inf.baseaddr, 0 ); s.endEA = toEA( inf.baseaddr, 0x400 ); s.sel = inf.baseaddr; s.type = SEG_IMEM; // internal memory // ig: лучше искать дырку не от нуля, а от базы загрузки // ea_t bottom = toEA( inf.baseaddr, 0 ); // intmem = s.startEA = freechunk( bottom, 1024, 0xF ); // s.endEA = s.startEA + 1024; // s.sel = ushort(s.startEA >> 4); // dash: дырку искать не пришлось, но я оставил это как пример на будущее add_segm_ex( &s, "INTMEM", NULL, ADDSEG_OR_DIE); predefined_t *ptr; for( ptr = iregs; ptr->name != NULL; ptr++ ) { ea_t ea = toEA( inf.baseaddr, ptr->addr ); ea_t oldea = get_name_ea( BADADDR, ptr->name ); if( oldea != ea ) { if( oldea != BADADDR ) set_name( oldea, NULL ); do_unknown( ea, DOUNK_EXPAND ); set_name( ea, ptr->name ); } if( ptr->cmt != NULL ) set_cmt( ea, ptr->cmt, 1 ); } } // do16bit( 0x18, 2 ); // SP always word break; case processor_t::oldfile: for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->startEA) ) { if ( getSRarea(s->startEA) == NULL ) { segreg_t sr; sr.startEA = s->startEA; sr.endEA = s->endEA; sr.reg(WSR) = 0; sr.reg(WSR1) = 0; sr.reg(rVds) = inf.baseaddr; sr.settags(SR_autostart); SRareas.create_area(&sr); } } break; case processor_t::newseg: // default DS is equal to Base Address (va_arg(va, segment_t *))->defsr[rVds-ph.regFirstSreg] = inf.baseaddr; break; case processor_t::newprc: extended = va_arg(va,int) != 0; if ( !extended ) ph.flag &= ~PR_SEGS; else ph.flag |= PR_SEGS; default: break; } va_end(va); return(1); }
void find_bios_funcs() { ea_t i; make_ascii_string(0x06000200, 16, ASCSTR_C); doByte(0x06000210, 36); make_vector(0x06000234, NULL); make_vector(0x06000238, NULL); make_vector(0x0600023C, NULL); make_ascii_string(0x06000240, 4, ASCSTR_C); make_ascii_string(0x06000244, 4, ASCSTR_C); doDwrd(0x06000248, 4); doDwrd(0x0600024C, 4); make_vector(0x06000250, NULL); doDwrd(0x06000264, 4); make_vector(0x06000268, NULL); make_vector(0x0600026C, "bios_run_cd_player"); make_vector(0x06000270, NULL); make_vector(0x06000274, "bios_is_mpeg_card_present"); doDwrd(0x06000278, 4); doDwrd(0x0600027C, 4); make_vector(0x06000280, NULL); make_vector(0x06000284, NULL); make_vector(0x06000288, NULL); make_vector(0x0600028C, NULL); doDwrd(0x06000290, 4); doDwrd(0x06000294, 4); make_vector(0x06000298, "bios_get_mpeg_rom"); make_vector(0x0600029C, NULL); doDwrd(0x060002A0, 4); doDwrd(0x060002A4, 4); doDwrd(0x060002A8, 4); doDwrd(0x060002AC, 4); make_vector(0x060002B0, NULL); doDwrd(0x060002B4, 4); doDwrd(0x060002B8, 4); doDwrd(0x060002BC, 4); doDwrd(0x060002C0, 4); for (i = 0x060002C4; i < 0x06000324; i+=4) make_vector(i, NULL); set_name(0x06000300, "bios_set_scu_interrupt"); set_name(0x06000304, "bios_get_scu_interrupt"); set_name(0x06000310, "bios_set_sh2_interrupt"); set_name(0x06000314, "bios_get_sh2_interrupt"); set_name(0x06000320, "bios_set_clock_speed"); doDwrd(0x06000324, 4); set_name(0x06000324, "bios_get_clock_speed"); for (i = 0x06000328; i < 0x06000348; i+=4) make_vector(i, NULL); set_name(0x06000340, "bios_set_scu_interrupt_mask"); set_name(0x06000344, "bios_change_scu_interrupt_mask"); doDwrd(0x06000348, 4); set_name(0x06000348, "bios_get_scu_interrupt_mask"); make_vector(0x0600034C, NULL); doDwrd(0x06000350, 4); doDwrd(0x06000354, 4); doDwrd(0x06000358, 4); doDwrd(0x0600035C, 4); for (i = 0x06000360; i < 0x06000380; i+=4) make_vector(i, NULL); doByte(0x06000380, 16); doWord(0x06000390, 16); doDwrd(0x060003A0, 32); make_ascii_string(0x060003C0, 0x40, ASCSTR_C); add_func(0x06000600, BADADDR); add_func(0x06000646, BADADDR); make_ascii_string(0x0600065C, 0x4, ASCSTR_C); add_func(0x06000678, BADADDR); add_func(0x0600067C, BADADDR); add_func(0x06000690, BADADDR); doDwrd(0x06000A80, 0x80); }