コード例 #1
0
static void fmovem(UINT16 w2)
{
	int i;
	int ea = REG_IR & 0x3f;
	int dir = (w2 >> 13) & 0x1;
	int mode = (w2 >> 11) & 0x3;
	int reglist = w2 & 0xff;

	if (dir)	// From FP regs to mem
	{
		switch (mode)
		{
			case 0:		// Static register list, predecrement addressing mode
			{
				for (i=0; i < 8; i++)
				{
					if (reglist & (1 << i))
					{
						WRITE_EA_FPE(ea, REG_FP[i]);
						USE_CYCLES(2);
					}
				}
				break;
			}

			default:	fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
		}
	}
	else		// From mem to FP regs
	{
		switch (mode)
		{
			case 2:		// Static register list, postincrement addressing mode
			{
				for (i=0; i < 8; i++)
				{
					if (reglist & (1 << i))
					{
						REG_FP[7-i] = READ_EA_FPE(ea);
						USE_CYCLES(2);
					}
				}
				break;
			}

			default:	fatalerror("040fpu0: FMOVEM: mode %d unimplemented at %08X\n", mode, REG_PC-4);
		}
	}
}
コード例 #2
0
static void fmove_fpcr(UINT16 w2)
{
	int ea = REG_IR & 0x3f;
	int dir = (w2 >> 13) & 0x1;
	int reg = (w2 >> 10) & 0x7;

	if (dir)	// From system control reg to <ea>
	{
		switch (reg)
		{
			case 1:		WRITE_EA_32(ea, REG_FPIAR); break;
			case 2:		WRITE_EA_32(ea, REG_FPSR); break;
			case 4:		WRITE_EA_32(ea, REG_FPCR); break;
			default:	fatalerror("fmove_fpcr: unknown reg %d, dir %d\n", reg, dir);
		}
	}
	else		// From <ea> to system control reg
	{
		switch (reg)
		{
			case 1:		REG_FPIAR = READ_EA_32(ea); break;
			case 2:		REG_FPSR = READ_EA_32(ea); break;
			case 4:		REG_FPCR = READ_EA_32(ea); break;
			default:	fatalerror("fmove_fpcr: unknown reg %d, dir %d\n", reg, dir);
		}
	}

	USE_CYCLES(10);
}
コード例 #3
0
static void fmove_reg_mem(UINT16 w2)
{
	int ea = REG_IR & 0x3f;
	int src = (w2 >>  7) & 0x7;
	int dst = (w2 >> 10) & 0x7;
	//int kfactor = w2 & 0x7f;

	switch (dst)
	{
		case 0:		// Long-Word Integer
		{
			INT32 d = (INT32)(REG_FP[src].f);
			WRITE_EA_32(ea, d);
			break;
		}
		case 1:		// Single-precision Real
		{
			float f = (float)(REG_FP[src].f);
			UINT32 d = *(UINT32 *)&f;
			WRITE_EA_32(ea, d);
			break;
		}
		case 2:		// Extended-precision Real
		{
			fatalerror("fmove_reg_mem: extended-precision real store unimplemented at %08X\n", REG_PC-4);
			break;
		}
		case 3:		// Packed-decimal Real with Static K-factor
		{
			fatalerror("fmove_reg_mem: packed-decimal real store unimplemented at %08X\n", REG_PC-4);
			break;
		}
		case 4:		// Word Integer
		{
			fatalerror("fmove_reg_mem: word integer store unimplemented at %08X\n", REG_PC-4);
			break;
		}
		case 5:		// Double-precision Real
		{
			UINT64 d = REG_FP[src].i;
			WRITE_EA_64(ea, d);
			break;
		}
		case 6:		// Byte Integer
		{
			fatalerror("fmove_reg_mem: byte integer store unimplemented at %08X\n", REG_PC-4);
			break;
		}
		case 7:		// Packed-decimal Real with Dynamic K-factor
		{
			fatalerror("fmove_reg_mem: packed-decimal real store unimplemented at %08X\n", REG_PC-4);
			break;
		}
	}

	USE_CYCLES(12);
}
コード例 #4
0
static void fbcc(void)
{
	INT32 disp;
//  int condition = REG_IR & 0x3f;
	int size = (REG_IR >> 6) & 0x1;

	if (size)	// 32-bit displacement
	{
		disp = OPER_I_32();
	}
	else
	{
		disp = (INT16)(OPER_I_16());
	}

	// TODO: condition and jump!!!

	USE_CYCLES(7);
}
コード例 #5
0
int m68k_execute(int num_cycles)
{
	if (regs.stopped)
	{
		regs.remainingCycles = 0;	// int32_t
		regs.interruptCycles = 0;	// uint32_t

		return num_cycles;
	}

#if 0
	/* Set our pool of clock cycles available */
	SET_CYCLES(num_cycles);
	m68ki_initial_cycles = num_cycles;

	/* ASG: update cycles */
	USE_CYCLES(CPU_INT_CYCLES);
	CPU_INT_CYCLES = 0;

	/* Return point if we had an address error */
	m68ki_set_address_error_trap(); /* auto-disable (see m68kcpu.h) */
#else
	regs.remainingCycles = num_cycles;
	/*int32_t*/ initialCycles = num_cycles;
	
	regs.remainingCycles -= regs.interruptCycles;
	regs.interruptCycles = 0;
#endif

	/* Main loop.  Keep going until we run out of clock cycles */
	do
	{
		// This is so our debugging code can break in on a dime.
		// Otherwise, this is just extra slow down :-P
		if (regs.spcflags & SPCFLAG_DEBUGGER)
		{
			// Not sure this is correct... :-P
			num_cycles = initialCycles - regs.remainingCycles;
			regs.remainingCycles = 0;	// int32_t
			regs.interruptCycles = 0;	// uint32_t

			return num_cycles;
		}
#if 0
		/* Set tracing accodring to T1. (T0 is done inside instruction) */
		m68ki_trace_t1(); /* auto-disable (see m68kcpu.h) */

		/* Set the address space for reads */
		m68ki_use_data_space(); /* auto-disable (see m68kcpu.h) */

		/* Call external hook to peek at CPU */
		m68ki_instr_hook(); /* auto-disable (see m68kcpu.h) */

		/* Record previous program counter */
		REG_PPC = REG_PC;

		/* Read an instruction and call its handler */
		REG_IR = m68ki_read_imm_16();
		m68ki_instruction_jump_table[REG_IR]();
		USE_CYCLES(CYC_INSTRUCTION[REG_IR]);

		/* Trace m68k_exception, if necessary */
		m68ki_exception_if_trace(); /* auto-disable (see m68kcpu.h) */
#else
//Testing Hover Strike...
#if 0
//Dasm(regs.pc, 1);
static int hitCount = 0;
static int inRoutine = 0;
static int instSeen;

//if (regs.pc == 0x80340A)
if (regs.pc == 0x803416)
{
	hitCount++;
	inRoutine = 1;
	instSeen = 0;
	printf("%i: $80340A start. A0=%08X, A1=%08X ", hitCount, regs.regs[8], regs.regs[9]);
}
else if (regs.pc == 0x803422)
{
	inRoutine = 0;
	printf("(%i instructions)\n", instSeen);
}

if (inRoutine)
	instSeen++;
#endif
// AvP testing... (problem was: 32 bit addresses on 24 bit address cpu--FIXED)
#if 0
	static int go = 0;

	if (regs.pc == 0x94BA)
	{
		go = 1;
		printf("\n");
	}

	if (regs.pc == 0x94C6)
		go = 0;

//	if (regs.regs[10] == 0xFFFFFFFF && go)
	if (go)
	{
//		printf("A2=-1, PC=%08X\n", regs.pc);
//		go = 0;
//		Dasm(regs.pc, 130);
		Dasm(regs.pc, 1);
		DumpRegisters();
	}
//94BA: 2468 0000                MOVEA.L	(A0,$0000) == $0002328A, A2
//94BE: 200A                     MOVE.L	A2, D0
//94C0: 6A02                     BPL.B	$94C4
//94C2: 2452                     MOVEA.L	(A2), A2			; <--- HERE
//94C4: 4283                     CLR.L	D3
#endif
//		pthread_mutex_lock(&executionLock);
		if (checkForIRQToHandle)
		{
			checkForIRQToHandle = 0;
			m68k_set_irq2(IRQLevelToHandle);
		}

#ifdef M68K_HOOK_FUNCTION
		M68KInstructionHook();
#endif
		uint32_t opcode = get_iword(0);
//if ((opcode & 0xFFF8) == 0x31C0)
//{
//	printf("MOVE.W D%i, EA\n", opcode & 0x07);
//}
		int32_t cycles = (int32_t)(*cpuFunctionTable[opcode])(opcode);
		regs.remainingCycles -= cycles;
//		pthread_mutex_unlock(&executionLock);

//printf("Executed opcode $%04X (%i cycles)...\n", opcode, cycles);
#endif
	}
	while (regs.remainingCycles > 0);

#if 0
	/* set previous PC to current PC for the next entry into the loop */
	REG_PPC = REG_PC;

	/* ASG: update cycles */
	USE_CYCLES(CPU_INT_CYCLES);
	CPU_INT_CYCLES = 0;

	/* return how many clocks we used */
	return m68ki_initial_cycles - GET_CYCLES();
#else
	regs.remainingCycles -= regs.interruptCycles;
	regs.interruptCycles = 0;

	// Return # of clock cycles used
	return initialCycles - regs.remainingCycles;
#endif
}
コード例 #6
0
static void fpgen_rm_reg(UINT16 w2)
{
	int ea = REG_IR & 0x3f;
	int rm = (w2 >> 14) & 0x1;
	int src = (w2 >> 10) & 0x7;
	int dst = (w2 >>  7) & 0x7;
	int opmode = w2 & 0x7f;
	double source;

	if (rm)
	{
		switch (src)
		{
			case 0:		// Long-Word Integer
			{
				INT32 d = READ_EA_32(ea);
				source = (double)(d);
				break;
			}
			case 1:		// Single-precision Real
			{
				UINT32 d = READ_EA_32(ea);
				source = (double)(*(float*)&d);
				break;
			}
			case 2:		// Extended-precision Real
			{
				fatalerror("fpgen_rm_reg: extended-precision real load unimplemented at %08X\n", REG_PC-4);
				break;
			}
			case 3:		// Packed-decimal Real
			{
				fatalerror("fpgen_rm_reg: packed-decimal real load unimplemented at %08X\n", REG_PC-4);
				break;
			}
			case 4:		// Word Integer
			{
				INT16 d = READ_EA_16(ea);
				source = (double)(d);
				break;
			}
			case 5:		// Double-precision Real
			{
				UINT64 d = READ_EA_64(ea);
				source = *(double*)&d;
				break;
			}
			case 6:		// Byte Integer
			{
				INT8 d = READ_EA_8(ea);
				source = (double)(d);
				break;
			}
			default:	fatalerror("fmove_rm_reg: invalid source specifier at %08X\n", REG_PC-4);
		}
	}
	else
	{
		source = REG_FP[src].f;
	}

	switch (opmode)
	{
		case 0x00:		// FMOVE
		{
			REG_FP[dst].f = source;
			USE_CYCLES(4);
			break;
		}
		case 0x04:		// FSQRT
		{
			REG_FP[dst].f = sqrt(source);
			// TODO: condition codes
			USE_CYCLES(109);
			break;
		}
		case 0x18:		// FABS
		{
			REG_FP[dst].f = fabs(source);
			// TODO: condition codes
			USE_CYCLES(3);
			break;
		}
		case 0x1a:		// FNEG
		{
			REG_FP[dst].f = -source;
			// TODO: condition codes
			USE_CYCLES(3);
			break;
		}
		case 0x20:		// FDIV
		{
			REG_FP[dst].f /= source;
			USE_CYCLES(43);
			break;
		}
		case 0x22:		// FADD
		{
			REG_FP[dst].f += source;
			// TODO: condition codes
			USE_CYCLES(9);
			break;
		}
		case 0x23:		// FMUL
		{
			REG_FP[dst].f *= source;
			// TODO: condition codes
			USE_CYCLES(11);
			break;
		}
		case 0x28:		// FSUB
		{
			REG_FP[dst].f -= source;
			// TODO: condition codes
			USE_CYCLES(9);
			break;
		}
		case 0x38:		// FCMP
		{
			// TODO: condition codes !!!
			USE_CYCLES(7);
			break;
		}
		case 0x3a:		// FTST
		{
			// TODO: condition codes !!!
			USE_CYCLES(7);
			break;
		}

		default:	fatalerror("fpgen_rm_reg: unimplemented opmode %02X at %08X\n", opmode, REG_PC-4);
	}
}