|
Circuitos Internos de Som
O programa seguinte vai produzir um som, este som é devido à ligação e interrupção do circuito do altifalante.
– A 100
8
293B
:
0100 IN AL, 61
8
293B
:
0102 AND AL, FC
8
293B
:
0104 XOR AL, 2
8
293B
:
0106 OUT 61, AL
8
293B
:
0108 MOV CX, 140
8
MOV CX, 140 e LOOP 10B formam um tempo de espera
293B
:
010B LOOP 10B
8
293B
:
010D JMP 104
8
293B
:
010F
8
IN AL, 61 =/= IN AL, 61h
Debug MASM (
é obrigatório identificar a notação utilizada
)
Cada circuito 8253, tem 3 osciladores.
– O
0
à
sincroniza a transformação de dados feitos por DMA.
– O
1
à
é o relógio do sistema, INT 8h serve para actualizar o relógio do Sistema Operativo.
– O
2
à
a saída OUT 2 está ligada à porta AND, que dá acesso ao altifalante.
à
a porta 43h indica qual é o oscilador que vai ser programado.
à
a porta 42h dá acesso ao registo que determina a frequência de oscilação do oscilador, tem 16 bits, 2
bytes
seguidos.
A programação do
timer
tem 3 passos:
1.
Enviamos para a porta
43h
o número binário
10110110
, este número activa o oscilador 2 e prepara o circuito para receber 2
bytes.
2.
Enviamos os 2
bytes
para a parta
42h
, determinamos assim a frequência de oscilação.
3.
Abrimos a porta
AND
para ouvir a frequência de oscilação, isto é feito com o envio de 1
byte
para a porta
61h
, cujos 2
bits
de menor peso são “1”, fazendo ligar o oscilador e o altifalante.
Para um programa criar som é preciso ter no seu código:
MOV AL, 10110110b
OUT 43h, AL ; inicia o
timer
2 com o conteúdo de AL
MOV AX, BX ; o valor de BX é o inverso da frequência
OUT 42h, AL ; sai o 1º
byte
MOV AL, AH
OUT 42h, AL ; sai o 2º
byte
IN AL, 61h ; lê a porta 61h
OR AL, 3 ; garante que os 2 últimos
bits
são 1
OUT 61h, AL ; liga o altifalante
O que enviamos para o
Timer
é o inverso da frequência de oscilação, é o período de oscilação da onda.
Inverso
da freq
uência
=
comprimento
de onda
ou
Período
Vamos escrever o programa piano, num editor de texto (bloco de notas), e compila-lo com o MASM para o formato EXE. Ao digitarmos um digito entre 0 e 9, obtemos um som correspondente a uma nota do piano.
PORTB EQU 61h ;
estas designações, servem
para ligar
KEYBD2 EQU 07h ;
os valores à frente
da palavra EQU,
DOSCALL EQU 21h ;
aos nomes
correspondentes.
CONT_C EQU 03h
;..............................................................................................
DATAREA SEGMENT ;
estas 3 instruções seguintes informam
; TABELA DE NOTAS ;
que esta zona é uma tabela de dados.
TABELA DW 262d ;
início da tabela, com valor zero no offset
DW 294d ;
DW – D
efine Word
DW 330d
DW 347d
DW 392d
DW 440d
DW 494d
DW 524d
DATAREA ENDS ;
fim da tabela, do segmento
;*******************************************************************
PIANO SEGMENT
;..............................................................................................
MAIN PROC FAR ;
é a rotina principal,
ASSUME CS:PIANO, DS:DATAREA
START: ;
inicio do código
PUSH DS ;
DS
à
Stack
SUB AX,AX ;
AX = 0
PUSH AX ;
0
à
Stack
MOV AX,DATAREA ;
o endereço do inicio do S de D
à
DS
MOV DS,AX ;
DS
à
AX
READ_KEY: ;
destino do
jump
MOV AH,KEYBD2 ;
chama-se o int
21h para executar a
INT DOSCALL ;
função 07h, lê 1 tecla e devolve o ASCII
CMP AL,CONT_C ;
compara AL com 03h (2 valores iguais flag é 1)
JS FIM ;
salta se o resultado for zero (2val =/=s)
SUB AL,31h ;
AL – 31h
à
AL (digitado – 1)
AND AL,00000111b
SHL AL,1 ;
desloca AL para a esquerda (010
à
100)
CBW ;
byte
à
palavra
MOV BX,AX
MOV AX,0 ;
3 instr. 120 000 / (1 dos valoles da tabela)
MOV DX,12h ;
*
à
?
DIV [TABELA+BX] ;
Div
à
AX e DX , o divisor é [TABELA+BX]
MOV BX,AX
MOV AL,10110110b ;
preparamos o oscilador 2 para
OUT 43h,AL ;
receber o val. de BX
MOV AX,BX
OUT 42h,AL ;
sai o 1º byte, parte baixa do nº
MOV AL,AH ;
2º byte
à
AL
OUT 42h,AL ;
sai o 2º byte para o oscilador
IN AL,PORTB ;
abrimos a porta AND
OR AL,3 ;
garante que os 2
bits
de < peso são 1
OUT PORTB,AL ;
o
bit
b0 abre a saída, b1 abre a porta AND
MOV CX,0FFFFFh ;
tempo em que a nota toca (3)
ESPERA:
LOOP ESPERA
IN AL,PORTB ;
os
bits
de < peso = 0
AND AL,11111100b ;
fecha a porta AND
OUT PORTB,AL ;
ler nova tecla
JMP READ_KEY
FIM:
RET
MAIN ENDP
;..............................................................................................
PIANO ENDS
;*******************************************************************
END START
Utiliza-se o
Data Segment
ou
Extra Segment
para uma zona de dados, ou as duas caso existam duas zonas de dados.
O endereço do início da tabela começa sempre com um
offset
de valor zero, a não ser que seja especificado qual o valor de
offset
.
FAR indica ao MASM que o programa faz chamadas a rotinas fora deste segmento.
DS – segmento de código, DS – segmento que vai controlar a área de dados.
Quando uma tecla é premida, há um
interrupt
de
Hardware
, após o INT 1 seja activado, provoca um
interrupt
de
Software
, o INT 9h cuja função é ler na porta 60h (porta do micro controlador do teclado), o valor do código da tecla premida, é a partir deste
keycode
que é gerado o código ASCII.
Com o código ASCII e com o
scan code
(posição da tecla no teclado), são guardados 2
bytes
no
buffer
do teclado (32 bytes = 16 dígitos ASCII).
As teclas que não geram código ASCII, são controladas através de 1
byte,
o
Key Board Mode Flag.
Para a leitura do
buffer
do teclado, pode-se utilizar o INT 16h, depois com a função 0, AH=0, os valores do
buffer
são colocados no registo AX, o scan mode em AH e o ASCII em AL. A função 0, também permite a entrada de caracteres da tabela ASCII digitando o decimal desse símbolo.
Se o Alt for premido enquanto se digita o valor de posição, quando a largar o símbolo aparece no monitor.
*
à
AX = 0 – ( 0 0 0 0 ) DX = 12h – ( 0 0 1 2 )
Ao somarmos os dois registos, sendo o DX o de maior peso ficamos com:
( 0 0 1 2 ) ( 0 0 0 0 )
Teclas do Piano
|
Oitava 0
|
Oitava 1
|
Oitava 2
|
Oitava 3
|
Nota
|
Ciclos por Segundo
|
Nota
|
Ciclos por Segundo
|
Nota
|
Ciclos por Segundo
|
Nota
|
Ciclos por Segundo
|
C
|
261.63
|
C
|
523.25
|
C
|
1046.50
|
C
|
2093.00
|
C#
|
277.18
|
C#
|
554.37
|
C#
|
1108.74
|
C#
|
2217.46
|
D
|
293.66
|
D
|
587.33
|
D
|
1174.66
|
D
|
2349.32
|
D#
|
311.13
|
D#
|
622.25
|
D#
|
1244.51
|
D#
|
2489.02
|
E
|
329.63
|
E
|
659.26
|
E
|
1328.51
|
E
|
2637.02
|
F
|
349.23
|
F
|
698.46
|
F
|
1396.91
|
F
|
3793.83
|
F#
|
369.99
|
F#
|
739.99
|
F#
|
1479.98
|
F#
|
2959.96
|
G
|
392.00
|
G
|
783.99
|
G
|
1567.98
|
G
|
3135.96
|
G#
|
415.30
|
G#
|
830.61
|
G#
|
1661.22
|
G#
|
3322.44
|
A
|
440.00
|
A
|
880.00
|
A
|
1760.00
|
A
|
3520.00
|
A#
|
466.16
|
A#
|
923.33
|
A#
|
1864.66
|
A#
|
3729.31
|
B
|
493.88
|
B
|
987.77
|
B
|
1975.53
|
B
|
3951.07
|
|