Powrót do spisu treści

Rozdział 5

PROCEDURY OPERATORÓW I FUNKCJI

    Opisana w poprzednim rozdziale instrukcja przypisania wykorzystuje wiele różnorodnych operatorów i funkcji. Sposób wywołania wszystkich procedur wykonawczych operatorów i funkcji jest jednakowy (zob. opis procedury EXEOP). Elementy składowe instrukcji przypisania można podzielić na sześć podstawowych grup: operatory arytmetyczne, operatory logiczne, operatory relacji, operatory przypisania, nawiasy oraz funkcje. Są one kolejno opisane w tym rozdziale.

5.1. Operatory arytmetyczne

    Do operatorów arytmetycznych zaliczamy operatory dodawania (+), odejmowania (-), mnożenia (*), dzielenia (/) i potęgowania (^) oraz znaki plus (+) i minus (-). Najprostszym operatorem jest znak plus. Nie zmienia on nic w wartości liczby i cała procedura wykonawcza ogranicza się do rozkazu RTS. Znajduje się on w procedurze RSTPTR, która została opisana w poprzednim rozdziale (str. 64).

    Wykonanie operatora znaku minus (-), który zmienia znak liczby, jest realizowane przez procedurę XMIN. Liczba do operacji jest pobierana z bufora tokenizacji przez procedurę GETVAR. Następnie zmieniana jest wartość najstarszego bitu w pierwszym bajcie liczby FP, co powoduje zmianę znaku tej liczby. XMIN kończy się skokiem do procedury PUTVAR, która zapisuje wynik ponownie do bufora tokenizacji.
            0100 ;eXecute MINus sign
            0110 ;
            0120 FR0 =   $D4
            0130 GETVAR = $ABE9
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $AC95
            0170 ;
            0180     JSR GETVAR
            0190     LDA FR0
            0200     BEQ EXIT
            0210     EOR #$80
            0220     STA FR0
            0230 EXIT JMP PUTVAR
    Działanie procedury GETVAR jest odwrotne do PUTVAR. Wartość odczytana z licznika STPTR i zmniejszona o jeden wskazuje - po pomnożeniu przez osiem - ostatni bajt ostatniej liczby w buforze. Według tej wartości osiem bajtów liczby jest przepisywane z bufora do rejestrów VART, VARN i FR0.
            0100 ;GET VARiable
            0110 ;
            0120 LOMEM = $80
            0130 STPTR = $AA
            0140 VART =  $D2
            0150 ;
            0160     *=  $ABE9
            0170 ;
            0180     LDA STPTR
            0190     DEC STPTR
            0200     ASL A
            0210     ASL A
            0220     ASL A
            0230     TAY
            0240     DEY
            0250     LDX #$07
            0260 LOOP LDA (LOMEM),Y
            0270     STA VART,X
            0280     DEY
            0290     DEX
            0300     BPL LOOP
            0310     RTS

5.1.1. Dodawanie

    Operacja dodawania (+) jest realizowana przez procedurę XADD. Składa się ona jedynie z trzech wywołań innych procedur. GETVRS pobiera z bufora dwie liczby, BADD wykonuje ich dodawanie, a PUTVAR umieszcza rezultat ponownie w buforze.
            0100 ;eXecute ADDition
            0110 ;
            0120 BADD =  $AD26
            0130 GETVRS = $ABFD
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $BDFA
            0170 ;
            0180     JSR GETVRS
            0190     JSR BADD
            0200     JMP PUTVAR
    Procedura GETVRS służy do odczytania dwóch liczb dla operacji arytmetycznej i jest złożeniem dwóch procedur GETVAR. Pierwsze wywołanie GETVAR pobiera jedną liczbę z bufora tokenizacji i umieszcza ją w rejestrze FR0. Liczba ta jest przepisywana przez procedurę FMOV01 (wchodzi ona w skład pakietu zmiennoprzecinkowego) do rejestru FR1. Kończący procedurę GETVRS skok do GETVAR powoduje pobranie drugiej liczby do rejestru FR0.
            0100 ;GET VaRiableS
            0110 ;
            0120 FMOV01 = $DDB6
            0130 GETVAR = $ABE9
            0140 ;
            0150     *=  $ABFD
            0160 ;
            0170     JSR GETVAR
            0180     JSR FMOV01
            0190     JMP GETVAR
    Zadaniem procedury BADD jest jedynie wywołanie procedury zmiennoprzecinkowej FADD. Użycie BADD zamiast bezpośredniego wywołania FADD ma na celu umożliwienie poprawnej sygnalizacji błędu powstałego podczas dodawania. Podobne jest znaczenie procedur BSUB, BMUL i BDIV. Zakończenie operacji zmiennoprzecinkowej z ustawionym bitem Carry oznacza wystąpienie błędu. W takich przypadkach wykonywany jest skok do procedury OVUNER (OVerflow/UNderflow ERror).
            0100 FADD =  $DA66
            0110 FDIV =  $DB28
            0120 FMUL =  $DADB
            0130 FSUB =  $DA60
            0140 OVUNER = $B91E
            0150 ;
            0160     *=  $AD26
            0170 ;
            0180 ;Basic ADDition
            0190 ;
            0200 BADD JSR FADD
            0210     BCS ERR
            0220     RTS
            0230 ;
            0240 ;Basic SUBtraction
            0250 ;
            0260 BSUB JSR FSUB
            0270     BCS ERR
            0280     RTS
            0290 ;
            0300 ;Basic MULtiplication
            0310 ;
            0320 BMUL JSR FMUL
            0330     BCS ERR
            0340     RTS
            0350 ;
            0360 ;Basic DIVision
            0370 ;
            0380 BDIV JSR FDIV
            0390     BCS ERR
            0400     RTS
            0410 ERR JSR OVUNER

5.1.2. Odejmowanie

    Operacja odejmowania (-) jest realizowana identycznie, jak dodawania. Po odczytaniu dwóch liczb przez GETVRS odejmowanie jest wykonywane przez BSUB (zob. wyżej). Uzyskany wynik jest zapisywany w buforze tokenizacji przez procedurę PUTVAR.
            0100 ;eXecute SUBtraction
            0110 ;
            0120 BSUB =  $AD2C
            0130 GETVRS = $ABFD
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $AC7A
            0170 ;
            0180     JSR GETVRS
            0190     JSR BSUB
            0200     JMP PUTVAR

5.1.3. Mnożenie

    Także przebieg operacji mnożenia (*) jest analogiczny do przebiegu poprzednio opisanych operacji. W celu realizacji obliczenia jest tu wywoływana procedura BMUL.
            0100 ;eXecute MULtiplication
            0110 ;
            0120 BMUL =  $AD32
            0130 GETVRS = $ABFD
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $AC83
            0170 ;
            0180     JSR GETVRS
            0190     JSR BMUL
            0200     JMP PUTVAR

5.1.4. Dzielenie

    Ostatnią z prostych operacji arytmetycznych jest dzielenie (/) wykonywane przez procedurę XDIV. Jedyną różnicą w stosunku do poprzednio opisanych procedur wykonawczych jest zastosowanie do realizacji obliczenia procedury BDIV.
            0100 ;eXecute DIVision
            0110 ;
            0120 BDIV =  $AD38
            0130 GETVRS = $ABFD
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $AC8C
            0170 ;
            0180     JSR GETVRS
            0190     JSR BDIV
            0200     JMP PUTVAR

5.1.5. Potęgowanie

    Znacznie bardziej skomplikowanym działaniem jest podnoszenie do potęgi (oznaczone operatorem ^). Jest ono wykonywane przez procedurę XRPW. Na jej początku sprawdzane są wartości liczb. Gdy wykładnik jest równy zero, to przez skok do procedury ONEP (wewnątrz XLEQ - zob. rozdział 5.3.1) wynik jest ustalany na jeden. Jeśli liczba potęgowana jest równa zero, to dla ujemnej wartości wykładnika sygnalizowana jest niepoprawna wartość (skok do procedury VALER w XSQR - zob. rozdział 5.2.4), zaś dla pozostałych wykładników wynikiem jest zero (następuje bezpośredni skok do procedury PUTVAR).
            0100 BMUL =  $AD32
            0110 CONVFN = $BA76
            0120 EXP10 = $DDCC
            0130 FR0 =   $D4
            0140 FR1 =   $E0
            0150 GETVRS = $ABFD
            0160 LOG10 = $DED1
            0170 ONEP =  $ACF0
            0180 OVUNER = $B91E
            0190 PUTVAR = $ABB2
            0200 VALER = $B15B
            0210 ZTEMP2 = $F7
            0220 ;
            0230     *=  $B15E
            0240 ;
            0250 ;eXecute Raise to PoWer function
            0260 ;
            0270 XRPW JSR GETVRS
            0280     LDA FR1
            0290     BEQ ONE
            0300     ROL A
            0310     LDY FR0
            0320     BNE EXE
            0330     BCS VALER
            0340 ;
            0350 ;PUT RESult
            0360 ;
            0370 PUTRES JMP PUTVAR
            0380 ONE JMP ONEP
            0390 EXE LDX #FR0
            0400     JSR CONVFN
            0410     ROR A
            0420     PHA
            0430     LDX #FR1
            0440     JSR CONVFN
            0450     TYA
            0460     BPL POS
            0470     AND #$7F
            0480     STA FR0
            0490     BCS GOOD
            0500     PLA
            0510     BCC VALER
            0520 GOOD LDA FR1
            0530     BPL BPS
            0540     CLC
            0550 BPS PHP
            0560     LDX ZTEMP2
            0570     CPX #$05
            0580     BCS PLS
            0590     LDA FR1+1,X
            0600     ROR A
            0610     BCC PLS
            0620     LDA #$80
            0630     BNE MIN
            0640 POS LDA FR1
            0650     BPL SST
            0660     CLC
            0670 SST PHP
            0680 PLS LDA #$00
            0690 MIN PHA
            0700     LDX #$05
            0710 LP1 LDA FR1,X
            0720     PHA
            0730     DEX
            0740     BPL LP1
            0750     JSR LOG10
            0760     LDX #$00
            0770     LDY #$05
            0780 LP2 PLA
            0790     STA FR1,X
            0800     INX
            0810     DEY
            0820     BPL LP2
            0830     JSR BMUL
            0840     JSR EXP10
            0850     BCS ERR
            0860     PLA
            0870     ORA FR0
            0880     STA FR0
            0890     PLP
            0900     PLA
            0910     BPL PUTRES
            0920     BCC PUTRES
            0930     LDX #FR0
            0940     JSR CONVFN
            0950     BCS PUTRES
            0960     LDA FR0
            0970     SEC
            0980     AND #$7F
            0990     SBC #$3F
            1000     CMP #$06
            1010     BCS PUT
            1020     TAX
            1030     TAY
            1040     SED
            1050     SEC
            1060 LP3 LDA FR0,X
            1070     ADC #$00
            1080     STA FR0,X
            1090     DEX
            1100     BNE LP3
            1110     CLD
            1120     BCC NXT
            1130     INC FR0
            1140     INC FR0+1
            1150 NXT INY
            1160     CPY #$06
            1170     BCS PUT
            1180     STX FR0,Y
            1190     BCC NXT
            1200 PUT JMP PUTVAR
            1210 ERR JSR OVUNER
    Dla wszystkich pozostałych wartości liczby potęgowanej i wykładnika przeprowadzane jest obliczenie. Przed jego opisaniem trzeba jednak wyjaśnić działanie pomocniczej procedury CONVFN. Wymaga ona jako danej wejściowej adresu rejestru FRn w rejestrze X. Jeżeli wskazany rejestr zawiera liczbę ujemną, to procedura CONVFN jest przerywana ze skasowanym bitem Carry. Dla liczb dodatnich ich wykładnik jest umieszczany w rejestrze ZTEMP2 (Zeropage TEMPorary register), a do akumulatora są odczytywane dwie pierwsze cyfry różne od zera stojące poniżej pozycji setek. Na przykład dla liczby 1234 będzię to 34. Jeśli nie ma takich cyfr, to bit Carry jest ustawiany.
            0100 ;CONVert Floating Number
            0110 ;
            0120 ZTEMP1 = $F5
            0130 ZTEMP2 = $F7
            0140 ;
            0150     *=  $BA76
            0160 ;
            0170     SEC
            0180     LDA $00,X
            0190     AND #$7F
            0200     SBC #$40
            0210     BCC END
            0220     STA ZTEMP1
            0230     STA ZTEMP2
            0240     TXA
            0250     ADC ZTEMP1
            0260     INX
            0270     INX
            0280     INX
            0290     INX
            0300     INX
            0310     INX
            0320     STX ZTEMP1
            0330     TAX
            0340 LOOP INX
            0350     CPX ZTEMP1
            0360     BCS END
            0370     LDA $00,X
            0380     BEQ LOOP
            0390 END RTS
    Procedura CONVFN jest najpierw wywoływana dla liczby potęgowanej, a zawartość akumulatora podzielona przez dwa jest zapisywana na stosie. Przy drugim wywołaniu CONVFN sprawdzany jest wykładnik potęgi. Teraz jest wyznaczany znak wyniku, przy czym sposób obliczenia zależy od znaku potęgowanej liczby. Następnie (w liniach 700-850 na wydruku) przeprowadzane jest właściwe obliczenie potęgi według wzoru:
                     A^B=10^(log10A*B)
    W tym miejscu procedura XRPW kończy się dla następujących przypadków: ujemny wykładnik, ujemna liczba potęgowana lub brak cyfry różnej od zera poniżej pozycji setek dla dodatniej liczby potęgowanej. Obliczenia są kontynuowane tylko dla cyfr znaczących mniejszych od setek, jeśli liczba potęgowana jest mniejsza od 10,000,000,000 (1005).

5.2. Funkcje

    Ważnym elementem interpretera są procedury obliczania różnorodnych funkcji. Ich wykorzystanie przy pisaniu własnych programów w języku maszynowym pozwala zaoszczędzić dużo pracy. Programując zaś w Basicu trzeba znać ograniczenia tych procedur, aby uniknąć błędów powodowanych przez niepoprawne wartości lub zbyt przybliżone wyniki. Atari Basic posiada 24 funkcje, których opis znajduje się poniżej, poza funkcją SGN opisaną razem z operatorami relacji.

5.2.1. Funkcja ABS

    Funkcja ABS zwraca moduł czyli wartość bezwzględną podanej liczby. Dla uzyskania takiego efektu wystarczy skasowanie najstarszego bitu w pierwszym bajcie liczby. Czynność ta jest wykonywana przez procedurę XABS. Liczba poddawana tej operacji jest pobierana z bufora przez procedurę GETVAR, a ponownie zapisywana przez PUTVAR.
            0100 ;eXecute ABS function
            0110 ;
            0120 FR0 =   $D4
            0130 GETVAR = $ABE9
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $B099
            0170 ;
            0180     JSR GETVAR
            0190     LDA FR0
            0200     AND #$7F
            0210     STA FR0
            0220     JMP PUTVAR

5.2.2. Funkcja RND

    Funkcja RND zwraca wartość losową z przedziału <0,1) czyli liczbę o wartości większej lub równej zero i mniejszej od jeden. Realizowana jest ona przez procedurę XRND. Najpierw stała RNDC o wartości 65536 jest przepisywana do rejestru FR1. Znajdujące się tu wywołanie procedury GETVAR jest konieczne dla usunięcia z bufora argumentu funkcji, który nie ma żadnego znaczenia. Następnie dwa przypadkowe bajty z rejestru sprzętowego RANDOM są umieszczane w rejestrze FR0 i zamieniane na liczbę zmiennoprzecinkową z zakresu od 0 do 65535. Liczba ta jest dzielona przy pomocy procedury BDIV przez stałą 65536. Na końcu uzyskany wynik jest przepisywany do bufora przez procedurę PUTVAR.
            0100 ;eXecute RND function
            0110 ;
            0120 BDIV =  $AD38
            0130 FLD1R = $DD98
            0140 FR0 =   $D4
            0150 GETVAR = $ABE9
            0160 IFP =   $D9AA
            0170 PUTVAR = $ABB2
            0180 RANDOM = $D20A
            0190 ;
            0200     *=  $B076
            0210 ;
            0220     LDX # <RNDC
            0230     LDY # >RNDC
            0240     JSR FLD1R
            0250     JSR GETVAR
            0260     LDY RANDOM
            0270     STY FR0
            0280     LDY RANDOM
            0290     STY FR0+1
            0300     JSR IFP
            0310     JSR BDIV
            0320     JMP PUTVAR
            0330 ;
            0340 ;RaNDom Constant
            0350 ;
            0360 RNDC .BYTE $42,$06,$55
            0370     .BYTE $36,$00,$00
    Trzeba zwrócić uwagę na to, że argument funkcji RND nie ma żadnego znaczenia pomimo, iż jest umieszczany w rejestrze FR0. Procedura IFP zamienia na liczbę zmiennoprzecinkową tylko dwa pierwsze bajty tego rejestru, a więc tylko te, które zostały odczytane z RANDOM.

5.2.3. Funkcja INT

    Funkcja INT zwraca część całkowitą podanego argumentu, przy czym liczba jest zawsze zaokrąglana do mniejszej wartości. Oznacza to, że INT(5.5)=5, lecz INT(-5.5)=-6! Procedura realizacyjna tej operacji - XINT - jest bardzo zbliżona do procedur operacji arytmetycznych. Składa się ona z wywołań trzech procedur: odczytu liczby (GETVAR), wykonania obliczenia (BINT) i zapisu wyniku (PUTVAR).
            0100 ;eXecute INT function
            0110 ;
            0120 BINT =  $B0D2
            0130 GETVAR = $ABE9
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $B0C8
            0170 ;
            0180     JSR GETVAR
            0190     JSR BINT
            0200     JMP PUTVAR
    Zasadnicze obliczenia w funkcji INT są wykonywane przez procedurę BINT. Rozpoczyna się ona od obliczenia pozycji przecinka w liczbie poddawanej przekształceniu. Następnie wszystkie cyfry po przecinku są zerowane, przy czym ich dotychczasowe wartości są sumowane w akumulatorze. Jeżeli liczba była dodatnia (FR0 mniejsze od $80) lub całkowita ujemna (akumulator równy zero), to BINT jest opuszczana przez skok do procedury normalizującej format - NFR0. Niecałkowita wartość liczby ujemnej wymaga jeszcze odjęcia jedności od wyniku (dokładnie jest to dodanie -1). Po tej operacji normalizacja formatu nie jest już potrzebna.
            0100 ;Basic INTeger routine
            0110 ;
            0120 BADD =  $AD26
            0130 FR0 =   $D4
            0140 FR1 =   $E0
            0150 NFR0 =  $DC00
            0160 ZFR0 =  $DA44
            0170 ;
            0180     *=  $B0D1
            0190 ;
            0200     LDA FR0
            0210     AND #$7F
            0220     SEC
            0230     SBC #$3F
            0240     BPL EXE
            0250     LDA #$00
            0260 EXE TAX
            0270     LDA #$00
            0280     TAY
            0290 LOOP CPX #$05
            0300     BCS ADD
            0310     ORA FR0+1,X
            0320     STY FR0+1,X
            0330     INX
            0340     BNE LOOP
            0350 ADD LDX FR0
            0360     BPL NRM
            0370     TAX
            0380     BEQ NRM
            0390     LDX #FR1
            0400     JSR ZFR0+2
            0410     LDA #$C0
            0420     STA FR1
            0430     LDA #$01
            0440     STA FR1+1
            0450     JSR BADD
            0460     RTS
            0470 NRM JMP NFR0

5.2.4. Funkcja SQR

    Funkcja SQR zwraca wartość pierwiastka kwadratowego podnego argumentu. Także tutaj zastosowano wywołanie zasadniczej procedury wykonawczej SQR po odczytaniu liczby przez GETVAR. Natomiast poprawność wyniku jest rozpoznawana w procedurze XSQR przez sprawdzenie bitu Carry. Błąd jest sygnalizowany przez BVALER (Bad VALue ERror), zaś sukces powoduje skok do PUTRES (znajduje się tam tylko rozkaz skoku JMP PUTVAR). Obie użyte tu etykiety - RESULT i VALER - są wykorzystywane przez procedury innych funkcji, co pozwala na zastąpienie rozkazów skoków bezwzględnych (JMP i JSR) rozkazami skoków względnych (B..). Każda taka zamiana daje jeden bajt oszczędności.
            0100 ;eXecute SQR function
            0110 ;
            0120 BVALER = $B92E
            0130 GETVAR = $ABE9
            0140 PUTRES = $B16C
            0150 SQR =   $BF43
            0160 ;
            0170     *=  $B153
            0180 ;
            0190 XSQR JSR GETVAR
            0200     JSR SQR
            0210 ;
            0220 ;RESULT
            0230 ;
            0240 RESULT BCC PUTRES
            0250 ;
            0260 ;VALue ERror
            0270 ;
            0280 VALER JSR BVALER
    Ze względu na znaczny stopień skomplikowania procedury SQR jej opis zostanie pominięty, a dociekliwi Czytelnicy mogą dokonać analizy samodzielnie. Należy jednak zauważyć, że poza wykorzystywaniem standardowych procedur obliczeń zmiennoprzecinkowych (FADD, FSUB, FMUL i FDIV) oraz przemieszczeń liczb FP (FLD.., FST.. i FMOV..) są tu jeszcze używane dwie tablice: TLOG i SQRC. Pierwsza z nich zawiera współczynniki logarytmowania i znajduje się w pakiecie FP.
            0100 DIGRT = $F1
            0110 ESIGN = $EF
            0120 FADD =  $DA66
            0130 FDIV =  $DB28
            0140 FLD0R = $DD89
            0150 FLD1R = $DD98
            0160 FMOV01 = $DDB6
            0170 FMUL =  $DADB
            0180 FPSCR = $05E6
            0190 FPSCR1 = $05EC
            0200 FR0 =   $D4
            0210 FR1 =   $E0
            0220 FST0R = $DDA7
            0230 FSUB =  $DA60
            0240 SQRC =  $BAF1
            0250 TLOG =  $DF66
            0260 ;
            0270     *=  $BF41
            0280 ;
            0290 ERR SEC
            0300     RTS
            0310 ;
            0320 ;SQuare Root routine
            0330 ;
            0340 SQR LDA #$00
            0350     STA DIGRT
            0360     LDA FR0
            0370     BMI ERR
            0380     CMP #$3F
            0390     BEQ LBL1
            0400     CLC
            0410     ADC #$01
            0420     STA DIGRT
            0430     STA FR1
            0440     LDA #$01
            0450     STA FR1+1
            0460     LDX #$04
            0470     LDA #$00
            0480 NXT1 STA FR1+2,X
            0490     DEX
            0500     BPL NXT1
            0510     JSR FDIV
            0520 LBL1 LDA #$06
            0530     STA ESIGN
            0540     LDX # <FPSCR
            0550     LDY # >FPSCR
            0560     JSR FST0R
            0570     JSR FMOV01
            0580     LDX # <SQRC
            0590     LDY # >SQRC
            0600     JSR FLD0R
            0610     JSR FSUB
            0620     LDX # <FPSCR
            0630     LDY # >FPSCR
            0640     JSR FLD1R
            0650     JSR FMUL
            0660 LOOP LDX # <FPSCR1
            0670     LDY # >FPSCR1
            0680     JSR FST0R
            0690     JSR FMOV01
            0700     LDX # <FPSCR
            0710     LDY # >FPSCR
            0720     JSR FLD0R
            0730     JSR FDIV
            0740     LDX # <FPSCR1
            0750     LDY # >FPSCR1
            0760     JSR FLD1R
            0770     JSR FSUB
            0780     LDX # <TLOG+6
            0790     LDY # >TLOG+6
            0800     JSR FLD1R
            0810     JSR FMUL
            0820     LDA FR0
            0830     BEQ LBL2
            0840     LDX # <FPSCR1
            0850     LDY # >FPSCR1
            0860     JSR FLD1R
            0870     JSR FADD
            0880     DEC ESIGN
            0890     BPL LOOP
            0900 LBL2 LDX # <FPSCR1
            0910     LDY # >FPSCR1
            0920     JSR FLD0R
            0930     LDA DIGRT
            0940     BEQ END
            0950     SEC
            0960     SBC #$40
            0970     CLC
            0980     ROR A
            0990     CLC
            1000     ADC #$40
            1010     AND #$7F
            1020     STA FR1
            1030     LDA DIGRT
            1040     ROR A
            1050     LDA #$01
            1060     BCC LBL3
            1070     LDA #$10
            1080 LBL3 STA FR1+1
            1090     LDX #$04
            1100     LDA #$00
            1110 NXT2 STA FR1+2,X
            1120     DEX
            1130     BPL NXT2
            1140     JSR FMUL
            1150 END RTS
    Druga tablica, umieszczona w interpreterze Atari Basic zawiera stałą o wartości 2 (2*1000). Stała ta jest wykorzystywana jako wartość stopnia pierwiastkowania.
            0100 ;SQuare Root Constant
            0110 ;
            0120     *=  $BAF1
            0130 ;
            0140     .BYTE $40,$02
            0150     .BYTE $00,$00
            0160     .BYTE $00,$00
    Konieczna jest tu jeszcze jedna dygresja. Uważny Czytelnik powinien zauważyć niezgodność adresu procedury SQR z podanym w pierwszej części "Mapy" ("Podstawowe procedury systemu operacyjnego"). Prawdziwy jest oczywiście adres podany tu, choć we wszystkich dostępnych źródłach jest inaczej. Podawany tam bowiem adres procedury SQR jest adresem w interpreterze Basic Revision B!, a więc w poprzedniej wersji. Uwaga ta dotyczy także pozostałych procedur zmiennoprzecinkowych: SIN, COS i ATAN.

5.2.5. Funkcja EXP

    Funkcja EXP zwraca wartość podniesienia liczby e (2.71828183) do potęgi podanej jako argument. Do realizacji tej funkcji wykorzystywana jest przez procedurę XEXP standardowa procedura pakietu FP - EXP. Przedtem jednak argument funkcji jest pobierany z bufora przez wywołanie GETVAR. Uzyskany wynik jest natomiast przesyłany do procedury RESULT, gdzie dokonywana jest ocena jego poprawności i zapisanie do bufora.
            0100 ;eXecute EXP function
            0110 ;
            0120 EXP =   $DDC0
            0130 GETVAR = $ABE9
            0140 RESULT = $B159
            0150 ;
            0160     *=  $B14A
            0170 ;
            0180     JSR GETVAR
            0190     JSR EXP
            0200     JMP RESULT

5.2.6. Funkcje LOG i CLOG

    Dla podanego argumentu funkcja LOG zwraca wartość logarytmu naturalnego (przy podstawie e), a funkcja CLOG - logarytmu dziesiętnego (przy podstawie 10). Wykonanie tych funkcji jest przeprowadzane przez procedury XLOG i XCLOG. Są one niemal identyczne, a różni je tylko wywoływana procedura pakietu FP: dla XLOG jest to LOG, zaś dla XCLOG - LOG10. Najpierw liczba do logarytmowania jest odczytywana z bufora przez GETVAR i gdy jest równa zero, to niepoprawna wartość jest sygnalizowana przez skok do VALER. W przeciwnym przypadku wywoływana jest odpowiednia procedura zmiennoprzecinkowa. Od tego miejsca przebieg obu procedur (XLOG i XCLOG) jest wspólny.
            0100 ;eXecute LOG function
            0110 ;
            0120 FR0 =   $D4
            0130 GETVAR = $ABE9
            0140 LOG =   $DECD
            0150 LOG10 = $DED1
            0160 PUTRES = $B16C
            0170 VALER = $B15B
            0180 ;
            0190     *=  $B121
            0200 ;
            0210 XLOG JSR GETVAR
            0220     LDA FR0
            0230     BEQ VALER
            0240     JSR LOG
            0250 ;
            0260 ;STore LOGarithm
            0270 ;
            0280 STLOG BCS VALER
            0290     LDA FR0
            0300     EOR #$3B
            0310     BNE PUTRES
            0320     LDA FR0+1
            0330     AND #$F8
            0340     BNE PUTRES
            0350     STA FR0
            0360     BEQ PUTRES
            0370 ;
            0380 ;eXecute CLOG function
            0390 ;
            0400 XCLOG JSR GETVAR
            0410     LDA FR0
            0420     BEQ VALER
            0430     JSR LOG10
            0440     JMP STLOG
    Przede wszystkim ustawiony bit Carry powoduje sygnalizację błędu przez skok do VALER. Następnie uzyskany rezultat jest przetwarzany do poprawnej postaci i procedura jest opuszczana skokiem do PUTRES.

5.2.7. Funkcja SIN

    Funkcja SIN zwraca wartość sinusa podanego argumentu. Procedura wykonawcza tej funkcji - XSIN - ma standardową strukturę: odczyt argumentu (GETVAR), wykonanie obliczenia (SIN) oraz sprawdzenie i zapisanie wyniku (RESULT).
            0100 ;eXecute SIN function
            0110 ;
            0120 GETVAR = $ABE9
            0130 RESULT = $B159
            0140 SIN =   $BE05
            0150 ;
            0160     *=  $B106
            0170 ;
            0180     JSR GETVAR
            0190     JSR SIN
            0200     JMP RESULT
    Zasadnicza procedura obliczeniowa jest wspólna dla obu funkcji trygonometrycznych (SIN i COS). Różna jest tylko wartość początkowa w tej procedurze. Do rejestru FCHRFLG (First CHaRacter FLaG) jest wpisywana wartość $01 dla cosinusa, $02 dla sinusa liczby ujemnej i $04 dla sinusa liczby dodatniej. Szczegółowy opis tej procedury zostanie pominięty. Trzeba jednak zwrócić uwagę na dwie tablice wykorzystywane przez nią. Tablica TRIGC zawiera wartość 1.
            0100 ;TRIGonometric's Constant
            0110 ;
            0120     *=  $BECF
            0130 ;
            0140     .BYTE $40,$01,$00
            0150     .BYTE $00,$00,$00

            0100 DIGRT = $F1
            0110 FCHRFLG = $F0
            0120 FDIV =  $DB28
            0130 FLD0R = $DD89
            0140 FLD1R = $DD98
            0150 FMOV01 = $DDB6
            0160 FMUL =  $DADB
            0170 FPSCR = $05E6
            0180 FR0 =   $D4
            0190 FR1 =   $E0
            0200 FST0R = $DDA7
            0210 FSUB =  $DA60
            0220 PLYEVL = $DD40
            0230 RADFLG = $FB
            0240 TRIGC = $BECF
            0250 TSCC =  $BE9F
            0260 ;
            0270     *=  $BE03
            0280 ;
            0290 ERR SEC
            0300     RTS
            0310 ;
            0320 ;SINus routine
            0330 ;
            0340 SIN LDA #$04
            0350     BIT FR0
            0360     BPL EXE
            0370     LDA #$02
            0380     BNE EXE
            0390 ;
            0400 ;COSinus routine
            0410 ;
            0420 COS LDA #$01
            0430 EXE STA FCHRFLG
            0440     LDA FR0
            0450     AND #$7F
            0460     STA FR0
            0470     LDA #$BD
            0480     CLC
            0490     ADC RADFLG
            0500     TAX
            0510     LDY #$BE
            0520     JSR FLD1R
            0530     JSR FDIV
            0540     BCC CNT
            0550     RTS
            0560 CNT LDA FR0
            0570     AND #$7F
            0580     SEC
            0590     SBC #$40
            0600     BMI LBL2
            0610     CMP #$04
            0620     BPL ERR
            0630     TAX
            0640     LDA FR0+1,X
            0650     STA DIGRT
            0660     AND #$10
            0670     BEQ LBL1
            0680     LDA #$02
            0690 LBL1 CLC
            0700     ADC DIGRT
            0710     AND #$03
            0720     ADC FCHRFLG
            0730     STA FCHRFLG
            0740     STX DIGRT
            0750     JSR FMOV01
            0760     LDX DIGRT
            0770     LDA #$00
            0780 LOOP STA FR1+2,X
            0790     INX
            0800     CPX #$03
            0810     BCC LOOP
            0820     JSR FSUB
            0830 LBL2 LSR FCHRFLG
            0840     BCC LBL3
            0850     JSR FMOV01
            0860     LDX # <TRIGC
            0870     LDY # >TRIGC
            0880     JSR FLD0R
            0890     JSR FSUB
            0900 LBL3 LDX # <FPSCR
            0910     LDY >FPSCR
            0920     JSR FST0R
            0930     JSR FMOV01
            0940     JSR FMUL
            0950     BCS ERR
            0960     LDA #$06
            0970     LDX # <TSCC
            0980     LDY # >TSCC
            0990     JSR PLYEVL
            1000     LDX # <FPSCR
            1010     LDY # >FPSCR
            1020     JSR FLD1R
            1030     JSR FMUL
            1040     LSR FSCHFLG
            1050     BCC END
            1060     CLC
            1070     LDA FR0
            1080     BEQ END
            1090     EOR #$80
            1100     STA FR0
            1110 END RTS
    Druga tablica (TSCC - stosowana tylko do obliczania funkcji sinus i cosinus) zawiera siedem wartości dla procedury przeliczania wielomianowego PLYEVL (znajduje się ona w pakiecie FP - zob. "Mapa pamięci Atari XL/XE. Podstawowe procedury systemu operacyjnego"). Są to kolejno liczby: -3.55149939*10-6, 1.60442752*10-4, -4.681754355*10-7, 0.0796926239, -0.6459640867, 1.57079632 i 90.
0100 ;Table: SIN & COS Constants 0110 ; 0120 *= $BE9F 0130 ; 0140 .BYTE $BD,$03,$55 0150 .BYTE $14,$99,$39 0160 .BYTE $3E,$01,$60 0170 .BYTE $44,$27,$52 0180 .BYTE $BC,$46,$81 0190 .BYTE $75,$43,$55 0200 .BYTE $3F,$07,$96 0210 .BYTE $92,$62,$39 0220 .BYTE $BF,$64,$59 0230 .BYTE $64,$08,$67 0240 .BYTE $40,$01,$57 0250 .BYTE $07,$96,$32 0260 .BYTE $40,$90,$00 0270 .BYTE $00,$00,$00     Książka "Mapa pamięci Atari XL/XE. Podstawowe procedury systemu operacyjnego" podaje adresy procedur SIN i COS zawartych w poprzedniej wersji interpretera Atari Basic (Revision B). Uwaga ta dotyczy także pozostałych procedur zmiennoprzecinkowych: SQR i ATAN.

5.2.8. Funkcja COS

    Funkcja COS zwraca wartość cosinusa podanego argumentu. Jej procedura wykonawcza - XCOS - jest niemal identyczna z procedurą funkcji SIN (zob. wyżej).
            0100 ;eXecute COS function
            0110 ;
            0120 COS =   $BE0F
            0130 GETVAR = $ABE9
            0140 RESULT = $B159
            0150 ;
            0160     *=  $B10F
            0170 ;
            0180     JSR GETVAR
            0190     JSR COS
            0200     JSR RESULT

5.2.9. Funkcja ATN

    Funkcja ATN zwraca wartość arcus tangens podanego argumentu. Także tu procedura wykonawcza - XATN - jest niemal identyczna z procedurą funkcji SIN (zob. wyżej).
            0100 ;eXecute ATN function
            0110 ;
            0120 ATAN =  $BED5
            0130 GETVAR = $ABE9
            0140 RESULT = $B159
            0150 ;
            0160     *=  $B118
            0170 ;
            0180     JSR GETVAR
            0190     JSR ATN
            0200     JSR RESULT
    Odmienna jest natomiast właściwa procedura obliczeniowa ATAN. Ponieważ jej struktura jest bardzo skomplikowana i zawiera wiele kolejnych przekształceń matematycznych, to opis zostanie pominięty.
            0100 ;Arcus TANgent routine
            0110 ;
            0120 DIGRT = $F1
            0130 FADD =  $DA66
            0140 FCHRFLG = $F0
            0150 FDIV =  $DB28
            0160 FLD1R = $DD98
            0170 FMOV01 = $DDB6
            0180 FMUL =  $DADB
            0190 FPSCR = $05E6
            0200 FR0 =   $D4
            0210 FST0R = $DDA7
            0220 PLYEVL = $DD40
            0230 RADFLG = $FB
            0240 RSQT =  $DE95
            0250 TATAN = $DFAE
            0260 TATNC = $BEC9
            0270 ;
            0280     *=  $BED5
            0290 ;
            0300     LDA #$00
            0310     STA FCHRFLG
            0320     STA DIGRT
            0330     LDA FR0
            0340     AND #$7F
            0350     CMP #$40
            0360     BMI LBL1
            0370     LDA FR0
            0380     AND #$80
            0390     STA FCHRFLG
            0400     INC DIGRT
            0410     LDA #$7F
            0420     AND FR0
            0430     STA FR0
            0440     LDX # <TATAN+$3C
            0450     LDY # >TATAN+$3C
            0460     JSR RSQT
            0470 LBL1 LDX # <FPSCR
            0480     LDY # >FPSCR
            0490     JSR FST0R
            0500     JSR FMOV01
            0510     JSR FMUL
            0520     BCS END
            0530     LDA #$0B
            0540     LDX # <TATAN
            0550     LDY # >TATAN
            0560     JSR PLYEVL
            0570     BCS END
            0580     LDX # <FPSCR
            0590     LDY # >FPSCR
            0600     JSR FLD1R
            0610     JSR FMUL
            0620     BCS END
            0630     LDA DIGRT
            0640     BEQ LBL2
            0650     LDX # <TATAN+$42
            0660     LDY # >TATAN+$42
            0670     JSR FLD1R
            0680     JSR FADD
            0690     LDA FCHRFLG
            0700     ORA FR0
            0710     STA FR0
            0720 LBL2 LDA RADFLG
            0730     BEQ END
            0740     LDX # <TATNC
            0750     LDY # >TATNC
            0760     JSR FLD1R
            0770     JSR FDIV
            0780 END RTS
    Wykorzystywana przez procedurę ATAN tablica TATNC zawiera stałą liczbową o wartości 0.01745329.
            0100 ;Table: ATN's Constant
            0110 ;
            0120     *=  $BEC9
            0130 ;
            0140     .BYTE $3F,$01,$74
            0150     .BYTE $53,$29,$25
    Książka "Mapa pamięci Atari XL/XE. Podstawowe procedury systemu operacyjnego" podaje adres procedury ATAN zawartej w poprzedniej wersji interpretera Atari Basic (Revision B). Uwaga ta dotyczy także pozostałych procedur zmiennoprzecinkowych: SQR, SIN i COS.

5.2.10. Funkcja CHR$

    Funkcja CHR$ zwraca znak, którego kod ASCII został podany jako argument, jej wynikiem jest więc stała tekstowa o długości jednego znaku. Argument pobrany przez procedurę GETVAR jest zamieniany przy pomocy GETINT na dwubajtową liczbę całkowitą, a jej młodszy bajt przepisywany jest do bufora LBUFF (Line BUFFer). Starszy bajt jest przy tym całkowicie pomijany, więc argument większy od 255 ($FF) da w rezultacie znak, którego kod ASCII jest równy reszcie z dzielenia argumentu przez 256. Trzeba jednak pamiętać, że argument większy od 65535 ($FFFF) spowoduje błąd podczas realizacji procedury GETINT.

    Ponieważ wynik jest zapisywany zawsze w to samo miejsce bufora LBUFF, to jednocześnie można wykonać tylko jedną funkcję CHR$. Na przykład, porównanie CHR$(A)=CHR$(B) będzie zawsze prawdziwe, gdyż przed wykonaniem porównania nowa wartość funkcji CHR$ skasuje poprzednią.
            0100 ;eXecute CHR$ function
            0110 ;
            0120 FR0 =   $D4
            0130 GETINT = $AD41
            0140 GETVAR = $ABE9
            0150 LBUFF = $0580
            0160 PUTVAR = $ABB2
            0170 VARN =  $D3
            0180 VART =  $D2
            0190 ;
            0200     *=  $B052
            0210 ;
            0220     JSR GETVAR
            0230     JSR GETINT
            0240     LDA FR0
            0250     STA LBUFF+$40
            0260     LDA # >LBUFF+$40
            0270     STA FR0+1
            0280     LDA # <LBUFF+$40
            0290     STA FR0
            0300     LDA #$01
            0310     STA FR0+2
            0320 ;
            0330 ;STRing TYPe
            0340 ;
            0350 STRTYP LDA #$00
            0360     STA FR0+3
            0370     STA VARN
            0380     LDA #$83
            0390     STA VART
            0400     JMP PUTVAR
    Adres znaku w buforze LBUFF umieszczany jest teraz w dwóch pierwszych bajtach rejestru FR0, a w dwóch następnych wartość 1, która oznacza długość stałej tekstowej. Odpowiednio do rejestru VARN wpisywane jest zero, a do VART - $83, co oznacza stałą tekstową. Procedura XCHR kończy się skokiem do PUTVAR, a więc zapisaniem wyniku do bufora tokenizacji.

5.2.11. Funkcja STR$

    Funkcja STR$ zamienia podany argument liczbowy na ciąg znaków ASCII. Procedura wykonawcza XSTR pobiera liczbę przez GETVAR i przy pomocy procedury FASC zamienia ją na ciąg znaków. Adres bufora zawierającego ten ciąg jest wpisywany do rejestru FR0 (dwa pierwsze bajty). Następnie obliczana jest długość ciągu, a wynik umieszczany jest w trzecim bajcie FR0. Teraz następuje skok do etykiety STRTYP (wewnątrz procedury XCHR), gdzie zapisywany jest numer i typ wartości.

    Ta funkcja może być użyta w wyrażeniu tylko jeden raz, gdyż podobnie jak XCHR, umieszcza wynik zawsze w tym samym miejscu. Ponadto trzeba uważać przy jednoczesnym użyciu funkcji STR$ i CHR$, gdyż obie korzystają z bufora LBUFF. Jeśli ciąg wynikowy funkcji STR$ będzie miał długość większą od 64 znaków, to zajmie miejsce przeznaczone na wynik funkcji CHR$. Ten rezultat, który był wcześniej obliczony, będzie więc niepoprawny.
            0100 ;eXecute STR$ function
            0110 ;
            0120 FASC =  $D8E6
            0130 FR0 =   $D4
            0140 GETVAR = $ABE9
            0150 INBUFP = $F3
            0160 STRTYP = $B069
            0170 ;
            0180     *=  $B034
            0190 ;
            0200     JSR GETVAR
            0210     JSR FASC
            0220     LDA INBUFP
            0230     STA FR0
            0240     LDA INBUFP+1
            0250     STA FR0+1
            0260     LDY #$FF
            0270 LOOP INY
            0280     LDA (INBUFP),Y
            0290     BPL LOOP
            0300     AND #$7F
            0310     STA (INBUFP),Y
            0320     INY
            0330     STY FR0+2
            0340     BNE STRTYP

5.2.12. Funkcja USR

    Funkcja USR powoduje wywołanie procedury w języku maszynowym od adresu podanego jako argument. Ponadto dalsze argumenty - jeśli są - zostają przekazane jako parametry do tej procedury. Do realizacji tej funkcji służy procedura XUSR. Zasadnicza operacja odczytu parametrów i wywołania procedury maszynowej użytkownika jest wykonywana przez PHDAT. Przekazany przez nią wynik jest zamieniany na liczbę zmiennoprzecinkową (przez IFP) i przy pomocy procedury PUTVAR zapisywany w buforze.
            0100 ;eXecute USR function
            0110 ;
            0120 IFP =   $D9AA
            0130 PHDAT = $B0AE
            0140 PUTVAR = $ABB2
            0150 ;
            0160     *=  $B0A5
            0170 ;
            0180     JSR PHDAT
            0190     JSR IFP
            0200     JMP PUTVAR
    Procedura PHDAT rozpoczyna się od odczytania z rejestru BHLD1 liczby parametrów funkcji USR i umieszczenia jej w liczniku ACNT1 (Auxiliary CouNTer 1). Następnie w pętli sterowanej stanem tego licznika wywoływana jest procedura GETNUM, która odczytuje kolejne parametry. Są one odkładane na stosie w kolejności bajtów młodszy/starszy. Na końcu wpisywana jest na stos liczba parametrów, natomiast ostatnia odczytana liczba pozostaje w rejestrze FR0. Liczba ta jest wykorzystywana jako adres skoku kończącego procedurę PHDAT.
            0100 ;PusH user's DATa
            0110 ;
            0120 ACNT1 = $C6
            0130 BHLD1 = $B0
            0140 FR0 =   $D4
            0150 GETNUM = $ABDA
            0160 ;
            0170     *=  $B0AE
            0180 ;
            0190     LDA BHLD1
            0200     STA ACNT1
            0210 LOOP JSR GETNUM
            0220     DEC ACNT1
            0230     BMI EXIT
            0240     LDA FR0
            0250     PHA
            0260     LDA FR0+1
            0270     PHA
            0280     JMP LOOP
            0290 EXIT LDA BHLD1
            0300     PHA
            0310     JMP (FR0)
    Wspomniana procedura GETNUM jest częścią składową LETNUM. Przez wywołanie XLET wartość wyrażenia jest obliczana i umieszczana w buforze. Teraz (od etykiety GETNUM) z bufora pobierana jest liczba zmiennoprzecinkowa, którą procedura GETINT zamienia na dwubajtową liczbę całkowitą.
            0100 GETINT = $AD41
            0110 GETVAR = $ABE9
            0120 XLET =  $AADA
            0130 ;
            0140     *=  $ABD7
            0150 ;
            0160 ;LET NUMber
            0170 ;
            0180 LETNUM JSR XLET
            0190 ;
            0200 ;GET NUMber
            0210 ;
            0220 GETNUM JSR GETVAR
            0230     JMP GETINT

5.2.13. Funkcja LEN

    Funkcja LEN zwraca wartość długości ciągu podanego jako argument. Wykonująca tą operację procedura XLEN najpierw odczytuje przy pomocy procedury FTARV wartość z bufora tokenizacji i umieszcza ją w rejestrze FR0. Procedura FTARV jest wywoływana zamiast bezpośredniego wywołania GETVAR, ponieważ sprawdza ponadto poprawność argumentu. Następnie wartość określająca aktualną długość ciągu jest przepisywana z trzeciego i czwartego bajtu rejestru FR0 do jego dwóch pierwszych bajtów. Przepisanie zawartości akumulatora i rejestru Y do FR0 zostało oznaczone etykietą STNUM i jest wykorzystywane także przez inne procedury.
            0100 ;eXecute LEN function
            0110 ;
            0120 FR0 =   $D4
            0130 FTARV = $AB90
            0140 IFP =   $D9AA
            0150 PUTVAR = $ABB2
            0160 VARN =  $D3
            0170 VART =  $D2
            0180 ;
            0190     *=  $AFB5
            0200 ;
            0210 XLEN JSR FTARV
            0220     LDA FR0+2
            0230     LDY FR0+3
            0240 ;
            0250 ;STore NUMber
            0260 ;
            0270 STNUM STA FR0
            0280     STY FR0+1
            0290 ;
            0300 ;CHange TYPe
            0310 ;
            0320 CHTYP JSR IFP
            0330 ;
            0340 ;NUMber TYPe
            0350 ;
            0360 NUMTYP LDA #$00
            0370     STA VART
            0380     STA VARN
            0390     JMP PUTVAR
    Teraz liczba całkowita jest zamieniana na zmienno- przecinkową (jest to oznaczone przez CHTYP). Po wpisaniu do rejestrów VART i VARN wartości oznaczających stałą liczbową procedura XLEN kończy się skokiem do PUTVAR, gdzie wynik przepisywany jest do bufora.

    W celu odczytania adresu ciągu będącego argumentem procedura FTARV najpierw wywołuje GETVAR. Jeśli zawartość rejestru VART oznacza stałą tekstową, to procedura FTARV się kończy. Skasowany bit 0 tego rejestru sygnalizuje natomiast, że zmienna nie była zadeklarowana i powoduje skok do procedury błędu DIMER (DIMension ERror).
0100 ;Find Table or ARray Value 0110 ; 0120 DIMER = $B922 0130 FR0 = $D4 0140 GETVAR = $ABE9 0150 STARP = $8C 0160 VART = $D2 0170 ; 0180 *= $AB90 0190 ; 0200 JSR GETVAR 0210 LDA #$02 0220 BIT VART 0230 BNE END 0240 ORA VART 0250 STA VART 0260 ROR A 0270 BCC ERR 0280 CLC 0290 LDA FR0 0300 ADC STARP 0310 STA FR0 0320 TAY 0330 LDA FR0+1 0340 ADC STARP+1 0350 STA FR0+1 0360 END RTS 0370 ERR JSR DIMER     Gdy zmienna jest poprawna, to przez dodanie zawartości STARP i FR0 obliczany jest jej adres w pamięci. Ta część procedury jest zbędna przy wykonywaniu funkcji XLEN, a wykorzystuje ją tylko funkcja XADR (zob. niżej).

5.2.14. Funkcja FRE

    Funkcja FRE zwraca wartość określającą wielkość pozostałej jeszcze, wolnej pamięci RAM. Procedura wykonawcza tej funkcji - XFRE - rozpoczyna się od wywołania GETVAR w celu odczytania z bufora argumentu, który nie ma jednak żadnego znaczenia. Właściwe obliczenie polega na odjęciu zawartości rejestrów MEMTOP (MEMory TOP) i BMEMHI (Basic MEMory HIgh address). Uzyskany rezultat określa liczbę bajtów pomiędzy górną granicą obszaru pamięci zajmowanego przez program w Basicu i dolną granicą programu ANTIC-a. Doprowadzenie wyniku odejmowania, który jest dwubajtową liczbą całkowitą do poprawnej postaci, jest osiągane przez skok do procedury CHTYP (wewnątrz XLEN).
            0100 ;eXecute FRE function
            0110 ;
            0120 BMEMHI = $90
            0130 CHTYP = $AFC0
            0140 FR0 =   $D4
            0150 GETVAR = $ABE9
            0160 MEMTOP = $02E5
            0170 ;
            0180     *=  $AFD6
            0190 ;
            0200     JSR GETVAR
            0210     SEC
            0220     LDA MEMTOP
            0230     SBC BMEMHI
            0240     STA FR0
            0250     LDA MEMTOP8+1
            0260     SBC BMEMHI+1
            0270     STA FR0+1
            0280     JMP CHTYP
    Przy wykorzystywaniu wyniku funkcji FRE do określenia, czy pozostaje wystarczający obszar pamięci na umieszczenie dodatkowych danych lub procedur w języku maszynowym, trzeba pamiętać, że górna granica programu Basica jest ruchoma. Każde otwarcie pętli FOR/NEXT zajmuje 16 bajtów, a każde wywołanie procedury GOSUB/RETURN - cztery bajty. Dostępny obszar pamięci należy więc zmniejszyć o liczbę ustaloną w zależności od maksymalnej liczby jednocześnie aktywnych pętli i procedur.

5.2.15. Funkcja PEEK

    Funkcja PEEK zwraca wartość zapisaną w komórce pamięci, której adres został podany jako argument. W tym celu procedura GETNUM odczytuje ze stosu argument i zamienia go na liczbę całkowitą. Liczba ta jest następnie wykorzystywana jako adres odczytu zawartości komórki pamięci. Doprowadzenie wyniku do postaci zmiennoprzecinkowej i zapisanie w buforze jest dokonywane przez procedurę STNUM wchodzącą w skład XLEN (zob. wyżej).
            0100 ;eXecute PEEK function
            0110 ;
            0120 FR0 =   $D4
            0130 GETNUM = $ABDA
            0140 STNUM = $AFBC
            0150 ;
            0160     *=  $AFCC
            0170 ;
            0180     JSR GETNUM
            0190     LDY #$00
            0200     LDA (FR0),Y
            0210     JMP STNUM

5.2.16. Funkcja ADR

    Funkcja ADR zwraca wartość określającą adres pierwszego znaku ciągu podanego jako argument. Procedura realizująca tą operację zawiera jedynie wywołanie FTARV i skok do CHTYP. Opisywana już wcześniej (zob. 5.2.13) procedura FTARV umieszcza w dwóch pierwszych bajtach rejestru FR0 adres podanego ciągu. Adres ten jest przekształcany do postaci stałej liczbowej w procedurze CHTYP, która znajduje się wewnątrz XLEN.
            0100 ;eXecute ADR function
            0110 ;
            0120 CHTYP = $AFC0
            0130 FTARV = $AB90
            0140 ;
            0150     *=  $B007
            0160 ;
            0170     JSR FTARV
            0180     JMP CHTYP

5.2.17. Funkcja ASC

    Funkcja ASC zwraca wartość kodu ATASCII pierwszego znaku ciągu podanego jako argument, jest więc odwrotnością funkcji CHR$. Jej procedura wykonawcza XASC przebiega podobnie do procedury XADR. Jednak do CHTYP jest przekazywany nie adres, lecz odczytany według tego adresu kod pierwszego znaku ciągu.
            0100 ;eXecute ASC function
            0110 ;
            0120 FR0 =   $D4
            0130 FTARV = $AB90
            0140 STNUM = $AFBC
            0150 ;
            0160     *=  $AFFD
            0170 ;
            0180     JSR FTARV
            0190     LDY #$00
            0200     LDA (FR0),Y
            0210     JMP STNUM

5.2.18. Funkcja VAL

    Funkcja VAL zwraca wartość uzyskaną z zamiany na liczbę cyfr ciągu ASCII podanego jako argument i jest funkcją odwrotną dla STR$. Realizuje ją procedura XVAL, która najpierw odczytuje informacje o ciągu przy pomocy GFILSP, a następnie zamienia odnaleziony ciąg na liczbę zmiennoprzecinkową przez wywołanie procedury AFP z pakietu FP. Wywołanie procedury PSTMAD jest tu konieczne tylko dla skasowania znacznika MEOLFLG (Modified EOL FLaG) ustawionego przez procedurę GFILSP. Poprawny wynik otrzymuje odpowiedni format i jest zapisywany na stosie przez skok do procedury NUMTYP, która znajduje się wewnątrz XLEN. Jeśli podany ciąg nie daje się zamienić na liczbę, to wykonywany jest skok do CHARER i sygnalizowany jest błąd (CHARacter ERror).
            0100 ;eXecute VAL function
            0110 ;
            0120 AFP =   $D800
            0130 CHARER = $B910
            0140 CIX =   $F2
            0150 GFILSP = $BD7D
            0160 NUMTYP = $AFC3
            0170 PSTMAD = $BD9D
            0180 ;
            0190     *=  $AFEB
            0200 ;
            0210     JSR GFILSP
            0220     LDA #$00
            0230     STA CIX
            0240     JSR AFP
            0250     JSR PSTMAD
            0260     BCC NUMTYP
            0270     JSR CHARER
    Procedura GFILSP najpierw odszukuje podany ciąg przy pomocy FTARV, a następnie wpisuje jego adres do wektora INBUFP. Ponadto do rejestru CSTAD przepisywany jest starszy bajt adresu ciągu i młodszy bajt jego długości. Przed opuszczeniem procedury znak końca wiersza (RETURN) jest jeszcze umieszczany na końcu ciągu, a jeśli jego długość jest większa od 256 bajtów, to jako 256 znak.
            0100 ;Get FILe SPecification
            0110 ;
            0120 CSTAD = $97
            0130 FR0 =   $D4
            0140 FTARV = $AB90
            0150 INBUFP = $F3
            0160 MEOLFLG = $92
            0170 ;
            0180     *=  $BD7D
            0190 ;
            0200     JSR FTARV
            0210     LDA FR0
            0220     STA INBUFP
            0230     LDA FR0+1
            0240     STA INBUFP+1
            0250     LDY FR0+2
            0260     LDX FR0+3
            0270     BEQ PUT
            0280     LDY #$FF
            0290 PUT LDA (INBUFP),Y
            0300     STA CSTAD
            0310     STY CSTAD+1
            0320     LDA #$9B
            0330     STA (INBUFP),Y
            0340     STA MEOLFLG
            0350     RTS

5.2.19. Funkcje manipulatorów

    Atari Basic posiada cztery dodatkowe funkcje, które służą do odczytu położenia manipulatorów. Funkcja STICK zwraca liczbę określającą pozycję joysticka, a STRIG - stan jego przycisku. Podobnie wynik funkcji PADDLE określa stan potencjometru, a PTRIG - jego przycisku. Argumentem tych funkcji jest numer manipulatora: 0 lub 1 dla joysticka oraz liczba od 0 do 3 dla potencjometru. Działanie wszystkich tych funkcji polega na odczycie zawartości odpowiedniego rejestru. Rejestr jest wybierany przez zsumowanie jego numeru i odległości od rejestru pierwszego manipulatora (PADDLE0). Przekształcenia i zapisania wyniku dokonuje procedura STNUM.
            0100 BVALER = $B92E
            0110 FR0 =   $D4
            0120 GETNUM = $ABDA
            0130 PADDL0 = $0270
            0140 STNUM = $AFBC
            0150 ;
            0160     *=  $B00D
            0170 ;
            0180 ;eXecute PADDLE function
            0190 ;
            0200 XPADDL LDA #$00
            0210     BEQ GET
            0220 ;
            0230 ;eXecute STICK function
            0240 ;
            0250 XSTICK LDA #$08
            0260     BNE GET
            0270 ;
            0280 ;eXecute PTRIG function
            0290 ;
            0300 XPTRIG LDA #$0C
            0310     BNE GET
            0320 ;
            0330 ;eXecute STRIG function
            0340 ;
            0350 XSTRIG LDA #$14
            0360 GET PHA
            0370     JSR GETNUM
            0380     LDA FR0+1
            0390     BNE ERR
            0400     LDA FR0
            0410     PLA
            0420     CLC
            0430     ADC FR0
            0440     TAX
            0450     LDA PADDL0,X
            0460     LDY #$00
            0470     BEQ STNUM
            0480 ERR JSR BVALER

5.3. Inne operatory

    Poza opisanymi wyżej operatorami i funkcjami Atari Basic posiada jeszcze dodatkowe operatory. Umożliwiają one wykonanie porównań, operacji logicznych, zmianę priorytetu działań itd. W wielu przypadkach operatory te są oznaczane jednakowymi symbolami, na co była już wcześniej zwracana uwaga.

5.3.1. Operatory relacji i logiczne

    Operatory logiczne i operatory relacji zwracają wartości PRAWDA lub FAŁSZ. W Atari Basic wartości logicznej FAŁSZ odpowiada wartość liczbowa zero, zaś wartości PRAWDA - jeden. Interpreter Basica zawiera następujące operatory relacji: mniejsze lub równe (<=), większe lub równe (>=), mniejsze (<), większe (>), różne (<>) i równe (=). Operatorami logicznymi są zaś AND (iloczyn logiczny), OR (alternatywa) i NOT (negacja). Wszystkie procedury wykonawcze tych operatorów są ze sobą ściśle powiązane, ponadto dołączona jest do nich procedura XSGN realizująca funkcję SGN.
            0100 ;Execute compare operators
            0110 ;
            0120 AF1 =   $DA48
            0130 CMPVAR = $AD11
            0140 FR0 =   $D4
            0150 FR1 =   $E0
            0160 GETVAR = $ABE9
            0170 GETVRS = $ABFD
            0180 PUTVAR = $ABB2
            0190 VART =  $D2
            0200 ;
            0210     *=  $ACA3
            0220 ;
            0230 ;eXecute Less or EQual
            0240 ;
            0250 XLEQ JSR CMPVAR
            0260     BMI ONEP
            0270     BEQ ONEP
            0280     BPL ZERO
            0290 ;
            0300 ;eXecute Not EQual
            0310 ;
            0320 XNEQ JSR CMPVAR
            0330     JMP RESLTZ
            0340 ;
            0350 ;eXecute LESs than
            0360 ;
            0370 XLES JSR CMPVAR
            0380     BMI ONEP
            0390     BPL ZERO
            0400 ;
            0410 ;eXecute GReaTer than
            0420 ;
            0430 XGRT JSR CMPVAR
            0440     BMI ZERO
            0450     BEQ ZERO
            0460     BPL ONEP
            0470 ;
            0480 ;eXecute Greater or EQual
            0490 ;
            0500 XGEQ JSR CMPVAR
            0510     BMI ZERO
            0520     BPL ONEP
            0530 ;
            0540 ;eXecute EQUal
            0550 ;
            0560 XEQU JSR CMPVAR
            0570     JMP RESLTO
            0580 ;
            0590 ;eXecute AND operator
            0600 ;
            0610 XAND JSR GETVRS
            0620     LDA FR0
            0630     AND FR1
            0640     JMP RESLTZ
            0650 ;
            0660 ;eXecute OR operator
            0670 ;
            0680 XOR JSR GETVRS
            0690     LDA FR0
            0700     ORA FR1
            0710 ;
            0720 ;RESuLT Zero
            0730 ;
            0740 RESLTZ BEQ ZERO
            0750     BNE ONEP
            0760 ;
            0770 ;eXecute NOT operator
            0780 ;
            0790 XNOT JSR GETVAR
            0800     LDA FR0
            0810 ;
            0820 ;RESuLT One
            0830 ;
            0840 RESLTO BEQ ONEP
            0850 ;
            0860 ;result ZERO
            0870 ;
            0880 ZERO LDA #$00
            0890     TAY
            0900     BEQ STRES
            0910 ;
            0920 ;result ONE Positive
            0930 ;
            0940 ONEP LDA #$40
            0950 ;
            0960 ;result ONE Negative
            0970 ;
            0980 ONEN LDY #$01
            0990 ;
            1000 ;STore RESult
            1010 ;
            1020 STRES STA FR0
            1030     STY FR0+1
            1040     LDX #FR0+2
            1050     LDY #$04
            1060     JSR AF1
            1070     STA VART
            1080 END JMP PUTVAR
            1090 ;
            1100 ;eXecute SGN function
            1110 ;
            1120 XSGN JSR GETVAR
            1130     LDA FR0
            1140     BEQ END
            1150     BPL ONEP
            1160     LDA #$C0
            1170     BMI ONEN
    Określenie relacji między dwoma argumantami rozpoczyna się zawsze od wywołania procedury CMPVAR, która dokonuje porównania odpowiednich wartości, a wynik sygnalizuje w odpowiednich bitach statusu procesora. Zależnie od rodzaju porównania i stanu bitów Negative i Zero wykonywane są skoki do właściwych fragmentów procedury, gdzie ustalane są wartości dwóch pierwszych bajtów wyniku. Pozostałe bajty rejestru FR0 są zerowane przez procedurę AF1 i rezultat przepisywany jest do bufora przez procedurę PUTVAR.

    Nieco inaczej przebiega obliczenie wyniku operacji logicznych. Procedury GETVRS (dla AND i OR) lub GETVAR (dla NOT) pobierają z bufora argumenty, na których pierwszym bajcie wykonywana jest odpowiednia operacja logiczna. Oznacza to, że operacje logiczne Atari Basic rozróżniają tylko dwa stany: zero i niezero. Opracowanie wyniku i jego zapisanie są analogiczne jak dla operatorów relacji.

    W opisywanym zespole procedur znajduje się również procedura XSGN, realizująca funkcję SGN, która zwraca znak podanego argumentu. W zależności od wartości najstarszego bitu liczby pobranej przez GETVAR następuje skok do odpowiedniej etykiety i zapisanie wyniku: 0, 1 lub -1.

    Samo porównanie wartości jest przeprowadzane przez procedurę CMPVAR. Najpierw odczytuje ona token operatora. Jeśli jest to token operacji na wartościach tekstowych, to wykonywany jest skok do procedury CMPSTR. W przeciwnym przypadku porównywane liczby są odczytywane z bufora i, przez wywołanie BSUB, odejmowane od siebie. Znak wyniku tego działania jest umieszczany w akumulatorze i procedura się kończy.
            0100 ;CoMPare VARiables
            0110 ;
            0120 BSUB =  $AD2C
            0130 CMPSTR = $AF6C
            0140 FR0 =   $D4
            0150 GETVRS = $ABFD
            0160 LOMEM = $80
            0170 STIX =  $A9
            0180 ;
            0190     *=  $AD11
            0200 ;
            0210     LDY STIX
            0220     DEY
            0230     LDA (LOMEM),Y
            0240     CMP #'/
            0250     BCC NUM
            0260     JMP CMPSTR
            0270 NUM JSR GETVRS
            0280 ;
            0290 ;GET SUBtract
            0300 ;
            0310 GETSUB JSR BSUB
            0320     LDA FR0
            0330     RTS
    W przypadku porównania ciągów tekstowych, najpierw - przez dwukrotne wywołanie procedury FTARV - odczytywane są informacje o nich. Następnie rozpoczyna się pętla, w której kolejno porównywany jest znak po znaku. Jeśli znaki są równe, to adresy kontrolowanych znaków są zwiększane i pętla się powtarza. Gdy znaki są różne, to wynik porównania jest zapisywany do akumulatora (jak w przypadku porównania liczb) i procedura się kończy. Pętla jest także przerywana, gdy wszystkie znaki są jednakowe, a został osiągnięty koniec jednego lub obu ciągów. Jeśli obu, to sygnalizowana jest ich równość. W przeciwnym przypadku ciąg dłuższy zostaje uznany za większy. Licznikiem jest tu długość ciągu zapisana w trzecim i czwartym bajcie rejestrów FR0 i FR1.
            0100 ;CoMPare STRings
            0110 ;
            0120 FMOV01 = $DDB6
            0130 FR0 =   $D4
            0140 FR1 =   $E0
            0150 FTARV = $AB90
            0160 ;
            0170     *=  $AF6C
            0180 ;
            0190 CMPSTR JSR FTARV
            0200     JSR FMOV01
            0210     JSR FTARV
            0220 LOOP LDX #FR0+2
            0230     JSR DECREG
            0240     PHP
            0250     LDX #FR1+2
            0260     JSR DECREG
            0270     BEQ CST
            0280     PLP
            0290     BEQ MNS
            0300     LDY #$00
            0310     LDA (FR0),Y
            0320     CMP (FR1),Y
            0330     BEQ IF0
            0340     BCC MNS
            0350 PLS LDA #$01
            0360     RTS
            0370 MNS LDA #$80
            0380     RTS
            0390 CST PLP
            0400     BNE PLS
            0410     RTS
            0420 IF0 INC FR0
            0430     BNE IF1
            0440     INC FR0+1
            0450 IF1 INC FR1
            0460     BNE LOOP
            0470     INC FR1+1
            0480     BNE LOOP
            0490 ;
            0500 ;DECrease REGister
            0510 ;
            0520 DECREG LDA $00,X
            0530     BNE SKIP
            0540     LDA $01,X
            0550     BEQ END
            0560     DEC $01,X
            0570 SKIP DEC $00,X
            0580     TAY
            0590 END RTS

5.3.2. Operatory przypisania

    W interpreterze Atari Basic występują dwa operatory przypisania (oba oznaczone znakiem "="): przypisanie liczbowe i przypisanie tekstowe. Służą one odpowiednio do nadania wartości zmiennym liczbowym i tekstowym. Pomimo jednakowego symbolu mają one inne tokeny i są realizowane przez inne procedury.

    Procedurą wykonawczą przypisania liczbowego jest XNLET. Przypisanie liczby musi być ostatnią operacją w obliczaniu wyrażenia. Dlatego najpierw sprawdzana jest wartość licznika STIX. Jeśli jest ona różna od $FF, to oznacza zmienną indeksowaną i konieczność obliczenia indeksów. W takim razie rejestr BHLD2 otrzymuje wartość $80 i procedura jest przerywana. W przeciwnym przypadku obie wartości są pobierane z bufora przez GETVRS, a następnie obliczona wartość liczby jest przepisywana do rejestru zmiennej liczbowej. Teraz XNLET kończy się skokiem do procedury SAVVAL.
            0100 ;eXecute Number LET mark
            0110 ;
            0120 BHLD2 = $B1
            0130 FR0 =   $D4
            0140 FR1 =   $E0
            0150 GETVRS = $ABFD
            0160 SAVVAL = $AC0C
            0170 STIX =  $A9
            0180 ;
            0190     *=  $AD4A
            0200 ;
            0210     LDA STIX
            0220     CMP #$FF
            0230     BNE EXIT
            0240     JSR GETVRS
            0250     LDX #$05
            0260 LOOP LDA FR1,X
            0270     STA FR0,X
            0280     DEX
            0290     BPL LOOP
            0300     JMP SAVVAL
            0310 EXIT LDA #$80
            0320     STA BHLD2
            0330     RTS
    W tej procedurze według numeru zmiennej z rejestru VARN obliczany jest jej adres w tablicy wartości zmiennych (przez wywołanie CALPC). Cała zmienna (rejestry VARN, VART i FR0 - razem osiem bajtów) jest przepisywana w pętli do obliczonego miejsca i procedura się kończy.
            0100 ;SAVe VALue
            0110 ;
            0120 CALPC = $AC1E
            0130 PCNTC = $9D
            0140 VARN =  $D3
            0150 VART =  $D2
            0160 ;
            0170     *=  $AC0C
            0180 ;
            0190     LDA VARN
            0200     JSR CALPC
            0210     LDX #$00
            0220 LOOP LDA VART,X
            0230     STA (PCNTC),Y
            0240     INY
            0250     INX
            0260     CPX #$08
            0270     BCC LOOP
            0280     RTS
    Znacznie bardziej skomplikowana jest procedura XSLET realizująca operację przypisania tekstowego. Najpierw wywoływana jest procedura FTARV i odczytany przez nią adres ciągu jest umieszczany w rejestrze OLDMHI, a jego długość w rejestrze MRANGE. Jeśli jest to ostatni operator wyrażenia, to przez ponowne wywołanie FTARV odczytywana jest maksymalna długość ciągu. Jeśli nie, to wywołanie procedury PRCOP powoduje obliczenie początkowego adresu przypisania. Przekroczenie zadeklarowanej długości nie powoduje błędu, a nadmiar znaków jest po prostu pomijany. Następnie obliczany jest adres w tablicy STARP, pod którym powinny znaleźć się znaki ciągu, i odpowiedni obszar pamięci jest przepisywany przez procedurę MOVMEM. Jeżeli wszystkie czynności przebiegły poprawnie, to po zapisaniu nowej długości ciągu wykonywany jest skok do procedury SAVVAL. Próba przypisania wartości niezadeklarowanej zmiennej tekstowej powoduje natomiast ustawienie bitu Carry przed końcem procedury.
            0100 ;eXecute String LET mark
            0110 ;
            0120 BHLD2 = $B1
            0130 FR0 =   $D4
            0140 FTARV = $AB90
            0150 MOVMEM = $A944
            0160 MRANGE = $A2
            0170 NEWMHI = $9B
            0180 OLDMHI = $99
            0190 PRCOP = $AB04
            0200 SAVVAL = $AC0C
            0210 STARP = $8C
            0220 STIX =  $A9
            0230 VARBL = $AB81
            0240 VARN =  $D3
            0250 ZTEMP3 = $F9
            0260 ;
            0270     *=  $AE8E
            0280 ;
            0290     JSR FTARV
            0300     LDA FR0
            0310     STA OLDMHI
            0320     LDA FR0+1
            0330     STA OLDMHI+1
            0340     LDA FR0+2
            0350     STA MRANGE
            0360     LDY FR0+3
            0370     STY MRANGE+1
            0380     LDY STIX
            0390     CPY #$FF
            0400     BEQ MAX
            0410     LDA #$80
            0420     STA BHLD2
            0430     JSR PRCOP
            0440     LDA FR0+3
            0450     LDY FR0+2
            0460     ROL BHLD2
            0470     BCS BPS
            0480 MAX JSR FTARV
            0490     LDA FR0+5
            0500     LDY FR0+4
            0510 BPS CMP MRANGE+1
            0520     BCC STR
            0530     BNE ADD
            0540     CPY MRANGE
            0550     BCS ADD
            0560 STR STA MRANGE+1
            0570     STY MRANGE
            0580 ADD CLC
            0590     LDA FR0
            0600     ADC MRANGE
            0610     TAY
            0620     LDA FR0+1
            0630     ADC MRANGE+1
            0640     TAX
            0650     SEC
            0660     TYA
            0670     SBC STARP
            0680     STA ZTEMP3
            0690     TXA
            0700     SBC STARP+1
            0710     STA ZTEMP3+1
            0720     SEC
            0730     LDA #$00
            0740     SBC MRANGE
            0750     STA MRANGE
            0760     SEC
            0770     LDA OLDMHI
            0780     SBC MRANGE
            0790     STA OLDMHI
            0800     LDA OLDMHI+1
            0810     SBC $00
            0820     STA OLDMHI+1
            0830     SEC
            0840     LDA FR0
            0850     SBC MRANGE
            0860     STA NEWMHI
            0870     LDA FR0+1
            0880     SBC #$00
            0890     STA NEWMHI+1
            0900     JSR MOVMEM
            0910     LDA VARN
            0920     JSR VARBL
            0930     SEC
            0940     LDA ZTEMP3
            0950     SBC FR0
            0960     TAY
            0970     LDA ZTEMP3+1
            0980     SBC FR0+1
            0990     TAX
            1000     LDA #$02
            1010     AND BHLD2
            1020     BEQ SAVE
            1030     LDA #$00
            1040     STA BHLD2
            1050     CPX FR0+3
            1060     BCC EXIT
            1070     BNE SAVE
            1080     CPY FR0+2
            1090     BCS SAVE
            1100 EXIT RTS
            1110 SAVE STY FR0+2
            1120     STX FR0+3
            1130     JMP SAVVAL

5.3.3. Operatory nawiasów

    Ważną rolę w wyrażeniach pełnią nawiasy. Służą one do wydzielenia indeksów w instrukcjach deklaracji zmiennych tablicowych (indeksowych i tekstowych) oraz przypisania wartości tym zmiennym. Także w tym przypadku jednakowym oznaczeniom odpowiadają różne tokeny i procedury wykonawcze.

    Napotkanie tokena oznaczającego nawias zmiennej indeksowanej powoduje wywołanie procedury XPIXV. Niemal identyczny jest w początkowym fragmencie przebieg procedury wywoływanej po rozpoznaniu tokena nawiasu w instrukcji deklarującej zmienną tablicową - XPDIM.

    W przypadku deklaracji na początku procedury XPDIM w rejestrze BHLD2 umieszczana jest wartość $40, która służy później do rozpoznania rodzaju nawiasu. Następnie z bufora pobierane są przy pomocy GETNUM liczby określające wymiar lub indeks zmiennej. Jeśli przy tym zawartość rejestru BHLD1 jest różna od zera, to są to dwie liczby, a gdy jest równa zero, to tylko jedna. Do rejestru CSTAD wpisywany jest pierwszy wymiar (jeśli istnieje) lub zero. Drugi wymiar przepisywany jest zawsze do rejestru ZTEMP1. Przekroczenie przez jeden z wymiarów wartości $7FFF powoduje sygnalizację błędu przez skok do procedury DIMER (DIMension ERror). Następnie odczytywana jest nazwa zmiennej (przez wywołanie GETVAR). Teraz możliwe są trzy sytuacje. Jeżeli jest to deklaracja, to procedura się kończy przez RTS. Jeżeli jest to nawias indeksu zmiennej, która nie była przedtem deklarowana (skasowany bit 0 rejestru VART), to sygnalizowany jest błąd. Dalsze kontynuowanie procedury następuje jedynie w przypadku nawiasu zmiennej indeksowanej, która została wcześniej deklarowana.
            0100 AUXBR = $AF
            0110 BHLD1 = $B0
            0120 BHLD2 = $B1
            0130 CSTAD = $97
            0140 DIMER = $B922
            0150 EVZTMP = $AF48
            0160 FR0 =   $D4
            0170 GETNUM = $ABDA
            0180 GETVAR = $ABE9
            0190 PUTVAR = $ABB2
            0200 STARP = $8C
            0210 STPTR = $AA
            0220 VART =  $D2
            0230 ZT1ADD = $AF3D
            0240 ZT1ML6 = $AF31
            0250 ZTEMP1 = $F5
            0260 ;
            0270     *=  $AD6D
            0280 ;
            0290 ;eXecute Parenthese of DIMension
            0300 ;
            0310 XPDIM LDA #$40
            0320     STA BHLD2
            0330 ;
            0340 ;eXecute Parenthese of IndeX Variable
            0350 ;
            0360 XPIXV BIT BHLD2
            0370     BPL GET1
            0380     LDA STPTR
            0390     STA AUXBR
            0400     DEC STPTR
            0410 GET1 LDA #$00
            0420     TAY
            0430     CMP BHLD1
            0440     BEQ GET2
            0450     DEC BHLD1
            0460     JSR GETNUM
            0470     LDA FR0+1
            0480     BMI ERR
            0490     LDY FR0
            0500 GET2 STA CSTAD+1
            0510     STY CSTAD
            0520     JSR GETNUM
            0530     LDA FR0
            0540     STA ZTEMP1
            0550     LDA FR0+1
            0560     BMI ERR
            0570     STA ZTEMP1+1
            0580     JSR GETVAR
            0590     BIT BHLD2
            0600     BVC CVT
            0610     LDA #$00
            0620     STA BHLD2
            0630     RTS
            0640 CVT ROR VART
            0650     BCS FDIM
            0660 ERR JSR DIMER
            0670 FDIM LDA ZTEMP1+1
            0680     CMP FR0+3
            0690     BCC SDIM
            0700     BNE ERR
            0710     LDA ZTEMP1
            0720     CMP FR0+2
            0730     BCS ERR
            0740 SDIM LDA CSTAD+1
            0750     CMP FR0+5
            0760     BCC MEM
            0770     BNE ERR
            0780     LDA CSTAD
            0790     CMP FR0+4
            0800     BCS ERR
            0810 MEM JSR EVZTMP
            0820     LDA CSTAD
            0830     LDY CSTAD+1
            0840     JSR ZT1ADD
            0850     JSR ZT1ML6
            0860     LDA FR0
            0870     LDY FR0+1
            0880     JSR ZT1ADD
            0890     LDA STARP
            0900     LDY STARP+1
            0910     JSR ZT1ADD
            0920     BIT BHLD2
            0930     BPL SAV
            0940     LDA AUXBR
            0950     STA STPTR
            0960     JSR GETVAR
            0970     LDY #$05
            0980 NXT1 LDA FR0,Y
            0990     STA (ZTEMP1),Y
            1000     DEY
            1010     BPL NXT1
            1020     INY
            1030     STY BHLD2
            1040     RTS
            1050 SAV LDY #$05
            1060 NXT2 LDA (ZTEMP1),Y
            1070     STA FR0,Y
            1080     DEY
            1090     BPL NXT2
            1100     INY
            1110     STY VART
            1120     JMP PUTVAR
    Odczytanie odpowiedniej wartości zmiennej indeksowanej rozpoczyna się od porównania podanych wymiarów z wymiarami zadeklarowanymi. Przekroczenie tych ostatnich powoduje także skok do DIMER. Jeśli dotąd wszystko przebiegło poprawnie, to wywoływana jest procedura EVZTMP, która przelicza zawartość rejestru ZTEMP1, aby umożliwić odszukanie w pamięci właściwego elementu.
            0100 ;EValuate ZTEMP registers
            0110 ;
            0120 FRE =   $DA
            0130 ZTEMP1 = $F5
            0140 ZTEMP2 = $F7
            0150 ZTEMP3 = $F9
            0160 ;
            0170     *=  $AF48
            0180 ;
            0190     LDA #$00
            0200     STA ZTEMP2
            0210     STA ZTEMP2+1
            0220     LDY #$10
            0230 LOOP LDA ZTEMP1
            0240     LSR A
            0250     BCC SKIP
            0260     CLC
            0270     LDX #$FE
            0280 NXT1 LDA ZTEMP3,X
            0290     ADC FRE,X
            0300     STA ZTEMP3,X
            0310     INX
            0320     BNE NXT1
            0330 SKIP LDX #$03
            0340 NXT2 ROR ZTEMP1,X
            0350     DEX
            0360     BPL NXT2
            0370     DEY
            0380     BNE LOOP
            0390     RTS
    Następnie, przez kolejne wywołania procedur ZT1ML6 i ZT1ADD z różnymi parametrami w akumulatorze i rejestrze Y, adres elementu zmiennej jest obliczany jako suma adresu w tablicy wartości tej zmiennej, indeksu tablicy od początku tablicy STARP oraz adresu początkowego STARP.
            0100 ZTEMP1 = $F5
            0110 ;
            0120     *=  $AF31
            0130 ;
            0140 ;ZTEMP1 MuLtiple by 6
            0150 ;
            0160 ZT1ML6 ASL ZTEMP1
            0170     ROL ZTEMP1+1
            0180     LDY ZTEMP1+1
            0190     LDA ZTEMP1
            0200     ASL ZTEMP1
            0210     ROL ZTEMP1+1
            0220 ;
            0230 ;ZTEMP1 ADDition
            0240 ;
            0250 ZT1ADD CLC
            0260     ADC ZTEMP1
            0270     STA ZTEMP1
            0280     TYA
            0290     ADC ZTEMP1+1
            0300     STA ZTEMP1+1
            0310     RTS
    Gdy element został już odszukany, to dalsze czynności zależą od zawartości rejestru BHLD2. Wartość ujemna oznacza zapis elementu, a dodatnia jego odczyt. W pierwszym przypadku liczba z rejestru FR0 jest przepisywana pod wskazany adres i procedura kończy się przez RTS. Podobnie w drugim przypadku liczba przepisywana jest z odnalezionego miejsca do rejestru FR0, lecz na końcu następuje skok do procedury PUTVAR, która zapisuje uzyskany wynik do bufora.

    Token nawiasu wyrażenia tekstowego powoduje wywołanie procedury XPSEX. Znaczna jej część jest przeznaczona na sprawdzenie zgodności wymiarów użytych ciągów tekstowych. Sposób porównania jest przy tym regulowany przez rejestry BHLD1 i BHLD2. Pierwszy z nich zawiera liczbę wartości użytych do określenia fragmentu ciągu, a drugi rodzaj operacji - zapis czy odczyt (jak w XPIXV). Przy zapisie podana długość ciągu jest porównywana z zadeklarowaną (piąty i szósty bajt rejestru FR0), a przy odczycie - z długością aktualną (trzeci i czwarty bajt FR0). Jeśli długość ciągu okaże się niepoprawna, to błąd jest sygnalizowany przez procedurę SLENER (String LENgth ERror).

    Na zakończenie procedura FTARV odczytuje adres ciągu w pamięci. Po dodaniu adresu elementu w ciągu otrzymany bezwzględny adres jest zapisywany do FR0. Przy odczycie jest to już koniec, a przy zapisie następuje skok do PUTVAR, gdzie współrzędne elementu są przepisywane do bufora.
            0100 ;eXecute Parenthesis of String Expression
            0110 ;
            0120 BHLD1 = $B0
            0130 BHLD2 = $B1
            0140 CSTAD = $97
            0150 FR0 =   $D4
            0160 FTARV = $AB90
            0170 GETSLN = $AE81
            0180 GETVAR = $ABE9
            0190 PUTVAR = $ABB2
            0200 SLENER = $B92A
            0210 ZTEMP1 = $F5
            0220 ;
            0230     *=  $AE11
            0240 ;
            0250     LDA BHLD1
            0260     BEQ GLN
            0270     JSR GETSLN
            0280     STY CSTAD+1
            0290     STA CSTAD
            0300 GLN JSR GETSLN
            0310     SEC
            0320     SBC #$01
            0330     STA ZTEMP1
            0340     TYA
            0350     SBC #$00
            0360     STA ZTEMP1+1
            0370     JSR GETVAR
            0380     LDA BHLD2
            0390     BPL SCD
            0400     ORA BHLD1
            0410     STA BHLD2
            0420     LDY FR0+5
            0430     LDA FR0+4
            0440     JMP CONT
            0450 SCD LDA FR0+2
            0460     LDY FR0+3
            0470 COND LDX BHLD1
            0480     BEQ SBZ
            0490     DEC BHLD1
            0500     CPY CSTAD+1
            0510     BCC ERR
            0520     BNE RAD
            0530     CMP CSTAD
            0540     BCC ERR
            0550 RAD LDY CSTAD+1
            0560     LDA CSTAD
            0570 SBZ SEC
            0580     SBC ZTEMP1
            0590     STA FR0+2
            0600     TAX
            0610     TYA
            0620     SBC ZTEMP1+1
            0630     STA FR0+3
            0640     BCC ERR
            0650     TAY
            0660     BNE ADZ
            0670     TXA
            0680     BEQ ERR
            0690 ADZ JSR FTARV+3
            0700     CLC
            0710     LDA FR0
            0720     ADC ZTEMP1
            0730     STA FR0
            0740     LDA FR0+1
            0750     ADC ZTEMP1+1
            0760     STA FR0+1
            0770     BIT BHLD2
            0780     BPL PUT
            0790     RTS
            0800 PUT JMP PUTVAR
            0810 ERR JSR SLENER
    W opisanej powyżej procedurze odczyt indeksu długości ciągu jest wykonywany przez pomocniczą procedurę GETSLN. Przez wywołanie GETNUM pobiera ona z bufora liczbę całkowitą i sprawdza jej wartość. Jeśli liczba ta jest równa zero (oba bajty zerowe), to przez skok do SLENER sygnalizowany jest błąd.
            0100 ;GET String LeNgth
            0110 ;
            0120 FR0 =   $D4
            0130 GETNUM = $ABDA
            0140 ;
            0150     *=  $AE81
            0160 ;
            0170     JSR GETNUM
            0180     LDA FR0
            0190     LDY FR0+1
            0200     BNE END
            0210     TAX
            0220     BEQ $AE7E   ;JSR SLENER
            0230 END RTS
    Ostatnia procedura jest wspólna dla przecinka oddzielającego indeksy zmiennej tablicowej (XCOM) oraz dla nawiasu zamykającego (XEPAR). Zdejmuje ona jedynie ze stosu dwie wartości (adres powrotny) i kończy się skokiem do procedury PRCOP wywołującej realizacyjną procedurę operatora lub funkcji. W przypadku przecinka zwiększana jest jeszcze zawartość rejestru BHLD1, który określa liczbę wartości użytych dla wskazania indeksu zmiennej. Należy tu zwrócić uwagę, że procedura XCOM jest wykonywana TYLKO dla przecinka w indeksie zmiennej tablicowej, a nie dla przecinków zastosowanych w innych miejscach.
            0100 BHLD1 = $B0
            0110 PRCOP = $AB04
            0120 STIX =  $A9
            0130 ;
            0140     *=  $AD64
            0150 ;
            0160 ;eXecute index COMma
            0170 ;
            0180 XCOM INC BHLD1
            0190 ;
            0200 ;eXecute End PARenthesis
            0210 ;
            0220 XEPAR LDY STIX
            0230     PLA
            0240     PLA
            0250     JMP PRCOP
Zientara Wojciech: Mapa pamięci Atari XL/XE. Procedury interpretera Basica, SOETO, Warszawa, 1988.