mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1442 lines
41 KiB
1442 lines
41 KiB
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
#include "ntdis.h"
|
|
|
|
|
|
|
|
typedef LPCH FAR *LPLPCH;
|
|
|
|
#define MAXL 20
|
|
|
|
char lhexdigit[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
|
|
char uhexdigit[] = { '0', '1', '2', '3', '4', '5', '6', '7',
|
|
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
|
|
char *hexdigit = &uhexdigit[0];
|
|
static int fUpper = TRUE;
|
|
|
|
/* current position in instruction */
|
|
static unsigned char FAR*pMem = (unsigned char *)NULL;
|
|
|
|
static int EAsize [2] = {0}; // size of effective address item
|
|
static long EAaddr [2] = {0}; // offset of effective address
|
|
|
|
int DumpAddress ( LPADDR, LPCH, int );
|
|
int DumpGeneric ( LSZ, LPCH, int );
|
|
int DumpComment ( LSZ, LPCH, int );
|
|
int DumpEA ( HPID, HTID, LPADDR, LPCH, int );
|
|
|
|
void OutputAddr(LPLPCH, LPADDR, int );
|
|
void OutputHexString(LPLPCH, LPCH, int);
|
|
void OutputHexCode(LPLPCH, LPCH, int);
|
|
|
|
UCHAR pszUndef[] = "????";
|
|
UCHAR pszNull[] = "";
|
|
|
|
UCHAR pszAbs_s[] = "abs.s";
|
|
UCHAR pszAdd[] = "add";
|
|
UCHAR pszAdd_s[] = "add.s";
|
|
UCHAR pszAddi[] = "addi";
|
|
UCHAR pszAddiu[] = "addiu";
|
|
UCHAR pszAddu[] = "addu";
|
|
UCHAR pszAnd[] = "and";
|
|
UCHAR pszAndi[] = "andi";
|
|
UCHAR pszBc0f[] = "bc0f";
|
|
UCHAR pszBc0fl[] = "bc0fl";
|
|
UCHAR pszBc0t[] = "bc0t";
|
|
UCHAR pszBc0tl[] = "bc0tl";
|
|
UCHAR pszBc1f[] = "bc1f";
|
|
UCHAR pszBc1fl[] = "bc1fl";
|
|
UCHAR pszBc1t[] = "bc1t";
|
|
UCHAR pszBc1tl[] = "bc1tl";
|
|
UCHAR pszBc2f[] = "bc2f";
|
|
UCHAR pszBc2fl[] = "bc2fl";
|
|
UCHAR pszBc2t[] = "bc2t";
|
|
UCHAR pszBc2tl[] = "bc2tl";
|
|
UCHAR pszBc3f[] = "bc3f";
|
|
UCHAR pszBc3fl[] = "bc3fl";
|
|
UCHAR pszBc3t[] = "bc3t";
|
|
UCHAR pszBc3tl[] = "bc3tl";
|
|
UCHAR pszBgez[] = "bgez";
|
|
UCHAR pszBgezal[] = "bgezal";
|
|
UCHAR pszBgezall[] = "bgezall";
|
|
UCHAR pszBgezl[] = "bgezl";
|
|
UCHAR pszBgtz[] = "bgtz";
|
|
UCHAR pszBgtzl[] = "bgtzl";
|
|
UCHAR pszBeq[] = "beq";
|
|
UCHAR pszBeql[] = "beql";
|
|
UCHAR pszBlez[] = "blez";
|
|
UCHAR pszBlezl[] = "blezl";
|
|
UCHAR pszBltz[] = "bltz";
|
|
UCHAR pszBltzal[] = "bltzal";
|
|
UCHAR pszBltzall[] = "bltzall";
|
|
UCHAR pszBltzl[] = "bltzl";
|
|
UCHAR pszBne[] = "bne";
|
|
UCHAR pszBnel[] = "bnel";
|
|
UCHAR pszBreak[] = "break";
|
|
UCHAR pszCache[] = "cache";
|
|
UCHAR pszCeil_w_s[] = "ceil.w.s";
|
|
UCHAR pszCfc0[] = "cfc0";
|
|
UCHAR pszCfc1[] = "cfc1";
|
|
UCHAR pszCfc2[] = "cfc2";
|
|
UCHAR pszCfc3[] = "cfc3";
|
|
UCHAR pszCtc0[] = "ctc0";
|
|
UCHAR pszCtc1[] = "ctc1";
|
|
UCHAR pszCtc2[] = "ctc2";
|
|
UCHAR pszCtc3[] = "ctc3";
|
|
UCHAR pszCop0[] = "cop0";
|
|
UCHAR pszCop1[] = "cop1";
|
|
UCHAR pszCop2[] = "cop2";
|
|
UCHAR pszCop3[] = "cop3";
|
|
UCHAR pszCvt_d_s[] = "cvt.d.s";
|
|
UCHAR pszCvt_e_s[] = "cvt.e.s";
|
|
UCHAR pszCvt_q_s[] = "cvt.q.s";
|
|
UCHAR pszCvt_s_s[] = "cvt.s.s";
|
|
UCHAR pszCvt_w_s[] = "cvt.w.s";
|
|
UCHAR pszC_eq_s[] = "c.eq.s";
|
|
UCHAR pszC_f_s[] = "c.f.s";
|
|
UCHAR pszC_le_s[] = "c.le.s";
|
|
UCHAR pszC_lt_s[] = "c.lt.s";
|
|
UCHAR pszC_nge_s[] = "c.nge.s";
|
|
UCHAR pszC_ngl_s[] = "c.ngl.s";
|
|
UCHAR pszC_ngle_s[] = "c.ngle.s";
|
|
UCHAR pszC_ngt_s[] = "c.ngt.s";
|
|
UCHAR pszC_ole_s[] = "c.ole.s";
|
|
UCHAR pszC_olt_s[] = "c.olt.s";
|
|
UCHAR pszC_seq_s[] = "c.seq.s";
|
|
UCHAR pszC_sf_s[] = "c.sf.s";
|
|
UCHAR pszC_ueq_s[] = "c.ueq.s";
|
|
UCHAR pszC_ule_s[] = "c.ule.s";
|
|
UCHAR pszC_ult_s[] = "c.ult.s";
|
|
UCHAR pszC_un_s[] = "c.un.s";
|
|
UCHAR pszDiv[] = "div";
|
|
UCHAR pszDivu[] = "divu";
|
|
UCHAR pszDiv_s[] = "div.s";
|
|
UCHAR pszEret[] = "eret";
|
|
UCHAR pszFloor_w_s[] = "floor.w.s";
|
|
UCHAR pszJ[] = "j";
|
|
UCHAR pszJal[] = "jal";
|
|
UCHAR pszJalr[] = "jalr";
|
|
UCHAR pszJr[] = "jr";
|
|
UCHAR pszLb[] = "lb";
|
|
UCHAR pszLbu[] = "lbu";
|
|
UCHAR pszLdc1[] = "ldc1";
|
|
UCHAR pszLdc2[] = "ldc2";
|
|
UCHAR pszLdc3[] = "ldc3";
|
|
UCHAR pszLh[] = "lh";
|
|
UCHAR pszLhu[] = "lhu";
|
|
UCHAR pszLl[] = "ll";
|
|
UCHAR pszLui[] = "lui";
|
|
UCHAR pszLw[] = "lw";
|
|
UCHAR pszLwc1[] = "lwc1";
|
|
UCHAR pszLwc2[] = "lwc2";
|
|
UCHAR pszLwc3[] = "lwc3";
|
|
UCHAR pszLwl[] = "lwl";
|
|
UCHAR pszLwr[] = "lwr";
|
|
UCHAR pszMfc0[] = "mfc0";
|
|
UCHAR pszMfc1[] = "mfc1";
|
|
UCHAR pszMfc2[] = "mfc2";
|
|
UCHAR pszMfc3[] = "mfc3";
|
|
UCHAR pszMfhi[] = "mfhi";
|
|
UCHAR pszMflo[] = "mflo";
|
|
UCHAR pszMov_s[] = "mov.s";
|
|
UCHAR pszMtc0[] = "mtc0";
|
|
UCHAR pszMtc1[] = "mtc1";
|
|
UCHAR pszMtc2[] = "mtc2";
|
|
UCHAR pszMtc3[] = "mtc3";
|
|
UCHAR pszMthi[] = "mthi";
|
|
UCHAR pszMtlo[] = "mtlo";
|
|
UCHAR pszMul_s[] = "mul.s";
|
|
UCHAR pszMult[] = "mult";
|
|
UCHAR pszMultu[] = "multu";
|
|
UCHAR pszNeg_s[] = "neg.s";
|
|
UCHAR pszNop[] = "nop";
|
|
UCHAR pszNor[] = "nor";
|
|
UCHAR pszOr[] = "or";
|
|
UCHAR pszOri[] = "ori";
|
|
UCHAR pszRfe[] = "rfe";
|
|
UCHAR pszRound_w_s[] = "round.w.s";
|
|
UCHAR pszSb[] = "sb";
|
|
UCHAR pszSc[] = "sc";
|
|
UCHAR pszSdc1[] = "sdc1";
|
|
UCHAR pszSdc2[] = "sdc2";
|
|
UCHAR pszSdc3[] = "sdc3";
|
|
UCHAR pszSh[] = "sh";
|
|
UCHAR pszSll[] = "sll";
|
|
UCHAR pszSllv[] = "sllv";
|
|
UCHAR pszSlt[] = "slt";
|
|
UCHAR pszSlti[] = "slti";
|
|
UCHAR pszSltiu[] = "sltiu";
|
|
UCHAR pszSltu[] = "sltu";
|
|
UCHAR pszSqrt_s[] = "sqrt.s";
|
|
UCHAR pszSra[] = "sra";
|
|
UCHAR pszSrav[] = "srav";
|
|
UCHAR pszSrl[] = "srl";
|
|
UCHAR pszSrlv[] = "srlv";
|
|
UCHAR pszSub[] = "sub";
|
|
UCHAR pszSub_s[] = "sub.s";
|
|
UCHAR pszSubu[] = "subu";
|
|
UCHAR pszSw[] = "sw";
|
|
UCHAR pszSwc1[] = "swc1";
|
|
UCHAR pszSwc2[] = "swc2";
|
|
UCHAR pszSwc3[] = "swc3";
|
|
UCHAR pszSwl[] = "swl";
|
|
UCHAR pszSwr[] = "swr";
|
|
UCHAR pszSync[] = "sync";
|
|
UCHAR pszSyscall[] = "syscall";
|
|
UCHAR pszTeq[] = "teq";
|
|
UCHAR pszTeqi[] = "teqi";
|
|
UCHAR pszTge[] = "tge";
|
|
UCHAR pszTgei[] = "tgei";
|
|
UCHAR pszTgeiu[] = "tgeiu";
|
|
UCHAR pszTgeu[] = "tgeu";
|
|
UCHAR pszTlbp[] = "tlbp";
|
|
UCHAR pszTlbr[] = "tlbr";
|
|
UCHAR pszTlbwi[] = "tlbwi";
|
|
UCHAR pszTlbwr[] = "tlbwr";
|
|
UCHAR pszTlt[] = "tlt";
|
|
UCHAR pszTlti[] = "tlti";
|
|
UCHAR pszTltiu[] = "tltiu";
|
|
UCHAR pszTltu[] = "tltu";
|
|
UCHAR pszTne[] = "tne";
|
|
UCHAR pszTnei[] = "tnei";
|
|
UCHAR pszTrunc_w_s[] = "trunc.w.s";
|
|
UCHAR pszXor[] = "xor";
|
|
UCHAR pszXori[] = "xori";
|
|
|
|
|
|
typedef struct optabentry {
|
|
PUCHAR pszOpcode;
|
|
ULONG fInstruction;
|
|
} OPTABENTRY, *POPTABENTRY;
|
|
|
|
OPTABENTRY opTable[] = {
|
|
{ pszNull, 0 }, // 00
|
|
{ pszNull, 0 }, // 01
|
|
{ pszJ, opnAddr26 }, // 02
|
|
{ pszJal, opnAddr26 }, // 03
|
|
{ pszBeq, opnRsRtRel16 }, // 04
|
|
{ pszBne, opnRsRtRel16 }, // 05
|
|
{ pszBlez, opnRsRel16 }, // 06
|
|
{ pszBgtz, opnRsRel16 }, // 07
|
|
{ pszAddi, opnRtRsImm16 }, // 08
|
|
{ pszAddiu, opnRtRsImm16 }, // 09
|
|
{ pszSlti, opnRtRsImm16 }, // 0a
|
|
{ pszSltiu, opnRtRsImm16 }, // 0b
|
|
{ pszAndi, opnRtRsUImm16 }, // 0c
|
|
{ pszOri, opnRtRsUImm16 }, // 0d
|
|
{ pszXori, opnRtRsUImm16 }, // 0e
|
|
{ pszLui, opnRtUImm16 }, // 0f
|
|
{ pszCop0, opnImm26 }, // 10
|
|
{ pszCop1, opnImm26 }, // 11
|
|
{ pszCop2, opnImm26 }, // 12
|
|
{ pszCop3, opnImm26 }, // 13
|
|
{ pszBeql, opnRsRtRel16 + opnR4000 }, // 14
|
|
{ pszBnel, opnRsRtRel16 + opnR4000 }, // 15
|
|
{ pszBlezl, opnRsRel16 + opnR4000 }, // 16
|
|
{ pszBgtzl, opnRsRel16 + opnR4000 }, // 17
|
|
{ pszUndef, 0 }, // 18
|
|
{ pszUndef, 0 }, // 19
|
|
{ pszUndef, 0 }, // 1a
|
|
{ pszUndef, 0 }, // 1b
|
|
{ pszUndef, 0 }, // 1c
|
|
{ pszUndef, 0 }, // 1d
|
|
{ pszUndef, 0 }, // 1e
|
|
{ pszUndef, 0 }, // 1f
|
|
{ pszLb, opnRtByteIndex }, // 20
|
|
{ pszLh, opnRtWordIndex }, // 21
|
|
{ pszLwl, opnRtLeftIndex }, // 22
|
|
{ pszLw, opnRtDwordIndex }, // 23
|
|
{ pszLbu, opnRtByteIndex }, // 24
|
|
{ pszLhu, opnRtWordIndex }, // 25
|
|
{ pszLwr, opnRtRightIndex }, // 26
|
|
{ pszUndef, 0 }, // 27
|
|
{ pszSb, opnRtByteIndex }, // 28
|
|
{ pszSh, opnRtWordIndex }, // 29
|
|
{ pszSwl, opnRtLeftIndex }, // 2a
|
|
{ pszSw, opnRtDwordIndex }, // 2b
|
|
{ pszUndef, 0 }, // 2c
|
|
{ pszUndef, 0 }, // 2d
|
|
{ pszSwr, opnRtRightIndex }, // 2e
|
|
{ pszCache, opnCacheRightIndex + opnR4000 }, // 2f
|
|
{ pszLl, opnRtDwordIndex }, // 30
|
|
{ pszLwc1, opnFtDwordIndex }, // 31
|
|
{ pszLwc2, opnRxtDwordIndex }, // 32
|
|
{ pszLwc3, opnRxtDwordIndex }, // 33
|
|
{ pszUndef, 0 }, // 34
|
|
{ pszLdc1, opnFtDwordIndex + opnR4000 }, // 35 Qword?
|
|
{ pszLdc2, opnRxtDwordIndex + opnR4000 }, // 36 Qword?
|
|
{ pszLdc3, opnRxtDwordIndex + opnR4000 }, // 37 Qword?
|
|
{ pszSc, opnRtDwordIndex }, // 38
|
|
{ pszSwc1, opnFtDwordIndex }, // 39
|
|
{ pszSwc2, opnRxtDwordIndex }, // 3a
|
|
{ pszSwc3, opnRxtDwordIndex }, // 3b
|
|
{ pszUndef, 0 }, // 3c
|
|
{ pszSdc1, opnFtDwordIndex + opnR4000 }, // 3d Qword?
|
|
{ pszSdc2, opnRxtDwordIndex + opnR4000 }, // 3e Qword?
|
|
{ pszSdc3, opnRxtDwordIndex + opnR4000 }, // 3f Qword?
|
|
};
|
|
|
|
OPTABENTRY opSpecialTable[] = {
|
|
{ pszSll, opnRdRtShift }, // 00
|
|
{ pszUndef, 0 }, // 01
|
|
{ pszSrl, opnRdRtShift }, // 02
|
|
{ pszSra, opnRdRtShift }, // 03
|
|
{ pszSllv, opnRdRtRs }, // 04
|
|
{ pszUndef, 0 }, // 05
|
|
{ pszSrlv, opnRdRtRs }, // 06
|
|
{ pszSrav, opnRdRtRs }, // 07
|
|
{ pszJr, opnRs }, // 08
|
|
{ pszJalr, opnRdOptRs }, // 09
|
|
{ pszUndef, 0 }, // 0a
|
|
{ pszUndef, 0 }, // 0b
|
|
{ pszSyscall, opnNone }, // 0c
|
|
{ pszBreak, opnImm20 }, // 0d
|
|
{ pszUndef, 0 }, // 0e
|
|
{ pszSync, opnNone + opnR4000 }, // 0f
|
|
{ pszMfhi, opnRd }, // 10
|
|
{ pszMthi, opnRs }, // 11
|
|
{ pszMflo, opnRd }, // 12
|
|
{ pszMtlo, opnRs }, // 13
|
|
{ pszUndef, 0 }, // 14
|
|
{ pszUndef, 0 }, // 15
|
|
{ pszUndef, 0 }, // 16
|
|
{ pszUndef, 0 }, // 17
|
|
{ pszMult, opnRsRt }, // 18
|
|
{ pszMultu, opnRsRt }, // 19
|
|
{ pszDiv, opnRsRt }, // 1a
|
|
{ pszDivu, opnRsRt }, // 1b
|
|
{ pszUndef, 0 }, // 1c
|
|
{ pszUndef, 0 }, // 1d
|
|
{ pszUndef, 0 }, // 1e
|
|
{ pszUndef, 0 }, // 1f
|
|
{ pszAdd, opnRdRsRt }, // 20
|
|
{ pszAddu, opnRdRsRt }, // 21
|
|
{ pszSub, opnRdRsRt }, // 22
|
|
{ pszSubu, opnRdRsRt }, // 23
|
|
{ pszAnd, opnRdRsRt }, // 24
|
|
{ pszOr, opnRdRsRt }, // 25
|
|
{ pszXor, opnRdRsRt }, // 26
|
|
{ pszNor, opnRdRsRt }, // 27
|
|
{ pszUndef, 0 }, // 28
|
|
{ pszUndef, 0 }, // 29
|
|
{ pszSlt, opnRdRsRt }, // 2a
|
|
{ pszSltu, opnRdRsRt }, // 2b
|
|
{ pszUndef, 0 }, // 2c
|
|
{ pszUndef, 0 }, // 2d
|
|
{ pszUndef, 0 }, // 2e
|
|
{ pszUndef, 0 }, // 2f
|
|
{ pszTge, opnRsRtImm10 + opnR4000 }, // 30
|
|
{ pszTgeu, opnRsRtImm10 + opnR4000 }, // 31
|
|
{ pszTlt, opnRsRtImm10 + opnR4000 }, // 32
|
|
{ pszTltu, opnRsRtImm10 + opnR4000 }, // 33
|
|
{ pszTeq, opnRsRtImm10 + opnR4000 }, // 34
|
|
{ pszUndef, 0 }, // 35
|
|
{ pszTne, opnRsRtImm10 + opnR4000 }, // 36
|
|
{ pszUndef, 0 }, // 37
|
|
{ pszUndef, 0 }, // 38
|
|
{ pszUndef, 0 }, // 39
|
|
{ pszUndef, 0 }, // 3a
|
|
{ pszUndef, 0 }, // 3b
|
|
{ pszUndef, 0 }, // 3c
|
|
{ pszUndef, 0 }, // 3d
|
|
{ pszUndef, 0 }, // 3e
|
|
{ pszUndef, 0 } // 3f
|
|
};
|
|
|
|
OPTABENTRY opBcondTable[] = {
|
|
{ pszBltz, opnRsRel16 }, // 00
|
|
{ pszBgez, opnRsRel16 }, // 01
|
|
{ pszBltzl, opnRsRel16 + opnR4000 }, // 02
|
|
{ pszBgezl, opnRsRel16 + opnR4000 }, // 03
|
|
{ pszUndef, 0 }, // 04
|
|
{ pszUndef, 0 }, // 05
|
|
{ pszUndef, 0 }, // 06
|
|
{ pszUndef, 0 }, // 07
|
|
{ pszTgei, opnRsImm16 + opnR4000 }, // 08
|
|
{ pszTgeiu, opnRsImm16 + opnR4000 }, // 09
|
|
{ pszTlti, opnRsImm16 + opnR4000 }, // 0a
|
|
{ pszTltiu, opnRsImm16 + opnR4000 }, // 0b
|
|
{ pszTeqi, opnRsImm16 + opnR4000 }, // 0c
|
|
{ pszUndef, 0 }, // 0d
|
|
{ pszTnei, opnRsImm16 + opnR4000 }, // 0e
|
|
{ pszUndef, 0 }, // 0f
|
|
{ pszBltzal, opnRsRel16 }, // 10
|
|
{ pszBgezal, opnRsRel16 }, // 11
|
|
{ pszBltzall, opnRsRel16 + opnR4000 }, // 12
|
|
{ pszBgezall, opnRsRel16 + opnR4000 } // 13
|
|
};
|
|
|
|
OPTABENTRY opCopnTable[] = {
|
|
{ pszMfc0, opnRtRxd }, // 00
|
|
{ pszMfc1, opnRtFs }, // 01
|
|
{ pszMfc2, opnRtRxd }, // 02
|
|
{ pszMfc3, opnRtRxd }, // 03
|
|
{ pszCfc0, opnRtRxd }, // 04
|
|
{ pszCfc1, opnRtFs }, // 05
|
|
{ pszCfc2, opnRtRxd }, // 06
|
|
{ pszCfc3, opnRtRxd }, // 07
|
|
{ pszMtc0, opnRtRxd }, // 08
|
|
{ pszMtc1, opnRtFs }, // 09
|
|
{ pszMtc2, opnRtRxd }, // 0a
|
|
{ pszMtc3, opnRtRxd }, // 0b
|
|
{ pszCtc0, opnRtRxd }, // 0c
|
|
{ pszCtc1, opnRtFs }, // 0d
|
|
{ pszCtc2, opnRtRxd }, // 0e
|
|
{ pszCtc3, opnRtRxd }, // 0f
|
|
{ pszBc0f, opnRel16 }, // 10
|
|
{ pszBc1f, opnRel16 }, // 11
|
|
{ pszBc2f, opnRel16 }, // 12
|
|
{ pszBc3f, opnRel16 }, // 13
|
|
{ pszBc0t, opnRel16 }, // 14
|
|
{ pszBc1t, opnRel16 }, // 15
|
|
{ pszBc2t, opnRel16 }, // 16
|
|
{ pszBc3t, opnRel16 }, // 17
|
|
{ pszBc0fl, opnRel16 + opnR4000 }, // 18
|
|
{ pszBc1fl, opnRel16 + opnR4000 }, // 19
|
|
{ pszBc2fl, opnRel16 + opnR4000 }, // 1a
|
|
{ pszBc3fl, opnRel16 + opnR4000 }, // 1b
|
|
{ pszBc0tl, opnRel16 + opnR4000 }, // 1c
|
|
{ pszBc1tl, opnRel16 + opnR4000 }, // 1d
|
|
{ pszBc2tl, opnRel16 + opnR4000 }, // 1e
|
|
{ pszBc3tl, opnRel16 + opnR4000 } // 1f
|
|
};
|
|
|
|
OPTABENTRY opFloatTable[] = {
|
|
{ pszAdd_s, opnFdFsFt }, // 00
|
|
{ pszSub_s, opnFdFsFt }, // 01
|
|
{ pszMul_s, opnFdFsFt }, // 02
|
|
{ pszDiv_s, opnFdFsFt }, // 03
|
|
{ pszSqrt_s, opnFdFs + opnR4000 }, // 04
|
|
{ pszAbs_s, opnFdFs }, // 05
|
|
{ pszMov_s, opnFdFs }, // 06
|
|
{ pszNeg_s, opnFdFs }, // 07
|
|
{ pszUndef, 0 }, // 08
|
|
{ pszUndef, 0 }, // 09
|
|
{ pszUndef, 0 }, // 0a
|
|
{ pszUndef, 0 }, // 0b
|
|
{ pszRound_w_s, opnFdFs + opnR4000 }, // 0c
|
|
{ pszTrunc_w_s, opnFdFs + opnR4000 }, // 0d
|
|
{ pszCeil_w_s, opnFdFs + opnR4000 }, // 0e
|
|
{ pszFloor_w_s, opnFdFs + opnR4000 }, // 0f
|
|
{ pszUndef, 0 }, // 10
|
|
{ pszUndef, 0 }, // 11
|
|
{ pszUndef, 0 }, // 12
|
|
{ pszUndef, 0 }, // 13
|
|
{ pszUndef, 0 }, // 14
|
|
{ pszUndef, 0 }, // 15
|
|
{ pszUndef, 0 }, // 16
|
|
{ pszUndef, 0 }, // 17
|
|
{ pszUndef, 0 }, // 18
|
|
{ pszUndef, 0 }, // 19
|
|
{ pszUndef, 0 }, // 1a
|
|
{ pszUndef, 0 }, // 1b
|
|
{ pszUndef, 0 }, // 1c
|
|
{ pszUndef, 0 }, // 1d
|
|
{ pszUndef, 0 }, // 1e
|
|
{ pszUndef, 0 }, // 1f
|
|
{ pszCvt_s_s, opnFdFs }, // 20
|
|
{ pszCvt_d_s, opnFdFs }, // 21
|
|
{ pszCvt_e_s, opnFdFs + opnR4000 }, // 22
|
|
{ pszCvt_q_s, opnFdFs + opnR4000 }, // 23
|
|
{ pszCvt_w_s, opnFdFs }, // 24
|
|
{ pszUndef, 0 }, // 25
|
|
{ pszUndef, 0 }, // 26
|
|
{ pszUndef, 0 }, // 27
|
|
{ pszUndef, 0 }, // 28
|
|
{ pszUndef, 0 }, // 29
|
|
{ pszUndef, 0 }, // 2a
|
|
{ pszUndef, 0 }, // 2b
|
|
{ pszUndef, 0 }, // 2c
|
|
{ pszUndef, 0 }, // 2d
|
|
{ pszUndef, 0 }, // 2e
|
|
{ pszUndef, 0 }, // 2f
|
|
{ pszC_f_s, opnFsFt }, // 30
|
|
{ pszC_un_s, opnFsFt }, // 31
|
|
{ pszC_eq_s, opnFsFt }, // 32
|
|
{ pszC_ueq_s, opnFsFt }, // 33
|
|
{ pszC_olt_s, opnFsFt }, // 34
|
|
{ pszC_ult_s, opnFsFt }, // 35
|
|
{ pszC_ole_s, opnFsFt }, // 36
|
|
{ pszC_ule_s, opnFsFt }, // 37
|
|
{ pszC_sf_s, opnFsFt }, // 38
|
|
{ pszC_ngle_s, opnFsFt }, // 39
|
|
{ pszC_seq_s, opnFsFt }, // 3a
|
|
{ pszC_ngl_s, opnFsFt }, // 3b
|
|
{ pszC_lt_s, opnFsFt }, // 3c
|
|
{ pszC_nge_s, opnFsFt }, // 3d
|
|
{ pszC_le_s, opnFsFt }, // 3e
|
|
{ pszC_ngt_s, opnFsFt } // 3f
|
|
};
|
|
|
|
#include "strings.h"
|
|
|
|
LPCH pszReg[] = {
|
|
szFr0, szFr1, szFr2, szFr3, szFr4, szFr5, szFr6, szFr7,
|
|
szFr8, szFr9, szFr10, szFr11, szFr12, szFr13, szFr14, szFr15,
|
|
szFr16, szFr17, szFr18, szFr19, szFr20, szFr21, szFr22, szFr23,
|
|
szFr24, szFr25, szFr26, szFr27, szFr28, szFr29, szFr30, szFr31,
|
|
|
|
szR0, szR1, szR2, szR3, szR4, szR5, szR6, szR7,
|
|
szR8, szR9, szR10, szR11, szR12, szR13, szR14, szR15,
|
|
szR16, szR17, szR18, szR19, szR20, szR21, szR22, szR23,
|
|
szR24, szR25, szR26, szR27, szR28, szR29, szR30, szR31,
|
|
|
|
szLo, szHi, szFsr, szFir, szPsr,
|
|
|
|
szFlagCu, szFlagCu3, szFlagCu2, szFlagCu1, szFlagCu0,
|
|
szFlagImsk,
|
|
szFlagInt5, szFlagInt4, szFlagInt3, szFlagInt2, szFlagInt1, szFlagInt0,
|
|
szFlagSw1, szFlagSw0,
|
|
szFlagKuo, szFlagIeo, // R3000 flags
|
|
szFlagKup, szFlagIep, // ...
|
|
szFlagKuc, szFlagIec, // ...
|
|
szFlagKsu, szFlagErl, szFlagExl, szFlagIe, // R4000 flags
|
|
|
|
szFlagFpc, // fl pt condition
|
|
|
|
szEaPReg, szExpPReg, szRaPReg, szPPReg, // psuedo-registers
|
|
szU0Preg, szU1Preg, szU2Preg, szU3Preg, szU4Preg,
|
|
szU5Preg, szU6Preg, szU7Preg, szU8Preg, szU9Preg
|
|
};
|
|
|
|
OPTABENTRY TlbrEntry = { pszTlbr, opnNone };
|
|
OPTABENTRY TlbwiEntry = { pszTlbwi, opnNone };
|
|
OPTABENTRY TlbwrEntry = { pszTlbwr, opnNone };
|
|
OPTABENTRY TlbpEntry = { pszTlbp, opnNone };
|
|
OPTABENTRY RfeEntry = { pszRfe, opnNone };
|
|
OPTABENTRY EretEntry = { pszEret, opnNone };
|
|
OPTABENTRY UndefEntry = { pszUndef, 0 };
|
|
OPTABENTRY NopEntry = { pszNop, opnNone };
|
|
|
|
static UCHAR * PBuf;
|
|
static int CchBuf;
|
|
INSTR disinstr;
|
|
|
|
void CalcMain (HPID,HTID,DOP,LPADDR,LPBYTE,int,int*,LPCH,int, LPCH,int, LPCH, int);
|
|
|
|
/****disasm - disassemble a MIPS R3/4000 instruction
|
|
*
|
|
* Input:
|
|
* pOffset = pointer to offset to start disassembly
|
|
* fEAout = if set, include EA (effective address)
|
|
*
|
|
* Output:
|
|
* pOffset = pointer to offset of next instruction
|
|
* pchDst = pointer to result string
|
|
*
|
|
***************************************************************************/
|
|
|
|
#define CCHMAX 256
|
|
static char rgchDisasm [ CCHMAX ];
|
|
static HPID hpidLocal;
|
|
static HTID htidLocal;
|
|
|
|
XOSD disasm ( HPID hpid, HTID htid, LPSDI lpsdi ) {
|
|
XOSD xosd = xosdNone;
|
|
int cchMax = CCHMAX;
|
|
DOP dop = lpsdi->dop;
|
|
LPCH lpchOut = rgchDisasm;
|
|
int ichCur = 0;
|
|
ADDR addrStart = lpsdi->addr;
|
|
int cch = 0;
|
|
int cb;
|
|
int cbUsed=0;
|
|
BYTE rgb [ MAXL ];
|
|
|
|
char rgchRaw [ MAXL * 2 + 1 ];
|
|
char rgchOpcode [ 80 ];
|
|
char rgchOperands [ 80 ];
|
|
char rgchEA [ 44 ];
|
|
char rgchComment [ 80 ];
|
|
|
|
hpidLocal = hpid;
|
|
htidLocal = htid;
|
|
_fmemset ( rgchRaw, 0, sizeof ( rgchRaw ) );
|
|
_fmemset ( rgchOpcode, 0, sizeof ( rgchOpcode ) );
|
|
_fmemset ( rgchOperands, 0, sizeof ( rgchOperands ) );
|
|
_fmemset ( rgchComment, 0, sizeof ( rgchComment ) );
|
|
_fmemset ( rgchEA, 0, sizeof ( rgchEA ) );
|
|
|
|
lpsdi->ichAddr = -1;
|
|
lpsdi->ichBytes = -1;
|
|
lpsdi->ichOpcode = -1;
|
|
lpsdi->ichOperands = -1;
|
|
lpsdi->ichComment = -1;
|
|
lpsdi->ichEA0 = -1;
|
|
lpsdi->ichEA1 = -1;
|
|
lpsdi->ichEA2 = -1;
|
|
|
|
lpsdi->cbEA0 = 0;
|
|
lpsdi->cbEA1 = 0;
|
|
lpsdi->cbEA2 = 0;
|
|
|
|
lpsdi->fAssocNext = 0;
|
|
|
|
lpsdi->lpch = rgchDisasm;
|
|
|
|
// Set up for upper or lower case
|
|
|
|
fUpper = ( dop & dopUpper ) == dopUpper;
|
|
if ( fUpper ) {
|
|
hexdigit = uhexdigit;
|
|
}
|
|
else {
|
|
hexdigit = lhexdigit;
|
|
}
|
|
|
|
ADDR_IS_FLAT( addrStart ) = TRUE;
|
|
|
|
// Output the address if it is requested
|
|
|
|
if ( ( dop & dopAddr ) == dopAddr ) {
|
|
cch = DumpAddress ( &addrStart, lpchOut, cchMax );
|
|
|
|
lpsdi->ichAddr = 0;
|
|
cchMax -= cch;
|
|
lpchOut += cch;
|
|
ichCur += cch;
|
|
}
|
|
|
|
#ifdef OSDEBUG4
|
|
xosd = ReadBuffer(hpid, htid, &addrStart, MAXL, rgb, &cb);
|
|
if (xosd != xosdNone) {
|
|
cb = 0;
|
|
}
|
|
#else
|
|
EMFunc ( emfSetAddr, hpid, htid, adrCurrent, (LONG) &addrStart );
|
|
cb = EMFunc ( emfReadBuf, hpid, htid, MAXL, (LONG) (LPV) rgb );
|
|
#endif
|
|
|
|
if ( cb <= 0 ) {
|
|
|
|
_fmemcpy ( rgchRaw, " ??", 4 );
|
|
_fmemcpy ( rgchOpcode, "???", 4 );
|
|
lpsdi->addr.addr.off++;
|
|
}
|
|
else {
|
|
|
|
CalcMain (
|
|
hpid,
|
|
htid,
|
|
lpsdi->dop,
|
|
&lpsdi->addr,
|
|
rgb,
|
|
cb,
|
|
&cbUsed,
|
|
rgchOpcode, sizeof(rgchOpcode),
|
|
rgchOperands, sizeof(rgchOperands),
|
|
rgchComment, sizeof(rgchComment)
|
|
);
|
|
|
|
// NOTENOTE jimsch - cbUsed must be 4
|
|
cbUsed = 4;
|
|
|
|
if ( GetAddrOff(lpsdi->addr) > 0xFFFFFFFF - cbUsed ) {
|
|
return xosdBadAddress;
|
|
}
|
|
|
|
if ( dop & dopRaw ) {
|
|
LPCH lpchT = rgchRaw;
|
|
|
|
OutputHexCode ( &lpchT, rgb, cbUsed );
|
|
|
|
*lpchT = '\0';
|
|
}
|
|
}
|
|
|
|
if ( ( dop & dopRaw ) && ( cchMax > 0 ) ) {
|
|
cch = DumpGeneric ( rgchRaw, lpchOut, cchMax );
|
|
|
|
lpsdi->ichBytes = ichCur;
|
|
cchMax -= cch;
|
|
lpchOut += cch;
|
|
ichCur += cch;
|
|
}
|
|
|
|
|
|
if ( ( dop & dopOpcode ) && ( cchMax > 0 ) ) {
|
|
cch = DumpGeneric ( rgchOpcode, lpchOut, cchMax );
|
|
|
|
lpsdi->ichOpcode = ichCur;
|
|
cchMax -= cch;
|
|
lpchOut += cch;
|
|
ichCur += cch;
|
|
}
|
|
|
|
if ( ( dop & dopOperands ) && ( cchMax > 0 ) && ( rgchOperands [ 0 ] != '\0' ) ) {
|
|
cch = DumpGeneric ( rgchOperands, lpchOut, cchMax );
|
|
|
|
lpsdi->ichOperands = ichCur;
|
|
cchMax -= cch;
|
|
lpchOut += cch;
|
|
ichCur += cch;
|
|
}
|
|
|
|
if ( ( dop & dopOperands ) && ( cchMax > 0 ) && ( rgchComment [ 0 ] != '\0' ) ) {
|
|
cch = DumpComment ( rgchComment, lpchOut, cchMax );
|
|
|
|
lpsdi->ichComment = ichCur;
|
|
cchMax -= cch;
|
|
lpchOut += cch;
|
|
ichCur += cch;
|
|
}
|
|
|
|
if ( dop & dopEA ) {
|
|
cch = DumpEA ( hpid, htid, &lpsdi->addrEA0, lpchOut, cchMax );
|
|
|
|
if ( cchMax > 0 && cch > 0 ) {
|
|
lpsdi->ichEA0 = ichCur;
|
|
cchMax -= cch;
|
|
lpchOut += cch;
|
|
ichCur += cch;
|
|
}
|
|
}
|
|
|
|
lpsdi->addr.addr.off += cbUsed;
|
|
|
|
return xosd;
|
|
}
|
|
|
|
void OutputStringM (PUCHAR pStr)
|
|
{
|
|
int cb;
|
|
|
|
if (CchBuf == 0) {
|
|
return;
|
|
}
|
|
|
|
cb = strlen(pStr);
|
|
if (cb > CchBuf) {
|
|
cb = CchBuf - 1;
|
|
}
|
|
|
|
strncpy(PBuf, pStr, cb);
|
|
PBuf[cb] = 0;
|
|
if (fUpper) {
|
|
_strupr(PBuf);
|
|
} else {
|
|
_strlwr(PBuf);
|
|
}
|
|
PBuf += cb;
|
|
CchBuf -= cb;
|
|
return;
|
|
}
|
|
|
|
void OutputReg (ULONG regnum)
|
|
{
|
|
OutputStringM(pszReg[regnum + 32]);
|
|
}
|
|
|
|
void OutputRxReg ( ULONG regnum)
|
|
{
|
|
if (CchBuf < 3) {
|
|
CchBuf = 0;
|
|
return;
|
|
}
|
|
|
|
*PBuf++ = 'r';
|
|
if (regnum > 9) {
|
|
*PBuf++ = (UCHAR) ('0' + regnum / 10);
|
|
}
|
|
*PBuf++ = (UCHAR) ('0' + regnum % 10);
|
|
CchBuf -= 2 + (regnum > 9);
|
|
return;
|
|
}
|
|
|
|
void OutputFReg (ULONG regnum, ULONG opn)
|
|
{
|
|
if (CchBuf < 4) {
|
|
CchBuf = 0;
|
|
return;
|
|
}
|
|
|
|
*PBuf++ = 'f';
|
|
if (opn & opnDwordIndex) {
|
|
*PBuf++ = 'p';
|
|
} else {
|
|
*PBuf++ = 'r';
|
|
}
|
|
|
|
if (regnum > 9) {
|
|
*PBuf++ = (UCHAR)('0' + regnum / 10);
|
|
}
|
|
*PBuf++ = (UCHAR)('0' + regnum % 10);
|
|
CchBuf -= 3 + (regnum > 9);
|
|
return;
|
|
}
|
|
|
|
void OutputHex (ULONG outvalue, ULONG length, BOOL fSigned)
|
|
{
|
|
UCHAR digit[8];
|
|
LONG index = 0;
|
|
|
|
if (fSigned && (long)outvalue < 0) {
|
|
if (CchBuf > 1) {
|
|
*PBuf++ = '-';
|
|
CchBuf -= 1;
|
|
}
|
|
outvalue = (ULONG) (- (LONG) outvalue);
|
|
}
|
|
|
|
if (CchBuf > 2) {
|
|
*PBuf++ = '0';
|
|
*PBuf++ = (fUpper) ? 'X' :'x';
|
|
CchBuf -= 2;
|
|
}
|
|
|
|
do {
|
|
digit[index++] = hexdigit[outvalue & 0xf];
|
|
outvalue >>= 4;
|
|
}
|
|
while (outvalue || (!fSigned && index < (LONG)length));
|
|
|
|
if (CchBuf > index) {
|
|
CchBuf -= index;
|
|
while (--index >= 0) {
|
|
*PBuf++ = digit[index];
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
|
|
/*** OutputDisSymbol - output symbol for disassembly
|
|
*
|
|
* Purpose:
|
|
* Access symbol table with given offset and put string into buffer.
|
|
*
|
|
* Input:
|
|
* offset - offset of address to output
|
|
*
|
|
* Output:
|
|
* buffer pointed by PBuf updated with string:
|
|
* if symbol, no disp: <symbol>(<offset>)
|
|
* if symbol, disp: <symbol>+<disp>(<offset>)
|
|
* if no symbol, no disp: <offset>
|
|
*
|
|
*************************************************************************/
|
|
|
|
void
|
|
OutputDisSymbol (
|
|
ULONG offset,
|
|
BOOL fSymbol
|
|
)
|
|
{
|
|
UCHAR chAddrBuffer[512];
|
|
LPCH lpchSymbol;
|
|
ADDR addrT={0}, addr={0};
|
|
int cb;
|
|
ODR odr;
|
|
|
|
odr.lszName = chAddrBuffer;
|
|
|
|
addr.addr.off = addrT.addr.off = offset;
|
|
MODE_IS_FLAT(addr.mode) = TRUE;
|
|
MODE_IS_FLAT(addrT.mode) = TRUE;
|
|
|
|
if (fSymbol) {
|
|
lpchSymbol = SHGetSymbol (&addrT, &addr, sopNone, &odr);
|
|
if (odr.dwDeltaOff == -1) {
|
|
lpchSymbol = NULL;
|
|
}
|
|
} else {
|
|
lpchSymbol = NULL;
|
|
}
|
|
|
|
if (lpchSymbol != NULL) {
|
|
cb = strlen(chAddrBuffer);
|
|
if (cb > CchBuf) {
|
|
cb = CchBuf;
|
|
}
|
|
strncpy(PBuf, chAddrBuffer, cb);
|
|
CchBuf -= cb;
|
|
PBuf += cb;
|
|
*PBuf = 0;
|
|
|
|
if (odr.dwDeltaOff) {
|
|
if (CchBuf > 1) {
|
|
*PBuf++ = '+';
|
|
CchBuf -= 1;
|
|
}
|
|
OutputHex(odr.dwDeltaOff, 8, TRUE);
|
|
}
|
|
if (CchBuf > 1) {
|
|
*PBuf++ = '(';
|
|
CchBuf -= 1;
|
|
}
|
|
}
|
|
OutputHex(offset, 8, FALSE);
|
|
if (lpchSymbol != NULL) {
|
|
if (CchBuf > 1) {
|
|
CchBuf -= 1;
|
|
*PBuf++ = ')';
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
void
|
|
CalcMain (
|
|
HPID hpid,
|
|
HTID htid,
|
|
DOP dop,
|
|
LPADDR lpaddr,
|
|
LPBYTE rgb,
|
|
int cbMax,
|
|
int FAR *lpcbUsed,
|
|
LPCH rgchOpcode,
|
|
int cchOpcode,
|
|
LPCH rgchOperands,
|
|
int cchOperands,
|
|
LPCH rgchComment,
|
|
int cchComment
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
description-of-function.
|
|
|
|
Arguments:
|
|
|
|
hpid - Supplies the process handle
|
|
hthd - Supplies a thread handle
|
|
dop - Supplies the set of disassembly options
|
|
lpaddr - Supplies the address to be disassembled
|
|
rgb - Supplies the buffer to dissassemble into
|
|
cbMax - Supplies the size of rgb
|
|
lpcbUsed - Returns the acutal size used
|
|
rgchOpcode - Supplies location to place opcode
|
|
rgchOperands - Supplies location to place operands
|
|
rgchComment - Supplies location to place comment
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG opcode;
|
|
ULONG temp;
|
|
POPTABENTRY pEntry;
|
|
UCHAR chSuffix = '\0';
|
|
PULONG poffset = &lpaddr->addr.off;
|
|
BOOL fEAout = TRUE;
|
|
DWORDLONG ull;
|
|
RD rd;
|
|
|
|
Unreferenced(cbMax);
|
|
Unreferenced(lpcbUsed);
|
|
|
|
*rgchComment = *rgchOperands = 0;
|
|
EAsize[0] = EAsize[1] = 0;
|
|
|
|
PBuf = rgchOpcode;
|
|
disinstr = *((INSTR*)rgb);
|
|
|
|
/*
|
|
* output the opcode in the table entry
|
|
*/
|
|
|
|
opcode = disinstr.jump_instr.Opcode;
|
|
pEntry = &opTable[opcode]; /* default value */
|
|
|
|
/*
|
|
* Check to see if in the table of special opcodes
|
|
*/
|
|
|
|
if (opcode == 0x00) {
|
|
if (disinstr.instruction) {
|
|
pEntry = &opSpecialTable[disinstr.special_instr.Funct];
|
|
} else {
|
|
pEntry = &NopEntry; /* special opcode for no-op */
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Check to see if in the table of regimm opcodes
|
|
*
|
|
*/
|
|
|
|
else if (opcode == 0x01) {
|
|
opcode = disinstr.immed_instr.RT;
|
|
if (opcode < 0x14) {
|
|
pEntry = &opBcondTable[opcode];
|
|
} else {
|
|
pEntry = &UndefEntry;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Check to see if in the table of COPz opcodes
|
|
*/
|
|
|
|
else if ((opcode & ~0x3) == 0x10) {
|
|
temp = disinstr.immed_instr.RS;
|
|
if (temp & 0x10) { /* test for CO bit */
|
|
if (opcode == 0x10) { /* test if COP0 */
|
|
temp = disinstr.special_instr.Funct;
|
|
if (temp == 0x01) {
|
|
pEntry = &TlbrEntry;
|
|
} else if (temp == 0x02) {
|
|
pEntry = &TlbwiEntry;
|
|
} else if (temp == 0x06) {
|
|
pEntry = &TlbwrEntry;
|
|
} else if (temp == 0x08) {
|
|
pEntry = &TlbpEntry;
|
|
} else if (temp == 0x10) {
|
|
pEntry = &RfeEntry;
|
|
} else if (temp == 0x18) {
|
|
pEntry = &EretEntry;
|
|
} else {
|
|
// pEntry = &UndefEntry;
|
|
;
|
|
}
|
|
}
|
|
else if (opcode == 0x11) { /* coprocessor operations */
|
|
opcode = disinstr.float_instr.Funct;
|
|
pEntry = &opFloatTable[opcode]; /* get opcode */
|
|
if (temp == 0x11) {
|
|
chSuffix = 'd';
|
|
} else if (temp == 0x12) {
|
|
chSuffix = 'e';
|
|
pEntry->fInstruction |= opnR4000;
|
|
} else if (temp == 0x13) {
|
|
chSuffix = 'q';
|
|
pEntry->fInstruction |= opnR4000;
|
|
} else if (temp == 0x14) {
|
|
chSuffix = 'w';
|
|
} else if (temp != 0x10) {
|
|
// pEntry = &UndefEntry;
|
|
;
|
|
}
|
|
} else {
|
|
// pEntry = &UndefEntry;
|
|
;
|
|
}
|
|
} else { /* no CO bit, general COPz ops */
|
|
if (!(temp & ~0x06)) {
|
|
/*
|
|
* rs = 0, 2, 4, 6
|
|
*/
|
|
|
|
pEntry = &opCopnTable[temp * 2 + (opcode - 0x10)];
|
|
} else if ((temp & ~0x04) == 0x08) {
|
|
/*
|
|
* rs = 8 or 0xc, rt = 0 to 3
|
|
*/
|
|
|
|
pEntry = &opCopnTable[(4 + (disinstr.immed_instr.RT & 3)) * 4
|
|
+ (opcode - 0x10)];
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* pEntry has the opcode string and operand template needed to
|
|
* output the instruction.
|
|
*/
|
|
|
|
strcpy(PBuf, pEntry->pszOpcode);
|
|
PBuf += strlen(PBuf);
|
|
|
|
if (PBuf[-1] != '?' && chSuffix) {
|
|
/*
|
|
* change xxx.s to xxx.d, xxx.w,
|
|
* xxx.e, or xxx.q (R4000 for e, q)
|
|
*/
|
|
|
|
PBuf[-1] = chSuffix;
|
|
}
|
|
|
|
PBuf = rgchOperands;
|
|
CchBuf = cchOperands;
|
|
|
|
/*
|
|
* cache instruction has special codes for RT field value:
|
|
* 0 = 'i'; 1 = 'd'; 2 = 'si'; 3 = 'sd'
|
|
*/
|
|
|
|
if (pEntry->fInstruction & opnCache) {
|
|
temp = disinstr.special_instr.RT;
|
|
|
|
if ((temp & 0x3) > 1) {
|
|
*PBuf++ = 's';
|
|
CchBuf -= 1;
|
|
temp -= 2;
|
|
}
|
|
if ((temp & 0x1) == 0) {
|
|
*PBuf++ = 'i';
|
|
} else {
|
|
*PBuf++ = 'd';
|
|
}
|
|
*PBuf++ = ',';
|
|
*PBuf++ = (char) ('0' + temp / 4);
|
|
*PBuf++ = ',';
|
|
CchBuf -= 4;
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnPreRt) {
|
|
OutputReg(disinstr.special_instr.RT);
|
|
*PBuf++ = ',';
|
|
CchBuf -= 1;
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnPreRxt) {
|
|
OutputRxReg(disinstr.special_instr.RT);
|
|
*PBuf++ = ',';
|
|
CchBuf -= 1;
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRd) {
|
|
OutputReg(disinstr.special_instr.RD);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnFd) {
|
|
OutputFReg(disinstr.float_instr.FD,
|
|
pEntry->fInstruction & opnAnyIndex);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRxd) {
|
|
OutputRxReg(disinstr.special_instr.RD);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRdOptRs) {
|
|
if (disinstr.special_instr.RD != 0x1f) {
|
|
OutputReg(disinstr.special_instr.RD);
|
|
*PBuf++ = ',';
|
|
CchBuf -= 1;
|
|
}
|
|
OutputReg(disinstr.immed_instr.RS);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRdComma) {
|
|
*PBuf++ = ',';
|
|
CchBuf -= 1;
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRs) {
|
|
OutputReg(disinstr.immed_instr.RS);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnFs) {
|
|
OutputFReg(disinstr.float_instr.FS, 0);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRsComma) {
|
|
*PBuf++ = ',';
|
|
CchBuf -= 1;
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRt) {
|
|
OutputReg(disinstr.immed_instr.RT);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnFt) {
|
|
OutputFReg(disinstr.float_instr.FT, 0);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRtComma) {
|
|
*PBuf++ = ',';
|
|
CchBuf -= 1;
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnPostRs) {
|
|
OutputReg(disinstr.immed_instr.RS);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnImm10) {
|
|
OutputHex((long)(short)disinstr.trap_instr.Value, 0, TRUE);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnImm16) {
|
|
OutputHex((long)(short)disinstr.immed_instr.Value, 0, TRUE);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnUImm16) {
|
|
OutputHex((long)(USHORT) disinstr.immed_instr.Value, 0, FALSE);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnRel16) {
|
|
OutputDisSymbol(((long)(short)disinstr.immed_instr.Value << 2)
|
|
+ *poffset + sizeof(ULONG), dop & dopSym);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnImm20) {
|
|
OutputHex(disinstr.break_instr.Value, 0, TRUE);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnImm26) {
|
|
OutputHex(disinstr.jump_instr.Target & 0x1ffffff, 0, TRUE);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnAddr26) {
|
|
OutputDisSymbol((disinstr.jump_instr.Target << 2)
|
|
+ (*poffset & 0xf0000000), dop & dopSym);
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnAnyIndex) {
|
|
|
|
OutputHex((long)(short)disinstr.immed_instr.Value, 0, TRUE);
|
|
if (CchBuf > 1) {
|
|
*PBuf++ = '(';
|
|
CchBuf -= 1;
|
|
}
|
|
OutputReg(disinstr.immed_instr.RS);
|
|
if (CchBuf > 1) {
|
|
*PBuf++ = ')';
|
|
CchBuf -= 1;
|
|
}
|
|
|
|
EMFunc(emfGetRegStruct, hpid, htid,
|
|
disinstr.immed_instr.RS + CV_M4_IntZERO,
|
|
(LONG)(LPV)&rd);
|
|
|
|
if (rd.cbits > 32) {
|
|
EMFunc (emfGetReg, hpid, htid,
|
|
disinstr.immed_instr.RS + CV_M4_IntZERO,
|
|
(LONG)(LPV)&ull
|
|
);
|
|
EAaddr[0] = (DWORD)ull;
|
|
} else {
|
|
EMFunc (emfGetReg, hpid, htid,
|
|
disinstr.immed_instr.RS + CV_M4_IntZERO,
|
|
(LONG)(LPV)&EAaddr[0]
|
|
);
|
|
}
|
|
|
|
EAaddr[0] += (long)(short) disinstr.immed_instr.Value;
|
|
|
|
if (pEntry->fInstruction & opnByteIndex) {
|
|
EAsize[0] = 1;
|
|
} else if (pEntry->fInstruction & opnWordIndex) {
|
|
EAsize[0] = 2;
|
|
} else if (pEntry->fInstruction & opnDwordIndex) {
|
|
EAsize[0] = 4;
|
|
} else if (pEntry->fInstruction & opnLeftIndex) {
|
|
EAsize[0] = (UCHAR)(4 - (EAaddr[0] & 3));
|
|
} else { /* opnRightIndex */
|
|
EAsize[0] = (UCHAR)((EAaddr[0] & 3) + 1);
|
|
}
|
|
}
|
|
|
|
if (pEntry->fInstruction & opnShift) {
|
|
OutputHex(disinstr.special_instr.RE, 2, FALSE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int DumpAddress ( LPADDR lpaddr, LPCH lpch, int cchMax ) {
|
|
LPCH lpchT = lpch;
|
|
|
|
Unreferenced(cchMax);
|
|
|
|
OutputAddr ( &lpch, lpaddr, (ADDR_IS_FLAT(*lpaddr) + 1) * 2 );
|
|
*lpch = '\0';
|
|
return lpch - lpchT + 1;
|
|
}
|
|
|
|
|
|
int
|
|
DumpGeneric (
|
|
LSZ lsz,
|
|
LPCH lpch,
|
|
int cchMax
|
|
)
|
|
{
|
|
int ich = 0;
|
|
|
|
while ( *(lsz + ich) != 0 && ich < cchMax - 1 ) {
|
|
*(lpch+ich) = *(lsz+ich);
|
|
ich += 1;
|
|
}
|
|
*( lpch + ich ) = '\0';
|
|
|
|
return ich + 1;
|
|
}
|
|
|
|
|
|
int
|
|
DumpComment (
|
|
LSZ lsz,
|
|
LPCH lpch,
|
|
int cchMax
|
|
)
|
|
{
|
|
*(lpch) = ';';
|
|
return DumpGeneric ( lsz, lpch + 1, cchMax - 1 ) + 1;
|
|
}
|
|
|
|
int
|
|
DumpEA (
|
|
HPID hpid,
|
|
HTID htid,
|
|
LPADDR lpaddr,
|
|
LPCH lpch,
|
|
int cchMax
|
|
)
|
|
{
|
|
LPCH lpchT = lpch;
|
|
BYTE rgb [ MAXL ];
|
|
int indx;
|
|
int cb;
|
|
#ifdef OSDEBUG4
|
|
XOSD xosd;
|
|
#endif
|
|
|
|
Unreferenced(cchMax);
|
|
|
|
for ( indx = 0; indx < 2; indx++ ) {
|
|
|
|
if ( EAsize [ indx ] ) {
|
|
ADDR addr = {0};
|
|
|
|
OutputHexString ( &lpchT, (LPBYTE) &EAaddr [ indx ], 4 );
|
|
|
|
*lpchT++ = '=';
|
|
|
|
addr.addr.off = (UOFFSET) EAaddr [ indx ];
|
|
addr.addr.seg = (SEGMENT) 0;
|
|
|
|
*lpaddr = addr;
|
|
|
|
#ifdef OSDEBUG4
|
|
xosd = ReadBuffer(hpid, htid, &addr, EAsize[indx], rgb, &cb);
|
|
if (xosd != xosdNone) {
|
|
cb = 0;
|
|
}
|
|
#else
|
|
EMFunc (
|
|
emfSetAddr,
|
|
hpid,
|
|
htid,
|
|
adrCurrent,
|
|
(LONG) (LPADDR) &addr
|
|
);
|
|
|
|
cb = EMFunc (
|
|
emfReadBuf,
|
|
hpid,
|
|
htid,
|
|
EAsize [ indx ],
|
|
(LONG) (LPV) rgb
|
|
);
|
|
#endif
|
|
|
|
if ( cb == EAsize [ indx ] ) {
|
|
OutputHexString ( &lpchT, rgb, EAsize [ indx ] );
|
|
}
|
|
else {
|
|
while ( EAsize [ indx ]-- ) {
|
|
*lpchT++ = '?';
|
|
*lpchT++ = '?';
|
|
}
|
|
}
|
|
*lpchT++ = '\0';
|
|
}
|
|
}
|
|
|
|
return lpchT - lpch;
|
|
}
|
|
|
|
|
|
|
|
/*** OutputHexString - output hex string
|
|
*
|
|
* Purpose:
|
|
* Output the value pointed by *lplpchMemBuf of the specified
|
|
* length. The value is treated as unsigned and leading
|
|
* zeroes are printed.
|
|
*
|
|
* Input:
|
|
* *lplpchBuf - pointer to text buffer to fill
|
|
* *pchValue - pointer to memory buffer to extract value
|
|
* length - length in bytes of value
|
|
*
|
|
* Output:
|
|
* *lplpchBuf - pointer updated to next text character
|
|
* *lplpchMemBuf - pointer update to next memory byte
|
|
*
|
|
*************************************************************************/
|
|
|
|
void OutputHexString (LPLPCH lplpchBuf, PCH pchValue, int length)
|
|
{
|
|
unsigned char chMem;
|
|
|
|
pchValue += length;
|
|
while ( length-- ) {
|
|
chMem = *--pchValue;
|
|
*(*lplpchBuf)++ = hexdigit[chMem >> 4];
|
|
*(*lplpchBuf)++ = hexdigit[chMem & 0x0f];
|
|
}
|
|
}
|
|
|
|
|
|
/*** OutputAddr - output address package
|
|
*
|
|
* Purpose:
|
|
* Output the address pointed to by lpaddr.
|
|
*
|
|
* Input:
|
|
* *lplpchBuf - pointer to text buffer to fill
|
|
* lpaddr - Standard address package.
|
|
*
|
|
* Output:
|
|
* *lplpchBuf - pointer updated to next text character
|
|
*
|
|
*************************************************************************/
|
|
|
|
VOID
|
|
OutputAddr (
|
|
LPLPCH lplpchBuf,
|
|
LPADDR lpaddr,
|
|
int alen
|
|
)
|
|
{
|
|
ADDR addr = *lpaddr;
|
|
|
|
*(*lplpchBuf)++ = '0';
|
|
*(*lplpchBuf)++ = (fUpper) ? 'X' : 'x';
|
|
OutputHexString ( lplpchBuf, (LPCH) &addr.addr.off, alen );
|
|
|
|
return;
|
|
} /* OutputAddr() */
|
|
|
|
|
|
/*** OutputHexCode - output hex code
|
|
*
|
|
* Purpose:
|
|
* Output the code pointed by lpchMemBuf of the specified
|
|
* length. The value is treated as unsigned and leading
|
|
* zeroes are printed. This differs from OutputHexString
|
|
* in that bytes are printed from low to high addresses.
|
|
*
|
|
* Input:
|
|
* *lplpchBuf - pointer to text buffer to fill
|
|
* lpchMemBuf - - pointer to memory buffer to extract value
|
|
* length - length in bytes of value
|
|
*
|
|
* Output:
|
|
* *lplpchBuf - pointer updated to next text character
|
|
*
|
|
*************************************************************************/
|
|
|
|
void OutputHexCode (LPLPCH lplpchBuf, LPCH lpchMemBuf, int length)
|
|
{
|
|
unsigned char chMem;
|
|
|
|
while (length--) {
|
|
chMem = lpchMemBuf[length];
|
|
*(*lplpchBuf)++ = hexdigit[chMem >> 4];
|
|
*(*lplpchBuf)++ = hexdigit[chMem & 0x0f];
|
|
}
|
|
}
|