Exemplo n.º 1
0
INLINE void SET_CONDITION_CODES(m68000_base_device *m68k, floatx80 reg)
{
//  UINT64 *regi;

//  regi = (UINT64 *)®

	REG_FPSR(m68k) &= ~(FPCC_N|FPCC_Z|FPCC_I|FPCC_NAN);

	// sign flag
	if (reg.high & 0x8000)
	{
		REG_FPSR(m68k) |= FPCC_N;
	}

	// zero flag
	if (((reg.high & 0x7fff) == 0) && ((reg.low<<1) == 0))
	{
		REG_FPSR(m68k) |= FPCC_Z;
	}

	// infinity flag
	if (((reg.high & 0x7fff) == 0x7fff) && ((reg.low<<1) == 0))
	{
		REG_FPSR(m68k) |= FPCC_I;
	}

	// NaN flag
	if (floatx80_is_nan(reg))
	{
		REG_FPSR(m68k) |= FPCC_NAN;
	}
}
Exemplo n.º 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;
}
Exemplo n.º 3
0
INLINE int TEST_CONDITION(m68000_base_device *m68k, int condition)
{
	int n = (REG_FPSR(m68k) & FPCC_N) != 0;
	int z = (REG_FPSR(m68k) & FPCC_Z) != 0;
	int nan = (REG_FPSR(m68k) & FPCC_NAN) != 0;
	int r = 0;
	switch (condition)
	{
		case 0x10:
		case 0x00:      return 0;                   // False

		case 0x11:
		case 0x01:      return (z);                 // Equal

		case 0x12:
		case 0x02:      return (!(nan || z || n));          // Greater Than

		case 0x13:
		case 0x03:      return (z || !(nan || n));          // Greater or Equal

		case 0x14:
		case 0x04:      return (n && !(nan || z));          // Less Than

		case 0x15:
		case 0x05:      return (z || (n && !nan));          // Less Than or Equal

		case 0x16:
		case 0x06:      return !nan && !z;

		case 0x17:
		case 0x07:      return !nan;

		case 0x18:
		case 0x08:      return nan;

		case 0x19:
		case 0x09:      return nan || z;

		case 0x1a:
		case 0x0a:      return (nan || !(n || z));          // Not Less Than or Equal

		case 0x1b:
		case 0x0b:      return (nan || z || !n);            // Not Less Than

		case 0x1c:
		case 0x0c:      return (nan || (n && !z));          // Not Greater or Equal Than

		case 0x1d:
		case 0x0d:      return (nan || z || n);             // Not Greater Than

		case 0x1e:
		case 0x0e:      return (!z);                    // Not Equal

		case 0x1f:
		case 0x0f:      return 1;                   // True

		default:        fatalerror("M68kFPU: test_condition: unhandled condition %02X\n", condition);
	}

	return r;
}
Exemplo n.º 4
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;
		}
	}
Exemplo n.º 5
0
static void fmove_reg_mem(m68000_base_device *m68k, UINT16 w2)
{
	int ea = m68k->ir & 0x3f;
	int src = (w2 >>  7) & 0x7;
	int dst = (w2 >> 10) & 0x7;
	int k = (w2 & 0x7f);

	switch (dst)
	{
		case 0:     // Long-Word Integer
		{
			INT32 d = (INT32)floatx80_to_int32(REG_FP(m68k)[src]);
			WRITE_EA_32(m68k, ea, d);
			break;
		}
		case 1:     // Single-precision Real
		{
			UINT32 d = floatx80_to_float32(REG_FP(m68k)[src]);
			WRITE_EA_32(m68k, ea, d);
			break;
		}
		case 2:     // Extended-precision Real
		{
			WRITE_EA_FPE(m68k, ea, REG_FP(m68k)[src]);
			break;
		}
		case 3:     // Packed-decimal Real with Static K-factor
		{
			// sign-extend k
			k = (k & 0x40) ? (k | 0xffffff80) : (k & 0x7f);
			WRITE_EA_PACK(m68k, ea, k, REG_FP(m68k)[src]);
			break;
		}
		case 4:     // Word Integer
		{
			int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
			if (value > 0x7fff || value < -0x8000 )
			{
				REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
			}
			WRITE_EA_16(m68k, ea, (INT16)value);
			break;
		}
		case 5:     // Double-precision Real
		{
			UINT64 d;

			d = floatx80_to_float64(REG_FP(m68k)[src]);

			WRITE_EA_64(m68k, ea, d);
			break;
		}
		case 6:     // Byte Integer
		{
			int32 value = floatx80_to_int32(REG_FP(m68k)[src]);
			if (value > 127 || value < -128)
			{
				REG_FPSR(m68k) |= FPES_OE | FPAE_IOP;
			}
			WRITE_EA_8(m68k, ea, (INT8) value);
			break;
		}
		case 7:     // Packed-decimal Real with Dynamic K-factor
		{
			WRITE_EA_PACK(m68k, ea, REG_D(m68k)[k>>4], REG_FP(m68k)[src]);
			break;
		}
	}

	m68k->remaining_cycles -= 12;
}