/* 
 * LLAMADA AL SISTEMA: sis_dormir
 */
int sis_dormir()
{
	TipoBCP * procesoAnterior;
	unsigned int segundos;	
	
	segundos = (unsigned int) leer_registro(1);
	
	/*Asignamos el valor de despertarEnTicks*/
	procesoActual->despertarEnTicks = ticks + (segundos*TICK);
	
	/*Insertamos el proceso en la lista de dormidos y cambiamos su estado*/	
	insertarOrdenadoListaBCP(&listaDormidos,procesoActual);
	procesoActual->estado = BLOQUEADO;
	
	/*Cambiamos al siguiente proceso que nos devuelve el planificador*/	
	procesoAnterior = procesoActual;
	procesoActual = planificador();
	
	/*En caso de que el proceso recuperado sea NULL, esperamos a que se encuentre el siguiente no 		NULL*/
	while (procesoActual == NULL) {
		esperaInterrupcion();
		procesoActual=planificador();
	}
	
	/*Cambiamos el estado del proceso y realizamos el cambio de contexto entre los dos procesos*/	
	procesoActual->estado = EJECUCION;
	cambio_contexto(&(procesoAnterior->contextoRegs), &(procesoActual->contextoRegs));

	return 0;
}
/*
 * Funcion auxiliar que termina proceso actual liberando sus recursos.
 * Usada por llamada terminar_proceso y por rutinas que tratan excepciones
 */
void liberarProceso()
{
	TipoBCP * procesoAnterior;

	liberar_imagen(procesoActual->infoMemoria); /* liberar mapa */
	procesoActual->estado=TERMINADO;

	/* Realizar cambio de contexto */
	procesoAnterior=procesoActual;
	procesoActual=planificador();
	while (procesoActual == NULL) {
		//printk("-> liberarProceso: esperaInterrupcion()\n");
		esperaInterrupcion();
        //printk("-> liberarProceso: FIN esperaInterrupcion()\n");
		procesoActual=planificador();
	}	

	printk("-> C.CONTEXTO POR FIN: de %d a %d\n",
			procesoAnterior->id, procesoActual->id);

	liberar_pila(procesoAnterior->pila);
	cambio_contexto(NULL, &(procesoActual->contextoRegs));
	
	return; /* no deberÌa llegar aqui */
}
static void nuevo_proceso(void)
{
        salvar_contexto;
        
        planificador();

        restaurar_contexto;
}
/*
 * Funcion que realiza una peticion de lectura/escritura
 * de un caracter al dispositivo de teclado
 */
int peticionCaracter_teclado(int descDispositivo, char *caracter, int operacion)
{ 

	TipoDatosPropiosDispositivo_teclado *datosPropiosDispositivo;
	TipoBCP * proceso;
	int ret;
	
	/* si la operacion NO es de lectura abortar */
	if (operacion != OP_READ) {
		return (-1);
	}
	
	/* obtener datos propios del dispositivo */
	datosPropiosDispositivo = (TipoDatosPropiosDispositivo_teclado *) 
							   tablaDispositivos[descDispositivo].datosPropiosDispositivo;
							   
    if ( estaVacioBufferCaracteres(&(datosPropiosDispositivo->bufferCaracteres)) ) {
      	/* si esta vacio bloquear el proceso y seleccionar otro */
		proceso = procesoActual;
		insertarUltimoListaBCP (&(datosPropiosDispositivo->listaProcesosBloqueados),proceso);
		proceso->estado = BLOQUEADO;
		procesoActual = planificador();
		while (procesoActual == NULL) {
			esperaInterrupcion();
			procesoActual=planificador();
		}	
        procesoActual->estado = EJECUCION;

        /* saltar al otro proceso */
        cambio_contexto(&(proceso->contextoRegs), &(procesoActual->contextoRegs));
	}
	
	/* cuando vuelva a ejecutar, obtener caracter y terminar con exito*/
	ret = extraerBufferCaracteres(&(datosPropiosDispositivo->bufferCaracteres),caracter);
	
    return (ret);
}
/*--------------------------------------------------------------------------*/
static int sys_kill_bill(void)
{
    /* by tarantino */

    struct PCB *tmp = (void *)0;
    unsigned long dir;
    unsigned int desplazamiento;
    unsigned int segmento;
    int pid = current->contexto->cx;
    int senal = current->contexto->dx;

    if (pid < 1 || pid == current->pid)
        return EINVAL;		/* no podemos matar al proceso 0 */


    if ((tablaprocesos[pid].estado) == PCB_LIBRE)
        return 0;

    if (senal == SIGKILL) {
        tablaprocesos[pid].estado = PROCESO_KILL;
        current = tablaprocesos + pid;
        planificador();
    }

    else if (senal == SIGUSR) {

        if (tablaprocesos[pid].signal != 0) {

            tmp = tablaprocesos + pid;
            segmento = (unsigned int)tmp->contexto->cs;
            desplazamiento = (unsigned int)tmp->signal;

            asm {
                mov bx, segmento
                push bx
                mov bx, desplazamiento
                push bx
                push bp
                mov bp,sp
                call dword ptr [bp+2]
                pop bp
                pop bx
                pop bx
                pop bx
            }
        }
        else {
            return 0;