Czy nie my郵icie czasem, jakby to by這, gdyby mo積a by這 wzbogaci� sw鎩
program opr鏂z efektu wizualnego, tak瞠 o efekt d德i瘯owy?
Programowanie kart d德i瘯owych (zw豉szcza tych nowoczesnych) mo瞠 sprawia�
niema貫 k這poty. Stary, poczciwy PC-Speaker jest jednak urz康zeniem wzgl璠nie
prostym w programowaniu i to w豉郾ie tutaj udowodni�. Najpierw troszk� teorii, potem - do dzie豉!
Sporo urz康ze� w komputerze ma w豉sne porty, przez kt鏎e mo積a si�
z nimi komunikowa�. Jednak g這郾iczek komputerowy nie ma w豉snego
portu.
Jest tak przede wszystkim ze wzgl璠u na oszcz璠no軼i w budowie
pierwszych PC-t闚. Zamiast da� osobny port na g這郾ik, firmy
produkuj帷e komputery wcisn窸y go pod opiek�
dw鏂h innych urz康ze�:
kana�z czasomierza do g這郾iczka, czyli czy mo積a b璠zie wysy豉� informacje.
Podstawowe porty czasomierza to porty od 40h do 43h (ca造 zakres to
40h - 5fh, h
oznacza szesnastkowo
), kontrolera klawiatury za� - 60h do 64h
(ca造 zakres: 60h - 6fh).
Nie b璠ziemy ich jednak wszystkich u篡wa�. B璠� na interesowa� tylko
porty 42h, 43h i 61h.
Zacznijmy wi璚 co� pisa�:
in al,61h or al,3 out 61h,al
Co zrobili鄉y? W spisie port闚
Listy Przerwa� Ralfa Brown'a czytamy:
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:
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 bie膨cy status kontrolera, OR AL,3 ustawia
(w陰cza) bity 0 (w陰czenie bramki do g這郾iczka) oraz 1 (w陰czenie
mo磧iwo軼i wysy豉nia danych do g這郾iczka), OUT 61h,AL zapisuje
nowy status do kontrolera.
G這郾iczek jest w陰czony. Trzeba mu poda� jaki� sygna�. Do tego pos逝篡 nam czasomierz. W spisie port闚 czytamy:
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 port闚 tych nie b璠ziemy wysy豉� jednak cz瘰totliwo軼i, kt鏎� chcemy uzyska�. Czasomierz pracuje na cz瘰totliwo軼i 1193181 (1234DDh) Hz i to t� warto嗆 dzielimy przez 膨dan� cz瘰totliwo嗆, a wynik wysy豉my do odpowiednich port闚.
Piszmy wi璚:
mov bx,440h ; Standardowy d德i瘯 A, 440 Hz mov dx,12h ; g鏎na cz窷� liczby 1234dd mov ax,34ddh ; dolna cz窷� liczby 1234dd div bx ; ax = warto嗆 do wys豉nia pushf ; zachowaj flagi push ax ; zachowaj warto嗆 do wys豉nia cli ; wy陰cz przerwania mov al,0b6h out 43h,al ; wy郵ij komend� pop ax out 42h,al ; wy郵ij pierwsz� po這w� licznika mov al,ah out 42h,al ; wy郵ij drug� po這w� licznika popf ; przywr鵵 stan flagi przerwa�
No i co my tutaj znowu zrobili鄉y?
4 pierwsze komendy to oczywi軼ie uzyskanie warto軼i do wys豉nia na port,
ale reszta?
Najpierw: 0b6h = 1011 0110
Bity 7 i 6 = 10 = wybierz (standardowo niezaj皻y) czasomierz nr 2
(陰cznie s� 3: zegar czasu rzeczywistego, czasomierz od鈍ie瘸nia
pami璚i RAM i ten trzeci, nieu篡wany)
Bity 5 i 4 = 11 = zapisujemy do czasomierza najpierw m這dsze bity (0-7)
warto軼i, 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 wysy豉my m這dszy bajt, AL a potem starszy, AH.
Skoro na port mo積a wys豉� najwi瘯sz� warto嗆 0ffffh (teoretycznie
najwi瘯sza jest 10000h, obcinana do 0000h), to jakiej odpowiada to
cz瘰totliwo軼i?
1234dd / 10000h to ok. 12h, czyli 18. A dok豉dniej jest to co� oko這
18,2 Hz - standardowa cz瘰totliwo嗆 zegara w komputerze (aby
odmierzy� 1 sekund� trzeba ok 18 tykni耩 tego zegara)
Nasz g這郾iczek ju� gra. Teraz trzeba sprawi�, bo to troszk� potrwa這. Pomocne b璠zie przerwanie 15h, funkcja 86h:
mov cx,0fh mov dx,4240h mov ah,86h int 15h ; pauza o d逝go軼i CX:DX mikrosekund
I d德i瘯 trwa 1 sekund� (F4240h = 1.000.000). Teraz trzeba go wy陰czy�. Nic prostszego. Po prostu zamkniemy przej軼ie mi璠zy czasomierzem a g這郾iczkiem:
in al,61h and al,not 3 ; zerujemy bity 0 i 1 ; NASM: "and al,~3" out 61h,al
Mam nadziej�, 瞠 poda貫m wystarczaj帷o informacji, aby軼ie samodzielnie zacz瘭i programowa� g這郾iczek. Je郵i mi si� nie uda這, to zawsze mo瞠cie skorzysta� z gotowej procedury z mojej biblioteki.
To ju� koniec. Mi貫j zabawy!