246 lines
6.7 KiB
C++
246 lines
6.7 KiB
C++
/*
|
|
* Interactive disassembler (IDA).
|
|
* Copyright (c) 1990-2000 by Ilfak Guilfanov.
|
|
* ALL RIGHTS RESERVED.
|
|
* E-mail: ig@datarescue.com
|
|
*
|
|
*
|
|
*/
|
|
|
|
#include "st7.hpp"
|
|
|
|
//----------------------------------------------------------------------
|
|
class out_st7_t : public outctx_t
|
|
{
|
|
out_st7_t(void) = delete; // not used
|
|
public:
|
|
void outreg(int r) { out_register(ph.reg_names[r]); }
|
|
void outmem(const op_t &x, ea_t ea);
|
|
bool out_operand(const op_t &x);
|
|
void out_insn(void);
|
|
};
|
|
CASSERT(sizeof(out_st7_t) == sizeof(outctx_t));
|
|
|
|
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_st7_t)
|
|
|
|
//----------------------------------------------------------------------
|
|
void out_st7_t::outmem(const op_t &x, ea_t ea)
|
|
{
|
|
qstring qbuf;
|
|
if ( get_name_expr(&qbuf, insn.ea+x.offb, x.n, ea, BADADDR) <= 0 )
|
|
{
|
|
st7_t &pm = *static_cast<st7_t *>(procmod);
|
|
const ioport_t *p = pm.find_sym(x.addr);
|
|
if ( p == NULL )
|
|
{
|
|
out_tagon(COLOR_ERROR);
|
|
out_btoa(x.addr, 16);
|
|
out_tagoff(COLOR_ERROR);
|
|
remember_problem(PR_NONAME, insn.ea);
|
|
}
|
|
else
|
|
{
|
|
out_line(p->name.c_str(), COLOR_IMPNAME);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bool complex = strchr(qbuf.begin(), '+') || strchr(qbuf.begin(), '-');
|
|
if ( complex )
|
|
out_symbol(ash.lbrace);
|
|
out_line(qbuf.begin());
|
|
if ( complex )
|
|
out_symbol(ash.rbrace);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
bool out_st7_t::out_operand(const op_t &x)
|
|
{
|
|
switch ( x.type )
|
|
{
|
|
|
|
case o_void:
|
|
return 0;
|
|
|
|
case o_reg:
|
|
outreg(x.reg);
|
|
break;
|
|
|
|
case o_imm:
|
|
out_symbol('#');
|
|
out_value(x, OOFS_IFSIGN|OOFW_IMM);
|
|
break;
|
|
|
|
case o_displ:
|
|
// o_displ Short Direct Indexed ld A,($10,X) 00..1FE + 1
|
|
// o_displ Long Direct Indexed ld A,($1000,X) 0000..FFFF + 2
|
|
out_symbol('(');
|
|
out_value(x, OOFS_IFSIGN
|
|
|OOF_ADDR
|
|
|((insn.auxpref & aux_16) ? OOFW_16 : OOFW_8));
|
|
out_symbol(',');
|
|
outreg(x.reg);
|
|
out_symbol(')');
|
|
break;
|
|
|
|
case o_phrase:
|
|
out_symbol('(');
|
|
outreg(x.reg);
|
|
out_symbol(')');
|
|
break;
|
|
|
|
case o_mem:
|
|
// o_mem Short Direct ld A,$10 00..FF + 1
|
|
// o_mem Long Direct ld A,$1000 0000..FFFF + 2
|
|
// o_mem Short Indirect ld A,[$10] 00..FF 00..FF byte + 2
|
|
// o_mem Long Indirect ld A,[$10.w] 0000..FFFF 00..FF word + 2
|
|
// o_mem Short Indirect Indexed ld A,([$10],X) 00..1FE 00..FF byte + 2
|
|
// o_mem Long Indirect Indexed ld A,([$10.w],X) 0000..FFFF 00..FF word + 2
|
|
// o_mem Relative Indirect jrne [$10] PC+/-127 00..FF byte + 2
|
|
// o_mem Bit Direct bset $10,#7 00..FF + 1
|
|
// o_mem Bit Indirect bset [$10],#7 00..FF 00..FF byte + 2
|
|
// o_mem Bit Direct Relative btjt $10,#7,skip 00..FF + 2
|
|
// o_mem Bit Indirect Relative btjt [$10],#7,skip 00..FF 00..FF byte + 3
|
|
if ( insn.auxpref & aux_index )
|
|
out_symbol('(');
|
|
if ( insn.auxpref & aux_indir )
|
|
out_symbol('[');
|
|
outmem(x, calc_mem(insn, x.addr));
|
|
if ( insn.auxpref & aux_long )
|
|
{
|
|
out_symbol('.');
|
|
out_symbol('w');
|
|
}
|
|
if ( insn.auxpref & aux_indir )
|
|
out_symbol(']');
|
|
if ( insn.auxpref & aux_index )
|
|
{
|
|
out_symbol(',');
|
|
outreg(x.reg);
|
|
out_symbol(')');
|
|
}
|
|
break;
|
|
|
|
case o_near:
|
|
outmem(x, calc_mem(insn, x.addr));
|
|
break;
|
|
|
|
default:
|
|
INTERR(10379);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------
|
|
void out_st7_t::out_insn(void)
|
|
{
|
|
out_mnemonic();
|
|
|
|
out_one_operand(0);
|
|
if ( insn.Op2.type != o_void )
|
|
{
|
|
out_symbol(',');
|
|
out_char(' ');
|
|
out_one_operand(1);
|
|
}
|
|
if ( insn.Op3.type != o_void )
|
|
{
|
|
out_symbol(',');
|
|
out_char(' ');
|
|
out_one_operand(2);
|
|
}
|
|
|
|
out_immchar_cmts();
|
|
flush_outbuf();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
//lint -esym(1764, ctx) could be made const
|
|
//lint -esym(818, seg) could be made const
|
|
void idaapi st7_segstart(outctx_t &ctx, segment_t *seg)
|
|
{
|
|
if ( is_spec_segm(seg->type) )
|
|
return;
|
|
|
|
const char *align;
|
|
switch ( seg->align )
|
|
{
|
|
case saAbs: align = "at: "; break;
|
|
case saRelByte: align = "byte"; break;
|
|
case saRelWord: align = "word"; break;
|
|
case saRelPara: align = "para"; break;
|
|
case saRelPage: align = "page"; break;
|
|
case saRel4K: align = "4k"; break;
|
|
case saRel64Bytes: align = "64"; break;
|
|
default: align = NULL; break;
|
|
}
|
|
if ( align == NULL )
|
|
{
|
|
ctx.gen_cmt_line("Segment alignment '%s' cannot be represented in assembly",
|
|
get_segment_alignment(seg->align));
|
|
align = "";
|
|
}
|
|
|
|
qstring sname;
|
|
qstring sclas;
|
|
get_visible_segm_name(&sname, seg);
|
|
get_segm_class(&sclas, seg);
|
|
|
|
ctx.out_printf(SCOLOR_ON SCOLOR_ASMDIR "%-*s segment %s ",
|
|
inf_get_indent()-1,
|
|
sname.c_str(),
|
|
align);
|
|
if ( seg->align == saAbs )
|
|
{
|
|
ea_t absbase = get_segm_base(seg);
|
|
ctx.out_btoa(absbase);
|
|
ctx.out_char(' ');
|
|
}
|
|
const char *comb;
|
|
switch ( seg->comb )
|
|
{
|
|
case scPub:
|
|
case scPub2:
|
|
case scPub3: comb = ""; break;
|
|
case scCommon: comb = "common"; break;
|
|
default: comb = NULL; break;
|
|
}
|
|
if ( comb == NULL )
|
|
{
|
|
ctx.gen_cmt_line("Segment combination '%s' cannot be represented in assembly",
|
|
get_segment_combination(seg->comb));
|
|
comb = "";
|
|
}
|
|
ctx.out_printf("%s '%s'", comb, sclas.c_str());
|
|
ctx.out_tagoff(COLOR_ASMDIR);
|
|
ctx.flush_outbuf(0);
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void idaapi st7_segend(outctx_t &, segment_t *)
|
|
{
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void idaapi st7_header(outctx_t &ctx)
|
|
{
|
|
ctx.gen_header(GH_PRINT_PROC | GH_PRINT_HEADER);
|
|
ctx.gen_empty_line();
|
|
}
|
|
|
|
//--------------------------------------------------------------------------
|
|
void st7_t::st7_footer(outctx_t &ctx) const
|
|
{
|
|
qstring nbuf = get_colored_name(inf_get_start_ea());
|
|
const char *name = nbuf.c_str();
|
|
const char *end = ash.end;
|
|
if ( end == NULL )
|
|
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s end %s",SCOLOR_AUTOCMT), ash.cmnt, name);
|
|
else
|
|
ctx.gen_printf(DEFAULT_INDENT,
|
|
COLSTR("%s",SCOLOR_ASMDIR) " " COLSTR("%s %s",SCOLOR_AUTOCMT),
|
|
ash.end, ash.cmnt, name);
|
|
}
|
|
|