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.