231 lines
6.1 KiB
C++
231 lines
6.1 KiB
C++
/*
|
|
* 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
|