Esempio n. 1
0
/**
 * This is called after completion of each VDI call
 */
unsigned long OpCode_VDI(uae_u32 opcode)
{
	Uint32 pc = M68000_GetPC();

	/* this is valid only after VDI trap, called from cartridge code */
	if (VDI_OldPC && pc >= 0xfa0000 && pc < 0xfc0000)
	{
		VDI_Complete();

		/* Set PC back to where originated from to continue instruction decoding */
		m68k_setpc(VDI_OldPC);
		VDI_OldPC = 0;
	}
	else
	{
		/* illegal instruction */
		op_illg(opcode);
	}

	get_word_prefetch (0);
	regs.ir = regs.irc;
	get_word_prefetch(2);

	return 4 * CYCLE_UNIT / 2;
}
Esempio n. 2
0
File: fpp.c Progetto: bernds/UAE
static void fpu_op_illg (uae_u32 opcode, int pcoffset)
{
    if ((currprefs.cpu_model == 68060 && (currprefs.fpu_model == 0 || (regs.pcr & 2)))
	|| (currprefs.cpu_model == 68040 && currprefs.fpu_model == 0)) {
	/* 68040 unimplemented/68060 FPU disabled exception.
	 * Line F exception with different stack frame.. */
	uaecptr newpc = m68k_getpc ();
	uaecptr oldpc = newpc - pcoffset;
	MakeSR ();
	if (!regs.s) {
	    regs.usp = m68k_areg (regs, 7);
	    m68k_areg (regs, 7) = regs.isp;
	}
	regs.s = 1;
	m68k_areg (regs, 7) -= 4;
	put_long (m68k_areg (regs, 7), oldpc);
	m68k_areg (regs, 7) -= 4;
	put_long (m68k_areg (regs, 7), oldpc);
	m68k_areg (regs, 7) -= 2;
	put_word (m68k_areg (regs, 7), 0x4000 + 11 * 4);
	m68k_areg (regs, 7) -= 4;
	put_long (m68k_areg (regs, 7), newpc);
	m68k_areg (regs, 7) -= 2;
	put_word (m68k_areg (regs, 7), regs.sr);
	write_log ("68040/060 FPU disabled exception PC=%x\n", newpc);
	newpc = get_long (regs.vbr + 11 * 4);
	m68k_setpc (newpc);
	return;
    }
    op_illg (opcode);
}
Esempio n. 3
0
void comp_fpp_opp (uae_u32 opcode, uae_u16 extra)
{
    int reg;
    int sreg, prec = 0;
    int	dreg = (extra >> 7) & 7;
    int source = (extra >> 13) & 7;
    int	opmode = extra & 0x7f;

    if (!currprefs.compfpu) {
		FAIL(1);
		return;
    }
    switch (source) {
	case 3: /* FMOVE FPx, <EA> */
		if (comp_fp_put(opcode,extra) < 0)
	    FAIL(1);
		return;
	case 4: /* FMOVE.L  <EA>, ControlReg */
		if (!(opcode & 0x30)) { /* Dn or An */
			if (extra & 0x1000) { /* FPCR */
		    	mov_l_mr((uae_u32)&regs.fpcr,opcode & 15);
#if USE_X86_FPUCW
		    	mov_l_rr(S1,opcode & 15);
		    	and_l_ri(S1,0xf0);
		    	fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
#endif
				return;
			}
			if (extra & 0x0800) { /* FPSR */
				FAIL(1);
				return;
				// set_fpsr(m68k_dreg (regs, opcode & 15));
			}
			if (extra & 0x0400) { /* FPIAR */
				mov_l_mr((uae_u32)&regs.fpiar,opcode & 15); return;
			}
	}
	else if ((opcode & 0x3f) == 0x3c) {
			if (extra & 0x1000) { /* FPCR */
		    	uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4);
		    	mov_l_mi((uae_u32)&regs.fpcr,val);
#if USE_X86_FPUCW
		    	mov_l_ri(S1,val&0xf0);
		    	fldcw_m_indexed(S1,(uae_u32)x86_fpucw);
#endif
				return;
			}
			if (extra & 0x0800) { /* FPSR */
			    FAIL(1);
			    return;
			}
			if (extra & 0x0400) { /* FPIAR */
				uae_u32 val=comp_get_ilong((m68k_pc_offset+=4)-4);
				mov_l_mi((uae_u32)&regs.fpiar,val);
				return;
			}
		}
		FAIL(1);
		return;
	case 5: /* FMOVE.L  ControlReg, <EA> */
		if (!(opcode & 0x30)) { /* Dn or An */
			if (extra & 0x1000) { /* FPCR */
				mov_l_rm(opcode & 15,(uae_u32)&regs.fpcr); return;
			}
			if (extra & 0x0800) { /* FPSR */
				FAIL(1);
				return;
			}
			if (extra & 0x0400) { /* FPIAR */
				mov_l_rm(opcode & 15,(uae_u32)&regs.fpiar); return;
			}
		}
		FAIL(1);
		return;
	case 6:
	case 7:
		{
	    uae_u32 list = 0;
	    int incr = 0;
	    if (extra & 0x2000) {
			uae_u32 ad;

			/* FMOVEM FPP->memory */
			switch ((extra >> 11) & 3) { /* Get out early if failure */
			case 0:
			case 2:
				break;
			case 1:
			case 3:
			default:
		    FAIL(1); return;
		}
		ad = comp_fp_adr (opcode);
		if (ad < 0) {
		    m68k_setpc (m68k_getpc () - 4);
		    op_illg (opcode);
		    return;
		}
		switch ((extra >> 11) & 3) {
		case 0:	/* static pred */
		    list = extra & 0xff;
		    incr = -1;
		    break;
		case 2:	/* static postinc */
		    list = extra & 0xff;
		    incr = 1;
		    break;
		case 1:	/* dynamic pred */
		case 3:	/* dynamic postinc */
		   abort();
		}
		if (incr < 0) { /* Predecrement */
			for (reg = 7; reg >= 0; reg--) {
				if (list & 0x80) {
					fmov_ext_mr((uintptr)temp_fp,reg);
					sub_l_ri(ad,4);
					mov_l_rm(S2,(uintptr)temp_fp);
					writelong_clobber(ad,S2,S3);
					sub_l_ri(ad,4);
					mov_l_rm(S2,(uintptr)temp_fp+4);
					writelong_clobber(ad,S2,S3);
					sub_l_ri(ad,4);
					mov_w_rm(S2,(uintptr)temp_fp+8);
					writeword_clobber(ad,S2,S3);
				}
				list <<= 1;
			}
		}
		else { /* Postincrement */
			for (reg = 0; reg <= 7; reg++) {
				if (list & 0x80) {
					fmov_ext_mr((uintptr)temp_fp,reg);
					mov_w_rm(S2,(uintptr)temp_fp+8);
					writeword_clobber(ad,S2,S3);
					add_l_ri(ad,4);
					mov_l_rm(S2,(uintptr)temp_fp+4);
					writelong_clobber(ad,S2,S3);
					add_l_ri(ad,4);
					mov_l_rm(S2,(uintptr)temp_fp);
					writelong_clobber(ad,S2,S3);
					add_l_ri(ad,4);
				}
				list <<= 1;
			}
		}
		if ((opcode & 0x38) == 0x18)
		    mov_l_rr((opcode & 7)+8,ad);
		if ((opcode & 0x38) == 0x20)
		    mov_l_rr((opcode & 7)+8,ad);
	    } else {
		/* FMOVEM memory->FPP */

		uae_u32 ad;
		switch ((extra >> 11) & 3) { /* Get out early if failure */
		case 0:
		case 2:
			break;
		case 1:
		case 3:
		default:
		    FAIL(1); return;
		}
		ad=comp_fp_adr (opcode);
		if (ad < 0) {
		    m68k_setpc (m68k_getpc () - 4);
		    op_illg (opcode);
		    return;
		}
		switch ((extra >> 11) & 3) {
		case 0:	/* static pred */
		    list = extra & 0xff;
		    incr = -1;
		    break;
		case 2:	/* static postinc */
		    list = extra & 0xff;
		    incr = 1;
		    break;
		case 1:	/* dynamic pred */
		case 3:	/* dynamic postinc */
			abort();
		}

		if (incr < 0) {
			// not reached
			for (reg = 7; reg >= 0; reg--) {
				if (list & 0x80) {
					sub_l_ri(ad,4);
					readlong(ad,S2,S3);
					mov_l_mr((uintptr)(temp_fp),S2);
					sub_l_ri(ad,4);
					readlong(ad,S2,S3);
					mov_l_mr((uintptr)(temp_fp)+4,S2);
					sub_l_ri(ad,4);
					readword(ad,S2,S3);
					mov_w_mr(((uintptr)temp_fp)+8,S2);
					fmov_ext_rm(reg,(uintptr)(temp_fp));
				}
				list <<= 1;
			}
		}
		else {
			for (reg = 0; reg <= 7; reg++) {
				if (list & 0x80) {
					readword(ad,S2,S3);
					mov_w_mr(((uintptr)temp_fp)+8,S2);
					add_l_ri(ad,4);
					readlong(ad,S2,S3);
					mov_l_mr((uintptr)(temp_fp)+4,S2);
					add_l_ri(ad,4);
					readlong(ad,S2,S3);
					mov_l_mr((uintptr)(temp_fp),S2);
					add_l_ri(ad,4);
					fmov_ext_rm(reg,(uintptr)(temp_fp));
				}
				list <<= 1;
			}
		}
		if ((opcode & 0x38) == 0x18)
		    mov_l_rr((opcode & 7)+8,ad);
		if ((opcode & 0x38) == 0x20)
		    mov_l_rr((opcode & 7)+8,ad);
	    }
	}
Esempio n. 4
0
void comp_fscc_opp (uae_u32 opcode, uae_u16 extra)
{
    uae_u32 ad;
    int cc;
    int reg;

    if (!currprefs.compfpu) {
		FAIL(1);
		return;
    }

#if DEBUG_FPP
    write_log (_T("JIT: fscc_opp at %08lx\n"), M68K_GETPC);
#endif

    if (extra & 0x20) {  /* only cc from 00 to 1f are defined */
		FAIL(1);
		return;
    }
	if ((opcode & 0x38) != 0) { /* We can only do to integer register */
		FAIL(1);
		return;
    }

    fflags_into_flags(S2);
    reg = (opcode & 7);

    mov_l_ri(S1,255);
    mov_l_ri(S4,0);
    switch (extra & 0x0f) { /* according to fpp.c, the 0x10 bit is ignored */
	case 0: break;  /* set never */
     case 1: mov_l_rr(S2,S4);
		cmov_l_rr(S4,S1,4);
	cmov_l_rr(S4,S2,10); break;
     case 2: cmov_l_rr(S4,S1,7); break;
     case 3: cmov_l_rr(S4,S1,3); break;
     case 4: mov_l_rr(S2,S4);
		cmov_l_rr(S4,S1,2);
	cmov_l_rr(S4,S2,10); break;
     case 5: mov_l_rr(S2,S4);
		cmov_l_rr(S4,S1,6);
	cmov_l_rr(S4,S2,10); break;
     case 6: cmov_l_rr(S4,S1,5); break;
     case 7: cmov_l_rr(S4,S1,11); break;
     case 8: cmov_l_rr(S4,S1,10); break;
     case 9: cmov_l_rr(S4,S1,4); break;
     case 10: cmov_l_rr(S4,S1,10); cmov_l_rr(S4,S1,7); break;
     case 11: cmov_l_rr(S4,S1,4); cmov_l_rr(S4,S1,3); break;
     case 12: cmov_l_rr(S4,S1,2); break;
     case 13: cmov_l_rr(S4,S1,6); break;
     case 14: cmov_l_rr(S4,S1,5); cmov_l_rr(S4,S1,10); break;
     case 15: mov_l_rr(S4,S1); break;
	}

    if (!(opcode & 0x38))
		mov_b_rr(reg,S4);
#if 0
    else {
	abort();
	if (!comp_fp_adr (opcode)) {
	    m68k_setpc (m68k_getpc () - 4);
	    op_illg (opcode, regs);
	}
	else
	    put_byte (ad, cc ? 0xff : 0x00);
    }
#endif
}