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

2631
idasdk76/module/z80/ana.cpp Normal file

File diff suppressed because it is too large Load Diff

429
idasdk76/module/z80/emu.cpp Normal file
View File

@@ -0,0 +1,429 @@
/*
* Interactive disassembler (IDA).
* Version 3.06
* Copyright (c) 1990-96 by Ilfak Guilfanov.
* ALL RIGHTS RESERVED.
* FIDO: 2:5020/209
* E-mail: ig@estar.msk.su
*
*/
#include "i5.hpp"
#include <idd.hpp>
//------------------------------------------------------------------------
static void set_immd_bit(const insn_t &insn, int n)
{
set_immd(insn.ea);
if ( !is_defarg(get_flags(insn.ea), n) )
{
switch ( insn.itype )
{
case I5_ani:
case I5_xri:
case I5_ori:
case I5_in:
case I5_out:
case I5_rst:
case HD_in0:
case HD_out0:
case HD_tstio:
op_num(insn.ea,-1);
break;
}
}
}
//----------------------------------------------------------------------
void z80_t::load_operand(const insn_t &insn, const op_t &x)
{
dref_t xreftype;
switch ( x.type )
{
case o_reg:
case o_phrase:
default:
break;
case o_imm:
xreftype = dr_O;
MakeImm:
set_immd_bit(insn, x.n);
if ( op_adds_xrefs(get_flags(insn.ea), x.n) )
insn.add_off_drefs(x, xreftype, 0);
break;
case o_displ:
xreftype = dr_R;
goto MakeImm;
case o_mem:
{
ea_t ea = map_data_ea(insn, x);
insn.add_dref(ea, x.offb, dr_R);
insn.create_op_data(ea, x);
}
break;
case o_near:
{
ea_t ea = map_code_ea(insn, x);
ea_t segbase = (ea - x.addr) >> 4;
ea_t thisseg = insn.cs;
int iscall = has_insn_feature(insn.itype,CF_CALL);
insn.add_cref(
ea,
x.offb,
iscall ? (segbase == thisseg ? fl_CN : fl_CF)
: (segbase == thisseg ? fl_JN : fl_JF));
if ( iscall && !func_does_return(ea) )
flow = false;
}
break;
}
}
//----------------------------------------------------------------------
static void save_operand(const insn_t &insn, const op_t &x)
{
switch ( x.type )
{
case o_reg:
break;
case o_mem:
{
ea_t ea = map_data_ea(insn, x);
insn.create_op_data(ea, x);
insn.add_dref(ea, x.offb, dr_W);
}
break;
case o_displ:
set_immd_bit(insn, x.n);
if ( op_adds_xrefs(get_flags(insn.ea), x.n) )
insn.add_off_drefs(x, dr_W, OOF_ADDR);
case o_phrase:
break;
default:
switch ( insn.itype )
{
case Z80_in0:
case Z80_outaw:
break;
default:
break;
}
break;
}
}
//----------------------------------------------------------------------
int z80_t::i5_emu(const insn_t &insn)
{
uint32 Feature = insn.get_canon_feature(ph);
flow = ((Feature & CF_STOP) == 0);
if ( (Feature & CF_USE1) )
load_operand(insn, insn.Op1);
if ( (Feature & CF_USE2) )
load_operand(insn, insn.Op2);
if ( Feature & CF_JUMP )
remember_problem(PR_JUMP, insn.ea);
switch ( insn.itype )
{
case I5_mov:
case I5_mvi:
case Z80_ld:
break;
case Z80_jp:
case Z80_jr: // Z80
case Z80_ret: // Z80
if ( insn.Op1.Cond != oc_not )
break;
// no break
case I5_jmp:
if ( insn.Op2.type == o_phrase )
remember_problem(PR_JUMP, insn.ea);
// no break
case I5_ret:
flow = false;
break;
case I5_rstv:
add_cref(insn.ea, map_code_ea(insn, 0x40, 0), fl_CN);
break;
case I5_rst:
{
int mul = isZ80() ? 1 : 8;
ushort offset = ushort(insn.Op1.value * mul);
add_cref(insn.ea, map_code_ea(insn, offset, 0), fl_CN);
}
case I5_call:
case I5_cc:
case I5_cnc:
case I5_cz:
case I5_cnz:
case I5_cpe:
case I5_cpo:
case I5_cp:
case I5_cm:
case Z80_exx: // Z80
// i5_CPUregs.bc.undef();
// i5_CPUregs.de.undef();
// i5_CPUregs.hl.undef();
// i5_CPUregs.af.undef();
// i5_CPUregs.ix.undef();
// i5_CPUregs.iy.undef();
break;
default:
// R1.undef();
// R2.undef();
break;
}
if ( Feature & CF_CHG1 )
save_operand(insn, insn.Op1);
if ( Feature & CF_CHG2 )
save_operand(insn, insn.Op2);
if ( flow )
add_cref(insn.ea, insn.ea+insn.size, fl_F);
return 1;
}
//----------------------------------------------------------------------
sval_t z80_t::named_regval(
const char *regname,
getreg_t *getreg,
const regval_t *rv)
{
// Get register info.
const char *main_regname;
bitrange_t bitrange;
if ( !get_reg_info(&main_regname, &bitrange, regname) )
return 0;
// Get main register value and apply bitrange.
sval_t ret = getreg(main_regname, rv).ival;
ret >>= bitrange.bitoff();
ret &= (1ULL << bitrange.bitsize()) - 1;
return ret;
}
//----------------------------------------------------------------------
sval_t z80_t::regval(const op_t &op, getreg_t *getreg, const regval_t *rv)
{
// Check for bad register number.
if ( op.reg > R_a2 )
return 0;
return named_regval(ph.reg_names[op.reg], getreg, rv);
}
//----------------------------------------------------------------------
bool z80_t::check_cond(
uint16_t cc,
getreg_t *getreg,
const regval_t *regvalues)
{
uint16_t F = named_regval("F", getreg, regvalues);
bool C = (F & (1 << 0)) != 0;
bool PV = (F & (1 << 2)) != 0;
bool Z = (F & (1 << 6)) != 0;
bool S = (F & (1 << 7)) != 0;
switch ( cc )
{
case oc_nz: return !Z; // non-zero
case oc_z: return Z; // zero
case oc_nc: return !C; // no carry
case oc_c: return C; // carry
case oc_po: return !PV; // parity odd
case oc_pe: return PV; // parity even
case oc_p: return !S; // sign positive
case oc_m: return S; // sign negative
case oc_not: return true;
}
return false;
}
//----------------------------------------------------------------------
ea_t z80_t::next_exec_insn(
ea_t ea,
getreg_t *getreg,
const regval_t *regvalues)
{
// Decode instruction at ea.
insn_t insn;
if ( decode_insn(&insn, ea) < 1 )
return BADADDR;
// Get next address to be executed.
ea_t target = BADADDR;
switch ( insn.itype )
{
case Z80_jp:
case Z80_jr:
case Z80_call:
if ( check_cond(insn.Op1.Cond, getreg, regvalues) )
{
if ( insn.Op2.type == o_near )
target = insn.Op2.addr;
else if ( insn.Op2.type == o_phrase )
target = regval(insn.Op2, getreg, regvalues);
}
break;
case Z80_djnz:
{
uint8_t B = named_regval("B", getreg, regvalues);
if ( (B-1) != 0 )
target = insn.Op1.addr;
}
break;
case Z80_ret:
if ( !check_cond(insn.Op1.Cond, getreg, regvalues) )
break;
// fallthrough
case Z80_reti:
case Z80_retn:
{
uint16_t SP = named_regval("SP", getreg, regvalues);
target = get_word(SP);
}
break;
}
return target;
}
//----------------------------------------------------------------------
ea_t z80_t::calc_step_over(ea_t ip) const
{
insn_t insn;
if ( ip == BADADDR || decode_insn(&insn, ip) < 1 )
return BADADDR;
// Allow stepping over call instructions and djnz.
bool step_over = is_call_insn(insn)
|| insn.itype == Z80_djnz;
if ( step_over )
return insn.ea + insn.size;
return BADADDR;
}
//----------------------------------------------------------------------
bool z80_t::get_operand_info(
idd_opinfo_t *opinf,
ea_t ea,
int n,
getreg_t *getreg,
const regval_t *regvalues)
{
// No Z80 instruction has operand number greater than 2.
if ( n < 0 || n > 2 )
return false;
// Decode instruction at ea.
insn_t insn;
if ( decode_insn(&insn, ea) < 1 )
return false;
// Check the instruction features to see if the operand is modified.
opinf->modified = has_cf_chg(insn.get_canon_feature(ph), n);
// Get operand value (possibly an ea).
uint64 v = 0;
const op_t &op = insn.ops[n];
switch ( op.type )
{
case o_reg:
// We use the getreg function (along with regvalues) to retrieve
// the value of the register specified in op.reg.
v = regval(op, getreg, regvalues);
break;
case o_mem:
case o_near:
// Memory addresses are stored in op.addr.
opinf->ea = op.addr;
break;
case o_phrase:
// Memory references using register value.
opinf->ea = regval(op, getreg, regvalues);
break;
case o_displ:
// Memory references using register and address value.
opinf->ea = regval(op, getreg, regvalues) + op.addr;
break;
case o_imm:
// Immediates are stored in op.value.
v = op.value;
break;
case o_cond:
// This is just a condition code type (see opcond_t). There is no
// meaningful value to return.
return false;
default:
return false;
}
opinf->value._set_int(v);
opinf->value_size = get_dtype_size(op.dtype);
return true;
}
//----------------------------------------------------------------------
bool z80_t::get_reg_info(
const char **main_regname,
bitrange_t *bitrange,
const char *regname)
{
// Sanity checks.
if ( regname == NULL || regname[0] == '\0' )
return false;
static const char *const subregs[][3] =
{
{ "af", "a", "f" },
{ "bc", "b", "c" },
{ "de", "d", "e" },
{ "hl", "h", "l" },
{ "af'", "a'", "f'" },
{ "bc'", "b'", "c'" },
{ "de'", "d'", "e'" },
{ "hl'", "h'", "l'" },
{ "ix", NULL, NULL },
{ "iy", NULL, NULL },
{ "sp", NULL, NULL },
{ "pc", NULL, NULL },
};
// Check if we are dealing with paired or single registers and return
// the appropriate information.
for ( size_t i = 0; i < qnumber(subregs); i++ )
{
for ( size_t j = 0; j < 3; j++ )
{
if ( subregs[i][j] == NULL )
break;
if ( strieq(regname, subregs[i][j]) )
{
if ( main_regname != NULL )
*main_regname = subregs[i][0];
if ( bitrange != NULL )
{
switch ( j )
{
case 0: *bitrange = bitrange_t(0, 16); break;
case 1: *bitrange = bitrange_t(8, 8); break;
case 2: *bitrange = bitrange_t(0, 8); break;
}
}
return true;
}
}
}
return false;
}

230
idasdk76/module/z80/i5.hpp Normal file
View File

@@ -0,0 +1,230 @@
/*
* Interactive disassembler (IDA).
* Version 2.06
* Copyright (c) 1990-93 by Ilfak Guilfanov. (2:5020/209@fidonet)
* ALL RIGHTS RESERVED.
*
*/
#ifndef I5HPP
#define I5HPP
#include "../idaidp.hpp"
#include "ins.hpp"
#include <diskio.hpp>
#include "../iohandler.hpp"
//------------------------------------------------------------------
// debugger functions
typedef const regval_t &idaapi getreg_t(const char *name, const regval_t *regvalues);
//------------------------------------------------------------------
// customization of insn_t structure:
#define o_cond o_idpspec0
#define Cond reg
//------------------------------------------------------------------
enum opcond_t // condition code types
{
oc_nz,
oc_z,
oc_nc,
oc_c,
oc_po,
oc_pe,
oc_p,
oc_m,
oc_not
};
//------------------------------------------------------------------
#define _PT_64180 0x01 // HD64180
#define _PT_Z80 0x02 // Z80
#define _PT_8085 0x04 // Intel 8085
#define _PT_Z180 0x08 // Z180
#define _PT_Z380 0x10 // Z380
#define _PT_GB 0x20 // GameBoy
#define PT_GB _PT_GB
#define PT_Z380 _PT_Z380
#define PT_Z180 ( PT_Z380 | _PT_Z180)
#define PT_64180 ( PT_Z180 | _PT_64180)
#define PT_Z80 ( PT_64180| _PT_Z80 | _PT_GB)
#define PT_8085 ( PT_Z80 | _PT_8085 )
extern int pflag;
enum RegNo ENUM_SIZE(uint16)
{
R_b = 0,
R_c = 1,
R_d = 2,
R_e = 3,
R_h = 4,
R_l = 5,
R_a = 7,
R_bc = 8,
R_de = 9,
R_hl = 10,
R_af = 11,
R_sp = 12,
R_ix = 13,
R_iy = 14,
R_af2 = 15,
R_r = 16,
R_i = 17,
R_f = 18,
R_xl = 19,
R_xh = 20,
R_yl = 21,
R_yh = 22,
R_w,
R_lw,
R_ixl,
R_ixu,
R_dsr,
R_xsr,
R_iyl,
R_iyu,
R_ysr,
R_sr,
R_ib,
R_iw,
R_xm,
R_lck,
R_bc2,
R_de2,
R_hl2,
R_ix2,
R_iy2,
R_b2,
R_c2,
R_d2,
R_e2,
R_h2,
R_l2,
R_m2,
R_a2,
R_vcs, // virtual code segment register
R_vds // virtual data segment register
};
//------------------------------------------------------------------
#define UAS_NOENS 0x0001 // I5: don't specify start addr in the .end directive
#define UAS_NPAIR 0x0002 // I5: pairs are denoted by 1 char ('b')
#define UAS_UNDOC 0x0004 // I5: does assembler support undoc-d instrs?
#define UAS_MKIMM 0x0008 // I5: place # in front of imm operand
#define UAS_MKOFF 0x0010 // I5: offset(ix) form
#define UAS_CNDUP 0x0020 // I5: conditions UPPERCASE
#define UAS_FUNNY 0x0040 // I5: special for A80
#define UAS_CSEGS 0x0080 // I5: generate 'cseg' directives
#define UAS_TOFF 0x0100 // I5: (ix+-10)
#define UAS_ZMASM 0x0200 // ZMASM
#define UAS_GBASM 0x0400 // RGBASM
#define aux_off16 0x0001 // o_displ: off16
//------------------------------------------------------------------
struct z80_iohandler_t : public iohandler_t
{
z80_iohandler_t(netnode &nn) : iohandler_t(nn) {}
};
struct insndesc_t;
struct z80_t : public procmod_t
{
netnode helper;
z80_iohandler_t ioh = z80_iohandler_t(helper);
int pflag = 0;
int code;
uchar saved_value = 0;
bool flow = false;
bool isx = false;
virtual ssize_t idaapi on_event(ssize_t msgid, va_list va) override;
const char *find_ioport(uval_t port);
const char *find_ioport_bit(int port, int bit);
void choose_device(int respinfo);
void set_cpu(int np);
void load_from_idb();
const char *set_idp_options(const char *keyword, int /*value_type*/, const void * /*value*/, bool /*idb_loaded*/);
// out.cpp
inline bool isFunny(void) { return (ash.uflag & UAS_FUNNY) != 0; }
void i5_header(outctx_t &ctx);
void i5_footer(outctx_t &ctx);
void i5_segstart(outctx_t &ctx, segment_t *);
// ana.cpp
int i5_ana(insn_t *_insn);
void load_z80_operand(insn_t &insn, op_t &x, uchar op);
bool search_map(insn_t &insn, const insndesc_t *map, uchar _code);
bool z380_insns(insn_t &insn, const insndesc_t *map, const insndesc_t *cb);
bool z380_ED(insn_t &insn);
void z80_ixcommands(insn_t &insn, bool _isx);
void z80_misc(insn_t &insn);
void ConvertToZ80(insn_t &insn);
void op_r1(op_t &x) const;
void op_r2(op_t &x) const;
void op_ss(op_t &x) const;
void op_dd(op_t &x) const;
void op_xdispl(insn_t &insn, op_t &x) const;
void op_ix(op_t &x) const;
void op_ibyte(op_t &x,int low) const;
int op_xbytereg(op_t &x,uint16 mode) const;
int op_xr1(op_t &x) const;
int op_xr2(op_t &x) const;
inline bool isGB(void);
inline bool isZ380(void);
inline bool isZ180(void);
inline bool isZ80(void);
inline bool is64180(void);
inline bool is8085(void);
// emu.cpp
int i5_emu(const insn_t &insn);
void load_operand(const insn_t &insn, const op_t &x);
sval_t named_regval(const char *regname, getreg_t *getreg, const regval_t *rv);
sval_t regval(const op_t &op, getreg_t *getreg, const regval_t *rv);
bool check_cond(uint16_t cc, getreg_t *getreg, const regval_t *regvalues);
ea_t next_exec_insn(
ea_t ea,
getreg_t *getreg,
const regval_t *regvalues);
ea_t calc_step_over(ea_t ip) const;
bool get_operand_info(
idd_opinfo_t *opinf,
ea_t ea,
int n,
getreg_t *getreg,
const regval_t *regvalues);
bool get_reg_info(
const char **main_regname,
bitrange_t *bitrange,
const char *regname);
};
extern int data_id;
#define PROCMOD_NAME z80
#define PROCMOD_NODE_NAME "$ " QSTRINGIZE(PROCMOD_NAME)
inline bool z80_t::isGB(void) { return (pflag & PT_GB) != 0; }
inline bool z80_t::isZ380(void) { return (pflag & PT_Z380) != 0; }
inline bool z80_t::isZ180(void) { return (pflag & PT_Z180) != 0; }
inline bool z80_t::isZ80(void) { return (pflag & PT_Z80) != 0; }
inline bool z80_t::is64180(void) { return (pflag & PT_64180) != 0; }
inline bool z80_t::is8085(void) { return !isZ80(); }
#endif // I5HPP

297
idasdk76/module/z80/ins.cpp Normal file
View File

@@ -0,0 +1,297 @@
/*
* Interactive disassembler (IDA).
* Version 2.05
* Copyright (c) 1990-93 by Ilfak Guilfanov. (2:5020/209@fidonet)
* ALL RIGHTS RESERVED.
*
*/
#include <ida.hpp>
#include <idp.hpp>
#include "ins.hpp"
const instruc_t Instructions[] =
{
{ "", 0 }, // Unknown Operation
//
// Intel 8080/8085 instructions
//
{ "aci", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add immediate to A with carry
{ "adc", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add reg to A with carry
{ "add", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add <reg> to A
{ "adi", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add immediate to A
{ "ana", CF_USE1 | CF_CHG1 | CF_USE2 }, // And reg to A
{ "ani", CF_USE1 | CF_CHG1 | CF_USE2 }, // And immediate to A
{ "call", CF_USE1 | CF_CALL }, // Call subroutine at <addr>
{ "cnz", CF_USE1 | CF_CALL }, // Call subroutine if non zero
{ "cz", CF_USE1 | CF_CALL }, // Call subroutine if zero
{ "cnc", CF_USE1 | CF_CALL }, // Call subroutine if carry clear
{ "cc", CF_USE1 | CF_CALL }, // Call subroutine if carry set
{ "cpo", CF_USE1 | CF_CALL }, // Call subroutine if odd parity
{ "cpe", CF_USE1 | CF_CALL }, // Call subroutine if even parity
{ "cp", CF_USE1 | CF_CALL }, // Call subroutine if positive
{ "cm", CF_USE1 | CF_CALL }, // Call subroutine if negative
{ "cmc", 0 }, // Complement carry
{ "cmp", CF_USE1 | CF_USE2 }, // Compare register with A
{ "cpi", CF_USE1 | CF_USE2 }, // Compare immediate data with A
{ "cma", 0 }, // Complement A
{ "daa", 0 }, // Decimal adjust A
{ "dad", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add register pair to HL
{ "dcr", CF_USE1 | CF_CHG1 }, // Decrement register
{ "dcx", CF_USE1 | CF_CHG1 }, // Decrement register pair
{ "di", 0 }, // Disable interrupts
{ "ei", 0 }, // Enable interrupts
{ "hlt", 0 }, // Halt
{ "in", CF_CHG1 | CF_USE2 }, // Input from port to A
{ "inr", CF_USE1 | CF_CHG1 }, // Increment register
{ "inx", CF_USE1 | CF_CHG1 }, // Increment register pair
{ "jmp", CF_USE1 }, // Jump
{ "jnz", CF_USE1 }, // Jump if not zero
{ "jz", CF_USE1 }, // Jump if zero
{ "jnc", CF_USE1 }, // Jump if carry clear
{ "jc", CF_USE1 }, // Jump if carry set
{ "jpo", CF_USE1 }, // Jump if parity odd
{ "jpe", CF_USE1 }, // Jump if parity even
{ "jp", CF_USE1 }, // Jump if plus
{ "jm", CF_USE1 }, // Jump if minus
{ "lda", CF_CHG1 | CF_USE2 }, // Load A direct from memory
{ "ldax", CF_CHG1 | CF_USE2 }, // Load A indirect from memory using register pair
{ "lhld", CF_CHG1 | CF_USE2 }, // Load HL direct from memory
{ "lxi", CF_CHG1 | CF_USE2 }, // Load register pair with immediate data
{ "mov", CF_CHG1 | CF_USE2 }, // Move register to register
{ "mvi", CF_CHG1 | CF_USE2 }, // Move immediate data to register
{ "nop", 0 }, // No Operation
{ "ora", CF_USE1 | CF_CHG1 | CF_USE2 }, // Or register with A
{ "ori", CF_USE1 | CF_CHG1 | CF_USE2 }, // Or immediate data to A
{ "out", CF_USE1 | CF_USE2 }, // Output to port
{ "pchl", CF_JUMP | CF_STOP }, // Jump to instruction at (HL)
{ "pop", CF_CHG1 }, // Pop register pair from stack
{ "push", CF_USE1 }, // Push register pair onto stack
{ "ret", CF_STOP }, // Return from subroutine
{ "rnz", 0 }, // Return if non zero
{ "rz", 0 }, // Return if zero
{ "rnc", 0 }, // Return if carry clear
{ "rc", 0 }, // Return if carry set
{ "rpo", 0 }, // Return if parity odd
{ "rpe", 0 }, // Return if parity even
{ "rp", 0 }, // Return if plus
{ "rm", 0 }, // Return if minus
{ "ral", 0 }, // Rotate A left with carry
{ "rlc", 0 }, // Rotate A left with branch carry
{ "rar", 0 }, // Rotate A right with carry
{ "rrc", 0 }, // Rotate A right with branch carry
{ "rst", CF_USE1 }, // Restart at vector <int>
{ "sbb", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract from A with borrow
{ "sbi", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract immediate from A with borrow
{ "stc", 0 }, // Set carry
{ "sphl", 0 }, // Exchange SP with HL
{ "sta", CF_CHG1 | CF_USE2 }, // Store A direct memory
{ "stax", CF_CHG1 | CF_USE2 }, // Store A indirect using register pair
{ "shld", CF_CHG1 | CF_USE2 }, // Store HL
{ "sui", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract immediate from A
{ "sub", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract from A
{ "xra", CF_USE1 | CF_CHG1 | CF_USE2 }, // XOR with A
{ "xri", CF_USE1 | CF_CHG1 | CF_USE2 }, // XOR A with immediate data
{ "xchg", 0 }, // Exchange DE with HL
{ "xthl", 0 }, // Exchange HL with top of stack
{ "rim", 0 }, // Read interrupt mask
{ "sim", 0 }, // Store Interrupt mask
//
// Z80 instructions
//
{ "and", CF_USE1 | CF_USE2 | CF_CHG1 }, // And with accumulator
{ "bit", CF_USE1 | CF_USE2 }, // Test <bit> in operand
{ "call", CF_USE2 | CF_CALL }, // call (cond & uncond)
{ "ccf", 0 }, // Complement carry flag
{ "cp", CF_USE1 | CF_USE2 }, // Compare with accumulator
{ "cpd", 0 }, // Compare accumulator with memory and\ndecrement address and byte counters
{ "cpdr", 0 }, // Compare accumulator with memory and\ndecrement address and byte counter,\ncontinue until match is found or\nbyte counter is zero
{ "cpi", 0 }, // Compare accumulator with memory and\nincrement address and byte counters
{ "cpir", 0 }, // Compare accumulator with memory and\nincrement address and byte counter,\ncontinue until match is found or\nbyte counter is zero
{ "cpl", 0 }, // Complement the accumulator
{ "dec", CF_USE1 | CF_CHG1 }, // Decrement operand
{ "djnz", CF_USE1 }, // Decrement reg B and jump relative if zero
{ "ex", CF_USE1 | CF_CHG1 | CF_USE2 | CF_CHG2 }, // Exchange operands
{ "exx", 0 }, // Exchange register pairs and alt reg pairs
{ "halt", 0 }, // Program execution stops
{ "im", CF_USE1 }, // Interrupt mode
{ "inc", CF_USE1 | CF_CHG1 }, // Increment operand
{ "ind", 0 }, // Input to memory and decrement pointer
{ "indr", 0 }, // Input to memory and decrement pointer until\nbyte counter is zero
{ "ini", 0 }, // Input to memory and increment pointer
{ "inir", 0 }, // Input to memory and increment pointer until\nbyte counter is zero
{ "jp", CF_USE2 }, // Jump (conditional & unconditional)
{ "jr", CF_USE1 | CF_USE2 }, // Jump relative (conditional & unconditional)
{ "ld", CF_CHG1 | CF_USE2 }, // Move operand2 to operand1
{ "ldd", 0 }, // Transfer data between memory and decrement\ndestination and source addresses
{ "lddr", 0 }, // Transfer data between memory until byte\ncounter is zero, decrement destintation\nand source addresses
{ "ldi", 0 }, // Transfer data between memory and increment\ndestination and source addresses
{ "ldir", 0 }, // Transfer data between memory until byte\ncounter is zero, increment destination\nand source addresses
{ "neg", 0 }, // Negate contents of accumulator
{ "or", CF_USE1 | CF_CHG1 | CF_USE2 }, // Or with accumulator
{ "otdr", 0 }, // Output from memory, decrement address\ncontinue until reg B is zero
{ "otir", 0 }, // Output from memory, increment address\ncontinue until reg B is zero
{ "outd", 0 }, // Output from memory, decrement address
{ "outi", 0 }, // Output from memory, increment address
{ "res", CF_USE1 | CF_CHG2 | CF_USE2 }, // Reset bit
{ "ret", 0 }, // Return (cond & uncond)
{ "reti", CF_STOP }, // Return from interrupt
{ "retn", CF_STOP }, // Return from non-maskable interrupt
{ "rl", CF_USE1 | CF_CHG1 }, // Rotate left through carry
{ "rla", 0 }, // Rotate left through carry accumulator
{ "rlc", CF_USE1 | CF_CHG1 }, // Rotate left branch carry
{ "rlca", 0 }, // Rotate left accumulator
{ "rld", 0 }, // Rotate one BCD digit left between the\naccumulator and memory
{ "rr", CF_USE1 | CF_CHG1 }, // Rotate right through carry
{ "rra", 0 }, // Rotate right through carry accumulator
{ "rrc", CF_USE1 | CF_CHG1 }, // Rotate right branch carry
{ "rrca", 0 }, // Rotate right branch carry accumulator
{ "rrd", 0 }, // Rotate one BCD digit right between the\naccumulator and memory
{ "scf", 0 }, // Set carry flag
{ "sbc", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract from A with borrow
{ "set", CF_USE1 | CF_CHG2 | CF_USE2 }, // Set bit
{ "sla", CF_USE1 | CF_CHG1 }, // Shift left arithmetic
{ "sra", CF_USE1 | CF_CHG1 }, // Shift right arithmetic
{ "srl", CF_USE1 | CF_CHG1 }, // Shift right logical
{ "xor", CF_USE1 | CF_CHG1 | CF_USE2 }, // Exclusive or with accumulator
{ "inp", CF_USE1 }, // Input from port (c) into operand
{ "outp", CF_USE1 }, // Output operand to port (c)
{ "srr", CF_USE1 }, // Shift left filling with 1
//
// HD64180 extensions
//
{ "in0", CF_USE1 | CF_CHG1 | CF_USE2 }, // load register with input from port (n)
{ "mlt", CF_USE1 }, // multiplication of each half\nof the specified register pair\nwith the 16-bit result going to\nthe specified register pair
{ "otim", 0 }, // load output port (c) with\nlocation (hl),\nincrement hl and b\ndecrement c
{ "otimr", 0 }, // load output port (c) with\nlocation (hl),\nincrement hl and c\ndecrement b\nrepeat until b = 0
{ "otdm", 0 }, // load output port (c) with\nlocation (hl),\ndecrement hl and b\ndecrement c
{ "otdmr", 0 }, // load output port (c) with\nlocation (hl),\ndecrement hl and c\ndecrement b\nrepeat until b = 0
{ "out0", CF_USE1 }, // load output port (n) from register
{ "slp", 0 }, // enter sleep mode
{ "tst", CF_USE1 }, // non-destructive'and' with accumulator and specified operand
{ "tstio", CF_USE1 }, // non-destructive 'and' of n and the contents of port (c)
//
// A80 special instructions
//
{ "lbcd", CF_CHG1 | CF_USE2 }, // Move operand to BC
{ "lded", CF_CHG1 | CF_USE2 }, // Move operand to DE
{ "lspd", CF_CHG1 | CF_USE2 }, // Move operand to SP
{ "lixd", CF_CHG1 | CF_USE2 }, // Move operand to IX
{ "liyd", CF_CHG1 | CF_USE2 }, // Move operand to IY
{ "sbcd", CF_CHG1 | CF_USE2 }, // Move BC to memory
{ "sded", CF_CHG1 | CF_USE2 }, // Move DE to memory
{ "sspd", CF_CHG1 | CF_USE2 }, // Move SP to memory
{ "sixd", CF_CHG1 | CF_USE2 }, // Move IX to memory
{ "siyd", CF_CHG1 | CF_USE2 }, // Move IY to memory
{ "xtix", CF_USE1 | CF_CHG1 | CF_USE2 | CF_CHG2 }, // Exchange SP and IX
{ "xtiy", CF_USE1 | CF_CHG1 | CF_USE2 | CF_CHG2 }, // Exchange SP and IY
{ "spix", CF_CHG1 | CF_USE2 }, // Move IX to SP
{ "spiy", CF_CHG1 | CF_USE2 }, // Move IY to SP
{ "pcix", CF_USE2 | CF_STOP }, // Jump indirect by IX
{ "pciy", CF_USE2 | CF_STOP }, // Jump indirect by IY
{ "mvra", CF_CHG1 | CF_USE2 }, // Move A to R
{ "mvia", CF_CHG1 | CF_USE2 }, // Move A to I
{ "mvar", CF_CHG1 | CF_USE2 }, // Move R to A
{ "mvai", CF_CHG1 | CF_USE2 }, // Move I to A
{ "dadix", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add operand to IX
{ "dadiy", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add operand to IY
{ "addc", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add operand to HL with carry
{ "addcix", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add operand to IX with carry
{ "addciy", CF_USE1 | CF_CHG1 | CF_USE2 }, // Add operand to IY with carry
{ "subc", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract from HL with borrow
{ "subcix", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract from IX with borrow
{ "subciy", CF_USE1 | CF_CHG1 | CF_USE2 }, // Subtract from IY with borrow
{ "jrc", CF_USE2 }, // Jump relative if carry
{ "jrnc", CF_USE2 }, // Jump relative if not carry
{ "jrz", CF_USE2 }, // Jump relative if zero
{ "jrnz", CF_USE2 }, // Jump relative if not zero
{ "cmpi", 0 }, // Compare accumulator with memory and\nincrement address and byte counters
{ "cmpd", 0 }, // Compare accumulator with memory and\ndecrement address and byte counters
{ "im0", CF_USE1 }, // Interrupt mode 0
{ "im1", CF_USE1 }, // Interrupt mode 1
{ "im2", CF_USE1 }, // Interrupt mode 2
{ "otd", 0 }, // Output from memory, decrement address
{ "oti", 0 }, // Output from memory, increment address
// Intel 8085 undocumented instructions
// (info from http://oak.oakland.edu/pub/cpm/maclib/i8085.lib)
{ "dsub", 0 }, // (HL) <- (HL)-(BC), affects all flags
{ "arhl", 0 }, // SHIFT HL RIGHT ONE BIT, (H7 IS DUPLICATED, L0 IS SHIFTED INTO CY)
{ "rdel", 0 }, // ROTATE DE LEFT ONE BIT THRU CY, (E0 RECEIVES CY, CY RECEIVES D7)
{ "ldhi", CF_USE1 }, // (DE) <- (HL)+arg
{ "ldsi", CF_USE1 }, // (DE) <- (SP)+arg
{ "shlx", 0 }, // ((DE)) <- (HL)
{ "lhlx", 0 }, // (HL) <- ((DE))
{ "rstv", 0 }, // RESTART 40H ON V (OVERFLOW)
{ "jx5", CF_USE1 }, // JUMP IF X5 SET
{ "jnx5", CF_USE1 }, // JUMP IF NOT X5 SET
// Z380 instructions
{ "cplw", CF_USE1 }, // Complement HL register
{ "swap", CF_USE1 }, // Swap upper register word with lower register word
{ "inw", CF_CHG1|CF_USE2 }, // Input word
{ "outw", CF_CHG1|CF_USE2 }, // Output word
{ "ldw", CF_CHG1|CF_USE2 }, // Load word
{ "addw", CF_CHG1|CF_USE2 }, // Add word
{ "subw", CF_CHG1|CF_USE2 }, // Subtract word
{ "adcw", CF_CHG1|CF_USE2 }, // Add with carry word
{ "sbcw", CF_CHG1|CF_USE2 }, // Subtract with borrow word
{ "andw", CF_CHG1|CF_USE2 }, // AND logical word
{ "xorw", CF_CHG1|CF_USE2 }, // XOR logical word
{ "orw", CF_CHG1|CF_USE2 }, // OR logical word
{ "cpw", CF_CHG1|CF_USE2 }, // Compare word
{ "ddir", CF_USE1 }, // Decoder directive
{ "calr", CF_USE1|CF_USE2 }, // Call relative
{ "ldctl", CF_CHG1|CF_USE2 }, // Load control register
{ "mtest", CF_USE1 }, // Mode test
{ "exxx", CF_USE1 }, // Exchange Index Register with Alternate Bank
{ "exxy", CF_USE1 }, // Exchange Index Register with Alternate Bank
{ "exall", CF_USE1 }, // Exchange all registers with Alternate Bank
{ "setc", CF_USE1 }, // Set control bit
{ "resc", CF_USE1 }, // Reset control bit
{ "rlcw", CF_USE1 }, // Rotate Left Circular Word
{ "rrcw", CF_USE1 }, // Rotate Right Circular Word
{ "rlw", CF_USE1 }, // Rotate Left Word
{ "rrw", CF_USE1 }, // Rotate Right Word
{ "slaw", CF_USE1 }, // Shift Left Arithmetic Word
{ "sraw", CF_USE1 }, // Shift Right Arithmetic Word
{ "srlw", CF_USE1 }, // Shift Right Logical Word
{ "multw", CF_USE1 }, // Multiply Word
{ "multuw", CF_USE1 }, // Multiply Word Unsigned
{ "divuw", CF_USE1 }, // Divide unsigned
{ "outaw", CF_CHG1|CF_USE1 }, // Output word direct to port address
{ "inaw", CF_CHG1|CF_USE1 }, // Input word direct from port address
{ "outa", CF_CHG1|CF_USE1 }, // Output byte direct to port address
{ "ina", CF_CHG1|CF_USE1 }, // Input byte direct from port address
{ "negw", CF_CHG1 }, // Negate word
{ "exts", CF_CHG1 }, // Extend byte sign
{ "extsw", CF_CHG1 }, // Extend word sign
{ "btest", 0 }, // Bank test
{ "ldiw", 0 }, // Load and increment (word)
{ "ldirw", 0 }, // Load and increment, repeat (word)
{ "lddw", 0 }, // Load and decrement (word)
{ "lddrw", 0 }, // Load and decrement, repeat (word)
{ "iniw", 0 }, // Input and increment (word)
{ "inirw", 0 }, // Input and increment, repeat (word)
{ "indw", 0 }, // Input and decrement (word)
{ "indrw", 0 }, // Input and decrement, repeat (word)
{ "outiw", 0 }, // Output and increment (word)
{ "otirw", 0 }, // Output and increment, repeat (word)
{ "outdw", 0 }, // Output and decrement (word)
{ "otdrw", 0 }, // Output and decrement, repeat (word)
// Gameboy instructions
{ "ldh", CF_CHG1|CF_USE2 },
{ "stop", CF_STOP },
};
CASSERT(sizeof(Instructions)/sizeof(Instructions[0]) == I5_last);

303
idasdk76/module/z80/ins.hpp Normal file
View File

@@ -0,0 +1,303 @@
/*
* 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)
{
I5_null = 0, // Unknown Operation
//
// Intel 8080-8085 instructions
//
I5_aci,
I5_adc, Z80_adc = I5_adc,
I5_add, Z80_add = I5_add,
I5_adi,
I5_ana,
I5_ani,
I5_call,
I5_cnz,
I5_cz,
I5_cnc,
I5_cc,
I5_cpo,
I5_cpe,
I5_cp,
I5_cm,
I5_cmc,
I5_cmp,
I5_cpi,
I5_cma,
I5_daa,
I5_dad,
I5_dcr,
I5_dcx,
I5_di, Z80_di = I5_di,
I5_ei, Z80_ei = I5_ei,
I5_halt,
I5_in, Z80_in = I5_in,
I5_inr,
I5_inx,
I5_jmp,
I5_jnz,
I5_jz,
I5_jnc,
I5_jc,
I5_jpo,
I5_jpe,
I5_jp,
I5_jm,
I5_lda,
I5_ldax,
I5_lhld,
I5_lxi,
I5_mov,
I5_mvi,
I5_nop,
I5_ora,
I5_ori,
I5_out, Z80_out = I5_out,
I5_pchl,
I5_pop, Z80_pop = I5_pop,
I5_push, Z80_push = I5_push,
I5_ret,
I5_rnz,
I5_rz,
I5_rnc,
I5_rc,
I5_rpo,
I5_rpe,
I5_rp,
I5_rm,
I5_ral,
I5_rlc,
I5_rar,
I5_rrc,
I5_rst,
I5_sbb,
I5_sbi,
I5_stc,
I5_sphl,
I5_sta,
I5_stax,
I5_shld,
I5_sui,
I5_sub, Z80_sub = I5_sub,
I5_xra,
I5_xri,
I5_xchg,
I5_xthl,
I5_rim,
I5_sim,
//
// Z80 extensions
//
Z80_and,
Z80_bit,
Z80_call,
Z80_ccf,
Z80_cp,
Z80_cpd,
Z80_cpdr,
Z80_cpi,
Z80_cpir,
Z80_cpl,
Z80_dec,
Z80_djnz,
Z80_ex,
Z80_exx,
Z80_halt,
Z80_im,
Z80_inc,
Z80_ind,
Z80_indr,
Z80_ini,
Z80_inir,
Z80_jp,
Z80_jr,
Z80_ld,
Z80_ldd,
Z80_lddr,
Z80_ldi,
Z80_ldir,
Z80_neg,
Z80_or,
Z80_otdr,
Z80_otir,
Z80_outd,
Z80_outi,
Z80_res,
Z80_ret,
Z80_reti,
Z80_retn,
Z80_rl,
Z80_rla,
Z80_rlc,
Z80_rlca,
Z80_rld,
Z80_rr,
Z80_rra,
Z80_rrc,
Z80_rrca,
Z80_rrd,
Z80_scf,
Z80_sbc,
Z80_set,
Z80_sla,
Z80_sra,
Z80_srl,
Z80_xor,
Z80_inp, // undocumented
Z80_outp, // undocumented
Z80_srr, // undocumented
//
// HD64180 extensions
//
HD_in0, Z80_in0 = HD_in0,
HD_mlt, Z80_mlt = HD_mlt,
HD_otim, Z80_otim = HD_otim,
HD_otimr, Z80_otimr = HD_otimr,
HD_otdm, Z80_otdm = HD_otdm,
HD_otdmr, Z80_otdmr = HD_otdmr,
HD_out0, Z80_out0 = HD_out0,
HD_slp, Z80_slp = HD_slp,
HD_tst, Z80_tst = HD_tst,
HD_tstio, Z80_tstio = HD_tstio,
//
// A80 special instructions
//
A80_lbcd,
A80_lded,
A80_lspd,
A80_lixd,
A80_liyd,
A80_sbcd,
A80_sded,
A80_sspd,
A80_sixd,
A80_siyd,
A80_xtix,
A80_xtiy,
A80_spix,
A80_spiy,
A80_pcix,
A80_pciy,
A80_mvra,
A80_mvia,
A80_mvar,
A80_mvai,
A80_addix,
A80_addiy,
A80_addc,
A80_addcix,
A80_addciy,
A80_subc,
A80_subcix,
A80_subciy,
A80_jrc,
A80_jrnc,
A80_jrz,
A80_jrnz,
A80_cmpi,
A80_cmpd,
A80_im0,
A80_im1,
A80_im2,
A80_otd,
A80_oti,
// Intel 8085 undocumented instructions
// (info from http://oak.oakland.edu/pub/cpm/maclib/i8085.lib)
I5_dsub, // (HL) <- (HL)-(BC), affects all flags
I5_arhl, // SHIFT HL RIGHT ONE BIT, (H7 IS DUPLICATED, L0 IS SHIFTED INTO CY)
I5_rdel, // ROTATE DE LEFT ONE BIT THRU CY, (E0 RECEIVES CY, CY RECEIVES D7)
I5_ldhi, // (DE) <- (HL)+arg
I5_ldsi, // (DE) <- (SP)+arg
I5_shlx, // ((DE)) <- (HL)
I5_lhlx, // (HL) <- ((DE))
I5_rstv, // RESTART 40H ON V (OVERFLOW)
I5_jx5, // JUMP IF X5 SET
I5_jnx5, // JUMP IF NOT X5 SET
// Z380 instructions
Z80_cplw, // Complement HL register
Z80_swap, // Swap upper register word with lower register word
Z80_inw, // Input word
Z80_outw, // Output word
Z80_ldw, // Load word
Z80_addw, // Add word
Z80_subw, // Subtract word
Z80_adcw, // Add with carry word
Z80_sbcw, // Subtract with borrow word
Z80_andw, // AND logical word
Z80_xorw, // XOR logical word
Z80_orw, // OR logical word
Z80_cpw, // Compare word
Z80_ddir, // Decoder directive
Z80_calr, // Call relative
Z80_ldctl, // Load control register
Z80_mtest, // Mode test
Z80_exxx, // Exchange Index Register with Alternate Bank
Z80_exxy, // Exchange Index Register with Alternate Bank
Z80_exall, // Exchange all registers with Alternate Bank
Z80_setc, // Set control bit
Z80_resc, // Reset control bit
Z80_rlcw, // Rotate Left Circular Word
Z80_rrcw, // Rotate Right Circular Word
Z80_rlw, // Rotate Left Word
Z80_rrw, // Rotate Right Word
Z80_slaw, // Shift Left Arithmetic Word
Z80_sraw, // Shift Right Arithmetic Word
Z80_srlw, // Shift Right Logical Word
Z80_multw, // Multiply Word
Z80_multuw, // Multiply Word Unsigned
Z80_divuw, // Divide unsigned
Z80_outaw, // Output word direct to port address
Z80_inaw, // Input word direct from port address
Z80_outa, // Output byte direct to port address
Z80_ina, // Input byte direct from port address
Z80_negw, // Negate word
Z80_exts, // Extend byte sign
Z80_extsw, // Extend word sign
Z80_btest, // Bank test
Z80_ldiw, // Load and increment (word)
Z80_ldirw, // Load and increment, repeat (word)
Z80_lddw, // Load and decrement (word)
Z80_lddrw, // Load and decrement, repeat (word)
Z80_iniw, // Input and increment (word)
Z80_inirw, // Input and increment, repeat (word)
Z80_indw, // Input and decrement (word)
Z80_indrw, // Input and decrement, repeat (word)
Z80_outiw, // Output and increment (word)
Z80_otirw, // Output and increment, repeat (word)
Z80_outdw, // Output and decrement (word)
Z80_otdrw, // Output and decrement, repeat (word)
// Gameboy instructions
GB_ldh,
GB_stop,
I5_last,
};
#endif

View File

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

321
idasdk76/module/z80/out.cpp Normal file
View File

@@ -0,0 +1,321 @@
/*
* Interactive disassembler (IDA).
* Version 2.06
* Copyright (c) 1990-93 by Ilfak Guilfanov. (2:5020/209@fidonet)
* ALL RIGHTS RESERVED.
*
*/
#include "i5.hpp"
//----------------------------------------------------------------------
class out_z80_t : public outctx_t
{
out_z80_t(void) = delete; // not used
z80_t &pm() { return *static_cast<z80_t *>(procmod); }
public:
void OutReg(int rgnum);
bool out_operand(const op_t &x);
void out_insn(void);
};
CASSERT(sizeof(out_z80_t) == sizeof(outctx_t));
DECLARE_OUT_FUNCS_WITHOUT_OUTMNEM(out_z80_t)
//----------------------------------------------------------------------
static const char *const condNames[] =
{
"nz",
"z",
"nc",
"c",
"po",
"pe",
"p",
"m"
};
//----------------------------------------------------------------------
void out_z80_t::OutReg(int rgnum)
{
if ( (ash.uflag & UAS_NPAIR) != 0 )
{
switch ( rgnum )
{
case R_bc: out_register(ph.reg_names[R_b]); return;
case R_de: out_register(ph.reg_names[R_d]); return;
case R_hl: out_register(ph.reg_names[R_h]); return;
}
}
if ( rgnum == R_af && pm().isZ80() && !pm().isFunny() )
out_register("af");
else
out_register(ph.reg_names[rgnum]);
}
//----------------------------------------------------------------------
bool out_z80_t::out_operand(const op_t &x)
{
if ( !x.shown() )
return false;
switch ( x.type )
{
case o_cond:
if ( x.Cond == oc_not )
return false;
{
char buf[3];
qstrncpy(buf, condNames[ x.Cond ], sizeof(buf));
if ( ash.uflag & UAS_CNDUP )
qstrupr(buf);
out_keyword(buf);
}
break;
case o_reg:
OutReg(x.reg);
break;
case o_displ: // Z80 only!!! + GB, one instruction
if ( ash.uflag & UAS_MKOFF )
out_value(x, OOF_ADDR|OOFW_16);
if ( !pm().isGB() )
out_symbol('(');
OutReg(x.phrase);
if ( !(ash.uflag & UAS_MKOFF) )
{
qstring buf;
if ( is_off(F, x.n)
&& get_offset_expression(&buf, insn.ea,x.n,insn.ea+x.offb,x.addr) )
{
out_symbol('+');
out_line(buf.c_str());
}
else
{
int offbit = (insn.auxpref & aux_off16) ? OOFW_16 : OOFW_8;
int outf = OOF_ADDR|offbit|OOFS_NEEDSIGN;
if ( ash.uflag & UAS_TOFF )
outf |= OOF_SIGNED;
out_value(x, outf);
}
}
if ( !pm().isGB() )
out_symbol(')');
break;
case o_phrase:
if ( pm().isZ80() && !pm().isFunny() )
{
out_symbol((ash.uflag & UAS_GBASM) ? '[' : '(');
OutReg(x.phrase);
out_symbol((ash.uflag & UAS_GBASM) ? ']' : ')');
}
else
{
if ( x.phrase == R_hl )
out_register("m");
else
OutReg(x.phrase);
}
break;
case o_void:
return 0;
case o_imm:
{
const char *name = NULL;
bool needbrace = false;
if ( pm().isZ80() )
{
switch ( insn.itype )
{
case I5_rst:
if ( pm().isFunny() )
{
int radix = get_radix(F, x.n);
out_long(x.value/8, radix);
return 1;
}
case Z80_im:
case Z80_bit:
case Z80_res:
case Z80_set:
// name = pm().find_ioport_bit(x.value);
break;
case HD_in0:
case HD_out0:
name = pm().find_ioport(x.value);
// fallthrough
case I5_in:
case I5_out:
case Z80_outaw:
case Z80_inaw:
if ( !pm().isFunny() )
{
out_symbol('(');
needbrace = true;
}
break;
default:
if ( ash.uflag & UAS_MKIMM )
out_symbol('#');
break;
}
}
if ( name != NULL )
out_line(name, COLOR_IMPNAME);
else
out_value(x, 0);
if ( needbrace )
out_symbol(')');
}
break;
case o_mem:
if ( pm().isZ80() && !pm().isFunny() )
out_symbol((ash.uflag & UAS_GBASM) ? '[' : '(');
// no break
case o_near:
{
ea_t v = map_ea(insn, x, x.type == o_near);
if ( v == insn.ea && ash.a_curip != NULL )
{
out_line(ash.a_curip);
}
else if ( !out_name_expr(x, v, x.addr) )
{
out_tagon(COLOR_ERROR);
out_btoa(x.addr,16);
out_tagoff(COLOR_ERROR);
remember_problem(PR_NONAME,insn.ea);
}
if ( x.type == o_mem && pm().isZ80() && !pm().isFunny() )
out_symbol((ash.uflag & UAS_GBASM) ? ']' : ')');
}
break;
default:
warning("bad optype %x", x.type);
break;
}
return 1;
}
//----------------------------------------------------------------------
static bool isIxyByte(const op_t &x)
{
return x.type == o_reg
&& (x.reg == R_xl
|| x.reg == R_xh
|| x.reg == R_yl
|| x.reg == R_yh);
}
//----------------------------------------------------------------------
inline bool isIxyOperand(const op_t &x)
{
return isIxyByte(x) || x.type == o_displ;
}
//----------------------------------------------------------------------
void out_z80_t::out_insn(void)
{
out_mnemonic();
bool comma = out_one_operand(0);
if ( comma && insn.Op2.shown() && insn.Op2.type != o_void )
{
out_symbol(',');
out_symbol(' ');
}
out_one_operand(1);
out_immchar_cmts();
flush_outbuf();
}
//--------------------------------------------------------------------------
void z80_t::i5_header(outctx_t &ctx)
{
ctx.gen_header(GH_PRINT_ALL_BUT_BYTESEX, ioh.device.c_str(), ioh.deviceparams.c_str());
}
//--------------------------------------------------------------------------
//lint -esym(1764, ctx) could be made const
//lint -esym(818, segm) could be made const
void z80_t::i5_segstart(outctx_t &ctx, segment_t *segm)
{
qstring sname;
get_segm_name(&sname, segm);
if ( ash.uflag & UAS_GBASM )
{
validate_name(&sname, VNT_IDENT);
ctx.gen_printf(DEFAULT_INDENT, COLSTR("SECTION \"%s\", %s",SCOLOR_ASMDIR),
sname.c_str(),
segtype(ctx.insn_ea) == SEG_CODE ? "CODE" : "DATA");
}
else if ( ash.uflag & UAS_ZMASM )
{
const char *dir = "segment";
if ( sname == ".text"
|| sname == ".data"
|| sname == ".bss" )
{
sname.clear();
dir = sname.c_str();
}
else
{
validate_name(&sname, VNT_IDENT);
}
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s %s",SCOLOR_ASMDIR), dir, sname.c_str());
}
else if ( ash.uflag & UAS_CSEGS )
{
validate_name(&sname, VNT_IDENT);
ctx.gen_cmt_line("segment '%s'", sname.c_str());
ctx.gen_printf(DEFAULT_INDENT,COLSTR("%cseg",SCOLOR_ASMDIR),segm->align == saAbs ? 'a' : 'c');
}
if ( (inf_get_outflags() & OFLG_GEN_ORG) != 0 )
{
ea_t org = ctx.insn_ea - get_segm_base(segm);
if ( org != 0 )
{
char buf[MAX_NUMBUF];
btoa(buf, sizeof(buf), org);
ctx.gen_printf(DEFAULT_INDENT, COLSTR("%s %s", SCOLOR_ASMDIR), ash.origin, buf);
}
}
}
//--------------------------------------------------------------------------
void z80_t::i5_footer(outctx_t & ctx)
{
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 )
{
if ( ash.uflag & UAS_NOENS )
{
ctx.out_char(' ');
ctx.out_line(ash.cmnt);
}
ctx.out_char(' ');
ctx.out_line(name.begin());
}
ctx.flush_outbuf(DEFAULT_INDENT);
}
else
{
ctx.gen_cmt_line("end of file");
}
}

1084
idasdk76/module/z80/reg.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,239 @@
.Z80180
; Enhanced Z80 Megacell
; http://www.zilog.com/products/partdetails.asp?id=Z80180
; INPUT/ OUTPUT PORTS
CNTLA0 0x0000 ASCI Channel Control Register A 0
CNTLA0.MPE 7 Multi-Processor Mode Enable
CNTLA0.RE 6 Receiver Enable
CNTLA0.TE 5 Transmitter Enable
CNTLA0._RTS0 4 Request to Send Channel 0
CNTLA0.MPBR_EFR 3 Multiprocessor Bit Receive/Error Flag Reset
CNTLA0.MOD2 2 ASCI Data Format Mode 2
CNTLA0.MOD1 1 ASCI Data Format Mode 1
CNTLA0.MOD0 0 ASCI Data Format Mode 0
CNTLA1 0x0001 ASCI Channel Control Register A 0
CNTLA1.MPE 7 Multi-Processor Mode Enable
CNTLA1.RE 6 Receiver Enable
CNTLA1.TE 5 Transmitter Enable
CNTLA1._RTS0 4 Request to Send Channel 0
CNTLA1.MPBR_EFR 3 Multiprocessor Bit Receive/Error Flag Reset
CNTLA1.MOD2 2 ASCI Data Format Mode 2
CNTLA1.MOD1 1 ASCI Data Format Mode 1
CNTLA1.MOD0 0 ASCI Data Format Mode 0
CNTLB0 0x0002 ASCI Channel Control Register B 0
CNTLB0.MPBT 7 Multiprocessor Bit Transmit
CNTLB0.MP 6 Multiprocessor Mode
CNTLB0.__CTS_PS 5 Clear to Send/Prescale
CNTLB0.PEO 4 Parity Even Odd
CNTLB0.DR 3 Divide Ratio
CNTLB0.SS2 2 Source/Speed Select 2
CNTLB0.SS1 1 Source/Speed Select 1
CNTLB0.SS0 0 Source/Speed Select 0
CNTLB1 0x0003 ASCI Channel Control Register B 1
CNTLB1.MPBT 7 Multiprocessor Bit Transmit
CNTLB1.MP 6 Multiprocessor Mode
CNTLB1.__CTS_PS 5 Clear to Send/Prescale
CNTLB1.PEO 4 Parity Even Odd
CNTLB1.DR 3 Divide Ratio
CNTLB1.SS2 2 Source/Speed Select 2
CNTLB1.SS1 1 Source/Speed Select 1
CNTLB1.SS0 0 Source/Speed Select 0
STAT0 0x0004 ASCI Status Register 0
STAT0.RDRF 7 Receive Data Register Full
STAT0.OVRN 6 Overrun Error
STAT0.PE 5 Parity Error
STAT0.FE 4 Framing Error
STAT0.REI 3 Receive Interrupt Enable
STAT0._DCD0 2 Data Carrier Detect
STAT0.TDRE 1 Transmit Data Register Empty
STAT0.TIE 0 Transmit Interrupt Enable
STAT1 0x0005 ASCI Status Register 1
STAT1.RDRF 7 Receive Data Register Full
STAT1.OVRN 6 Overrun Error
STAT1.PE 5 Parity Error
STAT1.FE 4 Framing Error
STAT1.REI 3 Receive Interrupt Enable
STAT1.TDRE 1 Transmit Data Register Empty
STAT1.TIE 0 Transmit Interrupt Enable
TDR0 0x0006
TDR1 0x0007
RDR0 0x0008
RDR1 0x0009
CNTR 0x000A CSIO Control/Status Register
CNTR.EF 7 End Flag
CNTR.EIE 6 End Interrupt Enable
CNTR.RE 5 Receive Enable
CNTR.TE 4 Transmit Enable
CNTR.SS2 2 Speed Select 2
CNTR.SS1 1 Speed Select 1
CNTR.SS0 0 Speed Select 0
TRDR 0x000B CSIO Transmit/Receive Data Register
TMDR0L 0x000C Timer Data Register Channel 0L
TMDR0H 0x000D Timer Data Register Channel 0H
RLDR0L 0x000E Timer Reload Register 0L
RLDR0H 0x000F Timer Reload Register 0H
TCR 0x0010 Timer Control Register
TCR.TIF1 7 Timer Interrupt Flag 1
TCR.TIF0 6 Timer Interrupt Flag 0
TCR.TIE1 5 Timer Interrupt Enable 1
TCR.TIE0 4 Timer Interrupt Enable 0
TCR.TOC1 3 Timer Output Control
TCR.TOC0 2 Timer Output Control
TCR.TDE1 1
TCR.TDE0 0
TMDR1L 0x0014 Timer Data Register Channel 1L
TMDR1H 0x0015 Timer Data Register Channel 1H
RLDR1L 0x0016 Timer Reload Register 1L
RLDR1H 0x0017 Timer Reload Register 1H
FRC 0x0018 Free Running Counter
SAR0L 0x0020 DMA Source Address Register Channel 0L
SAR0H 0x0021 DMA Source Address Register Channel 0H
SAR0B 0x0022 DMA Source Address Register Channel 0B
DAR0L 0x0023 DMA Destination Address Register Channel 0L
DAR0H 0x0024 DMA Destination Address Register Channel 0H
DAR0B 0x0025 DMA Destination Address Register Channel 0B
BCR0L 0x0026 DMA Byte Count Register Channel 0L
BCR0H 0x0027 DMA Byte Count Register Channel 0H
MAR1L 0x0028 DMA Memory Address Register, Channel 1L
MAR1H 0x0029 DMA Memory Address Register, Channel 1H
MAR1B 0x002A DMA Memory Address Register, Channel 1B
IAR1L 0x002B DMA I/O Address Register Channel 1L
IAR1H 0x002C DMA I/O Address Register Channel 1H
BCR1L 0x002E DMA Byte Count Register Channel 1L
BCR1H 0x002F DMA Byte Count Register Channel 1H
DSTAT 0x0030 DMA Status Register
DSTAT.DE1 7 DE1: DMA Enable Channel 1
DSTAT.DE0 6 DE0: DMA Enable Channel 0
DSTAT.DWE1 5 DE1 Bit WRITE Enable
DSTAT.DWE0 4 DE0 Bit WRITE Enable
DSTAT.DIE1 3 DMA Interrupt Enable Channel
DSTAT.DIE0 2 DMA Interrupt Enable Channel
DSTAT.DME 0 DMA Main Enable
DMODE 0x0031 DMA Mode Register
DMODE.DM1 5 Destination Mode Channel 0
DMODE.DM0 4 Destination Mode Channel 0
DMODE.SM1 3 Source Mode Channel 0
DMODE.SM0 2 Source Mode Channel 0
DMODE.MMOD 1 Memory Mode Channel 0
DCNTL 0x0032 DMA/WAIT Control Register
DCNTL.MWI1 7 Memory Wait Insertion
DCNTL.MWI0 6 Memory Wait Insertion
DCNTL.IWI1 5 I/O Wait Insertion
DCNTL.IWI0 4 I/O Wait Insertion
DCNTL.DMS1 3 DMA Request Sense
DCNTL.DMS0 2 DMA Request Sense
DCNTL.DIM1 1 DMA Channel 1 I/O and Memory Mode
DCNTL.DIM0 0 DMA Channel 1 I/O and Memory Mode
IL 0x0033 Interrupt Vector Low Register
IL.IL7 7
IL.IL6 6
IL.IL5 5
ITC 0x0034 Int/TRAP Control Register
ITC.TRAP 7
ITC.UFO 6 Undefined Fetch Object
ITC.ITE2 2 Interrupt Enable 2
ITC.ITE1 1 Interrupt Enable 1
ITC.ITE0 0 Interrupt Enable 0
RCR 0x0036 Refresh Control Register
RCR.REFE 7 Refresh Enable
RCR.REFW 6 Refresh Wait
RCR.CYC1 1 Cycle Interval
RCR.CYC0 0 Cycle Interval
CBR 0x0038 MMU Common Base Register (CBR)
CBR.CB7 7
CBR.CB6 6
CBR.CB5 5
CBR.CB4 4
CBR.CB3 3
CBR.CB2 2
CBR.CB1 1
CBR.CB0 0
BBR 0x0039 MMU Bank Base Register (BBR)
BBR.BB7 7
BBR.BB6 6
BBR.BB5 5
BBR.BB4 4
BBR.BB3 3
BBR.BB2 2
BBR.BB1 1
BBR.BB0 0
CBAR 0x003A MMU Common/Bank Area Register (CBAR)
CBAR.CA3 7
CBAR.CA2 6
CBAR.CA1 5
CBAR.CA0 4
CBAR.BA3 3
CBAR.BA2 2
CBAR.BA1 1
CBAR.BA0 0
OMCR 0x003E Operation Mode Control Register
OMCR.MIE 7
OMCR._MITE 6
OMCR._IOC 5
ICR 0x003F I/O Control Register (ICR)
ICR.IOA7 7
ICR.IOA6 6
ICR.IOSTP 5
.Z80181
; Smart Access Controller
.Z80182
; ZiLOG Intelligent Peripheral (ZIPT)
.Z80189
.Z8S180
; + Parallel I/O
.Z80195
; Smart Peripheral Controller (ROMless)
.Z80L183
; Mixed-Signal Z183 Internet Processor
.Z80S183
; Mixed-Signal Z183 Internet Processor
.Z8L180
; Enhanced Z80 Megacell
.Z8L180
; Low-Voltage Version (3.3 V)
.Z8L182
; ZiLOG Intelligent Peripheral (ZIPT) - Low Voltage Version
.Z8S180
; Enhanced Z80 Megacell
.Z8L180
; Low-Voltage Version (3.3 V)