Powrót do spisu treści

Rozdział 3

PRZERWANIA SYSTEMOWE

    Komputery Atari posiadają bardzo rozbudowany system przerwań, który stanowi jeden z najmocniejszych punktów systemu operacyjnego. Część przerwań jest wykorzystywana bezpośrednio przez OS, a niektóre są przeznaczone do zastosowania przez programy użytkownika. Są też one najczęściej wykorzystywanym przez programistów elementem systemu. Wszystkie występujące w Atari przerwania można podzielić na dwie zasadnicze grupy: przerwania niemaskowalne (NMI - Non Maskable Interrupt) i maskowalne (IRQ - Interrupt ReQuest).

    Zgłoszenie przerwania następuje na drodze sprzętowej poprzez przekazanie do CPU sygnału żądania przerwania odpowiednio po linii NMI lub IRQ szyny sterowania. Po otrzymaniu żądania przerwania NMI procesor odkłada na stos aktualną zawartość licznika programu i rejestru statusu oraz wykonuje skok pod adres zawarty w rejestrze NMIVEC ($FFFA). Przerwania NMI nie można zablokować i musi ono zostać wykonane.

    Żądanie przerwania IRQ jest obsługiwane podobnie z dwiema istotnymi różnicami. Najpierw sprawdzany jest bit I rejestru statusu i gdy jest on ustawiony, to żądanie przerwania jest ignorowane i procesor kontynuuje wykonywanie programu. Gdy bit I jest skasowany, wykonywane są operacje jak przy NMI, a następnie skok pod adres zawarty w rejestrze IRQVEC ($FFFE). Dzięki zastosowaniu takiego sposobu postępowania przerwania IRQ mogą być zablokowane (zamaskowane) przez ustawienie bitu I w rejestrze statusu procesora.

    Wypada dodać, że RESET jest także przerwaniem. Ma ono najwyższy priorytet i zawsze musi być wykonane. Wektor przerwania RESET (RESETVEC) jest umieszczony pod adresem $FFFC, między wektorami NMIVEC i IRQVEC.

3.1. Procedury przerwań niemaskowalnych

    Mimo, iż przerwanie niemaskowalne nie może zostać zablokowane, to jednak istnieje możliwość jego zabronienia. Wynika to z budowy wewnętrznej komputera. Żądanie przerwania niemaskowalnego jest wysyłane do CPU przez procesor obrazowy ANTIC. Może on wysłać sygnał żądania przerwania tylko wtedy, gdy ustawiony jest bit 6 lub 7 w jego sprzętowym rejestrze NMIEN (NMI ENable - $D40E).

    Ustawienie bitu 6 zezwala na żądanie przerwania wywołanego przez impuls synchronizacji pionowej obrazu (VBLKI - Vertical BLanK Interrupt). Ustawienie bitu 7 zezwala na żądanie przerwania wywołanego przez program ANTIC-a (DLI - Display List Interrupt). Jednocześnie z żądaniem przerwania ANTIC ustawia odpowiedni bit w rejestrze NMIST (NMI STatus) informującym o źródle przerwania.

3.1.1. Procedura rozpoznania źródła przerwania

    Po otrzymaniu sygnału żądania przerwania niemaskowalnego procesor pobiera z rejestru NMIVEC (NMI VECtor) adres procedury obsługi tego przerwania i przechodzi do jej wykonywania od pobranego adresu. Adres ten wskazuje na procedurę NMIFIRST ($C018).
            0100 ;NMI FIRST
            0110 ;
            0120 DLIV = $0200
            0130 NMIST = $D40F
            0140 VVBLKI = $0222
            0150 ;
            0160     *=  $C018
            0170 ;
            0180     BIT NMIST
            0190     BPL VBL
            0200     JMP (DLIV)
            0210 VBL CLD
            0220     PHA
            0230     TXA
            0240     PHA
            0250     TYA
            0260     PHA
            0270     STA NMIST
            0280     JMP (VVBLKI)
    W pierwszym kroku procedury sprawdzany jest najstarszy bit rejestru NMIST. Jeżeli jest on ustawiony, to znaczy, że przerwanie zostało wywołane przez program ANTIC-a i wykonywany jest skok do adresu zawartego w rejestrze DLIV (DLI Vector). Wskazywana przez ten rejestr procedura nie występuje w systemie i musi być zaprogramowana przez użytkownika. Wektor DLIV wskazuje więc normalnie rozkaz RTI.

    Gdy bit 7 w NMIST jest skasowany, to znaczy, że chodzi o przerwanie synchronizacji pionowej (Vertical BLanK Interrupt - VBLKI). W takim przypadku kasowany jest tryb dziesiętny procesora, zawartości jego rejestrów są odkładane na stos i rejestr NMIST jest zerowany, aby umożliwić zasygnalizowanie kolejnego przerwania. Następnie wykonywany jest skok do procedury wskazywanej przez wektor VVBLKI (Vector VBLK Immediate).

3.1.2. Struktura przerwania VBLK

    Przerwanie synchronizacji pionowej podzielone jest na dwie części. Każda z nich jest wskazywana przez wektor umieszczony w pamięci RAM. Umożliwia to prostą ingerencję programisty w przebieg przerwania. Schemat procedury jest następujący:

                         <VVBLKI>
                             |
                             v
              +--------------+---------------+
              |              |               |
              |              |      ++----------------++
              |        ++--------++ ||"natychmiastowa"||
              |        || SYSVBL || || procedura VBLK ||
              |        ++--------++ ||  użytkownika   ||
              |              |      ++----------------++
              |              v               |
              v              +<--------------+
    ++----------------++     |
    ||  "zastępcza"   ||     v
    || procedura VBLK || <VVBLKD>
    ||  użytkownika   ||     |
    ++----------------++     v
              |              +---------------+
              |              |               |
              |              |               v
              |              |      ++----------------++
              |              |      ||  "opóźniona"   ||
              |              |      || procedura VBLK ||
              |              |      ||  użytkownika   ||
              |              |      ++----------------++
              |              v               |
              +------------->+<--------------+
                             |
                             v
                       ++---------++
                       || EXITVBL ||
                       ++---------++
    Z powyższego schematu widać, że użytkownik może wstawić swoją procedurę zarówno przed ("natychmiastowa"), jak i po ("opóźniona") procedurze systemowej. Możliwe jest także całkowite ominięcie procedury systemowej przez procedurę użytkownika ("zastępcza"). W tym celu wystarczy jedynie zmienić odpowiednie wektory. Istnieje tu jednak pewne niebezpieczeństwo. Gdy przerwanie zostanie wywołane podczas wykonywania tej zmiany, to system zawiesi się. Dla uniknięcia takiej sytuacji OS zawiera specjalną procedurę SETVBLV, która służy do zmian wektorów.

3.1.3. Systemowa procedura VBLKI

    Podstawowym zadaniem procedury przerwania synchronizacji pionowej jest odliczanie czasu i obsługa zegarów systemowych. Przede wszystkim na początku procedury zwiększany jest stan zegara czasu rzeczywistego RTCLOCK (Real Time CLOCK). W tej fazie zwiększany jest także co 256 przerwań rejestr ATRACT i wykonywana jest obsługa tzw. trybu przyciągania uwagi.

    Tryb przyciągania uwagi (Attract Mode) jest specyficznym pomysłem twórców Atari. Rejestr ATRACT jest zerowany przez każde naciśnięcie klawisza. Jeżeli jednak osiągnie on wartość $80 (trwa to 32768 cykli zegarowych, czyli 645,36 sekund), to włączany jest tryb Attract. Rejestr ATRACT otrzymuje wartość $FE, rejestr ATRMSK wartość $F6 (zamiast $FE), a rejestr COLRSH wartość drugiego bajtu zegara RTCLOCK. Teraz wartość koloru pobrana z rejestru-cienia jest poddawana operacji EOR z zawartością COLRSH i AND z ATRMSK oraz zapisywana do rejestru koloru. Powoduje to cykliczne zmiany kolorów na ekranie.

    Następnie z wartością zero w rejestrze X wywoływana jest procedura DECTIM w celu zmniejszenia stanu licznika systemowego TIMCNT1 (TIMer CouNTer 1). Powrót z tej procedury z ustawionym bitem Z w rejestrze statusu oznacza wyzerowanie licznika i powoduje wywołanie poprzez skok do JMPTIM1 procedury od adresu wskazanego przez wektor TIMVEC1 (TIMer VECtor 1).

    Teraz sprawdzany jest znacznik CRITIC (CRITICal I/O). Jeśli jego wartość jest różna od zera, oznacza to, że wykonywana jest przez system operacja wejścia/wyjścia krytyczna czasowo. W takim przypadku procedura przerwania VBLK jest kończona skokiem bezpośrednio do procedury EXITVBL.
0100 ;SYStem Vertical          0370 JSTICK2 = $027A
0110 ;BLank interrupt          0380 JSTICK3 = $027B
0120 ;                         0390 KBCODE = $D209
0130 ATRACT = $4D              0400 KBCODES = $02FC
0140 ATRMSK = $4E              0410 KEYDEL = $02F1
0150 CHACT = $02F3             0420 KEYDIS = $026D
0160 CHBAS = $02F4             0430 KEYREP = $02DA
0170 CHBASE = $D409            0440 LPENH = $D40C
0180 CHRCTL = $D401            0450 LPENHS = $0234
0190 COLPF1 = $D017            0460 LPENV = $D40D
0200 COLPF1S = $02C5           0470 LPENVS = $0235
0210 COLPM0 = $D012            0480 PADDL0 = $0270
0220 COLPM0S = $02C0           0490 PORTA = $D300
0230 COLRSH = $4F              0500 POT0 =  $D200
0240 CONSOL = $D01F            0510 POTGO = $D20B
0250 CRITIC = $42              0520 PTRIG0 = $027C
0260 DECTIM = $C255            0530 PTRIG1 = $027D
0270 DLPTR = $D402             0540 RTCLOCK = $12
0280 DLPTRS = $0230            0550 SKSTAT = $D20F
0290 DMACTL = $D400            0560 SRTIMER = $022B
0300 DMACTLS = $022F           0570 STACK = $0100
0310 EXITVBL = $C28A           0580 TIMCNT1 = $0218
0320 GINTLK = $03FA            0590 TIMVEC1 = $0226
0330 GTIACTL = $D01B           0600 TIMVEC2 = $0228
0340 GTICTLS = $026F           0610 TRIG0 = $D010
0350 JSTICK0 = $0278           0620 TRIG0S = $0284
0360 JSTICK1 = $0279           0630 TRIG1 = $D011

0640 TRIG1S = $0285            1200     LDA VSFLAG
0650 TRIG2S = $0286            1210     BEQ NSC
0660 TRIG3 = $D013             1220     DEC VSFLAG
0670 TRIG3S = $0287            1230     LDA #$08
0680 VSCROL = $D405            1240     SEC
0690 VSFLAG = $026C            1250     SBC VSFLAG
0700 VVBLKD = $0224            1260     AND #$07
0710 ;                         1270     STA VSCROL
0720      *=  $C0DF            1280 NSC LDX #$08
0730 ;                         1290     STX CONSOL
0740 WAIT JMP WAIT             1300 COL CLI
0750 SYSVBL INC RTCLOCK+2      1310     LDA COLPM0S,X
0760     BNE ATT               1320     EOR COLRSH
0770     INC ATRACT            1330     AND ATRMSK
0780     INC RTCLOCK+1         1340     STA COLPM0,X
0790     BNE ATT               1350     DEX
0800     INC RTCLOCK           1360     BPL COL
0810 ATT LDA #$FE              1370     LDA CHBAS
0820     LDX #$00              1380     STA CHBASE
0830     LDY ATRACT            1390     LDA CHACT
0840     BPL ATR               1400     STA CHRCTL
0850     STA ATRACT            1410     LDX #$02
0860     LDX RTCLOCK+1         1420     JSR DECTIM
0870     LDA #$F6              1430     BNE NTI2
0880 ATR STA ATRMSK            1440     JSR JMPTIM2
0890     STX COLRSH            1450 NTI2 LDX #$02
0900     LDA COLPF1S           1460 TIM INX
0910     EOR COLRSH            1470     INX
0920     AND ATRMSK            1480     LDA TIMCNT1,X
0930     STA COLPF1            1490     ORA TIMCNT1+1,X
0940     LDX #$00              1500     BEQ NTI3
0950     JSR DECTIM            1510     JSR DECTIM
0960     BNE NTI1              1520     STA TIMVEC1,X
0970     JSR JMPTIM1           1530 NTI3 CPX #$08
0980 NTI1 LDA CRITIC           1540     BNE TIM
0990     BNE IOC               1550     LDA SKSTAT
1000     TSX                   1560     AND #$04
1010     LDA STACK+4,X         1570     BEQ NKY
1020     AND #$04              1580     LDA KEYDEL
1030     BEQ PHASE2            1590     BEQ NKY
1040 IOC JMP EXITVBL           1600     DEC KEYDEL
1050 PHASE2 LDA TRIG3          1610 NKY LDA SRTIMER
1060     CMP GINTLK            1620     BEQ JOY
1070     BNE WAIT              1630     LDA SKSTAT
1080     LDA LPENV             1640     AND #$04
1090     STA LPENVS            1650     BNE NOKEY
1100     LDA LPENH             1660     DEC SRTIMER
1110     STA LPENHS            1670     BNE JOY
1120     LDA DLPTRS+1          1680     LDA KEYDIS
1130     STA DLPTR+1           1690     BNE JOY
1140     LDA DLPTRS            1700     LDA KEYREP
1150     STA DLPTR             1710     STA SRTIMER
1160     LDA DMACTLS           1720     LDA KBCODE
1170     STA DMACTL            1730     CMP #$9F
1180     LDA GTICTLS           1740     BEQ JOY
1190     STA GTIACTL           1750     CMP #$83

1760     BEQ JOY               2040     STA TRIG1S
1770     CMP #$84              2050     STA TRIG3S
1780     BEQ JOY               2060     LDX #$03
1790     CMP #$94              2070 PAD LDA POT0,X
1800     BEQ JOY               2080     STA PADDL0,X
1810     AND #$3F              2090     STA PADDL0+4,X
1820     CMP #$11              2100     DEX
1830     BEQ JOY               2110     BPL PAD
1840     LDA KBCODE            2120     STA POTGO
1850     STA KBCODES           2130     LDX #$02
1860     JMP JOY               2140     LDY #$01
1870 NOKEY LDA #$00            2150 PDT LDA JSTICK0,Y
1880     STA SRTIMER           2160     LSR A
1890 JOY LDA PORTA             2170     LSR A
1900     LSR A                 2180     LSR A
1910     LSR A                 2190     STA PTRIG1,X
1920     LSR A                 2200     STA PTRIG1+4,X
1930     LSR A                 2210     LDA #$00
1940     STA JSTICK1           2220     ROL A
1950     STA JSTICK3           2230     STA PTRIG0,X
1960     LDA PORTA             2240     STA PTRIG0+4,X
1970     AND #$0F              2250     DEX
1980     STA JSTICK0           2260     DEX
1990     STA JSTICK2           2270     DEY
2000     LDA TRIG0             2280     BPL PDT
2010     STA TRIG0S            2290     JMP (VVBLKD)
2020     STA TRIG2S            2300 JMPTIM1 JMP (TIMVEC1)
2030     LDA TRIG1             2310 JMPTIM2 JMP (TIMVEC2)
    Jeżeli nie ma ograniczenia czasowego, to wykonywana jest druga faza procedury przerwania VBLK. Najpierw porównywane są zawartości rejestrów TRIG3 i GINTLK. Gdy są one różne, to znaczy, że został wyjęty lub włożont cartridge. Powoduje to skok do procedury WAIT, której pełna nazwa - WAIT for RESET (Czekaj na RESET) - dobrze wyjaśnia działanie: system zawiesza się i oczekuje na naciśnięcie klawisza RESET.

    W dalszej części procedury przerwania rejestry sprzętowe układów komputera uaktualniane są według rejestrów-cieni. Teraz następuje także zmniejszenie zawartości licznika przesuwu pionowego obrazu VSFLAG i przepisanie jej do VSCROL.

    Kolejny etap obejmuje czterokrotne wywołanie procedury DECTIM w celu zmniejszenia stanu pozostałych liczników systemowych. W przypadku wyzerowania licznika TIMCNT2 poprzez JMPTIM2 wywoływana jest procedura użytkownika (normalnie nie wykorzystywana przez OS). Wyzerowanie pozostałych liczników jest jedynie sygnalizowane we wskaźnikach TIMFLG3-TIMFLG5 (TIMer FLaG).

    Teraz wykonywana jest wstępna obsługa klawiatury. Jeśli rejestr SKSTAT (Serial/Keyboard STATus) sygnalizuje naciśnięcie klawisza, to zmniejszany jest licznik KEYDEL, który określa czas pomiędzy kolejnymi odczytami klawiatury. Naciśnięcie klawisza powoduje także zmniejszenie stanu licznika SRTIMER (wykorzystywany przez POKEY) i sprawdzanie kodu klawisza. Gdy nie jest to CTRL-1, HELP, CTRL-F1, CTRL-F2 ani CTRL-F4 (trzy ostatnie kody dotyczą modelu 1200XL), to zostaje przepisany do rejestru-cienia w pamięci RAM.

    Ostatnią częścią procedury SYSVBL jest przepisanie informacji z portów joysticków obsługiwanych przez układy I/O do rejestrów RAM. Z układu PIA odczytywane jest położenie joysticków, z układu POKEY położenie potencjometrów, a z GTIA - stan przycisków w joystickach i potencjometrach. Stare modele 400/800 posiadały gniazda dla czterech joysticków lub ośmiu potencjometrów, a modele XL/XE mają ich o połowę mniej. Ponieważ niektóre starsze gry wymagają takiej ilości manipulatorów jak w 400/800, to wartości dotyczące joysticków 0 i 1 są kopiowane do rejestrów joysticków 2 i 3. To samo dotyczy potencjometrów (wartości z 0-3 są kopiowane do 4-7).

    Procedura SYSVBL kończy się skokiem pod adres wskazywany przez wektor VVBLKD (Vector VBLK Deferred). Normalnie wskazuje on procedurę EXITVBL, lecz może być zmieniony przez użytkownika (przy pomocy SETVBLV).
            0100 ;EXIT Vertical BLank interrupt
            0110 ;
            0120     *=  $C28A
            0130 ;
            0140     PLA
            0150     TAY
            0160     PLA
            0170     TAX
            0180     PLA
            0190     RTI
    Zakończenie przerwania synchronizacji pionowej odbywa się poprzez procedurę EXITVBL. Jej jedynym zadaniem jest odtworzenie ze stosu umieszczonych tam na początku procedury obsługi przerwania rejestrów procesora. Po instrukcji RTI procesor odtwarza jeszcze rejestr statusu i licznik programu, co automatycznie powoduje kontynuowanie programu od miejsca, w którym wystąpiło żądanie przerwania.

3.1.4. Procedury uzupełniające VBLKI

    Podczas przerwania synchronizacji pięciokrotnie wywoływana jest procedura DECTIM. Służy ona do zmniejszania liczników systemowych TIMCNT1-5. Przed jej wywołaniem w rejestrze X musi zostać umieszczony numer licznika zmniejszony o 1 i pomnożony przez 2 ((licznik-1)*2), czyli indeks licznika liczony od TIMCNT1.
            0100 ;DECrement TIMer
            0110 ;
            0120 TIMCNT = $0218
            0130 ;
            0140     *=  $C255
            0150 ;
            0160     LDY TIMCNT,X
            0170     BNE DCL
            0180     LDY TIMCNT+1,X
            0190     BEQ DCL
            0200     DEC TIMCNT+1,X
            0210 DCL DEC TIMCNT,X
            0220     BNE NOT0
            0230     LDY TIMCNT+1,X
            0240     BNE NOT0
            0250     LDA #$00
            0260     RTS
            0270 NOT0 LDA #$FF
            0280     RTS
    Jeżeli zmniejszenie stanu licznika spowoduje jego wyzerowanie, to przed opuszczeniem procedury do akumulatora wpisywana jest wartość 0. W przeciwnym wypadku zawartością akumulatora jest #$FF.

    Wyzerowanie licznika TIMCNT1 lub TIMCNT2 powoduje wywołanie procedury, której adres wskazuje wektor TIMVEC1 lub TIMVEC2. Normalnie procedura licznika 2 jest niewykorzystana, natomiast TIMEVEC1 wskazuje procedurę TIM1INT.
             0100 ;TIMer 1 INTerrupt
             0110 ;
             0120 TIMFLG = $0317
             0130 ;
             0140     *=  $EC11
             0150 ;
             0160     LDA #$00
             0170     STA TIMFLG
             0180     RTS
    Procedura ta zeruje wskaźnik Timeout (czasu oczekiwania na odpowiedź), co jest wykorzystywane podczas operacji wejścia/wyjścia.

3.1.5. Ingerencja w procedurę VBLKI

    Jak wspomniano wcześniej zmiana procedury synchronizacji pionowej jest bardzo prosta. Własną procedurę użytkownik może umieścić w dowolnym miejscu procedury systemowej lub też zamiast niej. Dostęp systemu do procedury użytkownika uzyskuje się przez zmianę wektorów VVBLKI i/lub VVBLKD. Służy do tego procedura SETVBLV.

    Wymaga ona przed wywołaniem umieszczenia w rejestrze X starszego bajtu wektora, w rejestrze Y młodszego bajtu wektora i w akumulatorze numeru zmienianego wektora. Numery wektorów są następujące:

          0 - VIMIRQ
          1 - TIMCNT1
          2 - TIMCNT2
          3 - TIMCNT3
          4 - TIMCNT4
          5 - TIMCNT5
          6 - VVBLKI
          7 - VVBLKD
          8 - TIMVEC1
          9 - TIMVEC2
    Wymienione powyżej rejestry TIMCNT są licznikami zliczającymi wstecz (do zera) i zamiast wektora należy podać dla nich wartość początkową.
            0100 ;SET Vertical BLank
            0110 ;interrupt Vectors
            0120 ;
            0130 INTEMP = $022D
            0140 VIMIRQ = $0216
            0150 WSYNC = $D40A
            0160 ;
            0170     *=  $C272
            0180 ;
            0190     ASL A
            0200     STA INTEMP
            0210     TXA
            0220     LDX #$05
            0230     STA WSYNC
            0240 LOOP DEX
            0250     BNE LOOP
            0260     LDX INTEMP
            0270     STA VIMIRQ+1,X
            0280     TYA
            0290     STA VIMIRQ,X
            0300     RTS
    A oto opis działania SETVBLV. Najpierw numer wektora mnożony jest przez 2 (adresy są dwubajtowe) i odkładany tymczasowo do INTEMP, a do akumulatora przepisywana jest zawartość rejestru X. Po wpisaniu dowolnej wartości do rejestru WSYNC (Wait for SYNChronisation) następuje zatrzymanie procesora, aż do impulsu synchronizacji pionowej. Następnie, po odliczeniu czasu potrzebnego na wykonanie przez ANTIC operacji tworzenia linii obrazu, do rejestru określonego wartością pobraną z INTEMP (indeks od VIMIRQ) wpisywany jest starszy bajt z akumulatora i młodszy z rejestru Y. Procedura kończy się zwykłym rozkazem RTS.

3.1.6. Procedura przerwania DL

    Mimo, iż system operacyjny nie korzysta z przerwań wywoływanych przez program ANTIC-a (Display List Interrupt), to w pamięci ROM znajduje się procedura tego przerwania. Służy ona do obsługi delikatnego przesuwu obrazu. Przesuw delikatny polega na pionowym przemieszczaniu obrazu o jedną linię ekranową. Dla przesunięcia o jeden wiersz (linię obrazu) w trybie GRAPHICS 0 trzeba wykonać osiem przesunięć o linię ekranu.
            0100 ;Fine Scroll Display List
            0110 ;
            0120 ATRMSK = $4E
            0130 COLPF1 = $D017
            0140 COLPF2S = $02C6
            0150 COLRSH = $4F
            0160 WSYNC = $D40A
            0170 ;
            0180     *=  $FCC4
            0190 ;
            0200     PHA
            0210     LDA COLPF2S
            0220     EOR COLRSH
            0230     AND ATRMSK
            0240     STA WSYNC
            0250     STA COLPF1
            0260     PLA
            0270     RTI
    Procedura ta jest wywoływana przed wyświetleniem ostatniej linii obrazu i powoduje zmianę koloru tej linii tak, aby nie była widoczna jej zawartość. Ma to na celu ukrycie dodatkowej, ostatniej linii podczas przesuwania obrazu.

3.2. Procedury przerwań maskowalnych

    Żądanie przerwania maskowalnego IRQ powoduje (po zapisaniu na stos licznika programu i rejestru statusu) skok pod adres wskazany przez wektor IRQVEC ($FFFE). Wektor ten zawiera adres procedury JMPIRQV ($C02C).
            0100 ;JuMP IRQ Vector
            0110 ;
            0120 VIMIRQ = $0216
            0130 ;
            0140     *=  $C02C
            0150 ;
            0160     CLD
            0170     JMP (VIMIRQ)
    Ta króciutka procedura została dodana w modelach XL/XE, ponieważ wcześniejsze modele 400/800 robiły "dziwne" rzeczy podczas przerwań. Brakowało tam po prostu instrukcji CLD, która wyłącza dziesiętny tryb pracy procesora. Teraz po skasowaniu trybu dziesiętnego następuje skok do głównej procedury przerwania IRQ wskazywanej przez wektor VIMIRQ (Vector IMmediate IRQ).

3.2.1. Procedura rozpoznania źródła przerwania

    Do rozpoznania źródła sygnału żądania przerwania wykorzystywany jest przede wszystkim rejestr IRQST (IRQ STatus), którego każdy bit odpowiada jednemu z możliwych źródeł przerwania. Normalnie wszystkie bity tego rejestru są ustawione. Sygnał żądania przerwania powoduje (na drodze sprzętowej) skasowanie bitu odpowiadającego źródłu tego sygnału. Przyporządkowanie bitów rejestru IRQST jest następujące:
               0 - przerwanie zegara TIMER1
               1 - przerwanie zegara TIMER2
               2 - przerwanie zegara TIMER4
               3 - przerwanie końca transmisji
               4 - przerwanie zapisu szeregowego
               5 - przerwanie odczytu szeregowego
               6 - przerwanie klawiatury
               7 - przerwanie klawisza BREAK
    Analogiczne przyporządkowanie mają bity rejestru IRQEN (IRQ ENable). Skasowanie bitu w tym rejestrze powoduje zabronienie odpowiadającego mu przerwania IRQ.

    Rozpoznanie źródła przerwania IRQ wykonuje procedura SINRDYI. Wiele z jej odgałęzień jest aktualnie nie wykorzystane. Są one przewidziane dla przyszłych rozszerzeń systemu lub zastosowania przez użytkownika.

    W procedurze SINRDYI można zauważyć jedną z niewielu niekonsekwencji systemu. W jej środku jest wstawiona procedura BREAKIRQ, która nie ma żadnego związku z SINRDYI i musi być ominięta.
            0100 ;Serial INput ReaDY Irq
            0110 ;
            0120 DLIV =  $0200
            0130 IRQENS = $10
            0140 IRQST = $D20E
            0150 KEYDIS = $026D
            0160 NEWIOP = $028C
            0170 PACTL = $D302
            0180 PBCTL = $D303
            0190 PDVREG = $D1FF
            0200 PINTMSK = $0249
            0210 PORTA = $D300
            0220 PORTB = $D301
            0230 VBREAK = $0206
            0240 VINTER = $0204
            0250 VPIRQ = $0238
            0260 VPRCED = $0202
            0270 VSERIN = $020A
            0280 ;
            0290     *=  $C030
            0300 ;
            0310     PHA
            0320     LDA IRQST
            0330     AND #$20
            0340     BNE PDV
            0350     LDA #$DF
            0360     STA IRQST
            0370     LDA IRQENS
            0380     STA IRQST
            0390     JMP (VSERIN)
            0400 PDV TXA
            0410     PHA
            0420     LDA PDVREG
            0430     AND PINTMSK
            0440     BEQ MSK
            0450     JMP (VPIRQ)
            0460 MSK LDX #$06
            0470 LOOP LDA MASKTAB,X
            0480     CPX #$05
            0490     BNE BPS1
            0500     AND IRQENS
            0510     BEQ BPS2
            0520 BPS1 BIT IRQST
            0530     BEQ FIN
            0540 BPS2 DEX
            0550     BPL LOOP
            0560     JMP PRC
            0570 FIN EOR #$FF
            0580     STA IRQST
            0590     LDA IRQENS
            0600     STA IRQST
            0610     CPX #$00
            0620     BNE NEW
            0630     LDA KEYDIS
            0640     BNE PRC
            0650 NEW LDA VECTAB,X
            0660     TAX
            0670     LDA DLIV,X
            0680     STA NEWIOP
            0690     LDA DLIV+1,X
            0700     STA NEWIOP+1
            0710     PLA
            0720     TAX
            0730     JMP (NEWIOP)
            0740 ;
            0750     *=  $C0A0
            0760 ;
            0770 PRC PLA
            0780     TAX
            0790     BIT PACTL
            0800     BPL INT
            0810     LDA PORTA
            0820     JMP (VPRCED)
            0830 INT BIT PBCTL
            0840     BPL BRK
            0850     LDA PORTB
            0860     JMP (VINTER)
            0870 BRK PLA
            0880     STA NEWIOP
            0890     PLA
            0900     PHA
            0910     AND #$10
            0920     BEQ EXIT
            0930     LDA NEWIOP
            0940     PHA
            0950     JMP (VBREAK)
            0960 EXIT LDA NEWIOP
            0970     PHA
            0980 PLARTI PLA
            0990 RTI RTI
            1000 ;
            1010 ;MASK TABle
            1020 ;
            1030 MASKTAB .BYTE $80,$40,$04,$02
            1040     .BYTE $01,$08,$10,$20
            1050 ;
            1060 ;VECtor TABle
            1070 ;
            1080 VECTAB .BYTE $36,$08,$14,$12
            1090     .BYTE $10,$0E,$0C,$0A
    W pierwszej kolejności sprawdzany jest bit 5 IRQST, który sygnalizuje zapełnienie rejestru wejściowego i konieczność odczytania z niego danych. Gdy bit 5 jest skasowany, sterowanie zostaje przekazane do procedury ISRSIR.

    Następnie przez porównywanie poszczególnych bitów w rejestrach PDVREG i PINTMSK (Parallel INTerrupt MaSK) sprawdzane jest, czy źródłem żądania przerwania jest nowe urządzenie dołączone do szyny równoległej. Jeśli tak, to wykonywany jest skok do procedury obsługi tego przerwania wskazanej wektorem VPIRQ (Vector Parallel IRQ).

    Teraz sprawdzane są pozostałe bity rejestru IRQST w kolejności określonej przez maski bitowe z tabeli MASKTAB. Kolejność ta wyznacza więc priorytet przerwań maskowalnych. Po znalezieniu skasowanego bitu pozostałe są ustawiane, aby zablokować przerwania o niższym priorytecie. Gdy przerwanie zostało wywołane naciśnięciem klawisza (oprócz BREAK), to sprawdzane jest jeszcze, czy rejestr KEYDIS (KEYboard DISable) nie wskazuje zablokowania klawiatury.

    Następnie według znalezionego źródła przerwania odszukiwany jest w tabeli VECTAB indeks jego wektora. Wektor ten jest umieszczany w rejestrze NEWIOP i wykonywany jest skok pod zawarty tam adres. W ten sposób wywoływane są procedury ISRODN, ISRXD, CPUIRQ i BREAKIRQ. Pozostałe trzy wektory procedur obsługi przerwań wywołanych przez liczniki POKEY-a nie są normalnie wykorzystywane przez OS. Wskazują one na sekwencję rozkazów PLA, RTI i powodują powrót z przerwania.

    Jeżeli do tej pory nie zostało znalezione źródło przerwania, to sprawdzane są jeszcze porty układu PIA. Stwierdzenie żądania przerwania przez port A powoduje skok pod adres wskazany wektorem VPRCED (Vector PRoCEeD), a przez port B - wektorem VINTER (Vector INTERrupt). Także te procedury nie są używane przez system i przerwania kończy się sekwencją PLA, RTI.

    Na końcu kontrolowany jest bit B rejestru statusu procedora sprzed przerwania (trzeba go więc pobrać ze stosu). Jeśli bit B jest ustawiony, to znaczy, że przerwanie zostało wywołane rozkazem BRK i następuje skok pod adres umieszczony w rejestrze VBREAK (normalnie wskazuje on PLA, RTI - koniec przerwania).

    Jeżeli nie zostało odnalezione żadne źródło przerwania, to system operacyjny zakłada, że wystąpił jakiś błąd i kończy procedurę przerwania.

3.2.2. Przerwanie odczytu z szyny szeregowej

    Kontrolujący komunikację z urządzeniami zewnętrznymi poprzez szynę szeregową układ POKEY jest głównym źródłem przerwań maskowalnych. Jednocześnie z sygnałem żądania przerwania kasuje on odpowiedni bit rejestru IRQST, aby wskazać systemowi operacyjnemu konkretną przyczynę przerwania. Najwyższy priorytet ma przerwanie wywoływane przez POKEY, gdy w rejestrze SERIN (SERial INput) pojawi się bajt danych z urządzenia zewnętrznego. Kasowany jest wtedy bit 5 rejestru IRQST i procedura SINRDYI po rozpoznaniu źródła przerwania wywołuje procedurę ISRSIR
            0100 ;Interrupt Service Routine
            0110 ;at Serial Input Ready
            0120 ;
            0130 BUFEN = $34
            0140 BUFR =  $32
            0150 BUFRFL = $38
            0160 CHKSUM = $31
            0170 NOCKSM = $3C
            0180 RECVND = $39
            0190 SERIN = $D20D
            0200 SKSTAT = $D20F
            0210 SKSTRES = $D20A
            0220 STATUS = $30
            0230 ;
            0240     *=  $EB2E
            0250 ;
            0260     LDA SKSTAT
            0270     STA SKSTRES
            0280     BMI NER1
            0290     LDY #$8C
            0300     STY STATUS
            0310 NER1 AND #$20
            0320     BNE NER2
            0330     LDY #$8E
            0340     STY STATUS
            0350 NER2 LDA BUFRFL
            0360     BEQ EMPTY
            0370     LDA SERIN
            0380     CMP CHKSUM
            0390     BEQ END
            0400     LDY #$8F
            0410     STY STATUS
            0420 END LDA #$FF
            0430     STA RECVND
            0440 EXIT PLA
            0450     TAY
            0460     PLA
            0470     RTI
            0480 EMPTY LDA SERIN
            0490     LDY #$00
            0500     STA (BUFR),Y
            0510     CLC
            0520     ADC CHKSUM
            0530     ADC #$00
            0540     STA CHKSUM
            0550     INC BUFR
            0560     BNE BPS
            0570     INC BUFR+1
            0580 BPS LDA BUFR
            0590     CMP BUFEN
            0600     LDA BUFR+1
            0610     SBC BUFEN+1
            0620     BCC EXIT
            0630     LDA NOCKSM
            0640     BEQ CKS
            0650     LDA #$00
            0660     STA NOCKSM
            0670     BEQ END     
            0680 CKS LDA #$FF
            0690     STA BUFRFL
            0700     BNE EXIT
    Procedura ISRSIR najpierw sprawdza rejestr statusu złącza szeregowego i klawiatury SKSTAT. Poszczególne bity tego rejestru sygnalizują prawidłowość operacji odczytu. Gdy ustawiony jest bit 7, to znaczy, że odczytano zbyt mało lub zbyt dużo bitów. Powoduje to wpisanie do rejestru STATUS kodu błędu $8C (tzw. Framing Error). Ustawienie bitu 5 oznacza przepełnienie bufora i powoduje sygnalizowanie błędu o kodzie $8E (SIO Overrun).

    Następnie sprawdzany jest znacznik zapełnienia bufora wejściowego, w którym wartość różna od zera oznacza pełny bufor. W takim przypadku odebrany bajt danych traktowany jest jako suma kontrolna i porównywany z zawartością rejestru CHKSUM. Gdy są one różne, to sygnalizowany jest błąd sumy kontrolnej (kod $8F). Przed końcem procedury wskaźnik zakończenia transmisji RECVND (RECeiVe eND) jest jeszcze ustawiany na wartość $FF.

    Jeśli bufor wejściowy nie został jeszcze zapełniony, to bajt z rejestru wejściowego SERIN zostaje umieszczony w buforze i adres bufora (BUFR - BUFfeR) zwiększa się o jeden. Teraz następuje porównanie tego adresu z adresem końca bufora (BUFEN - BUFfer ENd). Gdy są one różne, procedura się kończy. W przeciwnym razie sprawdzany jest znacznik NOCKSM (NO ChecK SuM). Jego zawartość równa zero oznacza, że po danych nastąpi suma kontrolna. Wskaźnik zapełnienia bufora ustawiany jest więc na wartość $FF i procedura się kończy. Jeżeli wskaźnik NOCKSM ma wartość różną od zera, to znaczy, że nie będzie sumy kontrolnej. W tym przypadku przed zakończeniem przerwania wskaźnik RECVND otrzymuje wartość $FF, a NOCKSM - wartość zero.

3.2.3. Przerwanie zapisu na szynę szeregową.

    Stwierdzenie przez procedurę SINDRYI skasowania bitu 4 rejestru IRQST oznacza, że rejestr wyjściowy SEROUT został opróżniony i konieczne jest umieszczenie w nim następnego bajtu do zapisu na urządzeniu zewnętrznym. Wywoływana jest w tym celu procedura ISRODN.
            0100 ;Interrupt Service Routine
            0110 ;if Output Data Needed
            0120 ;
            0130 BUFEN = $34
            0140 BUFR = $32
            0150 CHKSNT = $3B
            0160 CHKSUM = $31
            0170 IRQEN = $D20E
            0180 IRQEND = $10
            0190 SEROUT = $D20D
            0200 ;
            0210     *=  EAAD
            0220 ;
            0230     TYA
            0240     PHA
            0250     INC BUFR
            0260     BNE BPS
            0270     INC BUFR+1
            0280 BPS LDA BUFR
            0290     CMP BUFEN
            0300     LDA BUFR+1
            0310     SBC BUFEN+1
            0320     BCC CONT
            0330     LDA CHKSNT
            0340     BNE SEND
            0350     LDA CHKSUM
            0360     STA SEROUT
            0370     LDA #$FF
            0380     STA CHKSNT
            0390     BNE EXIT
            0400 SEND LDA IRQENS
            0410     ORA #$08
            0420     STA IRQENS
            0430     STA IRQEN
            0440 EXIT PLA
            0450     TAY
            0460     PLA
            0470     RTI
            0480 CONT LDY #$00
            0490     LDA (BUFR),Y
            0500     STA SEROUT
            0510     CLC
            0520     ADC CHKSUM
            0530     ADC #$00
            0540     STA CHKSUM
            0550     JMP EXIT
    Na początku procedury adres bufora wyjściowego jest zwiększany o jeden i porównywany z adresem końca bufora. Jeżeli są one różne, to bajt danych z bufora jest przesyłany do rejestru SEROUT (SERial OUTput) oraz dodawany do zawartości rejestru CHKSUM.

    Gdy cały bufor został opróżniony, to sprawdzany jest wskaźnik CHKSNT (CHecK sum SeNT). Jeśli jest równy zero, to do rejestru SEROUT przepisywana jest suma kontrolna z rejestru CHKSUM i znacznik CHKSNT otrzymuje wartość $FF.

    Jeżeli CHKSNT wa wartość $FF, to znaczy, że suma kontrolna nie będzie wysyłana i bit 3 rejestru IRQEN jest ustawiany, co zezwala na wywołanie przerwania przez koniec transmisji.

3.2.4. Przerwanie końca transmisji szeregowej.

            0100 ;Interrupt Service Routine
            0110 ;if eXmitend Data
            0120 ;
            0130 CHKSNT = $3B
            0140 IRQEN = $D20E
            0150 IRQENS = $10
            0160 XMTDON = $3A
            0170 ;
            0180     *=  $EAEC
            0190 ;
            0200     LDA CHKSNT
            0210     BEQ EXIT
            0220     STA XMTDON
            0230     LDA IRQENS
            0240     AND #$F7
            0250     STA IRQENS
            0260     STA IRQEN
            0270 EXIT PLA
            0280     RTI
    Skasowanie bitu 3 w rejestrze IRQST sygnalizuje zakończenie transmisji szeregowej i powoduje wywołanie z SINDRYI procedury ISRXD.

    Najpierw badany jest wskaźnik CHKSNT. Jeśli jest równy 0, to suma kontrolna nie była wysłana i procedura się kończy. W przeciwnym razie CHKSNT jest przepisywany do wskaźnika XMTDON (eXMiTe DONe) sygnalizującego zakończenie transmisji i w rejestrze IRQEN kasowany jest bit zezwolenia na przerwanie końca transmisji (bit 3).

3.2.5. Przerwanie klawiatury

    Naciśnięcie dowolnego klawisza (oprócz BREAK) powoduje skasowanie bitu 6 rejestru IRQST. Procedura SINDRYI po rozpoznaniu źródła przerwania wywołuje wtedy procedurę CPUIRQ, której zadaniem jest odczyt naciśniętego klawisza.
                           < CPU IRQ >
                                |
                                v
                     nie /-------------\ tak
               +--------< KBCODE=OLDKBC >-------+
               |         \-------------/        |
               |                                v
               v                       tak /--------\
               +<-------------------------< KEYDEL=0 >
               |                           \--------/
               v                            nie |
          /----------\ nie                      v
         < KBCODE=$83 >---------------+      < RPT >
          \----------/                |
               | tak                  v
               v                 /--------\ nie
       +----------------+       < KEYDIS=0 >---------+
       | KEYDIS EOR $FF |        \--------/          |
       +----------------+         tak |              v
               |                      v           < EXIT >
               v                /----------\ tak
       nie /--------\ tak      < KBCODE=$9F >---+
        +-< KEYDIS=0 >-+        \----------/    |
        |  \--------/  |          nie |         v
        v              v              | +----------------+
 +------------+ +------------+        | | SSFLAG EOR $FF |
 | PB AND $FB | | PB ORA $04 |        | +----------------+
 +------------+ +------------+        |         |
        |              |              |         v
        +----->+<------+              |      < CONT >
               |                      v
               v      nie /--------------------\ tak
           < CONT >    +-< (KBCODE AND $3F)=$11 >-+
                       |  \--------------------/  |
                       |                          |
                       v                          v
             tak /----------\ nie      +------------------+
             +--< KBCODE=$84 >---+     | KBCODE -> HLPFLG |
             |   \----------/    |     +------------------+
             v                   v               |
    tak /---------\         /----------\ nie     v
+------< DMACTLS=0 >       < KBCODE=$94 >--+  < CONT >
|       \---------/         \----------/   |
|            | tak               |         +--------+
|            |                   v                  |
|            v           +------------------+       |
|  +-------------------+ | CHBAS <=> CHSPTR |       |
|  | DMACTLS -> DMASAV | +------------------+       |
|  +-------------------+         |                  |
|            |                   v                  |
|            v          tak /---------\ nie         |
|      +-----------+     +-< CHBAS=$CC >-+          |
|      | DMACTLS=0 |     |  \---------/  |          |
|      +-----------+     |               |          |
|            |           v               v          |
|            v     +------------+ +------------+    |
+----------->+     | PB AND $F7 | | PB ORA $08 |    |
             |     +------------+ +------------+    |
             |           |               |          |
             |           +------>+<------+     +----+
             |                   |             |
             |                   |             v
             |                   |   +-------------------+
             |                   |   | KBCODE -> KBCODES |
             |                   |   | KBCODE -> OLDKBC  |
             |    < CONT >       |   +-------------------+
             |        |          v             |
             |        +--------->+<------------+
             |                   |
             |                   v
             |            +------------+
             |            | KEYDEL=$03 |
             |            | ATRACT=$00 |
             |            +------------+    < RPT >
             |                   |             |
             |                   v             |
             |                   +<------------+
             |                   |
             |                   |
             |                   v
             |         +-------------------+
             |         | KRPDEL -> SRTIMER |
             |         +-------------------+
             |                   |
             |                   v
             |         nie  /---------\
             +<------------< DMACTLS=0 >
             |              \---------/
             |                   | tak
             |                   v
             |         +------------------+
             |         | DMASAV -> DMACTL |      < EXIT >
             |         +------------------+         |
             |                   |                  |
             |                   V                  |
             +------------------>+<-----------------+
                                 |
                                 V
                       < koniec przerwania >
    Należy zwrócić uwagę, że znaczna część wykonywanych w tej procedurze czynności dotyczy wyłącznie modelu 1200XL posiadającego klawisze funkcyjne od F1 do F4. Poprzez przedefiniowanie klawiszy można jednak zaimplementować te funkcje w pozostałych modelach serii XL i XE.

    Procedura CPUIRQ rozpoczyna się od porównania kodu naciśniętego klawisza pobranego z rejestru KBCODE (KeyBoard CODE) z kodem zapisanym w rejestrze OLDKBC (OLD KeyBoard Code) podczas poprzedniego przerwania. Jeżeli są takie same, to znaczy, że naciśnięty jest ten sam klawisz. Wtedy sprawdzany jest rejestr KEYDEL (KEYboard DELay) określający czas między dwoma naciśnięciami klawiszy. Gdy jest on różny od zera, to następuje skok do końcowej fazy procedury.

    Jeśli został naciśnięty inny klawisz niż poprzednio lub upłynął czas między dwoma odczytami, to kolejno sprawdzane są specjalne kombinacje klawiszy. Odczytany kod klawisza równy $83 oznacza naciśnięcie CONTROL-F1. Kombinacja ta służy do włączania i wyłączania klawiatury (w 1200XL), więc na zawartości rejestru KEYDIS dokonywana jest operacja EOR $FF, co powoduje przełączenie klawiatury (KEYDIS=0 - klawiatura włączona, KEYDIS=$FF - wyłączona). Następnie jest ustawiany lub kasowany bit 3 rejestru PORTB, który w modelu 1200XL steruje diodą LED 1 sygnalizującą zablokowanie klawiatury. Po zablokowaniu klawiatury procedura się kończy.

    Jako druga sprawdzana jest kombinacja klawiszy CONTROL-1, która zatrzymuje i wznawia przesuw pionowy obrazu (scrolling). Rozpoznanie tej kombinacji (kod $9F) powoduje przełączenie - poprzez EOR $FF - zawartości rejestru SSFLAG (Start/Stop FLAG). Normalnie w rejestrze tym znajduje się wartość 0. Naciśnięcie CONTROL-1 zmienia ją na $FF i powoduje zatrzymanie wyprowadzania danych na ekran. Kolejne naciśnięcie CONTROL-1 przywraca poprzednią sytuację.
            0100 ;CPU Interrupt ReQuest
            0110 ;
            0120 ATRACT = $4D
            0130 CHBAS = $02F4
            0140 CHSPTR = $026B
            0150 DMACTLS = $022F
            0160 DMASAV = $02DD
            0170 HLPFLG = $02DC
            0180 KBCODE = $D209
            0190 KBCODES = $02FC
            0200 KEYDEL = $02F1
            0210 KEYDIS = $026D
            0220 KRPDEL = $02D9
            0230 OLDKBC = $02F2
            0240 PORTB = $D301
            0250 SRTIMER = $022B
            0260 SSFLAG = $02FF
            0270 ;
            0280     *=  $FC19
            0290 ;
            0300     TXA
            0310     PHA
            0320     TYA
            0330     PHA
            0340     LDY PORTB
            0350     LDA KBCODE
            0360     CMP OLDKBC
            0370     BNE NKY
            0380     LDX KEYDEL
            0390     BNE RPT
            0400 NKY LDX KEYDIS
            0410     CMP #$83
            0420     BNE NKB
            0430     TXA
            0440     EOR #$FF
            0450     STA KEYDIS
            0460     BNE KBEN
            0470     TYA
            0480     ORA #$04
            0490     BNE KEND
            0500 KBEN TYA
            0510     AND #$FB
            0520 KEND TAY
            0530     BCS CONT
            0540 NKB TXA
            0550     BNE EXIT
            0560     LDA KBCODE
            0570     TAX
            0580     CMP #$9F
            0590     BNE NC1
            0600     LDA SSFLAG
            0610     EOR #$FF
            0620     STA SSFLAG
            0630     BCS CONT
            0640 NC1 AND #$3F
            0650     CMP #$11
            0660     BNE FKY
            0670     STX HLPFLG
            0680     BEQ CONT
            0690 STORE STX KBCODES
            0700     STX OLDKBC
            0710 CONT LDA #$03
            0720     STA KEYDEL
            0730     LDA #$00
            0740     STA ATRACT
            0750 RPT LDA KRPDEL
            0760     STA SRTIMER
            0770     LDA DMACTLS
            0780     BNE EXIT
            0790     LDA DMASAV
            0800     STA DMACTLS
            0810 EXIT STY PORTB
            0820     PLA
            0830     TAY
            0840     PLA
            0850     TAX
            0860     PLA
            0870     RTI
            0880 FKY CPX #$84
            0890     BEQ DISP
            0900     CPX #$94
            0910     BNE STORE
            0920     LDA CHBAS
            0930     LDX CHSPTR
            0940     STA CHSPTR
            0950     STX CHBAS
            0960     CPX #$CC
            0970     BEQ SET2
            0980     TYA
            0990     ORA $08
            1000     TAY
            1010     BNE CONT
            1020 SET2 TYA
            1030     AND #$F7
            1040     TAY
            1050     JMP CONT
            1060 DISP LDA DMACTLS
            1070     BEQ EXIT
            1080     STA DMASAV
            1090     LDA #$00
            1100     STA DMACTLS
            1110     BEQ EXIT
    Następnie badane jest, czy sześć młodszych bitów rejestru KBCODE ma wartość $11, co oznacza naciśnięcie klawisza HELP (w dowolnej kombinacji z SHIFT i/lub CONTROL). Jeśli tak, to zawartość KBCODE jest przepisywana do HLPFLG (HeLP FLaG).

    Jako ostatnie sprawdzane są dwie kombinacje klawiszy charakterystyczne dla 1200XL. Kod $84 oznacza kombinację CONTROL-F2, a kod $94 kombinację CONTROL-F4. Pierwsza z nich włącza i wyłącza dostęp ANTIC-a do pamięci, a więc włącza i wyłącza obraz. Na czas wyłączenia obrazu zawartość rejestru DMACTLS (DMA ConTroL Shadow register) jest przechowywana w DMASAV (DMA SAVe).

    Kombinacja CONTROL-F4 przełącza wbudowane zestawy znaków: standardowy i międzynarodowy. W tym przypadku zamieniane są miejscami zawartości wektorów CHBAS (CHaracter set BASe) i CHSPTR (CHaracter Set PoinTeR) oraz ustawiany lub kasowany jest bit 4 PORTB, który w 1200XL steruje diodą LED 2 (świeci się przy korzystaniu z zestawu międzynarodowego).

    Gdy nie została rozpoznana żadna z wymienionych kombinacji klawiszy, to kod naciśniętego klawisza jest zapisywany do rejestrów KBCODES i OLDKBC, rejestr KEYDEL otrzymuje wartość 3, a ATRACT jest zerowany. Następnie zawartość KRPDEL (Key RePeat DELay) jest przepisywana do licznika SRTIMER i procedura się kończy.

3.2.6. Przerwanie klawisza BREAK

    Klawisz BREAK posiada szczególne znaczenie i jego naciśnięcie jest oddzielnie sygnalizowane w bicie 7 rejestru IRQST. Przerwanie wywołane naciśnięciem tego klawisza jest obsługiwane przez procedurę BREAKIRQ.
            0100 ;BREAK key IRQ
            0110 ;
            0120 ATRACT = $4D
            0130 CRSINH = $02F0
            0140 IRQSTAT = $11
            0150 SSFLAG = $02FF
            0160 ;
            0170     *=  $C092
            0180 ;
            0190     LDA #$00
            0200     STA IRQSTAT
            0210     STA SSFLAG
            0220     STA CRSINH
            0230     STA ATRACT
            0240     PLA
            0250     RTI
    Jedynym zadaniem tej procedury jest wyzerowanie rejestrów IRQSTAT, SSFLAG, ATRACT i CRSINH. Znaczenie trzech pierwszych było już omawiane. Rejestr CRSINH (CuRSor INHibition) określa widoczność kursora. Jeżeli zawiera on wartość różną od zera, to kursor jest niewidoczny na ekranie.

3.2.7. Przerwanie nowego urządzenia

    Jako ostatnie zostanie omówione przerwanie, które ma drugi priorytet - ustępuje jedynie przerwaniu wywołanemu przez odczyt z szyny szeregowej. Jest to przerwanie wywoływane przez nowe urządzenie przyłączone do szyny równoległej. Znaczenie określenia "nowe urządzenie" zostało wyjaśnione wcześniej.

    Żądanie przerwania jest sygnalizowane przez nowe urządzenie w rejestrze PINTMSK i procedura SINDRYI po sprawdzeniu istnienia urządzenia (w rejestrze PDVREG) wywołuje procedurę NEWIOREQ.
            0100 ;NEW I/O REQest
            0110 ;
            0120 BITMASK = $CA21
            0130 DEVINT = $D808
            0140 PDVREG = $D1FF
            0150 PDVRS = $0248
            0160 ;
            0170     *=  $C96E
            0180 ;
            0190     LDX #$08
            0200 NEXT ROR A
            0210     BCS FIND
            0220     DEX
            0230     BNE NEXT
            0240 FIND LDA PDVRS
            0250     PHA
            0260     LDA BITMASK-1,X
            0270     STA PDVRS
            0280     STA PDVREG
            0290     JSR DEVINT
            0300     PLA
            0310     STA PDVRS
            0320     STA PDVREG
            0330     PLA
            0340     TAX
            0350     PLA
            0360     RTI
    Przed wywołaniem tej procedury w akumulatorze ustawione są bity odpowiadające urządzeniom żądającym przerwania. Po znalezieniu urządzenia, które wysłało sygnał żądania przerwania, aktualna zawartość rejestru PDVRS jest odkładana na stos, a w PDVRS jest umieszczana odpowiednia maska bitowa pobrana z tabeli BITMASK.
            1000 ;BIT MASK
            1010 ;
            1020     *=  $CA21
            1030 ;
            1040     .BYTE $80,$40,$20,$10
            1050     .BYTE $08,$04,$02,$01
    Następnie wywoływana jest znajdująca się w pamięci ROM nowego urządzenia procedura obsługi przerwania DEVINT (DEVice INTerrupt). Po jej zakończeniu odtwarzana jest ze stosu zawartość rejestrów PDVRS i PDVREG i na tym przerwanie jest zakończone.
Zientara Wojciech: Mapa pamięci Atari XL/XE. Podstawowe procedury systemu operacyjnego, SOETO, Warszawa, 1988.