Użytkownik:Mono
From Atariki
Wersja z dnia 19:46, 8 lis 2013 Mono (Dyskusja | wkład) (xmtdon) ← Previous diff |
Wersja z dnia 01:46, 11 lis 2013 Mono (Dyskusja | wkład) (→Komunikacja szeregowa - kiedy gaszony, kiedy zapalony) Next diff → |
||
Linia 173: | Linia 173: | ||
== Komunikacja szeregowa == | == Komunikacja szeregowa == | ||
- | Jak wspomniano [http://www.atari.org.pl/forum/viewtopic.php?pid=109609#p109609 w tym wątku] XMTDON jest ciągle zapalony i zezwolenie w IRQEN na jego obsługę będzie powodowało ciągłe zgłaszanie przerwania. Między przerwaniami nie zostanie wykonany ani jeden cykl programu użytkownika. | + | Jak wspomniano [http://www.atari.org.pl/forum/viewtopic.php?pid=109609#p109609 w tym wątku] XMTDON jest aktywny (zgaszony) kiedy nie trwa właśnie emisja bajtu danych przez szynę szeregową, wpp będzie ustawiany w stan nieaktywny (zapalony) a ponieważ nie ma możliwości zdezaktywowania tego bitu w IRQST, zezwolenie w IRQEN na jego obsługę będzie powodowało ciągłe zgłaszanie przerwania poza chwilami kiedy trwa transmisja bajtu. Między przerwaniami nie zostanie wykonany ani jeden cykl programu użytkownika. |
== IRQ rozszerzeń == | == IRQ rozszerzeń == |
Wersja z dnia 01:46, 11 lis 2013
Spis treści |
Mój brudnopis
Z systemem QMEG instalowana jest nieco zmodyfikowana czcionka standardowa (międzynarodowa została usunięta):
Pożyteczna strona: http://raster.infos.cz/atari/chars.htm
http://members.chello.nl/taf.offenga/ATP16.htm
Przerwania POKEY-a
Układ POKEY obsługuje kilka rodzajów przerwań IRQ:
- przerwania komunikacji poprzez szynę szeregową,
- przerwanie naciśnięcia dowolnego klawisza,
- przerwanie naciśnięcia klawisza Break,
- przerwania liczników 1, 2 i 4.
Każde z wymienionych przerwań jest maskowalne, co oznacza że istnieje możliwość zablokowania jego obsługi. Do obsługi przerwań przeznaczone są dwa rejestry:
- IRQEN - rejestr zezwolenia na obsługę przerwania,
- IRQST - rejestr znaczników wystąpienia przerwania.
Bity tych rejestrów przyporządkowane są odpowiednim przerwaniom:
- 7 - BREAK - przerwanie naciśnięcia klawisza Break,
- 6 - KEY - przerwanie naciśnięcia dowolnego klawisza prócz SHIFT, CONTROL, START, SELECT, OPTION, RESET,
- 5 - SERIN - przerwanie odebrania bajtu z szyny szeregowej,
- 4 - SEROUT - przerwanie opróżnienia bufora nadawczego szyny szeregowej,
- 3 - XMTDONE - przerwanie zakończenia transmisji przez szynę szeregową,
- 2 - TIMER4 - przerwanie licznika 4,
- 1 - TIMER2 - przerwanie licznika 2,
- 0 - TIMER1 - przerwanie licznika 1.
Zasada działania
Zapalenie odpowiedniego bitu w rejestrze IRQEN powoduje zezwolenie na obsługę danego przerwania. Jeśli zaistnieją warunki konieczne do wygenerowania przerwania (np. wciśnięty zostanie klawisz), to układ POKEY zasygnalizuje jego wystąpienie skasowaniem odpowiedniego bitu rejestru IRQST. Stan ten będzie się utrzymywał aż do momentu 'potwierdzenia obsługi przerwania' przez program użytkownika.
Skasowanie bitu w rejestrze IRQEN oznacza, że obsługa danego przerwania jest zabroniona i w rejestrze IRQST nie pojawi się żadna informacja o jego wystąpieniu, nawet jeśli zaistnieją ku temu niezbędne warunki.
Przerwania PIA
- PACTL.7 - linia PROCEED SIO
- PBCTL.7 - linia INTERRUPT SIO
Przerwanie wystąpiło gdy bity zapalone.
Bity zezwolenia na przerwanie:
- PACTL.0 - linia PROCEED SIO
- PBCTL.0 - linia INTERRUPT SIO
Przerwanie dozwolone gdy bity zapalone.
Potwierdzenie przyjęcia przerwania odbywa się przez:
- odczyt PORTA
- odczyt PORTB
http://www.atari.org.pl/forum/viewtopic.php?pid=128292#p128292
Inne przerwania
- PDVREG - nowe urządzenie
Bit zapalony w rejestrze odblokowuje przerwanie IRQ. Przerwanie wystąpiło, gdy bit w rejestrze zapalony. Potwierdzenie przyjęcia przerwania odbywa się przez zapalenie bitu w rejestrze.
- Bit B rejestru stanu CPU - rozkaz BRK
Gdy bit zapalony wiadomo, że wystąpiło przerwanie BRK.
Nie potwierdza się przyjęcia, bo nie ma możliwości programowego skasowania bitu B - sekwencja:
lda #0 pha plp
pozostawi w rejestrze znaczników wartość $30 czyli zapalony bit B i *.
Bajt następujący zaraz za rozkazem BRK jest ignorowany - RTI z obsługi BRK wraca dopiero do 2 bajtu po BRK.
Przerwanie można wygenerować również kiedy I jest zapalone (!), dobrze by więc było, aby procedura obsługi IRQ byla reentrant (chyba, że świadomie zabraniamy używania BRK w procedurach obsługi przerwań).
Przez większość czasu działania procesora B jest zapalone. B=0 tylko w momencie kiedy żąda się obsługi przerwania sprzętowego (np. od POKEYa) i taki stan jest podtrzymywany do końca sekwencji wejścia w przerwanie, po czym znowu jest zapalany. Z tego powodu testowanie czy wywołano rozkaz BRK odbywa się na wartości rejestru flagowego zostawionej na stosie przy wejściu w przerwanie, gdyż PHP+PLA pokaże B=1.
Priorytety
Wymienione przerwania są obsługiwane przez system operacyjny, który dla każdego z nich oferuje użytkownikowi osobny wektor.
Każde przerwanie ma przyporządkowany priorytet w związku z czym zawsze są one obsługiwane przez OS w następującej kolejności:
- VSERIN ($20A) - odczyt bajtu z szyny szeregowej,
- VPIRQ ($238) - komunikacja z nowym urządzeniem,
- VSEROR ($20C) - opróżnienie bufora nadawczego szyny szeregowej,
- VSEROC ($20E) - koniec transmisji szeregowej,
- VTIMR1 ($210) - wyzerowanie licznika 1,
- VTIMR2 ($212) - wyzerowanie licznika 2,
- VTIMR4 ($214) - wyzerowanie licznika 4,
- VKEY ($208) - wciśnięcie klawisza,
- VBRKKEY ($236) - wciśnięcie klawisza Break.
- VPRCED ($202) - stan niski linii PROCEED w złączu SIO,
- VINTER ($204) - stan niski linii INTERRUPT w złączu SIO,
- VBREAK ($206) - przerwanie rozkazu BRK procesora.
Obsługa przerwań POKEY-a
OS po wykryciu źródła przerwania potwierdza jego przyjęcie. Odbywa się to poprzez skasowanie oraz ponowne zapalenie bitu zezwolenia na obsługę przerwania w rejestrze IRQEN. Powoduje to ustawienie flagi zgłoszenia przerwania w rejestrze IRQST w stan nieaktywny (bit zapalony). Ponieważ rejestr IRQEN jest rejestrem tylko do zapisu, OS posiłkuje się rejestrem-cieniem IRQENS ($10) aby zapamiętać które przerwania mają być odblokowane. I tak sekwencja potwierdzenia obsługi przerwania wygląda następująco:
lda #%00000100 ;przykładowe przerwanie od TIMERa 4 bit IRQST bne _nie_wystapilo_ eor #$ff sta IRQEN ;zgaszenie flagi wystąpienia przerwania lda IRQENS sta IRQEN ;przywrócenie obsługi przerwań
Polling
Musi się odbywać przy zapalonym I, bo zablokowanie źródła przerwania powoduje że zgłoszenie nie pojawia się w IRQST.
lda #%00000100 ldx #%11111011 bit IRQST bne *-3 stx IRQEN ora IRQENS sta IRQEN
Wektoryzowanie
sei ldx vec ldy vec+1 stx _store_ sty _store_+1 ldx #<_procedura_ ldy #>_procedura_ stx vec sty vec+1 lda #%100 ora IRQENS sta IRQENS sta IRQEN cli
sei lda #%11111011 and IRQENS sta IRQENS sta IRQEN ldx _store_ ldy _store_+1 stx vec sty vec+1 cli
Liczniki
STIMER do startowania odliczania
Przy łączeniu dzielników w 16-bit przerwanie ustawia się w starszym liczniku (2 lub 4)
Ilość cykli zgodna z opisem generatorów dźwięku.
Komunikacja szeregowa
Jak wspomniano w tym wątku XMTDON jest aktywny (zgaszony) kiedy nie trwa właśnie emisja bajtu danych przez szynę szeregową, wpp będzie ustawiany w stan nieaktywny (zapalony) a ponieważ nie ma możliwości zdezaktywowania tego bitu w IRQST, zezwolenie w IRQEN na jego obsługę będzie powodowało ciągłe zgłaszanie przerwania poza chwilami kiedy trwa transmisja bajtu. Między przerwaniami nie zostanie wykonany ani jeden cykl programu użytkownika.
IRQ rozszerzeń
Nie można dołączyć obsługi przerwań od rozszerzeń (np. SoundBoard) o priorytetach niższych, bo nie ma odpowiedniego wektora. Priorytety wyższe mozna obsługiwać przez VIMIRQ.
Opóźnienia wywołania procedur obsługi przerwań IRQ
Ilość cykli o jakie opóźniona jest obsługa przerwania IRQ:
IRQENS=$10 KEYDIS=$26d
1. VSERIN - 43
2. VPIRQ - 46
3. VSEROR - 111
4. VSEROC - 125
od tej pory +5 cykli kiedy wystąpiło VSEROC i IRQENS.VSEROC=0
5. VTIMR1 - 158
6. VTIMR2 - 178
7. VTIMR4 - 198
8. VKBDKEY - 218
9. VBRKKEY - 243
od tej pory +18 cykli kiedy wystąpiło BRKKEY i KEYDIS=1
10. VPRCED - 214
11. VINTER - 221
12. VBREAK - 244
Całkowity czas trwania procedury IRQ kiedy nie jest obsługiwane żadne przerwanie wynosi 250 (+5+18=273) cykli.
Zaokrąglenia
Reguła zaokrąglania arytmetycznego mówi, że do liczby należy dodać 0.5 i wziąć część całkowitą. Zależnie od formatu liczb FXP, które chcemy dodawać należy najpierw sprowadzić je do wspólnej postaci (kropka powinna być na tym samym miejscu w obydwu liczbach) po czym przeprowadzić działanie począwszy od najmłodszego bajtu (wynik na bajtach części ułamkowej można zignorować).
Dodawanie
W najprostszej postaci kiedy liczby są w formacie FXP7.1 wystarczy:
clc lda CA adc CB ror adc #0 rol
w A jest wynik.
Dla FXP8.8 nie trzeba niczego przesuwać:
clc lda CA adc CB sta R lda CA+1 adc CB+1 asl R adc #0
Również i tu w A jest wynik.
Jeśli jedna z liczb jest całkowita, wtedy wystarczy przesunąć tylko jeden składnik np. dla CA(FXP8.0) i CB(FXP6.2):
lda CB lsr lsr adc CA
Jeśli rozważana jest liczba ze znakiem należy przy przesuwaniu w prawo lub rozszerzaniu zadbać o kopiowanie znaku argumentu.
Odejmowanie
SA(FXP8.0) SB(FXP8.8)
lda #$80 cmp SB lda SA sbc SB+1
Kopiowanie znaku
Przy przesuwaniu w prawo:
cmp #$80 ror
Przy rozszerzaniu:
asl lda #0 adc #$ff eor #$ff
Obrót bitowy w prawo
Metoda dość hakerska:
pha plp ror
SEV
ror bit *-1 rol
lub szybciej
bit @ @:eor #0
BOOT ZPG
Rejestry ZPG, które należy bezwzględnie zachować aby OS mógł poprawnie pracować po RESET:
- 9 - BOOT?
- A,B - DOSVEC
- C,D - DOSINI (2,3 - CASINI kiedy BOOT był z kasety)
Reszta zostanie podczas gorącego startu poprawnie zainicjalizowana.
PMG
Kiedy sprajty chcemy malować nie używając DMA, a modyfikując rejestry GRAFxx, wtedy ustawienie PMG powinno przebiegać tak:
1. Kasujemy bity 2 i 3 w DMACTLS/DMACTL.
2. Ustawiamy bity 0 i 1 w PMCNTL.
Niestety działa to tylko przy wyłączonym DMA dla ekranu (skasowany bit 5 DMACTL/DMACTLS).
Kiedy DMA dla ekranu jest włączone (ustawiony bit 5 DMACTL/DMACTLS) w trybie 2 ANTIC-a (GR.0) na sprajtach pojawiają się śmieci z szyny danych. Skasowanie bitów 0 i 1 w PMCNTL powoduje, że w takim przypadku sprajty wyświetlane są poprawnie (!).