www.pudn.com > potemkin_sourceforPSP.rar > ARMDis.cpp


#include "stdafx.h" 
#include "../../Globals.h" 
#include "../MemMap.h" 
#include "ARM.h" 
#include "ARMDis.h" 
#include "ARMTables.h" 
 
u32 disPC; 
//TODO: Condition codes! 
#define RDi(x) ((x>>12)&0xF)  
#define RNi(x) ((x>>16)&0xF) 
#define RMi(x) (x&0xf) 
#define RSi(x) ((x>>8)&0xF) 
#define RD(x) GetReg(RDi(x)) 
#define RN(x) GetReg(RNi(x)) 
#define RM(x) GetReg((x)&0xF) 
#define RS(x) GetReg((x>>8)&0xF) 
 
 
namespace ARMDis 
{ 
 
	const TCHAR *GetCondIdx(int index) 
	{ 
		return conditionNames[index]; 
	} 
 
	const TCHAR *GetCond(u32 op) 
	{ 
		return GetCondIdx(op>>28); 
	} 
 
	const TCHAR *GetReg(u32 reg) 
	{ 
		static const TCHAR *regs[16] =  
		{ 
			"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11","r12","sp","lr","pc" 
		}; 
		return regs[reg]; 
	} 
 
	const TCHAR *GetS(u32 op) 
	{ 
		return S_FLAG(op)? "." : "" ; 
	} 
 
	void Dis_Unknown(u32 op, char *out) 
	{ 
		strcpy(out,"???\t-- unknown --"); 
	} 
	void Dis_Unimpl(u32 op, char *out) 
	{ 
		strcpy(out,"???\t-- unimplemented --"); 
	} 
 
	// data processing addressing mode 
	void Dis_DPAddr(u32 op, char *out) 
	{ 
		if ((op&(1<<25))) //imm shift 
		{ 
			u32 cnst = op&0xFF; 
			u32 shift = ((op>>8)&0xF) << 1; 
			sprintf(out,"$%0x",_rotr(cnst,shift)); 
		} 
		else 
		{ 
			if ((op&0x10)) //reg shift 
			{ 
				TCHAR shifttype[4]; 
				switch((op>>5) & 0x3)  
				{ 
				case 0: _tcscpy(shifttype,"lsl"); break; 
				case 1: _tcscpy(shifttype,"lsr"); break; 
				case 2: _tcscpy(shifttype,"asr"); break; 
				case 3: _tcscpy(shifttype,"ror"); break; 
				} 
				sprintf(out,"%s %s %s", RM(op), shifttype, RS(op)); 
			} 
			else //immediate 
			{ 
				int shiftAmt = (op>>7) & 0x1F; 
				TCHAR shifttype[4]; 
				switch((op>>5) & 0x3)  
				{ 
				case 0: _tcscpy(shifttype,"lsl"); break; 
				case 1: _tcscpy(shifttype,"lsr"); break; 
				case 2: _tcscpy(shifttype,"asr"); break; 
				case 3: _tcscpy(shifttype,shiftAmt?"ror":"rrx"); if (!shiftAmt) shiftAmt=1; break;//ROR / RRX 
				} 
				if (strcmp(shifttype,"lsl") == 0 && shiftAmt == 0) 
					sprintf(out,"%s",RM(op)); 
				else 
					sprintf(out,"%s %s %d", RM(op), shifttype, shiftAmt); 
			} 
		} 
	} 
 
	//type 1 - 3 op 
	void Dis_DP1(u32 op, char *out, char *name) 
	{ 
		char addr[16]; 
		Dis_DPAddr(op, addr); 
		sprintf(out, "%s%s%s\t%s, %s, %s",name,GetCond(op),GetS(op),RD(op),RN(op),addr); 
	} 
	//type 2 - 2 op (tests with no output except the flags) 
	void Dis_DP2(u32 op, char *out, char *name) 
	{ 
		char addr[16]; 
		Dis_DPAddr(op, addr); 
		sprintf(out, "%s%s.\t%s, %s",name,GetCond(op),RN(op),addr); 
	} 
 
	//type 3 - 1 op (mov, mvn) 
	void Dis_DP3(u32 op, char *out, char *name) 
	{ 
		char addr[16]; 
		Dis_DPAddr(op, addr); 
		sprintf(out, "%s%s%s\t%s, %s",name,GetCond(op),GetS(op),RD(op),addr); 
	} 
 
	void Dis_AND(u32 op, char *out) {Dis_DP1(op,out,"and");} 
	void Dis_EOR(u32 op, char *out) {Dis_DP1(op,out,"eor");} 
	void Dis_SUB(u32 op, char *out) {Dis_DP1(op,out,"sub");} 
	void Dis_RSB(u32 op, char *out) {Dis_DP1(op,out,"rsb");} 
	void Dis_ADD(u32 op, char *out) {Dis_DP1(op,out,"add");} 
	void Dis_ADC(u32 op, char *out) {Dis_DP1(op,out,"adc");} 
	void Dis_SBC(u32 op, char *out) {Dis_DP1(op,out,"sbc");} 
	void Dis_RSC(u32 op, char *out) {Dis_DP1(op,out,"rsc");} 
	void Dis_TST(u32 op, char *out) {Dis_DP2(op,out,"tst");} 
	void Dis_TEQ(u32 op, char *out) {Dis_DP2(op,out,"teq");} 
	void Dis_CMP(u32 op, char *out) {Dis_DP2(op,out,"cmp");} 
	void Dis_CMN(u32 op, char *out) {Dis_DP2(op,out,"cmn");} 
	void Dis_ORR(u32 op, char *out) {Dis_DP1(op,out,"orr");} 
	void Dis_MOV(u32 op, char *out) {Dis_DP3(op,out,"mov");} 
	void Dis_BIC(u32 op, char *out) {Dis_DP1(op,out,"bic");} 
	void Dis_MVN(u32 op, char *out) {Dis_DP3(op,out,"mvn");} 
 
	void Dis_CLZ(u32 op, char *out)  
	{ 
		sprintf(out, "clz%s\t%s, %s",GetCond(op),RD(op),RM(op)); 
	} 
 
	void Dis_MRS(u32 op, char *out) 
	{ 
		sprintf(out, "mrs%s\t%s, %s_%c%c%c",GetCond(op),RD(op),(op&(1<<22)) ? "SPSR" : "CPSR", 
			((op&0x00010000)?'c':'_'), ((op&0x00020000)?'x':'_'), 
			((op&0x00040000)?'s':'_'), ((op&0x00080000)?'f':'_')); 
	} 
 
	void Dis_MSRreg(u32 op, char *out) 
	{ 
		sprintf(out, "msr\t%s_%c%c%c%c, %s",(op&(1<<22)) ? "SPSR" : "CPSR",	 
			((op&0x00010000)?'c':'_'), ((op&0x00020000)?'x':'_'), 
			((op&0x00040000)?'s':'_'), ((op&0x00080000)?'f':'_'),RM(op)); 
	} 
	void Dis_MSRimm(u32 op, char *out) 
	{ 
		int rot = (op>>8)&0xf; 
		int val = _rotr(op&0xff,rot); 
		sprintf(out, "msr\t%s_%c%c%c%c, %08x",(op&(1<<22)) ? "SPSR" : "CPSR", 
			((op&0x00010000)?'c':'_'), ((op&0x00020000)?'x':'_'), 
			((op&0x00040000)?'s':'_'), ((op&0x00080000)?'f':'_'),val); 
	} 
 
	void Dis_ldst(u32 op, char *out, char *name) 
	{ 
		TCHAR part2[256]; 
		sprintf(out, "%s%s\t%s, ",name,GetCond(op),RD(op)); 
 
		char sign = (op & (1<<23)) ? '+' : '-'; 
		if (op & (1<<25)) 
		{ 
			//reg offset 
			int shiftAmt = (op>>7) & 0x1F; 
			TCHAR shifttype[4]; 
			switch((op>>5) & 0x3)  
			{ 
			case 0: _tcscpy(shifttype,"lsl"); break; 
			case 1: _tcscpy(shifttype,"lsr"); break; 
			case 2: _tcscpy(shifttype,"asr"); break; 
			case 3: _tcscpy(shifttype,shiftAmt?"ror":"rrx"); if (!shiftAmt) shiftAmt=1; break;//ROR / RRX 
			} 
 
			if (!(op & (1<<24))) 
			{ 
				//postindex 
				if (strcmp(shifttype,"lsl") == 0 && shiftAmt == 0) 
					sprintf(part2,"[%s], %c%s",RN(op),sign,RM(op)); 
				else 
					sprintf(part2,"[%s], %c%s %s %d",RN(op),sign,RM(op), shifttype, shiftAmt); 
			} 
			else 
			{ 
				//preindex or normal 
				TCHAR *preindex = (op & (1<<21)) ? "!" : ""; 
				if (strcmp(shifttype,"lsl") == 0 && shiftAmt == 0) 
					sprintf(part2,"[%s %c %s]%s",RN(op),sign,RM(op),preindex); 
				else 
					sprintf(part2,"[%s %c %s %s %d]%s",RN(op),sign,RM(op), shifttype, shiftAmt,preindex); 
			} 
		} 
		else 
		{ 
			//imm offset 
			int imm = op&0xFFF; 
			if (!(op & (1<<24))) 
			{ 
				//postindex 
				sprintf(part2, "[%s], %c%03x",RN(op),sign,imm); 
			} 
			else 
			{ 
				//preindex or normal 
				TCHAR *preindex = (op & (1<<21)) ? "!" : ""; 
				//immediate offset 
				if (RNi(op) == 15) 
				{ 
					int addr = disPC+8; 
					sign=='+' ? addr+=imm : addr-=imm; 
					sprintf(part2, "[$%08x]%s (%08x)",addr,preindex,ReadMem32Unchecked(addr)); 
				} 
				else 
				{ 
					if (imm!=0) 
						sprintf(part2, "[%s %c $%03x]%s",RN(op),sign,imm,preindex); 
					else 
						sprintf(part2, "[%s]%s",RN(op),preindex); 
				} 
			} 
		} 
		strcat(out,part2); 
	} 
 
	void Dis_LDR(u32 op, char *out) {Dis_ldst(op,out,"ldr");} 
	void Dis_STR(u32 op, char *out) {Dis_ldst(op,out,"str");} 
	void Dis_LDRB(u32 op, char *out){Dis_ldst(op,out,"ldrb");} 
	void Dis_STRB(u32 op, char *out){Dis_ldst(op,out,"strb");} 
 
	void Dis_ldst2(u32 op, char *out, char *name) 
	{ 
		TCHAR part2[256]; 
		sprintf(out, "%s%s\t%s, ",name,GetCond(op),RD(op)); 
		char sign = (op & (1<<23)) ? '+' : '-'; 
		if (op&(1<<22)) 
		{ 
			//immediate offset 
			u8 imm = (op&0xF) | ((op>>4)&0xF0); 
			if (!(op & (1<<24))) 
			{ 
				//postindexed 
				sprintf(part2,"[%s], %c$%02x",RN(op),sign,imm); 
			} 
			else 
			{ 
				//preindexed or normal 
				TCHAR *preindex = (op&(1<<21)) ? "!" : ""; 
				sprintf(part2,"[%s %c $%02x]%s",RN(op),sign,imm,preindex); 
			} 
		} 
		else 
		{ 
			//register offset 
			if (!(op & (1<<24))) 
			{ 
				//postindexed 
				sprintf(part2,"[%s], %c%s",RN(op),sign,RM(op)); 
			} 
			else 
			{ 
				//preindexed or normal 
				TCHAR *preindex = (op&(1<<21)) ? "!" : ""; 
				sprintf(part2,"[%s %c %s]%s",RN(op),sign,RM(op),preindex); 
			} 
		} 
		strcat(out,part2); 
	} 
 
	void Dis_LDRH(u32 op, char *out) {Dis_ldst2(op,out,"ldrh");}  
	void Dis_STRH(u32 op, char *out) {Dis_ldst2(op,out,"strh");}  
	void Dis_LDRSH(u32 op, char *out) {Dis_ldst2(op,out,"ldrsh");}  
	void Dis_STRSH(u32 op, char *out) {Dis_ldst2(op,out,"strsh");}  
	void Dis_LDRSB(u32 op, char *out) {Dis_ldst2(op,out,"ldrsb");}  
	void Dis_STRSB(u32 op, char *out) {Dis_ldst2(op,out,"strsb");}  
 
	void Dis_stldm(u32 op, char *out, char *name) 
	{ 
		TCHAR *pre = (op&(1<<24)) ? "b" : "a"; //before after 
		TCHAR *up = (op&(1<<23)) ? "i" : "d"; 
		TCHAR *PSRuser = (op&(1<<22)) ? "^" : ""; 
		TCHAR *writeback = (op&(1<<21)) ? "!" : ""; 
		TCHAR reglist[512] = "{"; 
		int count=0; 
		for (int i=0; i<16; i++) 
		{ 
			if (op&(1<>8)&0xf; 
		int rdhi = (op>>16)&0xf; 
		int rdlo = (op>>12)&0xf; 
		sprintf(out,"umull\t%s:%s, %s, %s",GetReg(rdhi),GetReg(rdlo),GetReg(rm),GetReg(rs)); 
	} 
	void Dis_UMLAL(u32 op, char *out) 
	{ 
		int rm = op&0xf; 
		int rs = (op>>8)&0xf; 
		int rdhi = (op>>16)&0xf; 
		int rdlo = (op>>12)&0xf; 
		sprintf(out,"umlal\t%s:%s, %s, %s",GetReg(rdhi),GetReg(rdlo),GetReg(rm),GetReg(rs)); 
	} 
	void Dis_SMULL(u32 op, char *out) 
	{ 
		int rm = op&0xf; 
		int rs = (op>>8)&0xf; 
		int rdhi = (op>>16)&0xf; 
		int rdlo = (op>>12)&0xf; 
		sprintf(out,"smull\t%s:%s, %s, %s",GetReg(rdhi),GetReg(rdlo),GetReg(rm),GetReg(rs)); 
	} 
	void Dis_SMLAL(u32 op, char *out) 
	{ 
		int rm = op&0xf; 
		int rs = (op>>8)&0xf; 
		int rdhi = (op>>16)&0xf; 
		int rdlo = (op>>12)&0xf; 
		sprintf(out,"smlal\t%s:%s, %s, %s",GetReg(rdhi),GetReg(rdlo),GetReg(rm),GetReg(rs)); 
	} 
 
 
	//Software i 
	void Dis_SWI(u32 op, char *out) 
	{ 
		sprintf(out,"swi%s\t%08x",GetCond(op),op&0xFFFFFF); 
	} 
	//Branch and 
	void Dis_B(u32 op, char *out) 
	{ 
		u32 addr = disPC+8+4*SEX24(op&0xFFFFFF); 
		sprintf(out,"b%s\t->$%08x", GetCond(op), addr); 
	} 
	void Dis_BL(u32 op, char *out) 
	{ 
		u32 addr = disPC+8+4*SEX24(op&0xFFFFFF); 
		sprintf(out,"bl%s\t->$%08x", GetCond(op), addr); 
	} 
	void Dis_BLXr(u32 op, char *out) 
	{ 
		sprintf(out,"blx%s\t->%s", GetCond(op), RM(op)); 
	} 
	void Dis_BXr(u32 op, char *out) 
	{ 
		sprintf(out,"bx%s\t->%s", GetCond(op), RM(op)); 
	} 
	////////////////////////////////////////////////////////////////////////// 
	//THUMB 
	////////////////////////////////////////////////////////////////////////// 
 
#define TR0(op) GetReg(op&7) 
#define TR1(op) GetReg((op>>3)&7) 
#define TR2(op) GetReg((op>>6)&7) 
 
	void Dis_T_Unimpl(u16 op, char *out) 
	{ 
		strcpy(out,"???\t-- unimplemented --"); 
	} 
	void Dis_T_Unknown(u16 op, char *out) 
	{ 
		strcpy(out,"???\t-- unknown --"); 
	} 
 
	void Dis_T_2op(u16 op, char *out, char *name) 
	{ 
		sprintf(out,"%s\t%s, %s",name,TR0(op),TR1(op)); 
	} 
	//Data process 
	void Dis_T_AND(u16 op, char *out){Dis_T_2op(op,out,"and.");} 
	void Dis_T_EOR(u16 op, char *out){Dis_T_2op(op,out,"eor.");}    
	void Dis_T_ORR(u16 op, char *out){Dis_T_2op(op,out,"orr.");}    
	void Dis_T_BIC(u16 op, char *out){Dis_T_2op(op,out,"bic.");}    
 
	void Dis_T_LSL(u16 op, char *out){Dis_T_2op(op,out,"lsl.");} 
	void Dis_T_LSR(u16 op, char *out){Dis_T_2op(op,out,"lsr.");} 
	void Dis_T_ASR(u16 op, char *out){Dis_T_2op(op,out,"asr.");} 
	void Dis_T_ROR(u16 op, char *out){Dis_T_2op(op,out,"ror.");} 
 
	void Dis_T_ADC(u16 op, char *out){Dis_T_2op(op,out,"adc.");} 
	void Dis_T_SBC(u16 op, char *out){Dis_T_2op(op,out,"sbc.");} 
 
	void Dis_T_CMP(u16 op, char *out){Dis_T_2op(op,out,"cmp.");} 
	void Dis_T_CMN(u16 op, char *out){Dis_T_2op(op,out,"cmn.");} 
	void Dis_T_TST(u16 op, char *out){Dis_T_2op(op,out,"tst.");} 
	void Dis_T_NEG(u16 op, char *out){Dis_T_2op(op,out,"neg.");} 
	void Dis_T_MVN(u16 op, char *out){Dis_T_2op(op,out,"mvn.");} 
 
	void Dis_T_MUL(u16 op, char *out){Dis_T_2op(op,out,"mul.");} 
 
 
	void Dis_T_hiop(u16 op, char *out,char *name) 
	{ 
		int rd = ((op>>4)&8)|(op&7); 
		int rm = (op>>3)&0xf; 
		sprintf(out,"%s\t%s, %s",name,GetReg(rd),GetReg(rm)); 
	}  
	void Dis_T_ADDhi(u16 op, char *out){Dis_T_hiop(op,out,"add ");} 
	void Dis_T_CMPhi(u16 op, char *out){Dis_T_hiop(op,out,"cmp.");}  
	void Dis_T_MOVhi(u16 op, char *out){Dis_T_hiop(op,out,"mov ");} 
 
	void Dis_T_3op(u16 op, char *out, char *name) 
	{ 
		sprintf(out,"%s\t%s, %s, %s",name,TR0(op),TR1(op),TR2(op)); 
	} 
	void Dis_T_ADD(u16 op, char *out){Dis_T_3op(op,out,"add.");}  
	void Dis_T_SUB(u16 op, char *out){Dis_T_3op(op,out,"sub.");}  
 
	void Dis_T_2opimm(u16 op, char *out, char *name) 
	{ 
		sprintf(out,"%s\t%s, %s, %d",name,TR0(op),TR1(op),(op>>6)&7); 
	} 
	void Dis_T_ADDimm(u16 op, char *out){Dis_T_2opimm(op,out,"add.");} 
	void Dis_T_SUBimm(u16 op, char *out){Dis_T_2opimm(op,out,"sub.");} 
 
	void Dis_T_Shift(u16 op, char *out,char *name) 
	{ 
		int shift = (op >> 6) & 31; 
		sprintf(out,"%s\t%s, %s, %d",name,TR0(op),TR1(op),shift); 
	} 
	void Dis_T_LSLimm(u16 op, char *out){Dis_T_Shift(op,out,"lsl.");} 
	void Dis_T_LSRimm(u16 op, char *out){Dis_T_Shift(op,out,"lsr.");} 
	void Dis_T_ASRimm(u16 op, char *out){Dis_T_Shift(op,out,"asr.");} 
 
	void Dis_T_Imm8(u16 op, char *out,char *name) 
	{ 
		int value = op & 0xff; 
		sprintf(out,"%s\t%s, $%02x",name,TR0(op>>8),value); 
	} 
	void Dis_T_CMPimm(u16 op, char *out){Dis_T_Imm8(op,out,"cmp.");} 
	void Dis_T_MOVimm(u16 op, char *out){Dis_T_Imm8(op,out,"mov.");} 
	void Dis_T_ADDlim(u16 op, char *out){Dis_T_Imm8(op,out,"add.");} 
	void Dis_T_SUBlim(u16 op, char *out){Dis_T_Imm8(op,out,"sub.");} 
 
	void Dis_T_ADDpc(u16 op, char *out) 
	{ 
		sprintf(out,"add\t%s, pc, $%03x",TR0(op>>8),(op&0xff) << 2); 
	}  
	void Dis_T_ADDsp(u16 op, char *out) 
	{ 
		sprintf(out,"add\t%s, sp, $%03x",TR0(op>>8),(op&0xff) << 2); 
	}  
 
	void Dis_T_multiple(u16 op, char *out, char *name) 
	{ 
		TCHAR temp[256]={0}; 
		for (int i=0; i<7; i++) 
		{ 
			if (op&(1<>8),temp); 
	} 
 
	void Dis_T_STMIA(u16 op, char *out) {Dis_T_multiple(op,out,"stmia");} 
	void Dis_T_LDMIA(u16 op, char *out) {Dis_T_multiple(op,out,"ldmia");} 
 
	void Dis_T_ADDspi(u16 op, char *out) 
	{ 
		sprintf(out,"add\tsp, $%03x",(op&0x7F)*4); 
	} 
	void Dis_T_SUBspi(u16 op, char *out) 
	{ 
		sprintf(out,"sub\tsp, $%03x",(op&0x7F)*4); 
	} 
 
 
	//stack 
	void Dis_T_POP(u16 op, char *out) 
	{ 
		sprintf(out,"pop\t..."); 
	} 
	void Dis_T_PUSH(u16 op, char *out) 
	{ 
		sprintf(out,"push\t..."); 
	}   
 
 
	//loadstore 
	void Dis_T_LDRimm(u16 op, char *out) 
	{ 
		u32 addr=(disPC&~3)+(op&0xff)*4+4; 
		sprintf(out,"ldr\t%s, [%08x] (%08x)",TR0(op>>8),addr,ReadMem32Unchecked(addr)); 
	} 
	void Dis_T_LDRisp(u16 op, char *out) 
	{ 
		sprintf(out,"ldr\t%s, [sp, $%03x]",TR0(op>>8),(op&0xFF)*4); 
	} 
	void Dis_T_ld2opimm(u16 op, char *out, char *name, int mul)  
	{ 
		sprintf(out,"%s\t%s, [%s + %d]",name,TR0(op),TR1(op),((op>>6)&0x1F) * mul); 
	} 
 
	void Dis_T_LDR(u16 op, char *out)    {Dis_T_ld2opimm(op,out,"ldr",4);} 
	void Dis_T_LDRH(u16 op, char *out)   {Dis_T_ld2opimm(op,out,"ldrh",2);} 
	void Dis_T_LDRB(u16 op, char *out)   {Dis_T_ld2opimm(op,out,"ldrb",1);} 
	void Dis_T_STR(u16 op, char *out)    {Dis_T_ld2opimm(op,out,"str",4);} 
	void Dis_T_STRB(u16 op, char *out)   {Dis_T_ld2opimm(op,out,"strb",1);} 
	void Dis_T_STRH(u16 op, char *out)   {Dis_T_ld2opimm(op,out,"strh",2);} 
 
	void Dis_T_ld3reg(u16 op, char *out, char *name) 
	{ 
		sprintf(out,"%s\t%s, [%s + %s]",name,TR0(op),TR1(op),TR2(op)); 
	} 
	void Dis_T_LDRrof(u16 op, char *out) {Dis_T_ld3reg(op,out,"ldr");} 
	void Dis_T_LDRBro(u16 op, char *out) {Dis_T_ld3reg(op,out,"ldrb");} 
	void Dis_T_LDRHro(u16 op, char *out) {Dis_T_ld3reg(op,out,"ldrh");} 
	void Dis_T_LDRSB(u16 op, char *out)  {Dis_T_ld3reg(op,out,"ldrsb");} 
	void Dis_T_LDRSH(u16 op, char *out)  {Dis_T_ld3reg(op,out,"ldrsh");} 
	void Dis_T_STRrof(u16 op, char *out) {Dis_T_ld3reg(op,out,"str");} 
	void Dis_T_STRHro(u16 op, char *out) {Dis_T_ld3reg(op,out,"strh");} 
	void Dis_T_STRBro(u16 op, char *out) {Dis_T_ld3reg(op,out,"strb");} 
 
	void Dis_T_STRisp(u16 op, char *out) 
	{ 
		sprintf(out,"str\t%s, [sp, $%03x]",TR0(op>>8),(op&0xFF)*4); 
	} 
 
	//Software int 
	void Dis_T_SWI(u16 op, char *out) 
	{ 
		sprintf(out,"swi\t$%04x",op&0xFF); 
	} 
 
 
	//branch 
	void Dis_T_Bcond(u16 op, char *out) 
	{ 
		sprintf(out,"b%s\t->$%08x",GetCondIdx((op>>8)&0xf),disPC+((s32)(s8)op)*2+4); 
	} 
	void Dis_T_B(u16 op, char *out) 
	{ 
		sprintf(out,"b\t->$%08x",disPC+((s32)SEX11(op))*2+4); 
	} 
	void Dis_T_BX(u16 op, char *out) 
	{ 
		sprintf(out,"bx\t->%s",GetReg((op>>3)&0xF)); 
	} 
	void Dis_T_BLX(u16 op, char *out) 
	{ 
		sprintf(out,"blx\t->%s",GetReg((op>>3)&0xF)); 
	} 
	void Dis_T_BLend(u16 op, char *out) 
	{ 
		sprintf(out,"-\t-"); 
	} 
 
 
	void Dis_T_BLbig(u16 op, char *out) 
	{ 
		u16 op2 = ReadMem16Unchecked(disPC+2); 
		bool bx = (op & (1<<11)) ? true : false; 
		u32 offset = disPC+4+(SEX11(op)<<12); 
		offset += (op2 & 0x7ff)*2; 
		if (bx==0) 
			offset &=~3; 
		sprintf(out,"bl%s\t->$%08x",bx?"":"x",offset); 
	} 
 
 
}