Beispiel #1
0
static floatx80 READ_EA_PACK(m68000_base_device *m68k, int ea)
{
	floatx80 fpr;
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 2:     // (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			fpr = load_pack_float80(m68k, ea);
			break;
		}

		case 3:     // (An)+
		{
			UINT32 ea = REG_A(m68k)[reg];
			REG_A(m68k)[reg] += 12;
			fpr = load_pack_float80(m68k, ea);
			break;
		}

		case 7: // extended modes
		{
			switch (reg)
			{
				case 3: // (d16,PC,Dx.w)
					{
						UINT32 ea = EA_PCIX_32(m68k);
						fpr = load_pack_float80(m68k, ea);
					}
					break;

				default:
					fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
					break;
			}
		}
		break;

		default:    fatalerror("M68kFPU: READ_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k)); break;
	}

	return fpr;
}
Beispiel #2
0
ULONG ParseIntOp(PUCHAR inString,
                 PUCHAR *outString,
                 POPTBLENTRY pEntry,
                 PULONG poffset)
{
    ULONG instruction;
    ULONG Ra, Rb, Rc;
    ULONG lit;
    ULONG Format;	// Whether there is a literal or 3rd reg

    instruction = OPCODE(pEntry->opCode) +
                  OP_FNC(pEntry->funcCode);

    Ra = GetIntReg(inString, &inString);

    if (!TestCharacter(inString, &inString, ','))
 	error(OPERAND);

    if (TestCharacter(inString, &inString, '#')) {

        //
        // User is giving us a literal value

        lit = GetValue(inString, &inString, TRUE, WIDTH_LIT);
        Format = RBV_LITERAL_FORMAT;

    } else {

        //
        // using a third register value

        Rb = GetIntReg(inString, &inString);
        Format = RBV_REGISTER_FORMAT;
    }

    if (!TestCharacter(inString, &inString, ','))
 	error(OPERAND);

    Rc = GetIntReg(inString, &inString);

    if (!TestCharacter(inString, &inString, '\0'))
 	error(EXTRACHARS);

    instruction = instruction +
                  REG_A(Ra) +
                  RBV_TYPE(Format) +
                  REG_C(Rc);

    if (Format == RBV_REGISTER_FORMAT) {
        instruction = instruction + REG_B(Rb);
    } else {
        instruction = instruction + LIT(lit);
    }

    return(instruction);
}
Beispiel #3
0
static void WRITE_EA_PACK(m68000_base_device *m68k, int ea, int k, floatx80 fpr)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 2:     // (An)
		{
			UINT32 ea;
			ea = REG_A(m68k)[reg];
			store_pack_float80(m68k, ea, k, fpr);
			break;
		}

		case 3:     // (An)+
		{
			UINT32 ea;
			ea = REG_A(m68k)[reg];
			store_pack_float80(m68k, ea, k, fpr);
			REG_A(m68k)[reg] += 12;
			break;
		}

		case 4:     // -(An)
		{
			UINT32 ea;
			REG_A(m68k)[reg] -= 12;
			ea = REG_A(m68k)[reg];
			store_pack_float80(m68k, ea, k, fpr);
			break;
		}

		case 7:
		{
			switch (reg)
			{
				default:    fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
			}
		}
		default:    fatalerror("M68kFPU: WRITE_EA_PACK: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
	}
}
Beispiel #4
0
static void WRITE_EA_FPE(m68ki_cpu_core *m68k, int ea, floatx80 fpr)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 2:     // (An)
		{
			UINT32 ea;
			ea = REG_A(m68k)[reg];
			store_extended_float80(m68k, ea, fpr);
			break;
		}

		case 3:     // (An)+
		{
			UINT32 ea;
			ea = REG_A(m68k)[reg];
			store_extended_float80(m68k, ea, fpr);
			REG_A(m68k)[reg] += 12;
			break;
		}

		case 4:     // -(An)
		{
			UINT32 ea;
			REG_A(m68k)[reg] -= 12;
			ea = REG_A(m68k)[reg];
			store_extended_float80(m68k, ea, fpr);
			break;
		}

		case 7:
		{
			switch (reg)
			{
				default:    fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
			}
		}
		default:    fatalerror("M68kFPU: WRITE_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
	}
}
Beispiel #5
0
ULONG ParseJump(PUCHAR inString,
                PUCHAR *outString,
                POPTBLENTRY pEntry,
                PULONG poffset)
{
    ULONG instruction;
    ULONG Ra;
    ULONG Rb;
    ULONG hint;

    Ra = GetIntReg(inString, &inString);

    if (!TestCharacter(inString, &inString, ','))
	error(OPERAND);

    if (!TestCharacter(inString, &inString, '('))
	error(OPERAND);

    Rb = GetIntReg(inString, &inString);

    if (!TestCharacter(inString, &inString, ')'))
	error(OPERAND);

    if (TestCharacter(inString, &inString, ',')) {
        //
        // User is giving us a hint
        //
        hint = GetValue(inString, &inString, TRUE, WIDTH_HINT);
    } else {
        hint = 0;
    }

    if (!TestCharacter(inString, &inString, '\0'))
	error(EXTRACHARS);

    instruction = OPCODE(pEntry->opCode) +
                  JMP_FNC(pEntry->funcCode) +
		  REG_A(Ra) +
		  REG_B(Rb) +
		  HINT(hint);

    return(instruction);
}
Beispiel #6
0
/*** ParseFltBranch - parse floating point branch instruction
*
*   Purpose:
*	Given the users input, create the memory instruction.
*
*   Input:
*	*inString - present input position
*	pEntry - pointer into the asmTable for this instr type
*
*   Output:
*	*outstring - update input position
*
*   Returns:
*	the instruction.
*
*   Format:
*	op Fa,disp
*
*************************************************************************/
ULONG ParseFltBranch(PUCHAR inString,
                     PUCHAR *outString,
                     POPTBLENTRY pEntry,
                     PULONG poffset)
{
    ULONG instruction;
    ULONG Ra;
    LONG disp;

    Ra = GetFltReg(inString, &inString);

    if (!TestCharacter(inString, &inString, ','))
	error(OPERAND);

    //
    // the user gives an absolute address; we convert
    // that to a displacement, which is computed as a
    // difference off of (pc+1)
    // GetValue handles both numerics and symbolics
    //
    disp = GetValue(inString, &inString, TRUE, 32);

    // get the relative displacement from the updated pc
    disp = disp - (LONG)((*poffset)+4);

    // divide by four
    disp = disp >> 2;

    if (!TestCharacter(inString, &inString, '\0'))
	error(EXTRACHARS);

    instruction = OPCODE(pEntry->opCode) +
		  REG_A(Ra) +
		  BR_DISP(disp);

    return(instruction);
}
Beispiel #7
0
ULONG
ParseFltMemory(PUCHAR inString,
               PUCHAR *outString,
               POPTBLENTRY pEntry,
               PULONG poffset)
{
    ULONG instruction;
    ULONG Fa;
    ULONG Rb;
    ULONG disp;

    Fa = GetFltReg(inString, &inString);

    if (!TestCharacter(inString, &inString, ','))
	error(OPERAND);

    disp = GetValue(inString, &inString, TRUE, WIDTH_MEM_DISP);

    if (!TestCharacter(inString, &inString, '('))
	error(OPERAND);

    Rb = GetIntReg(inString, &inString);

    if (!TestCharacter(inString, &inString, ')'))
	error(OPERAND);

    if (!TestCharacter(inString, &inString, '\0'))
	error(EXTRACHARS);

    instruction = OPCODE(pEntry->opCode) +
		  REG_A(Fa) +
		  REG_B(Rb) +
		  MEM_DISP(disp);

    return(instruction);
}
Beispiel #8
0
static void WRITE_EA_32(m68000_base_device *m68k, int ea, UINT32 data)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 0:     // Dn
		{
			REG_D(m68k)[reg] = data;
			break;
		}
		case 1:     // An
		{
			REG_A(m68k)[reg] = data;
			break;
		}
		case 2:     // (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			m68ki_write_32(m68k, ea, data);
			break;
		}
		case 3:     // (An)+
		{
			UINT32 ea = EA_AY_PI_32(m68k);
			m68ki_write_32(m68k, ea, data);
			break;
		}
		case 4:     // -(An)
		{
			UINT32 ea = EA_AY_PD_32(m68k);
			m68ki_write_32(m68k, ea, data);
			break;
		}
		case 5:     // (d16, An)
		{
			UINT32 ea = EA_AY_DI_32(m68k);
			m68ki_write_32(m68k, ea, data);
			break;
		}
		case 6:     // (An) + (Xn) + d8
		{
			UINT32 ea = EA_AY_IX_32(m68k);
			m68ki_write_32(m68k, ea, data);
			break;
		}
		case 7:
		{
			switch (reg)
			{
				case 1:     // (xxx).L
				{
					UINT32 d1 = OPER_I_16(m68k);
					UINT32 d2 = OPER_I_16(m68k);
					UINT32 ea = (d1 << 16) | d2;
					m68ki_write_32(m68k, ea, data);
					break;
				}
				case 2:     // (d16, PC)
				{
					UINT32 ea = EA_PCDI_32(m68k);
					m68ki_write_32(m68k, ea, data);
					break;
				}
				default:    fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
			}
			break;
		}
		default:    fatalerror("M68kFPU: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
	}
}
Beispiel #9
0
static floatx80 READ_EA_FPE(m68000_base_device *m68k, int ea)
{
	floatx80 fpr;
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 2:     // (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			fpr = load_extended_float80(m68k, ea);
			break;
		}

		case 3:     // (An)+
		{
			UINT32 ea = REG_A(m68k)[reg];
			REG_A(m68k)[reg] += 12;
			fpr = load_extended_float80(m68k, ea);
			break;
		}
		case 4:     // -(An)
		{
			UINT32 ea = REG_A(m68k)[reg]-12;
			REG_A(m68k)[reg] -= 12;
			fpr = load_extended_float80(m68k, ea);
			break;
		}
		case 5:     // (d16, An)
		{
			// FIXME: will fail for fmovem
			UINT32 ea = EA_AY_DI_32(m68k);
			fpr = load_extended_float80(m68k, ea);
			break;
		}
		case 6:     // (An) + (Xn) + d8
		{
			// FIXME: will fail for fmovem
			UINT32 ea = EA_AY_IX_32(m68k);
			fpr = load_extended_float80(m68k, ea);
			break;
		}

		case 7: // extended modes
		{
			switch (reg)
			{
				case 2: // (d16, PC)
					{
						UINT32 ea = EA_PCDI_32(m68k);
						fpr = load_extended_float80(m68k, ea);
					}
					break;

				case 3: // (d16,PC,Dx.w)
					{
						UINT32 ea = EA_PCIX_32(m68k);
						fpr = load_extended_float80(m68k, ea);
					}
					break;

				default:
					fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k));
					break;
			}
		}
		break;

		default:    fatalerror("M68kFPU: READ_EA_FPE: unhandled mode %d, reg %d, at %08X\n", mode, reg, REG_PC(m68k)); break;
	}

	return fpr;
}
Beispiel #10
0
static UINT64 READ_EA_64(m68000_base_device *m68k, int ea)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);
	UINT32 h1, h2;

	switch (mode)
	{
		case 2:     // (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			h1 = m68ki_read_32(m68k, ea+0);
			h2 = m68ki_read_32(m68k, ea+4);
			return  (UINT64)(h1) << 32 | (UINT64)(h2);
		}
		case 3:     // (An)+
		{
			UINT32 ea = REG_A(m68k)[reg];
			REG_A(m68k)[reg] += 8;
			h1 = m68ki_read_32(m68k, ea+0);
			h2 = m68ki_read_32(m68k, ea+4);
			return  (UINT64)(h1) << 32 | (UINT64)(h2);
		}
		case 4:     // -(An)
		{
			UINT32 ea = REG_A(m68k)[reg]-8;
			REG_A(m68k)[reg] -= 8;
			h1 = m68ki_read_32(m68k, ea+0);
			h2 = m68ki_read_32(m68k, ea+4);
			return  (UINT64)(h1) << 32 | (UINT64)(h2);
		}
		case 5:     // (d16, An)
		{
			UINT32 ea = EA_AY_DI_32(m68k);
			h1 = m68ki_read_32(m68k, ea+0);
			h2 = m68ki_read_32(m68k, ea+4);
			return  (UINT64)(h1) << 32 | (UINT64)(h2);
		}
		case 6:     // (An) + (Xn) + d8
		{
			UINT32 ea = EA_AY_IX_32(m68k);
			h1 = m68ki_read_32(m68k, ea+0);
			h2 = m68ki_read_32(m68k, ea+4);
			return  (UINT64)(h1) << 32 | (UINT64)(h2);
		}
		case 7:
		{
			switch (reg)
			{
				case 1:     // (xxx).L
				{
					UINT32 d1 = OPER_I_16(m68k);
					UINT32 d2 = OPER_I_16(m68k);
					UINT32 ea = (d1 << 16) | d2;
					return (UINT64)(m68ki_read_32(m68k, ea)) << 32 | (UINT64)(m68ki_read_32(m68k, ea+4));
				}
				case 3:     // (PC) + (Xn) + d8
				{
					UINT32 ea =  EA_PCIX_32(m68k);
					h1 = m68ki_read_32(m68k, ea+0);
					h2 = m68ki_read_32(m68k, ea+4);
					return  (UINT64)(h1) << 32 | (UINT64)(h2);
				}
				case 4:     // #<data>
				{
					h1 = OPER_I_32(m68k);
					h2 = OPER_I_32(m68k);
					return  (UINT64)(h1) << 32 | (UINT64)(h2);
				}
				case 2:     // (d16, PC)
				{
					UINT32 ea = EA_PCDI_32(m68k);
					h1 = m68ki_read_32(m68k, ea+0);
					h2 = m68ki_read_32(m68k, ea+4);
					return  (UINT64)(h1) << 32 | (UINT64)(h2);
				}
				default:    fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
			}
			break;
		}
		default:    fatalerror("M68kFPU: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
	}

	return 0;
}
Beispiel #11
0
static UINT32 READ_EA_32(m68000_base_device *m68k, int ea)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 0:     // Dn
		{
			return REG_D(m68k)[reg];
		}
		case 2:     // (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			return m68ki_read_32(m68k, ea);
		}
		case 3:     // (An)+
		{
			UINT32 ea = EA_AY_PI_32(m68k);
			return m68ki_read_32(m68k, ea);
		}
		case 4:     // -(An)
		{
			UINT32 ea = EA_AY_PD_32(m68k);
			return m68ki_read_32(m68k, ea);
		}
		case 5:     // (d16, An)
		{
			UINT32 ea = EA_AY_DI_32(m68k);
			return m68ki_read_32(m68k, ea);
		}
		case 6:     // (An) + (Xn) + d8
		{
			UINT32 ea = EA_AY_IX_32(m68k);
			return m68ki_read_32(m68k, ea);
		}
		case 7:
		{
			switch (reg)
			{
				case 0:     // (xxx).W
				{
					UINT32 ea = (UINT32)OPER_I_16(m68k);
					return m68ki_read_32(m68k, ea);
				}
				case 1:     // (xxx).L
				{
					UINT32 d1 = OPER_I_16(m68k);
					UINT32 d2 = OPER_I_16(m68k);
					UINT32 ea = (d1 << 16) | d2;
					return m68ki_read_32(m68k, ea);
				}
				case 2:     // (d16, PC)
				{
					UINT32 ea = EA_PCDI_32(m68k);
					return m68ki_read_32(m68k, ea);
				}
				case 3:     // (PC) + (Xn) + d8
				{
					UINT32 ea =  EA_PCIX_32(m68k);
					return m68ki_read_32(m68k, ea);
				}
				case 4:     // #<data>
				{
					return  OPER_I_32(m68k);
				}
				default:    fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
			}
			break;
		}
		default:    fatalerror("M68kFPU: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
	}
	return 0;
}
Beispiel #12
0
static void WRITE_EA_64(m68ki_cpu_core *m68k, int ea, UINT64 data)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 2:     // (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			m68ki_write_32(m68k, ea, (UINT32)(data >> 32));
			m68ki_write_32(m68k, ea+4, (UINT32)(data));
			break;
		}
		case 3:     // (An)+
		{
			UINT32 ea = REG_A(m68k)[reg];
			REG_A(m68k)[reg] += 8;
			m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
			m68ki_write_32(m68k, ea+4, (UINT32)(data));
			break;
		}
		case 4:     // -(An)
		{
			UINT32 ea;
			REG_A(m68k)[reg] -= 8;
			ea = REG_A(m68k)[reg];
			m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
			m68ki_write_32(m68k, ea+4, (UINT32)(data));
			break;
		}
		case 5:     // (d16, An)
		{
			UINT32 ea = EA_AY_DI_32(m68k);
			m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
			m68ki_write_32(m68k, ea+4, (UINT32)(data));
			break;
		}
		case 6:     // (An) + (Xn) + d8
		{
			UINT32 ea = EA_AY_IX_32(m68k);
			m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
			m68ki_write_32(m68k, ea+4, (UINT32)(data));
			break;
		}
		case 7:
		{
			switch (reg)
			{
				case 1:     // (xxx).L
				{
					UINT32 d1 = OPER_I_16(m68k);
					UINT32 d2 = OPER_I_16(m68k);
					UINT32 ea = (d1 << 16) | d2;
					m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
					m68ki_write_32(m68k, ea+4, (UINT32)(data));
					break;
				}
				case 2:     // (d16, PC)
				{
					UINT32 ea = EA_PCDI_32(m68k);
					m68ki_write_32(m68k, ea+0, (UINT32)(data >> 32));
					m68ki_write_32(m68k, ea+4, (UINT32)(data));
					break;
				}
				default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
			}
			break;
		}
		default:    fatalerror("M68kFPU: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (UINT32)(data >> 32), (UINT32)(data), REG_PC(m68k));
	}
}
Beispiel #13
0
static const char* get_svc_call(m68000_base_device *m68k, int trap_no,
		int trap_code,  char *sb)
{
	UINT32 sp = REG_A(m68k)[7];
	UINT32 pa;
	const char * name = NULL;
	const char * param = NULL;

	switch (trap_no)
	{
	case 0:
		if (trap_no < sizeof(trap0) / 8)
		{
			name = trap0[trap_code * 2];
			param = trap0[trap_code * 2 + 1];
		}
		break;
	case 1:
		if (trap_no < sizeof(trap1) / 8)
		{
			name = trap1[trap_code * 2];
			param = trap1[trap_code * 2 + 1];
		}
		break;
	case 2:
		if (trap_no < sizeof(trap2) / 8)
		{
			name = trap2[trap_code * 2];
			param = trap2[trap_code * 2 + 1];
		}
		break;
	case 3:
		if (trap_no < sizeof(trap3) / 8)
		{
			name = trap3[trap_code * 2];
			param = trap3[trap_code * 2 + 1];
		}
		break;
	case 4:
		if (trap_no < sizeof(trap4) / 8)
		{
			name = trap4[trap_code * 2];
			param = trap4[trap_code * 2 + 1];
		}
		break;
	case 5:
		if (trap_no < sizeof(trap5) / 8)
		{
			name = trap5[trap_code * 2];
			param = trap5[trap_code * 2 + 1];
		}
		break;
	case 7:
		if (trap_no < sizeof(trap7) / 8)
		{
			name = trap7[trap_code * 2];
			param = trap7[trap_code * 2 + 1];
		}
		break;
	case 8:
		if (trap_no < sizeof(trap8) / 8)
		{
			name = trap8[trap_code * 2];
			param = trap8[trap_code * 2 + 1];
		}
		break;
	}

	sb[0] = '\0';

	if (name == NULL)
	{
		strcat(sb, "???");
	}
	else
	{
		strcat(sb, name);
		if (param != NULL)
		{
			int i;
			strcat(sb, "(");
			for (i = 0, pa = sp + 4; param[i] != '\0'; i++)
			{
				switch (param[i])
				{
				case ',':
					strcat(sb, ", ");
					pa += 4;
					break;
				default:
					strcat(sb, get_param(m68k, pa, param[i]));
					break;
				}
			}
			strcat(sb, ")");
		}
	}
	return sb;
}
Beispiel #14
0
int apollo_debug_instruction_hook(m68000_base_device *device, offs_t curpc)
{
	// trap data remembered for next rte
	static struct {
		UINT32 pc;
		UINT32 sp;
		UINT16 trap_no;
		UINT16 trap_code;
	} trap = { 0, 0, 0, 0 };

	if (apollo_config( APOLLO_CONF_TRAP_TRACE | APOLLO_CONF_FPU_TRACE))
	{
		UINT32 ppc_save;
		UINT16 ir;
		m68000_base_device *m68k = device;
		m68k->mmu_tmp_buserror_occurred = 0;

		/* Read next instruction */
		ir = (m68k->pref_addr == REG_PC(m68k)) ? m68k->pref_data : m68k->readimm16(REG_PC(m68k));

		// apollo_cpu_context expects the PC of current opcode in REG_PPC (not the previous PC)
		ppc_save = REG_PPC(m68k);
		REG_PPC(m68k) = REG_PC(m68k);

		if (m68k->mmu_tmp_buserror_occurred)
		{
			m68k->mmu_tmp_buserror_occurred = 0;
			// give up
		}
		else if ((ir & 0xff00) == 0xf200 && (apollo_config( APOLLO_CONF_FPU_TRACE)))
		{
			char sb[256];
			LOG(("%s sp=%08x FPU: %x %s", apollo_cpu_context(device->machine().firstcpu),
					REG_A(m68k)[7], ir, disassemble(m68k, REG_PC(m68k), sb)));
		}
		else if (!m68k->pmmu_enabled)
		{
			// skip
		}
		else if (ir == 0x4e73) // RTE
		{
			const UINT16 *data = get_data(m68k, REG_A(m68k)[7]);
			if ( REG_USP(m68k) == 0 && (data[0] & 0x2000) == 0) {
				LOG(("%s sp=%08x RTE: sr=%04x pc=%04x%04x v=%04x usp=%08x",
					apollo_cpu_context(device->machine().firstcpu),
					REG_A(m68k)[7], data[0], data[1], data[2], data[3], REG_USP(m68k)));
			}
		}
		else if ((ir & 0xfff0) == 0x4e40 && (ir & 0x0f) <= 8 && apollo_config(APOLLO_CONF_TRAP_TRACE))
		{
			// trap n
			trap.pc = REG_PC(m68k);
			trap.sp = REG_A(m68k)[7];
			trap.trap_no = ir & 0x0f;
			trap.trap_code = REG_D(m68k)[0] & 0xffff;

			char sb[1000];
			LOG(("%s sp=%08x Domain/OS SVC: trap %x 0x%02x: %s",
					apollo_cpu_context(device->machine().firstcpu), trap.sp,
					trap.trap_no, trap.trap_code,
					get_svc_call(m68k, trap.trap_no, trap.trap_code, sb)));

		}
		else if (trap.pc == REG_PC(m68k) - 2 && trap.sp == REG_A(m68k)[7])
		{
			// rte
			char sb[1000];
			LOG(("%s sp=%08x Domain/OS SVC:              %s D0=0x%x",
					apollo_cpu_context(device->machine().firstcpu), trap.sp,
					get_svc_call(m68k, trap.trap_no, trap.trap_code, sb), REG_D(m68k)[0]));

			trap.pc = 0;
			trap.sp = 0;
			trap.trap_no = 0;
			trap.trap_code = 0;
		}
		// restore previous PC
		REG_PPC(m68k) = ppc_save;
	}
	return 0;
}