update to ida 7.6, add builds

This commit is contained in:
2021-10-31 21:20:46 +02:00
parent e0e0f2be99
commit b1809fe2d9
1408 changed files with 279193 additions and 302468 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,94 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#ifndef _NEC78K0S_HPP
#define _NEC78K0S_HPP
#include "../idaidp.hpp"
#include "ins.hpp"
#include "../iohandler.hpp"
struct nec78k0s_t : public procmod_t
{
netnode helper;
iohandler_t ioh = iohandler_t(helper);
bool flow = false;
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
bool nec_find_ioport_bit(outctx_t &ctx, int port, int bit);
void nec78k0s_header(outctx_t &ctx);
int emu(const insn_t &insn);
void handle_operand(const op_t &x, bool forced_op, bool isload, const insn_t &insn);
void nec78k0s_footer(outctx_t &ctx) const;
void load_from_idb();
};
bool idaapi out_opnd(outctx_t &ctx, const op_t &x);
extern int data_id;
#define PROCMOD_NODE_NAME "$ 78k0s"
#define PROCMOD_NAME nec78k0s
#define UAS_NOSPA 0x0001 // no space after comma
//#define UAS_ZVBIT 0x0002 // '*' prefixes name in bit command
//#define UAS_AREAS 0x0004 // '.area' segment directive
//#define UAS_CCR 0x0008 // "ccr" register is named "cc"
// // "dpr" register is named "dp"
// // "pcr" register is named "pc"
//#define UAS_ORA 0x0010 // ORAA is named ORA
// // ORAB is named ORB
//#define UAS_CODE 0x0020 // "code", "data", "bss" directives
//#define UAS_AUTOPC 0x0040 // Automatic relative addressing by PC
// // (no need to substract PC value)
//#define UAS_ALL 0x0080 // "all" keyword is recognized as
// // a synonim for all registers
//#define UAS_OS9 0x0100 // has OS9 directive
//----------------------------------------------------------------------
// Redefine temporary names
//
#define exten segpref
#define xmode specflag1
#define prepost specflag2
#define addr16 specflag3
// bit operand
#define regmode specflag1
#define regdata specflag2
// callt
#define form specflag1
#define o_bit o_idpspec0
//------------------------------------------------------------------------
enum nec_registers { rX, rA, rC, rB, rE, rD, rL, rH, rAX, rBC, rDE, rHL,
rPSW, rSP, rS, rCC, rDPR,
bCY,
Rcs, Rds };
enum bitOper { SADDR=0, SFR, A, PSW, HL, CY };
//------------------------------------------------------------------------
extern qstring deviceparams;
extern qstring device;
struct ioport_bit_t;
bool nec_find_ioport_bit(outctx_t &ctx, int port, int bit);
uint32 Get_Data_16bits();
//------------------------------------------------------------------------
void idaapi nec78k0s_header(outctx_t &ctx);
void idaapi nec78k0s_footer(outctx_t &ctx);
void idaapi nec78k0s_segstart(outctx_t &ctx, segment_t *seg);
int idaapi ana(insn_t *_insn);
int idaapi emu(const insn_t &insn);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "78k_0s.hpp"
//------------------------------------------------------------------------
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 nec78k0s_t::handle_operand(const op_t &x, bool forced_op, bool isload, const insn_t &insn)
{
switch ( x.type )
{
case o_phrase:
case o_void:
case o_reg:
break;
case o_imm:
case o_displ:
set_immd(insn.ea);
if ( !forced_op )
{
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(get_flags(insn.ea), x.n) )
{
insn.add_off_drefs(x, dr_O, 0);
}
}
break;
case o_bit:
case o_mem:
DataSet(insn, x, map_code_ea(insn, x), isload);
break;
case o_near:
{
ea_t ea = to_ea(insn.cs, x.addr);
int iscall = has_insn_feature(insn.itype, CF_CALL);
insn.add_cref(ea, x.offb, iscall ? fl_CN : fl_JN);
if ( iscall )
flow = func_does_return(ea);
}
break;
default:
warning("%a: %s,%d: bad optype %d", insn.ea, insn.get_canon_mnem(ph), x.n, x.type);
break;
}
}
//----------------------------------------------------------------------
int nec78k0s_t::emu(const insn_t &insn)
{
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);
if ( Feature & CF_USE1 )
handle_operand(insn.Op1, flag1, 1, insn);
if ( Feature & CF_USE2 )
handle_operand(insn.Op2, flag2, 1, insn);
if ( Feature & CF_USE3 )
handle_operand(insn.Op3, flag3, 1, insn);
if ( Feature & CF_CHG1 )
handle_operand(insn.Op1, flag1, 0, insn);
if ( Feature & CF_CHG2 )
handle_operand(insn.Op2, flag2, 0, insn);
if ( Feature & CF_CHG3 )
handle_operand(insn.Op3, flag3, 0, insn);
if ( Feature & CF_JUMP )
remember_problem(PR_JUMP, insn.ea);
if ( flow )
add_cref(insn.ea, insn.ea + insn.size, fl_F);
return 1;
}

View File

@@ -0,0 +1,66 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include <ida.hpp>
#include <idp.hpp>
#include "ins.hpp"
//-----------------------------------------------------------------------
const instruc_t Instructions[] =
{
{ "", 0 }, // Unknown Operation
{ "cmp", CF_USE1 | CF_USE2 }, // Compare Byte Data Comparison
{ "xor", CF_CHG1 | CF_USE2 }, // Exclusive Or Exclusive Logical Sum of Byte Data
{ "and", CF_CHG1 | CF_USE2 }, // AND Logical Product of Byte Data
{ "or", CF_CHG1 | CF_USE2 }, // OR Logical Sum of Byte Data
{ "add", CF_CHG1 | CF_USE2 }, // ADD Byte Data Addition
{ "sub", CF_CHG1 | CF_USE2 }, // Subtract Byte Data Subtraction
{ "addc", CF_CHG1 | CF_USE2 }, // Add with Carry Addition of Byte Data with Carry
{ "subc", CF_CHG1 | CF_USE2 }, // Subtract with Carry Subtraction of Byte Data with Carry
{ "subw", CF_CHG1 | CF_USE2 }, // Subtract Word Data Subtraction
{ "addw", CF_CHG1 | CF_USE2 }, // Add Word Data Addition
{ "cmpw", CF_USE1 | CF_USE2 }, // Compare Word Data Comparison
{ "inc", CF_CHG1 }, // Increment Byte Data Increment
{ "dec", CF_CHG1 }, // Decrement Byte Data Decrement
{ "incw", CF_CHG1 }, // Increment Word Data Increment
{ "decw", CF_CHG1 }, // Decrement Word Data Decrement
{ "ror", CF_CHG1 }, // Rotate Right Byte Data Rotation to the Right
{ "rol", CF_CHG1 }, // Rotate Left Byte Data Rotation to the Left
{ "rorc", CF_CHG1 }, // Rotate Right with Carry Byte Data Rotation to the Right with Carry
{ "rolc", CF_CHG1 }, // Rotate Left with Carry Byte Data Rotation to the Left with Carry
{ "call", CF_USE1 | CF_CALL }, // CALL Subroutine Call (16 Bit Direct)
{ "callt", CF_USE1 | CF_CALL }, // Call Table Subroutine Call (Call Table Reference)
{ "ret", CF_STOP }, // Return from Subroutine
{ "reti", CF_STOP }, // Return from Interrupt / Return from Hardware Vectored Interrupt
{ "mov", CF_CHG1 | CF_USE2 }, // Move Byte Data Transfer
{ "xch", CF_CHG1 | CF_CHG2 }, // Exchange Byte Data Exchange
{ "xchw", CF_CHG1 | CF_CHG2 }, // Exchange Word Data Exchange
{ "set1", CF_CHG1 }, // Set Single Bit (Carry Flag) 1 Bit Data Set
{ "clr1", CF_CHG1 }, // Clear Single Bit (Carry Flag) 1 Bit Data Clear
{ "not1", CF_CHG1 }, // Not Single Bit (Carry Flag) 1 Bit Data Logical Negation
{ "push", CF_USE1 }, // Push
{ "pop", CF_CHG1 }, // Pop
{ "movw", CF_CHG1 | CF_USE2 }, // Move Word Data Transfer / Word Data Transfer with Stack Pointer
{ "br", CF_USE1 | CF_STOP }, // Unconditional Branch
{ "bc", CF_USE1 }, // Branch if Carry Conditional Branch with Carry Flag (CY = 1)
{ "bnc", CF_USE1 }, // Branch if Not Carry Conditional Branch with Carry Flag (CY = 0)
{ "bz", CF_USE1 }, // Branch if Zero Conditional Branch with Zero Flag (Z = 1)
{ "bnz", CF_USE1 }, // Branch if Not Zero Conditional Branch with Zero Flag (Z = 0)
{ "bt", CF_USE1 | CF_USE2 }, // Branch if True Conditional Branch by Bit Test (Byte Data Bit = 1)
{ "bf", CF_USE1 | CF_USE2 }, // Branch if False Conditional Branch by Bit Test (Byte Data Bit = 0)
{ "dbnz", CF_CHG1 | CF_USE2 }, // Decrement and Branch if Not Zero Conditional Loop (R1 != 0)
{ "nop", 0 }, // No Operation
{ "EI", 0 }, // Enable Interrupt
{ "DI", 0 }, // Disable Interrupt
{ "HALT", 0 }, // HALT Mode Set
{ "STOP", CF_STOP } // Stop Mode Set
};
//-----------------------------------------------------------------------
CASSERT(qnumber(Instructions) == NEC_78K_0S_last);

View File

@@ -0,0 +1,64 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2021 Hex-Rays
* ALL RIGHTS RESERVED.
*
*/
#ifndef __INSTRS_HPP
#define __INSTRS_HPP
extern const instruc_t Instructions[];
enum nameNum ENUM_SIZE(uint16)
{
NEC_78K_0S_null = 0, // Unknown Operation
NEC_78K_0S_cmp, // Compare Byte Data Comparison
NEC_78K_0S_xor, // Exclusive Or Exclusive Logical Sum of Byte Data
NEC_78K_0S_and, // AND Logical Product of Byte Data
NEC_78K_0S_or, // OR Logical Sum of Byte Data
NEC_78K_0S_add, // ADD Byte Data Addition
NEC_78K_0S_sub, // Subtract Byte Data Subtraction
NEC_78K_0S_addc, // Add with Carry Addition of Byte Data with Carry
NEC_78K_0S_subc, // Subtract with Carry Subtraction of Byte Data with Carry
NEC_78K_0S_subw, // Subtract Word Data Subtraction
NEC_78K_0S_addw, // Add Word Data Addition
NEC_78K_0S_cmpw, // Compare Word Data Comparison
NEC_78K_0S_inc, // Increment Byte Data Increment
NEC_78K_0S_dec, // Decrement Byte Data Decrement
NEC_78K_0S_incw, // Increment Word Data Increment
NEC_78K_0S_decw, // Decrement Word Data Decrement
NEC_78K_0S_ror, // Rotate Right Byte Data Rotation to the Right
NEC_78K_0S_rol, // Rotate Left Byte Data Rotation to the Left
NEC_78K_0S_rorc, // Rotate Right with Carry Byte Data Rotation to the Right with Carry
NEC_78K_0S_rolc, // Rotate Left with Carry Byte Data Rotation to the Left with Carry
NEC_78K_0S_call, // CALL Subroutine Call (16 Bit Direct)
NEC_78K_0S_callt, // Call Table Subroutine Call (Call Table Reference)
NEC_78K_0S_ret, // Return from Subroutine
NEC_78K_0S_reti, // Return from Interrupt / Return from Hardware Vectored Interrupt
NEC_78K_0S_mov, // Move Byte Data Transfer
NEC_78K_0S_xch, // Exchange Byte Data Exchange
NEC_78K_0S_xchw, // Exchange Word Data Exchange
NEC_78K_0S_set1, // Set Single Bit (Carry Flag) 1 Bit Data Set
NEC_78K_0S_clr1, // Clear Single Bit (Carry Flag) 1 Bit Data Clear
NEC_78K_0S_not1, // Not Single Bit (Carry Flag) 1 Bit Data Logical Negation
NEC_78K_0S_push, // Push
NEC_78K_0S_pop, // Pop
NEC_78K_0S_movw, // Move Word Data Transfer / Word Data Transfer with Stack Pointer
NEC_78K_0S_br, // Unconditional Branch
NEC_78K_0S_bc, // Branch if Carry Conditional Branch with Carry Flag (CY = 1)
NEC_78K_0S_bnc, // Branch if Not Carry Conditional Branch with Carry Flag (CY = 0)
NEC_78K_0S_bz, // Branch if Zero Conditional Branch with Zero Flag (Z = 1)
NEC_78K_0S_bnz, // Branch if Not Zero Conditional Branch with Zero Flag (Z = 0)
NEC_78K_0S_bt, // Branch if True Conditional Branch by Bit Test (Byte Data Bit = 1)
NEC_78K_0S_bf, // Branch if False Conditional Branch by Bit Test (Byte Data Bit = 0)
NEC_78K_0S_dbnz, // Decrement and Branch if Not Zero Conditional Loop (R1 != 0)
NEC_78K_0S_nop, // No Operation
NEC_78K_0S_EI, // Enable Interrupt
NEC_78K_0S_DI, // Disable Interrupt
NEC_78K_0S_HALT, // HALT Mode Set
NEC_78K_0S_STOP, // Stop Mode Set
NEC_78K_0S_last
};
#endif

View File

@@ -0,0 +1,52 @@
PROC=78k0s
CONFIGS=78k0s.cfg
include ../module.mak
# MAKEDEP dependency list ------------------
$(F)ana$(O) : $(I)auto.hpp $(I)bitrange.hpp $(I)bytes.hpp \
$(I)config.hpp $(I)diskio.hpp \
$(I)entry.hpp $(I)fpro.h $(I)funcs.hpp $(I)ida.hpp \
$(I)idp.hpp $(I)ieee.h $(I)kernwin.hpp $(I)lines.hpp \
$(I)llong.hpp $(I)loader.hpp \
$(I)nalt.hpp $(I)name.hpp \
$(I)netnode.hpp $(I)offset.hpp $(I)pro.h \
$(I)problems.hpp $(I)range.hpp $(I)segment.hpp \
$(I)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
78k_0s.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)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
78k_0s.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)ua.hpp $(I)xref.hpp ../idaidp.hpp ../iohandler.hpp \
78k_0s.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 78k_0s.hpp ins.hpp reg.cpp

View File

@@ -0,0 +1,232 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "78k_0s.hpp"
//----------------------------------------------------------------------
class out_nec78k0s_t : public outctx_t
{
out_nec78k0s_t(void) = delete; // not used
public:
void OutReg(int rgnum) { out_register(ph.reg_names[rgnum]); }
int OutVarName(const op_t &x, bool iscode);
bool out_operand(const op_t &x);
void out_insn(void);
};
CASSERT(sizeof(out_nec78k0s_t) == sizeof(outctx_t));
//----------------------------------------------------------------------
void idaapi out_insn(outctx_t &ctx)
{
out_nec78k0s_t *p = (out_nec78k0s_t *)&ctx;
p->out_insn();
}
bool idaapi out_opnd(outctx_t &ctx, const op_t &x)
{
out_nec78k0s_t *p = (out_nec78k0s_t *)&ctx;
return p->out_operand(x);
}
//----------------------------------------------------------------------
int out_nec78k0s_t::OutVarName(const op_t &x, bool iscode)
{
ushort addr = ushort(x.addr);
// get linear address
ea_t toea = map_ea(insn, addr, x.n, iscode);
// get its string representation
return out_name_expr(x, toea, x.addr);
}
//----------------------------------------------------------------------
bool out_nec78k0s_t::out_operand(const op_t &x)
{
switch ( x.type )
{
case o_void:
return 0;
case o_reg:
if ( x.prepost )
out_symbol('[');
OutReg(x.reg);
if ( x.xmode )
{
out_symbol('+');
out_value(x, OOF_ADDR | OOF_NUMBER | OOFW_8);
}
if ( x.prepost )
out_symbol(']');
break;
case o_phrase:
out_line(ph.reg_names[x.reg]);
break;
case o_bit:
switch ( x.reg )
{
case rPSW:
out_line("PSW.");
switch ( x.value )
{
case 0:
out_line("CY");
break;
case 4:
out_line("AC");
break;
case 6:
out_line("Z");
break;
case 7:
out_line("IE");
break;
default:
out_value(x, OOFW_IMM);
break;
}
break;
case rA:
out_line("A.");
out_char(char('0'+x.value));
break;
default:
if ( !OutVarName(x, true) )
out_value(x, OOF_ADDR | OOFW_16);
out_symbol('.');
// Look for a bit using its address
nec78k0s_t &pm = *static_cast<nec78k0s_t *>(procmod);
if ( !pm.nec_find_ioport_bit(*this, (int)x.addr, (int)x.value) )
out_char(char('0'+x.value)); // output data as immediate
break;
}
break;
case o_imm:
if ( !x.regmode )
{
out_symbol('#');
out_value(x, OOFW_IMM);
}
else
{
out_symbol('1');
}
break;
case o_mem:
// output a memory address (e.g. byte_98)
if ( x.addr16 )
out_symbol('!');
// output a name
if ( !OutVarName(x, false) )
out_value(x, OOF_ADDR | OOFW_16); // output just an address
break;
case o_near:
{
if ( x.addr16 )
out_symbol('!');
if ( x.form )
out_symbol('[');
// get linear address
ea_t v = to_ea(insn.cs,x.addr);
if ( !out_name_expr(x, v, x.addr) )
{
// print its value
out_value(x, OOF_ADDR | OOF_NUMBER | OOFW_16);
remember_problem(PR_NONAME, insn.ea);
}
if ( x.form )
out_symbol(']');
}
break;
default:
warning("out: %a: bad optype %d", insn.ip, x.type);
break;
}
return 1;
}
//----------------------------------------------------------------------
void out_nec78k0s_t::out_insn(void)
{
out_mnemonic();
out_one_operand(0);
// more operands?
if ( insn.Op2.type != o_void )
{
out_symbol(',');// print delimiter
// unless UAS_NOSPA is set, add a space
if ( !(ash.uflag & UAS_NOSPA) )
out_char(' ');
out_one_operand(1);
}
if ( insn.Op3.type != o_void )
{
out_symbol(',');
if ( !(ash.uflag & UAS_NOSPA) )
out_char(' ');
out_one_operand(2);
}
out_immchar_cmts();
flush_outbuf();
}
//--------------------------------------------------------------------------
void nec78k0s_t::nec78k0s_header(outctx_t &ctx)
{
ctx.gen_cmt_line("Processor: %s [%s]",
!ioh.device.empty()
? ioh.device.c_str()
: inf_get_procname().c_str(),
ioh.deviceparams.c_str());
ctx.gen_cmt_line("Target assebler: %s", ash.name);
if ( ash.header != NULL )
for ( const char *const *ptr=ash.header; *ptr != NULL; ptr++ )
ctx.flush_buf(*ptr, 0);
}
//--------------------------------------------------------------------------
void idaapi nec78k0s_segstart(outctx_t &, segment_t *)
{
}
//--------------------------------------------------------------------------
void nec78k0s_t::nec78k0s_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");
}
}

View File

@@ -0,0 +1,262 @@
/*
* Interactive disassembler (IDA).
* Copyright (c) 1990-2001 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* E-mail: ig@datarescue.com
*
*
*/
#include "78k_0s.hpp"
#include <segregs.hpp>
#include <diskio.hpp>
int data_id;
//----------------------------------------------------------------------
static const char *const RegNames[] =
{
"X", "A", "C", "B", "E", "D", "L", "H", "AX", "BC", "DE","HL",
"PSW", "SP", "s", "cc", "dpr",
"CY",
"cs", "ds"
};
//----------------------------------------------------------------------
static const asm_t nec78k0s =
{
AS_COLON | ASH_HEXF0 | ASD_DECF0 | ASO_OCTF0 | ASB_BINF4 | AS_N2CHR | AS_ONEDUP | AS_NOXRF,
UAS_NOSPA,
"NEC _78K_0S Assembler",
0,
NULL, // header
".org",
".end",
";", // comment string
'"', // string delimiter
'\'', // char delimiter
"'\"", // special symbols in char and string constants
".db", // ascii string directive
".db", // byte directive
".dw", // word directive
NULL, // 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 "NEC series:"
static const char *const shnames[] =
{
"78k0s",
NULL
};
static const char *const lnames[] =
{
FAMILY"NEC 78K/0S",
NULL
};
static const asm_t *const asms[] =
{
&nec78k0s,
NULL
};
//--------------------------------------------------------------------------
// return opcodes
static const uchar retcNEC78K0S_0[] = { 0x24 }; // reti
static const uchar retcNEC78K0S_1[] = { 0x20 }; // ret
static const bytes_t retcodes[] =
{
{ sizeof(retcNEC78K0S_0), retcNEC78K0S_0 },
{ sizeof(retcNEC78K0S_1), retcNEC78K0S_1 },
{ 0, NULL }
};
//------------------------------------------------------------------
bool nec78k0s_t::nec_find_ioport_bit(outctx_t &ctx, int port, int bit)
{
// find bit register in the ports list
const ioport_bit_t *b = find_ioport_bit(ioh.ports, port, bit);
if ( b != NULL && !b->name.empty() )
{
// output bit register name
ctx.out_line(b->name.c_str(), COLOR_IMPNAME);
return true;
}
return false;
}
//----------------------------------------------------------------------
void nec78k0s_t::load_from_idb()
{
ioh.restore_device();
}
//----------------------------------------------------------------------
// This old-style callback only returns the processor module object.
static ssize_t idaapi notify(void *, int msgid, va_list)
{
if ( msgid == processor_t::ev_get_procmod )
return size_t(SET_MODULE_DATA(nec78k0s_t));
return 0;
}
//----------------------------------------------------------------------
ssize_t idaapi nec78k0s_t::on_event(ssize_t msgid, va_list va)
{
switch ( msgid )
{
case processor_t::ev_init:
inf_set_be(false);
helper.create(PROCMOD_NODE_NAME);
break;
case processor_t::ev_term:
ioh.ports.clear();
clr_module_data(data_id);
break;
case processor_t::ev_newfile:
{
inf_set_gen_lzero(true);
char cfgfile[QMAXFILE];
ioh.get_cfg_filename(cfgfile, sizeof(cfgfile));
iohandler_t::parse_area_line0_t cb(ioh);
if ( choose_ioport_device2(&ioh.device, cfgfile, &cb) )
ioh.set_device_name(ioh.device.c_str(), IORESP_ALL);
}
break;
case processor_t::ev_ending_undo:
case processor_t::ev_oldfile:
load_from_idb();
break;
case processor_t::ev_creating_segm: // 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_header:
{
outctx_t *ctx = va_arg(va, outctx_t *);
nec78k0s_header(*ctx);
return 1;
}
case processor_t::ev_out_footer:
{
outctx_t *ctx = va_arg(va, outctx_t *);
nec78k0s_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 *);
nec78k0s_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;
}
default:
break;
}
return 0;
}
//-----------------------------------------------------------------------
// Processor Definition
//-----------------------------------------------------------------------
processor_t LPH =
{
IDP_INTERFACE_VERSION, // version
PLFM_NEC_78K0S, // id
// flag
PRN_HEX
| PR_SEGTRANS,
// flag2
0,
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
Rcs,Rds,
0, // size of a segment register
Rcs,Rds,
NULL, // No known code start sequences
retcodes,
0,
NEC_78K_0S_last,
Instructions, // instruc
};