Example #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);
	}
}
Example #2
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;
}
Example #3
0
INLINE void store_extended_float80(m68000_base_device *m68k, UINT32 ea, floatx80 fpr)
{
	m68ki_write_16(m68k, ea+0, fpr.high);
	m68ki_write_16(m68k, ea+2, 0);
	m68ki_write_32(m68k, ea+4, (fpr.low>>32)&0xffffffff);
	m68ki_write_32(m68k, ea+8, fpr.low&0xffffffff);
}
Example #4
0
static void WRITE_EA_FPE(m68ki_cpu_core *m68k, int ea, fp_reg fpr)
{
	int mode = (ea >> 3) & 0x7;
	int reg = (ea & 0x7);

	// TODO: convert to extended floating-point!

	switch (mode)
	{
		case 4:		// -(An)
		{
			UINT32 ea;
			REG_A[reg] -= 12;
			ea = REG_A[reg];
			m68ki_write_32(m68k, ea+0, (UINT32)(fpr.i >> 32));
			m68ki_write_32(m68k, ea+4, (UINT32)(fpr.i));
			m68ki_write_32(m68k, ea+8, 0);
			break;
		}
		default:	fatalerror("MC68040: WRITE_EA_FPE: unhandled mode %d, reg %d, data %f at %08X\n", mode, reg, fpr.f, REG_PC);
	}
}
Example #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);
	}
}
Example #6
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;
		}
	}
Example #7
0
INLINE void store_pack_float80(m68000_base_device *m68k, UINT32 ea, int k, floatx80 fpr)
{
	UINT32 dw1, dw2, dw3;
	char str[128], *ch;
	int i, j, exp;

	dw1 = dw2 = dw3 = 0;
	ch = &str[0];

	sprintf(str, "%.16e", fx80_to_double(fpr));

	if (*ch == '-')
	{
		ch++;
		dw1 = 0x80000000;
	}

	if (*ch == '+')
	{
		ch++;
	}

	dw1 |= (*ch++ - '0');

	if (*ch == '.')
	{
		ch++;
	}

	// handle negative k-factor here
	if ((k <= 0) && (k >= -13))
	{
		exp = 0;
		for (i = 0; i < 3; i++)
		{
			if (ch[18+i] >= '0' && ch[18+i] <= '9')
			{
				exp = (exp << 4) | (ch[18+i] - '0');
			}
		}

		if (ch[17] == '-')
		{
			exp = -exp;
		}

		k = -k;
		// last digit is (k + exponent - 1)
		k += (exp - 1);

		// round up the last significant mantissa digit
		if (ch[k+1] >= '5')
		{
			ch[k]++;
		}

		// zero out the rest of the mantissa digits
		for (j = (k+1); j < 16; j++)
		{
			ch[j] = '0';
		}

		// now zero out K to avoid tripping the positive K detection below
		k = 0;
	}

	// crack 8 digits of the mantissa
	for (i = 0; i < 8; i++)
	{
		dw2 <<= 4;
		if (*ch >= '0' && *ch <= '9')
		{
			dw2 |= *ch++ - '0';
		}
	}

	// next 8 digits of the mantissa
	for (i = 0; i < 8; i++)
	{
		dw3 <<= 4;
		if (*ch >= '0' && *ch <= '9')
		dw3 |= *ch++ - '0';
	}

	// handle masking if k is positive
	if (k >= 1)
	{
		if (k <= 17)
		{
			dw2 &= pkmask2[k];
			dw3 &= pkmask3[k];
		}
		else
		{
			dw2 &= pkmask2[17];
			dw3 &= pkmask3[17];
//          m68k->fpcr |=  (need to set OPERR bit)
		}
	}

	// finally, crack the exponent
	if (*ch == 'e' || *ch == 'E')
	{
		ch++;
		if (*ch == '-')
		{
			ch++;
			dw1 |= 0x40000000;
		}

		if (*ch == '+')
		{
			ch++;
		}

		j = 0;
		for (i = 0; i < 3; i++)
		{
			if (*ch >= '0' && *ch <= '9')
			{
				j = (j << 4) | (*ch++ - '0');
			}
		}

		dw1 |= (j << 16);
	}

	m68ki_write_32(m68k, ea, dw1);
	m68ki_write_32(m68k, ea+4, dw2);
	m68ki_write_32(m68k, ea+8, dw3);
}
Example #8
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));
	}
}