示例#1
0
文件: Debug.c 项目: dehaas-j/meka
void Z80_Disassemble_GetDecoratedSymbolFromAddress(const char* mnemonic, u16 addr, char* buf, int buf_len, bool display_symbols, bool display_addr)
{
	const t_debugger_symbol* symbol = NULL;
	if (display_symbols)
	{
		if (Z80_IsModifyingPC(mnemonic))
			symbol = Debugger_Symbols_GetClosestPreviousByAddr(addr, 64);		// too misleading for data address so only use for code address
		else
			symbol = Debugger_Symbols_GetLastByAddr(addr);
	}

	if (symbol != NULL)
	{
		if (display_addr)
		{
			if (symbol->cpu_addr != addr)
				snprintf(buf, buf_len,"%s+%Xh/%04Xh", symbol->name, addr-symbol->cpu_addr, addr);
			else
				snprintf(buf, buf_len,"%s/%04Xh", symbol->name, addr);
		}
		else
		{
			if (symbol->cpu_addr != addr)
				snprintf(buf, buf_len,"%s+%Xh", symbol->name, addr-symbol->cpu_addr);
			else
				snprintf(buf, buf_len,"%s", symbol->name);
		}
	}
	else
	{
		snprintf(buf, buf_len,"%04Xh", addr);
	}
}
示例#2
0
文件: Debug.c 项目: dafyddcrosby/meka
int     Z80_Disassemble(char *S, word A, bool display_symbols, bool resolve_indirect_offsets)
{
    char  R[256], H[256], C, *T, *P;
    byte  J, Offset = 0;
    word  B;
    int   relative_offset_base = 0;  // 0 : from PC, 1 : from IX, 2 : from IY

    B = A;
    C = '\0';
    J = 0;

    switch (RdZ80_NoHook(B))
    {
    case 0xCB: B++;T=MnemonicsCB[RdZ80_NoHook(B++&0xFFFF)];break;
    case 0xED: B++;T=MnemonicsED[RdZ80_NoHook(B++&0xFFFF)];break;
    case 0xDD: B++;C='X';
        if (RdZ80_NoHook(B&0xFFFF)!=0xCB) 
            T=MnemonicsXX[RdZ80_NoHook(B++&0xFFFF)];
        else
        { B++;Offset=RdZ80_NoHook(B++&0xFFFF);J=1;T=MnemonicsXCB[RdZ80_NoHook(B++&0xFFFF)]; }
        break;
    case 0xFD: B++;C='Y';
        if(RdZ80_NoHook(B&0xFFFF)!=0xCB) 
            T=MnemonicsXX[RdZ80_NoHook(B++&0xFFFF)];
        else
        { B++;Offset=RdZ80_NoHook(B++&0xFFFF);J=1;T=MnemonicsXCB[RdZ80_NoHook(B++&0xFFFF)]; }
        break;
    default:   
        T=Mnemonics[RdZ80_NoHook(B++&0xFFFF)];
        break;
    }

    if ((P=strchr(T,'^')) != NULL)
    {
        strncpy(R,T,P-T);R[P-T]='\0';
        sprintf(H,"%02Xh",RdZ80_NoHook(B++&0xFFFF));
        strcat(R,H);strcat(R,P+2);
    }
    else 
        strcpy(R,T);

    if ((P=strchr(R,'%')) != NULL) 
    {
        *P=C;
        if (C == 'X')
            relative_offset_base = 1;
        else if (C == 'Y')
            relative_offset_base = 2;
    }

    if ((P=strchr(R,'*')) != NULL)
    {
        if (S != NULL)
        {
            strncpy(S,R,P-R);S[P-R]='\0';
            sprintf(H,"%02Xh",RdZ80_NoHook(B++&0xFFFF));
            strcat(S,H);strcat(S,P+2);
        }
        else
        {
            B++;
        }
    }
    else
        if ((P=strchr(R,'@')) != NULL)
        {
            if (S != NULL)
            {
                strncpy(S,R,P-R);S[P-R]='\0';
                if(!J) 
                    Offset=RdZ80_NoHook(B++&0xFFFF);
                if (resolve_indirect_offsets && relative_offset_base == 0)
                {
                    const u16 target = B + (signed char)Offset;
                    const char sign = (Offset & 0x80) ? '-' : '+';
                    J = (Offset & 0x80) ? 256 - Offset : Offset;
                    sprintf(H, "%c%02Xh (%04Xh)", sign, J, target);
                    strcat(S,H);strcat(S,P+2); // skip the 'h' in the instruction
                }
                else
                {
                    strcat(S,Offset&0x80? "-":"+");
                    J=Offset&0x80? 256-Offset:Offset;
                    sprintf(H,"%02Xh",J);
                    strcat(S,H);strcat(S,P+2); // skip the 'h' in the instruction
                }
            }
            else
            {
                B++;
            }
        }
        else
            if((P=strchr(R,'#')) != NULL)
            {
                if (S != NULL)
                {
                    u16 addr = RdZ80_NoHook(B&0xFFFF)+256*RdZ80_NoHook((B+1)&0xFFFF);
                    t_debugger_symbol *symbol = display_symbols ? Debugger_Symbols_GetLastByAddr(addr) : NULL;
                    if (symbol != NULL)
                    {
                        strncpy(S,R,P-R);S[P-R]='\0';
                        snprintf(H,256,"%s (%04Xh)", symbol->name, addr);
                        strcat(S,H);strcat(S,P+2); // skip the 'h' in the instruction
                    }
                    else
                    {
                        strncpy(S,R,P-R);S[P-R]='\0';
                        sprintf(H,"%04Xh", addr);
                        strcat(S,H);strcat(S,P+2); // skip the 'h' in the instruction
                    }
                }
                B += 2;
            }
            else
            {
                if (S != NULL)
                    strcpy(S, R);
            }

    // MEKA-START: needed so it works properly when the instruction wrap at 0xffff
    if (B < A)
        return ((int)B+0x10000 - (int)A);
    // MEKA-END

    return (B-A);
}
示例#3
0
文件: Debug.c 项目: dehaas-j/meka
int     Z80_Disassemble(char *S, word A, bool display_symbols, bool display_symbols_for_current_index_registers, bool resolve_indirect_offsets)
{
    char  R[256], H[256], C;
    byte  Offset = 0;
	bool  has_offset = false;
    word  B;
    int   relative_offset_base = 0;  // 0 : from PC, 1 : from IX, 2 : from IY

    B = A;
    C = '\0';
    
	const char *T_const = NULL;
    switch (RdZ80_NoHook(B))
    {
    case 0xCB: B++;T_const=MnemonicsCB[RdZ80_NoHook(B++&0xFFFF)];break;
    case 0xED: B++;T_const=MnemonicsED[RdZ80_NoHook(B++&0xFFFF)];break;
    case 0xDD: B++;C='x';
        if (RdZ80_NoHook(B&0xFFFF)!=0xCB) 
            T_const=MnemonicsXX[RdZ80_NoHook(B++&0xFFFF)];
        else
        { B++;Offset=RdZ80_NoHook(B++&0xFFFF);has_offset=true;T_const=MnemonicsXCB[RdZ80_NoHook(B++&0xFFFF)]; }
        break;
    case 0xFD: B++;C='y';
        if(RdZ80_NoHook(B&0xFFFF)!=0xCB) 
            T_const=MnemonicsXX[RdZ80_NoHook(B++&0xFFFF)];
        else
        { B++;Offset=RdZ80_NoHook(B++&0xFFFF);has_offset=true;T_const=MnemonicsXCB[RdZ80_NoHook(B++&0xFFFF)]; }
        break;
    default:   
        T_const=Mnemonics[RdZ80_NoHook(B++&0xFFFF)];
        break;
    }
	char T[32];
	strcpy(T, T_const);
	StrLower(T);

	char *P;
    if ((P=strchr(T,'^')) != NULL)
    {
		assert(!has_offset);	// Should never get a ^ in the DD CB and FD CB paths
		if (S != NULL)
		{
			Offset = RdZ80_NoHook(B&0xFFFF);

			// convert 0xFF to -0x01 for nicer display
			const char offset_sign = (Offset & 0x80) ? '-' : '+';
			const byte offset_abs = (Offset & 0x80) ? 256 - Offset : Offset;

			if (resolve_indirect_offsets)
			{
				if (display_symbols_for_current_index_registers)
				{
					// P+2: skip the 'h' in the instruction
					const u16 addr = ((C == 'x') ? sms.R.IX.W : sms.R.IY.W) + (signed char)Offset;
					Z80_Disassemble_GetDecoratedSymbolFromAddress(R, addr, H, 256, display_symbols, false);		// Don't display full address because it is obvious (for IX/IY being typically stable)
					snprintf(R, 256, "%.*s%c%d=%s%s", (int)(P-T), T, offset_sign, offset_abs, H, P+2);
				}
				else
				{
					// P+2: skip the 'h' in the instruction
					snprintf(R, 256, "%.*s%c%d%s", (int)(P-T), T, offset_sign, offset_abs, P+2);
				}
			}
			else
			{
				snprintf(R, 256, "%.*s%c%d", (int)(P-T), T, offset_sign, offset_abs);
			}
		}
		else
		{
			strcpy(R,T);
		}
		B++;
	}
    else 
	{
        strcpy(R,T);
	}

    if ((P=strchr(R,'%')) != NULL) 
    {
        *P=C;
        if (C == 'x')
            relative_offset_base = 1;
        else if (C == 'y')
            relative_offset_base = 2;
    }

    if ((P=strchr(R,'*')) != NULL)
    {
        if (S != NULL)
        {
            strncpy(S,R,P-R);S[P-R]='\0';
            sprintf(H,"%02Xh",RdZ80_NoHook(B&0xFFFF));
            strcat(S,H);strcat(S,P+2);
        }
        B++;
    }
    else
	{
        if ((P=strchr(R,'@')) != NULL)
        {
            if (S != NULL)
            {
                if(!has_offset) 
                    Offset=RdZ80_NoHook(B&0xFFFF);

				// convert 0xFF to -0x01 for nicer display
				const char offset_sign = (Offset & 0x80) ? '-' : '+';
				const byte offset_abs = (Offset & 0x80) ? 256 - Offset : Offset;

                if (resolve_indirect_offsets)
                {
					// P+2: skip the 'h' in the instruction
					if (relative_offset_base == 0)
					{
						const u16 addr = (B+1) + (signed char)Offset;
						Z80_Disassemble_GetDecoratedSymbolFromAddress(R, addr, H, 256, display_symbols, true);
						snprintf(S, 255, "%.*s%c%02Xh (%s)%s", (int)(P-R), R, offset_sign, offset_abs, H, P+2);
					}
					else
					{
						const u16 addr = ((relative_offset_base == 1) ? sms.R.IX.W : sms.R.IY.W) + (signed char)Offset;
						Z80_Disassemble_GetDecoratedSymbolFromAddress(R, addr, H, 256, display_symbols, false);	// Don't display full address because it is obvious (for IX/IY being typically stable)
						snprintf(S, 255, "%.*s%c%d=%s%s", (int)(P-R), R, offset_sign, offset_abs, H, P+2);
					}
                }
                else
                {
					// P+2: skip the 'h' in the instruction
					snprintf(S, 256, "%.*s%c%02Xh%s", (int)(P-R), R, offset_sign, offset_abs, P+2);
                }
            }
			if(!has_offset)
				B++;
        }
		else if((P=strchr(R,'#')) != NULL)
		{
			if (S != NULL)
			{
				const u16 addr = RdZ80_NoHook(B&0xFFFF)+256*RdZ80_NoHook((B+1)&0xFFFF);
				Z80_Disassemble_GetDecoratedSymbolFromAddress(R, addr, H, 256, display_symbols, true);
				snprintf(S, 256, "%.*s%s%s", (int)(P-R), R, H, P+2);
			}
			B += 2;
		}
		else if(strncmp(R,"rst ",4)==0)
		{
			if (S != NULL)
			{
				const u16 addr = (u16)Debugger_Eval_ParseIntegerHex(R+4);
				const t_debugger_symbol* symbol = display_symbols ? Debugger_Symbols_GetLastByAddr(addr) : NULL;
				if (symbol != NULL)
				{
					sprintf(S,"rst %s/%02Xh", symbol->name, addr);
				}
				else
				{
					strcpy(S, R);
				}
			}
		}
		else
		{
			if (S != NULL)
				strcpy(S, R);
		}
	}

    // MEKA-START: needed so it works properly when the instruction wrap at 0xffff
    if (B < A)
        return ((int)B+0x10000 - (int)A);
    // MEKA-END

    return (B-A);
}