Exemplo n.º 1
0
def declaracionMetodo(tipo, scope):
    global current_scope
    global procs
    global func_memLocal, func_memTemp
    if scope in procs or scope in procs['global']:
        print('ERROR: Nombre de variable repetida en linea %d.' % lineNumber)
        sys.exit()
    current_scope = scope
    func_memLocal = mem.Memoria(inicioLocal)
    func_memTemp = mem.Memoria(inicioTemp)
    procs[current_scope] = [tipo, [], {}, contCuadruplos, []]
Exemplo n.º 2
0
def createMemory(methodName):
    tempGenMem = memoria.Memoria(110000)
    localGenMem = memoria.Memoria(50000)
    newMemory = {}
    dictionary = procs[methodName][2]

    for i in range(0, len(procs[methodName][4])):
        for j in range(0, procs[methodName][4][i]):
            if i < 5:
                newMemory[localGenMem.generarEspacioMemoria(
                    numToTipo[i + 1], 1)] = None
            else:
                newMemory[tempGenMem.generarEspacioMemoria(
                    numToTipo[i % 5 + 1], 1)] = None

    return newMemory
Exemplo n.º 3
0
def p_t_main(p):
    '''
    t_main : MAIN
    '''
    global procs
    scope = p[1]
    if scope in procs:
        print('ERROR: Funcion repetida en linea %d.' % lineNumber)
        sys.exit()
    global current_scope
    current_scope = scope
    global func_memLocal, func_memTemp
    func_memLocal = mem.Memoria(inicioLocal)
    func_memTemp = mem.Memoria(inicioTemp)
    procs[current_scope] = [p[1], [], {}, contCuadruplos, []]

    saltoMain = pSaltos.pop()
    cuadruplos[saltoMain][3] = contCuadruplos
Exemplo n.º 4
0
import ias_functions as ias
import arquivo as arq
import memoria as mem

#Ler um arquivo txt e passar uma lista para a classe memória
memoria_ias = mem.Memoria(arq.txt_toList())

#cria o simulador com a memória criada acima
computador = ias.process(memoria_ias)

#Executa as instruções
computador.run()

#Salva em um arquivo memoria_final.txt o estado final da memória
arq.salvar_memoria(computador)
Exemplo n.º 5
0
import memoria
import json

_memoria = memoria.Memoria()

data = _memoria.data


def sort_by_length(d):
    '''a helper function for sorting'''
    return d['length']


_sorted = sorted(data, key=sort_by_length)

for i in range(len(_sorted)):
    # print(_sorted[i]['length'])
    if _sorted[i]['length'] > 500:
        if _sorted[i]['text'] != "":
            print(_sorted[i]['text'])
    else:
        print('-', _sorted[i]['length'])

# print(json.dumps(_sorted, indent=4, sort_keys=True))
Exemplo n.º 6
0
        #go to a certain quadruple
        currentQuadruple = actualCuadruplo[3] + quadrupleOffset
    elif actualCuadruplo[0] == 'GOSUB':
        #got to first quadruple of the method
        saltosSubrutine.append(currentQuadruple + 1)
        currentQuadruple = actualCuadruplo[3] + quadrupleOffset
    elif actualCuadruplo[0] == 'ERA':
        #generate new memory for the new context
        memoryStack.append(actualMemory)
        scopeStack.append(currentScope)
        currentScope = actualCuadruplo[1]
        actualMemory = createMemory(actualCuadruplo[1])
        currentQuadruple = currentQuadruple + 1
    elif actualCuadruplo[0] == 'PARAM':
        #assign value to the directions in the new memory
        tempMemoryObject = memoria.Memoria(110000)
        localMemoryObject = memoria.Memoria(50000)
        if actualCuadruplo[1] < 60000:
            paramValue = globalMemory[actualCuadruplo[1]]
        elif actualCuadruplo[1] > 160000:
            paramValue = constantsMemory[actualCuadruplo[1]]
        else:
            prevMemory = memoryStack.pop()
            paramValue = prevMemory[actualCuadruplo[1]]
            memoryStack.append(prevMemory)

        if actualCuadruplo[1] >= 60000 and actualCuadruplo[1] < 120000:
            actualMemory[localMemoryObject.generarEspacioMemoria(
                procs[currentScope][1][actualCuadruplo[3]])] = paramValue
        else:
            actualMemory[tempMemoryObject.generarEspacioMemoria(
Exemplo n.º 7
0
#Contadores dir mem
contTemp = 0

#Contador de parametros
contParametros = []
scopeParametros = []

#Inicios memoria
inicioGlobales = 0
inicioLocal = 50000
inicioTemp = 110000
inicioCTE = 160000

#Memoria
memGlobales = mem.Memoria(inicioGlobales)
memConstantes = mem.Memoria(inicioCTE)

#Objetos memoria virtual para funciones
func_memLocal = mem.Memoria(inicioLocal)
func_memTemp = mem.Memoria(inicioTemp)


#Gramatica
def p_progam(p):
    '''
    program : t_prog ID ';' declare_vars jump_main prog_body
    '''
    cuadruplos.append(['ENDPROG', None, None, None])
    global contCuadruplos
    contCuadruplos += 1
Exemplo n.º 8
0
class Z80:
	#Registros
	B = "00"
	C = "00"
	D = "00"
	E = "00"
	H = "00"
	L = "00"
	A = "00"
	F = "00"
	SP = "0000"
	IX = "0000"
	IY = "0000"
	PC = "0000"
	IFF1 = "1"
	IFF2 = "1"
	I = "00"
	R = "00"
	# Registros auxiliares
	B_ = "00"
	C_ = "00"
	D_ = "00"
	E_ = "00"
	H_ = "00"
	L_ = "00"
	A_ = "00"
	F_ = "00"
	mem = memoria.Memoria()
	time = 0
	frec = 3580000

	# Metodo para mandar llamar a otro de los metodos del procesador mediante el nombre de la operacion a realizar
	# Si no hay operandos, se manda una cadena vacia

	@staticmethod
	def callMethod(object, name, opr):
		lista = ["JP", "JR", "CALL", "RET"]
		if (len(opr) == 0):
			if name in lista:
				flag = getattr(object, name)("")
			else:
				flag = getattr(object, name)()
			return flag
		if(name in lista):
			flag = getattr(object, name)(opr)
			return flag
		opr = opr.split(",")
		if (len(opr) == 1):
			flag = getattr(object, name)(opr[0])
			return flag
		else:
			flag = getattr(object, name)(opr[0], opr[1])
			return flag

	@staticmethod
	def hexToBin(numHex):
		return bin(int(numHex, 16))[2:].zfill(8)

	@staticmethod
	def binToHex(numBin):
		return hex(int(numBin, 2))[2:].zfill(2)

	# Funcion para cambiar las banderas, mandar indice del bit a cambiar y el valor nuevo
	@staticmethod
	def changeFlag(bitIndex, val):
		Z80.F = Z80.hexToBin(Z80.F)
		Z80.F = Z80.F[:7 - bitIndex] + val + Z80.F[7 - bitIndex + 1:]
		Z80.F = Z80.binToHex(Z80.F)

	# Funcion para obtener alguna de las banderas
	@staticmethod
	def getFlagBit(bitIndex):
		Z80.F = Z80.hexToBin(Z80.F)
		estado = int(Z80.F[7 - bitIndex])
		Z80.F = Z80.binToHex(Z80.F)
		return estado

	# Mandar en decimal el resultado para checar acarreo
	@staticmethod
	def carry(res):
		res = funciones.tobin(res,16)
		pos = res.find("1")
		res = res[pos:]

		if (len(res) > 8):
			Z80.changeFlag(0,'1')
		else:
			Z80.changeFlag(0,'0')

	# Mandar el resultado en decimal para checar si es cero
	@staticmethod
	def zero(res):
		if (int(res) == 0):
			Z80.changeFlag(6,'1')
		else:
			Z80.changeFlag(6,'0')

	# Mandar resultado en decimal para checar paridad
	@staticmethod
	def parity(res):
		res = funciones.tobin(res, 8)
		cont = res.count('1')
		if ((cont % 2) == 0):
			Z80.changeFlag(2,'1')
		else:
			Z80.changeFlag(2,'0')

	# Mandar el resultado en decimal para comprobar sobrepasamiento
	@staticmethod
	def overflow(res):
		if res in range(-128, 128):
			Z80.changeFlag(2, "0")
		else:
			Z80.changeFlag(2, "1")

	# Mandar resultado en decimal para comprobar el signo:
	@staticmethod
	def sign(res):
		if (res < 0):
			Z80.changeFlag(7, "1")
		else:
			Z80.changeFlag(7, "0")

	@staticmethod
	# Mandar ambos operandos en hexadecimal para comprobar medio acarreo y el signo de la operacion a realizar como cadena
	def halfCarry(op1, op2, o):
		op1 = str(int(op1[1], 16))
		op2 = str(int(op2[1], 16))
		res = eval(op1+o+op2)
		if res in range(0, 16):
			Z80.changeFlag(4, "0")
		else:
			Z80.changeFlag(4, "1")

	""" Metodo que se encarga de obtener el valor hexadecimal de s para las instrucciones que lo ocupan
	s puede ser n, r, (HL), (IX+d) e (IY+d)"""
	@staticmethod
	def obtenerS(op2):
		# Si se trata de un registro, se obtiene su valor
		if (len(op2) == 1):
			s = getattr(Z80, op2)
		# En caso de tratarse de la direccion apuntada por IX o IY, se obtiene su contenido
		elif (op2.find("IX+") != -1 or op2.find("IY+") != -1):
			op2 = op2.replace("(","").replace(")","").replace("H","").split("+")
			reg = getattr(Z80, op2[0])
			des = op2[1]
			s = funciones.tohex(int(reg, 16) + funciones.hextodec(des), 16)
			s = Z80.mem.obtenerContenido(s)
		# Si es la direccion que contiene HL, se obtiene su contenido
		elif (op2 == "(HL)"):
			s = Z80.mem.obtenerContenido(''.join([getattr(Z80,"H"), getattr(Z80,"L")]))
		# El ultimo caso es que sea un numero en hexadecimal
		else:
			s = op2.replace("H","")
		return s

	""" Metodo que se encarga de obtener el valor hexadecimal de ss para las instrucciones que lo ocupan
	ss puede ser BC, DE, HL, SP, IX e IY"""
	@staticmethod
	def obtenerSS(op2):
		if ((op2 == "SP") or (op2 == "IX") or (op2 == "IY")):
			ss = getattr(Z80, op2)
		else:
			ss = ''.join([getattr(Z80,op2[0]), getattr(Z80,op2[1])])
		return ss

	@staticmethod
	# Resta el contenido de A o HL con el operando 2 y con la bandera de acarreo
	def SBC(op1, op2):
		CY = getFlagBit(0)
		# Operacion de 8 bits
		if (op1 == "A"):
			s = funciones.tohex(int(Z80.obtenerS(op2),16) + int(CY,16), 8)
			Z80.halfCarry(Z80.A, s, "-")
			# Se realiza la operacion y se guarda en el acumulador
			Z80.A = int(Z80.A, 16) - int(s, 16)
			Z80.carry(Z80.A)
			Z80.zero(Z80.A)
			Z80.sign(Z80.A)
			Z80.overflow(Z80.A)
			Z80.A = funciontes.tohex(Z80.A, 8)
			Z80.changeFlag(1, "1")
		# Operacion de 16 bits
		else:
			# Se obtienen los respectivos valores
			HL = ''.join([Z80.H, Z80.L])
			ss = funciones.tohex(int(Z80.obtenerSS(op2),16)+int(CY,16), 8)
			Z80.halfCarry(HL, ss, "-")
			# Se realiza la operacion
			HL = int(HL,16) - int(ss,16)
			Z80.carry(HL)
			Z80.zero(HL)
			Z80.sign(HL)
			Z80.overflow(HL)
			HL = funciones.tohex(HL, 16)
			Z80.changeFlag(1, "1")
			# El primer byte se guarda en H y el segundo en L
			Z80.H = HL[:2]
			Z80.L = HL[2:]
		""" >>>>> N = 1, C = Z = S = H = DE ACUERDO A LA OPERACION, P/V = SOBREPASAMIENTO <<<<< """


	# Realiza operacion AND entre el acumulador (operando 1) con el operando 2
	@staticmethod
	def AND(op1, op2):
		a = getattr(Z80, op1)
		s = Z80.obtenerS(op2)
		a = list(funciones.tobin(int(a, 16), 8))
		s = list(funciones.tobin(int(s, 16), 8))
		for i in range(0, 8):
			# Si los caracteres en a y s son distintos, se cambia a 0 en el acumulador (a)
			if (a[i] != s[i]):
				a[i] = "0"
		Z80.A = int(''.join(a), 2)
		# CAMBIAR BANDERAS AQUI
		Z80.changeFlag(0, "0")
		Z80.changeFlag(1, "0")
		Z80.zero(Z80.A)
		Z80.sign(Z80.A)
		Z80.A = funciones.tohex(Z80.A, 8)
		Z80.parity(Z80.A)
		""" >>>>> C = N = 0, Z = S = H = DE ACUERDO A LA OPERACION, P/V = PARIDAD <<<<< """

	# Realiza operacion OR entre el acumulador (operando 1) con el operando 2
	@staticmethod
	def OR(op1, op2):
		a = getattr(Z80, op1)
		s = Z80.obtenerS(op2)

		a = list(funciones.tobin(int(a, 16), 8))
		s = list(funciones.tobin(int(s, 16), 8))
		for i in range(0, 8):
			# Si los caracteres en a y s son distintos, se cambia a 0 en el acumulador (a)
			if (a[i] != s[i]):
				a[i] = "1"
		Z80.A = int(''.join(a), 2)
		# CAMBIAR BANDERAS AQUI
		Z80.changeFlag(0, "0")
		Z80.changeFlag(1, "0")
		Z80.zero(Z80.A)
		Z80.sign(Z80.A)
		Z80.A = funciones.tohex(int(Z80.A, 8))
		Z80.parity(Z80.A)
		""" >>>>> C = N = 0, Z = S = H = DE ACUERDO A LA OPERACION, P/V = PARIDAD <<<<< """

	# Realiza operacion OR exclusivo entre el acumulador (operando 1) con el operando 2
	@staticmethod
	def XOR(op1, op2):
		a = getattr(Z80, op1)
		s = Z80.obtenerS(op2)

		a = list(funciones.tobin(int(a, 16), 8))
		s = list(funciones.tobin(int(s, 16), 8))
		for i in range(0, 8):
			# Si los caracteres en a y s son distintos, se cambia a 0 en el acumulador (a)
			if (a[i] != s[i]):
				a[i] = "1"
			else:
				a[i] = "0"
		Z80.A = int(''.join(a), 2)
		# CAMBIAR BANDERAS AQUI
		Z80.changeFlag(0, "0")
		Z80.changeFlag(1, "0")
		Z80.zero(Z80.A)
		Z80.sign(Z80.A)
		Z80.A = funciones.tohex(Z80.A, 8)
		Z80.parity(int(Z80.A,16))
		""" >>>>> C = N = 0, Z = S = H = DE ACUERDO A LA OPERACION, P/V = PARIDAD <<<<< """

	# Compara el contenido del acumulador (operando 1) con el operando 2
	@staticmethod
	def CP(op1, op2):
		a = getattr(Z80, op1)
		s = Z80.obtenerS(op2)
		Z80.halfCarry(a, s, "-")
		flag = Z80.getFlagBit(7)
		a = funciones.hextodec(a)
		s = funciones.hextodec(s)
		res = a - s
		Z80.zero(res)
		Z80.carry(res)
		Z80.sign(res)
		Z80.overflow(res)
		Z80.changeFlag(1, "1")
		# CAMBIAR BANDERAS CON EL RESULTADO OBTENIDO
		""" >>>>> C = Z = S = H = DE ACUERDO A LA OPERACION, N = 1, P/V = SOBREPASAMIENTO <<<<< """

		# Incrementa el contenido del operando dado
	@staticmethod
	def INC(op):
		# Incrementar valor de un registro
		if (len(op) == 1):
			a = Z80.obtenerS(op)
			Z80.halfCarry(a, "01", "+" )
			a = int(a, 16) + 1
			Z80.zero(a)
			Z80.sign(a)
			Z80.changeFlag(1, "0")
			Z80.overflow(a)
			setattr(Z80, op, funciones.tohex(a,8))
			""" >>>>> Z = S = H = DE ACUERDO A LA OPERACION, N = 0, P/V = SOBREPASAMIENTO <<<<< """

		# Incrementar valor de SP, IX o IY
		elif ((op == "SP") or (op == "IX") or (op == "IY")):
			a = funciones.tohex(int(Z80.obtenerSS(op), 16) + 1, 16)
			setattr(Z80, op, a)
			""" >>>>> No hay banderas afectadas <<<<< """

		# Incrementar (HL), (IX+d), (IY+d)
		elif (op.find('(')!=-1):
			a = Z80.obtenerS(op)
			Z80.halfCarry(a, "01","+")
			a = int(a, 16) + 1
			Z80.zero(a)
			Z80.sign(a)
			Z80.changeFlag(1, "0")
			Z80.overflow(a)
			a = funciones.tohex(a, 8)
			if op[1:3] == "HL":
				flag = Z80.mem.cambiarContenido(a, ''.join([Z80.H, Z80.L]))
				return flag
			else:
				flag = Z80.mem.cambiarContenido(a, getattr(Z80, op[1:3]))
				return flag
			""" >>>>> Z = S = H = DE ACUERDO A LA OPERACION, N = 0, P/V = SOBREPASAMIENTO <<<<< """

		# Incrementar BC, DE, HL
		else:
			a = funciones.tohex(int(Z80.obtenerSS(op), 16) + 1, 16)
			setattr(Z80, op[0], a[:2])
			setattr(Z80, op[1], a[2:])
			""" >>>>> No hay banderas afectadas <<<<< """

	# Decrementa el contenido del operando dado
	@staticmethod
	def DEC(op):
		# Decrementar valor de un registro
		if (len(op) == 1):
			a = Z80.obtenerS(op)
			Z80.halfCarry(a, "01", "-")
			a = int(a, 16) - 1
			# CAMBIAR BANDERAS AQUI
			Z80.zero(a)
			Z80.sign(a)
			Z80.changeFlag(1, "1")
			Z80.overflow(a)
			a = funciones.tohex(a, 8)
			setattr(Z80, op, a)
			""" >>>>> Z = S = H = DE ACUERDO A LA OPERACION, N = 1, P/V = SOBREPASAMIENTO <<<<< """

		# Decrementar valor de SP, IX o IY
		elif ((op == "SP") or (op == "IX") or (op == "IY")):
			a = funciones.tohex(int(Z80.obtenerSS(op), 16) - 1, 16)
			setattr(Z80, op, a)
			""" >>>>> No hay banderas afectadas <<<<< """

		# Decrementar (HL), (IX+d), (IY+d)
		elif (op.find('(')!=-1):
			a = Z80.obtenerS(op)
			Z80.halfCarry(a, "01", "-")
			a = int(a, 16) - 1
			# CAMBIAR BANDERAS AQUI
			Z80.zero(a)
			Z80.sign(a)
			Z80.changeFlag(1, "1")
			Z80.overflow(a)
			a = funciones.tohex(a, 8)
			if op[1:3] == "HL":
				flag = Z80.mem.cambiarContenido(a, ''.join([Z80.H, Z80.L]))
				return flag
			else:
				flag = Z80.mem.cambiarContenido(a, getattr(Z80, op[1:3]))
				return flag
			""" >>>>> Z = S = H = DE ACUERDO A LA OPERACION, N = 1, P/V = SOBREPASAMIENTO <<<<< """

		# Incrementar BC, DE, HL
		else:
			a = funciones.tohex(int(Z80.obtenerSS(op), 16) - 1, 16)
			setattr(Z80, op[0], a[:2])
			setattr(Z80, op[1], a[2:])
			""" >>>>> No hay banderas afectadas <<<<< """

	# Niega el contenido de A
	@staticmethod
	def CPL():
		a = list(funciones.tobin(int(Z80.A,16), 8))
		for i in range(0,8):
			if (a[i] == "1"): a[i] = "0"
			else: a[i] = "1"
		Z80.A = funciones.tohex(int(''.join(a),2), 8)
		Z80.changeFlag(1, "1") # Cambia a N
		Z80.changeFlag(4, "1") # Cambia a H
		""" >>>>> Banderas afectadas: N = 1, H = 1 <<<<< """

	# Hace negativo el contenido de A
	@staticmethod
	def NEG():
		Z80.halfCarry("00", Z80.A,"-")
		Z80.A = 0 - int(Z80.A, 16)
		# CAMBIAR BANDERAS AQUI
		Z80.carry(Z80.A)
		Z80.zero(Z80.A)
		Z80.sign(Z80.A)
		Z80.overflow(Z80.A)
		Z80. A = funciones.tohex(Z80.A, 8)
		""" >>>>> C = Z = S = H = SE AFECTA DE ACUERDO A LA OPERACION, P/V = SOBREPASAMIENTO, N = 1 <<<<<"""

	# Apaga los flip flops
	@staticmethod
	def DI():
		Z80.IFF1 = "0"
		Z80.IFF2 = "0"
		""" >>>>> No hay banderas afectadas <<<<< """

	# Enciende los flip flops
	@staticmethod
	def EI():
		Z80.IFF1 = "1"
		Z80.IFF2 = "1"
		""" >>>>> No hay banderas afectadas <<<<< """

	# Niega el bit de acarreo
	@staticmethod
	def CCF():
		flag = funciones.tobin(int(Z80.F, 16), 8)
		CY = flag [7]
		if (CY == "0"): CY = "1"
		else: CY = "0"
		Z80.F = int( CY + flag[1:], 2)
		# CAMBIAR BANDERAS AQUI
		Z80.carry(Z80.F)
		Z80.changeFlag(1, "0")
		Z80.F = funciones.tohex(Z80.F, 8)
		""" >>>>> C = SE AFECTA DE ACUERDO A LA OPERACION, N = 0, H = DESCONOCIDO <<<<<"""

	# Enciende el bit de acarreo
	@staticmethod
	def SCF():
		flag = funciones.tobin(int(Z80.F, 16), 8)
		CY = "1"
		Z80.F = funciones.tohex(int( CY + flag[1:], 2), 8)
		Z80.changeFlag(0, "1") # Cambia a C
		Z80.changeFLag(1, "0") # Cambia a N
		Z80.changeFlag(4, "0") # Cambia a H
		""" >>>>> Banderas afectadas: C = 1, N =0  y H = 0 <<<<< """

	@staticmethod
	def NOP():
		pass
		""" >>>>> No hay banderas afectadas <<<<< """

	@staticmethod
	def HALT():
		pass
		""" >>>>> No hay banderas afectadas <<<<< """

	@staticmethod
	def DAA():
		cy = Z80.getFlagBit(0) # Obtiene bandera de acarreo
		hc = Z80.getFlagBit(4)  # Obtiene bandera de medio acarreo

		if ((cy == 0) and (hc == 0)):
			if (int(Z80.A[0],16) in range(0, 10) and int(Z80.A[1],16) in range(0, 10)):
				Z80.halfCarry(Z80.A, "00", "+")
				Z80.changeFlag(0, "0")
				Z80.A = int(Z80.A, 16) + int("00", 16)

			elif (int(Z80.A[0],16) in range(0, 9) and int(Z80.A[1],16) in range(10, 16)):
				Z80.halfCarry(Z80.A, "06", "+")
				Z80.A = int(Z80.A, 16) + int("06", 16)
				Z80.changeFlag(0, "0")

			elif (int(Z80.A[0],16) in range(10, 16) and int(Z80.A[1],16) in range(0, 10)):
				Z80.halfCarry(Z80.A, "60", "+")
				Z80.A = int(Z80.A, 16) + int("60", 16)
				Z80.changeFlag(0, "1")

			elif (int(Z80.A[0],16) in range(9, 16) and int(Z80.A[1],16) in range(10, 16)):
				Z80.halfCarry(Z80.A, "66", "+")
				Z80.A = int(Z80.A, 16) + int("66", 16)
				Z80.changeFlag(0, "1")

		elif ((cy == 0) and (hc == 1)):
			if (int(Z80.A[0],16) in range(0, 10) and int(Z80.A[1],16) in range(0, 4)):
				Z80.halfCarry(Z80.A, "06", "+")
				Z80.A = int(Z80.A, 16) + int("06", 16)
				Z80.changeFlag(0, "0")

			elif (int(Z80.A[0],16) in range(10, 16) and int(Z80.A[1],16) in range(0, 4)):
				Z80.halfCarry(Z80.A, "66", "+")
				Z80.A = int(Z80.A, 16) + int("66", 16)
				Z80.changeFlag(0, "1")

			elif (int(Z80.A[0],16) in range(0, 9) and int(Z80.A[1],16) in range(6, 16)):
				Z80.halfCarry(Z80.A, "FA", "+")
				Z80.A = int(Z80.A, 16) + int("FA", 16)
				Z80.changeFlag(0, "0")

		elif((cy == 1) and (hc == 0)):
			if (int(Z80.A[0],16) in range(0, 3) and int(Z80.A[1],16) in range(0, 10)):
				Z80.halfCarry(Z80.A, "60", "+")
				Z80.A = int(Z80.A, 16) + int("60", 16)
				Z80.changeFlag(0, "1")

			elif (int(Z80.A[0],16) in range(0, 3) and int(Z80.A[1],16) in range(10, 16)):
				Z80.halfCarry(Z80.A, "66", "+")
				Z80.A = int(Z80.A, 16) + int("66", 16)
				Z80.changeFlag(0, "1")

			elif (int(Z80.A[0],16) in range(7, 16) and int(Z80.A[1],16) in range(0, 10)):
				Z80.halfCarry(Z80.A, "A0", "+")
				Z80.A = int(Z80.A, 16) + int("A0", 16)
				Z80.changeFlag(0, "1")

		elif((cy == 1) and (hc == 1)):
			if (int(Z80.A[0],16) in range(0, 4) and int(Z80.A[1],16) in range(0, 4)):
				Z80.halfCarry(Z80.A, "66", "+")
				Z80.A = int(Z80.A, 16) + int("66", 16)
				Z80.changeFlag(0, "1")

			elif (int(Z80.A[0],16) in range(6, 16) and int(Z80.A[1],16) in range(6, 16)):
				Z80.halfCarry(Z80.A, "9A", "+")
				Z80.A = int(Z80.A, 16) + int("9A", 16)
				Z80.changeFlag(0, "1")

		#CAMBIAR BANDERAS AQUI
		Z80.carry(Z80.A)
		Z80.zero(Z80.A)
		Z80.sign(Z80.A)
		Z80.A = funciones.tohex(Z80.A, 8)
		Z80.parity(int(Z80.A, 16))
		""" C = Z = S = H = CAMBIAN SEGUN EL RESULTADO, P/V = PARIDAD """

	@staticmethod
	def obtenerCont(op2):
		if (op2.find('IX+')!=-1 or op2.find('IY+')!=-1):
			op2 = op2.replace("(","").replace(")","").replace("H","").split("+")
			reg = getattr(Z80, op2[0])
			des = op2[1]
			s = funciones.tohex(int(reg, 16) + funciones.hextodec(des), 16)
			cont = Z80.mem.obtenerContenido(s)
		elif op2.find('H)') != -1:
			op2 = op2.replace('(', '').replace(')', '').replace('H', '')
			cont = Z80.mem.obtenerContenido(op2)
		else:
			d = int(getattr(Z80, op2[0]) + getattr(Z80, op2[1]), 16)
			cont = Z80.mem.obtenerContenido(op2)
		return cont

	@staticmethod
	def obtenerPosicion(op1):
		if (op1.find("IX+") != -1 or op1.find("IY+") != -1):
			op1 = op1.replace("(","").replace(")","").replace("H","").split("+")
			reg = getattr(Z80, op1[0])
			des = op1[1]
			pos = funciones.tohex(int(reg, 16) + funciones.hextodec(des), 16)
		# Si es la direccion que contiene HL, se obtiene su contenido
		elif (op1 == "(HL)" or op1 == "(BC)" or op1 == "(DE)"):
			op1 = op1.replace('(','').replace(')','')
			pos = getattr(Z80, op1[0]) + getattr(Z80, op1[1])
		# El ultimo caso es que sea un numero en hexadecimal
		else:
			pos = op1.replace('(','').replace(')','').replace('H','')
		return pos

	@staticmethod
	def LD(op1, op2):
		if len(op1) == 1:
			if op2.find('C)') != -1 or op2.find('E)') != -1 or op2.find('H)') != -1:
				cont  = Z80.obtenerCont(op2)
				Z80.A = cont
			else:
				s = Z80.obtenerS(op2)
				setattr(Z80, op1, s)
		else:
			if op1.find('(') != -1 and len(op2) == 1:
				pos = Z80.obtenerPosicion(op1)
				s = getattr(Z80, op2)
				flag = Z80.mem.cambiarContenido(s, pos)
				return flag
			elif op1.find('(') != -1 and op2.find('H') != 1:
				pos = Z80.obtenerPosicion(op1)
				op2 = op2.replace('H','')
				flag = Z80.mem.cambiarContenido(op2, pos)
				return flag
			elif op1.find('(') != -1:
				ss = Z80.obtenerSS(op2)
				pos = Z80.obtenerPosicion(op1)
				flag1 = Z80.mem.cambiarContenido(ss[0], pos + 1)
				flag2 = Z80.mem.cambiarContenido(ss[1], pos)
				flag1.update(flag2)
				return flag1
			elif op1 == 'SP':
				ss = Z80.obtenerSS(op2)
				setattr(Z80, op1, ss)
			else:
				if op1 == 'IX' or op1 == 'IY':
					if op2.find('(') != -1:
						pos = Z80.obtenerPosicion(op2)
						a1 = Z80.mem.obtenerContenido(pos)
						a2 = Z80.mem.obtenerContenido(hex(int(pos,16) + 1)[2:])
						setattr(Z80, op1, a2 + a1)
					else:
						op2 = op2.replace('H', '')
						setattr(Z80, op1, op2)
				else:
					if op2.find('(') != -1:
						pos = Z80.obtenerPosicion(op2)
						a1 = Z80.mem.obtenerContenido(pos)
						a2 = Z80.mem.obtenerContenido(pos + 1)
						setattr(Z80, op1[0], a2)
						setattr(Z80, op1[1], a1)
					else:
						op2 = op2.replace('H', '')
						setattr(Z80, op1[0], op2[0])
						setattr(Z80, op1[1], op2[1])

	@staticmethod
	def PUSH(arg):
		Z80.SP = int(Z80.SP, 16)
		####################
		if Z80.SP == 0:
			Z80.SP = 65536
		#####################
		if Z80.SP >= 65026 and Z80.SP <= 65536:
			if arg == 'IX' or arg == 'IY':
				arg = getattr(Z80, arg)
				flag1 = Z80.mem.cambiarContenido(arg[:2], hex(Z80.SP - 1)[2:])
				flag2 = Z80.mem.cambiarContenido(arg[2:], hex(Z80.SP - 2)[2:])
				Z80.SP = funciones.tohex(Z80.SP - 2, 16)
				flag1.update(flag2)
				return flag1
			else:
				qL = getattr(Z80, arg[1])
				qH = getattr(Z80, arg[0])
				flag1 = Z80.mem.cambiarContenido(qH, hex(Z80.SP - 1)[2:])
				flag2 = Z80.mem.cambiarContenido(qL, hex(Z80.SP - 2)[2:])
				Z80.SP = funciones.tohex(Z80.SP - 2, 16)
				flag1.update(flag2)
				return flag1
		else:
			Z80.SP = funciones.tohex(Z80.SP, 16)

	@staticmethod
	def POP(arg):
		Z80.SP = int(Z80.SP, 16)
		#######################
		if Z80.SP == 0:
			Z80.SP = 65536
		##############
		if Z80.SP >= 65024 and Z80.SP < 65535:
			if arg == 'IX':
				Z80.IX = Z80.mem.obtenerContenido(hex(Z80.SP + 1)[2:]) + Z80.mem.obtenerContenido(hex(Z80.SP)[2:])
				flag1 = Z80.mem.cambiarContenido('00', hex(Z80.SP + 1))
				flag2 = Z80.mem.cambiarContenido('00', hex(Z80.SP))
				Z80.SP = hex(Z80.SP + 2)[2:].zfill(4).upper()
				flag1.update(flag2)
			elif arg == 'IY':
				Z80.IY = Z80.mem.obtenerContenido(hex(Z80.SP + 1)[2:]) + Z80.mem.obtenerContenido(hex(Z80.SP)[2:])
				flag1 = Z80.mem.cambiarContenido('00', hex(Z80.SP + 1))
				flag2 = Z80.mem.cambiarContenido('00', hex(Z80.SP))
				Z80.SP = hex(Z80.SP + 2)[2:].zfill(4).upper()
				flag1.update(flag2)
			else:
				setattr(Z80, arg[0], Z80.mem.obtenerContenido(hex(Z80.SP + 1)[2:]))
				setattr(Z80, arg[1], Z80.mem.obtenerContenido(hex(Z80.SP)[2:]))
				flag1 = Z80.mem.cambiarContenido('00', hex(Z80.SP + 1))
				flag2 = Z80.mem.cambiarContenido('00', hex(Z80.SP))
				Z80.SP = hex(Z80.SP + 2)[2:].zfill(4).upper()
			return flag1
		else:
			Z80.SP = funciones.tohex(Z80.SP, 16)

	@staticmethod
	def intercambio(arg1, arg2):
		if arg2.rfind('\'') != -1:
			arg2 = arg2.replace('\'', '')
		aux = getattr(Z80, arg1[0])
		setattr(Z80, arg1[0], getattr(Z80, arg2[0]))
		setattr(Z80, arg2[0], aux)

		aux = getattr(Z80, arg1[1])
		setattr(Z80, arg1[1], getattr(Z80, arg2[1]))
		setattr(Z80, arg2[1], aux)

	@staticmethod
	def EX(arg1, arg2):
		# DE <-> HL o AF <-> A_F_
		if len(arg1) == 2:
			Z80.intercambio(arg1, arg2)
		# IX <-> (SP) o IY <-> (SP)
		elif arg2 == 'IX' or arg2 == 'IY':
			aux = getattr(Z80, arg2)
			Z80.POP(arg2)
			aux2 = getattr(Z80, arg2)
			setattr(Z80, arg2, aux)
			Z80.PUSH(arg2)
			setattr(Z80, arg2, aux2)
		# (SP) <-> HL
		else:
			aux = Z80.H + Z80.L
			Z80.POP(arg2)
			aux2 = Z80.H + Z80.L
			Z80.H = aux[:2]
			Z80.L = aux[2:]
			Z80.PUSH(arg2)
			Z80.H = aux2[:2]
			Z80.L = aux2[2:]

	@staticmethod
	def EXX():
		# BC <-> B_C_
		Z80.intercambio('BC', ['B_', 'C_'])

		# DE <-> D_E_
		Z80.intercambio('DE', ['D_', 'E_'])
		# HL <-> H_L_
		Z80.intercambio('HL', ['H_', 'L_'])

	@staticmethod
	def transferencia(sign):
		# (DE) <- (HL)
		dir1 = int(Z80.D + Z80.E, 16)
		dir2 = int(Z80.H + Z80.L, 16)
		con = Z80.mem.obtenerContenido(hex(dir2)[2:])
		flag = Z80.mem.cambiarContenido(con, hex(dir1)[2:])
		# DE <- DE + 1 o DE <- DE - 1
		dir1 = eval(str(dir1) + sign + '1')
		dir1 = funciones.tohex(dir1, 16)
		Z80.D = dir1[:2]
		Z80.E = dir1[2:]
		# HL <- HL + 1 o  HL <- HL - 1
		dir2 = eval(str(dir2) + sign + '1')
		dir2 = funciones.tohex(dir2, 16)
		Z80.H = dir2[:2]
		Z80.L = dir2[2:]
		# BC <- BC - 1
		dir1 = int(Z80.B + Z80.C, 16) - 1
		if dir1 == 0:
			Z80.changeFlag(2, '0')
		else:
			Z80.changeFlag(2, '1')
		dir1 = funciones.tohex(dir1, 16)
		Z80.B = dir1[:2]
		Z80.C = dir1[2:]
		return flag

	@staticmethod
	def LDI():
		Z80.changeFlag(1,'0')
		Z80.changeFlag(4,'0')
		flag = Z80.transferencia('+')
		return flag

	@staticmethod
	def LDIR():
		Z80.changeFlag(1,'0')
		Z80.changeFlag(4,'0')
		flag = {}
		c = int(Z80.B + Z80.C, 16)
		while c != 0:
			Z80.time += 21
			flag.update(Z80.transferencia('+'))
			c -= 1
		Z80.time += 16
		return flag

	@staticmethod
	def LDD():
		Z80.changeFlag(1,'0')
		Z80.changeFlag(4,'0')
		flag = Z80.transferencia('-')
		return flag

	@staticmethod
	def LDDR():
		Z80.changeFlag(1,'0')
		Z80.changeFlag(4,'0')
		c = int(Z80.B + Z80.C, 16)
		flag = {}
		while c != 0:
			Z80.time += 21
			flag.update(Z80.transferencia('-'))
			c -= 1
		Z80.time += 16
		return flag

	@staticmethod
	def busqueda(o):
		# BC <- BC - 1
		v = int(Z80.B + Z80.C, 16) - 1
		if v == 0:
			Z80.changeFlag(2, '0')
		else:
			Z80.changeFlag(2, '1')
		v = funciones.tohex(v, 16)
		Z80.B = v[:2]
		Z80.C = v[2:]
		# HL <- HL + 1 o HL <- HL - 1
		HL = Z80.H + Z80.L
		v = eval(str(int(HL, 16)) + o + '1')
		v = funciones.tohex(v, 16)
		Z80.H = v[:2]
		Z80.L = v[2:]
		# A - (HL)
		cont = Z80.mem.obtenerContenido(HL)
		Z80.halfCarry(Z80.A, cont, '-')
		Z80.changeFlag(1, '1')
		cont = int(Z80.A, 16) - int(cont, 16)
		Z80.sign(cont)
		if Z80.A == Z80.mem.obtenerContenido(HL):
			Z80.changeFlag(6, '1')
			return False
		else:
			Z80.changeFlag(6, '0')
			return True

	@staticmethod
	def CPI():
		Z80.busqueda('+')

	@staticmethod
	def CPIR():
		c = int(Z80.B + Z80.C, 16)
		while c != 0:
			b = Z80.busqueda('+')
			if b == False:
				break
			else:
				Z80.time += 21
				c -= 1
		Z80.time += 16

	@staticmethod
	def CPD():
		Z80.busqueda('-')

	@staticmethod
	def CPDR():
		c = int(Z80.B + Z80.C, 16)
		while c != 0:
			b = Z80.busqueda('-')
			if b == False:
				break
			else:
				Z80.time += 21
				c -= 1
		Z80.time += 16

	@staticmethod
	def ADD(op1, op2):
		if op1 == 'A':
			s = Z80.obtenerS(op2)
			Z80.halfCarry(Z80.A, s, '+')
			s = int(Z80.A, 16) + int(s, 16)
			Z80.carry(s)
			Z80.zero(s)
			Z80.overflow(s)
			Z80.sign(s)
			Z80.changeFlag(1,'0')
			Z80.A = funciones.tohex(s, 8)
		elif op1 == 'IX' or op1 == 'IY':
			s = int(getattr(Z80, op1), 16) + int(Z80.obtenerSS(op2), 16)
			Z80.carry(s)
			Z80.changeFlag(1,'0')
			s = funciones.tohex(s, 16)
			setattr(Z80, op1, s)
		else:
			HL = ''.join([Z80.H, Z80.L])
			ss = Z80.obtenerSS(op2)
			HL = int(HL, 16) + int(ss, 16)
			Z80.carry(HL)
			Z80.changeFlag(1,'0')
			HL = funciones.tohex(HL, 16)
			Z80.H = HL[:2]
			Z80.L = HL[2:]

	@staticmethod
	def ADC(op1, op2):
		CY = bin(int(Z80.F,16))[2:].zfill(8)[0]
		if (op1 == "A"):
			s = Z80.obtenerS(op2)
			Z80.halfCarry(Z80.A, s, '+')
			s = int(Z80.A, 16) + int(s, 16) + int(CY, 16)
			Z80.carry(s)
			Z80.zero(s)
			Z80.overflow(s)
			Z80.sign(s)
			Z80.changeFlag(1,'0')
			Z80.A = funciones.tohex(s, 8)
		else:
			HL = ''.join([Z80.H, Z80.L])
			ss = Z80.obtenerSS(op2)
			HL = int(HL,16) + int(ss,16) + int(CY, 2)
			Z80.carry(s)
			Z80.zero(s)
			Z80.overflow(s)
			Z80.sign(s)
			Z80.changeFlag(1,'0')
			HL = funciones.tohex(HL, 16)
			# El primer byte se guarda en H y el segundo en L
			Z80.H = HL[:2]
			Z80.L = HL[2:]

	@staticmethod
	def SUB(op1, op2):
		s = Z80.obtenerS(op2)
		Z80.halfCarry(Z80.A, s, '-')
		s = int(Z80.A, 16) - int(s, 16)
		Z80.carry(s)
		Z80.zero(s)
		Z80.overflow(s)
		Z80.sign(s)
		Z80.changeFlag(1,'1')
		Z80.A = funciones.tohex(s,8)

#Este metodo es el encargado de hacer los brincos por medio del PC, se manda a llamar
#desde los metodos JP y JR.
	@staticmethod
	def hexToDecJR(cadenahexa):
		numDec = int(cadenahexa,16)
		if numDec > 127:
			numDec = numDec - 256
		nuevoPC = int(Z80.PC,16) + numDec
		Z80.PC = str(funciones.tohex(nuevoPC,16))
		return

# Metodo para dar un brinco absoluto en el programa
# Actualiza el PC a la dirección en hexadecimal recibida.

	@staticmethod
	def JP(cadena):
		#Sanlto incondicional
		if (cadena.find(",") == -1):
			Z80.PC = cadena.replace("H","")
		else:
		#Saltos condicionales
			if(cadena.find("C") == 0):
				if Z80.getFlagBit(0) == 0:
					return
				else:
					Z80.PC = cadena[2:6]
			elif(cadena.find("C") == 1):
				if Z80.getFlagBit(0) == 1:
					return
				else:
					Z80.PC = cadena[3:7]
			elif(cadena.find("Z") == 0):
				if Z80.getFlagBit(6) == 0:
					return
				else:
					Z80.PC = cadena[2:6]
			elif(cadena.find("Z") == 1):
				if Z80.getFlagBit(6) == 1:
					return
				else:
					Z80.PC = cadena[3:7]
			elif(cadena.find("O") == 1):
				if Z80.getFlagBit(2) == 1:
					return
				else:
					Z80.PC = cadena[3:7]
			elif(cadena.find("E") == 1):
				if Z80.getFlagBit(2) == 0:
					return
				else:
					Z80.PC = cadena[3:7]
			elif(cadena.find("P") == 0):
				if Z80.getFlagBit(7) == 1:
					return
				else:
					Z80.PC = cadena[2:6]
			elif(cadena.find("M") == 0):
				if Z80.getFlagBit(7) == 0:
					return
				else:
					Z80.PC = cadena[2:6]

# Metodo para dar un brinco relativo al valor del PC con un
# alcance en el rango de e = <-127,129> desde la dirección
# del primer código de operación de esta instrucción.
# Recibe el valor del Brinco un numero hexadecimal en comple
# mento a dos y lo suma al valor actual del PC.

	@staticmethod
	def JR(cadena):
		# Salto incondicional relativo
		if (cadena.find(",") == -1):  #Es un salto incondicional
			Z80.hexToDecJR(cadena[0:2])
		else:
		# Salto condicional relativo
			if(cadena.find("C") == 0):
				if Z80.getFlagBit(0) == 0:
					Z80.time += 7
					return
				else:
					Z80.time += 12
					Z80.hexToDecJR(cadena[2:4])
			elif(cadena.find("C") == 1):
				if Z80.getFlagBit(0) == 1:
					Z80.time += 7
					return
				else:
					Z80.time += 12
					Z80.hexToDecJR(cadena[3:5])
			elif(cadena.find("Z") == 0):
				if Z80.getFlagBit(6) == 0:
					Z80.time += 7
					return
				else:
					Z80.time += 12
					Z80.hexToDecJR(cadena[2:4])
			elif(cadena.find("Z") == 1):
				if Z80.getFlagBit(6) == 1:
					Z80.time += 1
					return
				else:
					Z80.time += 12
					Z80.hexToDecJR(cadena[3:5])

# Metodo DJNZ que da un brinco relativo un número total de
# veces del valor en el registro B, se decremenata en uno
# antes de cada Brinco.

	@staticmethod
	def DJNZ(cadena):
		Z80.B = str(int(Z80.B)-1)
		if (int(Z80.B) != 0):
			Z80.time += 13
			Z80.hexToDecJR(cadena[0:2])
		else:
			Z80.time += 8
			return

# Metodo que manda a llamar o no al metodo C4LL (CALL)
# Si se trata de una llamada incondicional le pasa el
# valor que recibe de entrada para actualizar el PC
# Si se trata de una llamada condicional, verifica la
# condición y si la cumple llama a C4LL para actualizar
# el PC.

	@staticmethod
	def CALL(cadena):
		if (cadena.find(",") == -1):
			Z80.C4LL(cadena)
		else:
			if(cadena.find("C") == 0):
				if Z80.getFlagBit(0) == 0:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[2:6])
			elif(cadena.find("C") == 1):
				if Z80.getFlagBit(0) == 1:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[3:7])
			elif(cadena.find("Z") == 0):
				if Z80.getFlagBit(6) == 0:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[2:6])
			elif(cadena.find("Z") == 1):
				if Z80.getFlagBit(6) == 1:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[3:7])
			elif(cadena.find("O") == 1):
				if Z80.getFlagBit(2) == 1:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[3:7])
			elif(cadena.find("E") == 1):
				if Z80.getFlagBit(2) == 0:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[3:7])
			elif(cadena.find("P") == 0):
				if Z80.getFlagBit(7) == 1:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[2:6])
			elif(cadena.find("M") == 0):
				if Z80.getFlagBit(7) == 0:
					Z80.time += 10
					return
				else:
					Z80.time += 17
					Z80.C4LL(cadena[2:6])

# Función que almacena el valor del PC en la pila, para despues ser recuperado
# además que da un brinco absoluto a la dirección que recibe.

	@staticmethod
	def C4LL(cadena):
		Z80.SP = int(Z80.SP,16)
		##################
		if Z80.SP == 0:
			Z80.SP = 65536
		##################
		valorPC = Z80.PC
		if (Z80.SP > 65026 and Z80.SP <= 65536):
			flag1 = Z80.mem.cambiarContenido(valorPC[0:2],funciones.tohex(Z80.SP-1,16))
			flag2 = Z80.mem.cambiarContenido(valorPC[2:4],funciones.tohex(Z80.SP-2,16))
			Z80.SP = str(funciones.tohex(Z80.SP - 2,16))
			Z80.PC = cadena.replace("H","")
			flag1.update(flag2)
			return flag1
		else:
			Z80.SP = funciones.tohex(Z80.SP, 16)

	@staticmethod
	def RET(cadena):
		if (len(cadena) == 0):
			Z80.R3T()
		else:
			if(cadena.find("C") == 0):
				if Z80.getFlagBit(0) == 0:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("C") == 1):
				if Z80.getFlagBit(0) == 1:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("Z") == 0):
				if Z80.getFlagBit(6) == 0:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("Z") == 1):
				if Z80.getFlagBit(6) == 1:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("O") == 1):
				if Z80.getFlagBit(2) == 1:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("E") == 1):
				if Z80.getFlagBit(2) == 0:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("P") == 0):
				if Z80.getFlagBit(7) == 1:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()
			elif(cadena.find("M") == 0):
				if Z80.getFlagBit(7) == 0:
					Z80.time += 5
					return
				else:
					Z80.time += 11
					Z80.R3T()

# Regresa el PC almacenado en la pila al PC y pone ceros ('00')
# además actualiza el valor del SP

	@staticmethod
	def R3T():
		Z80.SP = int(Z80.SP,16)
		###########################
		if Z80.SP == 0:
			Z80.SP = 65536
		###########################
		if (Z80.SP >= 65024 and Z80.SP < 65535):
			Z80.PC = Z80.mem.obtenerContenido(funciones.tohex(Z80.SP+1,16))+Z80.mem.obtenerContenido(funciones.tohex(Z80.SP,16))
			Z80.SP = str(funciones.tohex(Z80.SP + 2,16))
		else:
			Z80.SP = funciones.tohex(Z80.SP, 16)

# Metodo que utiliza el modo de direccionamienro de pagina cero
# util ya que con un solo byte te permite dirigirte a varias
# posiciones de la pagina cero de la memoria donde usualmente
# suelen estar las subrutinas más utilizadas.

	@staticmethod
	def RST(cadena):
		cadena = cadena[0:2]
		Z80.SP = int(Z80.SP,16)
		#########################
		if Z80.SP == 0:
			Z80.SP = 65536
		##########################
		valorPC = Z80.PC
		if (Z80.SP > 65024 and Z80.SP <= 65536):
			fla1 = Z80.mem.cambiarContenido(valorPC[0:2], funciones.tohex(Z80.SP-1,16))
			flag2 = Z80.mem.cambiarContenido(valorPC[2:4], funciones.tohex(Z80.SP-2,16))
			Z80.SP = str(funciones.tohex(Z80.SP - 2,16))
			Z80.PC = '00'+cadena
			flag1.update(flag2)
			return flag1
		else:
			Z80.SP = funciones.tohex(Z80, 16)

	@staticmethod
	def checkRegister(o, name, register):
		if(register[0] == "("):
			getattr(o, name + "8")(register)
			return
		getattr(o, name + "4")(register)

	@staticmethod
	def checkRegister2(o, name, bitIndex, register):
		if(register[0] == "("):
			getattr(o, name + "8")(bitIndex,register)
			return
		getattr(o, name + "4")(bitIndex,register)

	@staticmethod
	def RLCA():
		Z80.A = Z80.binToHex(Library.CircularLeftRotation(Z80.A))
		Z80.changeFlag(1,"0")
		Z80.changeFlag(4,"0")

	@staticmethod
	def RLA():
		Z80.A = Z80.binToHex(Library.LeftRotation(Z80.A))
		Z80.changeFlag(1, "0")
		Z80.changeFlag(4, "0")

	#The contents of the Accumulator (Register A) are rotated right 1 bit position.
	# Bit 0 is copied to the Carry flag and also to bit 7. Bit 0 is the least-significant bit.
	@staticmethod
	def RRCA():
		Z80.A = Z80.binToHex(Library.CircularRightRotation(Z80.A))
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "0")

	@staticmethod
	def RRA():
		Z80.A = Z80.binToHex(Library.RightRotation(Z80.A))
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "0")

	@staticmethod
	def changeFlags(numberInBIN):
		""" Cambiar banderas para RLC,RL,RRC """
		Library.ChangeS(numberInBIN)
		Library.ChangeP(numberInBIN)
		Library.ChangeZ(numberInBIN)
		numberInHEX = Z80.hexToBin(numberInBIN)
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "0")


	@staticmethod
	def RLC(register):
		Z80.checkRegister(Z80, "RLC", register)

	#The contents of register r are rotated left 1 bit position. The contents of bit 7 are copied to
	#the Carry flag and also to bit 0. In the assembled object code, operand r is specified as follows:
	@staticmethod
	def RLC4(register):
		numberInHEX = getattr(Z80, register)
		numberInBIN = Library.CircularLeftRotation(numberInHEX)
		setattr(Z80, register, Z80.binToHex(numberInBIN))
		Z80.changeFlags(numberInBIN)

	@staticmethod
	def RLC8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.CircularLeftRotation(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag

	@staticmethod
	def RL(register):
		#mandando a llamar a RL4 o RL8 dependiendo
		#de cuantos bytes son los registros
		#para registros de 1 bytes es RL4
		#para regitros de 2 bytes es RL8
		Z80.checkRegister(Z80, "RL", register)

	@staticmethod
	def RL4(register):
		#valor del registro a rotar
		numberInHEX = getattr(Z80, register)
		#nuevo contenido del registro en binario
		numberInBIN = Library.LeftRotation(numberInHEX)
		#set el nuevo contenido al registro en números hexadecimales
		setattr(Z80, register, Z80.binToHex(numberInBIN))
		Z80.changeFlags(numberInBIN)

	@staticmethod
	def RL8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.LeftRotation(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag

## hasta aqui bien
	@staticmethod
	def RRC(register):
		#mandando a llamar a RRC4 o RRC8 dependiendo
		#de cuantos bytes son los registros
		#para registros de 1 bytes es RRC4
		#para regitros de 2 bytes es RRC8
		Z80.checkRegister(Z80, "RRC", register)

	@staticmethod
	def RRC4(register):
		#valor del registro a rotar
		numberInHEX = getattr(Z80, register)
		#nuevo contenido del registro en binario
		numberInBIN = Library.CircularRightRotation(numberInHEX)
		#set el nuevo contenido al registro en números hexadecimales
		setattr(Z80, register, Z80.binToHex(numberInBIN))
		Z80.changeFlags(numberInBIN)

	@staticmethod
	def RRC8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.CircularRightRotation(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag

	@staticmethod
	def RR(register):
		#mandando a llamar a RR4 o RR8 dependiendo
		#de cuantos bytes son los registros
		#para registros de 1 bytes es RR4
		#para regitros de 2 bytes es RR8
		Z80.checkRegister(Z80, "RR", register)

	@staticmethod
	def RR4(register):
		#valor del registro a rotar
		numberInHEX = getattr(Z80, register)
		#nuevo contenido del registro en binario
		numberInBIN = Library.RightRotation(numberInHEX)
		#set el nuevo contenido al registro en números hexadecimales
		setattr(Z80, register, Z80.binToHex(numberInBIN))
		Z80.changeFlags(numberInBIN)

	@staticmethod
	def RR8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.RightRotation(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag

	@staticmethod
	def SLA(register):
		Z80.checkRegister(Z80, "SLA", register)

	@staticmethod
	def SLA4(register):
		numberInHEX = getattr(Z80, register)
		numberInBIN = Library.ShiftLeft(numberInHEX)
		Z80.changeFlags(numberInBIN)
		setattr(Z80, register, Z80.binToHex(numberInBIN))

	@staticmethod
	def SLA8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.ShiftLeft(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag

	@staticmethod
	def SRA(register):
		Z80.checkRegister(Z80, "SRA", register)

	@staticmethod
	def SRA4(register):
		numberInHEX = getattr(Z80, register)
		numberInBIN = Library.RightArithmeticShift(numberInHEX)
		Z80.changeFlags(numberInBIN)
		setattr(Z80, register, Z80.binToHex(numberInBIN))

	@staticmethod
	def SRA8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.RightArithmeticShift(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag
## checar denuevo
	@staticmethod
	def changeFlagsSRL(numberInBIN):
		""" Cambiar banderas para RLC,RL,RRC """
		Z80.changeFlag(0, "0")
		Library.ChangeP(numberInBIN)
		Library.ChangeZ(numberInBIN)
		numberInHEX = Z80.hexToBin(numberInBIN)
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "0")

	@staticmethod
	def SRL(register):
		Z80.checkRegister(Z80, "SRL", register)

	@staticmethod
	def SRL4(register):
		numberInHEX = getattr(Z80, register)
		numberInBIN = Library.RightLogicalShift(numberInHEX)
		Z80.changeFlags(numberInBIN)
		setattr(Z80, register, Z80.binToHex(numberInBIN))

	@staticmethod
	def SRL8(register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		#nuevo contenido de la dirección de memoria en Binario
		content = Library.RightLogicalShift(content)
		Z80.changeFlags(content)
		#nuevo contenido de la memoria en hexadecimal
		content = Z80.binToHex(content)
		#set el nuevo contenido de la localidad de memoria
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		return flag

	@staticmethod
	def changeFlags2(numberInBIN):
		Library.ChangeS(numberInBIN)
		Library.ChangeS(numberInBIN)
		Library.ChangeP(numberInBIN)
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "0")

	@staticmethod
	def RLD():
		memoryAddress = getattr(Z80, "H") + getattr(Z80, "L")
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		content = Z80.hexToBin(content)
		high_order_four_bits = content[:4]
		low_order_four_bits = content[4:]
		contentOfA = Z80.hexToBin(Z80.A)
		high_order_four_bits_A = contentOfA[:4]
		low_order_four_bits_A = contentOfA[4:]
		contentOfA = high_order_four_bits_A + high_order_four_bits
		content = low_order_four_bits + low_order_four_bits_A
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		Z80.A = Z80.binToHex(contentOfA)
		Z80.changeFlags2(contentOfA)
		return flag

	@staticmethod
	def RRD():
		memoryAddress = getattr(Z80, "H") + getattr(Z80, "L")
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		content = Z80.hexToBin(content)
		high_order_four_bits = content[:4]
		low_order_four_bits = content[4:]
		contentOfA = Z80.hexToBin(Z80.A)
		high_order_four_bits_A = contentOfA[:4]
		low_order_four_bits_A = contentOfA[4:]
		contentOfA = high_order_four_bits_A + low_order_four_bits
		content = low_order_four_bits_A + high_order_four_bits
		flag = Z80.mem.cambiarContenido(content, memoryAddress)
		Z80.A = Z80.binToHex(contentOfA)
		Z80.changeFlags2(contentOfA)
		return flag

	@staticmethod
	def BIT(bitIndex, register):
		Z80.checkRegister2(Z80, "BIT", bitIndex, register)

	@staticmethod
	def BIT4(bitIndex, register):
		register = getattr(Z80, register)
		registerInBIN = Z80.hexToBin(register)
		if registerInBIN[7 - int(bitIndex)] != "0":
			Z80.changeFlag(6, "0")
		else:
			Z80.changeFlag(6, "1")
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "1")
		Z80.changeFlag(int(bitIndex), registerInBIN[7 - int(bitIndex)])

	@staticmethod
	def BIT8(bitIndex, register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		content = Z80.hexToBin(content)
		if content[7 - int(bitIndex)] != "0":
			Z80.changeFlag(6, "0")
		else:
			Z80.changeFlag(6, "1")
		#cambiando la bandera N
		Z80.changeFlag(1, "0")
		#cambiando la bandera H
		Z80.changeFlag(4, "1")
		Z80.changeFlag(int(bitIndex), content[7 - int(bitIndex)])


	@staticmethod
	def SET(bitIndex, register):
		Z80.checkRegister2(Z80, "SET", bitIndex, register)

	@staticmethod
	def SET4(bitIndex, register):
		numberInHEX = getattr(Z80, register)
		registerInBIN = Z80.hexToBin(numberInHEX)
		registerInBIN = list(registerInBIN)
		registerInBIN[7 - int(bitIndex)] = "1"
		registerInBIN = "".join(registerInBIN)
		setattr(Z80, register, Z80.binToHex(registerInBIN))

	@staticmethod
	def SET8(bitIndex, register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		content = Z80.hexToBin(content)
		content = list(content)
		content[7 - int(bitIndex)] = "1"
		content = "".join(content)
		flag = Z80.mem.cambiarContenido(Z80.binToHex(content), memoryAddress)
		return flag

	@staticmethod
	def RES(bitIndex, register):
		Z80.checkRegister2(Z80, "RES", bitIndex, register)

	@staticmethod
	def RES4(bitIndex, register):
		numberInHEX = getattr(Z80, register)
		registerInBIN = Z80.hexToBin(numberInHEX)
		registerInBIN = list(registerInBIN)
		registerInBIN[7 - int(bitIndex)] = "0"
		registerInBIN = "".join(registerInBIN)
		setattr(Z80, register, Z80.binToHex(registerInBIN))

	@staticmethod
	def RES8(bitIndex, register):
		memoryAddress = Library.isHL_IX_IY(register)
		content = memoria.Memoria.obtenerContenido(memoryAddress)
		content = Z80.hexToBin(content)
		content = list(content)
		content[7 - int(bitIndex)] = "0"
		content = "".join(content)
		flag = Z80.mem.cambiarContenido(Z80.binToHex(content), memoryAddress)
		return flag