update to ida 7.6, add builds
This commit is contained in:
251
idasdk76/module/m7900/7900.hpp
Normal file
251
idasdk76/module/m7900/7900.hpp
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _MITSUBISHI7900_HPP
|
||||
#define _MITSUBISHI7900_HPP
|
||||
|
||||
#include "../idaidp.hpp"
|
||||
#include "ins.hpp"
|
||||
#include <segregs.hpp>
|
||||
#include "../iohandler.hpp"
|
||||
#define PROCMOD_NAME m7900
|
||||
#define PROCMOD_NODE_NAME "$ " QSTRINGIZE(PROCMOD_NAME)
|
||||
|
||||
#define UAS_NOSPA 0x0001 // no space after comma
|
||||
#define UAS_SEGM 0x0002 // segments are named "segment XXX"
|
||||
|
||||
|
||||
// flags for insn.auxpref
|
||||
// operand prefix
|
||||
// 0x1 - .b
|
||||
// 0x2 - .w
|
||||
// 0x4 - .d
|
||||
|
||||
#define INSN_PREF_U 0x0000
|
||||
#define INSN_PREF_B 0x0001
|
||||
#define INSN_PREF_W 0x0002
|
||||
#define INSN_PREF_D 0x0004
|
||||
|
||||
#define RAZOPER insn.auxpref
|
||||
|
||||
// Detect status value
|
||||
#define getFlag_M get_sreg(insn.ea, rfM)
|
||||
#define getFlag_X get_sreg(insn.ea, rfX)
|
||||
|
||||
#define getDT get_sreg(insn.ea, rDT)
|
||||
#define getPG get_sreg(insn.ea, rPG)
|
||||
|
||||
#define getDPReg get_sreg(insn.ea, rDPReg)
|
||||
|
||||
#define getDPR0 get_sreg(insn.ea, rDPR0)
|
||||
#define getDPR1 get_sreg(insn.ea, rDPR1)
|
||||
#define getDPR2 get_sreg(insn.ea, rDPR2)
|
||||
#define getDPR3 get_sreg(insn.ea, rDPR3)
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Redefine temporary names
|
||||
//
|
||||
|
||||
#define xmode specflag1
|
||||
#define TypeOper specflag2
|
||||
|
||||
#define o_sr o_idpspec0
|
||||
#define o_ab o_idpspec1
|
||||
#define o_stk o_idpspec2
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
|
||||
enum mitsubishi_bit_PUL { bPS, bb, bDT, bDPR0, bY, bX, bB, bA };
|
||||
// ======= mitsubishi_bit_CPU ========================================
|
||||
/*
|
||||
__________________________
|
||||
|... |IPL|N|V|m|x|D|I|Z|C|
|
||||
__________________________
|
||||
*/
|
||||
|
||||
//
|
||||
// Bit 0: Carry flag (C)
|
||||
// Bit 1: Zero flag (Z)
|
||||
// Bit 2: Interrupt disable flag (I)
|
||||
// Bit 3: Decimal mode flag (D)
|
||||
// Bit 4: Index register length flag (x)
|
||||
// Bit 5: Data length flag (m)
|
||||
// Bit 6: Overflow flag (V)
|
||||
// Bit 7: Negative flag (N)
|
||||
// Bits 10 to 8: Processor interrupt priority level (IPL)
|
||||
//
|
||||
enum mitsubishi_bit_CPU { bIPL, bN, bV, bm, bx, bD, bI, bZ, bC };
|
||||
|
||||
|
||||
enum mitsubishi_registers { rA, rB, rE, rX, rY, rPC,
|
||||
rPS,
|
||||
rfIPL, rfN, rfV, rfD, rfI, rfZ, rfC,
|
||||
rDT, rPG, rDPReg, rDPR0, rDPR1, rDPR2, rDPR3,rfM, rfX,
|
||||
Rcs, Rds };
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
15____________________0
|
||||
| Ah | AL | - Accumulator A
|
||||
_____________________
|
||||
15____________________0
|
||||
| Bh | BL | - Accumulator B
|
||||
| ____________________|
|
||||
|
||||
31___________________________________________0
|
||||
| Eh | EL | - Accumulator E
|
||||
_____________________________________________
|
||||
|
||||
15____________________0
|
||||
| Xh | XL | - Index registr X
|
||||
_____________________
|
||||
15____________________0
|
||||
| Yh | YL | - Index registr Y
|
||||
_____________________
|
||||
|
||||
15____________________0
|
||||
| Sh | SL | - Stack pointer S
|
||||
_____________________
|
||||
|
||||
8_________0
|
||||
| DT | - Data bank registr(DT)
|
||||
_________
|
||||
|
||||
23_________15___________________0
|
||||
| PG | PCh | PCl | - Program counter(PC)
|
||||
_______________________________
|
||||
|_____________________________________________________ - Program bank registr()PG
|
||||
|
||||
15____________________0
|
||||
| DPR0h | DPR0L | - Direct page registr 0(DPR0)
|
||||
_____________________
|
||||
15____________________0
|
||||
| DPR1h | DPR1L | - Direct page registr 1(DPR1)
|
||||
_____________________
|
||||
15____________________0
|
||||
| DPR2h | DPR2L | - Direct page registr 2(DPR2)
|
||||
_____________________
|
||||
15____________________0
|
||||
| DPR3h | DPR3L | - Direct page registr 3(DPR3)
|
||||
_____________________
|
||||
15____________________0
|
||||
| PSh | PS L | - Procesor status register(PS)
|
||||
_____________________
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eMode { IMM_8=0, IMM_16, IMM_32, DIR_32, DIR_16, DIR_8 };
|
||||
|
||||
|
||||
// TDIR_DIR - Direct addressing mode DIR
|
||||
// TDIR_DIR_X - Direct index X addressing DIR,X
|
||||
// TDIR_DIR_Y - Direct index Y addressing DIR,Y
|
||||
// TDIR_INDIRECT_DIR - Direct indirect addressing mode (DIR)
|
||||
// TDIR_INDIRECT_DIR_X - Direct index X indirect addressing mode (DIR,X)
|
||||
// TDIR_INDIRECT_DIR_Y - Direct index Y indirect addressing mode (DIR,Y)
|
||||
// TDIR_L_INDIRECT_DIR - Direct indirect long addressing mode L(DIR)
|
||||
// TDIR_L_INDIRECT_DIR_Y - Direct indirect long indexed Y addressing mode L(DIR),Y
|
||||
|
||||
enum eTypeDIR { TDIR_DIR=0, TDIR_DIR_X, TDIR_DIR_Y, TDIR_INDIRECT_DIR,
|
||||
TDIR_INDIRECT_DIR_X, TDIR_INDIRECT_DIR_Y, TDIR_L_INDIRECT_DIR, TDIR_L_INDIRECT_DIR_Y };
|
||||
|
||||
|
||||
// TSP_SP - Stack pointer relative addressing mode(SR)
|
||||
// TSP_INDEX_SP_Y - Stack pointer relative indexed Y addressing mode((SR),Y)
|
||||
|
||||
enum eTypeSP { TSP_SP=0, TSP_INDEX_SP_Y };
|
||||
|
||||
|
||||
// TAB_ABS - Absolute addressing mode(ABS)
|
||||
// TAB_ABS_X - Absolute indexed X addressing mode(ABS,X)
|
||||
// TAB_ABS_Y - Absolute indexed Y addressing mode(ABS,Y)
|
||||
// TAB_ABL - Absolute long addressing mode(ABL)
|
||||
// TAB_ABL_X - Absolute long indexed X addressing mode(ABS,X)
|
||||
// TAB_INDIRECTED_ABS - Absolute indirect addressing mode((ABS))
|
||||
// TAB_L_INDIRECTED_ABS - Absolute indirect long addressing mode(L(ABS))
|
||||
// TAB_INDIRECTED_ABS_X - Absolute indexed X indirect addressing mode((ABS,X))
|
||||
|
||||
enum eTypeAB { TAB_ABS=0, TAB_ABS_X, TAB_ABS_Y, TAB_ABL, TAB_ABL_X,
|
||||
TAB_INDIRECTED_ABS, TAB_L_INDIRECTED_ABS, TAB_INDIRECTED_ABS_X };
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct ioport_bit_t;
|
||||
//------------------------------------------------------------------------
|
||||
int idaapi ana(insn_t *_insn);
|
||||
|
||||
inline void TRACE1(const char *szStr)
|
||||
{
|
||||
msg("%s\n", szStr);
|
||||
}
|
||||
|
||||
|
||||
inline void TRACE1(uint32 Data)
|
||||
{
|
||||
msg("DATA - %X\n", Data);
|
||||
}
|
||||
|
||||
|
||||
inline void TRACE(const char * /*szStr*/)
|
||||
{
|
||||
// msg("%s\n", szStr);
|
||||
}
|
||||
|
||||
|
||||
inline void TRACE(uint32 /*Data*/)
|
||||
{
|
||||
// msg("DATA - %X\n", Data);
|
||||
}
|
||||
|
||||
inline int GETBIT(uval_t Data, int bit)
|
||||
{
|
||||
uint32 TempByte = (uint32)Data;
|
||||
return (TempByte>>bit)&0x01;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
DECLARE_PROC_LISTENER(idb_listener_t, struct m7900_t);
|
||||
|
||||
struct m7900_t : public procmod_t
|
||||
{
|
||||
netnode helper;
|
||||
iohandler_t ioh = iohandler_t(helper);
|
||||
idb_listener_t idb_listener = idb_listener_t(*this);
|
||||
bool flow = false;
|
||||
|
||||
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
|
||||
|
||||
const char *set_idp_options(
|
||||
const char *keyword,
|
||||
int /*value_type*/,
|
||||
const void * /*value*/,
|
||||
bool /*idb_loaded*/);
|
||||
bool choose_device();
|
||||
|
||||
void handle_operand(const insn_t &insn, const op_t &x, bool is_forced, bool isload);
|
||||
int emu(const insn_t &insn);
|
||||
|
||||
void m7900_header(outctx_t &ctx);
|
||||
void m7900_segstart(outctx_t &ctx, segment_t *Srange) const;
|
||||
void m7900_footer(outctx_t &ctx) const;
|
||||
|
||||
void load_from_idb();
|
||||
};
|
||||
extern int data_id;
|
||||
#endif
|
||||
|
||||
10062
idasdk76/module/m7900/ana.cpp
Normal file
10062
idasdk76/module/m7900/ana.cpp
Normal file
File diff suppressed because it is too large
Load Diff
235
idasdk76/module/m7900/emu.cpp
Normal file
235
idasdk76/module/m7900/emu.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "7900.hpp"
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// convert to data and add cross-ref
|
||||
static void DataSet(const insn_t &insn, const op_t &x, ea_t EA, int isload)
|
||||
{
|
||||
insn.create_op_data(EA, x);
|
||||
insn.add_dref(EA, x.offb, isload ? dr_R : dr_W);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void m7900_t::handle_operand(const insn_t &insn, const op_t &x, bool is_forced, bool isload)
|
||||
{
|
||||
flags_t F = get_flags(insn.ea);
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_phrase:
|
||||
//remember_problem(PR_JUMP, insn.ea);
|
||||
case o_void:
|
||||
case o_reg:
|
||||
break;
|
||||
|
||||
case o_sr:
|
||||
case o_displ:
|
||||
set_immd(insn.ea);
|
||||
if ( !is_forced )
|
||||
{
|
||||
ushort addr = ushort(x.addr);
|
||||
if ( x.type == o_displ )
|
||||
{
|
||||
addr += (ushort)insn.ip;
|
||||
addr += insn.size;
|
||||
uint32 offb = map_code_ea(insn, addr, x.n);
|
||||
DataSet(insn, x, offb, isload);
|
||||
}
|
||||
else if ( op_adds_xrefs(F, x.n) )
|
||||
{
|
||||
insn.add_off_drefs(x, dr_O, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case o_stk:
|
||||
case o_imm:
|
||||
set_immd(insn.ea);
|
||||
if ( op_adds_xrefs(F, x.n) )
|
||||
insn.add_off_drefs(x, dr_O, 0);
|
||||
break;
|
||||
|
||||
case o_ab:
|
||||
if ( x.TypeOper == TAB_INDIRECTED_ABS_X )
|
||||
{
|
||||
ea_t ea = to_ea(insn.cs, x.addr);
|
||||
insn.create_op_data(ea, x.offb, dt_word);
|
||||
insn.add_dref(ea, x.offb, isload ? dr_R : dr_W);
|
||||
|
||||
// get data
|
||||
uint32 Addr;
|
||||
Addr = get_word(ea);
|
||||
Addr = uint32(Addr | (getPG<<16));
|
||||
insn.add_cref(Addr, 2, fl_JF);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataSet(insn, x, map_code_ea(insn, x), isload);
|
||||
}
|
||||
break;
|
||||
|
||||
case o_mem:
|
||||
// convert to data, add cross ref
|
||||
switch ( x.TypeOper )
|
||||
{
|
||||
case TDIR_DIR_Y:
|
||||
case TDIR_DIR_X:
|
||||
case TDIR_DIR:
|
||||
case TDIR_INDIRECT_DIR:
|
||||
case TDIR_INDIRECT_DIR_X:
|
||||
case TDIR_INDIRECT_DIR_Y:
|
||||
case TDIR_L_INDIRECT_DIR:
|
||||
case TDIR_L_INDIRECT_DIR_Y:
|
||||
if ( getDPReg == 1 )
|
||||
{
|
||||
insn_t tmp = insn;
|
||||
op_t &tmpx = tmp.ops[x.n];
|
||||
tmpx.addr &= 0xFF3F;
|
||||
DataSet(tmp, tmpx, map_code_ea(tmp, tmpx), isload);
|
||||
}
|
||||
else
|
||||
{
|
||||
DataSet(insn, x, map_code_ea(insn, x), isload);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DataSet(insn, x, map_code_ea(insn, x), isload);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case o_near:
|
||||
{
|
||||
ea_t ea = to_ea(insn.cs, x.addr);
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case m7900_jsr:
|
||||
insn.add_cref(ea, x.offb, fl_CN);
|
||||
if ( !func_does_return(ea) )
|
||||
flow = false;
|
||||
break;
|
||||
|
||||
case m7900_jsrl:
|
||||
insn.add_cref(ea, x.offb, fl_CF);
|
||||
if ( !func_does_return(ea) )
|
||||
flow = false;
|
||||
break;
|
||||
|
||||
case m7900_jmpl:
|
||||
insn.add_cref(ea, x.offb, fl_JF);
|
||||
break;
|
||||
|
||||
default:
|
||||
insn.add_cref(ea, x.offb, fl_JN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// warning("%a: %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), x.n, x.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static void LDD(const insn_t &ins)
|
||||
{
|
||||
static const int DPR[] = { rDPR0, rDPR1, rDPR2, rDPR3 };
|
||||
|
||||
for ( int i=0; i < 4; i++ )
|
||||
if ( GETBIT(ins.Op1.value, i) == 1 )
|
||||
split_sreg_range(ins.ea+ins.size, DPR[i], ins.ops[1+i].value, SR_auto);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int m7900_t::emu(const insn_t &insn)
|
||||
{
|
||||
// Set PG
|
||||
split_sreg_range(insn.ea, rPG, ( insn.ea & 0xFF0000 ) >> 16, SR_auto);
|
||||
|
||||
uint32 Feature = insn.get_canon_feature(ph);
|
||||
flow = (Feature & CF_STOP) == 0;
|
||||
|
||||
bool flag1 = is_forced_operand(insn.ea, 0);
|
||||
bool flag2 = is_forced_operand(insn.ea, 1);
|
||||
bool flag3 = is_forced_operand(insn.ea, 2);
|
||||
bool flag4 = is_forced_operand(insn.ea, 3);
|
||||
bool flag5 = is_forced_operand(insn.ea, 4);
|
||||
|
||||
|
||||
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);
|
||||
if ( Feature & CF_USE4 ) handle_operand(insn, insn.Op4, flag4, true);
|
||||
if ( Feature & CF_USE5 ) handle_operand(insn, insn.Op5, flag5, true);
|
||||
|
||||
if ( Feature & CF_JUMP )
|
||||
remember_problem(PR_JUMP, insn.ea);
|
||||
|
||||
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 ( Feature & CF_CHG4 ) handle_operand(insn, insn.Op4, flag4, false);
|
||||
if ( Feature & CF_CHG5 ) handle_operand(insn, insn.Op5, flag5, false);
|
||||
|
||||
if ( flow )
|
||||
add_cref(insn.ea, insn.ea + insn.size, fl_F);
|
||||
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case m7900_lddn:
|
||||
//split_sreg_range(insn.ea + insn.size, GetDPR(), insn.Op1.value, SR_auto);
|
||||
LDD(insn);
|
||||
break;
|
||||
|
||||
case m7900_ldt:
|
||||
split_sreg_range(insn.ea + insn.size, rDT, insn.Op1.value, SR_auto);
|
||||
break;
|
||||
|
||||
// clear m flag
|
||||
case m7900_clm:
|
||||
split_sreg_range(insn.ea + insn.size, rfM, 0, SR_auto);
|
||||
break;
|
||||
// set m flag
|
||||
case m7900_sem:
|
||||
split_sreg_range(insn.ea + insn.size, rfM, 1, SR_auto);
|
||||
break;
|
||||
|
||||
// clear processor status
|
||||
case m7900_clp:
|
||||
// clear m flag
|
||||
if ( ((insn.Op1.value & 0x20) >> 5) == 1 )
|
||||
split_sreg_range(insn.ea + insn.size, rfM, 0, SR_auto);
|
||||
// clear x flag
|
||||
if ( ((insn.Op1.value & 0x10) >> 4) == 1 )
|
||||
split_sreg_range(insn.ea + insn.size, rfX, 0, SR_auto);
|
||||
break;
|
||||
|
||||
// set processor status
|
||||
case m7900_sep:
|
||||
// set m flag
|
||||
if ( ((insn.Op1.value & 0x20) >> 5) == 1 )
|
||||
split_sreg_range(insn.ea + insn.size, rfM, 1, SR_auto);
|
||||
// set x flag
|
||||
if ( ((insn.Op1.value & 0x10) >> 4) == 1 )
|
||||
split_sreg_range(insn.ea + insn.size, rfX, 1, SR_auto);
|
||||
break;
|
||||
|
||||
// pull processor status from stack
|
||||
case m7900_plp:
|
||||
split_sreg_range(insn.ea + insn.size, rfM, BADSEL, SR_auto);
|
||||
split_sreg_range(insn.ea + insn.size, rfX, BADSEL, SR_auto);
|
||||
break;
|
||||
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
297
idasdk76/module/m7900/ins.cpp
Normal file
297
idasdk76/module/m7900/ins.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ida.hpp>
|
||||
#include <idp.hpp>
|
||||
#include "ins.hpp"
|
||||
|
||||
|
||||
|
||||
const instruc_t Instructions[] =
|
||||
{
|
||||
|
||||
{ "", 0 }, // Unknown Operation
|
||||
|
||||
{ "abs", CF_CHG1 }, // ABSolute
|
||||
{ "absd", CF_CHG1 }, // ABSolute at Double-word
|
||||
|
||||
{ "adc", CF_CHG1 | CF_USE2 }, // ADd with Carry
|
||||
{ "adcb", CF_CHG1 | CF_USE2 }, // ADd with Carry at Byte
|
||||
{ "adcd", CF_CHG1 | CF_USE2 }, // ADd with Carry at Double-word
|
||||
|
||||
{ "add", CF_CHG1 | CF_USE2 }, // Addition
|
||||
|
||||
{ "addb", CF_CHG1 | CF_USE2 }, // ADD at Byte
|
||||
|
||||
{ "addd", CF_CHG1 | CF_USE2 }, // ADD at Double-word
|
||||
{ "addm", CF_CHG1 | CF_USE2 }, // ADD immediate and Memory
|
||||
{ "addmb", CF_CHG1 | CF_USE2 }, // ADD immediate and Memory at Byte
|
||||
{ "addmd", CF_CHG1 | CF_USE2 }, // ADD immediate and Memory at Double-word
|
||||
{ "adds", CF_USE1 }, // ADD Stack pointer and immediate
|
||||
{ "addx", CF_USE1 }, // ADD index register X and immediate
|
||||
{ "addy", CF_USE1 }, // ADD index register Y and immediate
|
||||
|
||||
{ "and", CF_CHG1 | CF_USE2 }, // Logical AND
|
||||
{ "andb", CF_CHG1 | CF_USE2 }, // logical AND between immediate (Byte)
|
||||
{ "andm", CF_CHG1 | CF_USE2 }, // logical AND between immediate value and Memory
|
||||
{ "andmb", CF_CHG1 | CF_USE2 }, // logical AND between immediate value and Memory (Byte)
|
||||
{ "andmd", CF_CHG1 | CF_USE2 }, // logical AND between immediate value and Memory (Double word)
|
||||
|
||||
|
||||
{ "asl", CF_CHG1 }, // Arithmetic Shift to Left
|
||||
{ "asl", CF_CHG1 | CF_USE2 }, // Arithmetic Shift to Left by n bits
|
||||
{ "asld", CF_CHG1 | CF_USE2 }, // Arithmetic Shift to Left by n bits (Double word)
|
||||
|
||||
{ "asr", CF_CHG1 }, // Arithmetic Shift to Right
|
||||
{ "asr", CF_CHG1 | CF_USE2 }, // Arithmetic Shift to Right by n bits
|
||||
{ "asrd", CF_CHG1 | CF_USE2 }, // Arithmetic Shift to Right by n bits (Double word)
|
||||
|
||||
{ "bbc", CF_USE1 | CF_USE2 | CF_USE3 }, // Branch on Bit Clear
|
||||
{ "bbcb", CF_USE1 | CF_USE2 | CF_USE3 }, // Branch on Bit Clear (Byte)
|
||||
{ "bbs", CF_USE1 | CF_USE2 | CF_USE3 }, // Branch on Bit Set
|
||||
{ "bbsb", CF_USE1 | CF_USE2 | CF_USE3 }, // Branch on Bit Set (Byte)
|
||||
|
||||
{ "bcc", CF_USE1 }, // Branch on Carry Clear
|
||||
{ "bcs", CF_USE1 }, // Branch on Carry Set
|
||||
{ "beq", CF_USE1 }, // Branch on EQual
|
||||
{ "bge", CF_USE1 }, // Branch on Greater or Equal
|
||||
{ "bgt", CF_USE1 }, // Branch on Greater Than
|
||||
{ "bgtu", CF_USE1 }, // Branch on Greater Than with Unsign
|
||||
{ "ble", CF_USE1 }, // Branch on Less or Equal
|
||||
{ "bleu", CF_USE1 }, // Branch on Less Equal with Unsign
|
||||
{ "blt", CF_USE1 }, // Branch on Less Than
|
||||
{ "bmi", CF_USE1 }, // Branch on result MInus
|
||||
{ "bne", CF_USE1 }, // Branch on Not Equal
|
||||
{ "bpl", CF_USE1 }, // Branch on result PLus
|
||||
{ "bra", CF_USE1 | CF_JUMP | CF_STOP }, // BRanch Always
|
||||
{ "bral", CF_USE1 | CF_JUMP | CF_STOP }, // BRanch Always
|
||||
|
||||
{ "brk", 0 }, // run int 0xFFFA
|
||||
|
||||
{ "bsc", CF_USE1 | CF_USE2 | CF_USE3 }, // Branch on Single bit Clear
|
||||
{ "bsr", CF_USE1 | CF_CALL }, // Branch to SubRoutine
|
||||
{ "bss", CF_USE1 | CF_USE2 | CF_USE3 }, // Branch on Single bit Set
|
||||
|
||||
{ "bvc", CF_USE1 }, // Branch on oVerflow Clear
|
||||
{ "bvs", CF_USE1 }, // Branch on oVerflow Set
|
||||
|
||||
{ "cbeq", CF_USE1 | CF_USE2 | CF_USE3 }, // Compare immediate and Branch on EQual
|
||||
{ "cbeqb", CF_USE1 | CF_USE2 | CF_USE3 }, // Compare immediate and Branch on EQual at Byte
|
||||
{ "cbne", CF_USE1 | CF_USE2 | CF_USE3 }, // Compare immediate and Branch on Not Equal
|
||||
{ "cbneb", CF_USE1 | CF_USE2 | CF_USE3 }, // Compare immediate and Branch on Not Equal at Byte
|
||||
|
||||
{ "clc", 0 }, // CLear Carry flag
|
||||
{ "cli", 0 }, // CLear Interrupt disable status
|
||||
{ "clm", 0 }, // CLear M flag
|
||||
{ "clp", CF_USE1 }, // CLear Processor status
|
||||
|
||||
{ "clr", CF_CHG1 }, // CLeaR accumulator
|
||||
{ "clrb", CF_CHG1 }, // CLeaR accumulator at Byte
|
||||
{ "clrm", CF_CHG1 }, // CLeaR Memory
|
||||
{ "clrmb", CF_CHG1 }, // CLeaR Memory at Byte
|
||||
{ "clrx", 0 }, // CLeaR index register X
|
||||
{ "clry", 0 }, // CLeaR index register Y
|
||||
|
||||
{ "clv", 0 }, // CLear oVerflow flag
|
||||
|
||||
{ "cmp", CF_USE1 | CF_USE2 }, // CoMPare
|
||||
{ "cmpb", CF_USE1 | CF_USE2 }, // CoMPare at Byte
|
||||
{ "cmpd", CF_USE1 | CF_USE2 }, // CoMPare at Double-word
|
||||
{ "cmpm", CF_USE1 | CF_USE2 }, // CoMPare immediate with Memory
|
||||
{ "cmpmb", CF_USE1 | CF_USE2 }, // CoMPare immediate with Memory at Byte
|
||||
{ "cmpmd", CF_USE1 | CF_USE2 }, // CoMPare immediate with Memory at Double-word
|
||||
|
||||
{ "cpx", CF_USE1 }, // ComPare memory and index register X
|
||||
{ "cpy", CF_USE1 }, // ComPare memory and index register Y
|
||||
|
||||
{ "debne", CF_USE1 | CF_USE2 | CF_USE3 }, // DEcrement memory and Branch on Not Equal
|
||||
|
||||
{ "dec", CF_CHG1 }, // DECrement by one
|
||||
{ "dex", 0 }, // DEcrement index register X by one
|
||||
{ "dey", 0 }, // DEcrement index register Y by one
|
||||
|
||||
{ "div", CF_USE1 }, // DIVide unsigned
|
||||
{ "divs", CF_USE1 }, // DIVide with Sign
|
||||
{ "dxbne", CF_USE1 | CF_USE2 }, // Decrement index register X and Branch on Not Equal
|
||||
{ "dybne", CF_USE1 | CF_USE2 }, // Decrement index register Y and Branch on Not Equal
|
||||
|
||||
{ "eor", CF_CHG1 | CF_USE2 }, // Exclusive OR memory with accumulator
|
||||
{ "eorb", CF_CHG1 | CF_USE2 }, // Exclusive OR immediate with accumulator at Byte
|
||||
{ "eorm", CF_CHG1 | CF_USE2 }, // Exclusive OR immediate with Memory
|
||||
{ "eormb", CF_CHG1 | CF_USE2 }, // Exclusive OR immediate with Memory at Byte
|
||||
{ "eormd", CF_CHG1 | CF_USE2 }, // Exclusive OR immediate with Memory at Double-word
|
||||
|
||||
{ "exts", CF_CHG1 }, // EXTension Sign
|
||||
{ "extsd", CF_CHG1 }, // EXTension Sign at Double-word
|
||||
{ "extz", CF_CHG1 }, // EXTension Zero
|
||||
{ "extzd", CF_CHG1 }, // EXTension Zero at Double-word
|
||||
|
||||
{ "inc", CF_CHG1 }, // INCrement by one
|
||||
{ "inx", 0 }, // INcrement index register X by one
|
||||
{ "iny", 0 }, // INcrement index register y by one
|
||||
|
||||
{ "jmp", CF_USE1 | CF_JUMP | CF_STOP }, // JuMP16
|
||||
{ "jmpl", CF_USE1 | CF_JUMP | CF_STOP }, // Jump24
|
||||
|
||||
{ "jsr", CF_USE1 | CF_CALL }, // Jump to SubRoutine16
|
||||
{ "jsrl", CF_USE1 | CF_CALL }, // Jump to SubRoutine24
|
||||
|
||||
|
||||
{ "lda", CF_CHG1 | CF_USE2 }, // LoaD Accumulator from memory
|
||||
{ "ldab", CF_CHG1 | CF_USE2 }, // LoaD Accumulator from memory at Byte
|
||||
{ "ldad", CF_CHG1 | CF_USE2 }, // LoaD Accumulator from memory at Double-word
|
||||
{ "ldd", CF_USE1 | CF_USE2 | CF_USE3 | CF_USE4 | CF_USE5 }, // LoaD immediate to Direct page register n
|
||||
|
||||
{ "ldt", CF_USE1 }, // LoaD immediate to DaTa bank register
|
||||
{ "ldx", CF_USE1 }, // LoaD index register X from memory
|
||||
{ "ldxb", CF_USE1 }, // LoaD index register X from memory at Byte
|
||||
{ "ldy", CF_USE1 }, // LoaD index register Y from memory
|
||||
{ "ldyb", CF_USE1 }, // LoaD index register Y from memory at Byte
|
||||
|
||||
{ "lsr", CF_CHG1 }, // Logical Shift Right
|
||||
{ "lsr", CF_USE2 | CF_CHG1 }, // Logical n bits Shift Right
|
||||
{ "lsrd", CF_USE2 | CF_CHG1 }, // Logical n bits Shift Right at Double-word
|
||||
|
||||
{ "movm", CF_USE2 | CF_CHG1 }, // MOVe Memory to memory
|
||||
{ "movmb", CF_USE2 | CF_CHG1 }, // MOVe Memory to memory at Byte
|
||||
{ "movr", CF_USE1 | CF_HLL }, // MOVe Repeat memory to memory
|
||||
{ "movrb", CF_USE1 | CF_HLL }, // MOVe Repeat memory to memory at Byte
|
||||
|
||||
{ "mpy", CF_USE1 }, // MultiPlY
|
||||
{ "mpys", CF_USE1 }, // MultiPlY with Sign
|
||||
|
||||
{ "mvn", CF_USE1 | CF_USE2 }, // MoVe Negative
|
||||
{ "mvp", CF_USE1 | CF_USE2 }, // MoVe Positive
|
||||
|
||||
{ "neg", CF_CHG1 }, // NEGative
|
||||
{ "negd", CF_CHG1 }, // NEGative at Double-word
|
||||
{ "nop", 0 }, // No OPeration
|
||||
|
||||
|
||||
{ "ora", CF_CHG1 | CF_USE2 }, // OR memory with Accumulator
|
||||
{ "orab", CF_CHG1 | CF_USE2 }, // OR immediate with Accumulator at Byte
|
||||
{ "oram", CF_CHG1 | CF_USE2 }, // OR immediAte with Memory
|
||||
{ "oramb", CF_CHG1 | CF_USE2 }, // OR immediAte with Memory at Byte
|
||||
{ "oramd", CF_CHG1 | CF_USE2 }, // OR immediAte with Memory at Double-word
|
||||
|
||||
|
||||
{ "pea", CF_USE1 }, // Push Effective Address
|
||||
{ "pei", CF_USE1 }, // Push Effective Indirect address
|
||||
{ "per", CF_USE1 }, // Push Effective program counter Relative address
|
||||
{ "pha", 0 }, // PusH accumulator A on stack
|
||||
{ "phb", 0 }, // PusH accumulator B on stack
|
||||
{ "phd", 0 }, // PusH Direct page register on stack
|
||||
{ "phd", CF_USE1 }, // PusH Direct page register n on stack
|
||||
{ "phg", 0 }, // PusH proGram bank register on stack
|
||||
|
||||
{ "phld", CF_USE1 | CF_HLL }, // PusH dpr n to stack and Load immediate to Dpr n
|
||||
|
||||
{ "php", 0 }, // PusH Processor status on stack
|
||||
{ "pht", 0 }, // PusH daTa bank register on stack
|
||||
{ "phx", 0 }, // PusH index register X on stack
|
||||
{ "phy", 0 }, // PusH index register Y on stack
|
||||
|
||||
{ "pla", 0 }, // PuLl accumulator A from stack
|
||||
{ "plb", 0 }, // PuLl accumulator B from stack
|
||||
{ "pld", 0 }, // PuLl Direct page register from stack
|
||||
{ "pld", CF_USE1 }, // PuLl Direct page register n from stack
|
||||
{ "plp", 0 }, // PuLl Processor status from stack
|
||||
{ "plt", 0 }, // PuLl daTa bank register from stack
|
||||
{ "plx", 0 }, // PuLl index register X from stack
|
||||
{ "ply", 0 }, // PuLl index register Y from stack
|
||||
|
||||
{ "psh", CF_USE1 }, // PuSH
|
||||
{ "pul", CF_USE1 }, // PuLl
|
||||
|
||||
{ "rla", CF_USE1 }, // Rotate Left accumulator A
|
||||
{ "rmpa", CF_USE1 }, // Repeat Multiply and Accumulate
|
||||
|
||||
{ "rol", CF_CHG1 }, // ROtate one bit Left
|
||||
{ "rol", CF_USE2 | CF_CHG1 }, // n bits ROtate Left
|
||||
{ "rold", CF_USE2 | CF_CHG1 }, // n bits ROtate Left at Double-word
|
||||
|
||||
{ "ror", CF_CHG1 }, // ROtate one bit Right
|
||||
{ "ror", CF_USE2 | CF_CHG1 }, // n bits ROtate Right
|
||||
{ "rord", CF_USE2 | CF_CHG1 }, // n bits ROtate Right at Double-word
|
||||
|
||||
{ "rti", CF_STOP }, // Return from Interrupt
|
||||
{ "rtl", CF_STOP }, // ReTurn from subroutine Long
|
||||
{ "rtld", CF_USE1 | CF_STOP }, // ReTurn from subroutine Long and pull Direct page register n
|
||||
{ "rts", CF_STOP }, // ReTurn from Subroutine
|
||||
{ "rtsd", CF_USE1 | CF_STOP }, // ReTurn from Subroutine and pull Direct page register n
|
||||
|
||||
|
||||
{ "sbc", CF_USE1 | CF_USE2 }, // SuBtract with Carry
|
||||
{ "sbcb", CF_USE1 | CF_USE2 }, // SuBtract with Carry at Byte
|
||||
{ "sbcd", CF_USE1 | CF_USE2 }, // SuBtract with Carry at Double-word
|
||||
|
||||
|
||||
{ "sec", 0 }, // SEt Carry flag
|
||||
{ "sei", 0 }, // SEt Interrupt disable status
|
||||
{ "sem", 0 }, // SEt M flag
|
||||
{ "sep", CF_USE1 }, // SEt Processor status
|
||||
|
||||
|
||||
{ "sta", CF_CHG2 | CF_USE1 }, // STore Accumulator in memory
|
||||
{ "stab", CF_CHG2 | CF_USE1 }, // STore Accumulator in memory at Byte
|
||||
{ "stad", CF_CHG2 | CF_USE1 }, // STore Accumulator in memory at Double-word
|
||||
|
||||
{ "stp", 0 }, // SToP
|
||||
|
||||
{ "stx", CF_CHG1 }, // STore index register X in memory
|
||||
{ "sty", CF_CHG1 }, // STore index register Y in memory
|
||||
|
||||
{ "sub", CF_CHG1 | CF_USE2 }, // SUBtract
|
||||
{ "subb", CF_CHG1 | CF_USE2 }, // SUBtract at Byte
|
||||
{ "subd", CF_CHG1 | CF_USE2 }, // SUBtract at Double-word
|
||||
{ "subm", CF_CHG1 | CF_USE2 }, // SUBtract immediate from Memory
|
||||
{ "submb", CF_CHG1 | CF_USE2 }, // SUBtract immediate from Memory at Byte
|
||||
{ "submd", CF_CHG1 | CF_USE2 }, // SUBtract immediate from Memory at Double-word
|
||||
|
||||
{ "subs", CF_USE1 }, // SUBtract Stack pointer
|
||||
{ "subx", CF_USE1 }, // SUBtract immediate from index register X
|
||||
{ "suby", CF_USE1 }, // SUBtract immediate from index register Y
|
||||
|
||||
{ "tad", CF_USE1 }, // Transfer accumulator A to Direct page register n
|
||||
|
||||
{ "tas", 0 }, // Transfer accumulator A to Stack pointer
|
||||
{ "tax", 0 }, // Transfer accumulator A to index register X
|
||||
{ "tay", 0 }, // Transfer accumulator A to index register Y
|
||||
|
||||
{ "tbd", CF_USE1 }, // Transfer accumulator B to Direct page register n
|
||||
|
||||
{ "tbs", 0 }, // Transfer accumulator B to Stack pointer
|
||||
{ "tbx", 0 }, // Transfer accumulator B to index register X
|
||||
{ "tby", 0 }, // Transfer accumulator B to index register Y
|
||||
|
||||
{ "tda", CF_USE1 }, // Transfer Direct page register n to accumulator A
|
||||
{ "tdb", CF_USE1 }, // Transfer Direct page register n to accumulator B
|
||||
|
||||
{ "tds", 0 }, // Transfer Direct page register to Stack pointer
|
||||
{ "tsa", 0 }, // Transfer Stack pointer to accumulator A
|
||||
{ "tsb", 0 }, // Transfer Stack pointer to accumulator B
|
||||
|
||||
{ "tsd", 0 }, // Transfer Stack pointer to Direct page register
|
||||
{ "tsx", 0 }, // Transfer Stack pointer to index register X
|
||||
{ "txa", 0 }, // Transfer index register X to accumulator A
|
||||
{ "txb", 0 }, // Transfer index register X to accumulator B
|
||||
{ "txs", 0 }, // Transfer index register X to Stack pointer
|
||||
{ "txy", 0 }, // Transfer index register X to Y
|
||||
{ "tya", 0 }, // Transfer index register Y to accumulator A
|
||||
{ "tyb", 0 }, // Transfer index register Y to accumulator B
|
||||
{ "tyx", 0 }, // Transfer index register Y to X
|
||||
|
||||
{ "wit", CF_STOP }, // WaIT
|
||||
|
||||
{ "xab", 0 }, // eXchange accumulator A and B
|
||||
|
||||
};
|
||||
|
||||
CASSERT(qnumber(Instructions) == m7900_last);
|
||||
299
idasdk76/module/m7900/ins.hpp
Normal file
299
idasdk76/module/m7900/ins.hpp
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Copyright (c) 1990-2021 Hex-Rays
|
||||
* ALL RIGHTS RESERVED.
|
||||
*
|
||||
* MITSUBISHI 7900 Family
|
||||
*/
|
||||
|
||||
#ifndef __INSTRS_HPP
|
||||
#define __INSTRS_HPP
|
||||
|
||||
extern const instruc_t Instructions[];
|
||||
|
||||
enum nameNum ENUM_SIZE(uint16)
|
||||
{
|
||||
m7900_null = 0, // Unknown Operation
|
||||
|
||||
|
||||
m7900_abs, // ABSolute
|
||||
m7900_absd, // ABSolute at Double-word
|
||||
|
||||
m7900_adc, // ADd with Carry
|
||||
m7900_adcb, // ADd with Carry at Byte
|
||||
m7900_adcd, // ADd with Carry at Double-word
|
||||
|
||||
m7900_add, // Addition
|
||||
|
||||
m7900_addb, // ADD at Byte
|
||||
m7900_addd, // ADD at Double-word
|
||||
m7900_addm, // ADD immediate and Memory
|
||||
m7900_addmb, // ADD immediate and Memory at Byte
|
||||
m7900_addmd, // ADD immediate and Memory at Double-word
|
||||
m7900_adds, // ADD Stack pointer and immediate
|
||||
m7900_addx, // ADD index register X and immediate
|
||||
m7900_addy, // ADD index register Y and immediate
|
||||
|
||||
m7900_and, // Logical AND
|
||||
m7900_andb, // logical AND between immediate (Byte)
|
||||
|
||||
m7900_andm, // logical AND between immediate value and Memory
|
||||
m7900_andmb, // logical AND between immediate value and Memory (Byte)
|
||||
m7900_andmd, // logical AND between immediate value and Memory (Double word)
|
||||
|
||||
m7900_asl, // Arithmetic Shift to Left
|
||||
m7900_asln, // Arithmetic Shift to Left by n bits
|
||||
m7900_asldn, // Arithmetic Shift to Left by n bits (Double word)
|
||||
|
||||
|
||||
m7900_asr, // Arithmeticshift to the right
|
||||
m7900_asrn, // Arithmetic Shift to Right by n bits
|
||||
m7900_asrdn, // Arithmetic Shift to Right by n bits (Double word)
|
||||
|
||||
m7900_bbc, // Branch on Bit Clear
|
||||
m7900_bbcb, // Branch on Bit Clear (Byte)
|
||||
m7900_bbs, // Branch on Bit Set
|
||||
m7900_bbsb, // Branch on Bit Set (Byte)
|
||||
|
||||
m7900_bcc, // Branch on Carry Clear
|
||||
m7900_bcs, // Branch on Carry Set
|
||||
m7900_beq, // Branch on EQual
|
||||
m7900_bge, // Branch on Greater or Equal
|
||||
m7900_bgt, // Branch on Greater Than
|
||||
m7900_bgtu, // Branch on Greater Than with Unsign
|
||||
m7900_ble, // Branch on Less or Equal
|
||||
m7900_bleu, // Branch on Less Equal with Unsign
|
||||
m7900_blt, // Branch on Less Than
|
||||
m7900_bmi, // Branch on result MInus
|
||||
m7900_bne, // Branch on Not Equal
|
||||
m7900_bpl, // Branch on result PLus
|
||||
m7900_bra, // BRanch Always
|
||||
m7900_bral, // BRanch Always
|
||||
|
||||
m7900_brk, // force BReaK
|
||||
|
||||
m7900_bsc, // Branch on Single bit Clear
|
||||
m7900_bsr, // Branch to SubRoutine
|
||||
m7900_bss, // Branch on Single bit Set
|
||||
|
||||
m7900_bvc, // Branch on oVerflow Clear
|
||||
m7900_bvs, // Branch on oVerflow Set
|
||||
|
||||
m7900_cbeq, // Compare immediate and Branch on EQual
|
||||
m7900_cbeqb, // Compare immediate and Branch on EQual at Byte
|
||||
m7900_cbne, // Compare immediate and Branch on Not Equal
|
||||
m7900_cbneb, // Compare immediate and Branch on Not Equal at Byte
|
||||
|
||||
m7900_clc, // CLear Carry flag
|
||||
m7900_cli, // CLear Interrupt disable status
|
||||
m7900_clm, // CLear M flag
|
||||
m7900_clp, // CLear Processor status
|
||||
|
||||
m7900_clr, // CLeaR accumulator
|
||||
m7900_clrb, // CLeaR accumulator at Byte
|
||||
m7900_clrm, // CLeaR Memory
|
||||
m7900_clrmb, // CLeaR Memory at Byte
|
||||
m7900_clrx, // CLeaR index register X
|
||||
m7900_clry, // CLeaR index register Y
|
||||
|
||||
m7900_clv, // CLear oVerflow flag
|
||||
|
||||
m7900_cmp, // CoMPare
|
||||
m7900_cmpb, // CoMPare at Byte
|
||||
m7900_cmpd, // CoMPare at Double-word
|
||||
m7900_cmpm, // CoMPare immediate with Memory
|
||||
m7900_cmpmb, // CoMPare immediate with Memory at Byte
|
||||
m7900_cmpmd, // CoMPare immediate with Memory at Double-word
|
||||
|
||||
m7900_cpx, // ComPare memory and index register X
|
||||
m7900_cpy, // ComPare memory and index register Y
|
||||
|
||||
m7900_debne, // DEcrement memory and Branch on Not Equal
|
||||
|
||||
m7900_dec, // DECrement by one
|
||||
m7900_dex, // DEcrement index register X by one
|
||||
m7900_dey, // DEcrement index register Y by one
|
||||
|
||||
m7900_div, // DIVide unsigned
|
||||
m7900_divs, // DIVide with Sign
|
||||
m7900_dxbne, // Decrement index register X and Branch on Not Equal
|
||||
m7900_dybne, // Decrement index register Y and Branch on Not Equal
|
||||
|
||||
m7900_eor, // Exclusive OR memory with accumulator
|
||||
m7900_eorb, // Exclusive OR immediate with accumulator at Byte
|
||||
m7900_eorm, // Exclusive OR immediate with Memory
|
||||
m7900_eormb, // Exclusive OR immediate with Memory at Byte
|
||||
m7900_eormd, // Exclusive OR immediate with Memory at Double-word
|
||||
|
||||
m7900_exts, // EXTension Sign
|
||||
m7900_extsd, // EXTension Sign at Double-word
|
||||
m7900_extz, // EXTension Zero
|
||||
m7900_extzd, // EXTension Zero at Double-word
|
||||
|
||||
m7900_inc, // INCrement by one
|
||||
m7900_inx, // INcrement index register X by one
|
||||
m7900_iny, // INcrement index register y by one
|
||||
|
||||
m7900_jmp, // Jump
|
||||
m7900_jmpl, // Jump
|
||||
|
||||
m7900_jsr, // Jump to SubRoutine
|
||||
m7900_jsrl, // Jump to SubRoutine
|
||||
|
||||
|
||||
m7900_lda, // LoaD Accumulator from memory
|
||||
m7900_ldab, // LoaD Accumulator from memory at Byte
|
||||
m7900_ldad, // LoaD Accumulator from memory at Double-word
|
||||
m7900_lddn, // LoaD immediate to Direct page register n
|
||||
|
||||
m7900_ldt, // LoaD immediate to DaTa bank register
|
||||
m7900_ldx, // LoaD index register X from memory
|
||||
m7900_ldxb, // LoaD index register X from memory at Byte
|
||||
m7900_ldy, // LoaD index register Y from memory
|
||||
m7900_ldyb, // LoaD index register Y from memory at Byte
|
||||
|
||||
m7900_lsr, // Logical Shift Right
|
||||
m7900_lsrn, // Logical n bits Shift Right
|
||||
m7900_lsrdn, // Logical n bits Shift Right at Double-word
|
||||
|
||||
m7900_movm, // MOVe Memory to memory
|
||||
m7900_movmb, // MOVe Memory to memory at Byte
|
||||
m7900_movr, // MOVe Repeat memory to memory
|
||||
m7900_movrb, // MOVe Repeat memory to memory at Byte
|
||||
|
||||
m7900_mpy, // MultiPlY
|
||||
m7900_mpys, // MultiPlY with Sign
|
||||
|
||||
m7900_mvn, // MoVe Negative
|
||||
m7900_mvp, // MoVe Positive
|
||||
|
||||
m7900_neg, // NEGative
|
||||
m7900_negd, // NEGative at Double-word
|
||||
|
||||
m7900_nop, // No OPeration
|
||||
|
||||
m7900_ora, // OR memory with Accumulator
|
||||
m7900_orab, // OR immediate with Accumulator at Byte
|
||||
m7900_oram, // OR immediAte with Memory
|
||||
m7900_oramb, // OR immediAte with Memory at Byte
|
||||
m7900_oramd, // OR immediAte with Memory at Double-word
|
||||
|
||||
m7900_pea, // Push Effective Address
|
||||
m7900_pei, // Push Effective Indirect address
|
||||
m7900_per, // Push Effective program counter Relative address
|
||||
m7900_pha, // PusH accumulator A on stack
|
||||
m7900_phb, // PusH accumulator B on stack
|
||||
m7900_phd, // PusH Direct page register on stack
|
||||
m7900_phdn, // PusH Direct page register n on stack
|
||||
m7900_phg, // PusH proGram bank register on stack
|
||||
|
||||
m7900_phldn, // PusH dpr n to stack and Load immediate to Dpr n
|
||||
|
||||
m7900_php, // PusH Processor status on stack
|
||||
m7900_pht, // PusH daTa bank register on stack
|
||||
m7900_phx, // PusH index register X on stack
|
||||
m7900_phy, // PusH index register Y on stack
|
||||
|
||||
m7900_pla, // PuLl accumulator A from stack
|
||||
m7900_plb, // PuLl accumulator B from stack
|
||||
m7900_pld, // PuLl Direct page register from stack
|
||||
m7900_pldn, // PuLl Direct page register n from stack
|
||||
m7900_plp, // PuLl Processor status from stack
|
||||
m7900_plt, // PuLl daTa bank register from stack
|
||||
m7900_plx, // PuLl index register X from stack
|
||||
m7900_ply, // PuLl index register Y from stack
|
||||
|
||||
m7900_psh, // PuSH
|
||||
m7900_pul, // PuLl
|
||||
|
||||
m7900_rla, // Rotate Left accumulator A
|
||||
m7900_rmpa, // Repeat Multiply and Accumulate
|
||||
|
||||
m7900_rol, // ROtate one bit Left
|
||||
m7900_roln, // n bits ROtate Left
|
||||
|
||||
m7900_roldn, // n bits ROtate Left at Double-word
|
||||
|
||||
m7900_ror, // ROtate one bit Right
|
||||
m7900_rorn, // n bits ROtate Right
|
||||
m7900_rordn, // n bits ROtate Right at Double-word
|
||||
|
||||
m7900_rti, // Return from Interrupt
|
||||
m7900_rtl, // ReTurn from subroutine Long
|
||||
m7900_rtld, // ReTurn from subroutine Long and pull Direct page register n
|
||||
m7900_rts, // ReTurn from Subroutine
|
||||
m7900_rtsdn, // ReTurn from Subroutine and pull Direct page register n
|
||||
|
||||
|
||||
m7900_sbc, // SuBtract with Carry
|
||||
m7900_sbcb, // SuBtract with Carry at Byte
|
||||
m7900_sbcd, // SuBtract with Carry at Double-word
|
||||
|
||||
|
||||
m7900_sec, // SEt Carry flag
|
||||
m7900_sei, // SEt Interrupt disable status
|
||||
m7900_sem, // SEt M flag
|
||||
m7900_sep, // SEt Processor status
|
||||
|
||||
|
||||
m7900_sta, // STore Accumulator in memory
|
||||
m7900_stab, // STore Accumulator in memory at Byte
|
||||
m7900_stad, // STore Accumulator in memory at Double-word
|
||||
|
||||
|
||||
m7900_stp, // SToP
|
||||
m7900_stx, // STore index register X in memory
|
||||
m7900_sty, // STore index register Y in memory
|
||||
|
||||
m7900_sub, // SUBtract
|
||||
m7900_subb, // SUBtract at Byte
|
||||
m7900_subd, // SUBtract at Double-word
|
||||
m7900_subm, // SUBtract immediate from Memory
|
||||
m7900_submb, // SUBtract immediate from Memory at Byte
|
||||
m7900_submd, // SUBtract immediate from Memory at Double-word
|
||||
m7900_subs, // SUBtract Stack pointer
|
||||
m7900_subx, // SUBtract immediate from index register X
|
||||
m7900_suby, // SUBtract immediate from index register Y
|
||||
|
||||
|
||||
|
||||
m7900_tadn, // Transfer accumulator A to Direct page register n
|
||||
|
||||
|
||||
m7900_tas, // Transfer accumulator A to Stack pointer
|
||||
m7900_tax, // Transfer accumulator A to index register X
|
||||
m7900_tay, // Transfer accumulator A to index register Y
|
||||
|
||||
m7900_tbdn, // Transfer accumulator B to Direct page register n
|
||||
|
||||
m7900_tbs, // Transfer accumulator B to Stack pointer
|
||||
m7900_tbx, // Transfer accumulator B to index register X
|
||||
m7900_tby, // Transfer accumulator B to index register Y
|
||||
|
||||
m7900_tdan, // Transfer Direct page register n to accumulator A
|
||||
m7900_tdbn, // Transfer Direct page register n to accumulator B
|
||||
|
||||
m7900_tds, // Transfer Direct page register to Stack pointer
|
||||
|
||||
|
||||
m7900_tsa, // Transfer Stack pointer to accumulator A
|
||||
m7900_tsb, // Transfer Stack pointer to accumulator B
|
||||
m7900_tsd, // Transfer Stack pointer to Direct page register
|
||||
m7900_tsx, // Transfer Stack pointer to index register X
|
||||
m7900_txa, // Transfer index register X to accumulator A
|
||||
m7900_txb, // Transfer index register X to accumulator B
|
||||
m7900_txs, // Transfer index register X to Stack pointer
|
||||
m7900_txy, // Transfer index register X to Y
|
||||
m7900_tya, // Transfer index register Y to accumulator A
|
||||
m7900_tyb, // Transfer index register Y to accumulator B
|
||||
m7900_tyx, // Transfer index register Y to X
|
||||
|
||||
m7900_wit, // WaIT
|
||||
|
||||
m7900_xab, // eXchange accumulator A and B
|
||||
|
||||
m7900_last //
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
6250
idasdk76/module/m7900/m7900.cfg
Normal file
6250
idasdk76/module/m7900/m7900.cfg
Normal file
File diff suppressed because it is too large
Load Diff
52
idasdk76/module/m7900/makefile
Normal file
52
idasdk76/module/m7900/makefile
Normal file
@@ -0,0 +1,52 @@
|
||||
PROC=m7900
|
||||
CONFIGS=m7900.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)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
|
||||
../iohandler.hpp 7900.hpp ana.cpp ins.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)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
|
||||
../iohandler.hpp 7900.hpp emu.cpp ins.hpp
|
||||
$(F)ins$(O) : $(I)bitrange.hpp $(I)bytes.hpp $(I)config.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)nalt.hpp \
|
||||
$(I)netnode.hpp $(I)pro.h $(I)range.hpp $(I)segment.hpp \
|
||||
$(I)ua.hpp $(I)xref.hpp ins.cpp ins.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)segregs.hpp $(I)ua.hpp $(I)xref.hpp ../idaidp.hpp \
|
||||
../iohandler.hpp 7900.hpp ins.hpp out.cpp
|
||||
$(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 7900.hpp ins.hpp reg.cpp
|
||||
846
idasdk76/module/m7900/out.cpp
Normal file
846
idasdk76/module/m7900/out.cpp
Normal file
@@ -0,0 +1,846 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include "7900.hpp"
|
||||
|
||||
static const char *const BitNamesCPU[] = { "IPL", "N", "V", "m", "x", "D", "I", "Z", "C" };
|
||||
static const char *const BitNamesPUL[] = { "PS", "0", "DT", "DP0", "Y", "X", "B", "A" };
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
class out_m7900_t : public outctx_t
|
||||
{
|
||||
out_m7900_t(void) = delete; // not used
|
||||
public:
|
||||
void OutReg(int rgnum) { out_register(ph.reg_names[rgnum]); }
|
||||
int OutVarName(const op_t &x);
|
||||
void SetDP0Plus(const op_t &x) { out_value(x, OOFW_IMM | OOFW_16); }
|
||||
void GetNumPUL(uval_t data);
|
||||
void GetNumDPRn(uval_t data);
|
||||
void GetCLPFlags(uval_t data);
|
||||
ea_t OutDPRReg(ea_t Addr, uval_t gDPReg);
|
||||
void OutDPR(uint32 Data);
|
||||
void OutDT(uint32 Data);
|
||||
void OutIMM(uint32 Data);
|
||||
void MOVRB(void);
|
||||
void MOVR(void);
|
||||
void MOV(const op_t &x);
|
||||
|
||||
bool out_operand(const op_t &x);
|
||||
void out_insn(void);
|
||||
void out_proc_mnem(void);
|
||||
};
|
||||
CASSERT(sizeof(out_m7900_t) == sizeof(outctx_t));
|
||||
|
||||
DECLARE_OUT_FUNCS(out_m7900_t)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::GetNumPUL(uval_t data)
|
||||
{
|
||||
int bitOut = 0;
|
||||
for ( int i=0; i < 8; i++ )
|
||||
{
|
||||
if ( GETBIT(data, i) == 1 )
|
||||
{
|
||||
if ( bitOut != 0 )
|
||||
out_symbol(',');
|
||||
out_register(BitNamesPUL[7-i]);
|
||||
if ( bitOut == 0 )
|
||||
bitOut++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::GetNumDPRn(uval_t data)
|
||||
{
|
||||
switch ( data )
|
||||
{
|
||||
case 0x1:
|
||||
out_symbol('0');
|
||||
break;
|
||||
case 0x2:
|
||||
out_symbol('1');
|
||||
break;
|
||||
case 0x4:
|
||||
out_symbol('2');
|
||||
break;
|
||||
case 0x8:
|
||||
out_symbol('3');
|
||||
break;
|
||||
default:
|
||||
out_symbol('(');
|
||||
bool add_comma = false;
|
||||
for ( int i=0; i < 4; ++i )
|
||||
{
|
||||
if ( GETBIT(data, i) == 1 )
|
||||
{
|
||||
if ( add_comma )
|
||||
out_symbol(',');
|
||||
out_long(i, 10);
|
||||
add_comma = true;
|
||||
}
|
||||
}
|
||||
out_symbol(')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::GetCLPFlags(uval_t data)
|
||||
{
|
||||
int bitOut = 0;
|
||||
for ( int i=0; i < 8; i++ )
|
||||
{
|
||||
if ( GETBIT(data, i) == 1 )
|
||||
{
|
||||
if ( bitOut != 0 )
|
||||
out_symbol(',');
|
||||
out_register(BitNamesCPU[8-i]);
|
||||
if ( bitOut == 0 )
|
||||
bitOut++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int out_m7900_t::OutVarName(const op_t &x)
|
||||
{
|
||||
return out_name_expr(x, to_ea(insn.cs, x.addr), x.addr);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static int getNumDPR(uval_t iDPR )
|
||||
{
|
||||
switch ( iDPR )
|
||||
{
|
||||
case 0x0: return 0;
|
||||
case 0x40: return 1;
|
||||
case 0x80: return 2;
|
||||
case 0xC0: return 3;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
ea_t out_m7900_t::OutDPRReg(ea_t Addr, uval_t gDPReg)
|
||||
{
|
||||
if ( gDPReg == 1 )
|
||||
{
|
||||
char szTemp[5];
|
||||
uval_t Data = Addr;
|
||||
Data &= 0xC0;
|
||||
qsnprintf(szTemp, sizeof(szTemp), "DP%d", getNumDPR(Data));
|
||||
out_register(szTemp);
|
||||
Addr &= 0xFF3F;
|
||||
}
|
||||
else
|
||||
{
|
||||
out_keyword("DP0");
|
||||
}
|
||||
return Addr;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static sel_t GetValueDP(const insn_t &insn, int DPR )
|
||||
{
|
||||
if ( getDPReg == 1 )
|
||||
{
|
||||
switch ( DPR )
|
||||
{
|
||||
case 0x0: return getDPR0;
|
||||
case 0x40: return getDPR1;
|
||||
case 0x80: return getDPR2;
|
||||
case 0xC0: return getDPR3;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::OutDPR(uint32 Data)
|
||||
{
|
||||
ea_t Val = Data;
|
||||
Val = OutDPRReg(Val, getDPReg);
|
||||
out_symbol(':');
|
||||
out_printf(COLSTR("%a",SCOLOR_NUMBER), Val+GetValueDP(insn, Data&0xC0));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::OutDT(uint32 Data)
|
||||
{
|
||||
out_register("DT");
|
||||
out_symbol('+');
|
||||
out_symbol(':');
|
||||
out_printf(COLSTR("%X",SCOLOR_NUMBER), Data);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::OutIMM(uint32 Data)
|
||||
{
|
||||
out_symbol('#');
|
||||
out_printf(COLSTR("%x",SCOLOR_NUMBER), Data);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::MOVRB(void)
|
||||
{
|
||||
int i;
|
||||
uint32 Val1, Val2;
|
||||
uchar code = get_byte(insn.ea+1);
|
||||
uchar nib = (code >> 4) & 0xF;
|
||||
uchar count = code & 0x0F;
|
||||
|
||||
switch ( nib )
|
||||
{
|
||||
case 0x0:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val1 = get_byte(insn.ea+2+(i*2));// imm
|
||||
Val2 = get_byte(insn.ea+2+(i*2)+1);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val2);
|
||||
out_symbol(',');
|
||||
// imm
|
||||
OutIMM(Val1);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*3));// mmll
|
||||
Val1 = get_byte(insn.ea+2+(i*3)+2);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDT(Val2);
|
||||
out_symbol(',');
|
||||
OutReg(rX);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val1 = get_byte(insn.ea+2+(i*3));// imm
|
||||
Val2 = get_word(insn.ea+2+(i*3)+1);// mmll
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val2);
|
||||
out_symbol(',');
|
||||
// IMM
|
||||
OutIMM(Val1);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val1 = get_byte(insn.ea+2+(i*2));// dd1
|
||||
Val2 = get_byte(insn.ea+2+(i*2)+1);// dd2
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val2);
|
||||
out_symbol(',');
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val1 = get_byte(insn.ea+2+(i*3));// imm
|
||||
Val2 = get_word(insn.ea+2+(i*3)+1);// mmll
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val2);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDPR(Val1);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_byte(insn.ea+2+(i*3));// mmll
|
||||
Val1 = get_word(insn.ea+2+(i*3)+1);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val1);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDPR(Val2);
|
||||
out_symbol(',');
|
||||
OutReg(rX);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x8:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*3));// mmll
|
||||
Val1 = get_byte(insn.ea+2+(i*3)+2);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
// DT
|
||||
OutDT(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xA:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val1 = get_word(insn.ea+2+(i*4));// imm
|
||||
Val2 = get_word(insn.ea+2+(i*4)+2);// mmll
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val2);
|
||||
out_symbol(',');
|
||||
// DT
|
||||
OutDT(Val1);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::MOVR(void)
|
||||
{
|
||||
int i;
|
||||
uint32 Val1, Val2;
|
||||
uchar code = get_byte(insn.ea+1);
|
||||
uchar nib = (code >> 4) & 0xF;
|
||||
uchar count = code & 0x0F;
|
||||
|
||||
switch ( nib )
|
||||
{
|
||||
case 0x0:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*3));// mmll
|
||||
Val1 = get_byte(insn.ea+2+(i*3)+2);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
// DT
|
||||
OutDT(Val2);
|
||||
out_symbol(',');
|
||||
OutReg(rX);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x1:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
if ( getFlag_M == 0 )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*3));// imm
|
||||
Val1 = get_byte(insn.ea+2+(i*3)+2);// dd
|
||||
}
|
||||
else
|
||||
{
|
||||
Val2 = get_byte(insn.ea+2+(i*2));// imm
|
||||
Val1 = get_byte(insn.ea+2+(i*2)+1);// dd
|
||||
}
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
// imm
|
||||
OutIMM(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
if ( getFlag_M == 0 )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*4));// imm
|
||||
Val1 = get_word(insn.ea+2+(i*4)+2);// llmm
|
||||
}
|
||||
else
|
||||
{
|
||||
Val2 = get_byte(insn.ea+2+(i*3));// imm
|
||||
Val1 = get_word(insn.ea+2+(i*3)+1);// llmm
|
||||
}
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val1);
|
||||
out_symbol(',');
|
||||
// IMM
|
||||
OutIMM(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x5:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_byte(insn.ea+2+(i*2));// dd
|
||||
Val1 = get_byte(insn.ea+2+(i*2)+1);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDPR(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x6:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val1 = get_byte(insn.ea+2+(i*3));// imm
|
||||
Val2 = get_word(insn.ea+2+(i*3)+1);// mmll
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val2);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
OutReg(rX);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x7:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_byte(insn.ea+2+(i*3));// mmll
|
||||
Val1 = get_word(insn.ea+2+(i*3)+1);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDT(Val1);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDPR(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x9:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*3));// mmll
|
||||
Val1 = get_byte(insn.ea+2+(i*3)+2);// dd
|
||||
|
||||
// DPRxx
|
||||
OutDPR(Val1);
|
||||
out_symbol(',');
|
||||
// DPR
|
||||
OutDT(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
|
||||
case 0xB:
|
||||
for ( i=0; i < count; i++ )
|
||||
{
|
||||
Val2 = get_word(insn.ea+2+(i*4));// imm
|
||||
Val1 = get_word(insn.ea+2+(i*4)+2);// llmm
|
||||
|
||||
// DT
|
||||
OutDT(Val1);
|
||||
out_symbol(',');
|
||||
// DT
|
||||
OutDT(Val2);
|
||||
|
||||
if ( i != (count-1) )
|
||||
out_symbol(',');
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::MOV(const op_t &x)
|
||||
{
|
||||
switch ( x.TypeOper )
|
||||
{
|
||||
case m7900_movrb: MOVRB(); break;
|
||||
case m7900_movr: MOVR(); break;
|
||||
default:
|
||||
// msg("out: %a: bad prefix %d\n", insn.ip, RAZOPER);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
bool out_m7900_t::out_operand(const op_t &x)
|
||||
{
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_void:
|
||||
return 0;
|
||||
|
||||
case o_reg:
|
||||
OutReg(x.reg);
|
||||
break;
|
||||
|
||||
case o_phrase:
|
||||
out_line(ph.reg_names[x.reg]);
|
||||
break;
|
||||
|
||||
case o_ab:
|
||||
switch ( x.TypeOper )
|
||||
{
|
||||
case TAB_L_INDIRECTED_ABS:
|
||||
out_symbol('L');
|
||||
// fallthrough
|
||||
|
||||
case TAB_INDIRECTED_ABS:
|
||||
out_symbol('(');
|
||||
if ( !OutVarName(x) )
|
||||
out_value(x, OOF_ADDR | OOFS_NOSIGN);
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
case TAB_INDIRECTED_ABS_X:
|
||||
out_symbol('(');
|
||||
|
||||
if ( !OutVarName(x) )
|
||||
out_value(x, OOF_ADDR | OOFS_NOSIGN);
|
||||
|
||||
out_symbol(',');
|
||||
OutReg(rX);
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
case TAB_ABS_Y:
|
||||
case TAB_ABS_X:
|
||||
case TAB_ABS:
|
||||
out_register("DT");
|
||||
out_symbol(':');
|
||||
|
||||
if ( !OutVarName(x) )
|
||||
out_value(x, OOF_ADDR | OOFS_NOSIGN | OOFW_32);
|
||||
break;
|
||||
|
||||
case TAB_ABL_X:
|
||||
case TAB_ABL:
|
||||
out_register("LG");
|
||||
out_symbol(':');
|
||||
|
||||
if ( !OutVarName(x) )
|
||||
out_value(x, OOF_ADDR | OOFS_NOSIGN | OOFW_32);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case o_sr:
|
||||
if ( x.TypeOper == TSP_INDEX_SP_Y )
|
||||
out_symbol('(');
|
||||
|
||||
if ( x.xmode == IMM_32 )
|
||||
out_value(x, OOFW_IMM | OOFW_32);
|
||||
else if ( x.xmode == IMM_16 )
|
||||
out_value(x, OOFW_IMM | OOFW_16);
|
||||
else
|
||||
out_value(x, OOFW_IMM);
|
||||
|
||||
if ( x.TypeOper == TSP_INDEX_SP_Y )
|
||||
{
|
||||
out_symbol(',');
|
||||
OutReg(rPS);
|
||||
out_symbol(')');
|
||||
}
|
||||
break;
|
||||
|
||||
case o_stk:
|
||||
// there are special cases
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case m7900_pei: SetDP0Plus(x); break;
|
||||
case m7900_psh:
|
||||
case m7900_pul: GetNumPUL(x.value); break;
|
||||
|
||||
default:
|
||||
out_symbol('#');
|
||||
out_value(x, OOFW_IMM | OOFS_NOSIGN);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case o_imm:
|
||||
// there are special cases
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case m7900_sep:// Set Processor status
|
||||
case m7900_clp:// CLear Processor status
|
||||
GetCLPFlags(x.value);
|
||||
break;
|
||||
|
||||
case m7900_lddn:
|
||||
case m7900_tdan:
|
||||
case m7900_phdn:
|
||||
case m7900_rtsdn:
|
||||
case m7900_pldn:
|
||||
case m7900_rtld:
|
||||
case m7900_phldn:
|
||||
GetNumDPRn(x.value);
|
||||
break;
|
||||
case m7900_bsc:
|
||||
case m7900_bss:
|
||||
out_value(x, OOFW_IMM);
|
||||
break;
|
||||
|
||||
default:
|
||||
out_symbol('#');
|
||||
out_value(x, OOFW_IMM);
|
||||
break;
|
||||
}
|
||||
break;// case o_imm
|
||||
|
||||
case o_mem:
|
||||
// output memory variable name (for example 'byte_98')
|
||||
if ( x.TypeOper == m7900_movr || x.TypeOper == m7900_movrb )
|
||||
{
|
||||
MOV(x);
|
||||
break;
|
||||
}
|
||||
|
||||
switch ( x.TypeOper )
|
||||
{
|
||||
case TDIR_DIR_Y:
|
||||
case TDIR_DIR_X:
|
||||
case TDIR_DIR:
|
||||
{
|
||||
op_t y = x;
|
||||
y.addr = OutDPRReg(y.addr, getDPReg);
|
||||
out_symbol(':');
|
||||
if ( !OutVarName(y) )
|
||||
out_value(y, OOF_ADDR |OOF_NUMBER| OOFS_NOSIGN);
|
||||
}
|
||||
break;
|
||||
|
||||
case TDIR_L_INDIRECT_DIR_Y:
|
||||
case TDIR_L_INDIRECT_DIR:
|
||||
out_symbol('L');
|
||||
// fallthrough
|
||||
|
||||
case TDIR_INDIRECT_DIR_Y:
|
||||
case TDIR_INDIRECT_DIR:
|
||||
out_symbol('(');
|
||||
{
|
||||
op_t y = x;
|
||||
y.addr = OutDPRReg(y.addr, getDPReg);
|
||||
out_symbol(':');
|
||||
if ( !OutVarName(y) )
|
||||
out_value(y, OOF_ADDR |OOF_NUMBER| OOFS_NOSIGN);
|
||||
}
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
case TDIR_INDIRECT_DIR_X:
|
||||
out_symbol('(');
|
||||
|
||||
{
|
||||
op_t y = x;
|
||||
y.addr = OutDPRReg(y.addr, getDPReg);
|
||||
out_symbol(':');
|
||||
if ( !OutVarName(y) )
|
||||
out_value(y, OOF_ADDR |OOF_NUMBER| OOFS_NOSIGN);
|
||||
}
|
||||
|
||||
out_symbol(',');
|
||||
OutReg(rX);
|
||||
out_symbol(')');
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case o_near:
|
||||
{
|
||||
ea_t v = to_ea(insn.cs,x.addr);
|
||||
if ( !out_name_expr(x, v, x.addr) )
|
||||
{
|
||||
out_value(x, OOF_ADDR | OOFS_NOSIGN);
|
||||
// remember_problem(PR_NONAME, insn.ea);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// warning("out: %a: bad optype %d", insn.ip, x.type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static const char *GetPrefics(int Raz)
|
||||
{
|
||||
switch ( Raz )
|
||||
{
|
||||
case INSN_PREF_B: return ".b";
|
||||
case INSN_PREF_W: return "";
|
||||
case INSN_PREF_D: return ".d";
|
||||
case INSN_PREF_U: return "";
|
||||
default:
|
||||
// msg("out: %a: bad prefix %d\n", insn.ip, RAZOPER);
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::out_proc_mnem(void)
|
||||
{
|
||||
out_mnem(8, GetPrefics(RAZOPER)); // output instruction mnemonics
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_m7900_t::out_insn(void)
|
||||
{
|
||||
out_mnemonic();
|
||||
|
||||
out_one_operand(0); // output the first operand
|
||||
|
||||
if ( insn.Op2.type != o_void )
|
||||
{
|
||||
out_symbol(','); // operand sep
|
||||
if ( (ash.uflag & UAS_NOSPA) == 0 )
|
||||
out_char(' ');
|
||||
out_one_operand(1);
|
||||
}
|
||||
|
||||
if ( insn.Op3.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
if ( (ash.uflag & UAS_NOSPA) == 0 )
|
||||
out_char(' ');
|
||||
out_one_operand(2);
|
||||
}
|
||||
|
||||
if ( insn.Op4.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
if ( (ash.uflag & UAS_NOSPA) == 0 )
|
||||
out_char(' ');
|
||||
out_one_operand(3);
|
||||
}
|
||||
|
||||
|
||||
if ( insn.Op5.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
if ( (ash.uflag & UAS_NOSPA) == 0 )
|
||||
out_char(' ');
|
||||
out_one_operand(4);
|
||||
}
|
||||
|
||||
out_immchar_cmts();
|
||||
flush_outbuf();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void m7900_t::m7900_header(outctx_t &ctx)
|
||||
{
|
||||
ctx.gen_header(GH_PRINT_ALL_BUT_BYTESEX, NULL, ioh.device.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// generate segment header
|
||||
//lint -esym(1764, ctx) could be made const
|
||||
//lint -esym(818, Srange) could be made const
|
||||
void m7900_t::m7900_segstart(outctx_t &ctx, segment_t *Srange) const
|
||||
{
|
||||
qstring sname;
|
||||
get_visible_segm_name(&sname, Srange);
|
||||
|
||||
if ( ash.uflag & UAS_SEGM )
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR("SEGMENT %s", SCOLOR_ASMDIR), sname.c_str());
|
||||
else
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR(".SECTION %s", SCOLOR_ASMDIR), sname.c_str());
|
||||
|
||||
ea_t orgbase = ctx.insn_ea - get_segm_para(Srange);
|
||||
if ( orgbase != 0 )
|
||||
{
|
||||
char buf[MAX_NUMBUF];
|
||||
btoa(buf, sizeof(buf), orgbase);
|
||||
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s %s", SCOLOR_ASMDIR), ash.origin, buf);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void m7900_t::m7900_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");
|
||||
}
|
||||
}
|
||||
441
idasdk76/module/m7900/reg.cpp
Normal file
441
idasdk76/module/m7900/reg.cpp
Normal file
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Interactive disassembler (IDA).
|
||||
* Version 3.05
|
||||
* Copyright (c) 1990-95 by Ilfak Guilfanov.
|
||||
* ALL RIGHTS RESERVED.
|
||||
* FIDO: 2:5020/209
|
||||
* E-mail: ig@estar.msk.su
|
||||
*
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include "7900.hpp"
|
||||
#include <diskio.hpp>
|
||||
#include <entry.hpp>
|
||||
int data_id;
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static const char *const RegNames[] =
|
||||
{
|
||||
"A", "B", "E", "X", "Y", "PC", "S",
|
||||
"fIPL", "fN", "fV", "fD", "fI", "fZ", "fC",
|
||||
"DT", "PG", "DPReg", "DPR0","DPR1", "DPR2","DPR3","fM", "fX",
|
||||
"cs", "ds"
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static const asm_t AS79 =
|
||||
{
|
||||
AS_COLON // create colons after data names ?
|
||||
// ASCII directives:
|
||||
|AS_1TEXT // 1 text per line, no bytes
|
||||
|ASH_HEXF0 // format of hex numbers:// 34h
|
||||
|ASD_DECF0 // format of dec numbers:// 34
|
||||
|ASB_BINF0 // format of binary numbers:// 010101b
|
||||
|AS_ONEDUP, // One array definition per line
|
||||
|
||||
UAS_NOSPA | UAS_SEGM,
|
||||
"Mitsubishi AS79 V4.10",
|
||||
0,
|
||||
NULL, // header
|
||||
".org",
|
||||
".end",
|
||||
|
||||
";", // comment string
|
||||
'"', // string delimiter
|
||||
'\'', // char delimiter
|
||||
"'\"", // special symbols in char and string constants
|
||||
|
||||
".BYTE", // ascii string directive
|
||||
".BYTE", // byte directive
|
||||
".WORD", // word directive
|
||||
".DWORD", // no double words
|
||||
NULL, // no qwords
|
||||
NULL, // oword (16 bytes)
|
||||
NULL, // no float
|
||||
NULL, // no double
|
||||
NULL, // no tbytes
|
||||
NULL, // no packreal
|
||||
NULL, //".db.#s(b,w) #d,#v", // #h - header(.byte,.word)
|
||||
// #d - size of array
|
||||
// #v - value of array elements
|
||||
// #s - size specifier
|
||||
".rs %s", // uninited data (reserve space)
|
||||
".equ",
|
||||
NULL, // seg prefix
|
||||
"*", // a_curip
|
||||
NULL, // returns function header line
|
||||
NULL, // returns function footer line
|
||||
NULL, // public
|
||||
NULL, // weak
|
||||
NULL, // extrn
|
||||
NULL, // comm
|
||||
NULL, // get_type_name
|
||||
NULL, // align
|
||||
'(', ')', // lbrace, rbrace
|
||||
NULL, // mod
|
||||
NULL, // and
|
||||
NULL, // or
|
||||
NULL, // xor
|
||||
NULL, // not
|
||||
NULL, // shl
|
||||
NULL, // shr
|
||||
NULL, // sizeof
|
||||
};
|
||||
//----------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------
|
||||
#define FAMILY "Mitsubishi series:"
|
||||
|
||||
static const char *const shnames[] =
|
||||
{
|
||||
"m7900",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *const lnames[] =
|
||||
{
|
||||
FAMILY"Mitsubishi 7700 Family / 7900 Series",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static const asm_t *const asms[] =
|
||||
{
|
||||
&AS79,
|
||||
NULL
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static const uchar retc_0[] = { 0xF1 }; // rti
|
||||
static const uchar retc_1[] = { 0x94 }; // rtl
|
||||
static const uchar retc_2[] = { 0x1C, 0x77 }; // rtld 0
|
||||
static const uchar retc_3[] = { 0x2C, 0x77 }; // rtld 1
|
||||
static const uchar retc_4[] = { 0x4C, 0x77 }; // rtld 2
|
||||
static const uchar retc_5[] = { 0x8C, 0x77 }; // rtld 3
|
||||
static const uchar retc_6[] = { 0x84 }; // rts
|
||||
static const uchar retc_7[] = { 0x18, 0x77 }; // rtsd 0
|
||||
static const uchar retc_8[] = { 0x28, 0x77 }; // rtsd 1
|
||||
static const uchar retc_9[] = { 0x48, 0x77 }; // rtsd 2
|
||||
static const uchar retc_10[] = { 0x88, 0x77 }; // rtsd 3
|
||||
static const uchar retc_11[] = { 0x00, 0x74 }; // brk
|
||||
|
||||
static const bytes_t retcodes[] =
|
||||
{
|
||||
{ sizeof(retc_0), retc_0 },
|
||||
{ sizeof(retc_1), retc_1 },
|
||||
{ sizeof(retc_2), retc_2 },
|
||||
{ sizeof(retc_3), retc_3 },
|
||||
{ sizeof(retc_4), retc_4 },
|
||||
{ sizeof(retc_5), retc_5 },
|
||||
{ sizeof(retc_6), retc_6 },
|
||||
{ sizeof(retc_6), retc_7 },
|
||||
{ sizeof(retc_6), retc_8 },
|
||||
{ sizeof(retc_9), retc_9 },
|
||||
{ sizeof(retc_10), retc_10 },
|
||||
{ sizeof(retc_11), retc_11 },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
#define ADDRRESET 0xFFFE
|
||||
|
||||
const char *m7900_t::set_idp_options(
|
||||
const char *keyword,
|
||||
int /*value_type*/,
|
||||
const void * /*value*/,
|
||||
bool /*idb_loaded*/)
|
||||
{
|
||||
if ( keyword != NULL )
|
||||
return IDPOPT_BADKEY;
|
||||
|
||||
char cfgfile[QMAXFILE];
|
||||
ioh.get_cfg_filename(cfgfile, sizeof(cfgfile));
|
||||
if ( !choose_ioport_device(&ioh.device, cfgfile)
|
||||
&& ioh.device == NONEPROC )
|
||||
{
|
||||
warning("No devices are defined in the configuration file %s", cfgfile);
|
||||
}
|
||||
|
||||
ioh.set_device_name(ioh.device.c_str(), IORESP_PORT|IORESP_INT);
|
||||
|
||||
return IDPOPT_OK;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------
|
||||
bool m7900_t::choose_device()
|
||||
{
|
||||
char cfgfile[QMAXFILE];
|
||||
ioh.get_cfg_filename(cfgfile, sizeof(cfgfile));
|
||||
iohandler_t::parse_area_line0_t cb(ioh);
|
||||
bool ok = choose_ioport_device2(&ioh.device, cfgfile, &cb);
|
||||
if ( !ok )
|
||||
{
|
||||
ioh.device = NONEPROC;
|
||||
|
||||
segment_t *sptr = get_first_seg();
|
||||
if ( sptr != NULL )
|
||||
{
|
||||
//inf_set_start_ea(sptr->start_ea);
|
||||
//inf_set_start_ip(0);
|
||||
|
||||
// No processor selected, so create RESET.
|
||||
// According to 7900 manual RESET resides at 0xFFFE address
|
||||
create_word(ADDRRESET, 2);
|
||||
ea_t proc = get_word(ADDRRESET);
|
||||
if ( proc != 0xFFFF && is_mapped(proc) )
|
||||
{
|
||||
op_plain_offset(ADDRRESET, 0, 0);
|
||||
add_entry(proc, proc, "__RESET", true);
|
||||
set_cmt(ADDRRESET, "RESET", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
void m7900_t::load_from_idb()
|
||||
{
|
||||
ioh.restore_device(IORESP_NONE);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
ssize_t idaapi idb_listener_t::on_event(ssize_t notification_code, va_list va)
|
||||
{
|
||||
switch ( notification_code )
|
||||
{
|
||||
case idb_event::sgr_changed:
|
||||
// In case of fM or fX segment registers undefine data above current address
|
||||
{
|
||||
int reg = va_arg(va, int);
|
||||
if ( reg == rfM || reg == rfX || reg == rDT || reg == rPG )
|
||||
{
|
||||
// msg("Deleting instructions in range %08a..%08a\n",ea1, ea2);
|
||||
// for (ea_t x = ea1; x < ea2; x = next_that(x, ea2, is_code))
|
||||
// del_items(x, DELIT_SIMPLE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
static const char *const m7900_help_message =
|
||||
"AUTOHIDE REGISTRY\n"
|
||||
"You have loaded a file for the Mitsubishi 7900 family processor.\n\n"\
|
||||
"This processor can be used in two different 'length modes' : 8-bit and 16-bit.\n"\
|
||||
"IDA allows to specify the encoding mode for every single instruction.\n"\
|
||||
"For this, IDA uses two virtual segment registers : \n"\
|
||||
" - rDPReg(1), - rDPR0(0), rDPR1(0), rDPR2(0), rDPR3(0) \n"\
|
||||
" - rDT(0), rPG(0), rPC(0), rPS(0) \n"\
|
||||
" - fM, used to specify the data length;(0)\n"\
|
||||
" - fX, used to specify the index register length.(0)\n\n"\
|
||||
"Switching their state from 0 to 1 will switch the disassembly from 16-bit to 8-bit.\n"\
|
||||
"You can change their value using the 'change segment register value' command"\
|
||||
"(the canonical hotkey is Alt-G).\n\n"\
|
||||
"Note : in the real design, those registers are represented as flags in the\n"\
|
||||
"processor status register.\n";
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 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(m7900_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
ssize_t idaapi m7900_t::on_event(ssize_t msgid, va_list va)
|
||||
{
|
||||
int code = 0;
|
||||
switch ( msgid )
|
||||
{
|
||||
|
||||
case processor_t::ev_init:
|
||||
hook_event_listener(HT_IDB, &idb_listener, &LPH);
|
||||
helper.create(PROCMOD_NODE_NAME);
|
||||
break;
|
||||
|
||||
case processor_t::ev_newfile:
|
||||
if ( choose_device() )
|
||||
ioh.set_device_name(ioh.device.c_str(), IORESP_ALL);
|
||||
|
||||
// Set the default segment register values :
|
||||
// -1 (badsel) for DR
|
||||
// 0 for fM and fX
|
||||
for ( segment_t *s=get_first_seg(); s != NULL; s=get_next_seg(s->start_ea) )
|
||||
{
|
||||
set_default_sreg_value(s, rDPR0, 0x0);
|
||||
set_default_sreg_value(s, rDPR1, 0x0);
|
||||
set_default_sreg_value(s, rDPR2, 0x0);
|
||||
set_default_sreg_value(s, rDPR3, 0x0);
|
||||
set_default_sreg_value(s, rDT, 0x0);
|
||||
set_default_sreg_value(s, rPG, 0x0);
|
||||
set_default_sreg_value(s, rPC, 0xFFFE);
|
||||
set_default_sreg_value(s, rPS, 0x0FFF);
|
||||
|
||||
set_default_sreg_value(s, rfI, 1);
|
||||
set_default_sreg_value(s, rfD, 0);
|
||||
set_default_sreg_value(s, rfX, 0);
|
||||
set_default_sreg_value(s, rfM, 0);
|
||||
set_default_sreg_value(s, rfIPL, 0);
|
||||
|
||||
set_default_sreg_value(s, rDPReg, 1);
|
||||
}
|
||||
info(m7900_help_message);
|
||||
break;
|
||||
|
||||
case processor_t::ev_term:
|
||||
unhook_event_listener(HT_IDB, &idb_listener);
|
||||
clr_module_data(data_id);
|
||||
break;
|
||||
|
||||
|
||||
case processor_t::ev_ending_undo:
|
||||
case processor_t::ev_oldfile:
|
||||
load_from_idb();
|
||||
break;
|
||||
|
||||
case processor_t::ev_creating_segm: // new segment
|
||||
{
|
||||
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_mnem:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
out_mnem(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_header:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
m7900_header(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_footer:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
m7900_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 *);
|
||||
m7900_segstart(*ctx, seg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_ana_insn:
|
||||
{
|
||||
insn_t *out = va_arg(va, insn_t *);
|
||||
return ana(out);
|
||||
}
|
||||
|
||||
case processor_t::ev_emu_insn:
|
||||
{
|
||||
const insn_t *insn = va_arg(va, const insn_t *);
|
||||
return 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_set_idp_options:
|
||||
{
|
||||
const char *keyword = va_arg(va, const char *);
|
||||
int value_type = va_arg(va, int);
|
||||
const char *value = va_arg(va, const char *);
|
||||
const char **errmsg = va_arg(va, const char **);
|
||||
bool idb_loaded = va_argi(va, bool);
|
||||
const char *ret = set_idp_options(keyword, value_type, value, idb_loaded);
|
||||
if ( ret == IDPOPT_OK )
|
||||
return 1;
|
||||
if ( errmsg != NULL )
|
||||
*errmsg = ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Processor Definition
|
||||
//-----------------------------------------------------------------------
|
||||
processor_t LPH =
|
||||
{
|
||||
IDP_INTERFACE_VERSION, // version
|
||||
PLFM_M7900, // id
|
||||
// flag
|
||||
PR_RNAMESOK // can use register names for byte names
|
||||
| PR_BINMEM // The module creates RAM/ROM segments for binary files
|
||||
// (the kernel shouldn't ask the user about their sizes and addresses)
|
||||
| PR_SEGS // has segment registers?
|
||||
| PR_SGROTHER, // the segment registers don't contain
|
||||
// the segment selectors, something else
|
||||
// flag2
|
||||
PR2_IDP_OPTS, // the module has processor-specific configuration options
|
||||
8, // 8 bits in a byte for code segments
|
||||
8, // 8 bits in a byte for other segments
|
||||
|
||||
shnames,
|
||||
lnames,
|
||||
|
||||
asms,
|
||||
|
||||
notify,
|
||||
|
||||
RegNames, // Regsiter names
|
||||
qnumber(RegNames), // Number of registers
|
||||
|
||||
rDT,
|
||||
Rds,
|
||||
0, // size of a segment register
|
||||
Rcs,Rds,
|
||||
|
||||
NULL, // No known code start sequences
|
||||
retcodes,
|
||||
|
||||
0,
|
||||
m7900_last,
|
||||
Instructions, // instruc
|
||||
3, // int tbyte_size; -- doesn't exist
|
||||
|
||||
{ 0, 0, 0, 0 }, // char real_width[4];
|
||||
// number of symbols after decimal point
|
||||
// 2byte float (0-does not exist)
|
||||
// normal float
|
||||
// normal double
|
||||
// long double
|
||||
m7900_rts, // Icode of return instruction. It is ok to give any of possible return instructions
|
||||
};
|
||||
Reference in New Issue
Block a user