Пример #1
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[reg];
			m68ki_write_32(m68k, ea, (UINT32)(data >> 32));
			m68ki_write_32(m68k, ea, (UINT32)(data));
			break;
		}
		case 4:		// -(An)
		{
			UINT32 ea;
			REG_A[reg] -= 8;
			ea = REG_A[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;
		}
		default:	fatalerror("MC68040: WRITE_EA_64: unhandled mode %d, reg %d, data %08X%08X at %08X\n", mode, reg, (UINT32)(data >> 32), (UINT32)(data), REG_PC);
	}
}
Пример #2
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[reg];
		}
		case 2:		// (An)
		{
			UINT32 ea = REG_A[reg];
			return m68ki_read_32(m68k, ea);
		}
		case 3:		// (An)+
		{
			UINT32 ea = EA_AY_PI_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 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 4:		// #<data>
				{
					return  OPER_I_32(m68k);
				}
				default:	fatalerror("MC68040: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
			}
			break;
		}
		default:	fatalerror("MC68040: READ_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
	}
	return 0;
}
Пример #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[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[reg];
			REG_A[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 7:
		{
			switch (reg)
			{
				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("MC68040: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
			}
			break;
		}
		default:	fatalerror("MC68040: READ_EA_64: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
	}

	return 0;
}
Пример #4
0
static void fmove_fpcr(m68ki_cpu_core *m68k, UINT16 w2)
{
	int ea = m68k->ir & 0x3f;
	int dir = (w2 >> 13) & 0x1;
	int regsel = (w2 >> 10) & 0x7;
	int mode = (ea >> 3) & 0x7;

	if ((mode == 5) || (mode == 6))
	{
		UINT32 address = 0xffffffff;	// force a bus error if this doesn't get assigned

		if (mode == 5)
		{
			address = EA_AY_DI_32(m68k);
		}
		else if (mode == 6)
		{
			address = EA_AY_IX_32(m68k);
		}

		if (dir)	// From system control reg to <ea>
		{
			if (regsel & 4) { m68ki_write_32(m68k, address, REG_FPCR(m68k)); address += 4; }
			if (regsel & 2) { m68ki_write_32(m68k, address, REG_FPSR(m68k)); address += 4; }
			if (regsel & 1) { m68ki_write_32(m68k, address, REG_FPIAR(m68k)); address += 4; }
		}
		else		// From <ea> to system control reg
		{
			if (regsel & 4) { REG_FPCR(m68k) = m68ki_read_32(m68k, address); address += 4; }
			if (regsel & 2) { REG_FPSR(m68k) = m68ki_read_32(m68k, address); address += 4; }
			if (regsel & 1) { REG_FPIAR(m68k) = m68ki_read_32(m68k, address); address += 4; }
		}
	}
	else
	{
		if (dir)	// From system control reg to <ea>
		{
			if (regsel & 4) WRITE_EA_32(m68k, ea, REG_FPCR(m68k));
			if (regsel & 2) WRITE_EA_32(m68k, ea, REG_FPSR(m68k));
			if (regsel & 1) WRITE_EA_32(m68k, ea, REG_FPIAR(m68k));
		}
		else		// From <ea> to system control reg
		{
			if (regsel & 4) REG_FPCR(m68k) = READ_EA_32(m68k, ea);
			if (regsel & 2) REG_FPSR(m68k) = READ_EA_32(m68k, ea);
			if (regsel & 1) REG_FPIAR(m68k) = READ_EA_32(m68k, ea);
		}
	}

	m68k->remaining_cycles -= 10;
}
Пример #5
0
static void WRITE_EA_32(m68ki_cpu_core *m68k, int ea, UINT32 data)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	switch (mode)
	{
		case 0:		// Dn
		{
			REG_D[reg] = data;
			break;
		}
		case 2:		// (An)
		{
			UINT32 ea = REG_A[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("MC68040: WRITE_EA_32: unhandled mode %d, reg %d at %08X\n", mode, reg, REG_PC);
			}
			break;
		}
		default:	fatalerror("MC68040: WRITE_EA_32: unhandled mode %d, reg %d, data %08X at %08X\n", mode, reg, data, REG_PC);
	}
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
0
static void fmove_fpcr(m68000_base_device *m68k, UINT16 w2)
{
	int ea = m68k->ir & 0x3f;
	int dir = (w2 >> 13) & 0x1;
	int regsel = (w2 >> 10) & 0x7;
	int mode = (ea >> 3) & 0x7;

	if ((mode == 5) || (mode == 6))
	{
		UINT32 address = 0xffffffff;    // force a bus error if this doesn't get assigned

		if (mode == 5)
		{
			address = EA_AY_DI_32(m68k);
		}
		else if (mode == 6)
		{
			address = EA_AY_IX_32(m68k);
		}

		if (dir)    // From system control reg to <ea>
		{
			if (regsel & 4) { m68ki_write_32(m68k, address, REG_FPCR(m68k)); address += 4; }
			if (regsel & 2) { m68ki_write_32(m68k, address, REG_FPSR(m68k)); address += 4; }
			if (regsel & 1) { m68ki_write_32(m68k, address, REG_FPIAR(m68k)); address += 4; }
		}
		else        // From <ea> to system control reg
		{
			if (regsel & 4) { REG_FPCR(m68k) = m68ki_read_32(m68k, address); address += 4; }
			if (regsel & 2) { REG_FPSR(m68k) = m68ki_read_32(m68k, address); address += 4; }
			if (regsel & 1) { REG_FPIAR(m68k) = m68ki_read_32(m68k, address); address += 4; }
		}
	}
	else
	{
		if (dir)    // From system control reg to <ea>
		{
			if (regsel & 4) WRITE_EA_32(m68k, ea, REG_FPCR(m68k));
			if (regsel & 2) WRITE_EA_32(m68k, ea, REG_FPSR(m68k));
			if (regsel & 1) WRITE_EA_32(m68k, ea, REG_FPIAR(m68k));
		}
		else        // From <ea> to system control reg
		{
			if (regsel & 4) REG_FPCR(m68k) = READ_EA_32(m68k, ea);
			if (regsel & 2) REG_FPSR(m68k) = READ_EA_32(m68k, ea);
			if (regsel & 1) REG_FPIAR(m68k) = READ_EA_32(m68k, ea);
		}
	}

#if 0
	// FIXME: (2011-12-18 ost)
	// rounding_mode and rounding_precision of softfloat.c should be set according to current fpcr
	// but:  with this code on Apollo the following programs in /systest/fptest will fail:
	// 1. Single Precision Whetstone will return wrong results never the less
	// 2. Vector Test will fault with 00040004: reference to illegal address

	if ((regsel & 4) && dir == 0)
	{
		int rnd = (REG_FPCR(m68k) >> 4) & 3;
		int prec = (REG_FPCR(m68k) >> 6) & 3;

		logerror("m68k_fpsp:fmove_fpcr fpcr=%04x prec=%d rnd=%d\n", REG_FPCR(m68k), prec, rnd);

#ifdef FLOATX80
		switch (prec)
		{
		case 0: // Extend (X)
			floatx80_rounding_precision = 80;
			break;
		case 1: // Single (S)
			floatx80_rounding_precision = 32;
			break;
		case 2: // Double (D)
			floatx80_rounding_precision = 64;
			break;
		case 3: // Undefined
			floatx80_rounding_precision = 80;
			break;
		}
#endif

		switch (rnd)
		{
		case 0: // To Nearest (RN)
			float_rounding_mode = float_round_nearest_even;
			break;
		case 1: // To Zero (RZ)
			float_rounding_mode = float_round_to_zero;
			break;
		case 2: // To Minus Infinitiy (RM)
			float_rounding_mode = float_round_down;
			break;
		case 3: // To Plus Infinitiy (RP)
			float_rounding_mode = float_round_up;
			break;
		}
	}
Пример #9
0
static void WRITE_EA_64(m68000_base_device *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));
	}
}
Пример #10
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)