loop ensamblador audio assembly timer x86-16 sound-synthesis

audio - loop - dup ensamblador



Cómo tocar los acordes en ASM 8086? (1)

Quiero saber cuál es la mejor manera de jugar más de 1 nota en el momento del montaje. Si puede, agregue un procedimiento que explique su respuesta. ¡Gracias!


Naranja, el siguiente código es un programa hecho hace mucho tiempo en EMU8086 y Windows XP (se ejecutó en ese momento). Ahora tengo Windows 8 64 bits y ya no se ejecuta. Le daré el código porque puede ser útil. Todos los nombres y comentarios están en español porque soy costarricense, pero el código de ensamblador es universal (el traductor de Google te dará una mano):

.model small .stack 100h .data ;---------------------------------------------------------------------------- MENSAJEPLAY DB '' PROYECTO ® PIANO ¯'',13,10 DB 13,10 DB '' LAS TECLAS DE LAS NOTAS VAN EN EL ORDEN SIGUIENTE:'',13,10 DB 13,10 DB '' 2 3 5 6 7'' ,13,10 DB '' q w e r t y u'',13,10,13,10 DB 13,10 DB '' s d g h j'' ,13,10 DB '' z x c v b n m'',13,10,13,10 DB '' PARA TERMINAR PRESIONE ESC'',''$'' ;---------------------------------------------------------------------------- .code TONO MACRO NUMERO ;Esta macro recibe el tono MOV BX,NUMERO ;y manda a llamar a los procedimientos CALL BOCINA ENDM ;---------------------------------------------------------------------------- CLRSCR PROC ;Limpia la pantalla MOV AH,6 XOR AL,AL XOR CX,CX MOV DX,184FH MOV BH,13 INT 10H RET ENDP ;---------------------------------------------------------------------------- BocinaOn PROC ;Activa la bocina IN AL, 61h OR AL, 11B OUT 61h, AL RET BocinaOn ENDP ;---------------------------------------------------------------------------- BocinaOff PROC ;Desactiva la bocina IN AL, 61h AND AL, 11111100b OUT 61h, AL RET BocinaOff ENDP ;---------------------------------------------------------------------------- Ajustar PROC ;Ajusta la bocina con la frecuencia dada PUSH BP MOV BP, SP MOV DX, 18 MOV AX, 13353 MOV BX, [BP + 4] DIV BX MOV BX, AX MOV AL, 0B6h OUT 43h, AL ;ENVIAR AL PUERTO LA FRECUENCIA EN DOS BYTES POR SEPARADO. MOV AX, BX OUT 42h, AL ;ENVIA PRIMER BYTE. (PUERTO PARALELO = 378H) MOV AL, AH OUT 42h, AL ;ENVIA SEGUNDO BYTE. (PUERTO SERIAL = 3F8H) POP BP RET Ajustar ENDP ;---------------------------------------------------------------------------- Suena proc ;Activa la bocina y coloca el nombre de CALL bocinaON ;la tecla. MOV AX,40H MOV ES,AX MOV DX,ES:[006EH] MOV AX,ES:[006CH] ADD AX,7 ADC DX,0 ;Se le suma 7 unidades a ese valor CLIC: CMP DX,ES:[006EH] ;Y se compara hasta que sean iguales JB FINI ;Pasando por un ciclo, cuando llegen JA CLIC ;a ser iguales se sale del ciclo y CMP AX,ES:[006CH] JA CLIC FINI: CALL BocinaOff ;Se desconecta la bocina y regresa. RET Suena endp ;---------------------------------------------------------------------------- Bocina proc ;Este procedimiento guarda AX y BX en PUSH BX ;la pila para no perder su valor, con MOV AX, BX ;esto llama a ajusta y a suena PUSH AX CALL Ajustar ;Pone la frecuencia en el puerto. POP AX POP BX CALL SUENA ;Activa el speaker y lo desactiva. ret Bocina endp ;---------------------------------------------------------------------------- ;CONVERTIR A MINUSCULA SI ERA MAYUSCULA MINUSCULA PROC CMP AL, 65 ;''A'' JB CONTINUAR ;SI LA TECLA ES MENOR QUE LA ''A'' NO HACE NADA CMP AL, 90 ;''Z'' JA CONTINUAR ;SI LA TECLA ES MAYOR QUE LA ''Z'' NO HACE NADA ADD AL, 32 ;Convierte may£scula en min£scula. CONTINUAR: RET MINUSCULA ENDP ;---------------------------------------------------------------------------- ;CAPTURA LA TECLA CON LA NOTA QUE EL USUARIO DESEA. TECLA PROC MOV AH,8 ;Si la hay, obtiene la nota INT 21H CALL MINUSCULA RET TECLA ENDP ;---------------------------------------------------------------------------- ;Cicla el programa hasta que el usuario presione la tecla ESC. ;El procedimiento reacciona a las teclas indicadas en el segmento de datos. ;Cualquier otra tecla es ignorada. ;La tecla presionada es convertida a min£scula, ya que la tabla ASCII ;trata distinto unas de otras. ;Despu‚s de que cada tecla es presionada, el ciclo vuelve al inicio y ;se repite. ;Si la tecla presionada corresponde a una nota musical, el c¢digo ;correspondiente es enviado al parlante. SPEAKER PROC COMIENZA: CALL TECLA CMP AL,''q'' ;DO alto JNE S1 ;SI NO ES LA TECLA ESPERADA, SALTA PARA VERIFICAR LA SIGUIENTE. TONO 523 ;SI ES LA TECLA ESPERADA, GENERA EL SONIDO CORRESPONDIENTE JMP COMIENZA ;DESPUES DEL SONIDO REINICIA PARA ESPERAR OTRO SONIDO. S1: CMP AL,''w'' ;RE alto JNE S2 TONO 587 JMP COMIENZA S2: CMP AL,''e'' ;MI alto JNE S3 TONO 659 JMP COMIENZA S3: CMP AL,''r'' ;FA alto JNE S4 TONO 698 JMP COMIENZA S4: CMP AL,''t'' ;SOL alto JNE S5 TONO 784 JMP COMIENZA S5: CMP AL,''y'' ;LA alto JNE S6 TONO 880 JMP COMIENZA S6: CMP AL,''u'' ;SI alto JNE S8 TONO 988 JMP NOSALTO1 SALTO1: JMP COMIENZA NOSALTO1: JMP COMIENZA S8: CMP AL,''2'' ;DO# alto JNE S9 TONO 554 JMP COMIENZA S9: CMP AL,''3'' ;RE# alto JNE S10 TONO 622 JMP COMIENZA S10: CMP AL,''5'' ;FA# alto JNE S11 TONO 740 JMP COMIENZA S11: CMP AL,''6'' ;SOL# alto JNE S12 TONO 830 JMP COMIENZA S12: CMP AL,''7'' ;SIb alto JNE S13 TONO 923 JMP COMIENZA S13: CMP AL,''z'' ;DO bajo JNE S14 TONO 261 JMP COMIENZA S14: CMP AL,''x'' ;RE bajo JNE S15 TONO 293 JMP COMIENZA S15: CMP AL,''c'' ;MI bajo JNE S16 TONO 329 JMP NOSALTO2 SALTO2: JMP SALTO1 NOSALTO2: JMP COMIENZA S16: CMP AL,''v'' ;FA bajo JNE S17 TONO 349 JMP COMIENZA S17: CMP AL,''b'' ;SOL bajo JNE S18 TONO 392 JMP COMIENZA S18: CMP AL,''n'' ;LA bajo JNE S19 TONO 466 JMP COMIENZA S19: CMP AL,''m'' ;SI bajo JNE S20 TONO 498 JMP COMIENZA S20: CMP AL,''s'' ;DO# bajo JNE S21 TONO 277 JMP COMIENZA S21: CMP AL,''d'' ;RE# bajo JNE S22 TONO 311 JMP COMIENZA S22: CMP AL,''g'' ;FA# bajo JNE S23 TONO 370 JMP COMIENZA S23: CMP AL,''h'' ;SOL# bajo JNE S24 TONO 415 JMP COMIENZA S24: CMP AL,''j'' ;SIb bajo JNE S25 TONO 515 JMP COMIENZA S25: CMP AL,27 ;27 = tecla ESC (terminar). JNE SALTO2 RET SPEAKER ENDP ;---------------------------------------------------------------------------- MENSAJE PROC MOV AH,9 LEA DX,MENSAJEPLAY INT 21H RET MENSAJE ENDP ;---------------------------------------------------------------------------- EMPIEZA: MOV AX, @data ;se mandan llamar todos los MOV DS, AX ;procedimientos CALL CLRSCR ;Limpiar pantalla. CALL MENSAJE ;Despliega la explicaci¢n del programa. CALL SPEAKER ;Sonidos. MOV AX, 4C00H INT 21H ;---------------------------------------------------------------------------- END EMPIEZA

Lo que hace es mostrarle las teclas para presionar para que las notas suenen. Puede abrirlo en EMU8086 y ejecutarlo, pero las interrupciones de los parlantes se comportan de forma extraña debido a Windows 8.

Orange acaba de editar la pregunta, ahora quiere que toquen notas simultáneas. Bueno, mi código no hace eso, reproduce una nota a la vez. Para dos o más notas para tocar al mismo tiempo, necesitaríamos hilos o procesos que se ejecuten de esa manera.

No estoy seguro de que el ensamblador pueda hacer eso, ni siquiera está seguro si el altavoz, controlado por una interrupción, puede hacerlo. Esto se debe a que algo llamado "reentrada", o algo así, se refiere al problema causado cuando se ejecuta una interrupción cuando ya se está ejecutando, generalmente el programa se detiene cuando ocurre.