Tajemnice ATARI

Piszemy DEMO


   

Ostatnim razem zakończyliśmy zmagania nad grafika naszego komputera. Tym razem zajmiemy się dźwiękiem.

    Najprostsze dźwięki można osiągnąć wykorzystując rejestr Consol ($D01F), bez użycia generatorów dźwiękowych Atari. Podstawowym zadaniem tego rejestru jest obsługa trzech klawiszy konsoli. Trzy najmłodsze bity odzwierciedlają stan klawiszy: Start (bit 0), Select (bit 1) i Option (bit 2), przy czym bit zgaszony oznacza, że klawisz został wciśnięty. Na temat innych bitów rejestru Consol nie znaleźliśmy żadnych informacji w dostępnych nam źródłach. Okazuje się jednak, że przy pomocy bitu 3 można wygenerować dźwięk, zmieniając jego stan okresowo. Demonstruje to poniższy program:
Procedure Equ $8800

List_mem  Equ %00000110 
List_err  Equ %00000101 
Code_mem  Equ %00010000 
Code_dsk  Equ %00100000

Consol    Equ $D01F

        Opt List_err+Code_mem
          Org Procedure

          Ldx #$00
          Txa 
L1        Eor #$0F
          Sta Consol
          Ldy #$00 
L2        Dey
          Bne L2
          Inx
          Bne L1
          Rts

          End of File
    Łatwo zauważyć, że nie można dokładnie określić częstotliwości generowanego tym sposobem dźwięku. Możliwość określenia głośności, wysokości i stopnia zniekształcenia dźwięku dają dopiero cztery niezależne generatory dźwięku. Każdy z nich posiada dwa rejestry kontrolne. Pierwszy rejestr, o nazwie AUDFx {x - numer kanału 1-4), określa częstotliwość pracy danego generatora. Standardowo częstotliwość dźwięku mierzy się w Hz. W naszym przypadku mamy do dyspozycji tylko jeden bajt i aby wygenerować odpowiedni dźwięk trzeba skorzystać z zależności:

częstotliwość = 31960/(x+1),

gdzie x to bajt wysyłany do AUDF. Natomiast rejestr drugi o nazwie AUDCx (gdzie x oznacza również nr kanału), określa głośność i stopień zniekształcenia dźwięku. Bity 0-3 tego rejestru określają głośność dźwięku, bitem czwartym zajmiemy się później, natomiast bity 5-7 sterują zniekształceniami dźwięku. Najwyższa pora, aby podać adresy wszystkich ośmiu rejestrów:

AUDF1 - częst. pracy generatora 1
AUDC1 - sterowanie generatorem 1
AUDF2 - częst. pracy generatora 2
AUDC2 - sterowanie generatorem 2
AUDF3 - częst. pracy generatora 3
AUDC3 - sterowanie generatorem 3
AUDF4 - częst. pracy generatora 4
AUDC4 - sterowanie generatorem 4

    Rejestry te zajmują w pamięci lokacje $D200 - $D207 i wszystkie są rejestrami sprzętowymi, które przy odczycie pętała mną funkcję.

    Poniższy przykład odgrywa dźwięki o losowej częstotliwości, wykorzystując generator 1.
Procedure Equ $8800

List_mem  Equ %00000110 
List_err  Equ %00000101 
Code_mem  Equ %00010000
Code_dsk  Equ %00100000

Audc1     Equ $D201 
Audf1     Equ $D200 
Kbcodes   Equ $02FC 
Random    Equ $D20A 
Rtclok    Equ $12

        Opt List err+Code_mem
          Org Procedure

L1        Lda Random
          Sta Audf1
          Lda #$AA
          Sta Audc1
          Lda Rtclok+$02
L2        Cmp Rtclok+$02
          Beq L2
          Lda Kbcodes
          Bmi L1
          Lda #$00
          Sta Audc1
          Rts

          End of File
    Kolejny przykład produkuje dźwięki na dwóch generatorach. Jeden ze wzrastającą częstotliwością, drugi z malejącą.
Procedure Equ $8800
List_mem  Equ %00000110 
List_err  Equ %00000101
Code_mem  Equ %00010000 
Code_dsk  Equ %00100000

Audcl     Equ $D201 
Audc2     Equ $D203 
Audfl     Equ $D200 
Audf2     Equ $0202
Kbcodes   Equ $02FC 
Random    Equ $D20A
Rtclok    Equ $12

        Opt List_err+Code_main
          Org Procedure

          Ldx #$00
          Ldy #$FF 
L1        Lda #$AA
          Stx Audfl
          Sty Audf2
          Sta Audcl
          Sta Audc2
          Lda Rtclok+$02 
L2        Cmp Rtclok+$02
          Beq L2
          Inx
          Dey
          Bne L1
          Sty Audcl
          Sty Audc2
          Rts
    
          End of File
    Oba zaprezentowane przykłady generują czyste dźwięki, bez zniekształceń. Dźwięk czysty otrzymujemy, jeśli bity 5-7 AUDCx ustawione są w następujący sposób: 101 lub 111. Przy innym ustawieniu bitów, np. 100 lub 011, otrzymuje się dźwięk zniekształcony.

    Bit 4 AUDCx zwany jest dwustanowym bitem regulacji głośności lub kontrolą siły głosu bez modulacji. Głośnik wytwarza dźwięk przez drgania membrany. Czwarty bit AUDCx umożliwia właśnie poruszanie membraną głośnika w przód i w tył. W ten sposób wytworzyć można również ciekawe dźwięki. Jak w przykładzie poniżej:
Procedure Equ $8800
List_mem  Equ %00000110 
List_err  Equ %00000101
Code_mem  Equ %00010000
Code_dsk  Equ %00100000

Audcl     Equ $D201 
Kbcodes   Equ $02FC 
Rtclok    Equ $12

        Opt List_err+Code_mem
          Org Procedure

L1        Ldx #$0A 
L2        Lda Tabela,x
          Sta Audcl
          Jsr Opoz
          Lda #$00
          Sta Audcl
          Jsr Opoz
          Dex
          Bpl L2
          Lda Kbcodes
          Bmi L1
          Rts

Opoz      Ldy Rtclok+$02
L3        Cpy Rtclok+$02
          Beg L3
          Rts

Tabela    Dta B($15),B($16)
          Dta B($17),B($18)
          Dta B($19),B($1A)
          Dta B($19),B($18)
          Dta B($17),B($16)
          Dta B($15)

          End of File
    Kolejne wartości dla AUDC1 pobierane są z tabeli Tabela. Po 1/50 sekundy membrana powraca do stanu pierwotnego, aby po kolejnej 1/50 sekundy pobrać następną wartość z tablicy.

    Ostatni program zamienia klawiaturę Atari w klawiaturę syntezatora. Klawisz Y odpowiada środkowemu C w piątej oktawie (261 Hz).
Procedure Equ $8800
List_mem  Equ %00000110 
List_err  Equ %00000101
Code_mem  Equ %00010000
Code_dsk  Equ %00100000

Audcl     Equ $D201
Audfl     Equ $D200
Kbcodes   Equ $02FC
Skstat    Equ $D20F

        Opt List_err+Code_mem
          Org Procedure

L0        Ldy #$FF
          Sty Kbcodes
L1        Lda Kbcodes
          Bmi L1
          Cmp #$1C
          Beg L5
          Ldx #$17
L2        Cmp Klawisze,x
          Beq L3
          Dex
          Bpl L2
          Bmi L0
L3        Lda Dzwięki,x
          Sta Audf1
          Lda #$AA
          Sta Audcl
L4        Lda Skstat
          And #$04
          Beg L4
          Lda #$00
          Sta Audcl
          Sta Audfl
          Beg L0
L5        Rts

Klawisze  Dta B($2C),B($1F)
          Dta B($2F),B($1E)
          Dta B($2E),B($2A)
          Dta B($18),B($28)
          Dta B($1D),B($2D)
          Dta B($1B),B($2B)
          Dta B($0B),B($35)
          Dta B($0D),B($30)
          Dta B($08),B($0A)
          Dta B($36),B($0E)
          Dta B($37),B($0F)
          Dta B($34),B($0C)

Dzwieki   Dta B($F3),B($E6)
          Dta B($D9),B($CC)
          Dta B($C1),B($B6)
          Dta B($AD),B($A2)
          Dta B($99),B($90)
          Dta B($88),B($80)
          Dta B($79),B($72)
          Dta B($6C),B($66)
          Dta B($60),B($5B)
          Dta B($55),B($51)
          Dta B($4C),B($48)
          Dta B($44),B($40)

          End of File
    W tablicy Klawisze umieszczone są kody klawiszy dwóch górnych rzędów klawiatury, a w tablicy Dźwięki - odpowiadające im częstotliwości. Naciśnięcie klawisza ESC przerywa działanie programu. Naciśnięcie klawisza powoduje odszukanie jego kodu w tablicy Klawisze, wybranie odpowiedniego dźwięku z tablicy Dźwięki i przesłanie go do generatora 1. Dźwięk trwa tak długo, jak długo naciśnięty jest klawisz. Informacja o tym zawarta jest w rejestrze Skstat.

    Dodatkowym rejestrem modyfikującym dźwięk jest rejestr AUDCTL ($D208).

Bit 0 tego rejestru przełącza główny zegar bazowy z częstotliwości 64 kHz na 15 kHz, co w praktyce pozwala uzyskać niższe częstotliwości dźwięku.

Bity 1 i 2 to filtry górnoprzepustowe kontrolujące dźwięki.

Bit 3 łączy kanały 3 i 4 dając szesnastobitową zmienną kontrolującą i tym samym zmniejszając skok częstotliwości z 1/256 (jeden bajt) do 1/65536 (jedno słowo).

Bit 4 ma takie samo znaczenie jak bit 3, przy czym łączone są kanały 1 i 2.

Bity 5 i 6 działają podobnie jak bit 0, przy czym zwiększają wysokość generowanego tonu odpowiednio w generatorach 3 i 1.

Bit 7 przełącza licznik "poly" z 17 na 9 bitów. Im mniejsza pojemność tego licznika, tym częściej powtarzane są zniekształcenia generowanego dźwięku.

    Używanie filtrów "na własną rękę" może być ciekawym eksperymentem. Rejestr AUDCTL nie został jednak opisany tak dokładnie, aby jego możliwości można było profesjonalnie wykorzystać, tym zajmują się programy muzyczne. Zaprezentowaliśmy procedury tworzące proste dźwięki, natomiast skomplikowaną muzykę, wykonywaną, co ważniejsze - na przerwaniach, tworzy się z wykorzystaniem np. Chaos Music Composer'a lub Future Composer'a, które uważamy za najlepsze (nie biorąc pod uwagę programów dołączających dźwięki digitalizowane).

    W następnym artykule rozpoczniemy już pisanie naszego dema. Nabyte dotąd wiadomości pozwolą nam zrozumieć w pełni działanie wszystkich procedur.

Tomasz Bielak
Rafał Bielecki



Powrót na start | Powrót do spisu treści | Powrót na stronę główną

Pixel 2002