Escribir un programa en assembler que envíe por el altavoz de la PC tres sonidos simultáneamente. Estos sonidos serán señales senoidales y se especificarán en la línea de comandos, de la siguiente manera:
SONIDO frec_A frec_B frec_C duración
donde frec_A, frec_B
y frec_C
son las frecuencias de los sonidos en Hz y duración
está dada en centésimas de segundo.
Ejemplo: SONIDO 200 500 900 43
durante 0,43 seg el programa deberá reproducir la suma de los tres tonos puros de 200 Hz, 500 Hz y 900 Hz.
Durante la ejecución del programa, las interrupciones deben estar deshabilitadas.
Al principio del programa, éste deberá mostrar el siguiente texto en pantalla:
La frecuencia de operación del procesador es de xxx MHz
.
Para calcular dicho valor se deberá utilizar la instrucción RDTSC, válida sólo en procesadores Pentium y posteriores, que devuelve en el par de registros de 32 bits EDX:EAX la cantidad de ciclos de reloj ejecutados desde el encendido. Utilizar como base de tiempo conocido el timer cero, que cuenta de 0000h a FFFFh en 54,93 mseg.
En la segunda parte el programa deberá reproducir el sonido en el parlante. Utilizar modulación por ancho de pulso (PWM) de la siguiente manera: muestrear la señal cada 4096 ciclos de procesador (usando RDTSC). El ciclo de trabajo se determinará como cociente entre la amplitud actual y la amplitud pico a pico.
Para generar las muestras se utilizará una tabla de 256 entradas que representa un ciclo de onda:
Entrada 00h (0º): 7Fh.
Entrada 40h (90º): FEh.
Entrada 80h (180º): 7Fh.
Entrada C0h (270º): 00h.
En general, a la entrada n le corresponderá el valor 127 + 127 sin((2*pi*n)/256). El alumno deberá calcular los 256 valores y ubicarlos en las directivas DB correspondientes.
Ahora determinaremos la velocidad con la que se deberá recorrer la tabla, es decir cuántas entradas de tabla hay que avanzar por cada muestra.
Sea tC = tiempo de un ciclo de onda, tM = tiempo de una muestra, tE = tiempo entre dos entradas consecutivas de la tabla, fC = frecuencia de la CPU, fS = frecuencia de la señal y ME = Cantidad de entradas de la tabla por muestra.
ME = | tM tE | = | 4096/fC tc/256 | = | 1048576 fS fC |
---|
Es decir, que a mayor frecuencia de señal, la tabla se recorre más rápido.
Como la cantidad de entradas de la tabla por muestra no es un número entero (en general), lo mejor es multiplicar el número obtenido por 256, hacer los cálculos, y luego volver a dividir por 256.
Ejemplo: Indicar los elementos de la tabla que se utilizarán para generar una onda de 200 Hz si el procesador está corriendo a 166 MHz.
De la fórmula que está más arriba, ME = 1048576 * 200 / 166000000 = 1,2633.
Multiplicando por 256, resulta 256 ME = 256 * 1,2633 = 323 = 143h.
Haciendo una tabla de múltiplos de 143h:
Múltiplo de 143h | Tomar entrada | Valor de la tabla |
---|---|---|
0000h | 00h | 7Fh |
0143h | 01h | 82h |
0286h | 02h | 85h |
03C9h | 03h | 88h |
050Ch | 05h | 8Fh |
064Fh | 06h | 92h |
0792h | 07h | 95h |
08D5h | 08h | 98h |
0A18h | 0Ah | 9Eh |
0B5Bh | 0Bh | A1h |
0C9Eh | 0Ch | A4h |
0DE1h | 0Dh | A7h |
0F24h | 0Fh | AAh |
..... | ... | ... |
FEDEh | FEh | 79h |
0021h | 00h | 7Fh |
0164h | 01h | 82h |
Nótese que la suma se realiza con 16 bits. Los bits de mayor orden se descartan, pues sólo indican ciclos completos. Como la señal es periódica, no nos interesa en qué ciclo estamos.
Si se desean valores más exactos, se puede multiplicar el número por 65536 en vez de por 256, aunque esta precisión alcanza para este ejercicio.
Una vez que se conocen las entradas, se toman los valores que indica la tabla y se suman entre sí los tres valores. Como esta suma puede valer entre 00h y 3*FEh = 2FAh, habrá que dividir la suma por este número para determinar el ciclo de trabajo del pulso.
Escribir dos programas en assembler, uno llamado CLIENTE y otro SERVIDOR que correrán en dos PC diferentes, unidas entre sí por el puerto serie.
El programa SERVIDOR deberá tener una tabla con nombres y contraseñas.
El programa CLIENTE, cuando arranque, pedirá un nombre y una contraseña (que no se debe ver en la pantalla). Este le enviará la información al servidor, que le indicará si la combinación nombre-contraseña se encuentra disponible.
En caso afirmativo se deberá mostrar en pantalla (tanto en el cliente como en el servidor) el texto:
El cliente xxxx ingresó al sistema.
.
En caso negativo se deberá mostrar (sólo en el cliente):
Combinación nombre-contraseña inválida. Acceso denegado.
Una vez que el cliente ingresó al sistema, entra en modo interactivo, de esta manera el usuario puede ingresar comandos dentro de la aplicación. El programa dispone de tres comandos:
READ nombre_de_archivo
: En este caso el servidor deberá mostrar el texto El cliente xxxx está leyendo el archivo nombre_de_archivo.
y se deberá realizar la transferencia. Una vez terminada el programa CLIENTE pide otro comando.
WRITE nombre_de_archivo
: En este caso el servidor deberá mostrar el texto El cliente xxxx está escribiendo el archivo nombre_de_archivo.
y se deberá realizar la transferencia. Una vez terminada el programa CLIENTE pide otro comando.
BYE
: Tanto el cliente como el servidor deberán mostrar en la pantalla Fin de conexión
y se deben terminar ambos programas.
La interfaz de bajo nivel entre ambos extremos de la comunicación deberá ser diseñado por el grupo.
a) Dibujar un circuito esquemático para conectar un conversor analógico/digital de 8 entradas y 12 bits al bus ISA.
b) Escribir un programa que, luego de leer los valores máximos y mínimos permitidos de los conversores de un archivo (el formato de este archivo puede ser definido libremente por el grupo), comience a leer los valores de los conversores.
El programa deberá medir el tiempo en segundos en que los diferentes canales tengan vlores fuera de rango, y cuando vuelven a estar en el rango, deberán mostrar el siguiente texto o textos similares en la impresora:
El canal 3 superó el máximo permitido por 12 segundos.
Nótese que varios conversores pueden tener valores fuera de rango simultáneamente.