⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arm9rutinasarm.cpp

📁 ARM9Core v0.4, 在x86 Win32 下模拟仿真ARM9 微处理器的Library.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*
    ARM9Core
    Copyright (C) 2007 Alberto Huerta Aranda,
	Sergio Hidalgo Serrano, Daniel Sa駏do Vacas

    This library is free software; you can redistribute it and/or
	modify it under the terms of the GNU Lesser General Public
	License as published by the Free Software Foundation; either
	version 3 of the License, or (at your option) any later version.

	This library is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
	Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
	License along with this library. If not, see <http://www.gnu.org/licenses/>

*/


/**************************************************************************************

  Archivo: ARM9RutinasARM.cpp

  Descripcion: Codigo de las rutinas del modo ARM

**************************************************************************************/

#include "ARM9RutinasARM.h"
#include "ARM9Core.h"
#include <stdio.h>

ARM9RutinasARM::ARM9RutinasARM () {

	tablaGenerada = 0;

	int aux[] = {0x0F0F, 0xF0F0, 0x3333, 0xCCCC, 0x00FF, 0xFF00,
				0x5555, 0xAAAA, 0x3030, 0xCFCF, 0xAA55, 0x55AA,
				0xA050, 0x5FAF, 0xFFFF, 0xFFFF};


	//Genera la tabla precalculada de condiciones
	for (int i = 0; i < 16; i++) {

		tablaCond[i][0] = (aux[i] & 0x8000) != 0;
		tablaCond[i][1] = (aux[i] & 0x4000) != 0;
		tablaCond[i][2] = (aux[i] & 0x2000) != 0;
		tablaCond[i][3] = (aux[i] & 0x1000) != 0;

		tablaCond[i][4] = (aux[i] & 0x0800) != 0;
		tablaCond[i][5] = (aux[i] & 0x0400) != 0;
		tablaCond[i][6] = (aux[i] & 0x0200) != 0;
		tablaCond[i][7] = (aux[i] & 0x0100) != 0;

		tablaCond[i][8] = (aux[i] & 0x0080) != 0;
		tablaCond[i][9] = (aux[i] & 0x0040) != 0;
		tablaCond[i][10] = (aux[i] & 0x0020) != 0;
		tablaCond[i][11] = (aux[i] & 0x0010) != 0;

		tablaCond[i][12] = (aux[i] & 0x0008) != 0;
		tablaCond[i][13] = (aux[i] & 0x0004) != 0;
		tablaCond[i][14] = (aux[i] & 0x0002) != 0;
		tablaCond[i][15] = (aux[i] & 0x0001) != 0;
		
	}

}


int ARM9RutinasARM::run (ARM9Core *core, ARM9Contexto *contexto, int nCiclos) {

	ARM9Instruccion32 instruccion;
	void *dir;

	this->core = core;
	this->contexto = contexto;

	int rn, rd, rs, rm, rot, operando1, operando2, acumulador, acumulador2, resultado;
	int signo1, signo2;
	int shift, tipoShift;
	int l, s, c, shifterCarryOut, a, v, esDPI, esLSRO, dirOffset;
	uint32 dirEfectiva, dirEfectiva2;
	int u, b, w, i, j, esSignedHalfword, listaRegistros, lsmUserMode, lsmCPSR;
	int resultado2, esMISR, r, mascara;
	int64 var1_64, var2_64; uint64 uvar1_64, uvar2_64;

/*-------------------------------------------------------------------------*/
/*  Tabla de saltos
/*-------------------------------------------------------------------------*/
#include "ARM9TablaARM.h"

/*-------------------------------------------------------------------------*/
/*  Lectura de la siguiente instrucci髇
/*-------------------------------------------------------------------------*/

LecturaInstruccion:

	//Antes de leer, comprobamos el numero de ciclos restantes
	if ((nCiclos <= 0) || (core->getExcepcionActiva() != EXCEP_NONE))
		return nCiclos;

	//Lee la siguiente instruccion
	instruccion.u_word = core->readInstruccion (contexto->PC->u_word);
	contexto->PC->u_word += 0x4; //+4 bytes

	if (core->getExcepcionActiva() != EXCEP_NONE)
		return nCiclos;

	//Obtenemos la direccion de la subrutina a partir del codigo de la
	//tabla de saltos (bits 27-20)
	dir = tablaSaltos[instruccion.comunes.codigoTabla][instruccion.comunes.codigoTabla2];
	
	//Salta a la subrutina
	__asm jmp dir	
	


/*-------------------------------------------------------------------------*/
/*	Rutina ADD (DP)
/*-------------------------------------------------------------------------*/
RUT_add:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}
	
	//ADD	
	__asm {
		add		eax, ebx		;suma
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina ADC (DP)
/*-------------------------------------------------------------------------*/
RUT_adc:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	c = contexto->flags.c;

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}
	
	//ADC
	__asm {
		add		eax, ebx		;suma
		add		eax, c
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina SUB (DP)
/*-------------------------------------------------------------------------*/
RUT_sub:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}

	//SUB	
	__asm {
		mov		operando2, ebx	;preserva para el flag de carry
		neg		ebx
		add		eax, ebx		;resta
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	signo2 = signo2 ^ 0x80000000;
	GETFLAGS_SUB

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina SBC (DP)
/*-------------------------------------------------------------------------*/
RUT_sbc:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	c = contexto->flags.c;

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}
	
	//SBC
	__asm {
		add		eax, c
		sub		eax, 1
		mov		operando1, eax	;preserva para el flag de carry
		mov		operando2, ebx
		neg		ebx
		add		eax, ebx		;resta
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	signo2 = signo2 ^ 0x80000000;
	GETFLAGS_SUB

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina RSB (DP)
/*-------------------------------------------------------------------------*/
RUT_rsb:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}

	//RSB	
	__asm {
		mov		operando1, ebx	;preserva para el flag de carry
		mov		operando2, eax
		neg		eax
		add		ebx, eax		;resta
		pushf					;guarda los flags en la pila
		mov		resultado, ebx	;guarda el resultado
	}

	//Guarda los flags
	signo1 = signo1 ^ 0x80000000;
	GETFLAGS_SUB

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;




/*-------------------------------------------------------------------------*/
/*	Rutina RSC (DP)
/*-------------------------------------------------------------------------*/
RUT_rsc:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	c = contexto->flags.c;

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT
	}
	
	//RSC
	__asm {
		add		ebx, c
		sub		ebx, 1
		mov		operando2, eax	;preserva para el flag de carry
		mov		operando1, ebx
		neg		eax
		add		ebx, eax		;resta
		pushf					;guarda los flags en la pila
		mov		resultado, ebx	;guarda el resultado
	}

	//Guarda los flags
	signo1 = signo1 ^ 0x80000000;
	GETFLAGS_SUB

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina MOV (DP)
/*-------------------------------------------------------------------------*/
RUT_mov:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//MOV	
	__asm {
		or		ebx, 0			;OR 0 para obtener los flags (el x86 no lo hace con move)
		pushf					;guarda los flags en la pila
		mov		resultado, ebx	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina MVN (DP)
/*-------------------------------------------------------------------------*/
RUT_mvn:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//MVN	
	__asm {
		mov		eax, 0FFFFFFFFh
		xor		eax, ebx		;XOR con eax para obtener los flags (el x86 no lo hace con move)
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina AND (DP)
/*-------------------------------------------------------------------------*/
RUT_and:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//AND	
	__asm {
		and		eax, ebx		;and
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina EOR (DP)
/*-------------------------------------------------------------------------*/
RUT_eor:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}
	
	//EOR	
	__asm {
		xor		eax, ebx		;or exclusiva
		pushf					;guarda los flags en la pila
		mov		resultado, eax	;guarda el resultado
	}

	//Guarda los flags
	GETFLAGS_SHIFTER

	contexto->bancoRegistros[rd].u_word = resultado;

	nCiclos--;
	goto LecturaInstruccion;


/*-------------------------------------------------------------------------*/
/*	Rutina ORR (DP)
/*-------------------------------------------------------------------------*/
RUT_orr:

	//Comprueba el codigo de condicion
	COMPROBAR_COND

	//Obtiene los operandos
	GETOPS_DP

	if (esDPI) {
		//Rota (expande) el operando inmediato
		ROTATE_DPI
	}else{
		//Desplaza el operando 2
		SHIFT_CARRY
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -