Tajemnice ATARI

Sekrety POKEY-a

    Na temat przerwań napisano już wiele, o zegarach POKEY przy okazji efektów dźwiękowych również, ale o przerwaniach zegarów POKEY niewiele. Zegary POKEY generują przerwanie po dojściu do zera, a że liczą z szybkością większą niż liczniki systemowe zastosowanie narzuca się samo - pomiar czasu z dużą dokładnością. Parę słów na temat rejestrów sprzętowych.

• AUDF - rejestr częstotliwości, wartość tu wpisana będzie określała stopień podziału zegara bazowego.
• AUDC - rejestr sterujący natężeniem i zniekształceniami dźwięku, nas on nie interesuje.
• AUDCTL - najważniejszy dla nas rejestr sterujący, kolejne bity mają następujące znaczenie:

   Bit 0 - wybór zegara bazowego (0=64kHz, l=15kHz)
   Bit 1 i 2 - włącza filtry górnoprzepustowe
   Bit 3 - włączony scala liczniki 3 i 4 w jeden dzielnik 16-bitowy
   Bit 4 - jak bit 3, ale dla liczników 1 i 2
   Bit 5 - ustawiony przełącza zegar bazowy licznika 3 na 2.217MHz
   Bit 6 - przełącza zegar licznika l na 2.217 MHz
   Bit 7 - przełącza 17-bitowy rejestr przesuwający na rejestr 9-bitowy dla uzyskania dodatkowych sposobów zniekształcania dźwięku, nas nie interesuje.

    Na wstępie należy się pewne wyjaśnienie. Wszystkie wartości częstotliwości zegara bazowego są podane z pewnym przybliżeniem. Niestety w dostępnej mi literaturze nie odnalazłem dokładnych wartości dla systemu PAL.

    Czas na kawałek programu.
* POMIAR CZASU PRZY POMOCY PRZERWAN
* LICZNIKOW POKEY

         OPT %0010110

AUDCTL   EQU   $D208
AUDC1    EQU   $D201
AUDF1    EQU   $D200
IRQEN    EQU   $D20E 
IRQENS   EQU   $0010
VTIMR1   EQU   $0210
STIMER   EQU   $D209
PORTA    EQU   $D300


         ORG  $0600

LICZNIK  DTA B($00),B(00)  ;LICZNIK GLOWNY 
LICZ_l   DTA B($00),B(00)  ;REJESTRY POMIAROW
         DTA B($00),B(00)  ;POSREDNICH
STATUS   DTA B($00)        ;WSK. PRZEPELNIENIA


* OBSLUGA PRZERWANIA LICZNIKA 

STOPER   INC LICZNIK       ;LICZNIK=LICZNIK+1
         BNE STOP_1
         INC LICZNIK+1     ;PRZENIESIENIE 
         BNE STOP_1
         LDA #$FF          ;PRZEPELNIENIE
         STA STATUS
STOP_l   PLA
         RTI

* KONIEC PRZERWANIA POKEY


* USTALENIE PARAMETROW PRZERWANIA POKEY

INIT     PLA            ;WYWOŁANIE Z BASICA
         LDA STOPER 
         STA VTIMR1+1   ;MSB 
         LDA #%00000000 
         STA AUDCTL     ;ZEGAR 64KHZ 
         LDA #64        ;PODZIAL 64=1000Hz 
         STA AUDF1 
         LDA #$00 
         STA AUDC1
         STA STIMER     ;WPIS WARTOSCI
         RTS
 
         END
    Dwa bajty licznika pozwalają na odmierzenie co najwyżej 64 s. Przepełnienie licznika sygnalizowane jest wpisaniem liczby $FF do komórki STATUS. Dwa dwubajtowe rejestry pozwalają na zapis wyników pośrednich.

    Program start - i nic? Oczywiście trzeba jeszcze w komórce określającej zezwolenie na przerwanie (IRQEN) ustawić odpowiedni bit. Ale to później.

    No dobrze, mamy stoper - ale po co ? Zastosowania mogą być różne. Poniższy przykład może służyć jako inspiracja do własnych poszukiwań. Zbudujmy układ czterech fotokomórek, ustawmy na równi pochyłej i już na lekcji fizyki sprawdzamy czy wzory opisujące przyspieszenie są prawdziwe. Zostawiając oczywiście margines błędu na tarcie i tym podobne złośliwości. Schemat przykładowego układu pokazany jest na rysunku. Szczegółów nie będę opisywał, a kto nie wie jak to zrobić, niech się lepiej poradzi bardziej doświadczonego kolegi. Dodam tylko, że diody emitujące bezpieczniej będzie zasilać z zewnętrznego źródła ze względu na dość duży pobór prądu. Do połączenia układu z komputerem wykorzystamy wejście joysticka 1.

    I kolejny fragment programu:
CZAS_STR PLA            ;WYWOLANIE Z BASICA 
         LDA #$00       ;ZEROWANIE
         LDX #$6        ;LICZNIKOW,REJESTROW 
ZERUJ    STA LICZNIK,X  ;ORAZ WSK. PRZEPELNIENIA
         DEX      
         BPL ZERUJ

         LDA #%00000001
CZEK_1   BIT PORTA      ;CZEKAJ NA
         BNE CZEK_l     ;1 FOTOKOMORKE
         PHA            ;ZAPAMIETAJ MASKE
         LDA IRQENS     ;ODCZYT IRQ
         ORA #$01       ;ZEZW. NA PRZERWANIE
                        ;TIMER1
         STA IRQENS     ;START CZAS
         STA IRQEN
         LDX #$4        ;WSKAZNIK
CZEK_3   LDY #$80       ;FILTR ANTY-ZAKLOCENIOWY
AAA      DEY
         BNE AAA
         PLA
         ASL @          ;MASKA W LEWO
CZEK_3   BIT PORTA      ;CZEKAJ NA KOLEJNA
         BNE CZEK_2     ;FOTOKOMORKE
         DEX
         BMI CZEK_4
         PHA            ;PRZECHOWAJ MASKE
         SEI            ;ZAKAZ PRZERWAN
         LDA LICZNIK+1  ;NA CZAS PRZEPISYWANIA
         STA LICZ_1,X   ;WARTOSCI LICZNIKA
         DEX            ;DO REJESTROW POSREDNICH
         LDA LICZNIK
         STA LICZ_l,X
         CLI
         JMP CZEK_3
CZEK_4   LDA IRQENS     ;LICZNIKI STOP
         AND #$FE
         STA IRQENS
         STA IRQEN
         RTS

         END


    Teraz trochę komentarza. Pierwsza fotokomórka uruchamia stoper, zezwalając na przerwanie TIMER-a 1. Dwa kolejne sygnały z fotokomórek 213 spowodują przepisanie wartości licznika do rejestrów pośrednich. Sygnał z czwartej fotokomórki zatrzymuje stoper.

    Program nie posiada tzw. wyjścia awaryjnego. Będzie czekał w nieskończoność na kolejne sygnały. Takie awaryjne wyjście każdy może sobie dopisać, albo po prostu wyłączyć zasilanie układu.

    A teraz przykładowy pragram w BASIC-u.
10 FOR I=1536 TO 1663:READ A:POKE I,A:
NEXT I
20 LICZ=1536:STAT=1542
30 OPEN #1,4,0,"K:"
40 INIT=USR(1560)
50 PRINT "S-START";:GET #1,A:IF A<>83 
THEN CLOSE #1:END 
60 PRINT :PRINT 
70 START=USR(1590)
80 IF PEEK(STAT)<>0 THEN PRINT "PRZEPE
LNIENIE":PRINT :GOTO 50
90 T1=(PEEK(LICZ+4)+PEEK(LICZ+5)*256)/
1000
100 T2=(PEEK(LICZ+2)+PEEK(LICZ+3)*256)
/1000
110 T3=(PEEK(LICZ+0)+PEEK(LICZ+1)*256)
/1000
120 PRINT "T1=";T1;" s"
130 PRINT "T2=";T2;" s"
140 PRINT "T3=";T3;" s"
150 PRINT :GOTO 50
1000 DATA 0,0,0,0,0,0,0,238,0,6,208,10
,238,1,6,208
1010 DATA 5,169,255,141,6,6,104,64,104
,169,7,141,16,2,169,6
1020 DATA 141,17,2,169,0,141,8,210,169
,64,141,0,210,169,0,141
1030 DATA 1,210,141,9,210,96,104,169,0
,162,6,157,0,6,202,16
1040 DATA 250,169,1,44,0,211,208,251,7
2,165,16,9,1,133,16,141
1050 DATA 14,210,162,4,160,128,136,208
,253,104,10,44,0,211,208,251
1060 DATA 202,48,19,72,120,173,1,6,157
,2,6,202,173,0,6,157
1070 DATA 2,6,88,76,84,6,165,16,41,254
,133,16,141,14,210,96
    Na koniec pewna refleksja. Jak już było powiedziane, licznik TIMER generuje przerwanie po dojściu do zera. Więc gdyby ustawić częstotliwość zegara bazowego na 2.217 MHz, przerwania można by wywoływać co jeden cykl procesora. Oczywiście wtedy komputer odmówi współpracy. Ci, co lubią eksperymenty niech sami spróbują określić maksymalną częstotliwość takich przerwań. Ja tylko dodam, że już przy przerwaniach co 0.5 ms widać wyraźnie spowolnienie komputera.

    Życzę udanych eksperymentów i ostrożności, której nigdy nie za mało.

Roman Zwiejski



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

Pixel 2002