Example #1
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 #2
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;
		}
	}