Example #1
0
static floatx80 READ_EA_PACK(m68ki_cpu_core *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;
}
Example #2
0
static void WRITE_EA_8(m68ki_cpu_core *m68k, int ea, UINT8 data)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 0:		// Dn
		{
			REG_D(m68k)[reg] = data;
			break;
		}
		case 2:		// (An)
		{
			UINT32 ea = REG_A(m68k)[reg];
			m68ki_write_8(m68k, ea, data);
			break;
		}
		case 3:		// (An)+
		{
			UINT32 ea = EA_AY_PI_8(m68k);
			m68ki_write_8(m68k, ea, data);
			break;
		}
		case 4:		// -(An)
		{
			UINT32 ea = EA_AY_PD_8(m68k);
			m68ki_write_8(m68k, ea, data);
			break;
		}
		case 5:		// (d16, An)
		{
			UINT32 ea = EA_AY_DI_8(m68k);
			m68ki_write_8(m68k, ea, data);
			break;
		}
		case 6:		// (An) + (Xn) + d8
		{
			UINT32 ea = EA_AY_IX_8(m68k);
			m68ki_write_8(m68k, ea, data);
			break;
		}
		case 7:
		{
			switch (reg)
			{
				case 1:		// (xxx).B
				{
					UINT32 d1 = OPER_I_16(m68k);
					UINT32 d2 = OPER_I_16(m68k);
					UINT32 ea = (d1 << 16) | d2;
					m68ki_write_8(m68k, ea, data);
					break;
				}
				case 2:		// (d16, PC)
				{
					UINT32 ea = EA_PCDI_16(m68k);
					m68ki_write_8(m68k, ea, data);
					break;
				}
				default:	fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC(m68k));
			}
			break;
		}
		default:	fatalerror("M68kFPU: WRITE_EA_8: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC(m68k));
	}
}
Example #3
0
static UINT64 READ_EA_64(m68ki_cpu_core *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;
}
Example #4
0
static floatx80 READ_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 = 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;
}
Example #5
0
static UINT32 READ_EA_32(m68ki_cpu_core *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;
}
Example #6
0
static void fmovem(m68ki_cpu_core *m68k, UINT16 w2)
{
	int i;
	int ea = m68k->ir & 0x3f;
	int dir = (w2 >> 13) & 0x1;
	int mode = (w2 >> 11) & 0x3;
	int reglist = w2 & 0xff;

	UINT32 mem_addr = 0;
	switch (ea >> 3)
	{
		case 5:		// (d16, An)
			mem_addr= EA_AY_DI_32(m68k);
			break;
		case 6:		// (An) + (Xn) + d8
			mem_addr= EA_AY_IX_32(m68k);
			break;
	}

	if (dir)	// From FP regs to mem
	{
		switch (mode)
		{
			case 1: // Dynamic register list, postincrement or control addressing mode.
				// FIXME: not really tested, but seems to work
				reglist = REG_D(m68k)[(reglist >> 4) & 7];

			case 0:		// Static register list, predecrement or control addressing mode
			{
				for (i=0; i < 8; i++)
				{
					if (reglist & (1 << i))
					{
						switch (ea >> 3)
						{
							case 5:		// (d16, An)
							case 6:		// (An) + (Xn) + d8
								store_extended_float80(m68k, mem_addr, REG_FP(m68k)[i]);
								mem_addr += 12;
								break;
							default:
								WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[i]);
								break;
						}

						m68k->remaining_cycles -= 2;
					}
				}
				break;
			}

			case 2:		// Static register list, postdecrement or control addressing mode
			{
				for (i=0; i < 8; i++)
				{
					if (reglist & (1 << i))
					{
						switch (ea >> 3)
						{
							case 5:		// (d16, An)
							case 6:		// (An) + (Xn) + d8
								store_extended_float80(m68k, mem_addr, REG_FP(m68k)[7-i]);
								mem_addr += 12;
								break;
							default:
								WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[7-i]);
								break;
						}

						m68k->remaining_cycles -= 2;
					}
				}
				break;
			}

			default:	fatalerror("M680x0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC(m68k)-4);
		}
	}
	else		// From mem to FP regs
	{
		switch (mode)
Example #7
0
static void fpgen_rm_reg(m68ki_cpu_core *m68k, UINT16 w2)
{
	int ea = m68k->ir & 0x3f;
	int rm = (w2 >> 14) & 0x1;
	int src = (w2 >> 10) & 0x7;
	int dst = (w2 >>  7) & 0x7;
	int opmode = w2 & 0x7f;
	floatx80 source;

	// fmovecr #$f, fp0 f200 5c0f

	if (rm)
	{
		switch (src)
		{
			case 0:		// Long-Word Integer
			{
				INT32 d = READ_EA_32(m68k, ea);
				source = int32_to_floatx80(d);
				break;
			}
			case 1:		// Single-precision Real
			{
				UINT32 d = READ_EA_32(m68k, ea);
				source = float32_to_floatx80(d);
				break;
			}
			case 2:		// Extended-precision Real
			{
				source = READ_EA_FPE(m68k, ea);
				break;
			}
			case 3:		// Packed-decimal Real
			{
				source = READ_EA_PACK(m68k, ea);
				break;
			}
			case 4:		// Word Integer
			{
				INT16 d = READ_EA_16(m68k, ea);
				source = int32_to_floatx80((INT32)d);
				break;
			}
			case 5:		// Double-precision Real
			{
				UINT64 d = READ_EA_64(m68k, ea);

				source = float64_to_floatx80(d);
				break;
			}
			case 6:		// Byte Integer
			{
				INT8 d = READ_EA_8(m68k, ea);
				source = int32_to_floatx80((INT32)d);
				break;
			}
			case 7:		// FMOVECR load from constant ROM
			{
				switch (w2 & 0x7f)
				{
					case 0x0:	// Pi
						source.high = 0x4000;
						source.low = U64(0xc90fdaa22168c235);
						break;

					case 0xb:	// log10(2)
						source.high = 0x3ffd;
						source.low = U64(0x9a209a84fbcff798);
						break;

					case 0xc:	// e
						source.high = 0x4000;
						source.low = U64(0xadf85458a2bb4a9b);
						break;

					case 0xd:	// log2(e)
						source.high = 0x3fff;
						source.low = U64(0xb8aa3b295c17f0bc);
						break;

					case 0xe:	// log10(e)
						source.high = 0x3ffd;
						source.low = U64(0xde5bd8a937287195);
						break;

					case 0xf:	// 0.0
						source = int32_to_floatx80((INT32)0);
						break;

					case 0x30:	// ln(2)
						source.high = 0x3ffe;
						source.low = U64(0xb17217f7d1cf79ac);
						break;

					case 0x31:	// ln(10)
						source.high = 0x4000;
						source.low = U64(0x935d8dddaaa8ac17);
						break;

					case 0x32:	// 1 (or 100?  manuals are unclear, but 1 would make more sense)
						source = int32_to_floatx80((INT32)1);
						break;

					case 0x33:	// 10^1
						source = int32_to_floatx80((INT32)10);
						break;

					case 0x34:	// 10^2
						source = int32_to_floatx80((INT32)10*10);
						break;

					default:
						fatalerror("fmove_rm_reg: unknown constant ROM offset %x at %08x\n", w2&0x7f, REG_PC(m68k)-4);
						break;
				}

				// handle it right here, the usual opmode bits aren't valid in the FMOVECR case
				REG_FP(m68k)[dst] = source;
				m68k->remaining_cycles -= 4;
				return;
			}
			default:	fatalerror("fmove_rm_reg: invalid source specifier %x at %08X\n", src, REG_PC(m68k)-4);
		}
	}
	else
	{
		source = REG_FP(m68k)[src];
	}



	switch (opmode)
	{
		case 0x00:		// FMOVE
		{
			REG_FP(m68k)[dst] = source;
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 4;
			break;
		}
		case 0x01:		// FINT
		{
			INT32 temp;
			temp = floatx80_to_int32(source);
			REG_FP(m68k)[dst] = int32_to_floatx80(temp);
			break;
		}
		case 0x03:		// FINTRZ
		{
			INT32 temp;
			temp = floatx80_to_int32_round_to_zero(source);
			REG_FP(m68k)[dst] = int32_to_floatx80(temp);
			break;
		}
		case 0x04:		// FSQRT
		{
			REG_FP(m68k)[dst] = floatx80_sqrt(source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 109;
			break;
		}
		case 0x0e:      // FSIN
		{
			REG_FP(m68k)[dst] = source;
			floatx80_fsin(REG_FP(m68k)[dst]);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 75;
			break;
		}
		case 0x0f:		// FTAN
		{
			REG_FP(m68k)[dst] = source;
			floatx80_ftan(REG_FP(m68k)[dst]);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 75;
			break;
		}
		case 0x18:		// FABS
		{
			REG_FP(m68k)[dst] = source;
			REG_FP(m68k)[dst].high &= 0x7fff;
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 3;
			break;
		}
		case 0x1a:		// FNEG
		{
			REG_FP(m68k)[dst] = source;
			REG_FP(m68k)[dst].high ^= 0x8000;
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 3;
			break;
		}
		case 0x1d:      // FCOS
		{
			REG_FP(m68k)[dst] = source;
			floatx80_fcos(REG_FP(m68k)[dst]);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 75;
			break;
		}
		case 0x1e:		// FGETEXP
		{
			INT16 temp2;

			temp2 = source.high;	// get the exponent
			temp2 -= 0x3fff;	// take off the bias
			REG_FP(m68k)[dst] = double_to_fx80((double)temp2);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 6;
		}
		case 0x20:		// FDIV
		{
			REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
			m68k->remaining_cycles -= 43;
			break;
		}
		case 0x22:		// FADD
		{
			REG_FP(m68k)[dst] = floatx80_add(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 9;
			break;
		}
		case 0x23:		// FMUL
		{
			REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 11;
			break;
		}
		case 0x24:		// FSGLDIV
		{
			REG_FP(m68k)[dst] = floatx80_div(REG_FP(m68k)[dst], source);
			m68k->remaining_cycles -= 43; //  // ? (value is from FDIV)
			break;
		}
		case 0x25:		// FREM
		{
			REG_FP(m68k)[dst] = floatx80_rem(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 43;	// guess
			break;
		}
		case 0x27:		// FSGLMUL
		{
			REG_FP(m68k)[dst] = floatx80_mul(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 11; // ? (value is from FMUL)
			break;
		}
		case 0x28:		// FSUB
		{
			REG_FP(m68k)[dst] = floatx80_sub(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, REG_FP(m68k)[dst]);
			m68k->remaining_cycles -= 9;
			break;
		}
		case 0x38:		// FCMP
		{
			floatx80 res;
			res = floatx80_sub(REG_FP(m68k)[dst], source);
			SET_CONDITION_CODES(m68k, res);
			m68k->remaining_cycles -= 7;
			break;
		}
		case 0x3a:		// FTST
		{
			floatx80 res;
			res = source;
			SET_CONDITION_CODES(m68k, res);
			m68k->remaining_cycles -= 7;
			break;
		}

		default:	fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PPC(m68k));
	}
}
Example #8
0
static void WRITE_EA_PACK(m68ki_cpu_core *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));
	}
}
Example #9
0
int apollo_debug_instruction_hook(device_t *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;
		m68ki_cpu_core *m68k = (m68ki_cpu_core *) downcast<legacy_cpu_device *> (device)->token();
		m68k->mmu_tmp_buserror_occurred = 0;

		/* Read next instruction */
		ir = (m68k->pref_addr == REG_PC(m68k)) ? m68k->pref_data : m68k->memory.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;
}