Powrót do spisu treści

Rozdział 2

PROCEDURY STARTU KOMPUTERA

2.1. Główna procedura RESET

    Po włączeniu zasilania komputera oraz po naciśnięciu klawisza RESET, który zeruje układy komputera, konieczne jest zainicjowanie pracy systemu. Zadanie to wykonuje procedura RESET mająca dwa warianty przebiegu.

    Wariant zimnego startu (RESET COLD) jest wykonywany zawsze po włączeniu zasilania (tzw. Power Up). Po naciśnięciu klawisza RESET wykonywany jest wariant startu gorącego (RESET WARM). Należy pamiętać, że dokonanie zmian w niektórych rejestrach systemowych w obszarze RAM może spowodować przejście z procedury startu gorącego do startu zimnego. Odwrotna zmiana wariantu procedury jest niemożliwa.

2.1.1. Struktura procedury RESET

    Cały przebieg procedury startu jest bardzo skomplikowany, zostanie więc przedstawiony etapami poczynając od schematu blokowego.
                       <RESET>
                          |
                       +-----+
                       | SEI |
                       +-----+
                          |
                          v
                   +-------------+
                   | sprawdzenie | 
                   | zawartości  | niepoprawna
                   |  rejestrów  |---->-----+
                   |   PUPBT1-3  |          |
                   +-------------+          |
                          |                 |
                 poprawna |                 |
                          v                 |
                      <RESETWM>             |
                          |                 |
                          v                 |
                     /---------\            |
                    / cartridge \  tak      v
                   < wyjęty  lub >----->--->+
                    \ włożony ? /           |
                     \---------/            |
                          | nie             |
                          |                 |
                          v                 |
                    /-----------\           |
              nie  /  czy  jest  \          |
           +-<----<   dołączony   >         |
           |       \ cartridge ? /          |
           |        \-----------/           |
           |              | tak             |
           |              v                 |
           |        ++---------++           |
           |        || NEWCART ||           |
           |        ++---------++           |
           |              |                 |
           |              v                 |
           |          /-------\ tak         |
           |         <  nowy?  >--->------->+
           |          \-------/             |
           |              | nie             |
           |              v                 |
           +--------------+                 |
                          |                 |   <POWER UP>
                          v                 |        |
                      /--------\ nie        v        |
                     < COLDST=0 >--->------>+<-------+
                      \--------/            |
                       tak |                |
                           |            <RESETCD>
                           |                |
                           v                v
                    +------------|    +----------+
                    | WARMST=$FF |    | WARMST=0 |
                    +------------+    +----------+
                           |                |
                           +------->+<------+
                                    |
                                    v
                                 +-----+
                                 | SEI |
                                 | CLD |
                                 +-----+
                                    |
                                    v
                               ++--------++
                               || CARTGO ||
                               ++--------++
                                    |
                                    |
                                    v
                          nie  /--------\  tak
                     +---<----< WARMST=0 >---->---+
                     |         \--------/         |
                     v                            v
                  <WARM2>                 +---------------+
                     |                    | zerowanie RAM |
                     v                    |  w  obszarze  |
            tak  /-------\                |  $0008-$FFFF  |
         +-<----< DERRF=0 >               +---------------+
         |       \-------/                        |
         |           | nie                        v
         |           v                   +----------------+
         |     +----------+              | DOSVEC=TESTROM |
         |     | APPMHI=0 |              +----------------+
         |     +----------+                       |
         |           |                            v
         +---------+ |                     +-------------+
                   | |                     | sprawdzenie |
                   v v                     | pamięci ROM |
            +---------------+              +-------------+
            | zerowanie RAM |                     |
            |  w obszarach  |                     v
            |  $0200-$03ED  |              +------------+
            |   i $10-$7F   |              | COLDST=$FF |
            +---------------+              +------------+
                    |                             |
                    +------------->+<-------------+
                                   |
                                   v
                                <COLD2>
                                   |
                                   v
                             /----------\
                        tak / czy BASIC  \ nie
                    +--<---<     jest     >--->--+
                    |       \ dołączony? /       |
                    |        \----------/        |
               +----------+                +----------+
               | BASICF=0 |                | BASICF=1 |
               +----------+                +----------+
                    |                            |
                    +------------->+<------------+
                                   |
                                   |
                                   v
                            +--------------+
                            |  ustawienie  |
                            |   PUPBT1-3   |
                            | i marginesów |
                            +--------------+
                                   |
                            +--------------+
                            |  ustawienie  |
                            |  parametrów  |
                            | zależnych od |
                            |  systemu TV  |
                            +--------------+
                                   |
                           +---------------+
                           | przeniesienie |
                           |   wektorów    |
                           |   przerwań    |
                           |   i tabeli    |
                           |  sterowników  |
                           | z ROM  do RAM |
                           +---------------+
                                   |
                                   v
                             ++---------++
                             || SYSINIT ||
                             ++---------++
                                   |
                              /---------\
                             /   udane   \nie ++---------++
                            < inicjowanie >-->|| TESTINI ||
                             \ systemu ? /    ++---------++
                              \---------/
                                   | tak
                                   v
                          nie /----------\
                    +----<---< RAMSIZ>$B0 >
                    |         \----------/
                    v              | tak
              /----------\         |
             /  czy jest  \ nie    v
            < w  gnieździe >--->-->+
             \ cartridge? /        |
              \----------/         |
                tak |              |
                    |              |
                    v              |
              ++---------++        |
              || NEWCART ||        |
              ++---------++        |
                    |              |
                    v              |
              ++----------++       |
              || INITCART ||       |
              ++----------++       |
                    |              v
                    +------------->+
                                   |
                                   v
                             +-----------+
                             |  otwarcie |
                             |  edytora  |
                             +-----------+
                                   |
                                   v
                               /-------\ nie    +-------+
                              < udane ? >------>| RESET |
                               \-------/        +-------+
                               tak |
                                   v
                             ++---------++
                             || CASBOOT ||
                             ++---------++
                                   |
                                   v
                       nie /---------------\ tak
                  +---<---< jest cartridge? >--->---+
                  |        \---------------/        |
                  |                                 v
                  |                          /---------\
                  v                     tak /  wykonać  \
                  +<-------------------<---<    odczyt   >
                  |                         \ z dysku ? /
                  v                          \---------/
              ++------++                      nie |
              || BOOT ||                          |
              ++------++                          |
                  |                               |
                  +--------------->+<-------------+
                                   |
                                   |
                                   v
                              +----------+
                              | COLDST=0 |
                              +----------+
                                   |
                                   v
                       nie /---------------\ tak
                  +---<---< jest cartridge? >---+
                  |        \---------------/    |
                  |                             v
                  |                     /---------------\
                  v                nie /    przekazać    \
                  +<--------------<---<    sterowanie     >
                  |                    \ do cartridge'a? /
                  |                     \---------------/
                  |                         tak |
                  v                             v
             ++--------++                 ++---------++
             || DOSVEC ||                 || CARTRUN ||
             ++--------++                 ++---------++

2.1.2. Przebieg procedury RESET

    Po włączeniu zasilania układy wewnętrzne komputera ustawiają (na drodze sprzętowej) licznik programu procesora na wartość RESETCD ($C2C8). Po przekazaniu sterowania procesorowi zaczyna on wykonywanie programu od tego właśnie miejsca.

    Odmiennie zachowuje się procesor po otrzymaniu sygnału RESET. Pobiera on dwa bajty z rejestru RESETVEC ($FFFC) i umieszcza je w liczniku programu. Ta operacja także dokonywana jest sprzętowo. W komputerach Atari w rejestrze RESETVEC znajduje się adres procedury RESET ($C2AA). Od tego więc miejsca kontynuowane jest wykonywanie programu.

    Zasadnicza procedura RESET przedstawia się następująco:
0100 ; RESET                   0270 DERRF = $03EC
0110 ;                         0280 DLIV =  $0200
0120 APPMHI = $0E              0290 DOSVEC = $0A
0130 BASICF = $03F8            0300 GINTLK = $03FA
0140 BOOT = $C58B              0310 HATABS = $031A
0150 CARTGO = $C471            0320 ICAX1 = $034A
0160 CARTINI = $BFFE           0330 ICBUFA = $0344
0170 CARTINS = $BFFC           0340 ICCMD = $0342
0180 CARTOPT = $BFFD           0350 INIT31A = $C42E
0190 CARTRUN = $BFFA           0360 INIT200 = $C44B
0200 CASBOOT = $C66E           0370 JCIOMAIN = $E456
0210 CHBAS = $02F4             0380 KEYREP = $02DA
0220 CHACTL = $02F3            0390 KRPDEL = $02D9
0230 CKROM1 = $FF73            0400 LINKSOM = $E739
0240 CKROM2 = $FF92            0410 LMARGIN = $52
0250 COLDST = $0244            0420 LNFLG = $00
0260 DDEVIC = $0300            0430 NEWCART = $C4C9

0440 NGFLAG = $01              1000     BNE WARM2
0450 PAL =   $D014             1010     LDA #$00
0460 PALNTS = $62              1020     LDY #$08
0470 PORTB = $D301             1030     STA RAMLO
0480 PUPBT1 = $033D            1040     STA RAMLO+1
0490 PUPBT2 = $033E            1050 LOOP LDA #$FF
0500 PUPBT3 = $033F            1060     STA (RAMLO),Y
0510 RAMLO = $04               1070     CMP (RAMLO),Y
0520 RAMSIZ = $02E4            1080     BEQ OK1
0530 RMARGIN = $53             1090     LSR NGFLAG
0540 SYSINIT = $C535           1100 OK1 LDA #$00
0550 TESTINI = $5003           1110     STA (RAMLO),Y
0560 TESTROM = $F223           1120     CMP (RAMLO),Y
0570 TRAMSZ = $06              1130     BEQ OK2
0580 TRIG3 = $D013             1140     LSR NGFLAG
0590 WARMST = $08              1150 OK2 INY
0600 ;                         1160     BNE LOOP1
0610     *=  $C290             1170     INC RAMLO+1
0620 ;                         1180     LDX RAMLO+1
0630 RESETWM SEI               1190     CPX TRAMSZ
0640     LDA TRIG3             1200     BNE LOOP1
0650     CMP GINTLK            1210     LDA # <TESTROM
0660     BNE RESETCD           1220     STA DOSVEC
0670     ROR A                 1230     LDA # >TESTROM
0680     BCC OLDCART           1240     STA DOSVEC+1
0690     JSR NEWCART           1250     LDA PORTB
0700     BNE RESETCD           1260     AND #$7F
0710 OLDCART LDA COLDST        1270     STA PORTB
0720     BNE RESETCD           1280     JSR CKROM1
0730     LDA #$FF              1290     BCS BAD
0740     BNE CONT              1300     JSR CKROM2
0750 RESET SEI                 1310     BCC ROMOK
0760     LDX #$8C              1320 BAD LSR NGFLAG
0770 DELAY1 DEY                1330 ROMOK LDA PORTB
0780     BNE DELAY1            1340     ORA #$80
0790     DEX                   1350     STA PORTB
0800     BNE DELAY1            1360     LDA #$FF
0810     LDA PUPBT1            1370     STA COLDST
0820     CMP #$5C              1380     BNE COLD2
0830     BNE RESETCD           1390 WARM2 LDX #$00
0840     LDA PUPBT2            1400     LDA DERRF
0850     CMP #$93              1410     BEQ LOOP2
0860     BNE RESETCD           1420     STX APPMHI
0870     LDA PUPBT3            1430     STX APPMHI+1
0880     CMP #$25              1440     TXA
0890     BEQ RESETWM           1450 LOOP2 STA DLIV,X
0900 RESETCD LDA #$00          1460     CPX #$ED
0910 CONT STA WARMST           1470     BCS BYPASS
0920     SEI                   1480     STA DDEVIC,X
0930     CLD                   1490 BYPASS DEX
0940     LDX #$FF              1500     BNE LOOP2
0950     TXS                   1510     LDX #$10
0960     JSR CARTGO            1520 LOOP3 STA LNFLG,X
0970     LDA #$01              1530     INX
0980     STA NGFLAG            1540     BPL LOOP3
0990     LDA WARMST            1550 COLD2 LDX #$00

1560     LDA PORTB             2060 NOERR LDX #$00
1570     AND #$02              2070     STX TRAMSZ
1580     BEQ BASICON           2080     LDX RAMSIZ
1590     INX                   2090     CPX #$B0
1600 BASICON STX BASICF        2100     BCS NOCART
1610     LDA #$5C              2110     LDX CARTINS
1620     STA PUPBT1            2120     BNE NOCART
1630     LDA #$93              2130     INC TRAMSZ
1640     STA PUPBT2            2140     JSR NEWCART
1650     LDA #$25              2150     JSR INITCART
1660     STA PUPBT3            2160 NOCART LDA #$03
1670     LDA #$02              2170     LDX #$00
1680     STA LMARGIN           2180     STA ICCMD,X
1690     LDA #$27              2190     LDA # <NAME
1700     STA RMARGIN           2200     STA ICBUFA,X
1710     LDA PAL               2210     LDA # <NAME
1720     AND #$0E              2220     STA ICBUFA+1,X
1730     BNE TVPAL             2230     LDA #$0C
1740     LDA #$05              2240     STA ICAX1,X
1750     LDX #$01              2250     JSR JCIOMAIN
1760     LDY #$28              2260     BPL DELAY2
1770     BNE SETTV             2270     JMP RESET
1780 TVPAL LDA #$06            2280 DELAY2 INX
1790     LDX #$00              2290     BNE DELAY2
1800     LDY #$30              2300     INY
1810 SETTV STA KEYREP          2310     BPL DELAY2
1820     STX PALNTS            2320     JSR CASBOOT
1830     STY KRPDEL            2330     LDA TRAMSZ
1840     LDX #$25              2340     BEQ DBOOT
1850 LOOP4 LDA INIT200,X       2350     LDA CARTBOOT
1860     STA DLIV,X            2360     ROR A
1870     DEX                   2370     BCC NOBOOT
1880     BPL LOOP4             2380 DBOOT JSR BOOT
1890     LDX #$0E              2390     JSR LINKSOM
1900 LOOP5 LDA INIT31A,X       2400 NOBOOT LDA #$00
1910     STA HATABS,X          2410     STA COLDST
1920     DEX                   2420     LDA TRAMSZ
1930     BPL LOOP5             2430     BEQ DOSVECC
1940     JSR SYSINIT           2440     LDA CARTOPT
1950     CLI                   2450     AND #$04
1960     LDA NGFLAG            2460     BEQ DOSVECC
1970     BNE NOERR             2470 COLDCART JMP (CARTRUN)
1980     LDA PORTB             2480 DOSVECC JMP (DOSVEC)
1990     AND #$7F              2490 INITCART JMP (CARTINI)
2000     STA PORTB             2500 CLCRTS CLC
2010     LDA #$02              2510     RTS
2020     STA CHACTL            2520 ;
2030     LDA #$E0              2530     *= $C448
2040     STA CHBAS             2540 NAME .BYTE "E:",$9B
2050 GOMEMTST JMP TESTINI
    Przebieg procedury RESET zależy w znacznym stopniu od rodzaju startu (zimny czy gorący). Przy gorącym starcie przede wszystkim kontrolowane są różne rejestry systemowe w celu sprawdzenia, czy nie zachodzi konieczność wykonania zimnego startu.

    Najpierw sprawdzane są trzy rejestry PUPBT (Power UP Byte), które muszą zawierać ściśle określone wartości - kolejno $5C, $93 i $25. W następnej kolejności kontrolowana jest obecność cartridge'a oraz jego rodzaj. Jeżeli został on wyjęty, włożony lub zamieniony, to cały system inicjowany jest ponownie. Wykorzystywany tu rejestr TRIG3 jest ustawiany na drodze sprzętowej i zawiera 1, jeśli jest dołączony zewnętrzny cartridge. Wartość rejestru GINTLK jest ustalana według TRIG3 podczas inicjowania komputera. Niezgodność ich zawartości powoduje więc przejście do zimnego startu.

    Na końcu tego etapu kontrolowany jest wskaźnik COLDST. Jeżeli jego wartość jest różna od zera, także następuje przejście do zimnego startu. Gdy wszystkie sprawdzenia wypadły pomyślnie, wskaźnik WARMST uzyskuje wartość $FF (służy on póżniej do rozróżniania rodzaju startu.

    Jeżeli zostało włączone zasilanie lub system rozpoznał konieczność dokonania zimnego startu, to wskaźnik WARMST jest ustawiany na wartość zero. Od tego miejsca obie procedury przebiegają wspólnie.

    Następnie wywoływana jest procedura CARTGO, która sprawdza obecność cartridge'a i rozpoznaje jego rodzaj, inicjuje porty I/O, oraz sprawdza wielkość dostępnej pamięci RAM. Obliczona wielkość RAM (w stronach) jest umieszczana w rejestrze TRAMSZ. Kolejnym etapem jest zerowanie pamięci RAM. Przy starcie zimnym kasowana jest zawartość całej pamięci od adresu $08 do wartości umieszczonej w TRAMSZ. Podczas startu gorącego wyzerowaniu ulegają jedynie obszary od $10 do $7F oraz od $0200 do $03ED. Procedura zimnego startu sprawdza jeszcze poprawność pamięci ROM przez przeliczenie sum kontrolnych oraz ustawia wskaźnik COLDST na wartość $FF i wektor DOSVEC na adres procedury TESTROM.

    Teraz następuje ustawienie wartości w rejestrach systemu operacyjnego w pamięci RAM. Najpierw wskaźnik BASICF otrzymuje wartość 0, gdy interpreter Basica jest dołączony lub 1, gdy jest odłączony. Do rejestrów PUPBT wpisywane są odpowiednie wartości (zob. wyżej) oraz ustawiane są marginesy ekranu. Po rozpoznaniu według zawartości rejestru PAL rodzaju systemu telewizyjnego (PAL czy NTSC) ustalane są wartości zmiennych systemowych zależnych od częstotliwości zegara taktującego (PAL ma 50 Hz, a NTSC - 60 Hz). Są to wielkości określające szybkość powtarzania klawisza (KEYREP) oraz czas rozpoczęcia powtarzania przy stałym jego wciśnięciu (KRPDEL).

    Wektory systemu znajdujące się na drugiej stronie pamięci są teraz przepisywane z tabeli INIT200, która jest umieszczona w ROM-ie. Tabela ta zawiera systemowe wektory przerwań maskowalnych i niemaskowalnych, zajmujące obszar $0200-$0225.
            0100 ;INITiation table $200
            0110 ;
            0120 CPUIRQ = $FC19
            0130 EXITVBL = $C28A
            0140 ISRODN = $EAAD
            0150 ISRSIR = $EB2E
            0160 ISRXD = $EAEC
            0170 PLARTI = $C0CD
            0180 RTI =   $C0CE
            0190 SINDRYI = $C030
            0200 SYSVBL = $C0E2
            0210 ZERO =  $00
            0220 ;
            0230     *=  $C44B
            0240 ;
            0250 INIT200 .WORD RTI,PLARTI
            0260     .WORD PLARTI,PLARTI
            0270     .WORD CPUIRQ,ISRSIR
            0280     .WORD ISRODN,ISRXD
            0290     .WORD PLARTI,PLARTI
            0300     .WORD PLARTI,SINDRYI
            0310     .WORD ZERO,ZERO
            0320     .WORD ZERO,ZERO
            0330     .WORD ZERO,SYSVBL
            0340     .WORD EXITVBL
    Następnie przenoszona jest tabela adresów procedur obsługi urządzeń zewnętrznych (HATABS). Nie jest ona wypełniana w całości, gdyż tabela INIT31A zawiera jedynie adresy procedur zapisanych w ROM-ie. Znajdują się tam adresy procedur obsługi edytora (E:), ekranu (S:), klawiatury (K:), drukarki (P:) i magnetofonu (C:).
            0100 ;INITiation table $31A
            0110 ;
            0120 CASVEC = $E440
            0130 EDTVEC = $E400
            0140 KBDVEC = $E420
            0150 PRTVEC = $E430
            0160 SCRVEC = $E410
            0170 ;
            0180     *= $C42E
            0190 ;
            0200 INIT31A .BYTE 'P
            0210     .WORD PRTVEC
            0220     .BYTE 'C
            0230     .WORD CASVEC
            0240     .BYTE 'E
            0250     .WORD EDTVEC
            0260     .BYTE 'S
            0270     .WORD SCRVEC
            0280     .BYTE 'K
            0290     .WORD KBDVEC
    Procedury obsługi innych urządzeń (np. stacji dysków lub modemu) są zapisywane w pamięci RAM i dla udostępnienia ich systemowi operacyjnemu tabela HATABS jest uzupełniana podczas późniejszego instalowania tych urządzeń.

    Po tych wszystkich operacjach wywoływana jest procedura SYSINIT, która przeprowadza inicjowanie pozostałej części systemu oraz urządzeń zewnętrznych. Będzie ona dokładnie opisana w dalszej części.

    Błędy występujące podczas wykonywania powyższych procedur są sygnalizowane w rejestrze NGFLAG. Po zakończeniu SYSINIT zawartość tego rejestru jest kontrolowana i gdy wskazuje błędy, to program przechodzi do wbudowanej procedury testowania komputera (tzw. SELFTEST). W przeciwnym wypadku kontynuowana jest procedura RESET.

    Jeżeli dołączony jest cartridge (rejestr CARTINS ma wartość 1, gdy brak cartridge'a i Basic jest odłączony), to teraz jest on inicjowany (lecz jeszcze nie uruchamiany). Na zakończenie tej części kanał IOCBO jest otwierany dla edytora. Gdy przy otwieraniu wystąpi błąd, następuje skok do początku procedury RESET.

    W tym momencie cały system jest już gotowy do pracy. Teraz poszukiwane jest wyjście z procedury RESET do programu użytkownika. Najpierw przez wywołanie CASBOOT dokonywana jest próba odczytu z kasety. Następnie, po sprawdzeniu, czy nie zabrania tego zainstalowany cartridge (CARTOPT=0 oznacza zakaz odczytu), podejmowana jest próba odczytu z dyskietki. Dopiero po tym wskaźnik COLDST jest ustawiany na wartość 0, która spowoduje po naciśnięciu klawisza RESET wykonanie gorącego startu.

    Na zakończenie sterowanie komputerem zostaje przekazane pod adres zawarty w rejestrze DOSVEC (jeżeli nie ma cartridge'a i nie został dokonany odczyt z kasety lub dyskietki, to nadal jest tam adres TESTROM) albo, jeśli zainstalowany cartridge zabraniał odczytu, pod adres zawarty w rejestrze CARTRUN. Pewną ciekawostką jest umieszczenie na końcu procedury RESET zupełnie niepotrzebnych tu instrukcji CLC i RTS. Przewidywano wykorzystanie ich przez różne procedury systemu operacyjnego, lecz mogą one z powodzeniem zostać użyte w programie użytkownika.

2.2. Obliczanie sum kontrolnych

    Podczas inicjowania komputera sprawdzana jest poprawność układów pamięci ROM zawierających system operacyjny. Dokonywane jest to przez zsumowanie zawartości wszystkich bajtów pamięci i porównanie otrzymanego wyniku z zapisaną w ROM sumą kontrolną.

    Ponieważ system operacyjny jest zapisany w dwóch oddzielnych blokach pamięci, które posiadają odrębne sumy kontrolne, to sprawdzenie poprawności ROM wykonywane jest przez dwie procedury - CKROM1 i CKROM2.

    Procedura CKROM1 kontroluje pamięć ROM znajdującą się w obszarach $C002-$CFFF, $5000-$57FF i $D800-$DFFF. Obszary $E000-$FFF7 i $FFFA-$FFFF są kontrolowane przez procedurę CKROM2.

    Porównanie podanych obszarów ROM ze wskazanymi na początku książki wykazuje dwie dwubajtowe luki. Są to miejsca umieszczenia sum kontrolnych, które oczywiście nie podlegają sprawdzaniu. Pierwszy blok pamięci ma sumę kontrolną pod adresem $C000 (CHSRO1), a drugi pod $FFF8 (CHSRO2).
            0100 ;Check ROM
            0110 ;
            0120 CHSRO1 = $C000
            0130 CHSRO2 = $FFF8
            0140 CKSUM = $8B
            0150 GETCKS = $FFA9
            0160 ;
            0170     *=  $FF73
            0180 ;
            0190 CKROM1 LDX #$00
            0200     STX CKSUM
            0210     STX CKSUM+1
            0220 LOOP JSR GETCKS
            0230     CPX #$0C
            0240     BNE LOOP
            0250     LDA CHSRO1
            0260     LDX CHSRO1+1
            0270 CHECK CMP CKSUM
            0280     BNE BAD
            0290     CPX CKSUM+1
            0300     BNE BAD
            0310     CLC
            0320     RTS
            0330 BAD SEC
            0340     RTS
            0400 CKROM LDX #$00
            0410     STX CKSUM
            0420     STX CKSUM+1
            0430     LDX #$0C
            0440     JSR GETCKS
            0450     JSR GETCKS
            0460     LDA CHSRO2
            0470     LDX CHSRO2+1
            0480     JMP CHECK
    Przebieg obu procedur jest bardzo prosty. Po wyzerowaniu rejesrtu CKSUM, w którym będzie zliczana suma bajtów pamięci ROM, wywoływana jest właściwa procedura obliczająca sumę kontrolną - GETCKS. Następnie obliczona suma jest porównywana z sumą zapisaną w ROM. Jeżeli są one równe, to bit przeniesienia (Carry) w rejestrze statusu procesora jest kasowany, w przeciwnym razie jest on ustawiany.

    Powrót do procedury RESET z ustawionym bitem Carry powoduje zmianę zawartości rejestru NGFLAG, który służy do kontroli poprawności inicjowania systemu.

    Bezpośrednio obliczająca sumę kontrolną procedura GETCKS wymaga przy wywołaniu przekazania w rejestrze X numeru sprawdzanego bloku pamięci. Adres początkowy i końcowy tego bloku jest pobierany z tabeli CKSTAB.
            0100 ;GET ChecK Sum
            0110 ;
            0120 CKSUM = $8B
            0130 TMPREG = $9E
            0140 ;
            0150     *=  $FFA9
            0160 ;
            0170     LDY #$00
            0180 LOOP LDA CKSTAB,X
            0190     STA TMPREG,Y
            0200     INX
            0210     INY
            0220     CPX #$04
            0230     BNE LOOP
            0240     LDY #$00
            0250 NEXT CLC
            0260     LDA (TMPREG),Y
            0270     ADC CKSUM
            0280     STA CKSUM
            0290     BCC NXT1
            0300     INC CKSUM+1
            0310 NXT1 INC TMPREG
            0320     BNE NXT2
            0330     INC TMPREG+1
            0340 NXT2 LDA TMPREG
            0350     CMP TMPREG+2
            0360     BNE NEXT
            0370     LDA TMPREG+1
            0380     CMP TMPREG+3
            0390     BNE NEXT
            0400     RTS
            0410 ;
            0420 CKSTAB
            0430     .WORD $C002,$D000
            0440     .WORD $5000,$5800
            0450     .WORD $D800,$E000
            0460     .WORD $E000,$FFF8
            0470     .WORD $FFFA,$00
    GETCKS najpierw pobiera z CKSTAB adres początkowy i końcowy sprawdzanego bloku (według wartości X) i umieszcza je w tymczasowym rejestrze TMPREG. Następnie korzystając z podanych adresów odczytuje zawartości kolejnych komórek pamięci i dodaje je do zawartości CKSUM. Po osiągnięciu adresu końcowego procedura się kończy.

    Warto zauważyć, że adres końcowy w tabeli CKSTAB wskazuje na pierwszą komórkę pamięci nie należącą do badanego bloku. Jest to spowodowane zwiększaniem adresu na końcu pętli.

    Ostatnia informacja dotyczy rejestrów w pamięci RAM wykorzystywanych przez powyższe procedury. Znajdują się one w obszarze przeznaczonym dla oprogramowania i po procedurze inicjowania systemu nie są więcej wykorzystywane przez OS.

    Oprócz procedur sprawdzających poprawność pamięci ROM system operacyjny zawiera jeszcze procedurę obliczającą sumę kontrolną obszaru $BFF0-$C0EF. Sumuje ona wartości bajtów w tym obszarze i umieszcza je w rejestrze CARTCK. Ponieważ przedtem dokonywane jest porównanie obliczonej sumy z aktualną zawartością tego rejestru, umożliwia to także sprawdzenie, czy została dokonana zamiana cartridge'a. W tym właśnie celu procedura NEWCART jest wywoływana na początku procedury gorącego startu. W przypadku stwierdzenia takiej zamiany następuje przejście do zimnego startu systemu.
            0100 ;NEW CARTridge ?
            0110 ;
            0120 CART = $BFF0
            0130 CARTCK = $03EB
            0140 ;
            0150     *=  $C4C9
            0160 ;
            0170     LDA #$00
            0180     TAX
            0190     CLC
            0200 LOOP ADC CART,X
            0210     INX
            0220     BNE LOOP
            0230     CMP CARTCK
            0240     STA CARTCK
            0250     RTS
    Niezależnie od rodzaju startu procedura ta jest wywoływana - gdy cartridge jest dołączony - po zainicjowaniu systemu, a przed zainicjowaniem cartridge'a.

2.3. Procedury inicjowania bloków systemu

    Prawidłowa praca całego systemu komputerowego wymaga umieszczenia w rejestrach znajdujących się w pamięci RAM oraz w rejestrach sprzętowych określonych wartości, które będą wykorzystywane potem przez OS. Czynność ta nazywana jest inicjowaniem i wykonywana jest przez kilkanaście procedur wywoływanych kolejno podczas startu systemu.

    Jako ostatnia wykonywana jest procedura inicjowania cartridge'a. (jeśli jest dołączony). Jest ona umieszczona w cartridge'u, a jej wektor zapisany jest pod adresem $BFFE. Ponieważ znajduje się ona w cartridge'u, to nie może być tutaj opisana.

2.3.1. Procedury rozpoznania cartridge'a i RAM

    Przed zainicjowaniem system musi sprawdzić, jakimi dysponuje obszarami pamięci RAM i dodatkowej pamięci ROM (cartridge). Do tego celu służą procedury CARTGO i GRAMHI.

    Procedura CARTGO sprawdza najpierw obecność cartridge'a w gnieździe i jeśli jest, to jego rodzaj. W przypadku stwierdzenia obecności cartridge'a diagnostycznego (ustawiony bit 7 rejestru CARTOPT) dalsze sterowanie jest przekazywane do niego. W przeciwnym razie dokonywane jest inicjowanie portów I/O poprzez procedurę IOPORTINI.

    Teraz określany jest status wbudowanego interpretera Basica. Jest on sterowany poprzez bit 1 w PORTB. Jeżeli bit ten jest skasowany (równy zero), to pamięć ROM zawierająca interpreter jest dostępna w obszarze $A000-$BFFF. Gdy bit 1 w PORTB jest ustawiony (równy jeden), układ zarządzania pamięcią blokuje dostęp do interpretera.

    W tej fazie interpreter jest najpierw odłączany. Jeżeli jest to start zimny, sprawdzany jest rejestr CONSOL sygnalizujący stan klawiszy konsoli (START, SELECT i OPTION). Klawiszom tym są przyporządkowane odpowiednio bity 0, 1 i 2. Normalnie bity te są ustawione i rejestr CONSOL zawiera wartość $07. Naciśnięcie któregoś klawisza kasuje odpowiadający mu bit. Gdy bit 2 CONSOL jest ustawiony (klawisz OPTION nie wciśnięty), interpreter Basica jest ponownie włączany przez skasowanie bitu 1 PORTB.

    Podczas startu gorącego włączenie Basica następuje po stwierdzeniu wartości zero w rejestrze BASICF, który otrzymał odpowiednią wartość podczas wcześniejszej fazy procedury RESET.
            0100 ;CARTridge GOes ?
            0110 ;
            0120 BASICF = $03F8
            0130 CARTINI = $BFFE
            0140 CARTINS = $BFFC
            0150 CARTOPT = $BFFD
            0160 CONSOL = $D01F
            0170 IOPORTINI = $C4DA
            0180 PORTB = $D301
            0190 RAMLO = $04
            0200 TRAMSZ = $06
            0210 TRIG3 = $D013
            0220 WARMST = $08
            0230 ;
            0240     *=  $C471
            0250 ;
            0260     LDA TRIG3
            0270     ROR A
            0280     BCC PINI
            0290     LDA CARTINS
            0300     BNE PINI
            0310     LDA CARTOPT
            0320     BPL PINI
            0330     JMP (CARTINI)
            0340 PINI JSR IOPORTINI
            0350     LDA PORTB
            0360     ORA #$02
            0370     STA PORTB
            0380     LDA WARMST
            0390     BEQ CNSL
            0400     LDA BASICF
            0410     BNE GRAMHI
            0420     BEQ ON
            0430 CNSL LDA CONSOL
            0440     AND #$04
            0450     BEQ GRAMHI
            0460 ON  LDA PORTB
            0470     AND #$FD
            0480     STA PORTB
            0490 ;
            0500 ;Get RAM HIgh
            0510 ;
            0520 GRAMHI LDA #$00
            0530     TAY
            0540     STA RAMLO+1
            0550     LDA #$28
            0560     STA TRAMSZ
            0570 LOOP LDA (RAMLO+1),Y
            0580     EOR #$FF
            0590     STA (RAMLO+1),Y
            0600     CMP (RAMLO+1),Y
            0610     BNE END
            0620     EOR #$FF
            0630     STA (RAMLO+1),Y
            0640     CMP (RAMLO+1),Y
            0650     BNE END
            0660     INC TRAMSZ
            0670     BNE LOOP
            0680 END RTS
    CARTGO nie kończy się instrukcją RTS (powrót z procedury), lecz przechodzi bezpośrednio w procedurę GRAMHI. Sprawdzana jest tu wielkość dostępnej pamięci RAM mierzona w stronach (po 256 KB). Pierwszy bajt każdej strony pamięci jest dwukrotnie poddawany operacji EOR (exclusive-or) z wartością $FF i za każdym razem porównywany ze swoją poprzednią wartością. Jeśli operacja EOR nie powoduje zmiany zawartości komórki, oznacza to, że nie jest to komórka pamięci RAM. Aktualnie obliczona liczba stron pamięci RAM jest zapisywana tymczasowo do rejestru TRAMSZ.

    Warto zauważyć, że przyjęty sposób testowania pamięci RAM nie powoduje zmiany jej zawartości, dzięki czemu zapisany w pamięci program nie ulega skasowaniu podczas gorącego startu. Samo sprawdzanie wielkości RAM jest konieczne z powodu istnienia różnych odmian komputerów w serii XL i XE oraz możliwości zainstalowania cartridge'a o wielkości 8 lub 16 KB. Na przykład model 600XL, mający identyczny system operacyjny, posiada jedynie 16 KB RAM.

2.3.2. Procedura inicjowania portów I/O.

    Gdy nie została stwierdzona obecność cartridge'a diagnostycznego, to z CARTGO jest wywoływana procedura IOPORTINI. Jej zadaniem jest zainicjowanie portów I/O. Są to sprzętowe rejestry wewnętrznych, specjalizowanych układów komputera, które służą do obsługi urządzeń zewnętrznych i odciążają w tej pracy jednostkę centralną (procesor 6502).
            0100 ;I/O PORT INItiation
            0110 ;
            0120 ANTIC = $D400
            0130 AUDC3 = $D205
            0140 AUDC4 = $D207
            0150 AUDCTL = $D208
            0160 GTIA = $D000
            0170 PACTL = $D302
            0180 PBCTL = $D303
            0190 PIA = $D300
            0200 POKEY = $D200
            0210 PORTA = $D300
            0220 PORTB = $D301
            0230 SEROUT = $D20D
            0240 SKCTL = $D20F
            0250 ;
            0260     *=  $C4DA
            0270 ;
            0280     LDA #$00
            0290     TAX
            0300     STA PBCTL
            0310 NEXT STA GTIA,X
            0320     STA ANTIC,X
            0330     STA POKEY,X
            0340     CPX #$01
            0350     BEQ BYPASS
            0360     STA PIA,X
            0370 BYPASS INX
            0380     BNE NEXT
            0390     LDA #$3C
            0400     STA PBCTL
            0410     LDA #$FF
            0420     STA PORTB
            0430     LDA #$38
            0440     STA PACTL
            0450     STA PBCTL
            0460     LDA #$00
            0470     STA PORTA
            0480     LDA #$FF
            0490     STA PORTB
            0500     LDA #$3C
            0510     STA PACTL
            0520     STA PBCTL
            0530     LDA PORTB
            0540     LDA PORTA
            0550     LDA #$22
            0560     STA SKCTL
            0570     LDA #$A0
            0580     STA AUDC3
            0590     STA AUDC4
            0600     LDA #$28
            0610     STA AUDCTL
            0620     LDA #$FF
            0630     STA SEROUT
            0640     RTS
    W pierwszej fazie procedury zerowane są wszystkie rejestry układów GTIA, ANTIC i POKEY oraz rejestry układu PIA z wyjątkiem PORTB. Wyzerowanie tego rejestru, sterującego zarządzaniem obszarami pamięci komputera, spowodowałoby zawieszenie się systemu z powodu odłączenia pamięci ROM zawierającej system operacyjny.

    Najdłuższa część procedury przeznaczona jest na ustalenie stanu początkowego rejestrów układu PIA. Znaczna długość tej fazy jest spowodowana specyficznym działaniem układu PIA, w którym rejestry PORTA i PORTB są sterowane pośrednio poprzez rejestry PACTL i PBCTL. W rezultacie przeprowadzonych operacji port A ustawiany jest jako rejestr wejściowy, a port B jako wyjściowy.

    Ostatnią czynnością jest nadanie wartości początkowych rejestrom POKEY-a, które obsługują zegary transmisji danych przez złącze szeregowe oraz z klawiatury. Są to rejestry kontroli generatorów dźwięku AUDC3 i AUDC4 oraz rejestr kontrolujący wszystkie generatory AUDCTL (dokładny opis ich funkcji znajduje się w książce "Mapa pamięci Atari XL/XE. Procedury wejścia/wyjścia" (SOETO, 1988). Od tej chwili komputer może komunikować się z urządzeniami zewnętrznymi. Do prawidłowej pracy każde z tych urządzeń wymaga jednak jeszcze oddzielnego zainicjowania, co wykonuje procedura SYSINIT.

2.3.3. Procedura inicjowania systemu

    Najważniejszą z procedur wywoływanych przez RESET jest procedura SYSINIT, której zadaniem jest właściwe zainicjowanie pracy całego systemu operacyjnego. Po jej wykonaniu komputer powinien być gotowy do pracy.
            0100 ;SYStem INITiation
            0110 ;
            0120 BREAKIRQ = $C092
            0130 CASVEC = $E440
            0140 CKEY = $03E9
            0150 CONSOL = $D01F
            0160 EDTVEC = $E400
            0170 IRQSTAT = $11
            0180 JCIOINIT = $E46E
            0190 JDSKINIT = $E450
            0200 JNMIEN = $E46B
            0210 JSIOINIT = $E465
            0220 KBDVEC = $E420
            0230 MEMLO = $02E7
            0240 MEMTOP = $02E5
            0250 NEWINITC = $E49B
            0260 NEWIOREQ = $C96E
            0270 PRTVEC = $E430
            0280 RAMSIZ = $02E4
            0290 SCRVEC = $E410
            0300 TRAMSZ = $06
            0310 VBRKEY = $0236
            0320 VPIRQ = $0238
            0330 ;
            0340     *=  $C535
            0350 ;
            0360     DEC IRQSTAT
            0370     LDA # <BREAKIRQ
            0380     STA VBRKEY
            0390     LDA # >BREAKIRQ
            0400     STA VBRKEY+1
            0410     LDA TRAMSZ
            0420     STA RAMSIZ
            0430     STA MEMTOP+1
            0440     LDA #$00
            0450     STA MEMTOP
            0460     LDA #$00
            0470     STA MEMLO
            0480     LDA #$07
            0490     STA MEMLO+1
            0500     JSR EDTVEC+$0C
            0510     JSR SCRVEC+$0C
            0520     JSR KBDVEC+$0C
            0530     JSR PRTVEC+$0C
            0540     JSR CASVEC+$0C
            0550     JSR JCIOINIT
            0560     JSR JSIOINIT
            0570     JSR JNMIEN
            0580     JSR JDSKINIT
            0590     LDA # <NEWIOREQ
            0600     STA VPIRQ
            0610     LDA # >NEWIOREQ
            0620     STA VPIRQ+1
            0630     JSR NEWINITC
            0640     LDA CONSOL
            0650     AND #$01
            0660     EOR #$01
            0670     STA CKEY
            0680     RTS
    W pierwszym kroku procedury kasowane są wszystkie żądania przerwań maskowalnych IRQ przez ustawienie rejestru IRQSTAT na wartość $FF ($00-1=$FF). Następnie wektor przerwania wywoływanego przez klawisz BREAK ustawiany jest na adres procedury BREAKIRQ.

    Ustalona poprzednio wielkość pamięci RAM (zapisana w TRAMSZ) jest teraz przepisywana do rejestrów MEMTOP i RAMSIZ, przy czym ten drugi zawiera tylko liczbę stron pamięci. Do rejestru MEMLO jest natomiast wpisywana wartość $0700, która określa najniższy adres pamięci dostępny dla oprogramowania. Ma to na celu ochronę obszaru zmiennych oraz buforów systemowych, a także rejestrów wykorzystywanych przez oprogramowanie.

    Teraz kolejno wywoływane są procedury inicjowania urządzeń zewnętrznych, a następnie systemowych procedur wejścia/wyjścia oraz przerwań niemaskowalnych. Do wektora VPIRQ (Vector Parallel IRQ) jest przy tym wpisywany adres procedury NEWIOREQ, która obsługuje przerwania wywoływane przez nowe urządzenia.

    Ostatnią czynnością jest sprawdzenie w rejestrze CONSOL, czy został wciśnięty klawisz START. Jeżeli tak, to znacznik CKEY otrzymuje wartość 1, w przeciwnym wypadku 0.

2.3.4. Procedura inicjowania edytora

    Procedura ta jest wywoływana trzykrotnie w celu zainicjowania kolejno edytora, klawiatury i ekranu. Jej wywołanie odbywa się pośrednio poprzez adresy skoku umieszczone w tablicy procedur obsługi. Dla wymienionych urządzeń adresy te są aktualnie jednakowe i wskazują procedurę POWERON, jednak takie rozwiązanie umożliwia łatwe wprowadzenie zmian w ewentualnych, następnych wersjach OS. Jest to jeden z wielu przykładów dalekowzroczności projektantów Atari.
            0100 ;POWER ON action
            0110 ;
            0120 FKDEF = $FC11
            0130 FKDEFP = $60
            0140 KBCODES = $02FC
            0150 KEYDEF = $FB51
            0160 KEYDEFP = $79
            0170 RAMSIZ = $02E4
            0180 RAMTOP = $6A
            0190 SHFOLK = $02BE
            0200 ;
            0210    *=  $EF6E
            0220 ;
            0230    LDA #$FF
            0240    STA KBCODES
            0250    LDA RAMSIZ
            0260    STA RAMTOP
            0270    LDA #$40
            0280    STA SHFOLK
            0290    LDA # <KEYDEF
            0300    STA KEYDEFP
            0310    LDA # >KEYDEF
            0320    STA KEYDEFP+1
            0330    LDA # <FKDEF
            0340    STA FKDEFP
            0350    LDA # >FKDEF
            0360    STA FKDEFP+1
            0370    RTS
    Procedura POWERON kolejno ustawia wszystkie parametry niezbędne do pracy edytora (klawiatury i ekranu). Do rejestru KBCODES wpisywana jest wartość $FF, która oznacza, że nie został naciśnięty żaden klawisz. Wielkość dostępnej pamięci (w stronach) przepisywana jest z RAMSIZ do RAMTOP. Wartość $40 umieszczona w SHFOLK oznacza, że klawiatura pracuje w trybie dużych liter.

    Na zakończenie wektory KEYDEFP i FKDEFP są ustawiane na wartości adresów zawartych w pamięci ROM tabel zawierających kody klawiszy. Tabela FKDEF dotyczy klawiszy funkcyjnych F1-F4, które występują jedynie w modelu 1200XL. Ponieważ system operacyjny był pisany z myślą o całej serii XL, to tabela ta znajduje się we wszystkich modelach, lecz nie jest wykorzystywana poza 1200XL.

2.3.5. Procedura inicjowania drukarki

    Zainicjowanie drukarki polega jedynie na ustawieniu w rejestrze PTIMOT wartości $1E. Określa ona tzw. Timeout, czyli czas oczekiwania komputera na odpowiedź po wysłaniu polecenia do urządzenia zewnętrznego i jest różna dla różnych urządzeń. Jeżeli po odliczeniu wskazanej przez Timeout liczby cykli zegarowych komputer nie otrzyma odpowiedzi z urządzenia, to wywoływany jest błąd o kodzie 138 (przekroczony czas oczekiwania). Używanie wartości Timeout przy komunikacji z urządzeniami peryferyjnymi pozwala na współpracę komputera z urządzeniami o różnej szybkości pracy i jest kolejnym przykładem elastyczności systemu.
            0100 ;PRinter INITiation
            0110 ;
            0120 PTIMOT = $0314
            0130 ;
            0140     *=  $FE99
            0150 ;
            0160     LDA #$1E
            0170     STA PTIMOT
            0180     RTS

2.3.6. Procedura inicjowania magnetofonu

    Ponieważ magnetofon jest jedynym "nieinteligentnym" urządzeniem zewnętrznym, tzn. nie ma wbudowanych układów do komunikacji z komputerem, to komputer wysyła polecenia i dane bez oczekiwania na odpowiedź lub potwierdzenie. Z tego powodu nie jest określany czas oczekiwania na odpowiedź (Timeout). Inicjowanie magnetofonu polega więc jedynie na ustawieniu w rejestrze CBAUD (Cassette BAUD rate) szybkości transmisji na 600 bodów (bitów na sekundę).
            0100 ;CASsette INITiation
            0110 ;
            0120 CBAUD = $02EE
            0130 ;
            0140     *=  $FCDB
            0150 ;
            0160     LDA #$CC
            0170     STA CBAUD
            0180     LDA #$05
            0190     STA CBAUD+1
            0200     RTS
    Stosowana w Atari szybkość transmisji z magnetofonu nie jest oszałamiająca (np. w Commodore 64 stosuje się 3800 bodów). Dlatego też istnieje wiele programów przyspieszających zapis i odczyt. Ingerują one między innymi w zawartość rejestru CBAUD.

2.3.7. Inicjowanie bloku kontroli urządzeń

    Blok kontroli urządzeń (Device Control Block) jest wykorzystywany przez procedurę SIO przede wszystkim do komunikacji ze stacją dysków elastycznych. Przygotowanie systemu do współpracy ze stacją dysków wymaga określenia czasu oczekiwania na odpowiedź (Timeout), tak jak dla drukarki. Dodatkowo ustalana jest na 128 bajtów długość sektora zapisanego na dyskietce.
            0100 ;DiSK INITiation
            0110 ;
            0120 DSCTLN = $02D5
            0130 DSKTIM = $0246
            0140 ;
            0150     *=  $C6A3
            0160 ;
            0170     LDA #$A0
            0180     STA DSKTIM
            0190     LDA #$80
            0200     STA DSCTLN
            0210     LDA #$00
            0220     STA DSCTLN+1
            0230     RTS

2.3.8. Inicjowanie centralnej procedury I/O

    Wykonywane przez procedurę CIOINIT zainicjowanie centralnej procedury obsługi operacji wejścia/wyjścia polega jedynie na wpisaniu do wszystkich bloków kontroli (IOCB) dwóch wartości. Identyfikator urządzenia (ICCHID) otrzymuje wartość $FF, co oznacza urządzenie nieistniejące. Jako adres procedury Put Byte (odczytu lub zapisu bajtu - zależnie od sposobu dostępu) umieszczany jest adres procedury CIONOPN.
            0100 ;Central I/O INITiation
            0110 ;
            0120 ICCHID = $0340
            0130 ICPUTB = $0346
            0140 ;
            0150     *=  $E4C1
            0160 ;
            0170     LDX #$00
            0180 LOOP LDA #$FF
            0190     STA ICCHID,X
            0200     LDA # <CIONOPN-1
            0210     STA ICPUTB,X
            0220     LDA # >CIONOPN
            0230     STA ICPUTB+1,X
            0240     TXA
            0250     CLC
            0260     ADC #$10
            0270     TAX
            0280     CMP #$80
            0290     BCC LOOP
            0300     RTS
            0310 ;
            0320 ;CIO Not OPeN
            0330 ;
            0340 CIONOPN LDY #$85
            0350     RTS
    Próba odczytu lub zapisu przez wywołanie procedury CIO spowoduje teraz umieszczenie w rejestrze Y wartości $85, czyli wystąpieniu błędu "NOT OPEN" (kanał nie został otwarty).

2.3.9. Inicjowanie szeregowej procedury I/O

    Przygotowanie do pracy procedury SIO, która bezpośrednio obsługuje transmisję poprzez szynę szeregową, wymaga jedynie wpisania odpowiednich wartości do rejestru kontroli złącza szeregowego i klawiatury (Serial and Keyboard ConTroL) oraz jego odpowiednika w pamięci RAM (tzw. rejestr-cień). Poza tym procedura inicjowania ustawia znacznik zezwolenia na dźwięk podczas transmisji, a do rejestrów kontroli portów układu PIA wpisuje wartości, które ustawiają PORTA i PORTB jako rejestry przesyłania danych.
            0100 ;Serial I/O INITiation
            0110 ;
            0120 IOSNDEN = $41
            0130 PACTL = $D302
            0140 PBCTL = $D303
            0150 SKCTL = $D20F
            0160 SKCTLS = $0232
            0170 ;
            0180     *=  $E95C
            0190 ;
            0200     LDA #$3C
            0210     STA PACTL
            0220     LDA #$3C
            0230     STA PBCTL
            0240     LDA #$03
            0250     STA SKCTLS
            0260     STA IOSNDEN
            0270     STA SKCTL
            0280     RTS

2.3.10. Inicjowanie nowych urządzeń

    System operacyjny Atari był projektowany tak, aby umożliwić maksymalną elastyczność. Szybki rozwój techniki czynił oczywistym powstanie w przyszłości urządzeń, których działanie trudno było przewidzieć podczas tworzenia systemu. Z tego powodu tabela procedur obsługi urządzeń zewnętrznych została umieszczona w pamięci RAM i przewidziano możliwość jej rozszerzania do jedenastu wpisów.

    Sposób ten jest stosowany także w innych komputerach, projektanci Atari poszli jednak jeszcze dalej! Założyli powstanie w przyszłości urządzeń zewnętrznych korzystających z szyny równoległej komputera i nazwali je "nowymi urządzeniami" (new device). Do ich obsługi przewidziano liczne procedury systemu operacyjnego. Procedury te przez kilka lat stanowiły powód do zdziwienia, a nawet kpin. Przewidywania twórców Atari okazały się jednak słuszne: jest już pierwsze urządzenie korzystające z tych procedur - twardy dysk 20 MB firmy Supra Corp.

    Chociaż na etapie projektowania nie można było przewidzieć nawet zasady działania tych urządzeń, to jednak trzeba było ustalić kilka podstawowych warunków. Przede wszystkim w obszarze portów I/O wydzielono część przestrzeni adresowej dla rejestrów nowych urządzeń ($D100-$D1FF). Następnie ustalono, że nowe urządzenie będzie powodowało odłączenie obszaru ROM zawierającego procedury operacji zmiennoprzecinkowych ($D800-$DFFF). W uzyskanej w ten sposób przestrzeni adresowej zostanie sprzętowo (przez przełączenie linii magistrali adresowej) umieszczona część pamięci ROM urządzenia.

    Po tej długiej, lecz koniecznej dygresji czas na opis procedury inicjowania nowych urządzeń.
            0100 ;NEW device INITiation
            0110 ;
            0120 DEVID1 = $D803
            0130 DEVID2 = $D80B
            0140 DEVINIT = $D819
            0150 PDVREG = $D1FF
            0160 PDVRS = $0248
            0170 ;
            0180     *=  $C90C
            0190 ;
            0200     LDA #$01
            0210     STA PDVRS
            0220 DEV LDA PDVRS
            0230     STA PDVREG
            0240     LDA DEVID1
            0250     CMP #$80
            0260     BNE NEXT
            0270     LDA DEVID2
            0280     CMP #$91
            0290     BNE NEXT
            0300     JSR DEVINIT
            0310 NEXT ASL PDVRS
            0320     BNE DEV
            0330     LDA #$00
            0340     STA PDVREG
            0350     RTS
    Procedura kolejno aktywizuje nowe urządzenia (może być ich osiem) i sprawdza dwa bajty identyfikacyjne (DEVID1=$80 i DEVID2=$91). Jeżeli wynik jest pozytywny, to wywoływana jest procedura inicjowania urządzenia zapisana w jego pamięci (od adresu DEVINIT). Uaktywnienie urządzenia polega na ustawieniu bitu o odpowiadającym mu numerze (od 0 do 7) w rejestrze PDVREG (Parallel DeVice REGister) znajdującym się w tym urządzeniu. Rejestr ten posiada w obszarze zmiennych systemowych komputera swój rejestr-cień PDVRS.

2.3.11. Inicjowanie przerwań niemaskowalnych

    Po przygotowaniu do pracy całego systemu wykonywana jest procedura uruchamiająca przerwania niemaskowalne (NMI - Non Maskable Interrupt). Umieszcza ona w rejestrze NMIEN (NMI ENable) wartość $40, co oznacza zezwolenie na przerwania wywoływane przez impuls synchronizacji pionowej obrazu (zob. rozdział 3.1.1.). Dodatkowo przepisuje ona wartość wskaźnika TRIG3, sygnalizującego obecność cartridge'a do rejestru GINTLK.
            0100 ;NMI ENaBLe
            0110 ;
            0120 GINTLK = $03FA
            0130 NMIEN = $D40E
            0140 TRIG3 = $D013
            0150 ;
            0160     *=  $C00C
            0170 ;
            0180     LDA #$40
            0190     STA NMIEN
            0200     LDA TRIG3
            0210     STA GINTLK
            0220     RTS

2.4. Procedury odczytu wstępnego (boot)

    Po zainicjowaniu pracy wszystkich niezbędnych elementów systemu procedura RESET musi przekazać sterowanie komputera do programu użytkownika. W tym celu po zimnym starcie próbuje dokonać odczytu z magnetofonu i stacji dysków, a po starcie gorącym sprawdza, czy taki odczyt był uprzednio wykonany. Pozytywny wynik (odczytu lub sprawdzenia) powoduje skok do adresu wskazanego przez wektor inicjowania odczytanego programu. W tym miejscu pojawia się największa możliwość ingerencji w procedurę RESET i wykonania programu wskazanego przez programistę.

2.4.1. Procedura odczytu z magnetofonu

    Jako pierwsza wywoływana jest procedura odczytu z magnetofonu.
            0100 ;CASsette BOOT
            0110 ;
            0120 BLOCK1 = $C5BB
            0130 BOOT? = $09
            0140 CASINI = $02
            0150 CASSBT = $03EA
            0160 CKEY =  $03E9
            0170 DOSINI = $0C
            0180 GAPTYP = $3E
            0190 JCASOPIN = $E47D
            0200 WARMST = $08
            0210 ;
            0220     *=  $C66E
            0230 ;
            0240     LDA WARMST
            0250     BEQ RD
            0260     LDA BOOT?
            0270     AND #$02
            0280     BEQ EXIT
            0290     JMP CASINITC
            0300 RD  LDA CKEY
            0310     BEQ EXIT
            0320     LDA #$80
            0330     STA GAPTYP
            0340     INC CASSBT
            0350     JSR JCASOPIN
            0360     JSR BLOCK1
            0370     LDA #$00
            0380     STA CASSBT
            0390     STA CKEY
            0400     ASL BOOT?
            0410     LDA DOSINI
            0420     STA CASINI
            0430     LDA DOSINI+1
            0440     STA CASINI+1
            0450 EXIT RTS
            0460 CASINITC JMP (CASINI)
    Jeśli jest to start gorący (WARMST=$FF), to kontrolowany jest znacznik BOOT?. Gdy ma on ustawiony bit 1, wykonywany jest skok do programu, którego adres wskazuje wektor CASINI. W przeciwnym wypadku następuje wyjście z procedury CASBOOT i powrót do RESET.

    Przy zimnym starcie systemu najpierw sprawdzany jest znacznik CKEY, określający, czy został naciśnięty klawisz START. Zerowa wartość tego znacznika oznacza brak odczytu z magnetofonu i powoduje opuszczenie CASBOOT.

    Po stwierdzeniu konieczności odczytu z magnetofonu rejestr GAPTYP ustawiany jest na $80, co oznacza krótkie przerwy między rekordami zapisanymi na kasecie oraz zwiększana jest wartość wskaźnika CASSBT (z 0 na 1). Następnie wywoływana jest procedura CASOPIN, której zadaniem jest otworzenie kanału IOCB do odczytu z magnetofonu. Teraz poprzez skok do środka procedury BOOT (zob. niżej), w miejsce oznaczone etykietą BLOCK1, wykonywany jest właściwy odczyt z magnetofonu.

    Na zakończenie zerowane są wskaźniki CASSBT i CKEY, a BOOT? jest mnożony przez 2. Ponieważ procedura BOOT umieszcza wektor startowy programu w rejestrze DOSINI, a po odczycie z magnetofonu wykorzystywany jest wektor CASINI, to trzeba jeszcze przepisać jego zawartość (z DOSINI do CASINI).

2.4.2. Procedura odczytu ze stacji dysków

    Procedura wstępnego odczytu ze stacji dysków rozpoczyna się tak samo jak odczyt z magnetofonu. Jedynie zamiast bitu 1 przy gorącym starcie sprawdzany jest bit 0 wskaźnika BOOT?, sygnalizujący poprawny odczyt z dyskietki. Ustawienie tego bitu powoduje skok do adresu zawartego w rejestrze DOSINI.
            0100 ;BOOT
            0110 ;
            0120 BLOAD = $C629
            0130 BOOT? = $09
            0140 BOOTAD = $0242
            0150 CASBUF = $0400
            0160 CASSBT = $03EA
            0170 DAUX1 = $030A
            0180 DAUX2 = $030B
            0190 DBUFA = $0304
            0200 DCMND = $0302
            0210 DFLAG = $0240
            0220 DOSINI = $0C
            0230 DOSINITC = $C63B
            0240 DRDERR = $C63E
            0250 DSECCNT = $0241
            0260 DUNIT = $0301
            0270 GETBLK = $C659
            0280 JDSKINT = $E453
            0290 RAMLO = $04
            0300 WARMST = $08
            0310 ;
            0320     *=  $C58B
            0330 ;
            0340     LDA WARMST
            0350     BEQ RD
            0360     LDA BOOT?
            0370     AND #$01
            0380     BEQ EXIT
            0390     JMP DOSINITC
            0400 RD  LDA #$01
            0410     STA DUNIT
            0420     LDA #$53
            0430     STA DCMND
            0440     JSR JDSKINT
            0450     BMI EXIT
            0460 RP1 LDA #$00
            0470     STA DAUX2
            0480     LDA #$01
            0490     STA DAUX1
            0500     LDA # <CASBUF
            0510     STA DBUFA
            0520     LDA # >CASBUF
            0530     STA DBUFA+1
            0540 BLOCK1 JSR GETBLK
            0550     BPL NER
            0560 ERR JSR DRDERR
            0570     LDA CASSBT
            0580     BEQ RP1
            0590 EXIT RTS
            0600 NER LDX #$03
            0610 LOOP1 LDA CASBUF,X
            0620     STA DFLAG,X
            0630     DEX
            0640     BPL LOOP1
            0650     LDA BOOTAD
            0660     STA RAMLO
            0670     LDA BOOTAD+1
            0680     STA RAMLO+1
            0690     LDA CASBUF+4
            0700     STA DOSINI
            0710     LDA CASBUF+5
            0720     STA DOSINI+1
            0730 NXT LDY #$7F
            0740 LOOP2 LDA CASBUF,Y
            0750     STA (RAMLO),Y
            0760     DEY
            0770     BPL LOOP2
            0780     CLC
            0790     LDA RAMLO
            0800     ADC #$80
            0810     STA RAMLO
            0820     LDA RAMLO+1
            0830     ADC #$00
            0840     STA RAMLO+1
            0850     DEC DSECCNT
            0860     BEQ END
            0870     INC DAUX1
            0880 RP2 JSR GETBLK
            0890     BPL NXT
            0900     JSR DRDERR
            0910     LDA CASSBT
            0920     BNE ERR
            0930     BEQ RP2
            0940 END LDA CASSBT
            0950     BEQ BLD
            0960     JSR GETBLK
            0970 BLD JSR BLOAD
            0980     BCS ERR
            0990     JSR DOSINITC
            1000     INC BOOT?
            1010     RTS
    W przypadku zimnego startu zawsze podejmowana jest próba odczytu ze stacji dysków numer 1. W tym celu do rejestru DUNIT wpisywany jest numer stacji (1), a do DCMND kod rozkazu odczytu statusu ($53). Potem wywoływana jest procedura DSKINT i po uzyskaniu negatywnego wyniku (brak odpowiedzi od stacji) następuje opuszczenie procedury BOOT.

    Gdy została stwierdzona gotowość do pracy stacji numer 1 (status dodatni), numer sektora jest ustawiany na 1, a jako adres bufora do umieszczenia odczytanego bloku wskazywany jest bufor magnetofonu (CASBUF). W tym miejscu (od etykiety BLOCK1) następuje wejście z procedury CASBOOT - ta część jest wspólna dla odczytu z obu urządzeń. Teraz wywoływana jest procedura GETBLK, która pobiera blok bajtów z urządzenia zewnętrznego. Jeśli podczas odczytu wystąpił błąd, to wywoływana jest procedura DRDERR i w przypadku magnetofonu następuje zakończenie odczytu, a w przypadku stacji dysków próba odczytu jest ponawiana (aź do skutku). Do rozróżnienia urządzenia, z którego dokonywany jest odczyt, służy tu znacznik CASSBT (CASSette BooT). Przy odczycie ze stacji dysków ma on wartość zero, a przy odczycie z magnetofonu procedura CASBOOT nadaje mu wartość $01.

    Po bezbłędnym odczycie bloku pierwsze sześć bajtów z bufora jest przenoszone do różnych rejestrów: bajt 1 do DFLAG, bajt 2 do DSECCNT, bajty 3 i 4 do BOOTAD i RAMLO oraz bajty 5 i 6 do DOSINI. Dzięki temu DSECCNT (Disc SECtor CouNTer) zawiera liczbę bloków do odczytu, BOOTAD (BOOT ADdress) i RAMLO adres początkowy umieszczenia odczytanych bloków w pamięci, a DOSINI adres inicjowania odczytanego programu. Ostatnim krokiem tego etapu jest przeniesienie zawartości bufora magnetofonu do miejsca ładowania wskazanego wektorem RAMLO.

    Dalszy przebieg odczytu jest podobny. Kolejno, aż do wyzerowania licznika DSECCNT, bloki danych są odczytywane do bufora magnetofonu i stąd przenoszone na miejsce wskazane przez RAMLO. Wektor RAMLO jest zwiększany po odczycie każdego bloku o 128, co zapewnia zapisanie odczytanych bloków w pamięci bezpośrednio jeden za drugim. Wystąpienie błędu w którymkolwiek momencie odczytu powoduje wywołanie procedury DRDERR i przerwanie odczytu z magnetofonu lub ponowny odczyt (od początku, tj. od pierwszego sektora) ze stacji dysków.

    Po zakończeniu odczytu wywoływana jest procedura BLOAD oraz procedura inicjowania (od adresu umieszczonego w DOSINI). Przed opuszczeniem procedury BOOT zwiększana jest jeszcze o jeden zawartość wskaźnika BOOT?.

2.4.3. Pomocnicze procedury odczytu

    Procedury wstępnego odczytu CASBOOT i BOOT wykorzystują kilka procedur pomocniczych. Procedury DSKINT (Disk INTerface), CIOMAIN (CIO MAIN routine), CASOPIN (CASsette OPen for INput) i CASRDBL (CASsette ReaD BLock) są standardowymi procedurami wejścia/wyjścia i są opisane w książce "Mapa pamięci Atari XL/XE. Procedury wejścia/wyjścia" wydanej przez SOETO. Tu przedstawione będą tylko procedury GETBLK, DRDERR i BLOAD.
            0100 ;GET BlocK
            0110 ;
            0120 CASSBT = $03EA
            0130 DCMND = $0302
            0140 DUNIT = $0301
            0150 JCASRDBL = $E47A
            0160 JDSKINT = $E453
            0170 ;
            0180     *=  $C659
            0190 ;
            0200     LDA CASSBT
            0210     BEQ DSK
            0220     JMP JCASRDBL
            0230 DSK LDA #$52
            0240     STA DCMND
            0250     LDA #$01
            0260     STA DUNIT
            0270     JMP JDSKINT
    Procedura GETBLK rozpoznaje według zawartości rejestru CASSBT rodzaj urządzenia zewnętrznego (stacja dysków czy magnetofon) i przechodzi do procedury odczytu z magnetofonu CASRDBL, albo ustawia numer stacji dysków (1) i kod rozkazu odczytu sektora ($52) oraz przechodzi do procedury operacji dyskowych DSKINT.
            0100 ;Boot LOADer
            0110 ;
            0120 BOOTAD = $0242
            0130 DOSINI = $0C
            0140 RAMLO = $04
            0150 ;
            0160     *=  $C629
            0170 ;
            0180     CLC
            0190     LDA BOOTAD
            0200     ADC #$06
            0210     STA RAMLO
            0220     LDA BOOTAD+1
            0230     ADC #$00
            0240     STA RAMLO+1
            0250     JMP (RAMLO)
            0260 DOSINITC JMP (DOSINI)
    Zadaniem procedury BLOAD jest wykonanie wstępnych czynności wymaganych przez wczytany program. W tym celu adres ładowania programu pobrany z rejestru BOOTAD jest zwiększany o 6 (liczba bajtów nagłówka) i umieszczany w RAMLO. Wektor RAMLO służy następnie do wykonania skoku do wczytanego programu (do jego części wstępnej - w przypadku magnetofonu jest to zwykle zatrzymanie silnika).
            0100 ;Disk ReaD ERRor
            0110 ;
            0120 ICBUFA = $0344
            0130 ICBUFL = $0348
            0140 ICCMD = $0342
            0150 JCIOMAIN = $E456
            0160 ;
            0170 ;Disk ERRor MeSsaGe
            0180 ;
            0190     *=  $C43D
            0200 ;
            0210 DERRMSG .BYTE "BOOT ERROR"
            0220     .BYTE $9B   ;End Of Line
            0230 ;
            0240 ;Disk ReaD ERRor
            0250 ;
            0260     *= $C63E
            0270 ;
            0280     LDX # <DERRMSG
            0290     LDY # >DERRMSG
            0300 PUTLINE TXA
            0310     LDX #$00
            0320     STA ICBUFA,X
            0330     TYA
            0340     STA ICBUFA+1,X
            0350     LDA #$09
            0360     STA ICCMD,X
            0370     LDA #$FF
            0380     STA ICBUFL,X
            0390     JMP JCIOMAIN
    Wystąpienie błędu w dowolnej fazie procedury BOOT powoduje wywołanie procedury DRDERR. W rejestrze X umieszczany jest młodszy, a w rejestrze Y starszy bajt adresu tekstu "BOOT ERROR". Następnie są one przepisywane do ICBUFA jako adres bufora dla IOCB 0, a do rejestru ICCMD wpisywany jest kod rozkazu "Put Line" (wyślij linię). Po przejściu do procedury CIOMAIN powoduje to wyświetlenie na ekranie wskazanego napisu.

    Procedurę tą można łatwo wykorzystać do pisania na ekranie w trybie 0. Należy wpisać do rejestrów X i Y adres tekstu i wywołać procedurę DRDERR od etykiety PUTLINE ($C642) zamiast od początku. Maksymalna długość tekstu (razem ze znakiem końca linii - RETURN) może wynosić 255 bajtów. Tekst jest umieszczany na ekranie począwszy od aktualnej pozycji kursora.

2.5. Procedura testu komputera

    W przypadku wystąpienia błędu podczas inicjowania systemu operacyjnego wywoływana jest procedura TESTROM.
            0100 ;TEST ROM enable
            0110 ;
            0120 SWITROM = $C8FC
            0130 ;
            0140     *=  $F223
            0150 ;
            0160     JMP SWITROM
    Jedyną jej funkcją jest bezpośredni skok do procedury SWITROM. Wydaje się to całkiem bezsensowne, lecz w tym miejscu znajdował się w starych modelach Atari 400/800 początek procedury tzw. "memo pad". Skok ten służy więc zachowaniu adresu pomimo zmiany systemu, gdyż adres ten wykorzystywany jest w niektórych programach.
            0100 ;SWITch ROM
            0110 ;
            0120 COLDST = $0244
            0130 JTESTST = $E483
            0140 PORTB = $D301
            0150 ;
            0160     *=  $C8FC
            0170 ;
            0180     LDA #$FF
            0190     STA COLDST
            0200     LDA PORTB
            0210     AND #$7F
            0220     STA PORTB
            0230     JMP JTESTST
    Właściwe przejście do testowania komputera odbywa się w procedurze SWITROM. Ustawia ona wskaźnik zimnego startu na $FF (zimny start po RESET) oraz przełącza program testowania pamięci (SELFTEST) do obszaru $5000-$57FF. Na zakończenie wykonuje pośredni skok do procedury testującej.
Zientara Wojciech: Mapa pamięci Atari XL/XE. Podstawowe procedury systemu operacyjnego, SOETO, Warszawa, 1988.