SPKR TUT



#Start Contents

Programowanie glosniczka w asemblerze

Czy nie myslicie czasem, jakby to bylo, gdyby mozna bylo wzbogacic
swoj program oprocz efektu wizualnego, takze o efekt dzwiekowy?
Programowanie kart dzwiekowych (zwlaszcza tych nowoczesnych) moze
sprawiac niemale klopoty. Stary, poczciwy PC-Speaker jest jednak
urzadzeniem wzglednie prostym w programowaniu.
I to wlasnie tutaj udowodnie. Najpierw troszke teorii, potem - do
dziela!
Sporo urzadzen w komputerze ma wlasne porty, przez ktore mozna sie z
nimi komunikowac. Jednak glosniczek komputerowy nie ma wlasnego
portu.
Jest tak przede wszystkim ze wzgledu na oszczednosci w budowie
pierwszych PC-tow. Zamiast dac osobny port na glosnik, firmy
produkujace komputery wcisnely go "pod opieke" dwoch innych urzadzen:
* czasomierza systemowego, ktory posluzy nam do wytworzenia
impulsow odpowiedniej czestotliwosci
* kontrolera klawiatury, ktory kontroluje, czy jest otwarty "kanal"
z czasomierza do glosniczka, czyli czy mozna bedzie wysylac
informacje.

Podstawowe porty czasomierza to porty od 40h do 43h (caly zakres to
40h - 5fh, "h" oznacza "szesnastkowo"), kontrolera klawiatury zas -
60h do 64h (caly zakres: 60h - 6fh).
Nie bedziemy ich jednak wszystkich uzywac. Beda na interesowac tylko
porty 42h, 43h i 61h.
Zacznijmy wiec cos pisac:
in al,61h
or al,3
out 61h,al

Co zrobilismy? W spisie portow Listy Przerwan Ralfa Brown'a czytamy:
(przeskocz port 61h)
0061 R- KB controller port B control register (ISA, EISA)
0061 -W KB controller port B (ISA, EISA)

(R - czytanie (read) , W - pisanie (write))

oraz:
(przeskocz opis portu 61h)
Bitfields for KB controller port B (system control port) [output]:
Bit(s) Description (Table P0392)
7 pulse to 1 for IRQ1 reset (PC,XT)
6-4 reserved
3 I/O channel parity check disable
2 RAM parity check disable
1 speaker data enable
0 timer 2 gate to speaker enable

Komenda IN AL,61h czyta biezacy status kontrolera, OR AL,3 ustawia
(wlacza) bity 0 (wlaczenie bramki do glosniczka) oraz 1 (wlaczenie
mozliwosci wysylania danych do glosniczka), OUT 61h,AL zapisuje nowy
status do kontrolera.
Glosniczek jest wlaczony. Trzeba mu podac jakis sygnal. Do tego
posluzy nam czasomierz. W spisie portow czytamy:
(przeskocz opis portow 42h i 43h)
0042 RW PIT counter 2, cassette & speaker

0043 RW PIT mode port, control word register for counters 0-2
Once a control word has been written (43h), it must be followed
immediately by performing the corresponding action to the counter
registers (40h-42h), else the system may hang!!

Do portow tych nie bedziemy wysylac jednak czestotliwosci, ktora
chcemy uzyskac. Czasomierz pracuje na czestotliwosci 1193181
(1234DDh) Hz i to te wartosc dzielimy przez zadana czestotliwosc, a
wynik wysylamy do odpowiednich portow.
Piszmy wiec:
(przeskocz wlaczanie glosniczka)
mov bx,440h ; Standardowy dzwiek A, 440 Hz
mov dx,12h ; gorna czesc liczby 1234dd
mov ax,34ddh ; dolna czesc liczby 1234dd
div bx ; ax = wartosc do wyslania

push ax
mov al,0b6h
out 43h,al

pop ax
out 42h,al
mov al,ah
out 42,al

No i co my tutaj znowu zrobilismy?
4 pierwsze komendy to oczywiscie uzyskanie wartosci do wyslania na
port, ale reszta?
Najpierw: 0b6h = 1011 0110
Bity 7 i 6 = 10 = wybierz (standardowo niezajety) czasomierz nr 2
(lacznie sa 3: zegar czasu rzeczywistego, czasomierz odswiezania
pamieci RAM i ten trzeci, nieuzywany)
Bity 5 i 4 = 11 = zapisujemy do czasomierza najpierw mlodsze bity
(0-7) wartosci, potem starsze (8-15)
Bity 3-1 = 011 = wybierz tryb nr 3, czyli generator fali kwadratowej
Bit 0 = 0 = licznik binarny 16-bitowy.
Zgodnie z tym, najpierw wysylamy mlodszy bajt, AL a potem starszy,
AH.

Skoro na port mozna wyslac najwieksza wartosc 0ffffh (teoretycznie
najwieksza jest 10000h, obcinana do 0000h), to jakiej odpowiada to
czestotliwosci?
1234dd / 10000h to ok. 12h, czyli 18. A dokladniej jest to cos okolo
18,2 Hz - standardowa czestotliwosc zegara w komputerze (aby
odmierzyc 1 sekunde trzeba ok 18 tykniec tego zegara)
Nasz glosniczek juz gra. Teraz trzeba sprawic, bo to troszke
potrwalo. Pomocne bedzie przerwanie 15h, funkcja 86h:
mov cx,0fh
mov dx,4240h
mov ah,86h
int 15h ; pauza o dlugosci CX:DX mikrosekund

I dzwiek trwa 1 sekunde (F4240h = 1.000.000). Teraz trzeba go
wylaczyc. Nic prostszego. Po prostu zamkniemy przejscie miedzy
czasomierzem a glosniczkiem:
in al,61h
and al,not 3 ; zerujemy bity 0 i 1
; NASM: "and al,~3"
out 61h,al

Mam nadzieje, ze podalem wystarczajaco informacji, abyscie
samodzielnie zaczeli programowac glosniczek. Jesli mi sie nie udalo,
to zawsze mozecie skorzystac z gotowej procedury z mojej biblioteki.
To juz koniec. Milej zabawy!

Spis tresci off-line (Alt+1)
Spis tresci on-line (Alt+2)
Ulatwienia dla niepelnosprawnych (Alt+0)


Wyszukiwarka

Podobne podstrony:
DOS SPKR TUT
SPKR TUT
SPKR TUT
ART121 tut 2
phys tut 08
phys tut 12
DOS DIOD TUT
SYS TUT
ART121 tut 3
MYSZ TUT
PWR TUT
GRAF TUT
tut?2 sdram vhdl
tut?bug hardware vhdlDE2
BIBL TUT
PWR TUT
SYS TUT

więcej podobnych podstron