128 lines
4.0 KiB
C++
128 lines
4.0 KiB
C++
/*
|
|
This module has been created by Petr Novak
|
|
*/
|
|
|
|
#ifndef _XA_HPP
|
|
#define _XA_HPP
|
|
|
|
#include "../idaidp.hpp"
|
|
#include "ins.hpp"
|
|
|
|
//------------------------------------------------------------------------
|
|
// customization of the insn_t structure:
|
|
|
|
// XA bit references:
|
|
|
|
#define o_bit o_idpspec0
|
|
#define o_bitnot o_idpspec1
|
|
|
|
// fRi and other indirect register number (for o_phrase):
|
|
#define indreg specflag1
|
|
|
|
// ash.uflag bit meanings:
|
|
|
|
#define UAS_PSAM 0x0001 // PseudoSam: use funny form of
|
|
// equ for intmem
|
|
#define UAS_SECT 0x0002 // Segments are named .SECTION
|
|
#define UAS_NOSEG 0x0004 // No 'segment' directives
|
|
#define UAS_NOBIT 0x0008 // No bit.# names, use bit_#
|
|
#define UAS_SELSG 0x0010 // Segment should be selected by its name
|
|
#define UAS_EQCLN 0x0020 // ':' in EQU directives
|
|
#define UAS_AUBIT 0x0040 // Don't use BIT directives -
|
|
// assembler generates bit names itself
|
|
#define UAS_CDSEG 0x0080 // Only DSEG,CSEG,XSEG
|
|
#define UAS_NODS 0x0100 // No .DS directives in Code segment
|
|
#define UAS_NOENS 0x0200 // don't specify start addr in the .end directive
|
|
#define UAS_PBIT 0x0400 // assembler knows about predefined bits
|
|
#define UAS_PBYTNODEF 0x0800 // do not define predefined byte names
|
|
|
|
enum processor_subtype_t
|
|
{
|
|
// odd types are binary mode
|
|
// even types are source modes
|
|
prc_xaG3 = 0, // XAG3
|
|
};
|
|
|
|
struct predefined_t;
|
|
struct xa_t : public procmod_t
|
|
{
|
|
processor_subtype_t ptype;
|
|
bool flow = false; // does the current instruction pass
|
|
|
|
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
|
|
|
|
void attach_bit_comment(const insn_t &insn, int addr, int bit) const;
|
|
const predefined_t *GetPredefined(const predefined_t *ptr, int addr, int bit) const;
|
|
const predefined_t *GetPredefinedBits(int addr, int bit) const;
|
|
static int IsPredefined(const char *name);
|
|
|
|
void xa_header(outctx_t &ctx);
|
|
void xa_footer(outctx_t &ctx);
|
|
void xa_segstart(outctx_t &ctx, segment_t *seg);
|
|
|
|
int ana(insn_t *insn);
|
|
|
|
int emu(const insn_t &insn);
|
|
void handle_operand(insn_t &insn, const op_t &x, bool loading);
|
|
|
|
void xa_data(outctx_t &ctx, bool analyze_only);
|
|
static bool xa_create_func(func_t *pfn);
|
|
static bool xa_is_switch(switch_info_t *si, const insn_t &insn);
|
|
static int xa_frame_retsize(const func_t *pfn);
|
|
static void xa_stkvar_def(outctx_t &ctx, const member_t *mptr, sval_t v);
|
|
static int xa_align_insn(ea_t ea);
|
|
};
|
|
|
|
#define INTMEMBASE (2L << 24)
|
|
#define SFRBASE (INTMEMBASE + 0x400)
|
|
#define EXTRAMBASE (1L << 24)
|
|
|
|
inline ea_t map_addr(ea_t off)
|
|
{
|
|
return ((off >= 0x800) ? EXTRAMBASE : INTMEMBASE) + off;
|
|
}
|
|
|
|
#define DS 0x441
|
|
#define ES 0x442
|
|
#define CS 0x443
|
|
|
|
//------------------------------------------------------------------------
|
|
// Registers
|
|
enum xa_registers
|
|
{
|
|
rR0L, rR0H, rR1L, rR1H, rR2L, rR2H, rR3L, rR3H, rR4L, rR4H,
|
|
rR5L, rR5H, rR6L, rR6H, rR7L, rR7H,
|
|
rR0, rR1, rR2, rR3, rR4, rR5, rR6, rR7,
|
|
rR8, rR9, rR10, rR11, rR12, rR13, rR14, rR15,
|
|
rA, rDPTR, rC, rPC, rUSP,
|
|
rCS, rDS, rES
|
|
};
|
|
|
|
// Indirect addressing modes without a displacement:
|
|
enum xa_phrases
|
|
{
|
|
fAdptr, // [A+DPTR]
|
|
fApc, // [A+PC]
|
|
fRi, // [Ri], reg number in indreg
|
|
fRii, // [[Ri]], reg number in indreg
|
|
fRip, // [Ri+], reg number in indreg
|
|
fRipi, // [[Ri+]], reg number in indreg
|
|
fRid8, // [Ri+d8], reg number in indreg
|
|
fRid16, // [Ri+d16], reg number in indreg
|
|
fRlistL, // PUSH/POP list of registers lower half
|
|
fRlistH, // PUSH/POP upper half of registers
|
|
};
|
|
|
|
|
|
// The predefined locations
|
|
struct predefined_t
|
|
{
|
|
uchar proc;
|
|
uint16 addr;
|
|
uchar bit;
|
|
const char *name;
|
|
const char *cmt;
|
|
};
|
|
|
|
#endif
|