update
This commit is contained in:
539
idasdk75/module/cr16/ana.cpp
Normal file
539
idasdk75/module/cr16/ana.cpp
Normal file
@@ -0,0 +1,539 @@
|
||||
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "cr16.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static uchar Rproc(uchar code)
|
||||
{
|
||||
switch ( code )
|
||||
{
|
||||
case 0x1:
|
||||
return rPSR;
|
||||
case 0x3:
|
||||
return rINTBASE;
|
||||
case 0x4:
|
||||
return rINTBASEH;
|
||||
case 0x5:
|
||||
return rCFG;
|
||||
case 0x7:
|
||||
return rDSR;
|
||||
case 0x9:
|
||||
return rDCR;
|
||||
case 0xB:
|
||||
return rISP;
|
||||
case 0xD:
|
||||
return rCARL;
|
||||
case 0xE:
|
||||
return rCARH;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// immediate operands
|
||||
static void SetImmData(op_t &op, int32 code, int bits)
|
||||
{
|
||||
// extend sign
|
||||
if ( code & (1 << bits) )
|
||||
code -= 1L << (bits + 1);
|
||||
op.type = o_imm;
|
||||
// always in the second byte
|
||||
op.offb = 1;
|
||||
// data size
|
||||
op.dtype = bits > 8 ? (bits > 16 ? dt_dword : dt_word) : dt_byte;
|
||||
// value
|
||||
op.addr = op.value = code;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// register operand
|
||||
static void SetReg(op_t &op, uchar reg_n)
|
||||
{
|
||||
op.type = o_reg;
|
||||
op.reg = reg_n;
|
||||
op.dtype = dt_word;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// relative jump
|
||||
static void SetRelative(op_t &op, int32 disp, int bits, const insn_t &insn)
|
||||
{
|
||||
op.type = o_near;
|
||||
op.dtype = dt_word;
|
||||
op.offb = 0;
|
||||
// sign extend
|
||||
if ( disp & (1 << bits) )
|
||||
disp -= 1L << (bits + 1);
|
||||
op.addr = insn.ip + disp;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
static ushort GetWord(insn_t &insn)
|
||||
{
|
||||
ushort wrd = insn.get_next_byte();
|
||||
wrd |= ((ushort) insn.get_next_byte()) << 8;
|
||||
return wrd;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// store/load operands
|
||||
static void SetSL(insn_t &insn, op_t &op, ushort code)
|
||||
{
|
||||
op.reg = rR0 + ((code >> 1) & 0x0F);
|
||||
op.dtype = (code & 0x2000) ? dt_word : dt_byte;
|
||||
if ( code & 1 )
|
||||
{
|
||||
if ( code & 0x1000 )
|
||||
{
|
||||
if ( code & 0x800 )
|
||||
{
|
||||
if ( (code & 0x1F) == 0x1F )
|
||||
{
|
||||
// absolute addr
|
||||
op.type = o_mem;
|
||||
op.addr = op.value = GetWord(insn) | (((uint32) code & 0x600) << 11);
|
||||
}
|
||||
else
|
||||
{ // reg pair
|
||||
op.type = o_displ;
|
||||
op.addr = op.value = GetWord(insn) | (((uint32) code & 0x600) << 11);
|
||||
op.specflag1 |= URR_PAIR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // reg base
|
||||
op.type = o_displ;
|
||||
op.addr = op.value = GetWord(insn) | (((uint32) code & 0x600) << 11);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Offset
|
||||
op.type = o_displ;
|
||||
op.addr = op.value = ((code >> 8) & 0x1E) | 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
op.type = o_displ;
|
||||
op.addr = op.value = (code >> 8) & 0x1E;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
#define EXTOPS uint16(-2)
|
||||
static const uint16 Ops[16] =
|
||||
{
|
||||
CR16_addb, CR16_addub, EXTOPS, CR16_mulb,
|
||||
CR16_ashub, CR16_lshb, CR16_xorb, CR16_cmpb,
|
||||
CR16_andb, CR16_addcb, CR16_br, CR16_tbit,
|
||||
CR16_movb, CR16_subcb, CR16_orb, CR16_subb,
|
||||
};
|
||||
|
||||
static const uint16 ExtOps[16] =
|
||||
{
|
||||
CR16_cbitb, CR16_sbitb, CR16_tbitb, CR16_storb,
|
||||
};
|
||||
|
||||
// extended instructions
|
||||
// register-relative with no displacement:
|
||||
// 54 3 2109 8 76 5 4321 d
|
||||
// 01 i 0010 bs1 ex-op bs0 bit-num/Imm 1
|
||||
// register-relative with 16-bit displacement:
|
||||
// 54 3 2109 8 76 5 4321 d
|
||||
// 00 i 0010 bs1 ex-op bs0 bit-num/Imm 1
|
||||
// 18-bit absolute memory:
|
||||
// 54 3 2109 8 76 5 4321 d
|
||||
// 00 i 0010 bs1 ex-op bs0 bit-num/Imm 0
|
||||
static void SetExtOp(insn_t &insn, ushort code)
|
||||
{
|
||||
if ( code & 1 )
|
||||
{
|
||||
// Register-relative
|
||||
insn.Op2.reg = rR0 + ((code >> 5) & 9);
|
||||
insn.Op2.type = o_displ;
|
||||
insn.Op2.dtype = (code & 0x2000) ? dt_word : dt_byte;
|
||||
if ( (code >> 14) & 1 )
|
||||
{
|
||||
// no displacement
|
||||
insn.Op2.addr = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
insn.Op2.addr = GetWord(insn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 18-bit absolute memory
|
||||
insn.Op2.type = o_mem;
|
||||
insn.Op2.dtype = (code & 0x2000) ? dt_word : dt_byte;
|
||||
int adext = ((code >> 7) & 2) | ((code >> 5) & 1);
|
||||
insn.Op2.addr = GetWord(insn) | (adext<<16);
|
||||
}
|
||||
insn.Op1.type = o_imm;
|
||||
insn.Op1.value = (code >> 1) & 0xF;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// analyzer
|
||||
int idaapi CR16_ana(insn_t *_insn)
|
||||
{
|
||||
if ( _insn == NULL )
|
||||
return 0;
|
||||
insn_t &insn = *_insn;
|
||||
if ( insn.ip & 1 )
|
||||
return 0;
|
||||
|
||||
// get instruction word
|
||||
ushort code = GetWord(insn);
|
||||
|
||||
uchar WordFlg = (code >> 13) & 1;
|
||||
uchar OpCode = (code >> 9) & 0x0F;
|
||||
uchar Oper1 = (code >> 5) & 0x0F;
|
||||
uchar Oper2 = (code >> 1) & 0x0F;
|
||||
|
||||
|
||||
switch ( (code >> 14) & 3 )
|
||||
{
|
||||
// register-register op and special OP
|
||||
case 0x01:
|
||||
if ( code & 1 )
|
||||
{
|
||||
// 01xxxxxxxxxxxxx1
|
||||
insn.itype = Ops[OpCode];
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
case EXTOPS:
|
||||
{
|
||||
int exop = (Oper1 >> 1) & 3;
|
||||
insn.itype = ExtOps[exop] + WordFlg;
|
||||
SetExtOp(insn, code);
|
||||
}
|
||||
break;
|
||||
// branch's
|
||||
case CR16_br:
|
||||
if ( WordFlg )
|
||||
{
|
||||
insn.itype = CR16_jal;
|
||||
SetReg(insn.Op1, rR0 + Oper1);
|
||||
SetReg(insn.Op2, rR0 + Oper2);
|
||||
}
|
||||
else
|
||||
{
|
||||
insn.itype = CR16_jeq + Oper1;
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
}
|
||||
break;
|
||||
// Special tbit
|
||||
case CR16_tbit:
|
||||
if ( WordFlg == 0 )
|
||||
return 0;
|
||||
insn.itype--;
|
||||
// fallthrough
|
||||
// all other cmds
|
||||
default: // fix word operations
|
||||
if ( WordFlg )
|
||||
insn.itype++;
|
||||
// Setup register OP
|
||||
SetReg(insn.Op2, rR0 + Oper1);
|
||||
// Setup register OP
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // 01xxxxxxxxxxxxx0
|
||||
if ( WordFlg )
|
||||
{
|
||||
// 011xxxxxxxxxxxx0
|
||||
static const uchar SCmd[16] =
|
||||
{
|
||||
CR16_mulsb, CR16_mulsw, CR16_movd, CR16_movd,
|
||||
CR16_movxb, CR16_movzb, CR16_push, CR16_seq,
|
||||
CR16_lpr, CR16_spr, CR16_beq, CR16_bal,
|
||||
CR16_retx, CR16_excp, CR16_di, CR16_wait
|
||||
};
|
||||
insn.itype = SCmd[OpCode];
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
|
||||
case CR16_beq:
|
||||
{
|
||||
// 01 1 1010 cond d16,d19-d17 0
|
||||
insn.itype = CR16_beq + Oper1;
|
||||
int disp = GetWord(insn);
|
||||
disp |= (Oper2 & 8) << (16-3);
|
||||
disp |= (Oper2 & 7) << 17;
|
||||
SetRelative(insn.Op1, disp, 20, insn);
|
||||
}
|
||||
break;
|
||||
|
||||
case CR16_push:
|
||||
{
|
||||
static const uchar PQ[4] =
|
||||
{
|
||||
CR16_push, CR16_pop,
|
||||
CR16_popret, CR16_popret
|
||||
};
|
||||
insn.itype = PQ[Oper1 >> 2];
|
||||
SetReg(insn.Op2, rR0 + Oper2);
|
||||
SetImmData(insn.Op1, (Oper1 & 3) + 1, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
case CR16_mulsw:
|
||||
SetReg(insn.Op2, rR0 + Oper1);
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
insn.Op2.specflag1 |= URR_PAIR;
|
||||
break;
|
||||
|
||||
case CR16_movd:
|
||||
SetReg(insn.Op2, rR0 + Oper2);
|
||||
insn.Op2.specflag1 |= URR_PAIR;
|
||||
// !!!! ADD HIIIII ?!?!?!?
|
||||
SetImmData(insn.Op1, GetWord(insn), 20);
|
||||
break;
|
||||
case CR16_excp:
|
||||
if ( Oper1 != 0x0F )
|
||||
return 0;
|
||||
SetImmData(insn.Op1, Oper2, 4);
|
||||
break;
|
||||
|
||||
case CR16_retx:
|
||||
if ( Oper1 != 0x0F )
|
||||
return 0;
|
||||
if ( Oper2 != 0x0F )
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case CR16_wait:
|
||||
if ( Oper1 == 0x0F )
|
||||
{
|
||||
if ( Oper2 == 0x0F )
|
||||
break;
|
||||
if ( Oper2 == 0x03 )
|
||||
{
|
||||
insn.itype = CR16_eiwait;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( (code & 0x19E) == 0x84 )
|
||||
{
|
||||
insn.itype = CR16_storm;
|
||||
SetImmData(insn.Op1, (Oper2 & 3) + 1, 8);
|
||||
break;
|
||||
}
|
||||
if ( (code & 0x19E) == 0x04 )
|
||||
{
|
||||
insn.itype = CR16_loadm;
|
||||
SetImmData(insn.Op1, (Oper2 & 3) + 1, 8);
|
||||
break;
|
||||
}
|
||||
if ( (Oper2 & 0x6) == 0 )
|
||||
{
|
||||
insn.itype = CR16_muluw;
|
||||
SetReg(insn.Op2, rR0 + Oper1);
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
insn.Op2.specflag1 |= URR_PAIR;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case CR16_di:
|
||||
if ( Oper2 != 0x0F )
|
||||
return 0;
|
||||
switch ( Oper1 )
|
||||
{
|
||||
case 0x0F:
|
||||
insn.itype = CR16_ei;
|
||||
case 0x0E:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case CR16_seq:
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
if ( Oper1 > 0x0D )
|
||||
return 0;
|
||||
insn.itype = CR16_seq + Oper1;
|
||||
break;
|
||||
|
||||
case CR16_lpr:
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
Oper1 = Rproc(Oper1);
|
||||
if ( Oper1 == 0 )
|
||||
return 0;
|
||||
SetReg(insn.Op2, Oper1);
|
||||
break;
|
||||
|
||||
case CR16_spr:
|
||||
SetReg(insn.Op2, rR0 + Oper2);
|
||||
Oper1 = Rproc(Oper1);
|
||||
if ( Oper1 == 0 )
|
||||
return 0;
|
||||
SetReg(insn.Op1, Oper1);
|
||||
break;
|
||||
|
||||
case CR16_bal:
|
||||
{
|
||||
// 01 1 1011 lnk-pair d16,d19-d17 0
|
||||
SetReg(insn.Op1, rR0 + Oper1);
|
||||
insn.Op1.specflag1 |= URR_PAIR;
|
||||
int disp = GetWord(insn);
|
||||
disp |= (Oper2 & 8) << (16-3);
|
||||
disp |= (Oper2 & 7) << 17;
|
||||
SetRelative(insn.Op2, disp, 20, insn);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
SetReg(insn.Op2, rR0 + Oper1);
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // jump's
|
||||
// 010xxxxxxxxxxxx0
|
||||
insn.itype = CR16_beq + Oper1;
|
||||
SetRelative(insn.Op1, (code & 0x1E) | (OpCode << 5), 8, insn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// short immediate-register (two word)
|
||||
case 0x00:
|
||||
insn.itype = Ops[OpCode];
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case 0:
|
||||
return 0;
|
||||
// branch's
|
||||
case CR16_br:
|
||||
if ( code & 1 )
|
||||
{
|
||||
static const uchar BQ[4] =
|
||||
{
|
||||
CR16_beq0b, CR16_beq1b,
|
||||
CR16_bne0b, CR16_bne1b
|
||||
};
|
||||
insn.itype = BQ[(Oper1 >> 1) & 3];
|
||||
if ( WordFlg )
|
||||
insn.itype++;
|
||||
SetReg(insn.Op1, rR0 + (Oper1 & 0x9));
|
||||
SetRelative(insn.Op1, code & 0x1E, 5, insn);
|
||||
}
|
||||
else if ( WordFlg )
|
||||
{
|
||||
insn.itype = CR16_bal;
|
||||
SetReg(insn.Op1, rR0 + Oper1);
|
||||
if ( (code & 0x0F) == 0x0E )
|
||||
{
|
||||
SetRelative(insn.Op2,
|
||||
GetWord(insn) | (((uint32) code & 0x10) << 12), 16, insn);
|
||||
insn.Op2.addr = insn.Op2.value = insn.Op2.addr & 0x1FFFF;
|
||||
}
|
||||
else
|
||||
SetRelative(insn.Op2, code & 0x1F, 4, insn);
|
||||
}
|
||||
else
|
||||
{
|
||||
insn.itype = CR16_beq + Oper1;
|
||||
if ( (code & 0x0F) == 0x0E )
|
||||
{
|
||||
SetRelative(insn.Op1,
|
||||
GetWord(insn) | (((uint32) code & 0x10) << 12), 16, insn);
|
||||
insn.Op1.addr = insn.Op1.value = insn.Op2.addr & 0x1FFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRelative(insn.Op1, code & 0x1F, 4, insn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EXTOPS:
|
||||
{
|
||||
// 54 3 2109 8 76 5 4321 d
|
||||
// 00 i 0010 bs1 ex-op bs0 bit-num/Imm d
|
||||
int exop = (Oper1 >> 1) & 3;
|
||||
insn.itype = ExtOps[exop] + WordFlg;
|
||||
SetExtOp(insn, code);
|
||||
}
|
||||
break;
|
||||
|
||||
// Special tbit
|
||||
case CR16_tbit:
|
||||
if ( WordFlg == 0 )
|
||||
{
|
||||
// jcond large format
|
||||
// 00 0 1011 cond target-pair 1
|
||||
// jal large format
|
||||
// 00 0 1011 link-pair target-pair 0
|
||||
if ( code & 1 )
|
||||
{
|
||||
insn.itype = CR16_jeq + Oper1;
|
||||
SetReg(insn.Op1, rR0 + Oper2);
|
||||
insn.Op1.specflag1 |= URR_PAIR;
|
||||
}
|
||||
else
|
||||
{
|
||||
insn.itype = CR16_jal;
|
||||
SetReg(insn.Op1, rR0 + Oper1);
|
||||
insn.Op1.specflag1 |= URR_PAIR;
|
||||
SetReg(insn.Op2, rR0 + Oper2);
|
||||
insn.Op2.specflag1 |= URR_PAIR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
insn.itype--;
|
||||
// fallthrough
|
||||
|
||||
// all other cmds
|
||||
default:
|
||||
if ( code == 0x200 )
|
||||
{
|
||||
insn.itype = CR16_nop;
|
||||
break;
|
||||
}
|
||||
if ( WordFlg ) // fix word operations
|
||||
insn.itype++;
|
||||
// Setup register OP
|
||||
SetReg(insn.Op2, rR0 + Oper1);
|
||||
// Setup immediate
|
||||
if ( (code & 0x1F) == 0x11 )
|
||||
SetImmData(insn.Op1, GetWord(insn), 15);
|
||||
else
|
||||
SetImmData(insn.Op1, code & 0x1F, 4);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// LOADi
|
||||
case 0x02:
|
||||
insn.itype = WordFlg ? CR16_loadw : CR16_loadb;
|
||||
SetReg(insn.Op2, rR0 + Oper1);
|
||||
SetSL(insn, insn.Op1, code);
|
||||
break;
|
||||
// STORi
|
||||
case 0x3:
|
||||
insn.itype = WordFlg ? CR16_storw : CR16_storb;
|
||||
SetReg(insn.Op1, rR0 + Oper1);
|
||||
SetSL(insn, insn.Op2, code);
|
||||
break;
|
||||
}
|
||||
return insn.size;
|
||||
}
|
||||
357
idasdk75/module/cr16/cr16.cfg
Normal file
357
idasdk75/module/cr16/cr16.cfg
Normal file
@@ -0,0 +1,357 @@
|
||||
; 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
|
||||
;
|
||||
; NSC CompactRISC CR16 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 SC14402
|
||||
|
||||
|
||||
.SC14402
|
||||
|
||||
; MEMORY MAP
|
||||
area DATA SRAM 0xEA00:0xEC00 Sequencer RAM
|
||||
area DATA IRAM 0xEC00:0xF400 Internal RAM
|
||||
area DATA DRAM 0xF400:0xFBFE Data RAM
|
||||
area DATA FSR 0xFBFE:0x10000 Special Function Register
|
||||
|
||||
; Interrupt and reset vector assignments
|
||||
interrupt RESET_ 0x0000 RESET
|
||||
interrupt NMI_ 0x0004 NMI
|
||||
interrupt TRAP_SVC_ 0x000A Trap SVC
|
||||
interrupt TRAP_DVZ_ 0x000C Trap DVZ
|
||||
interrupt TRAP_FLG_ 0x000E Trap FLG
|
||||
interrupt TRAP_BPT_ 0x0010 Trap BPT
|
||||
interrupt TRAP_TRC_ 0x0012 Trap TRC
|
||||
interrupt TRAP_UND_ 0x0014 Trap UND
|
||||
interrupt ISE_ 0x001E ISE
|
||||
interrupt IRQ0_ 0x0020 SW INT
|
||||
interrupt IRQ1_ 0x0022 Keyboard IRQ
|
||||
interrupt IRQ2_ 0x0024 UART IRQ
|
||||
interrupt IRQ3_ 0x0026 Timer 0 IRQ
|
||||
interrupt IRQ4_ 0x0028 Timer 1 IRQ
|
||||
interrupt IRQ5_ 0x002A Clk 100 IRQ
|
||||
interrupt IRQ6_ 0x002C DIP IRQ
|
||||
|
||||
; INPUT/OUTPUT
|
||||
DIPPC 0xFBFE DIP Programm Counter
|
||||
DIPCTRL 0xFBFF DIP Controll
|
||||
INTRESET 0xFF02 Reset Interrupt
|
||||
INTSET 0xFF03 Set Interrupt
|
||||
SWINTPRI 0xFF04 SW INT Priority
|
||||
KBINTPRI 0xFF05 KB INT Priority
|
||||
UARTINTPRI 0xFF06 UART INT Priority
|
||||
T0INTPRI 0xFF07 T0 INT Priority
|
||||
T1INTPRI 0xFF08 T1 INT Priority
|
||||
CLKINTPRI 0xFF09 CLK100 INT Priority
|
||||
DIPINTPRI 0xFF0A DIP INT Priority
|
||||
P0DATA 0xFF10 Port 0
|
||||
P0SET 0xFF11 Port 0 Set Bit
|
||||
P0RESET 0xFF12 Port 0 Reset Bit
|
||||
P0DIR 0xFF13 Port 0 Direction
|
||||
P0UARTCTL 0xFF14 Port 0 UART Controll
|
||||
P0UARTDATA 0xFF15 Port 0 UART Data Register
|
||||
P0ENV 0xFF16 Port 0 Environ
|
||||
P0TEST 0xFF17 Port 0 ADPCM/CODEC Testpoints
|
||||
P1DATA 0xFF20 Port 1
|
||||
P1SET 0xFF21 Port 1 Set Bit
|
||||
P1RESET 0xFF22 Port 1 Reset Bit
|
||||
P1DIR 0xFF23 Port 1 Direction
|
||||
P1INTENABLE 0xFF24 Port 1 Interrupt Enable
|
||||
P1FILTER 0xFF25 Port 1 debounce filter
|
||||
P2DATA 0xFF30 Port 2
|
||||
P2DIR 0xFF33 Port 2 Direction
|
||||
P2MODE 0xFF34 Port 2 Mode
|
||||
P2ADCCONTROLL 0xFF35 Port 2 ADC Controll
|
||||
P2ADCVALUE 0xFF36 Port 2 ADC Value
|
||||
P2DACVALUE 0xFF37 Port 2 DAC Value
|
||||
WTDG_RELOAD 0xFF40 Watchdog Reload
|
||||
T0RELOADMLO 0xFF42 Timer 0 Reload M Low
|
||||
T0RELOADMHI 0xFF43 Timer 0 Reload M Low
|
||||
T0RELOADNLO 0xFF44 Timer 0 Reload N Low
|
||||
T0RELOADNHI 0xFF45 Timer 0 Reload N Low
|
||||
T1RELOADMLO 0xFF46 Timer 1 Reload M Low
|
||||
T1RELOADMHI 0xFF47 Timer 1 Reload M Low
|
||||
T1RELOADNLO 0xFF48 Timer 1 Reload N Low
|
||||
T1RELOADNHI 0xFF49 Timer 1 Reload N Low
|
||||
TIMERCONTROLL 0xFF4A Timer Controll
|
||||
SBICLK 0xFF50 SBI Clock
|
||||
SBIBANK 0xFF51 SBI Bank
|
||||
SBIAUXCSLOW 0xFF52 SBI Aux chipselect controll low
|
||||
SBIAUXCSHIGH 0xFF53 SBI Aux chipselect controll high
|
||||
SBIAUXWAIT 0xFF54 SBI AUX Wait
|
||||
SBISETFREEZE 0xFF55 SBI Set Freeze
|
||||
SBIRESETFREEZE 0xFF56 SBI Reset Freeze
|
||||
DEBUGSFR 0xFF57 DEBUG Register
|
||||
|
||||
.CR16MCS9
|
||||
|
||||
; MEMORY MAP
|
||||
area CODE FLASH 0x0000:0xC000 Flash Program Memory
|
||||
area DATA SRAM 0xC000:0xCC00 Static RAM
|
||||
area DATA ISP 0xE000:0xE600 ISP Memory
|
||||
area DATA EEPROM 0xE800:0xF000 EEPROM
|
||||
area DATA EEPROM 0xF000:0xF080 EEPROM
|
||||
area DATA FSR 0xF400:0x10000 Peripherals
|
||||
|
||||
; Interrupt and reset vector assignments
|
||||
interrupt RESET_ 0x0000 RESET
|
||||
;interrupt NMI_ 0x0004 NMI
|
||||
;interrupt TRAP_SVC_ 0x000A Trap SVC
|
||||
;interrupt TRAP_DVZ_ 0x000C Trap DVZ
|
||||
;interrupt TRAP_FLG_ 0x000E Trap FLG
|
||||
;interrupt TRAP_BPT_ 0x0010 Trap BPT
|
||||
;interrupt TRAP_TRC_ 0x0012 Trap TRC
|
||||
;interrupt TRAP_UND_ 0x0014 Trap UND
|
||||
;interrupt ISE_ 0x001E ISE
|
||||
;interrupt IRQ0_ 0x0020 SW INT
|
||||
;interrupt IRQ1_ 0x0022 Keyboard IRQ
|
||||
;interrupt IRQ2_ 0x0024 UART IRQ
|
||||
;interrupt IRQ3_ 0x0026 Timer 0 IRQ
|
||||
;interrupt IRQ4_ 0x0028 Timer 1 IRQ
|
||||
;interrupt IRQ5_ 0x002A Clk 100 IRQ
|
||||
;interrupt IRQ6_ 0x002C DIP IRQ
|
||||
|
||||
; INPUT/OUTPUT
|
||||
BCFG 0xf900
|
||||
IOCFG 0xf902
|
||||
SZCFG0 0xf904
|
||||
SZCFG1 0xf906
|
||||
SZCFG2 0xf908
|
||||
MCFG 0xf910
|
||||
DBGCFG 0xf912
|
||||
MSTAT 0xf914
|
||||
TMODE 0xf920
|
||||
FLCTRL1 0xf930
|
||||
FLSEC 0xf932
|
||||
ISPKEY 0xf934
|
||||
FLCTRL2 0xf936
|
||||
DMCSR 0xf940
|
||||
DMPSLR 0xf942
|
||||
DMSTART 0xf944
|
||||
DMTRAN 0xf946
|
||||
DMPROG 0xf948
|
||||
DMERASE 0xf94a
|
||||
DMEND 0xf94c
|
||||
DMPCNT 0xf94e
|
||||
DMCNT 0xf950
|
||||
DMISTAT 0xf952
|
||||
DMKEY 0xf954
|
||||
FLCSR 0xf960
|
||||
FLPSLR 0xf962
|
||||
FLSTART 0xf964
|
||||
FLTRAN 0xf966
|
||||
FLPROG 0xf968
|
||||
FLERASE 0xf96a
|
||||
FLEND 0xf96c
|
||||
FLPCNT 0xf96e
|
||||
FLCNT1 0xf970
|
||||
FLCNT2 0xf972
|
||||
PGMKEY 0xf974
|
||||
PBDIR 0xfb00
|
||||
PBDIN 0xfb02
|
||||
PBDOUT 0xfb04
|
||||
PBWKPU 0xfb06
|
||||
PCDIR 0xfb10
|
||||
PCDIN 0xfb12
|
||||
PCDOUT 0xfb14
|
||||
PCWKPU 0xfb16
|
||||
PFALT 0xfd20
|
||||
PFDIR 0xfd22
|
||||
PFDIN 0xfd24
|
||||
PFDOUT 0xfd26
|
||||
PFWKPU 0xfd28
|
||||
PFSCHEN 0xfd2a
|
||||
PGALT 0xfca0
|
||||
PGDIR 0xfca2
|
||||
PGDIN 0xfca4
|
||||
PGDOUT 0xfca6
|
||||
PGWKPU 0xfca8
|
||||
PGSCHEN 0xfcaa
|
||||
PHALT 0xfcc0
|
||||
PHDIR 0xfcc2
|
||||
PHDIN 0xfcc4
|
||||
PHDOUT 0xfcc6
|
||||
PHWKPU 0xfcc8
|
||||
PIALT 0xfee0
|
||||
PIDIR 0xfee2
|
||||
PIDIN 0xfee4
|
||||
PIDOUT 0xfee6
|
||||
PIWKPU 0xfee8
|
||||
PISCHEN 0xfeea
|
||||
PLALT 0xff00
|
||||
PLDIR 0xff02
|
||||
PLDIN 0xff04
|
||||
PLDOUT 0xff06
|
||||
PLWKPU 0xff08
|
||||
PLSCHEN 0xff0a
|
||||
CRCTRL 0xfc40
|
||||
PRSSC 0xfc42
|
||||
PRSSC1 0xfc44
|
||||
PMCSR 0xfc60
|
||||
WKEDG 0xfc80
|
||||
WKENA 0xfc82
|
||||
WKICTL 0xfc84
|
||||
WKICTL2 0xfc86
|
||||
WKPND 0xfc88
|
||||
WKPCL 0xfc8a
|
||||
IVCT 0xfe00
|
||||
NMISTAT 0xfe02
|
||||
EXNMI 0xfe04
|
||||
NMIIMNTR 0xfe06
|
||||
ISTAT0 0xfe0a
|
||||
ISTAT1 0xfe0c
|
||||
IENAM0 0xfe0e
|
||||
IENAM1 0xfe10
|
||||
IDBG 0xfe1a
|
||||
ITEST0 0xfe1c
|
||||
ITEST1 0xfe1e
|
||||
U1TBUF 0xfe40
|
||||
U1RBUF 0xfe42
|
||||
U1ICTRL 0xfe44
|
||||
U1STAT 0xfe46
|
||||
U1FRS 0xfe48
|
||||
U1MDSL 0xfe4a
|
||||
U1BAUD 0xfe4c
|
||||
U1PSR 0xfe4e
|
||||
U2TBUF 0xfe80
|
||||
U2RBUF 0xfe82
|
||||
U2ICTRL 0xfe84
|
||||
U2STAT 0xfe86
|
||||
U2FRS 0xfe88
|
||||
U2MDSL 0xfe8a
|
||||
U2BAUD 0xfe8c
|
||||
U2PSR 0xfe8e
|
||||
ACBSDA 0xfec0
|
||||
ACBST 0xfec2
|
||||
ACBCST 0xfec4
|
||||
ACBCTL1 0xfec6
|
||||
ACBADDR 0xfec8
|
||||
ACBCTL2 0xfeca
|
||||
MWDAT 0xfe60
|
||||
MWCTL 0xfe62
|
||||
MWSTAT 0xfe64
|
||||
MWTEST 0xfe66
|
||||
TWCFG 0xff20
|
||||
TWCP 0xff22
|
||||
TWMT0 0xff24
|
||||
T0CSR 0xff26
|
||||
WDCNT 0xff28
|
||||
WDSDM 0xff2a
|
||||
T1CNT1 0xff40
|
||||
T1CRA 0xff42
|
||||
T1CRB 0xff44
|
||||
T1CNT2 0xff46
|
||||
T1PRSC 0xff48
|
||||
T1CKC 0xff4A
|
||||
T1CTRL 0xff4C
|
||||
T1ICTL 0xff4E
|
||||
T1ICLR 0xff50
|
||||
T2CNT1 0xff60
|
||||
T2CRA 0xff62
|
||||
T2CRB 0xff64
|
||||
T2CNT2 0xff66
|
||||
T2PRSC 0xff68
|
||||
T2CKC 0xff6A
|
||||
T2CTRL 0xff6C
|
||||
T2ICTL 0xff6E
|
||||
T2ICLR 0xff70
|
||||
MODE 0xff80
|
||||
IO1CTL 0xff82
|
||||
IO2CTL 0xff84
|
||||
INTCTL 0xff86
|
||||
INTPND 0xff88
|
||||
CLK1PS 0xff8a
|
||||
COUNT1 0xff8c
|
||||
PERCAP1 0xff8e
|
||||
DTYCAP1 0xff90
|
||||
COUNT2 0xff92
|
||||
PERCAP2 0xff94
|
||||
DTYCAP2 0xff96
|
||||
CLK2PS 0xff98
|
||||
COUNT3 0xff9a
|
||||
PERCAP3 0xff9c
|
||||
DTYCAP3 0xff9e
|
||||
COUNT4 0xffa0
|
||||
PERCAP4 0xffa2
|
||||
DTYCAP4 0xffa4
|
||||
ADCST 0xffC0
|
||||
ADCCNT1 0xffC2
|
||||
ADCCNT2 0xffC4
|
||||
ADCCNT3 0xffC6
|
||||
ADCENG 0xffC8
|
||||
ADDATA0 0xffCA
|
||||
ADDATA1 0xffCC
|
||||
ADDATA2 0xffCE
|
||||
ADDATA3 0xffD0
|
||||
ACMP 0xffe0
|
||||
CMB0_CNTSTAT 0xf400
|
||||
CMB0_TSTP 0xf402
|
||||
CMB0_DATA3 0xf404
|
||||
CMB0_DATA2 0xf406
|
||||
CMB0_DATA1 0xf408
|
||||
CMB0_DATA0 0xf40a
|
||||
CMB0_ID0 0xf40c
|
||||
CMB0_ID1 0xf40e
|
||||
CMB1 0xf410
|
||||
CMB2 0xf420
|
||||
CMB3 0xf430
|
||||
CMB4 0xf440
|
||||
CMB5 0xf450
|
||||
CMB6 0xf460
|
||||
CMB7 0xf470
|
||||
CMB8 0xf480
|
||||
CMB9 0xf490
|
||||
CMB10 0xf4a0
|
||||
CMB11 0xf4b0
|
||||
CMB12 0xf4c0
|
||||
CMB13 0xf4d0
|
||||
CMB14 0xf4e0
|
||||
CMB15 0xf4f0
|
||||
CGCR 0xf500
|
||||
CTIM 0xf502
|
||||
GMSKX 0xf504
|
||||
GMSKB 0xf506
|
||||
BMSKX 0xf508
|
||||
BMSKB 0xf50a
|
||||
CIEN 0xf50c
|
||||
CIPND 0xf50e
|
||||
CICLR 0xf510
|
||||
CICEN 0xf512
|
||||
CSTPND 0xf514
|
||||
CANEC 0xf516
|
||||
CEDIAG 0xf518
|
||||
CTMR 0xf51a
|
||||
BSPD 0xf51c
|
||||
RTDIAG 0xf51e
|
||||
59
idasdk75/module/cr16/cr16.hpp
Normal file
59
idasdk75/module/cr16/cr16.hpp
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#ifndef _CR16_HPP
|
||||
#define _CR16_HPP
|
||||
|
||||
#include <ida.hpp>
|
||||
#include <idp.hpp>
|
||||
|
||||
#include "../idaidp.hpp"
|
||||
#define near
|
||||
#define far
|
||||
#include "ins.hpp"
|
||||
#include "../iohandler.hpp"
|
||||
|
||||
// ============================================================
|
||||
// specflags1 bits
|
||||
//-----------------------------------------------
|
||||
#define URR_PAIR (0x01) // indirect reference via reg pair
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// processor registers
|
||||
enum CR16_registers
|
||||
{
|
||||
rNULLReg,
|
||||
rR0, rR1, rR2, rR3, rR4, rR5, rR6, rR7,
|
||||
rR8, rR9, rR10, rR11, rR12, rR13, rRA, rSP,
|
||||
// special registers
|
||||
rPC, rISP, rINTBASE, rPSR, rCFG, rDSR, rDCR,
|
||||
rCARL, rCARH, rINTBASEL, rINTBASEH,
|
||||
rVcs, rVds
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
int idaapi CR16_ana(insn_t *_insn);
|
||||
int idaapi CR16_emu(const insn_t &insn);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
struct cr16_t : public procmod_t
|
||||
{
|
||||
netnode helper;
|
||||
iohandler_t ioh = iohandler_t(helper);
|
||||
bool flow = false; // flow stop flag
|
||||
|
||||
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
|
||||
|
||||
void CR16_header(outctx_t &ctx);
|
||||
void handle_operand(const insn_t &insn, const op_t &x, bool is_forced, bool isload);
|
||||
int CR16_emu(const insn_t &insn);
|
||||
|
||||
void CR16_segstart(outctx_t &ctx, segment_t *Sarea) const;
|
||||
void CR16_footer(outctx_t &ctx) const;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
103
idasdk75/module/cr16/emu.cpp
Normal file
103
idasdk75/module/cr16/emu.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "cr16.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// handle using/changing of operands
|
||||
void cr16_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 )
|
||||
{
|
||||
// nothing to do
|
||||
case o_void:
|
||||
case o_reg:
|
||||
case o_displ:
|
||||
break;
|
||||
|
||||
// immediate operand
|
||||
case o_imm:
|
||||
// can't be changed
|
||||
if ( !isload )
|
||||
goto badTouch;
|
||||
set_immd(insn.ea);
|
||||
// if not forced and marked as offset
|
||||
if ( !is_forced && is_off(get_flags(insn.ea), x.n) )
|
||||
{
|
||||
// it's an offset
|
||||
if ( x.dtype == dt_word )
|
||||
ea &= 0xFFFF;
|
||||
else if ( x.dtype == dt_byte )
|
||||
ea &= 0xFF;
|
||||
insn.add_dref(ea, x.offb, dr_O);
|
||||
}
|
||||
break;
|
||||
|
||||
// jump or call
|
||||
case o_near:
|
||||
if ( has_insn_feature(insn.itype, CF_CALL) )
|
||||
{
|
||||
// add cross-reference
|
||||
insn.add_cref(ea, x.offb, fl_CN);
|
||||
// doesn't return?
|
||||
flow = func_does_return(ea);
|
||||
}
|
||||
else
|
||||
{
|
||||
insn.add_cref(ea, x.offb, fl_JN);
|
||||
}
|
||||
break;
|
||||
|
||||
// memory reference
|
||||
case o_mem:
|
||||
// make data at target address
|
||||
insn.create_op_data(ea, x);
|
||||
// add xref to memory
|
||||
insn.add_dref(ea, x.offb, isload ? dr_R : dr_W);
|
||||
break;
|
||||
|
||||
// other - report error
|
||||
default:
|
||||
badTouch:
|
||||
warning("%a %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), x.n, x.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// emulator
|
||||
int cr16_t::CR16_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);
|
||||
|
||||
flow = ((Feature & CF_STOP) == 0);
|
||||
|
||||
// handle reads
|
||||
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_JUMP )
|
||||
remember_problem(PR_JUMP, insn.ea);
|
||||
|
||||
// handle writes
|
||||
if ( Feature & CF_CHG1 )
|
||||
handle_operand(insn, insn.Op1, flag1, false);
|
||||
if ( Feature & CF_CHG2 )
|
||||
handle_operand(insn, insn.Op2, flag2, false);
|
||||
// if not stopping, add flow xref
|
||||
if ( flow )
|
||||
add_cref(insn.ea, insn.ea + insn.size, fl_F);
|
||||
|
||||
return 1;
|
||||
}
|
||||
128
idasdk75/module/cr16/ins.cpp
Normal file
128
idasdk75/module/cr16/ins.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "cr16.hpp"
|
||||
|
||||
// NB! word versions must follow byte versions
|
||||
// this is done to simplify decoding in ana.c
|
||||
const instruc_t Instructions[] =
|
||||
{
|
||||
{ "", 0 },
|
||||
{ "addb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "addw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "addub", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "adduw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "addcb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "addcw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "andb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "andw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "ashub", CF_USE1|CF_USE2|CF_CHG2|CF_SHFT },
|
||||
{ "ashuw", CF_USE1|CF_USE2|CF_CHG2|CF_SHFT },
|
||||
{ "beq", CF_USE1|CF_JUMP },
|
||||
{ "bne", CF_USE1|CF_JUMP },
|
||||
{ "bcs", CF_USE1|CF_JUMP },
|
||||
{ "bcc", CF_USE1|CF_JUMP },
|
||||
{ "bhi", CF_USE1|CF_JUMP },
|
||||
{ "bls", CF_USE1|CF_JUMP },
|
||||
{ "bgt", CF_USE1|CF_JUMP },
|
||||
{ "ble", CF_USE1|CF_JUMP },
|
||||
{ "bfs", CF_USE1|CF_JUMP },
|
||||
{ "bfc", CF_USE1|CF_JUMP },
|
||||
{ "blo", CF_USE1|CF_JUMP },
|
||||
{ "bhs", CF_USE1|CF_JUMP },
|
||||
{ "blt", CF_USE1|CF_JUMP },
|
||||
{ "bge", CF_USE1|CF_JUMP },
|
||||
{ "br", CF_USE1|CF_JUMP|CF_STOP },
|
||||
{ "bal", CF_USE1|CF_CHG1|CF_USE2|CF_CALL },
|
||||
{ "cmpb", CF_USE1|CF_USE2 },
|
||||
{ "cmpw", CF_USE1|CF_USE2 },
|
||||
{ "beq1b", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "beq1w", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "beq0b", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "beq0w", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "bne1b", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "bne1w", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "bne0b", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "bne0w", CF_USE1|CF_USE2|CF_JUMP },
|
||||
{ "di", 0 },
|
||||
{ "ei", 0 },
|
||||
{ "excp", CF_USE1 },
|
||||
{ "jeq", CF_USE1|CF_JUMP },
|
||||
{ "jne", CF_USE1|CF_JUMP },
|
||||
{ "jcs", CF_USE1|CF_JUMP },
|
||||
{ "jcc", CF_USE1|CF_JUMP },
|
||||
{ "jhi", CF_USE1|CF_JUMP },
|
||||
{ "jls", CF_USE1|CF_JUMP },
|
||||
{ "jgt", CF_USE1|CF_JUMP },
|
||||
{ "jle", CF_USE1|CF_JUMP },
|
||||
{ "jfs", CF_USE1|CF_JUMP },
|
||||
{ "jfc", CF_USE1|CF_JUMP },
|
||||
{ "jlo", CF_USE1|CF_JUMP },
|
||||
{ "jhs", CF_USE1|CF_JUMP },
|
||||
{ "jlt", CF_USE1|CF_JUMP },
|
||||
{ "jge", CF_USE1|CF_JUMP },
|
||||
{ "jump", CF_USE1|CF_JUMP|CF_STOP },
|
||||
{ "jal", CF_USE1|CF_CHG1|CF_USE2|CF_CALL },
|
||||
{ "loadb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "loadw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "loadm", CF_USE1 },
|
||||
{ "lpr", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "lshb", CF_USE1|CF_USE2|CF_CHG2|CF_SHFT },
|
||||
{ "lshw", CF_USE1|CF_USE2|CF_CHG2|CF_SHFT },
|
||||
{ "movb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "movw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "movxb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "movzb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "movd", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "mulb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "mulw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "mulsb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "mulsw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "muluw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "nop", 0 },
|
||||
{ "orb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "orw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "push", CF_USE1|CF_USE2 },
|
||||
{ "pop", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "popret", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "retx", CF_STOP },
|
||||
{ "seq", CF_USE1|CF_CHG1 },
|
||||
{ "sne", CF_USE1|CF_CHG1 },
|
||||
{ "scs", CF_USE1|CF_CHG1 },
|
||||
{ "scc", CF_USE1|CF_CHG1 },
|
||||
{ "shi", CF_USE1|CF_CHG1 },
|
||||
{ "sls", CF_USE1|CF_CHG1 },
|
||||
{ "sgt", CF_USE1|CF_CHG1 },
|
||||
{ "sle", CF_USE1|CF_CHG1 },
|
||||
{ "sfs", CF_USE1|CF_CHG1 },
|
||||
{ "sfc", CF_USE1|CF_CHG1 },
|
||||
{ "slo", CF_USE1|CF_CHG1 },
|
||||
{ "shs", CF_USE1|CF_CHG1 },
|
||||
{ "slt", CF_USE1|CF_CHG1 },
|
||||
{ "sge", CF_USE1|CF_CHG1 },
|
||||
{ "spr", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "storb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "storw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "storm", CF_USE1 },
|
||||
{ "subb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "subw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "subcb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "subcw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "tbit", CF_USE1|CF_USE2 },
|
||||
{ "tbitb", CF_USE1|CF_USE2 },
|
||||
{ "tbitw", CF_USE1|CF_USE2 },
|
||||
{ "sbitb", CF_USE1|CF_USE2 },
|
||||
{ "sbitw", CF_USE1|CF_USE2 },
|
||||
{ "cbitb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "cbitw", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "wait", 0 },
|
||||
{ "eiwait", 0 },
|
||||
{ "xorb", CF_USE1|CF_USE2|CF_CHG2 },
|
||||
{ "xorw", CF_USE1|CF_USE2|CF_CHG2 }
|
||||
};
|
||||
|
||||
CASSERT(qnumber(Instructions) == CR16_last);
|
||||
136
idasdk75/module/cr16/ins.hpp
Normal file
136
idasdk75/module/cr16/ins.hpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-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)
|
||||
{
|
||||
CR16_null = 0, // Unknown Operation
|
||||
CR16_addb,
|
||||
CR16_addw,
|
||||
CR16_addub,
|
||||
CR16_adduw,
|
||||
CR16_addcb,
|
||||
CR16_addcw,
|
||||
CR16_andb,
|
||||
CR16_andw,
|
||||
CR16_ashub,
|
||||
CR16_ashuw,
|
||||
// !!! don't change sequence !!!
|
||||
CR16_beq,
|
||||
CR16_bne,
|
||||
CR16_bcs,
|
||||
CR16_bcc,
|
||||
CR16_bhi,
|
||||
CR16_bls,
|
||||
CR16_bgt,
|
||||
CR16_ble,
|
||||
CR16_bfs,
|
||||
CR16_bfc,
|
||||
CR16_blo,
|
||||
CR16_bhs,
|
||||
CR16_blt,
|
||||
CR16_bge,
|
||||
CR16_br,
|
||||
//----------------------------
|
||||
CR16_bal,
|
||||
CR16_cmpb,
|
||||
CR16_cmpw,
|
||||
CR16_beq1b,
|
||||
CR16_beq1w,
|
||||
CR16_beq0b,
|
||||
CR16_beq0w,
|
||||
CR16_bne1b,
|
||||
CR16_bne1w,
|
||||
CR16_bne0b,
|
||||
CR16_bne0w,
|
||||
CR16_di,
|
||||
CR16_ei,
|
||||
CR16_excp,
|
||||
// !!! don't change sequence !!!
|
||||
CR16_jeq,
|
||||
CR16_jne,
|
||||
CR16_jcs,
|
||||
CR16_jcc,
|
||||
CR16_jhi,
|
||||
CR16_jls,
|
||||
CR16_jgt,
|
||||
CR16_jle,
|
||||
CR16_jfs,
|
||||
CR16_jfc,
|
||||
CR16_jlo,
|
||||
CR16_jhs,
|
||||
CR16_jlt,
|
||||
CR16_jge,
|
||||
CR16_jump,
|
||||
//----------------------------
|
||||
CR16_jal,
|
||||
CR16_loadb,
|
||||
CR16_loadw,
|
||||
CR16_loadm,
|
||||
CR16_lpr,
|
||||
CR16_lshb,
|
||||
CR16_lshw,
|
||||
CR16_movb,
|
||||
CR16_movw,
|
||||
CR16_movxb,
|
||||
CR16_movzb,
|
||||
CR16_movd,
|
||||
CR16_mulb,
|
||||
CR16_mulw,
|
||||
CR16_mulsb,
|
||||
CR16_mulsw,
|
||||
CR16_muluw,
|
||||
CR16_nop,
|
||||
CR16_orb,
|
||||
CR16_orw,
|
||||
CR16_push,
|
||||
CR16_pop,
|
||||
CR16_popret,
|
||||
CR16_retx,
|
||||
// !!! don't change sequence !!!
|
||||
CR16_seq,
|
||||
CR16_sne,
|
||||
CR16_scs,
|
||||
CR16_scc,
|
||||
CR16_shi,
|
||||
CR16_sls,
|
||||
CR16_sgt,
|
||||
CR16_sle,
|
||||
CR16_sfs,
|
||||
CR16_sfc,
|
||||
CR16_slo,
|
||||
CR16_shs,
|
||||
CR16_slt,
|
||||
CR16_sge,
|
||||
//----------------------------
|
||||
CR16_spr,
|
||||
CR16_storb,
|
||||
CR16_storw,
|
||||
CR16_storm,
|
||||
CR16_subb,
|
||||
CR16_subw,
|
||||
CR16_subcb,
|
||||
CR16_subcw,
|
||||
CR16_tbit,
|
||||
CR16_tbitb,
|
||||
CR16_tbitw,
|
||||
CR16_sbitb,
|
||||
CR16_sbitw,
|
||||
CR16_cbitb,
|
||||
CR16_cbitw,
|
||||
CR16_wait,
|
||||
CR16_eiwait,
|
||||
CR16_xorb,
|
||||
CR16_xorw,
|
||||
CR16_last
|
||||
};
|
||||
|
||||
#endif
|
||||
46
idasdk75/module/cr16/makefile
Normal file
46
idasdk75/module/cr16/makefile
Normal file
@@ -0,0 +1,46 @@
|
||||
PROC=cr16
|
||||
CONFIGS=cr16.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)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 cr16.hpp 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)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 \
|
||||
cr16.hpp emu.cpp ins.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)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 \
|
||||
cr16.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)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 \
|
||||
cr16.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)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 cr16.hpp ins.hpp reg.cpp
|
||||
195
idasdk75/module/cr16/out.cpp
Normal file
195
idasdk75/module/cr16/out.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "cr16.hpp"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
class out_CR16_t : public outctx_t
|
||||
{
|
||||
out_CR16_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_CR16_t) == sizeof(outctx_t));
|
||||
|
||||
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_CR16_t)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
void out_CR16_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);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// output one operand
|
||||
bool out_CR16_t::out_operand(const op_t &x)
|
||||
{
|
||||
int flags;
|
||||
switch ( x.type )
|
||||
{
|
||||
case o_displ:
|
||||
//out_value(insn, x, OOF_ADDR|OOFS_IFSIGN|OOF_SIGNED|OOFW_32);
|
||||
out_value(x, /*OOFS_NOSIGN | */ OOF_ADDR | OOF_SIGNED | OOFW_IMM);
|
||||
out_symbol('(');
|
||||
if ( x.specflag1 & URR_PAIR )
|
||||
{
|
||||
out_register(ph.reg_names[x.reg + 1]);
|
||||
out_symbol(',');
|
||||
out_register(ph.reg_names[x.reg]);
|
||||
}
|
||||
else
|
||||
{
|
||||
out_register(ph.reg_names[x.reg]);
|
||||
}
|
||||
out_symbol(')');
|
||||
break;
|
||||
|
||||
case o_reg:
|
||||
if ( x.specflag1 & URR_PAIR )
|
||||
{
|
||||
out_symbol('(');
|
||||
out_register(ph.reg_names[x.reg + 1]);
|
||||
out_symbol(',');
|
||||
out_register(ph.reg_names[x.reg]);
|
||||
out_symbol(')');
|
||||
}
|
||||
else
|
||||
{
|
||||
out_register(ph.reg_names[x.reg]);
|
||||
}
|
||||
break;
|
||||
|
||||
case o_imm:
|
||||
out_symbol('$');
|
||||
flags = /*OOFS_NOSIGN | OOF_SIGNED | */OOFW_IMM;
|
||||
switch ( insn.itype )
|
||||
{
|
||||
case CR16_addb:
|
||||
case CR16_addw:
|
||||
case CR16_addub:
|
||||
case CR16_adduw:
|
||||
case CR16_addcb:
|
||||
case CR16_addcw:
|
||||
case CR16_ashub:
|
||||
case CR16_ashuw:
|
||||
case CR16_lshb:
|
||||
case CR16_lshw:
|
||||
flags |= OOF_SIGNED;
|
||||
break;
|
||||
}
|
||||
out_value(x, flags);
|
||||
break;
|
||||
|
||||
case o_near:
|
||||
OutVarName(x);
|
||||
break;
|
||||
|
||||
case o_mem:
|
||||
OutVarName(x);
|
||||
break;
|
||||
|
||||
case o_void:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
warning("out: %a: bad optype %d", insn.ea, x.type);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// main output function
|
||||
void out_CR16_t::out_insn(void)
|
||||
{
|
||||
// print mnemonic
|
||||
out_mnemonic();
|
||||
|
||||
// print first operand
|
||||
if ( insn.Op1.type != o_void )
|
||||
out_one_operand(0);
|
||||
|
||||
// print second operand
|
||||
if ( insn.Op2.type != o_void )
|
||||
{
|
||||
out_symbol(',');
|
||||
out_char(' ');
|
||||
out_one_operand(1);
|
||||
}
|
||||
|
||||
out_immchar_cmts();
|
||||
flush_outbuf();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// header of the listing
|
||||
void cr16_t::CR16_header(outctx_t &ctx)
|
||||
{
|
||||
ctx.gen_header(GH_PRINT_ALL_BUT_BYTESEX, ioh.device.c_str(), ioh.deviceparams.c_str());
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// segment start
|
||||
//lint -esym(1764, ctx) could be made const
|
||||
//lint -esym(818, Sarea) could be made const
|
||||
void cr16_t::CR16_segstart(outctx_t &ctx, segment_t *Sarea) const
|
||||
{
|
||||
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 offset not zero, print it (ORG XXXX)
|
||||
if ( (inf_get_outflags() & OFLG_GEN_ORG) != 0 )
|
||||
{
|
||||
ea_t org = ctx.insn_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 cr16_t::CR16_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");
|
||||
}
|
||||
}
|
||||
246
idasdk75/module/cr16/reg.cpp
Normal file
246
idasdk75/module/cr16/reg.cpp
Normal file
@@ -0,0 +1,246 @@
|
||||
|
||||
/*
|
||||
* National Semiconductor Corporation CR16 processor module for IDA.
|
||||
* Copyright (c) 2002-2006 Konstantin Norvatoff, <konnor@bk.ru>
|
||||
* Freeware.
|
||||
*/
|
||||
|
||||
#include "cr16.hpp"
|
||||
#include <diskio.hpp>
|
||||
#include <segregs.hpp>
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// list of registers
|
||||
static const char *const RegNames[] =
|
||||
{
|
||||
// empty
|
||||
"",
|
||||
// general purpose
|
||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
||||
"r8", "r9", "r10", "r11", "r12", "r13", "ra", "sp",
|
||||
// special
|
||||
"pc", "isp", "intbase", "psr", "cfg", "dsr", "dcr", "carl", "carh",
|
||||
"intbaseh", "intbasel",
|
||||
|
||||
// pseudo segments
|
||||
"cs", "ds"
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// 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(new cr16_t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
ssize_t idaapi cr16_t::on_event(ssize_t msgid, va_list va)
|
||||
{
|
||||
switch ( msgid )
|
||||
{
|
||||
case processor_t::ev_init:
|
||||
inf_set_be(false);
|
||||
inf_set_gen_lzero(true);
|
||||
helper.create("$ CR16");
|
||||
break;
|
||||
|
||||
case processor_t::ev_term:
|
||||
ioh.ports.clear();
|
||||
break;
|
||||
|
||||
case processor_t::ev_newfile:
|
||||
// ask for a processor from the config file
|
||||
// use it to handle ports and registers
|
||||
{
|
||||
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:
|
||||
//fall through
|
||||
case processor_t::ev_oldfile:
|
||||
ioh.restore_device();
|
||||
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 *);
|
||||
CR16_header(*ctx);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_out_footer:
|
||||
{
|
||||
outctx_t *ctx = va_arg(va, outctx_t *);
|
||||
CR16_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 *);
|
||||
CR16_segstart(*ctx, seg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
case processor_t::ev_ana_insn:
|
||||
{
|
||||
insn_t *out = va_arg(va, insn_t *);
|
||||
return CR16_ana(out);
|
||||
}
|
||||
|
||||
case processor_t::ev_emu_insn:
|
||||
{
|
||||
const insn_t *insn = va_arg(va, const insn_t *);
|
||||
return CR16_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;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// PseudoSam
|
||||
//-----------------------------------------------------------------------
|
||||
static const asm_t pseudosam =
|
||||
{
|
||||
AS_COLON | AS_UDATA | ASH_HEXF3 | ASD_DECF0,
|
||||
// user flags
|
||||
0,
|
||||
"Generic CR16 assembler", // title
|
||||
0, // help id
|
||||
NULL, // header
|
||||
"org", // ORG directive
|
||||
"end", // end directive
|
||||
|
||||
";", // comment
|
||||
'"', // string delimiter
|
||||
'\'', // character constant
|
||||
"\\\"'", // special characters
|
||||
|
||||
"db", // ascii string directive
|
||||
".byte", // byte directive
|
||||
".word", // word directive
|
||||
NULL, // dword (4 bytes)
|
||||
NULL, // qword (8 bytes)
|
||||
NULL, // oword (16 bytes)
|
||||
NULL, // float (4 bytes)
|
||||
NULL, // double (8 bytes)
|
||||
NULL, // 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) symbol in assembler
|
||||
NULL, // Generate function header lines
|
||||
NULL, // Generate function footer lines
|
||||
NULL, // public
|
||||
NULL, // weak
|
||||
NULL, // extrn
|
||||
NULL, // comm
|
||||
NULL, // Get name of type of item at ea or id
|
||||
".ALIGN", // align
|
||||
'(', ')', // 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 "NSC CR16:"
|
||||
|
||||
// short names
|
||||
static const char *const shnames[] = { "CR16", NULL };
|
||||
|
||||
// long names
|
||||
static const char *const lnames[] = { FAMILY"NSC CR16", NULL };
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// return instructions
|
||||
static const uchar retcode_1[] = { 0x00, 0x0B }; // RTS
|
||||
|
||||
static const bytes_t retcodes[] =
|
||||
{
|
||||
{ sizeof(retcode_1), retcode_1 },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Processor Definition
|
||||
//-----------------------------------------------------------------------
|
||||
processor_t LPH =
|
||||
{
|
||||
IDP_INTERFACE_VERSION, // version
|
||||
PLFM_CR16, // processor ID
|
||||
// flag
|
||||
PR_USE32
|
||||
| PR_BINMEM
|
||||
| PR_SEGTRANS,
|
||||
// flag2
|
||||
0,
|
||||
8, // 8 bits in a byte for code segments
|
||||
8, // 8 bits in a byte for data segments
|
||||
|
||||
shnames, // short processor names (NULL terminated)
|
||||
lnames, // long processor names (NULL terminated)
|
||||
|
||||
asms, // assemblers
|
||||
|
||||
notify, // Event notification handler
|
||||
|
||||
RegNames, // Regsiter names
|
||||
qnumber(RegNames), // Number of registers
|
||||
|
||||
rVcs, rVds,
|
||||
2, // size of a segment register
|
||||
rVcs, rVds,
|
||||
NULL, // Array of typical code start sequences
|
||||
retcodes, // Array of 'return' instruction opcodes
|
||||
0, CR16_last, // icode of the first and the last instruction
|
||||
Instructions, // instruc
|
||||
3, // Size of long double (tbyte) for this processor - 24 bits
|
||||
{0, 0, 0, 0}, // Number of digits in floating numbers after the decimal point
|
||||
0, // Icode of return instruction
|
||||
NULL, // micro virtual mashine
|
||||
};
|
||||
Reference in New Issue
Block a user