예제 #1
0
파일: arm.c 프로젝트: netux79/mame2003Wii
unsigned arm_dasm(char *buffer, unsigned int pc)
{
#ifdef MAME_DEBUG
	arm_disasm( buffer, pc, cpu_read32(pc&ADDRESS_MASK) );
	return 4;
#else
	sprintf(buffer, "$%08x", READ32(pc));
	return 4;
#endif
}
예제 #2
0
파일: arm.c 프로젝트: crazii/mameplus
void arm_cpu_device::HandleMemSingle( UINT32 insn )
{
	UINT32 rn, rnv, off, rd;

	/* Fetch the offset */
	if (insn & INSN_I)
	{
		off = decodeShift(insn, NULL);
	}
	else
	{
		off = insn & INSN_SDT_IMM;
	}

	/* Calculate Rn, accounting for PC */
	rn = (insn & INSN_RN) >> INSN_RN_SHIFT;

//  if (rn==0xf) logerror("%08x:  Source R15\n",R15);

	if (insn & INSN_SDT_P)
	{
		/* Pre-indexed addressing */
		if (insn & INSN_SDT_U)
		{
			if (rn != eR15)
				rnv = (GetRegister(rn) + off);
			else
				rnv = (R15 & ADDRESS_MASK) + off;
		}
		else
		{
			if (rn != eR15)
				rnv = (GetRegister(rn) - off);
			else
				rnv = (R15 & ADDRESS_MASK) - off;
		}

		if (insn & INSN_SDT_W)
		{
			SetRegister(rn,rnv);
			if (ARM_DEBUG_CORE && rn == eR15)
				logerror("writeback R15 %08x\n", R15);
		}
		else if (rn == eR15)
		{
			rnv = rnv + 8;
		}
	}
	else
	{
		/* Post-indexed addressing */
		if (rn == eR15)
		{
			rnv = (R15 & ADDRESS_MASK) + 8;
		}
		else
		{
			rnv = GetRegister(rn);
		}
	}

	/* Do the transfer */
	rd = (insn & INSN_RD) >> INSN_RD_SHIFT;
	if (insn & INSN_SDT_L)
	{
		/* Load */
		m_icount -= S_CYCLE + I_CYCLE + N_CYCLE;
		if (insn & INSN_SDT_B)
		{
			if (ARM_DEBUG_CORE && rd == eR15)
				logerror("read byte R15 %08x\n", R15);
			SetRegister(rd,(UINT32) cpu_read8(rnv) );
		}
		else
		{
			if (rd == eR15)
			{
				R15 = (cpu_read32(rnv) & ADDRESS_MASK) | (R15 & PSR_MASK) | (R15 & MODE_MASK);

				/*
				The docs are explicit in that the bottom bits should be masked off
				when writing to R15 in this way, however World Cup Volleyball 95 has
				an example of an unaligned jump (bottom bits = 2) where execution
				should definitely continue from the rounded up address.

				In other cases, 4 is subracted from R15 here to account for pipelining.
				*/
				if ((cpu_read32(rnv)&3)==0)
					R15 -= 4;

				m_icount -= S_CYCLE + N_CYCLE;
			}
			else
			{
				SetRegister(rd, cpu_read32(rnv));
			}
		}
	}
	else
	{
		/* Store */
		m_icount -= 2 * N_CYCLE;
		if (insn & INSN_SDT_B)
		{
			if (ARM_DEBUG_CORE && rd==eR15)
				logerror("Wrote R15 in byte mode\n");

			cpu_write8(rnv, (UINT8) GetRegister(rd) & 0xffu);
		}
		else
		{
			if (ARM_DEBUG_CORE && rd==eR15)
				logerror("Wrote R15 in 32bit mode\n");

			cpu_write32(rnv, rd == eR15 ? R15 + 8 : GetRegister(rd));
		}
	}

	/* Do post-indexing writeback */
	if (!(insn & INSN_SDT_P)/* && (insn&INSN_SDT_W)*/)
	{
		if (insn & INSN_SDT_U)
		{
			/* Writeback is applied in pipeline, before value is read from mem,
			    so writeback is effectively ignored */
			if (rd==rn)
			{
				SetRegister(rn,GetRegister(rd));
			}
			else
			{
				if ((insn&INSN_SDT_W)!=0)
				logerror("%08x:  RegisterWritebackIncrement %d %d %d\n",R15,(insn & INSN_SDT_P)!=0,(insn&INSN_SDT_W)!=0,(insn & INSN_SDT_U)!=0);

				SetRegister(rn,(rnv + off));
			}
		}
		else
		{
			/* Writeback is applied in pipeline, before value is read from mem,
			    so writeback is effectively ignored */
			if (rd==rn)
			{
				SetRegister(rn,GetRegister(rd));
			}
			else
			{
				SetRegister(rn,(rnv - off));

				if ((insn&INSN_SDT_W)!=0)
				logerror("%08x:  RegisterWritebackDecrement %d %d %d\n",R15,(insn & INSN_SDT_P)!=0,(insn&INSN_SDT_W)!=0,(insn & INSN_SDT_U)!=0);
			}
		}
	}
} /* HandleMemSingle */
예제 #3
0
파일: arm.c 프로젝트: hoglet67/PiTubeDirect
void arm2_execute_run(int tube_cycles)
{
#ifdef TRACE
  int i;
#endif
  UINT32 pc;
  UINT32 insn;
  //int m_icount = number;

  do
  {
    //debugger_instruction_hook(this, R15 & ADDRESS_MASK);

    /* load instruction */
    pc = R15;
#ifdef INCLUDE_DEBUGGER
      if (arm2_debug_enabled)
      {
         debug_preexec(&arm2_cpu_debug, pc & ADDRESS_MASK);
      }
#endif
    insn = cpu_read32( pc & ADDRESS_MASK );

#ifdef TRACE
    if ((pc & ADDRESS_MASK) == 0xa060)
    {
      m_trace = 1;
    }
    if (m_trace)
    {
      printf("%08X %08X ", pc, insn);
      for (i = eR0; i <= eR7; i++)
      {
        printf("%08X ", m_sArmRegister[i]);
      }
      if(darm_armv7_disasm(&d, insn) == 0 && darm_str2(&d, &str, 0) == 0)
      {
        printf("%s\r\n", str.total);
      }
      else
      {
        printf("***\r\n");
      }
    }
    if ((pc & ADDRESS_MASK) == 0xa0c0)
    {
      m_trace = 0;
    }
    if ((pc & ADDRESS_MASK) == 0xa2ac)
    {
      m_trace = 0;
    }
    if ((insn & 0x0D900000) == 0x01000000)
    {
      printf("S bit not set in %08x at %08x\r\n", insn, pc & ADDRESS_MASK);
      insn |= INSN_S;
    }
#endif
    switch (insn >> INSN_COND_SHIFT)
    {
      case COND_EQ:
      if (Z_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_NE:
      if (Z_IS_SET(pc)) goto L_Next;
      break;
      case COND_CS:
      if (C_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_CC:
      if (C_IS_SET(pc)) goto L_Next;
      break;
      case COND_MI:
      if (N_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_PL:
      if (N_IS_SET(pc)) goto L_Next;
      break;
      case COND_VS:
      if (V_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_VC:
      if (V_IS_SET(pc)) goto L_Next;
      break;
      case COND_HI:
      if (C_IS_CLEAR(pc) || Z_IS_SET(pc)) goto L_Next;
      break;
      case COND_LS:
      if (C_IS_SET(pc) && Z_IS_CLEAR(pc)) goto L_Next;
      break;
      case COND_GE:
      if (!(pc & N_MASK) != !(pc & V_MASK)) goto L_Next; /* Use x ^ (x >> ...) method */
      break;
      case COND_LT:
      if (!(pc & N_MASK) == !(pc & V_MASK)) goto L_Next;
      break;
      case COND_GT:
      if (Z_IS_SET(pc) || (!(pc & N_MASK) != !(pc & V_MASK))) goto L_Next;
      break;
      case COND_LE:
      if (Z_IS_CLEAR(pc) && (!(pc & N_MASK) == !(pc & V_MASK))) goto L_Next;
      break;
      case COND_NV:
      goto L_Next;
    }
    /* Condition satisfied, so decode the instruction */
    if ((insn & 0x0fc000f0u) == 0x00000090u) /* Multiplication */
    {
      HandleMul(insn);
      R15 += 4;
    }
    else if (!(insn & 0x0c000000u)) /* Data processing */
    {
      HandleALU(insn);
    }
    else if ((insn & 0x0c000000u) == 0x04000000u) /* Single data access */
    {
      HandleMemSingle(insn);
      R15 += 4;
    }
    else if ((insn & 0x0e000000u) == 0x08000000u ) /* Block data access */
    {
      HandleMemBlock(insn);
      R15 += 4;
    }
    else if ((insn & 0x0e000000u) == 0x0a000000u) /* Branch */
    {
      HandleBranch(insn);
    }
    else if ((insn & 0x0f000000u) == 0x0e000000u) /* Coprocessor */
    {
      if (m_copro_type == ARM_COPRO_TYPE_VL86C020)
      HandleCoProVL86C020(insn);
      else
      HandleCoPro(insn);

      R15 += 4;
    }
    else if ((insn & 0x0f000000u) == 0x0f000000u) /* Software interrupt */
    {
      pc=R15+4;
      R15 = eARM_MODE_SVC; /* Set SVC mode so PC is saved to correct R14 bank */
      SetRegister( 14, pc ); /* save PC */
      R15 = (pc&PSR_MASK)|(pc&IRQ_MASK)|0x8|eARM_MODE_SVC|I_MASK|(pc&MODE_MASK);
      CYCLE_COUNT(2 * S_CYCLE + N_CYCLE);
    }
    else /* Undefined */
    {
      logerror("%08x:  Undefined instruction\n",R15);
      L_Next:
      CYCLE_COUNT(S_CYCLE);
      R15 += 4;
    }

    //arm2_check_irq_state();

    tubeUseCycles(1); 
    } while (tubeContinueRunning());
  //while( m_icount > 0 );
  //while (number--);
} /* arm_execute */