update to ida 7.6, add builds
This commit is contained in:
1128
idasdk76/module/mn102/ana.cpp
Normal file
1128
idasdk76/module/mn102/ana.cpp
Normal file
File diff suppressed because it is too large
Load Diff
115
idasdk76/module/mn102/emu.cpp
Normal file
115
idasdk76/module/mn102/emu.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Panasonic MN102 (PanaXSeries) processor module for IDA.
|
||||
* Copyright (c) 2000-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "pan.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// handle use/change of operands
|
||||
void mn102_t::handle_operand(const insn_t &insn, const op_t &x, bool is_forced, bool isload)
|
||||
{
|
||||
ea_t ea = map_code_ea(insn, x);
|
||||
switch ( x.type )
|
||||
{
|
||||
// unused
|
||||
case o_void:
|
||||
break;
|
||||
// nothing to do
|
||||
case o_reg:
|
||||
break;
|
||||
|
||||
// try to handle as offset
|
||||
case o_displ: // if not forced and marked as offset
|
||||
if ( !is_forced && is_off(get_flags(insn.ea), x.n) )
|
||||
{
|
||||
// add cross-reference
|
||||
insn.add_dref(ea, x.offb, isload ? dr_R : dr_W);
|
||||
}
|
||||
break;
|
||||
|
||||
// immediate operand
|
||||
case o_imm:
|
||||
// may not be changed
|
||||
if ( !isload )
|
||||
goto badTouch;
|
||||
// set immediate flag
|
||||
set_immd(insn.ea);
|
||||
if ( !is_forced )
|
||||
{
|
||||
flags_t F = get_flags(insn.ea);
|
||||
if ( is_off(F, x.n)
|
||||
|| (x.specflag1 & URB_ADDR) != 0 && !is_defarg(F, x.n) )
|
||||
{
|
||||
if ( !is_off(F, x.n) )
|
||||
op_plain_offset(insn.ea, x.n, 0);
|
||||
// it's an offset
|
||||
insn.add_dref(ea, x.offb, dr_O);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// jump or call
|
||||
case o_near:
|
||||
// is it a call?
|
||||
if ( has_insn_feature(insn.itype,CF_CALL) )
|
||||
{
|
||||
// add code xref
|
||||
insn.add_cref(ea, x.offb, fl_CN);
|
||||
// does the function return?
|
||||
flow = func_does_return(ea);
|
||||
}
|
||||
else
|
||||
{
|
||||
insn.add_cref(ea, x.offb, fl_JN);
|
||||
}
|
||||
break;
|
||||
|
||||
// memory reference
|
||||
case o_mem:
|
||||
insn.create_op_data(ea, x);
|
||||
// add cross-reference
|
||||
insn.add_dref(ea, x.offb, isload ? dr_R : dr_W);
|
||||
break;
|
||||
|
||||
// othewrwise - error
|
||||
default:
|
||||
badTouch:
|
||||
warning("%a %s,%d: bad optype %d",
|
||||
insn.ea, insn.get_canon_mnem(ph),
|
||||
x.n, x.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// emulator
|
||||
int mn102_t::mn102_emu(const insn_t &insn)
|
||||
{
|
||||
uint32 Feature = insn.get_canon_feature(ph);
|
||||
// get operand types
|
||||
bool flag1 = is_forced_operand(insn.ea, 0);
|
||||
bool flag2 = is_forced_operand(insn.ea, 1);
|
||||
bool flag3 = is_forced_operand(insn.ea, 2);
|
||||
|
||||
flow = ((Feature & CF_STOP) == 0);
|
||||
|
||||
// add cross-references for operands
|
||||
if ( Feature & CF_USE1 ) handle_operand(insn, insn.Op1, flag1, true);
|
||||
if ( Feature & CF_USE2 ) handle_operand(insn, insn.Op2, flag2, true);
|
||||
if ( Feature & CF_USE3 ) handle_operand(insn, insn.Op3, flag3, true);
|
||||
// add jumps to problem queue
|
||||
if ( Feature & CF_JUMP )
|
||||
remember_problem(PR_JUMP, insn.ea);
|
||||
|
||||
// handle changed operands
|
||||
if ( Feature & CF_CHG1 ) handle_operand(insn, insn.Op1, flag1, false);
|
||||
if ( Feature & CF_CHG2 ) handle_operand(insn, insn.Op2, flag2, false);
|
||||
if ( Feature & CF_CHG3 ) handle_operand(insn, insn.Op3, flag3, false);
|
||||
// if not stopping, continue with the next instruction
|
||||
if ( flow )
|
||||
add_cref(insn.ea, insn.ea+insn.size, fl_F);
|
||||
|
||||
return 1;
|
||||
}
|
||||
83
idasdk76/module/mn102/ins.cpp
Normal file
83
idasdk76/module/mn102/ins.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Panasonic MN102 (PanaXSeries) processor module for IDA.
|
||||
* Copyright (c) 2000-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "pan.hpp"
|
||||
|
||||
const instruc_t Instructions[] =
|
||||
{
|
||||
{ "", 0 },
|
||||
{ "ADD", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "ADDC", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "ADDNF", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "AND", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "ASR", CF_USE1|CF_CHG1 },
|
||||
{ "BCC", CF_USE1|CF_JUMP },
|
||||
{ "BCCX", CF_USE1|CF_JUMP },
|
||||
{ "BCLR", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "BCS", CF_USE1|CF_JUMP },
|
||||
{ "BCSX", CF_USE1|CF_JUMP },
|
||||
{ "BEQ", CF_USE1|CF_JUMP },
|
||||
{ "BEQX", CF_USE1|CF_JUMP },
|
||||
{ "BGE", CF_USE1|CF_JUMP },
|
||||
{ "BGEX", CF_USE1|CF_JUMP },
|
||||
{ "BGT", CF_USE1|CF_JUMP },
|
||||
{ "BGTX", CF_USE1|CF_JUMP },
|
||||
{ "BHI", CF_USE1|CF_JUMP },
|
||||
{ "BHIX", CF_USE1|CF_JUMP },
|
||||
{ "BLE", CF_USE1|CF_JUMP },
|
||||
{ "BLEX", CF_USE1|CF_JUMP },
|
||||
{ "BLS", CF_USE1|CF_JUMP },
|
||||
{ "BLSX", CF_USE1|CF_JUMP },
|
||||
{ "BLT", CF_USE1|CF_JUMP },
|
||||
{ "BLTX", CF_USE1|CF_JUMP },
|
||||
{ "BNC", CF_USE1|CF_JUMP },
|
||||
{ "BNCX", CF_USE1|CF_JUMP },
|
||||
{ "BNE", CF_USE1|CF_JUMP },
|
||||
{ "BNEX", CF_USE1|CF_JUMP },
|
||||
{ "BNS", CF_USE1|CF_JUMP },
|
||||
{ "BNSX", CF_USE1|CF_JUMP },
|
||||
{ "BRA", CF_USE1|CF_JUMP|CF_STOP },
|
||||
{ "BSET", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "BTST", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "BVC", CF_USE1|CF_JUMP },
|
||||
{ "BVCX", CF_USE1|CF_JUMP },
|
||||
{ "BVS", CF_USE1|CF_JUMP },
|
||||
{ "BVSX", CF_USE1|CF_JUMP },
|
||||
{ "CMP", CF_USE1|CF_USE2 },
|
||||
{ "DIVU", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "EXT", CF_USE1 },
|
||||
{ "EXTX", CF_USE1|CF_CHG1 },
|
||||
{ "EXTXB", CF_USE1|CF_CHG1 },
|
||||
{ "EXTXBU", CF_USE1|CF_CHG1 },
|
||||
{ "EXTXU", CF_USE1|CF_CHG1 },
|
||||
{ "JMP", CF_USE1|CF_JUMP|CF_STOP },
|
||||
{ "JSR", CF_USE1|CF_CALL },
|
||||
{ "LSR", CF_USE1|CF_CHG1 },
|
||||
{ "MOV", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "MOVB", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "MOVBU", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "MOVX", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "MUL", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "MULQ", CF_USE1|CF_USE2 },
|
||||
{ "MULQH", CF_USE1|CF_USE2 },
|
||||
{ "MULQL", CF_USE1|CF_USE2 },
|
||||
{ "MULU", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "NOP", 0 },
|
||||
{ "NOT", CF_USE1|CF_CHG1 },
|
||||
{ "OR", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "PXST", 0 },
|
||||
{ "ROL", CF_USE1|CF_CHG1 },
|
||||
{ "ROR", CF_USE1|CF_CHG1 },
|
||||
{ "RTI", CF_STOP },
|
||||
{ "RTS", CF_STOP },
|
||||
{ "SUB", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "SUBC", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "TBNZ", CF_USE1|CF_USE2|CF_USE3|CF_JUMP },
|
||||
{ "TBZ", CF_USE1|CF_USE2|CF_USE3|CF_JUMP },
|
||||
{ "XOR", CF_USE1|CF_USE2|CF_CHG2 }
|
||||
};
|
||||
|
||||
CASSERT(qnumber(Instructions) == mn102_last);
|
||||
88
idasdk76/module/mn102/ins.hpp
Normal file
88
idasdk76/module/mn102/ins.hpp
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Panasonic MN102 (PanaXSeries) processor module for IDA.
|
||||
* Copyright (c) 2000-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#ifndef __INSTRS_HPP
|
||||
#define __INSTRS_HPP
|
||||
|
||||
// List of instructions
|
||||
extern const instruc_t Instructions[];
|
||||
|
||||
enum nameNum ENUM_SIZE(uint16)
|
||||
{
|
||||
mn102_null = 0, // Unknown Operation
|
||||
mn102_add,
|
||||
mn102_addc,
|
||||
mn102_addnf,
|
||||
mn102_and,
|
||||
mn102_asr,
|
||||
mn102_bcc,
|
||||
mn102_bccx,
|
||||
mn102_bclr,
|
||||
mn102_bcs,
|
||||
mn102_bcsx,
|
||||
mn102_beq,
|
||||
mn102_beqx,
|
||||
mn102_bge,
|
||||
mn102_bgex,
|
||||
mn102_bgt,
|
||||
mn102_bgtx,
|
||||
mn102_bhi,
|
||||
mn102_bhix,
|
||||
mn102_ble,
|
||||
mn102_blex,
|
||||
mn102_bls,
|
||||
mn102_blsx,
|
||||
mn102_blt,
|
||||
mn102_bltx,
|
||||
mn102_bnc,
|
||||
mn102_bncx,
|
||||
mn102_bne,
|
||||
mn102_bnex,
|
||||
mn102_bns,
|
||||
mn102_bnsx,
|
||||
mn102_bra,
|
||||
mn102_bset,
|
||||
mn102_btst,
|
||||
mn102_bvc,
|
||||
mn102_bvcx,
|
||||
mn102_bvs,
|
||||
mn102_bvsx,
|
||||
mn102_cmp,
|
||||
mn102_divu,
|
||||
mn102_ext,
|
||||
mn102_extx,
|
||||
mn102_extxb,
|
||||
mn102_extxbu,
|
||||
mn102_extxu,
|
||||
mn102_jmp,
|
||||
mn102_jsr,
|
||||
mn102_lsr,
|
||||
mn102_mov,
|
||||
mn102_movb,
|
||||
mn102_movbu,
|
||||
mn102_movx,
|
||||
mn102_mul,
|
||||
mn102_mulq,
|
||||
mn102_mulqh,
|
||||
mn102_mulql,
|
||||
mn102_mulu,
|
||||
mn102_nop,
|
||||
mn102_not,
|
||||
mn102_or,
|
||||
mn102_pxst,
|
||||
mn102_rol,
|
||||
mn102_ror,
|
||||
mn102_rti,
|
||||
mn102_rts,
|
||||
mn102_sub,
|
||||
mn102_subc,
|
||||
mn102_tbnz,
|
||||
mn102_tbz,
|
||||
mn102_xor,
|
||||
mn102_last
|
||||
};
|
||||
|
||||
#endif
|
||||
57
idasdk76/module/mn102/makefile
Normal file
57
idasdk76/module/mn102/makefile
Normal file
@@ -0,0 +1,57 @@
|
||||
PROC=mn102l00
|
||||
CONFIGS=mn102l00.cfg
|
||||
|
||||
|
||||
include ../module.mak
|
||||
|
||||
# MAKEDEP dependency list ------------------
|
||||
$(F)ana$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)diskio.hpp \
|
||||
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
|
||||
$(I)llong.hpp $(I)loader.hpp \
|
||||
$(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
|
||||
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
|
||||
ana.cpp ins.hpp pan.hpp
|
||||
$(F)emu$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)diskio.hpp \
|
||||
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
|
||||
$(I)llong.hpp $(I)loader.hpp \
|
||||
$(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
|
||||
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
|
||||
emu.cpp ins.hpp pan.hpp
|
||||
$(F)ins$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)diskio.hpp \
|
||||
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
|
||||
$(I)llong.hpp $(I)loader.hpp \
|
||||
$(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
|
||||
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
|
||||
ins.cpp ins.hpp pan.hpp
|
||||
$(F)out$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)diskio.hpp \
|
||||
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
|
||||
$(I)llong.hpp $(I)loader.hpp \
|
||||
$(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
|
||||
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
|
||||
ins.hpp out.cpp pan.hpp
|
||||
$(F)reg$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
|
||||
$(I)config.hpp $(I)diskio.hpp \
|
||||
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
|
||||
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
|
||||
$(I)llong.hpp $(I)loader.hpp \
|
||||
$(I)nalt.hpp $(I)name.hpp \
|
||||
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
|
||||
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
|
||||
../iohandler.hpp ins.hpp pan.hpp reg.cpp
|
||||
73
idasdk76/module/mn102/mn102l00.cfg
Normal file
73
idasdk76/module/mn102/mn102l00.cfg
Normal file
@@ -0,0 +1,73 @@
|
||||
; The format of the input file:
|
||||
; each device definition begins with a line like this:
|
||||
;
|
||||
; .devicename
|
||||
;
|
||||
; after it go the port definitions in this format:
|
||||
;
|
||||
; portname address
|
||||
;
|
||||
; the bit definitions (optional) are represented like this:
|
||||
;
|
||||
; portname.bitname bitnumber
|
||||
;
|
||||
; lines beginning with a space are ignored.
|
||||
; comment lines should be started with ';' character.
|
||||
;
|
||||
; the default device is specified at the start of the file
|
||||
;
|
||||
; .default device_name
|
||||
;
|
||||
; all lines non conforming to the format are passed to the callback function
|
||||
;
|
||||
; Panasonic MN102 SPECIFIC LINES
|
||||
;------------------------
|
||||
;
|
||||
; the processor definition may include the memory configuration.
|
||||
; the line format is:
|
||||
|
||||
; area CLASS AREA-NAME START:END
|
||||
;
|
||||
; where CLASS is anything, but please use one of CODE, DATA, BSS
|
||||
; START and END are addresses, the end address is not included
|
||||
|
||||
; Interrupt vectors are declared in the following way:
|
||||
|
||||
; entry NAME ADDRESS COMMENT
|
||||
|
||||
.default MN102
|
||||
|
||||
|
||||
.MN102
|
||||
|
||||
; MEMORY MAP
|
||||
area DATA IRAM 0x08000:0x0FC00 Internal RAM
|
||||
area DATA FSR 0x0FC00:0x10000 Special Function Register
|
||||
area CODE IROM 0x80000:0xFC000 Internal ROM
|
||||
|
||||
; Interrupt and reset vector assignments
|
||||
entry RESET_ 0x80000 RESET after power on
|
||||
entry IRQMANAGER_ 0x80008 IRQ Manager
|
||||
|
||||
; INPUT/OUTPUT (not all!)
|
||||
CPUM 0xFC00 CPU mode control register
|
||||
EFCR 0xFC08 Memory control register
|
||||
IAGR 0xFC0E Interrupt accept group number register
|
||||
NMICR 0xFC40 Non-maskable interrupt control register
|
||||
WDICR 0xFC42 Watchdog Interrupt Control Register
|
||||
UNICR 0xFC44 Undefined Instruction Interrupt Control Register
|
||||
EIICR 0xFC46 Error Interrupt Control Register
|
||||
IQ0ICL 0xFC50 External Interrupt 0 Control Register
|
||||
IQ0ICH 0xFC51 External Interrupt 0 Control Register
|
||||
TM0ICL 0xFC52 Timer 0 Underflow Interrupt Control Register
|
||||
TM0ICH 0xFC53 Timer 0 Underflow Interrupt Control Register
|
||||
TM8ICL 0xFC54 Timer 8 Underflow Interrupt Control Register
|
||||
TM8ICH 0xFC55 Timer 8 Underflow Interrupt Control Register
|
||||
TM8AICL 0xFC56 Timer 8 Capture A Interrupt Control Register
|
||||
TM8AICH 0xFC57 Timer 8 Capture A Interrupt Control Register
|
||||
IQ1ICL 0xFC58 External Interrupt 1 Control Register
|
||||
IQ1ICH 0xFC59 External Interrupt 1 Control Register
|
||||
IRQTRG 0xFCB0
|
||||
KEYTRG 0xFCB2
|
||||
KEYCTR 0xFCB4
|
||||
WDREG 0xFCB8
|
||||
198
idasdk76/module/mn102/out.cpp
Normal file
198
idasdk76/module/mn102/out.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Panasonic MN102 (PanaXSeries) processor module for IDA.
|
||||
* Copyright (c) 2000-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "pan.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
class out_mn102_t : public outctx_t
|
||||
{
|
||||
out_mn102_t(void) = delete; // not used
|
||||
public:
|
||||
void OutVarName(const op_t &x);
|
||||
bool out_operand(const op_t &x);
|
||||
void out_insn(void);
|
||||
};
|
||||
CASSERT(sizeof(out_mn102_t) == sizeof(outctx_t));
|
||||
|
||||
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_mn102_t)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_mn102_t::OutVarName(const op_t &x)
|
||||
{
|
||||
ea_t toea = map_code_ea(insn, x);
|
||||
if ( !out_name_expr(x, toea, x.addr) )
|
||||
{
|
||||
out_value(x, OOF_ADDR | OOF_NUMBER | OOFS_NOSIGN | OOFW_32);
|
||||
remember_problem(PR_NONAME, insn.ea);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// print one operand
|
||||
bool out_mn102_t::out_operand(const op_t & x)
|
||||
{
|
||||
switch ( x.type )
|
||||
{
|
||||
// memory reference with a regsiter
|
||||
// (disp,Ri)
|
||||
case o_displ:
|
||||
out_symbol('(');
|
||||
out_value(x);
|
||||
out_symbol(',');
|
||||
out_register(ph.reg_names[x.reg]);
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
// register
|
||||
case o_reg:
|
||||
if ( x.reg&0x80 )
|
||||
out_symbol('(');
|
||||
if ( x.reg&0x10 )
|
||||
{
|
||||
out_register(ph.reg_names[((x.reg>>5)&3)+rD0]);
|
||||
out_symbol(',');
|
||||
}
|
||||
out_register(ph.reg_names[x.reg&0x0F]);
|
||||
if ( x.reg&0x80 )
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
// immediate operand
|
||||
case o_imm:
|
||||
refinfo_t ri;
|
||||
// micro bug-fix
|
||||
if ( get_refinfo(&ri, insn.ea, x.n) )
|
||||
{
|
||||
if ( ri.flags == REF_OFF16 )
|
||||
set_refinfo(insn.ea, x.n, REF_OFF32, ri.target, ri.base, ri.tdelta);
|
||||
}
|
||||
out_value(x, /*OOFS_NOSIGN | */ OOF_SIGNED | OOFW_IMM);
|
||||
break;
|
||||
|
||||
// code reference
|
||||
case o_near:
|
||||
OutVarName(x);
|
||||
break;
|
||||
|
||||
// direct memory reference
|
||||
case o_mem:
|
||||
out_symbol('(');
|
||||
OutVarName(x);
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
// nothing for void
|
||||
case o_void:
|
||||
return 0;
|
||||
|
||||
// unknown operand
|
||||
default:
|
||||
warning("out: %a: bad optype %d",insn.ea,x.type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// main instruction printer
|
||||
void out_mn102_t::out_insn(void)
|
||||
{
|
||||
// print mnemonic
|
||||
out_mnemonic();
|
||||
|
||||
// print first operands
|
||||
if ( insn.Op1.type != o_void )
|
||||
out_one_operand(0);
|
||||
|
||||
// second operand
|
||||
if ( insn.Op2.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
out_one_operand(1);
|
||||
// third operand
|
||||
if ( insn.Op3.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
out_one_operand(2);
|
||||
}
|
||||
}
|
||||
|
||||
out_immchar_cmts();
|
||||
flush_outbuf();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// listing header
|
||||
void mn102_t::mn102_header(outctx_t &ctx)
|
||||
{
|
||||
ctx.gen_header(GH_PRINT_ALL_BUT_BYTESEX, ioh.device.c_str(), ioh.deviceparams.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// segment header
|
||||
//lint -esym(1764, ctx) could be made const
|
||||
//lint -esym(818, Sarea) could be made const
|
||||
void mn102_t::mn102_segstart(outctx_t &ctx, segment_t *Sarea) const
|
||||
{
|
||||
ea_t ea = ctx.insn_ea;
|
||||
const char *SegType = Sarea->type == SEG_CODE ? "CSEG"
|
||||
: Sarea->type == SEG_DATA ? "DSEG"
|
||||
: "RSEG";
|
||||
// print RSEG <NAME>
|
||||
qstring sn;
|
||||
get_visible_segm_name(&sn, Sarea);
|
||||
ctx.gen_printf(-1, "%s %s ", SegType, sn.c_str());
|
||||
// if org is not zero, print it
|
||||
if ( (inf_get_outflags() & OFLG_GEN_ORG) != 0 )
|
||||
{
|
||||
ea_t org = ea - get_segm_base(Sarea);
|
||||
if ( org != 0 )
|
||||
{
|
||||
char bufn[MAX_NUMBUF];
|
||||
btoa(bufn, sizeof(bufn), org);
|
||||
ctx.gen_printf(-1, "%s %s", ash.origin, bufn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// end of listing
|
||||
void mn102_t::mn102_footer(outctx_t &ctx) const
|
||||
{
|
||||
if ( ash.end != NULL )
|
||||
{
|
||||
ctx.gen_empty_line();
|
||||
ctx.out_line(ash.end, COLOR_ASMDIR);
|
||||
qstring name;
|
||||
if ( get_colored_name(&name, inf_get_start_ea()) > 0 )
|
||||
{
|
||||
size_t i = strlen(ash.end);
|
||||
do
|
||||
ctx.out_char(' ');
|
||||
while ( ++i < 8 );
|
||||
ctx.out_line(name.begin());
|
||||
}
|
||||
ctx.flush_outbuf(DEFAULT_INDENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.gen_cmt_line("end of file");
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void idaapi mn102_data(outctx_t &ctx, bool analyze_only)
|
||||
{
|
||||
ea_t ea = ctx.insn_ea;
|
||||
// micro bug-fix
|
||||
refinfo_t ri;
|
||||
if ( get_refinfo(&ri, ea, 0) && ri.flags == REF_OFF16 )
|
||||
set_refinfo(ea, 0, REF_OFF32, ri.target, ri.base, ri.tdelta);
|
||||
|
||||
ctx.out_data(analyze_only);
|
||||
}
|
||||
65
idasdk76/module/mn102/pan.hpp
Normal file
65
idasdk76/module/mn102/pan.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Panasonic MN102 (PanaXSeries) processor module for IDA.
|
||||
* Copyright (c) 2000-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#ifndef _PAN_HPP
|
||||
#define _PAN_HPP
|
||||
|
||||
#include <ida.hpp>
|
||||
#include <idp.hpp>
|
||||
|
||||
#include "../idaidp.hpp"
|
||||
#include "ins.hpp"
|
||||
#include "../iohandler.hpp"
|
||||
|
||||
//-----------------------------------------------
|
||||
// additional bits (specflag1)
|
||||
#define URB_ADDR 0x1 // immediate operand is an address
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
#ifdef _MSC_VER
|
||||
#define ENUM8BIT : uint8
|
||||
#else
|
||||
#define ENUM8BIT
|
||||
#endif
|
||||
// list of processor registers
|
||||
enum mn102_registers ENUM8BIT
|
||||
{
|
||||
rNULLReg,
|
||||
rD0, rD1, rD2, rD3,
|
||||
rA0, rA1, rA2, rA3,
|
||||
rMDR,rPSW, rPC,
|
||||
rVcs, rVds
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int idaapi mn102_ana(insn_t *_insn);
|
||||
|
||||
void idaapi mn102_data(outctx_t &ctx, bool analyze_only);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct mn102_t : public procmod_t
|
||||
{
|
||||
netnode helper;
|
||||
iohandler_t ioh = iohandler_t(helper);
|
||||
bool flow = false; // code flow continues flag
|
||||
|
||||
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
|
||||
|
||||
void handle_operand(const insn_t &insn, const op_t &x, bool is_forced, bool isload);
|
||||
int mn102_emu(const insn_t &insn);
|
||||
|
||||
void mn102_header(outctx_t &ctx);
|
||||
void mn102_segstart(outctx_t &ctx, segment_t *Sarea) const;
|
||||
void mn102_footer(outctx_t &ctx) const;
|
||||
|
||||
void load_from_idb();
|
||||
};
|
||||
|
||||
extern int data_id;
|
||||
#define PROCMOD_NODE_NAME "$ MN102"
|
||||
#define PROCMOD_NAME mn102
|
||||
|
||||
#endif
|
||||
251
idasdk76/module/mn102/reg.cpp
Normal file
251
idasdk76/module/mn102/reg.cpp
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Panasonic MN102 (PanaXSeries) processor module for IDA.
|
||||
* Copyright (c) 2000-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "pan.hpp"
|
||||
#include <diskio.hpp>
|
||||
#include <segregs.hpp>
|
||||
int data_id;
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// register names
|
||||
static const char *const RegNames[] =
|
||||
{
|
||||
// empty
|
||||
"",
|
||||
"D0","D1","D2","D3",
|
||||
"A0","A1","A2","SP", // SP is alias of A3
|
||||
// special
|
||||
"MDR","PSW","PC",
|
||||
// pseudo-segment
|
||||
"cs","ds"
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void mn102_t::load_from_idb()
|
||||
{
|
||||
ioh.restore_device();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// This old-style callback only returns the processor module object.
|
||||
static ssize_t idaapi notify(void *, int msgid, va_list)
|
||||
{
|
||||
if ( msgid == processor_t::ev_get_procmod )
|
||||
return size_t(SET_MODULE_DATA(mn102_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
ssize_t idaapi mn102_t::on_event(ssize_t msgid, va_list va)
|
||||
{
|
||||
int code = 0;
|
||||
switch ( msgid )
|
||||
{
|
||||
case processor_t::ev_init:
|
||||
inf_set_be(false);
|
||||
inf_set_gen_lzero(true);
|
||||
helper.create(PROCMOD_NODE_NAME);
|
||||
break;
|
||||
|
||||
case processor_t::ev_term:
|
||||
ioh.ports.clear();
|
||||
clr_module_data(data_id);
|
||||
break;
|
||||
|
||||
case processor_t::ev_newfile:
|
||||
{
|
||||
char cfgfile[QMAXFILE];
|
||||
ioh.get_cfg_filename(cfgfile, sizeof(cfgfile));
|
||||
iohandler_t::parse_area_line0_t cb(ioh);
|
||||
if ( choose_ioport_device2(&ioh.device, cfgfile, &cb) )
|
||||
ioh.set_device_name(ioh.device.c_str(), IORESP_ALL);
|
||||
}
|
||||
break;
|
||||
|
||||
case processor_t::ev_ending_undo:
|
||||
case processor_t::ev_oldfile:
|
||||
load_from_idb();
|
||||
break;
|
||||
|
||||
case processor_t::ev_creating_segm:
|
||||
{
|
||||
segment_t *s = va_arg(va, segment_t *);
|
||||
// Set default value of DS register for all segments
|
||||
set_default_dataseg(s->sel);
|
||||
}
|
||||
break;
|
||||
|
||||
case processor_t::ev_out_header:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
mn102_header(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_footer:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
mn102_footer(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_segstart:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
segment_t *seg = va_arg(va, segment_t *);
|
||||
mn102_segstart(*ctx, seg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_ana_insn:
|
||||
{
|
||||
insn_t *out = va_arg(va, insn_t *);
|
||||
return mn102_ana(out);
|
||||
}
|
||||
|
||||
case processor_t::ev_emu_insn:
|
||||
{
|
||||
const insn_t *insn = va_arg(va, const insn_t *);
|
||||
return mn102_emu(*insn) ? 1 : -1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_insn:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
out_insn(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_operand:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
const op_t *op = va_arg(va, const op_t *);
|
||||
return out_opnd(*ctx, *op) ? 1 : -1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_data:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
bool analyze_only = va_argi(va, bool);
|
||||
mn102_data(*ctx, analyze_only);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
//-----------------------------------------------------------------------
|
||||
// PseudoSam
|
||||
//-----------------------------------------------------------------------
|
||||
static const asm_t pseudosam =
|
||||
{
|
||||
AS_COLON | AS_UDATA | ASH_HEXF3 | ASD_DECF0,
|
||||
0,
|
||||
"Generic assembler", // assembeler name
|
||||
0, // help topic ID
|
||||
NULL, // header lines
|
||||
"org", // org
|
||||
"end", // end
|
||||
|
||||
";", // comment string
|
||||
'"', // string delimiter
|
||||
'\'', // char delimiter
|
||||
"\\\"'", // special symbols in char and string constants
|
||||
|
||||
"db", // ascii string directive
|
||||
"DB", // byte directive
|
||||
"DW", // word directive
|
||||
"DL", // dword (4 bytes)
|
||||
NULL, // qword (8 bytes)
|
||||
NULL, // oword (16 bytes)
|
||||
NULL, // float (4 bytes)
|
||||
NULL, // double (8 bytes)
|
||||
"DT", // tbyte (10/12 bytes)
|
||||
NULL, // packed decimal real
|
||||
"#d dup(#v)", // arrays (#h,#d,#v,#s(...)
|
||||
"db ?", // uninited arrays
|
||||
".equ", // equ
|
||||
NULL, // seg prefix
|
||||
"$", // current IP (instruction pointer)
|
||||
NULL, // func_header
|
||||
NULL, // func_footer
|
||||
NULL, // "public" name keyword
|
||||
NULL, // "weak" name keyword
|
||||
NULL, // "extrn" name keyword
|
||||
NULL, // "comm" (communal variable)
|
||||
NULL, // const char *(*get_type_name)(int32 flag,uint32 id);
|
||||
"align", // "align" keyword
|
||||
'(', ')', // lbrace, rbrace
|
||||
NULL, // mod
|
||||
NULL, // and
|
||||
NULL, // or
|
||||
NULL, // xor
|
||||
NULL, // not
|
||||
NULL, // shl
|
||||
NULL, // shr
|
||||
NULL, // sizeof
|
||||
};
|
||||
|
||||
// list of assemblers
|
||||
static const asm_t *const asms[] = { &pseudosam, NULL };
|
||||
//-----------------------------------------------------------------------
|
||||
#define FAMILY "Panasonic MN10200:"
|
||||
static const char *const shnames[] = { "MN102L00", NULL };
|
||||
static const char *const lnames[] = { FAMILY"Panasonic MN102L00", NULL };
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// codes of subroutine returns
|
||||
static const uchar retcode_1[] = { 0xFE }; // ret
|
||||
static const uchar retcode_2[] = { 0xEB }; // reti
|
||||
static const bytes_t retcodes[] =
|
||||
{
|
||||
{ sizeof(retcode_1), retcode_1 },
|
||||
{ sizeof(retcode_2), retcode_2 },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Processor Definition
|
||||
//-----------------------------------------------------------------------
|
||||
processor_t LPH =
|
||||
{
|
||||
IDP_INTERFACE_VERSION, // version
|
||||
PLFM_MN102L00, // id
|
||||
// flag
|
||||
PR_USE32
|
||||
| PR_BINMEM
|
||||
| PR_SEGTRANS
|
||||
| PR_DEFSEG32,
|
||||
// flag2
|
||||
0,
|
||||
8, // 8 bits in a byte for code segments
|
||||
8, // 8 bits in a byte
|
||||
|
||||
shnames,
|
||||
lnames,
|
||||
|
||||
asms,
|
||||
|
||||
notify,
|
||||
|
||||
RegNames, // Regsiter names
|
||||
qnumber(RegNames), // Number of registers
|
||||
|
||||
rVcs,rVds,
|
||||
2, // size of a segment register
|
||||
rVcs,rVds,
|
||||
NULL, // typical code starts
|
||||
retcodes, // returns
|
||||
0,mn102_last, // first, last itype
|
||||
Instructions, // instruction array
|
||||
3, // tbyte size: 24 bits
|
||||
{0,0,0,0}, // floating point type sizes
|
||||
0, // Icode for return
|
||||
NULL, // micro virtual mashine
|
||||
};
|
||||
Reference in New Issue
Block a user