INTERPRETACJA WIERSZY BASIC ORAZ ROZKAZÓW

TABLICE SKŁADNIOWE

i. Tablica offsetów

Dla każdego z pięćdziesięciu rozkazów języka BASIC istnieje określona wartość offsetu

                Rozkaz    Adres                   Rozkaz    Adres
1A48 DEFB +B1   DEF FN    1AF9      1A61 DEFB +94 BORDER    1AF5
1A49 DEFB +CB   CAT       1B14      1A62 DEFB +56 CONTINUE  1AB8
1A4A DEFB +BC   FORMAT    1B06      1A63 DEFB +3F DIM       1AA2
1A4B DEFB +BF   MOVE      1B0A      1A64 DEFB +41 REM       1AA5
1A4C DEFB +C4   ERASE     1B10      1A65 DEFB +2B FOR       1A90
1A4D DEFB +AF   OPEN #    1AFC      1A66 DEFB +17 GO TO     1A7D
1A4E DEFB +B4   CLOSE #   1B02      1A67 DEFB +1F GO SUB    1A86
1A4F DEFB +93   MERGE     1AE2      1A68 DEFB +37 INPUT     1A9F
1A50 DEFB +91   VERIFY    1AE1      1A69 DEFB +77 LOAD      1AE0
1A51 DEFB +92   BEEP      1AE3      1A6A DEFB +44 LIST      1AAE
1A52 DEFB +95   CIRCLE    1AE7      1A6B DEFB +0F LET       1A7A
1A53 DEFB +98   INK       1AEB      1A6C DEFB +59 PAUSE     1AC5
1A54 DEFB +98   PAPER     1AEC      1A6D DEFB +2B NEXT      1A98
1A55 DEFB +98   FLASH     1AED      1A6E DEFB +43 POKE      1AB1
1A56 DEFB +98   BRIGHT    1AEE      1A6F DEFB +2D PRINT     1A9C
1A57 DEFB +98   INVERSE   1AEF      1A70 DEFB +51 PLOT      1AC1
1A58 DEFB +98   OVER      1AF0      1A71 DEFB +3A RUN       1AAB
1A59 DEFB +98   OUT       1AF1      1A72 DEFB +6D SAVE      1ADF
1A5A DEFB +7F   LPRINT    1AD9      1A73 DEFB +42 RANDOMIZE 1AB5
1A5B DEFB +81   LLIST     1ADC      1A74 DEFB +0D IF        1A81
1A5C DEFB +2E   STOP      1A8A      1A75 DEFB +49 CLS       1ABE
1A5D DEFB +6C   READ      1AC9      1A76 DEFB +5C DRAW      1AD2
1A5E DEFB +6E   DATA      1ACC      1A77 DEFB +44 CLEAR     1ABB
1A5F DEFB +70   RESTORE   1ACF      1A78 DEFB +15 RETURN    1A8D
1A60 DEFB +48   NEW       1AA8      1A79 DEFB +5D COPY      1AD6

ii. Tablica parametrów

Dla każdego z pięćdziesięciu rozkazów języka BASIC istnieje do ośmiu elementów w tablicy parametrów. Elementy te określają szczegóły klasy rozkazu, wymagane separatory oraz w odpowiednich miejscach adresy procedur.

1A7A P-LET        DEFB  +01                 CLASS-01
                  DEFB  +3D                 '='
                  DEFB  +02                 CLASS-02

1A7D P-GO-TO      DEFB  +06                 CLASS-06
                  DEFB  +00                 CLASS-00
                  DEFB  +67,+1E             GO-TO,1E67

1A81 P-IF         DEFB  +06                 CLASS-06
                  DEFB  +CB                 'THEN'
                  DEFB  +05                 CLASS-05
                  DEFB  +F0,+1C             IF,1CF0

1A86 P-GO-SUB     DEFB  +06                 CLASS-06
                  DEFB  +00                 CLASS-00
                  DEFB  +ED,+1E             GO-SUB,1EED

1A8A P-STOP       DEFB  +00                 CLASS-00
                  DEFB  +EE,+1C             STOP,1CEE

1A8D P-RETURN     DEFB  +00                 CLASS-00
                  DEFB  +23,+1F             RETURN,1F23

1A90 P-FOR        DEFB  +04                 CLASS-04
                  DEFB  +3D                 '='
                  DEFB  +06                 CLASS-06
                  DEFB  +CC                 'TO'
                  DEFB  +06                 CLASS-06
                  DEFB  +05                 CLASS-05
                  DEFB  +03,+1D             FOR,1D03

1A98 P-NEXT       DEFB  +04                 CLASS-04
                  DEFB  +00                 CLASS-00
                  DEFB  +AB,+1D             NEXT,1DAB

1A9C P-PRINT      DEFB  +05                 CLASS-05
                  DEFB  +CD,+1F             PRINT,1FCD

1A9F P-INPUT      DEFB  +05                 CLASS-05
                  DEFB  +89,+20             INPUT,2089

1AA2 P-DIM        DEFB  +05                 CLASS-05
                  DEFB  +02,+2C             DIM,2C02

1AA5 P-REM        DEFB  +05                 CLASS-05
                  DEFB  +B2,+1B             REM,1BB2

1AA8 P-NEW        DEFB  +00                 CLASS-00
                  DEFB  +B7,+11             NEW,11B7

1AAB P-RUN        DEFB  +03                 CLASS-03
                  DEFB  +A1,+1E             RUN,1EA1

1AAE P-LIST       DEFB  +05                 CLASS-05
                  DEFB  +F9,+17             LIST,17F9

1AB1 P-POKE       DEFB  +08                 CLASS-08
                  DEFB  +00                 CLASS-00
                  DEFB  +80,+1E             POKE,1E80

1AB5 P-RANDOM     DEFB  +03                 CLASS-03
                  DEFB  +4F,+1E             RANDOMIZE,1E4F

1AB8 P-CONT       DEFB  +00                 CLASS-00
                  DEFB  +5F,+1E             CONTINUE,1E5F

1ABB P-CLEAR      DEFB  +03                 CLASS-03
                  DEFB  +AC,+1E             CLEAR,1EAC

1ABE P-CLS        DEFB  +00                 CLASS-00
                  DEFB  +6B,+0D             CLS,0D6B

1AC1 P-PLOT       DEFB  +09                 CLASS-09
                  DEFB  +00                 CLASS-00
                  DEFB  +DC,+22             PLOT,22DC

1AC5 P-PAUSE      DEFB  +06                 CLASS-06
                  DEFB  +00                 CLASS-00
                  DEFB  +3A,+1F             PAUSE,1F3A

1AC9 P-READ       DEFB  +05                 CLASS-05
                  DEFB  +ED,+1D             READ,1DED

1ACC P-DATA       DEFB  +05                 CLASS-05
                  DEFB  +27,+1E             DATA,1E27

1ACF P-RESTORE    DEFB  +03                 CLASS-03
                  DEFB  +42,+1E             RESTORE,1E42

1AD2 P-DRAW       DEFB  +09                 CLASS-09
                  DEFB  +05                 CLASS-05
                  DEFB  +82,+23             DRAW,2382

1AD6 P-COPY       DEFB  +00                 CLASS-00
                  DEFB  +AC+0E              COPY,0EAC

1AD9 P-LPRINT     DEFB  +05                 CLASS-05
                  DEFB  +C9,+1F             LPRINT,1FC9

1ADC P-LLIST      DEFB  +05                 CLASS-05
                  DEFB  +F5,+17             LLIST,17F5

1ADF P-SAVE       DEFB  +0B                 CLASS-0B

1AE0 P-LOAD       DEFB  +0B                 CLASS-0B

1AE1 P-VERIFY     DEFB  +0B                 CLASS-0B

1AE2 P-MERGE      DEFB  +0B                 CLASS-0B

1AE3 P-BEEP       DEFB  +08                 CLASS-08
                  DEFB  +00                 CLASS-00
                  DEFB  +F8,+03             BEEP,03F8

1AE7 P-CIRCLE     DEFB  +09                 CLASS-09
                  DEFB  +05                 CLASS-05
                  DEFB  +20,+23             CIRCLE,2320

1AEB P-INK        DEFB  +07                 CLASS-07

1AEC P-PAPER      DEFB  +07                 CLASS-07

1AED P-FLASH      DEFB  +07                 CLASS-07

1AEE P-BRIGHT     DEFB  +07                 CLASS-07

1AEF P-INVERSE    DEFB  +07                 CLASS-07

1AF0 P-OVER       DEFB  +07                 CLASS-07

1AF1 P-OUT        DEFB  +08                 CLASS-08
                  DEFB  +00                 CLASS-00
                  DEFB  +7A,+1E             OUT,1E7A

1AF5 P-BORDER     DEFB  +06                 CLASS-06
                  DEFB  +00                 CLASS-00
                  DEFB  +94,+22             BORDER,2294

1AF9 P-DEF-FN     DEFB  +05                 CLASS-05
                  DEFB  +60,+1F             DEF-FN,1F60

1AFC P-OPEN       DEFB  +06                 CLASS-06
                  DEFB  +2C                 ','
                  DEFB  +0A                 CLASS-0A
                  DEFB  +00                 CLASS-00
                  DEFB  +36,+17             OPEN,1736

1B02 P-CLOSE      DEFB  +06                 CLASS-06
                  DEFB  +00                 CLASS-00
                  DEFB  +E5,+16             CLOSE,16E5

1B06 P-FORMAT     DEFB  +0A                 CLASS-0A
                  DEFB  +00                 CLASS-00
                  DEFB  +93,+17             CAT-ETC,1793

1B0A P-MOVE       DEFB  +0A                 CLASS-0A
                  DEFB  +2C                 ','
                  DEFB  +0A                 CLASS-0A
                  DEFB  +00                 CLASS-00
                  DEFB  +93,+17             CAT-ETC,1793

1B10 P-ERASE      DEFB  +0A                 CLASS-0A
                  DEFB  +00                 CLASS-00
                  DEFB  +93,+17             CAT-ETC,1793

1B14 P-CAT        DEFB  +00                 CLASS-00
                  DEFB  +93,+17             CAT-ETC,1793

Uwaga: wymagania dla każdej z różnych klas rozkazów są następujące:

CLASS-00 – Brak dalszych parametrów.
CLASS-01 – Używana w LET. Wymagana jest zmienna.
CLASS-02 – Używana w LET. Musi wystąpić wyrażenie liczbowe lub znakowe.
CLASS-03 – Może wystąpić wyrażenie liczbowe. Jeśli go nie ma, przyjmuje się standardowo zero.
CLASS-04 – Musi wystąpić zmienna o jednoliterowej nazwie.
CLASS-05 – Może być podany zbiór elementów.
CLASS-06 – Musi wystąpić wyrażenie liczbowe.
CLASS-07 – Obsługuje elementy kolorów.
CLASS-08 – Muszą wystąpić dwa wyrażenia liczbowe rozdzielone przecinkiem.
CLASS-09 – Jak dla CLASS-08, lecz elementy kolorów mogą poprzedzać wyrażenia.
CLASS-0A – Musi wystąpić wyrażenie łańcuchowe.
CLASS-0B – Obsługuje procedury magnetofonu.

'GŁÓWNA PĘTLA' INTERPRETERA JĘZYKA BASIC

Gdy sprawdzana jest składnia, to wejście do procedury interpretacji poleceń języka BASIC następuje w punkcie LINE-SCAN, natomiast przy wykonywaniu rozkazów punktem wejścia jest LINE-RUN.

Każde polecenie zostaje po kolei przetworzone, a zmienna systemowa CH-ADD jest wykorzystywana do wskazywania każdego kodu lub rozkazu pojawiającego się w obszarze programu lub w obszarze edycyjnym.

1B17 LINE-SCAN    RES   7,(FLAGS)           Sygnalizuj 'sprawdzanie składni'.
                  CALL  19FB,E-LINE-NO      CH-ADD zostaje ustawione na pierwszy kod
                                            za każdym numerem wiersza.
                  XOR   A                   Zmienna systemowa SUBPPC
                  LD    (SUBPPC),A          jest inicjowana na +00
                  DEC   A                   a ERR-NR na +FF.
                  LD    (ERR-NR),A
                  JR    1B29,STMT-L-1       Skocz naprzód, aby przetworzyć
                                            pierwszy rozkaz wiersza.

PĘTLA ROZKAZÓW.

Każdy rozkaz jest kolejno przetwarzany aż do osiągnięcia końca wiersza.

1B28 STMT-LOOP    RST   0020,NEXT-CHAR      Zwiększaj CH-ADD wzdłuż wiersza.
1B29 STMT-L-1     CALL  16BF,SET-WORK       Przestrzeń robocza jest czyszczona.
                  INC   (SUBPPC)            Zwiększaj SUBPPC przy każdym obiegu pętli.
                  JP    M,1C8A,REPORT-C     Lecz dozwolone jest tylko '127' rozkazów
                                            w pojedynczym wierszu.
                  RST   0018,GET-CHAR       Pobierz znak.
                  LD    B,+00               Wyzeruj ten rejestr na później.
                  CP    +0D                 Jeśli znakiem jest 'powrót karetki',
                  JR    Z,1BB3,LINE-END     to wykonaj skok.
                  CP    +3A                 Jeśli jest to ':',
                  JR    Z,1B28,STMT-LOOP    to wróć na początek pętli.

Zidentyfikowano polecenie, zatem rozpatrzony zostanie pierwszy rozkaz.

                  LD    HL,+1B76            Załaduj na stos maszynowy
                  PUSH  HL                  adres powrotny STMT-RET.
                  LD    C,A                 Chwilowo zapamiętaj rozkaz
                  RST   0020,NEXT-CHAR      w rejestrze C, gdy CH-ADD
                  LD    A,C                 jest ponownie przesuwane.
                  SUB   +CE                 Zmniejsz kod rozkazu o +CE;
                                            da to zakres od +00 do
                                            +31 dla pięćdziesięciu rozkazów.
                  JP    C,1C8A,REPORT-C     Twórz odpowiedni raport błędu,
                                            jeśli kod nie oznacza rozkazu.
                  LD    C,A                 Przenieś kod rozkazu do
                                            pary rejestrów BC (B zawiera +00).
                  LD    HL,+1A48            Adres bazowy tablicy składniowej offsetów.
                  ADD   HL,BC               Pożądany offset jest przekazywany do
                  LD    C,(HL)              rejestru C i używany do wyliczenia
                  ADD   HL,BC               adresu bazowego dla pozycji rozkazu
                                            w tablicy parametrów.
                  JR    1B55,GET-PARAM      Skocz naprzód do pętli skanującej z
                                            tym adresem.

Wykonywane są po kolei procedury klas rozkazów, które odnoszą się do bieżącego polecenia. Przetwarza się również wszystkie niezbędne separatory.

1B52 SCAN-LOOP    LD    HL,(T-ADDR)         Tymczasowy wskaźnik do elementów
                                            w tablicy parametrów.
1B55 GET-PARAM    LD    A,(HL)              Pobierz kolejno każdy element.
                  INC   HL                  Uaktualnij wskaźnik elementów dla 
                  LD    (T-ADDR),HL         następnego obiegu.
                  LD    BC,+1B52            Załaduj na stos maszynowy
                  PUSH  BC                  adres powrotny - SCAN-LOOP.
                  LD    C,A                 Przepisz element do rejestru C na później.
                  CP    +20                 Skocz naprzód, jeśli element jest
                  JR    NC,1B6F,SEPARATOR   'separatorem'.
                  LD    HL,+1C01            Adres bazowy tablicy
                                            'klas rozkazów'.
                  LD    B,+00               Wyczyść rejestr B i
                  ADD   HL,BC               zaindeksuj tę tablicę.
                  LD    C,(HL)              Pobierz przesunięcie i oblicz
                  ADD   HL,BC               adres startowy procedury pożądanej klasy rozkazów.
                  PUSH  HL                  Umieść ten adres na stosie maszynowym.
                  RST   0018,GET-CHAR       Przed wykonaniem skoku pośredniego
                  DEC   B                   do procedury klasy rozkazu przenieś
                  RET                       kod rozkazu do rejestru A i ustaw
                                            rejestr B na +FF.

PROCEDURA 'SEPARATOR'

Zostaje utworzony raport błędu – 'Nonsense in BASIC', jeśli brak wymaganego separatora. Jednakże zwróć uwagę, iż w czasie sprawdzania składni raport ten nie pojawia się na ekranie – jedynie 'znacznik błędu'.

1B6F SEPARATOR    RST   0018,GET-CHAR       Bieżący znak zostaje pobrany
                  CP    C                   i porównany z elementem
                                            tablicy parametrów.
                  JP    NZ,1C8A,REPORT-C    Jeśli nie ma zgodności, utwórz raport błędu.
                  RST   0020,NEXT-CHAR      Przejdź za poprawny znak
                  RET                       i powróć.

PROCEDURA 'STMT-RET'

Po poprawnej interpretacji polecenia wykonywany jest powrót do punktu wejścia.

1B76 STMT-RET     CALL  1F54,BREAK-KEY      Klawisz BREAK jest sprawdzany po
                                            każdym poleceniu.
                  JR    C,1B7D,STMT-R-1     Skocz naprzód, chyba że jest naciśnięty.

Raport L - 'PRZERWA w programie'

1B7B REPORT-L     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +14

Kontynuuj w tym miejscu, jeśli klawisza BREAK nie naciśnięto.

1B7D STMT-R-1     BIT   7,(NSPPC)           Skocz naprzód, jeśli nie należy wykonać
                  JR    NZ,1BF4,STMT-NEXT   'przeskoku' w programie.
                  LD    HL,(NEWPPC)         Pobierz numer 'nowego wiersza'
                  BIT   7,H                 i skocz naprzód, chyba że jest przetwarzane
                  JR    Z,1B9E,LINE-NEW     kolejne polecenie w obszarze edycyjnym.

PUNKT WEJŚCIA 'LINE-RUN'

Ten punkt wejścia jest używany zawsze, gdy ma zostać uruchomiony wiersz programu w obszarze edycyjnym. W takim przypadku znacznik składni/uruchomienia (bit nr 7 zmiennej FLAGS) będzie ustawiony na 1.

Wejście to jest również używane przy sprawdzaniu składni wiersza w obszarze edycyjnym, który zawiera więcej niż jedno polecenie (bit 7 FLAGS będzie wyzerowany).

1B8A LINE-RUN     LD    HL,+FFFE            Wiersz w obszarze edycyjnym
                  LD    (PPC),HL            jest uważany za wiersz '-2'.
                  LD    HL,(WORKSP)         Ustaw HL na znacznik końca
                  DEC   HL                  obszaru edycyjnego,
                  LD    DE,(E-LINE)         a DE na komórkę tuż przed
                  DEC   DE                  początkiem tego obszaru.
                  LD    A,(NSPPC)           Pobierz numer następnego
                                            polecenia do obsłużenia
                  JR    1BD1,NEXT-LINE      przed skokiem naprzód.

PROCEDURA 'LINE-NEW'

W programie nastąpił skok i należy znaleźć adres początku nowego wiersza.

1B9E LINE-NEW     CALL  196E,LINE-ADDR      Znajdowany jest adres startowy wiersza
                                            lub adres pierwszego następnego wiersza.
                  LD    A,(NSPPC)           Pobierz numer polecenia.
                  JR    Z,1BBF,LINE-USE     Skocz naprzód, jeśli pożądany
                  AND   A                   wiersz został znaleziony; inaczej
                  JR    NZ,1BEC,REPORT-N    sprawdź poprawność numeru polecenia - musi być zero.
                  LD    B,A                 Również sprawdź, czy 'pierwszy wiersz za nim'
                  LD    A,(HL)              nie jest faktycznie poza 'końcem programu'.
                  AND   +C0
                  LD    A,B
                  JR    Z,1BBF,LINE-USE     Skocz naprzód przy poprawnym adresie;
                                            inaczej sygnalizuj błąd 'OK'.

Raport 0 - 'OK'

1BB0 REPORT-0     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +FF

Uwaga: Oczywiście nie jest to błąd w normalnym sensie – raczej skok poza program.

PROCEDURA ROZKAZU 'REM'

Adres powrotny do STMT-RET jest usuwany ze stosu, co w rezultacie powoduje zignorowanie reszty wiersza.

1BB2 REM          POP   BC                  Usuń adres - STMT-RET.

PROCEDURA 'LINE-END'

Przy sprawdzaniu składni wykonywany jest prosty powrót, jednakże w czasie 'uruchomienia' adres przechowywany przez NXTLIN musi zostać sprawdzony przed użyciem.

1BB3 LINE-END     CALL  2530,SYNTAX-Z       Wróć, jeśli sprawdzana jest składnia;
                  RET   Z                   inaczej pobierz adres
                  LD    HL,(NXTLIN)         przechowywany w NXTLIN.
                  LD    A,+C0               Również wróć, jeśli ten adres
                  AND   (HL)                wskazuje poza program
                  RET   NZ                  - 'uruchomienie' dobiegło końca.
                  XOR   A                   Sygnalizuj 'polecenie zero' przed kontynuowaniem.

PROCEDURA 'LINE-USE'

Ta krótka procedura posiada trzy funkcje:

i. Zmienia polecenie zera na polecenie '1'.
ii. Znalezienie numeru nowego wiersza i wprowadzenie go do PPC.
iii. Utworzenie adresu początku kolejnego wiersza.

1BBF LINE-USE     CP    +01                 Rozkaz zero staje się
                  ADC   A,+00               rozkazem '1'
                  LD    D,(HL)              Numer wiersza, który ma zostać
                  INC   HL                  użyty, jest pobierany
                  LD    E,(HL)              i przekazywany do.
                  LD    (PPC),DE
                  INC   HL                  Teraz znajdź 'długość'
                  LD    E,(HL)              tego wiersza.
                  INC   HL
                  LD    D,(HL)
                  EX    DE,HL               Wymień ze sobą te wartości.
                  ADD   HL,DE               Utwórz adres początku
                  INC   HL                  kolejnego wiersza w HL, a adres
                                            pierwszej komórki przed pierwszym znakiem
                                            'następnego' wiersza w DE.

PROCEDURA 'NEXT-LINE'

Na wejściu para rejestrów HL wskazuje na pierwszą komórkę za końcem 'następnego' wiersza do obsługi, a para rejestrów DE wskazuje na komórkę przed pierwszym znakiem tego wiersza. Stosuje się to zarówno do wierszy w obszarze programu jak i do wiersza w obszarze edycyjnym, gdzie następnym wierszem będzie znów ten sam wiersz, gdy zawiera on polecenia wciąż do interpretacji.

1BD1 NEXT-LINE    LD    (NXTLIN),HL         Ustaw NXTLIN do użytku, gdy bieżący wiersz
                                            został skompletowany.
                  EX    DE,HL               Jak zwykle, CH-ADD wskazuje na komórkę
                  LD    (CH-ADD),HL         przed pierwszym znakiem
                                            do interpretacji.
                  LD    D,A                 Zostaje pobrany numer polecenia.
                  LD    E,+00               Rejestr E jest zerowany w przypadku
                                            korzystania z EACH-STMT.
                  LD    (NSPPC),+FF         Sygnalizuj 'bez skoku'.
                  DEC   D                   Numer polecenia minus jeden
                  LD    (SUBPPC),D          idzie do SUBPPC.
                  JP    Z,1B28,STMT-LOOP    Teraz można przetworzyć pierwsze polecenie.
                  INC   D                   Jednakże dla dalszych poleceń
                  CALL  198B,EACH-STMT      należy znaleźć 'adres początkowy'.
                  JR    Z,1BF4,STMT-NEXT    Skocz naprzód, chyba że polecenie nie istnieje.

Raport N - 'Rozkaz utracony'

1BEC REPORT-N     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów
                  DEFB  +16

PROCEDURA 'CHECK-END'

Jest to ważna procedura i wywołuje się ją z wielu miejsc w programie monitora w trakcie sprawdzania składni edytowanego wiersza. Celem procedury jest utworzenie raportu błędu, jeśli koniec polecenia nie został osiągnięty, oraz przejście do następnego polecenia w przypadku prawidłowej składni.

1BEE CHECK-END    CALL  2530,SYNTAX-Z       Nie kontynuuj, jeśli nie jest
                  RET   NZ                  sprawdzana składnia.
                  POP   BC                  Usuń adresy
                  POP   BC                  SCAN-LOOP i STMT-RET
                                            przed przejściem do STMT-NEXT.

PROCEDURA 'STMT-NEXT'

Jeśli bieżącym znakiem jest 'powrót karetki', to następne polecenie znajduje się w 'następnym wierszu'; jeśli jest nim ':', to jest ono w tym samym wierszu; lecz jeśli występuje dowolny inny znak, to mamy błąd składni.

1BF4 STMT-NEXT    RST   0018,GET-CHAR       Pobierz bieżący znak.
                  CP    +0D                 Wybierz 'następny wiersz', jeśli
                  JR    Z,1BB3,LINE-END     jest nim 'powrót karetki'.
                  CP    +3A                 Wybierz 'następne polecenie',
                  JP    Z,1B28,STMT-LOOP    jeśli jest to ' : '.
                  JP    1C8A,REPORT-C       W przeciwnym razie występuje błąd składniowy.

TABLICA 'KLAS ROZKAZÓW'

adres przesunięcie klasa    adres klasy
1C01  0F           CLASS-00 1C10
1C02  1D           CLASS-01 1C1F
1C03  4B           CLASS-02 1C4E
1C04  09           CLASS-03 1C0D
1C05  67           CLASS-04 1C6C
1C06  0B           CLASS-05 1C11
1C07  7B           CLASS-06 1C82
1C08  8E           CLASS-07 1C96
1C09  71           CLASS-08 1C7A
1C0A  B4           CLASS-09 1CBE
1C0B  81           CLASS-0A 1C8C
1C0C  CF           CLASS-0B 1CDB

'KLASY ROZKAZÓW – 00, 03 i 05'

Za rozkazami klasy-03 może wystąpić liczba, lecz może jej również nie być, np. RUN lub RUN 200.

1C0D CLASS-03     CALL  1CDE,FETCH-NUM      Pobierana jest liczba, lecz zostanie użyte
                                            zero, jeśli jej nie będzie.

Rozkazy klasy-00 nie powinny mieć jakichkolwiek parametrów, np. COPY lub CONTINUE.

1C10 CLASS-00     CP    A                   Ustaw znacznik zera na później.

Rozkazy klasy-05 mogą posiadać ciąg parametrów, np. PRINT lub PRINT "222".

1C11 CLASS-05     POP   BC                  We wszystkich przypadkach usuń adres SCAN-LOOP.
                  CALL  Z,1BEE,CHECK-END    Jeśli są przetwarzane rozkazy klas 00 i 03
                                            oraz jest sprawdzana składnia, to przejdź dalej
                                            do przetwarzania następnego polecenia.
                  EX    DE,HL               Zapamiętaj wskaźnik wiersza w parze rejestrów DE.

PROCEDURA 'JUMP-C-R'

Po przetworzeniu elementów klas rozkazów i separatorów w tablicy parametrów skocz do odpowiedniej procedury obsługującej właściwy rozkaz.

1C16 JUMP-C-R     LD    HL,(T-ADDR)         Pobierz wskaźnik do
                  LD    C,(HL)              elementów tablicy parametrów
                  INC   HL                  oraz pobierz adres pożądanej
                  LD    B,(HL)              procedury rozkazu.
                  EX    DE,HL               Z powrotem wymień wskaźniki
                  PUSH  BC                  i wykonaj pośredni skok
                  RET                       do procedury rozkazu.

'KLASY ROZKAZÓW – 01, 02 i 04'

Te trzy klasy rozkazów są używane przez rozkazy przetwarzające zmienne – LET, FOR i NEXT oraz pośrednio przez READ i INPUT.

Rozkaz klasy 01 dotyczy identyfikacji zmiennej w poleceniu LET, READ lub INPUT.

1C1F CLASS-01     CALL  28B2,LOOK-VARS      Sprawdź w obszarze zmiennych, czy dana zmienna
                                            była lub nie była jeszcze użyta.

PROCEDURA 'ZMIENNEJ W PRZYPISANIU'

Ta procedura tworzy odpowiednie wartości dla zmiennych systemowych DEST i STRLEN.

1C22 VAR-A-1      LD    (FLAGX),+00         Inicjuj FLAGX na +00.
                  JR    NC,1C30,VAR-A-2     Skocz naprzód, jeśli ta zmienna
                                            była wcześniej używana.
                  SET   1,(FLAGX)           Sygnalizuj 'nowa zmienna'.
                  JR    NZ,1C46,VAR-A-3     Utwórz błąd, jeśli jest próba użycia
                                            'niezwymiarowanej tablicy'.

Raport 2 - Zmienna nieznaleziona

1C2E REPORT-2     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +01

Kontynuuj obsługę istniejących zmiennych.

1C30 VAR-A-2      CALL  Z,2996,STK-VARS     Parametry prostych zmiennych łańcuchowych
                                            oraz wszystkich zmiennych tablicowych
                                            są przekazywane na stos kalkulatora.
                                            (STK-VARS wykona 'slicing' łańcucha,
                                            jeśli będzie to potrzebne.)
                  BIT   6,(FLAGS)           Skocz naprzód, jeśli jest obsługiwana
                  JR    NZ,1C46,VAR-A-3     zmienna numeryczna.
                  XOR   A                   Wyczyść rejestr A.
                  CALL  2530,SYNTAX-Z       Parametry łańcucha zmiennej łańcuchowej
                  CALL  NZ,2BF1,STK-FETCH   zostają pobrane, chyba że jest sprawdzana składnia.
                  LD    HL,+5C71            To jest FLAGX.
                  OR    (HL)                Bit 0 jest ustawiany tylko wtedy, gdy obsługiwane są
                  LD    (HL),A              całe 'proste łańcuchy', a stąd sygnalizuje on
                                            potrzebę 'usunięcia starej kopii'.
                  EX    DE,HL               HL teraz wskazuje na łańcuch lub na
                                            element tablicy.

Ścieżki teraz schodzą się ze sobą, aby odpowiednio ustawić STRLEN i DEST. Dla wszystkich zmiennych numerycznych oraz 'nowych' łańcuchów i zmiennych tablic łańcuchów STRLEN zawiera 'literę' nazwy zmiennej. Lecz dla 'starych' łańcuchów i zmiennych tablicowych łańcuchów 'dzielonych' lub pełnych przechowuje ona długość w 'przypisaniu'.

1C46 VAR-A-3      LD    (STRLEN),BC         Ustaw odpowiednio STRLEN.

DEST przechowuje adres 'przeznaczenia' 'starej' zmiennej, lecz w rzeczywistości będzie to adres 'źródła' dla 'nowej' zmiennej.

                  LD    (DEST),HL           Ustaw odpowiednio DEST
                  RET                       i powróć.

Klasa rozkazów 02 zajmuje się faktycznym obliczeniem wartości, która ma zostać przypisana w poleceniu LET.

1C4E CLASS-02     POP   BC                  Adres SCAN-LOOP jest usuwany ze stosu.
                  CALL  1C56,VAL-FET-1      Wykonane zostaje przypisanie.
                  CALL  1BEE,CHECK-END      Przesuń się do kolejnego polecenia
                                            albo poprzez CHECK-END przy sprawdzaniu
                  RET                       składni, albo przez STMT-RET w czasie
                                            'wykonywania' programu.

PROCEDURA 'POBRANIA WARTOŚCI'

Ta procedura używana jest przez polecenia LET, READ i INPUT do obliczenia najpierw wartości, a następnie do przypisania jej przydzielonej zmiennej.

Punkt wejścia VAL-FET-1 jest używany przez LET i READ i bierze pod uwagę FLAGS, natomiast punkt wejścia VAL-FET-2 jest używany przez INPUT i bierze pod uwagę FLAGX.

1C56 VAL-FET-1    LD    A,(FLAGS)           Użyj FLAGS.
1C59 VAL-FET-2    PUSH  AF                  Zapamiętaj na stosie FLAGS lub FLAGX.
                  CALL  24FB,SCANNING       Oblicz następne wyrażenie.
                  POP   AF                  Pobierz stare FLAGS lub FLAGX.
                  LD    D,(FLAGS)           Pobierz nowe FLAGS.
                  XOR   D                   Zmienna i wyrażenie muszą być tej samej natury
                  AND   +40                 numeryczne lub znakowe.
                  JR    NZ,1C8A,REPORT-C    Jeśli nie są, utwórz raport C.
                  BIT   7,D                 Skocz naprzód, aby wykonać
                  JP    NZ,2AFF,LET         przypisanie, chyba że jest sprawdzana
                  RET                       składnia, to wtedy po prostu powróć

PROCEDURA 'KLASY ROZKAZÓW 04'

Punkt wejścia do klasy rozkazów 0r jest używany przez polecenia FOR i NEXT.

1C6C CLASS-04     CALL  28B2,LOOK-VARS      Poszukaj w obszarze zmiennych
                                            używanej zmiennej.
                  PUSH  AF                  Zapamiętaj parę rejestrów AF podczas
                  LD    A,C                 testowania bajtu ogranicznika w celu
                  OR    +9F                 upewnienia się, że zmienna ta jest
                  INC   A                   zmienną sterującą pętli FOR-NEXT.
                  JR    NZ,1C8A,REPORT-C
                  POP   AF                  Odtwórz rejestr znaczników
                  JR    1C22,VAR-A-1        i skocz wstecz, aby uczynić znalezioną zmienną
                                            'zmienną w przypisaniu'.

PROCEDURA 'WYRAŻEŃ NUMERYCZNYCH/ŁAŃCUCHOWYCH'

Istnieje ciąg krótkich procedur, które są używane do pobierania wyniku obliczenia następnego wyrażenia. Wynik z pojedynczego wyrażenia jest zwracany jako 'ostatnia wartość' na stosie kalkulatora.

Punkt wejścia NEXT-2NUM jest używany, gdy zmienna systemowa CH-ADD musi być uaktualniona, aby wskazywać początek pierwszego wyrażenia.

1C79 NEXT-2NUM    RST   0020,NEXT-CHAR      Zwiększ CH-ADD.

Punkt wejścia EXPT-2NUM (EQU. CLASS-08) zezwala na obliczenie dwóch wyrażeń numerycznych rozdzielonych przecinkiem.

1C7A EXPT-2NUM    CALL  1C82,EXPT-1NUM      Oblicz kolejno każde z wyrażeń.
     (CLASS-08)
                  CP    +2C                 Twórz raport błędów, jeśli separator
                  JR    NZ,1C8A             nie jest przecinkiem.
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.

Punkt wejścia EXPT-1NUM (EQU. CLASS-06) zezwala na obliczenie pojedynczego wyrażenia.

1C82 EXPT-1NUM    CALL  24FB,SCANNING       Oblicz pierwsze wyrażenie.
     (CLASS-06)
                  BIT   6,(FLAGS)           Wróć, gdy wynik był numeryczny;
                  RET   NZ                  inaczej jest to błąd.

Raport C - Nonsens w BASIC

1C8A REPORT-C     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +0B

Punkt wejścia EXPT-EXP (EQU. CLASS-0A) zezwala na obliczenie pojedynczego wyrażenia łańcuchowego.

1C8C EXPT-EXP     CALL  24FB,SCANNING       Oblicz następne wyrażenie.
     (CLASS-0A)
                  BIT   6,(FLAGS)           Tym razem wróć, jeśli wynikiem
                  RET   Z                   jest łańcuch; inaczej generuj
                  JR    1C8A,REPORT-C       raport błędu.

PROCEDURA 'USTAWIANIA STAŁYCH KOLORÓW' (KLASA-07)

Ta procedura umożliwia kolorom tymczasowym przejście w kolory stałe. Jako klasa rozkazów 07 staje się ona procedurą obsługi sześciu rozkazów związanych z elementami koloru.

1C96 PERMS        BIT   7,(FLAGS)           Odczytany zostaje znacznik składnia/uruchomienie.
     (CLASS-07)
                  RES   0,(TV-FLAG)         Sygnalizuj 'główny ekran'.
                  CALL  NZ,0D4D,TEMPS       Tylko podczas 'uruchomienia' wywołaj TEMPS,
                                            aby upewnić się, że kolory tymczasowe
                                            będą głównymi kolorami ekranu.
                  POP   AF                  Usuń adres powrotny do SCAN-LOOP.
                  LD    A,(T-ADDR)          Pobierz młodszy bajt T-ADDR i odejmij +13, aby otrzymać
                  SUB   +13                 zakres od +D9 do +DE, co odpowiada
                                            kodom symboli od INK do OVER.
                  CALL  21FC,CO-TEMP-4      Skocz naprzód, aby zmienić kolory tymczasowe zgodnie
                                            z rozkazem BASIC.
                  CALL  1BEE,CHECK-END      Przejdź do następnego polecenia przy
                                            sprawdzaniu składni.
                  LD    HL,(ATTR-T)         Teraz wartości kolorów tymczasowych
                  LD    (ATTR-P),HL         stają się wartościami kolorów stałych (oba ATTR-P i MASK-P).
                  LD    HL,+5C91            To jest P-FLAG; i jego również
                  LD    A,(HL)              należy wziąć pod uwagę.

Następne instrukcje sprytnie kopiują parzyste bity dostarczonego bajtu do bitów nieparzystych. W rezultacie bity stałe stają się takie same jak bity tymczasowe.

                  RLCA                      Przesuń maskę w lewo.
                  XOR   (HL)                Ustaw w masce tylko
                  AND   +AA                 parzyste bity pozostałego bajtu.
                  XOR   (HL)
                  LD    (HL),A              Odtwórz wynik.
                  RET

PROCEDURA 'KLASA-09 ROZKAZÓW'

Procedura ta jest używana przez rozkazy PLOT, DRAW i CIRCLE do określenia standardowych warunków jako  'FLASH 8; BRIGHT 8; PAPER 8;', które są ustawiane przed przetworzeniem jakichkolwiek osadzonych elementów koloru.

1CBE CLASS-09     CALL  2530,SYNTAX-Z       Skocz naprzód, jeśli
                  JR    Z,1CD6,CL-09-1      jest sprawdzana składnia.
                  RES   0,(TV-FLAG)         Sygnalizuj 'główny ekran'.
                  CALL  0D4D,TEMPS          Ustaw kolory tymczasowe dla głównego ekranu.
                  LD    HL,+5C90            To jest MASK-T.
                  LD    A,(HL)              Pobierz jej bieżącą wartość, lecz
                  OR    +F8                 zatrzymaj tylko część INK 'niemaskowaną'.
                  LD    (HL),A              Odtwórz tę wartość, która teraz
                                            oznacza 'FLASH 8; BRIGHT 8; PAPER 8;'.
                  RES   6,(P-FLAG)          Również upewnij się, że nie występuje 'PAPER 9'.
                  RST   0018,GET-CHAR       Pobierz bieżący znak przed rozpoczęciem
                                            przetwarzania osadzonych elementów koloru.
1CD6 CL-09-1      CALL  21E2,CO-TEMP        Zajmij się lokalnie dominującymi elementami koloru.
                  JR    1C7A,EXPT-2NUM      Teraz pobierz dwa pierwsze parametry
                                            dla PLOT, DRAW lub CIRCLE.

PROCEDURA 'KLASA-0B ROZKAZÓW'

Ta procedura jest używana przez rozkazy SAVE, LOAD, VERIFY i MERGE.

1CDB CLASS-0B     JP    0605,SAVE-ETC       Skocz do procedury obsługi magnetofonu.

PROCEDURA 'POBRANIA LICZBY'

Procedura ta powoduje obliczenie wartości wyrażenia liczbowego, lecz daje zero w przypadku jego braku.

1CDE FETCH-NUM    CP    +0D                 Skocz naprzód, jeśli koniec wiersza.
                  JR    Z,1CE6,USE-ZERO
                  CP    +3A                 Lecz skocz do EXPT-1NUM, chyba że
                  JR    NZ,1C82,EXPT-1NUM   jesteśmy na końcu polecenia.

Teraz jest używany kalkulator, aby dodać zero do stosu kalkulatora.

1CE6 USE-ZERO     CALL  2530,SYNTAX-Z       Nie wykonuj tej operacji
                  RET   Z                   przy sprawdzaniu składni.
                  RST   0028,FP-CALC        Użyj kalkulatora.
                  DEFB  +A0,stk-zero        'Ostatnia wartość' to teraz zero.
                  DEFB  +38,end-calc
                  RET                       Wróć z zerem dodanym do stosu kalkulatora.

PROCEDURY ROZKAZÓW

Ta część 16KB programu monitora od adresu 1CEE do 23FA zawiera w większości procedury rozkazów interpretera języka BASIC.

PROCEDURA ROZKAZU 'STOP'

Procedura rozkazu STOP zawiera jedynie wywołanie procedury obsługi błędów.

1CEE STOP         RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
     (RAPORT-9)   DEFB  +08

PROCEDURA ROZKAZU 'IF'

Na wejściu wyrażenie pomiędzy IF a THEN jest 'ostatnią wartością' na stosie kalkulatora. Jeśli logicznie sprowadza się do prawdy, to zostanie obsłużony następny rozkaz; w przeciwnym razie wiersz zostanie potraktowany jako zakończony.

1CF0 IF           POP   BC                  Usuń adres powrotny - STMT-RET.
                  CALL  2530,SYNTAX-Z       Skocz naprzód, jeśli sprawdzana
                  JR    Z,1D00,IF-1         jest składnia.

Teraz użyj kalkulatora do usunięcia ostatniej wartości na stosie kalkulatora, lecz pozostaw parę rejestrów DE wskazującą pierwszy bajt tej wartości.

                  RST   0028,FP-CALC        Użyj kalkulatora.
                  DEFB  +02,delete          Obecna 'ostatnia wartość' jest usuwana.
                  DEFB  +38,end-calc
                  EX    DE,HL               Ustaw HL na wskazywanie pierwszego bajtu
                  CALL  34E9,TEST-ZERO      i wywołaj TEST-ZERO.
                  JP    C,1BB3,LINE-END     Jeśli wartość była 'fałszem', skocz
                                            do następnego wiersza.
1D00 IF-1         JP    1B29,STMT-L-1       Przy 'prawdzie' skocz do rozkazu
                                            za THEN.

PROCEDURA ROZKAZU 'FOR'

Wejście do tej procedury rozkazu następuje z WARTOŚCIĄ i GRANICĄ dla polecenia FOR umieszczonymi na szczycie stosu kalkulatora.

1D03 FOR          CP    +CD                 Skocz naprzód o ile nie jest obecny parametr 'STEP'.
                  JR    NZ,1D10,F-USE-1
                  RST   0020,NEXT-CHAR      Przesuń do przodu CH-ADD i pobierz
                  CALL  1C82,EXPT-1NUM      wartość kroku dla STEP.
                  CALL  1BEE,CHECK-END      Przejdź dalej do kolejnego rozkazu
                  JR    1D16,F-REORDER      jeśli jest sprawdzana składnia;
                                            inaczej skocz naprzód.

Nie występuje parametr STEP, zatem zostanie użyta wartość '1'.

1D10 F-USE-1      CALL  1BEE,CHECK-END      Przejdź do następnego rozkazu
                                            przy sprawdzaniu składni; inaczej
                  RST   0028,FP-CALC        użyj kalkulatora do umieszczenie '1'
                  DEFB  +A1,stk-one         na stosie kalkulatora.
                  DEFB  +38,end-calc

Elementami na stosie są WARTOŚĆ (w), GRANICA (g) i KROK (k). Wartości te teraz należy przetworzyć.

1D16 F-REORDER    RST   0028,FP-CALC        w, g, k
                  DEFB  +C0,st-mem-0        w, g, k (mem-0 = k)
                  DEFB  +02,delete          w, g
                  DEFB  +01,exchange        g, w
                  DEFB  +E0,get-mem-0       g, w, k
                  DEFB  +01,exchange        g, k, w
                  DEFB  +38,end-calc

Zostaje teraz ustawiona zmienna sterująca pętli FOR i jest traktowana jako tymczasowy obszar pamięci kalkulatora.

                  CALL  2AFF,LET            Zmienna zostaje znaleziona lub w razie potrzeby
                                            utworzona (używane jest w).
                  LD    (MEM),HL            Uczyń ją 'obszarem pamięci'.

Znaleziona zmienna może okazać się zwykłą zmienną liczbową zajmującą sześć komórek, a w takim przypadku należy ją rozszerzyć.

                  DEC   HL                  Pobierz jednoliterową nazwę znakową.
                  LD    A,(HL)
                  SET   7,(HL)              Upewnij się, że bit 7 tej nazwy jest ustawiony.
                  LD    BC,+0006            Będzie miała co najmniej sześć komórek.
                  ADD   HL,BC               Ustaw HL za nimi.
                  RLCA                      Obróć nazwę i skocz, jeśli
                  JR    C,1D34,F-L&S        była to już zmienna pętli FOR.
                  LD    C,+0D               Inaczej zarezerwuj trzynaście dalszych komórek.
                  CALL  1655,MAKE-ROOM
                  INC   HL                  Ponownie ustaw HL na pozycję GRANICY.

Teraz są dodawane początkowe wartości GRANICY i KROKU..

1D34 F-L&S        PUSH  HL                  Wskaźnik zostaje zapamiętany.
                  RST   0028,FP-CALC        g, k
                  DEFB  +02,delete          g
                  DEFB  +02,delete          -
                  DEFB  +38,end-calc        DE wciąż wskazuje na 'g'.
                  POP   HL                  Wskaźnik jest odtwarzany i
                  EX    DE,HL               oba wskaźniki są wymieniane ze sobą.
                  LD    C,+0A               Dziesięć bajtów GRANICY
                  LDIR                      i KROKU zostaję przemieszczone.

Teraz zostają wprowadzone numery wiersza i rozkazu początku pętli.

                  LD    HL,(PPC)            Numer bieżącego wiersza.
                  EX    DE,HL               Wymień rejestry przed
                  LD    (HL),E              dołączeniem tego numeru do
                  INC   HL                  zmiennej sterującej pętli FOR.
                  LD    (HL),D
                  LD    D,(SUBPPC)          Pierwszym rozkazem w pętli
                  INC   D                   zawsze jest następny rozkaz w wierszu -
                  INC   HL                  czy istnieje lub nie.
                  LD    (HL),D

Zostaje wywołana procedura NEXT-LOOP, aby sprawdzić możliwość 'obiegu' i następuje powrót, jeśli taki obieg jest możliwy; w przeciwnym razie musi zostać zidentyfikowany rozkaz za pętlą FOR-NEXT.

                  CALL  1DDA,NEXT-LOOP      Czy 'obieg' możliwy?
                  RET   NC                  Wróć, jeśli tak.
                  LD    B,(STRLEN-lo)       Pobierz nazwę zmiennej.
                  LD    HL,(PPC)            Skopiuj bieżący numer wiersza
                  LD    (NEWPPC),HL         do NEWPPC.
                  LD    A,(SUBPPC)          Pobierz numer bieżącego rozkazu
                  NEG                       i zaneguj go arytmetycznie.
                  LD    D,A                 Przenieś wynik do rejestru D.
                  LD    HL,(CH-ADD)         Pobierz bieżącą wartość zmiennej CH-ADD.
                  LD    E,+F3               Będzie wykonane poszukiwanie 'NEXT'.

Teraz w obszarze programu od bieżącej pozycji w górę poszukiwane jest pierwsze wystąpienie NEXT z odpowiednią zmienną.

1D64 F-LOOP       PUSH  BC                  Zapamiętaj nazwę zmiennej.
                  LD    BC,(NXTLIN)         Pobierz bieżącą wartość NXTLIN.
                  CALL  1D86,LOOK-PROG      Teraz obszar programu będzie
                                            przeszukiwany, a BC będzie się zmieniać
                                            przy każdym testowanym wierszu.
                  LD    (NXTLIN),BC         Przy powrocie zapamiętaj wskaźnik.
                  POP   BC                  Odtwórz nazwę zmiennej.
                  JR    C,1D84,REPORT-I     Jeśli nie ma dalszych rozkazów NEXT, to sygnalizuj błąd.
                  RST   0020,NEXT-CHAR      Przesuń się za znalezione NEXT.
                  OR    +20                 Zezwól na duże lub małe litery,
                  CP    B                   zanim zostanie sprawdzona nazwa zmiennej.
                  JR    Z,1D7C,F-FOUND      Skocz naprzód, jeśli jest zgodna.
                  RST   0020,NEXT-CHAR      Zwiększ ponownie CH-ADD i
                  JR    1D64,F-LOOP         skocz wstecz, jeśli zmienna nie jest właściwa.

NEWPPC zawiera numer wiersza, w którym znaleziono właściwy rozkaz NEXT. Teraz należy znaleźć numer rozkazu i umieścić go w NSPPC.

1D7C F-FOUND      RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  LD    A,+01               Licznik rozkazów w rejestrze D
                  SUB   D                   zliczał rozkazy wstecz od zera, zatem należy go odjąć od '1'.
                  LD    (NSPPC),A           Wynik zostaje zachowany.
                  RET                       Teraz powróć do STMT-RET.

Raport I - FOR bez NEXT

1D84 REPORT-I     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +11

PROCEDURA 'LOOK-PROG'

Ta procedura wykorzystywana jest do znalezienia DATA, DEF FN lub NEXT. Na wejściu kod właściwego rozkazu umieszczony jest w rejestrze E, a para rejestrów HL wskazuje na początek przeszukiwanego obszaru.

1D86 LOOK-PROG    LD    A,(HL)              Pobierz bieżący znak.
                  CP    +3A                 Skocz naprzód, jeśli jest nim ':',
                  JR    Z,1DA3,LOOK-P-2     co będzie oznaczało, że w bieżącym wierszu
                                            znajduje się więcej rozkazów.

Teraz zostaje rozpoczęta pętla, która zbada każdy kolejny wiersz w programie.

1D8B LOOK-P-1     INC   HL                  Pobierz starszy bajt
                  LD    A,(HL)              numeru wiersza i wróć z
                  AND   +CO                 ustawionym przeniesieniem, jeśli
                  SCF                       w programie nie ma dalszych wierszy.
                  RET   NZ
                  LD    B,(HL)              Numer wiersza zostaje pobrany
                  INC   HL                  i przekazany do NEWPPC.
                  LD    C,(HL)
                  LD    (NEWPPC),BC
                  INC   HL                  Następnie zostaje pobrana długość.
                  LD    C,(HL)
                  INC   HL
                  LD    B,(HL)
                  PUSH  HL                  Wskaźnik jest zapamiętywany podczas
                  ADD   HL,BC               tworzenia adresu końca wiersza
                  LD    B,H                 w parze rejestrów BC.
                  LD    C,L
                  POP   HL                  Wskaźnik jest odtwarzany.
                  LD    D,+00               Ustaw licznik rozkazów na zero.
1DA3 LOOK-P-2     PUSH  BC                  Wskaźnik końca wiersza jest zapamiętywany
                  CALL  198B,EACH-STMT      podczas sprawdzania rozkazów w wierszu.
                  POP   BC
                  RET   NC                  Powróć, jeśli wystąpił poszukiwany rozkaz;
                  JR    1D8B,LOOK-P-1       inaczej rozważ następny wiersz.

PROCEDURA ROZKAZU 'NEXT'

'Przypisywana zmienna' została już określona (zobacz CLASS-04,1C6C); pozostaje zmiana WARTOŚCI wg wymagań.

1DAB NEXT         BIT   1,(FLAGX)           Jeśli zmienna nie została znaleziona,
                  JP    NZ,1C2E,REPORT-2    to skocz do raportu błędu.
                  LD    HL,(DEST)           Adres zmiennej zostaje pobrany
                  BIT   7,(HL)              a nazwa jest dalej testowana.
                  JR    Z,1DD8,REPORT-1

Następnie WARTOŚĆ i KROK zmiennej są przetwarzane przez kalkulator.

                  INC   HL                  Przejdź poza nazwę.
                  LD    (MEM),HL            Uczyń zmienną tymczasowym 'obszarem pamięci'
                  RST   0028,FP-CALC        -
                  DEFB  +E0,get-mem-0       w
                  DEFB  +E2,get-mem-2       w, k
                  DEFB  +0F,addition        w+k
                  DEFB  +C0,st-mem-0        w+k
                  DEFB  +02,delete          -
                  DEFB  +38,end-calc        -

Wynik dodawania WARTOŚCI i KROKU jest teraz sprawdzany z GRANICĄ przez wywołanie NEXT-LOOP.

                  CALL  1DDA,NEXT-LOOP      Sprawdź nową WARTOŚĆ z GRANICĄ.
                  RET   C                   Powreóć, jeśli pętla FOR-NEXT
                                            została ukończona.

Inaczej zbierz numer wiersza i rozkazu początku pętli.

                  LD    HL,(MEM)            Znajdź adres młodszego bajtu
                  LD    DE,+000F            początkowego numeru wiersza.
                  ADD   HL,DE
                  LD    E,(HL)              Teraz pobierz ten numer wiersza.
                  INC   HL
                  LD    D,(HL)
                  INC   HL
                  LD    H,(HL)              A za nim numer rozkazu.
                  EX    DE,HL               Wymień te numery przed
                  JP    1E73,GO-TO-2        skokiem naprzód, aby zostały potraktowane
                                            jak wiersz docelowy rozkazu GO TO.

Raport 1 - NEXT bez FOR

1DD8 REPORT-1     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +00

PROCEDURA 'NEXT-LOOP'

Ta procedura jest używana do określenia, czy GRANICA przekroczyła bieżącą WARTOŚĆ. Procedura musi sprawdzać znak KROKU.

Jeśli GRANICA jest przekroczona, procedura wraca z ustawionym znacznikiem przeniesienia.

1DDA NEXT-LOOP    RST   0028,FP-CALC        -
                  DEFB  +E1,get-mem-1       g
                  DEFB  +E0,get-mem-0       g, w
                  DEFB  +E2,get-mem-2       g, w, k
                  DEFB  +36,less-0          g, w,(1/0)
                  DEFB  +00,jump-true       g, w,(1/0)
                  DEFB  +02,to NEXT-1       g, w,(1/0)
                  DEFB  +01,exchange        w, g
1DE2 NEXT-1       DEFB  +03,subtract        w-g lub g-w
                  DEFB  +37,greater-0       (1/0)
                  DEFB  +00,jump-true       (1/0)
                  DEFB  +04,to NEXT-2       -
                  DEFB  +38,end-calc        -
                  AND   A                   Wyczyść znacznik przeniesienia
                  RET                       i powróć - pętla jest możliwa.

Jednakże, gdy pętla nie jest możliwa, znacznik przeniesienia musi być ustawiony.

1DE9 NEXT-2       DEFB  +38,end-calc        -
                  SCF                       Ustaw znacznik przeniesienia
                  RET                       i powróć.

PROCEDURA ROZKAZU 'READ'

Rozkaz READ pozwala odczytywać listę DATA i posiada efekt podobny do ciągu rozkazów LET.

Każde przypisanie w pojedynczym rozkazie READ jest obsługiwane kolejno. Zmienna systemowa X-PTR używana jest do przechowywania wskaźnika rozkazu READ, podczas gdy CH-ADD używane jest do przechodzenia przez listę DATA.

1DEC READ-3       RST   0020,NEXT-CHAR      Wróć tutaj przy każdym obiegu po pierwszym,
                                            aby przejść wzdłuż rozkazu READ.
1DED READ         CALL  1C1F,CLASS-01       Sprawdź, czy zmienna była wcześniej użyta;
                                            jeśli tak, to ją odszukaj.
                  CALL  2530,SYNTAX-Z       Skocz naprzód, jeśli jest sprawdzana
                  JR    Z,1E1E,READ-2       składnia.
                  RST   0018,GET-CHAR       Zapamiętaj bieżący wskaźnik
                  LD    (X-PTR),HL          CH-ADD w X-PTR.
                  LD    HL,(DATADD)         Pobierz wskaźnik do bieżącej listy DATA
                  LD    A,(HL)              i skocz naprzód, chyba że
                  CP    +2C                 musi być znaleziony następny
                  JR    Z,1E0A,READ-1       rozkaz DATA.
                  LD    E,+E4               Szukanie 'DATA'.
                  CALL  1D86,LOOK-PROG      Skocz naprzód, jeśli szukanie się
                  JR    NC,1E0A,READ-1      powiodło.

Raport E - Brak danych w DATA

1E08 REPORT-E     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +0D

Kontynuacja – pobieranie wartości z listy DATA.

1E0A READ-1       CALL  0077,TEMP-PTR1      Przesuń wskaźnik wzdłuż
                                            listy DATA i ustaw CH-ADD.
                  CALL  1C56,VAL-FET-1      Pobierz wartość i przypisz ją zmiennej.
                  RST   0018,GET-CHAR       Pobierz bieżącą wartość
                  LD    (DATADD),HL         CH-ADD i zapisz ją w DATADD.
                  LD    HL,(X-PTR)          Pobierz wskaźnik rozkazu
                  LD    (X-PTR-hi),+00      READ i wyczyść X-PTR.
                  CALL  0078,TEMP-PTR2      Ustaw CH-ADD ponownie na rozkaz READ.
1E1E READ-2       RST   0018,GET-CHAR       Pobierz bieżący znak i sprawdź,
                  CP    +2C                 czy jest to ','.
                  JR    Z,1DEC,READ-3       Jeśli tak, to skocz wstecz, ponieważ
                                            są jeszcze dalsze elementy;
                  CALL  1BEE,CHECK-END      inaczej wróć poprzez
                  RET                       CHECK-END (jeśli sprawdza się składnię)
                                            lub wykonaj instrukcję RET (do STMT-RET).

PROCEDURA ROZKAZU 'DATA'

Podczas sprawdzania składni rozkaz DATA jest sprawdzany, aby upewnić się, że zawiera poprawne wyrażenia rozdzielone przecinkami. W czasie wykonania rozkaz ten jest pomijany.

1E27 DATA         CALL  2530,SYNTAX-Z       Skocz naprzód o ile nie jest
                  JR    NZ,1E37,DATA-2      sprawdzana składnia.

Teraz następuje wejście do pętli, które obsługuje każde wyrażenie w rozkazie DATA.

1E2C DATA-1       CALL  24FB,SCANNING       Skanuj następne wyrażenie.
                  CP    +2C                 Sprawdź, czy jest poprawny separator - ',';
                  CALL  NZ,1BEE,CHECK-END   lecz przejdź do następnego rozkazu, jeśli
                                            porównanie się nie powiodło
                  RST   0020,NEXT-CHAR      Gdy są wciąż nieprzeglądnięte wyrażenia,
                  JR    1E2C,DATA-1         wracaj na początek pętli.

W czasie wykonania rozkaz DATA musi być pominięty.

1E37 DATA-2       LD    A,+E4               Należy pominąć rozkaz 'DATA'.

PROCEDURA 'PASS-BY'

Na wejściu rejestr A zawiera albo kod rozkazu DATA, albo kod rozkazu DEF FN w zależności od typu rozkazu, który ma zostać pominięty.

1E39 PASS-BY      LD    B,A                 Do pary rejestrów BC wpisz bardzo dużą liczbę.
                  CPDR                      Szukaj wstecz kodu rozkazu.
                  LD    DE,+0200            Teraz szukaj wzdłuż wiersza
                  JP    198B,EACH-STMT      następnego rozkazu. (rozkaz numer 'D-1'th
                                            od bieżącej pozycji).

PROCEDURA ROZKAZU 'RESTORE'

Parametrem rozkazu RESTORE jest numer wiersza. Jeśli go nie podano, zostanie użyty numer zero.

Punkt wejścia REST-RUN jest używany przez procedurę rozkazu RUN.

1E42 RESTORE      CALL  1E99,FIND-INT2      Wstaw parametr do pary rejestrów BC.
1E45 REST-RUN     LD    H,B                 Przenieś wynik do
                  LD    L,C                 pary rejestrów HL.
                  CALL  196E,LINE-ADDR      Teraz odszukaj adres tego
                                            wiersza lub pierwszego za nim.
                  DEC   HL                  Ustaw DATADD na pozycję poprzedzającą
                  LD    (DATADD),HL         ten adres.
                  RET                       Gdy skończone, powróć.

PROCEDURA ROZKAZU 'RANDOMIZE'

Jeśli z rozkazem występuje parametr, to zostaje on umieszczony w parze rejestrów BC, a następnie przesłany do odpowiedniej zmiennej systemowej. Jednakże, jeśli parametr ma wartość zero, to zamiast niego będzie użyta zawartość zmiennych FRAMES1 i FRAMES2.

1E4F RANDOMIZE    CALL  1E99,FIND-INT2      Pobierz parametr.
                  LD    A,B                 Skocz naprzód o ile
                  OR    C                   wartość parametru nie wynosi zero.
                  JR    NZ,1E5A,RAND-1
                  LD    BC,(FRAMES1)        Zamiast tego pobierz dwa młodsze bajty
                                            zmiennej systemowej FRAMES.
1E5A RAND-1       LD    (SEED),BC           Teraz umieść wynik w zmiennej SEED
                  RET                       i powróć.

PROCEDURA ROZKAZU 'CONTINUE'

Numer wiersza oraz numer rozkazu w wierszu są wykorzystywane do wykonania skoku.

1E5F CONTINUE     LD    HL,(OLDPPC)         Numer wiersza.
                  LD    D,(OSPPC)           Numer rozkazu w wierszu.
                  JR    1E73,GO-TO-2        Skocz naprzód.

PROCEDURA ROZKAZU 'GO TO'

Argument rozkazu GO TO powinien być numerem wiersza w zakresie od 1 do 9999, lecz faktyczny test sprawdza górną wartość 61439.

1E67 GO-TO        CALL  1E99,FIND-INT2      Pobierz argument i przekaż go
                  LD    H,B                 do pary rejestrów HL.
                  LD    L,C
                  LD    D,+00               Ustaw numer rozkazu na zero.
                  LD    A,H                 Zgłoś błąd
                  CP    +F0                 - liczba całkowita poza zakresem -
                  JR    NC,1E9F,REPORT-B    dla numerów wierszy większych od '61439'

Punkt wejścia GO-TO-2 jest używany do określania numeru następnego wiersza, który ma zostać obsłużony w niektórych okolicznościach.

1E73 GO-TO-2      LD    (NEWPPC),HL         Wprowadź numer wiersza
                  LD    (NSPPC),D           a następnie numer rozkazu.
                  RET                       Powróć do STMT-RET.

PROCEDURA ROZKAZU 'OUT'

Dwa parametry rozkazu OUT są pobierane ze stosu kalkulatora i używane zgodnie z ich przeznaczeniem.

1E7A OUT          CALL  1E85,TWO-PARAM      Pobranie parametrów.
                  OUT   (C),A               Właściwa instrukcja OUT.
                  RET                       Powróć do STMT-RET.

PROCEDURA ROZKAZU 'POKE'

W podobny sposób zostaje wykonany rozkaz POKE.

1E80 POKE         CALL  1E85,TWO-PARAM      Pobranie parametrów.
                  LD    (BC),A              Właściwa operacja POKE.
                  RET                       Powrót do STMT-RET.

PROCEDURA 'TWO-PARAM'

Parametr na szczycie stosu musi dać się załadować do pojedynczego rejestru. Jeśli jest ujemny, to zostanie poddany negacji z uzupełnieniem do dwóch. Drugi parametr musi dać się załadować do pary rejestrów.

1E85 TWO-PARAM    CALL  2DD5,FP-TO-A        Pobranie parametru.
                  JR    C,1E9F,REPORT-B     Zgłoś błąd, jeśli ma zbyt dużą wartość.
                  JR    Z,1E8E,TWO-P-1      Skocz naprzód przy dodatnich
                  NEG                       liczbach, lecz ujemne zaneguj.
1E8E TWO-P-1      PUSH  AF                  Zapamiętaj pierwszy parametr
                  CALL  1E99,FIND-INT2      podczas pobierania drugiego.
                  POP   AF                  Odtwórz pierwszy parametr
                  RET                       przed powrotem.

PROCEDURA 'ZNAJDOWANIA LICZB CAŁKOWITYCH'

'Ostatnia wartość' na stosie kalkulatora zostaje pobrana odpowiednio do rejestru lub do pary rejestrów w zależności od użytego punktu wejścia FIND-INT1 lub FIND-INT2.

1E94 FIND-INT1    CALL  2DD5,FP-TO-A        Pobierz ostatnią wartość.
                  JR    1E9C,FIND-I-1       Skocz naprzód.
1E99 FIND-INT2    CALL  2DA2,FP-TO-BC       Pobierz ostatnią wartość.
1E9C FIND-I-1     JR    C,1E9F,REPORT-B     W obu przypadkach przepełnienie
                                            jest oznaczane ustawieniem znacznika przeniesienia.
                  RET   Z                   Wróć ze wszystkimi liczbami dodatnimi,
                                            które są w odpowiednim zakresie.

Raport B - Liczba całkowita poza zakresem

1E9F REPORT-B     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów
                  DEFB  +0A

PROCEDURA ROZKAZU 'RUN'

Parametr rozkazu RUN jest umieszczany w NEWPPC przez wywołanie procedury rozkazu GO TO. Następnie są wykonywane operacje 'RESTORE 0' i 'CLEAR 0' przed powrotem.

1EA1 RUN          CALL  1E67,GO-TO          Ustaw odpowiednio NEWPPC.
                  LD    BC,+0000            Teraz wykonaj 'RESTORE 0'.
                  CALL  1E45,REST-RUN
                  JR    1EAF,CLEAR-1        Powróć poprzez procedurę rozkazu CLEAR.

PROCEDURA ROZKAZU 'CLEAR'

Procedura ta czyści obszar zmiennych oraz ekran i przesuwa RAMTOP. W wyniku ostatniej operacji zostaje przebudowany stos maszynowy procesora, co daje efekt wyczyszczenia również stosu GO SUB.

1EAC CLEAR        CALL  1E99,FIND-INT2      Pobierz parametr - używając standardowo zera.
1EAF CLEAR-RUN    LD    A,B                 Skocz naprzód, jeśli parametr jest różny
                  OR    C                   od zera. Gdy wywołanie nastąpiło z
                  JR    NZ,1EB7,CLEAR-1     rozkazu RUN, to nie ma skoku.
                  LD    BC,(RAMTOP)         Jeśli mamy zero, użyj istniejącej wartości RAMTOP.
1EB7 CLEAR-1      PUSH  BC                  Zapamiętaj tę wartość.
                  LD    DE,(VARS)           Następnie odzyskaj wszystkie bajty
                  LD    HL,(E-LINE)         bieżącego obszaru zmiennych.
                  DEC   HL
                  CALL  19E5,RECLAIM-1
                  CALL  0D6B,CLS            Wyczyść obszar wyświetlania.

Wartość w parze rejestrów BC, która zostanie użyta jako RAMTOP, podlega testowi, czy nie jest zbyt mała lub zbyt duża.

                  LD    HL,(STKEND)         Bieżąca wartość STKEND.
                  LD    DE,+0032            jest zwiększana o 50 przed testowaniem.
                  ADD   HL,DE               Tworzy to dolną granicę.
                  POP   DE
                  SBC   HL,DE
                  JR    NC,1EDA,REPORT-M    RAMTOP jest zbyt małe.
                  LD    HL,(P-RAMT)         Przy teście górnej granicy dla RAMTOP
                  AND   A                   zostaje ono porównane z
                  SBC   HL,DE               P-RAMT.
                  JR    NC,1EDC,CLEAR-2     Skocz naprzód, jeśli wartość jest akceptowalna.

Raport M - złe RAMTOP

1EDA REPORT-M     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędu.
                  DEFB  +15

Kontynuuj operację CLEAR.

1EDC CLEAR-2      EX    DE,HL               Teraz ta wartość może zostać w końcu
                  LD    (RAMTOP),HL         umieszczona w RAMTOP.
                  POP   DE                  Pobierz adres - STMT-RET.
                  POP   BC                  Pobierz 'adres błędu'.
                  LD    (HL),+3E            Wprowadź znacznik końca stosu GO SUB.
                  DEC   HL                  Pozostaw jedną komórkę.
                  LD    SP,HL               Ustaw wskaźnik stosu
                                            na pusty stos GO SUB.
                  PUSH  BC                  Następnie przekaż 'adres błędu'
                  LD    (ERR-SP),SP         na stos i zapisz jego adres w ERR-SP.
                  EX    DE,HL               Zostaje wykonany pośredni powrót
                  JP    (HL)                do STMT-RET.

Uwaga: Gdy procedura ta jest wywoływana z RUN, to wartości NEWPPC i NSPPC zostaną zniszczone i żadne polecenie za rozkazem RUN nigdy nie będzie znalezione przed wykonaniem skoku.

PROCEDURA ROZKAZU 'GO SUB'

Na stosie GO SUB zostają umieszczone bieżąca wartość PPC oraz zwiększona o 1 wartość SUBPPC.

1EED GO-SUB       POP   DE                  Zapisz adres - STMT-RET.
                  LD    H,(SUBPPC)          Pobierz numer rozkazu w wierszu
                  INC   H                   i zwiększ go.
                  EX    (SP),HL             Wymień 'adres błędu'
                                            z numerem rozkazu.
                  INC   SP                  Zwróć jeden adres.
                  LD    BC,(PPC)            Teraz zapisz bieżący numer wiersza.
                  PUSH  BC
                  PUSH  HL                  Zwróć 'adres błędu'
                  LD    (ERR-SP),SP         na stos maszynowy i zresetuj
                                            ERR-SP, aby wskazywało na niego.
                  PUSH  DE                  Wróć pod adres - STMT-RET.
                  CALL  1E67,GO-TO-1        Teraz ustaw NEWPPC i NSPPC na pożądane wartości.
                  LD    BC,+0014            Lecz przed skokiem sprawdź miejsce.

PROCEDURA 'TESTOWANIA MIEJSCA'

Wykonane zostaje kilka testów, aby się upewnić, że jest wystarczająca ilość pamięci na wykonywane zadanie.

1F05 TEST-ROOM    LD    HL,(STKEND)         Zwiększ wartość pobraną z
                  ADD   HL,BC               STKEND o wartość przyniesioną
                                            do procedury w parze rejestrów BC.
                  JR    C,1F15,REPORT-4     Skocz naprzód, jeśli wynik jest większy od +FFFF.
                  EX    DE,HL               Spróbuj jeszcze raz, zostawiając
                  LD    HL,+0050            kolejne osiemdziesiąt bajtów.
                  ADD   HL,DE
                  JR    C,1F15,REPORT-4
                  SBC   HL,SP               Na koniec sprawdź tę wartość z adresem
                                            stosu maszynowego.
                  RET   C                   Jeśli wszystko OK, powróć.

Raport 4 - Brak pamięci

1F15 REPORT-4     LD    L,+03               To jest błąd czasu wykonania
                  JP    0055,ERROR-3        i znacznik błędu nie będzie użyty.

PROCEDURA 'ILOŚCI WOLNEJ PAMIĘCI'

Nie istnieje rozkaz FRE języka BASIC w SPECTRUM, lecz jest procedura wykonująca takie zadanie.

Oszacowanie ilości wolnej przestrzeni można zawsze uzyskać za pomocą polecenia:

PRINT 65536-USR 7962

1F1A FREE-MEM     LD    BC,+0000            Nie zwiększaj zajętości pamięci.
                  CALL  1F05,TEST-ROOM      Zrób test i przenieś
                  LD    B,H                 wynik do pary rejestrów BC
                  LD    C,L                 przed powrotem.
                  RET

PROCEDURA ROZKAZU 'RETURN'

Numer wiersza oraz numer rozkazu, pod które należy wykonać powrót, zostają pobrane ze stosu GO SUB.

1F23 RETURN       POP   BC                  Pobierz adres - STMT-RET.
                  POP   HL                  Pobierz 'adres błędu'.
                  POP   DE                  Pobierz ostatni element ze stosu GO SUB.
                  LD    A,D                 Sprawdzane jest, czy pobrany element
                  CP    +3E                 jest znacznikiem końca stosu GO SUB.
                  JR    Z,1F36,REPORT-7     Skocz, jeśli tak.
                  DEC   SP                  Pełny element używa tylko trzech komórek.
                  EX    (SP),HL             Zamień numer rozkazu z 'adresem błędu'.
                  EX    DE,HL               Przenieś numer rozkazu.
                  LD    (ERR-SP),SP         Resetuj wskaźnik błędu.
                  PUSH  BC                  Zastąp adres - STMT-RET.
                  JP    1E73,GO-TO-2        Skocz wstecz, aby zmienić NEWPPC i NSPPC.

Raport 7 - RETURN bez GOSUB

1F36 REPORT-7     PUSH  DE                  Zamień znacznik końca
                  PUSH  HL                  i 'adres błędu'.
                  RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +06

PROCEDURA ROZKAZU 'PAUSE'

Okres dla rozkazu PAUSE zostaje określony przez zliczanie przerwań maskowanych, które występują co 1/50 sekundy.

Pauza kończy się po wystąpieniu odpowiedniej liczby tych przerwań lub gdy zmienna systemowa FLAGS sygnalizuje naciśnięcie klawisza.

1F3A PAUSE        CALL  1E99,FIND-INT2      Pobierz parametr.
1F3D PAUSE-1      HALT                      Czekaj na przerwanie maskowane.
                  DEC   BC                  Zmniejsz o 1 licznik.
                  LD    A,B                 Jeśli w ten sposób licznik
                  OR    C                   osiągnie wartość zero, to rozkaz PAUSE
                  JR    Z,1F4F,PAUSE-END    dobiegł do końca.
                  LD    A,B                 Jeśli argument miał wartość 0,
                  AND   C                   to teraz para rejestrów BC będzie zawierać +FFFF 
                  INC   A                   i ta wartość zostanie sprowadzona do zera.
                  JR    NZ,1F49,PAUSE-2     Skocz przy wszystkich innych wartościach parametru.
                  INC   BC                  Zeruj BC.
1F49 PAUSE-2      BIT   5,(FLAGS)           Skocz wstecz o ile nie został
                  JR    Z,1F3D,PAUSE-1      naciśnięty klawisz.

Okres rozkazu PAUSE już minął.

1F4F PAUSE-END    RES   5,(FLAGS)           Sygnalizuj 'brak naciśniętego klawisza'.
                  RET                       Teraz powróć do STMT-RET.

PROCEDURA 'KLAWISZA BREAK'

Ta procedura jest wywoływana w kilku przypadkach do odczytu klawisza BREAK. Znacznik przeniesienia jest zwracany w stanie wyzerowanym tylko wtedy, gdy jednocześnie są wciśnięte klawisze SHIFT i BREAK.

1F54 BREAK-KEY    LD    A,+7F               Utwórz adres portu
                  IN    A,(+FE)             +7FFE i wczytaj z niego bajt.
                  RRA                       Testuj tylko bit 0, przesuwając go
                                            na pozycję znacznika przeniesienia.
                  RET   C                   Wróć, gdy jest naciśnięty klawisz BREAK.
                  LD    A,+FE               Utwórz adres portu
                  IN    A,(+FE)             +FEFE i wczytaj z niego bajt.
                  RRA                       Ponownie sprawdź bit 0.
                  RET                       Wróć z wyzerowanym przeniesieniem, jeśli
                                            oba klawisze są wciśnięte.

PROCEDURA ROZKAZU 'DEF FN'

Podczas sprawdzania składni rozkaz DEF FN jest sprawdzany, aby upewnić się, że posiada poprawną postać. Tworzone jest również miejsce na wynik obliczania funkcji.

Lecz w czasie uruchomienia rozkaz DEF FN jest pomijany.

1F60 DEF-FN       CALL  2530,SYNTAX-Z       Skocz naprzód przy sprawdzaniu składni.
                  JR    Z,1F6A,DEF-FN-1
                  LD    A,+CE               Inaczej pomiń rozkaz 'DEF FN'.
                  JP    1E39,PASS-BY

Najpierw rozważ zmienną funkcji.

1F6A DEF-FN-1     SET   6,(FLAGS)           Sygnalizuj 'zmienna liczbowa'.
                  CALL  2C8D,ALPHA          Sprawdź, czy obecny kod jest literą.
                  JR    NC,1F89,DEF-FN-4    Skocz naprzód, jeśli nie jest.
                  RST   0020,NEXT-CHAR      Pobierz następny znak.
                  CP    +24                 Skocz naprzód, jeśli nie jest nim
                  JR    NZ,1F7D,DEF-FN-2    znak '$'.
                  RES   6,(FLAGS)           Zmień bit 6, ponieważ jest to zmienna łańcuchowa.
                  RST   0020,NEXT-CHAR      Pobierz następny znak..
1F7D DEF-FN-2     CP    +28                 Znak '(' musi wystąpić za
                  JR    NZ,1FBD,DEF-FN-7    nazwą zmiennej.
                  RST   0020,NEXT-CHAR      Pobierz następny znak..
                  CP    +29                 Skocz naprzód, jeśli jest nim
                  JR    Z,1FA6,DEF-FN-6     ')', ponieważ funkcja nie ma parametrów.

Teraz następuje wejście do pętli, która przetwarza kolejno każdy parametr.

1F86 DEF-FN-3     CALL  2C8D,ALPHA          Obecny kod musi być
1F89 DEF-FN-4     JP    NC,1C8A,REPORT-C    literą.
                  EX    DE,HL               Zapisz wskaźnik w DE.
                  RST   0020,NEXT-CHAR      Pobierz następny znak..
                  CP    +24                 Skocz naprzód, jeśli nie jest nim
                  JR    NZ,1F94,DEF-FN-5    znak '$'.
                  EX    DE,HL               Inaczej zapisz nowy wskaźnik w DE.
                  RST   0020,NEXT-CHAR      Pobierz następny znak..
1F94 DEF-FN-5     EX    DE,HL               Przesuń wskaźnik ostatniego znaku
                                            nazwy do pary rejestrów HL.
                  LD    BC,+0006            Teraz zarezerwuj sześć komórek
                  CALL  1655,MAKE-ROOM      za tym ostatnim znakiem
                  INC   HL                  i umieść 'znacznik liczby' w
                  INC   HL                  pierwszej z zarezerwowanych komórek.
                  LD    (HL),+0E
                  CP    +2C                 Jeśli bieżącym znakiem jest
                  JR    NZ,1FA6,DEF-FN-6    ',', to skocz wstecz, ponieważ
                  RST   0020,NEXT-CHAR      powinien wystąpić kolejny parametr;
                  JR    1F86,DEF-FN-3       inaczej wyjdź z pętli.

Teraz zostaje rozważona definicja funkcji.

1FA6 DEF-FN-6     CP    +29                 Sprawdź, że istnieje znak ')'.
                  JR    NZ,1FBD,DEF-FN-7
                  RST   0020,NEXT-CHAR      Zostaje pobrany następny znak.
                  CP    +3D                 Musi to być znak '='.
                  JR    NZ,1FBD,DEF-FN-7
                  RST   0020,NEXT-CHAR      Pobierz następny znak.
                  LD    A,(FLAGS)           Zapamiętaj naturę zmiennej: numeryczna lub znakowa.
                  PUSH  AF
                  CALL  2F4B,SCANNING       Teraz rozważ definicję wyrażenia.
                  POP   AF                  Pobierz naturę zmiennej
                  XOR   (FLAGS)             i sprawdź, czy ma ona ten sam typ
                  AND   +40                 jak ten znaleziony dla definicji.
1FBD DEF-FN-7     JP    NZ,1C8A,REPORT-C    Jeśli trzeba, utwórz raport błędów.
                  CALL  1BEE,CHECK-END      Wyjdź poprzez procedurę CHECK-END.
                                            (W ten sposób nastąpi przejście do
                                            przetwarzania kolejnego rozkazu w wierszu.)

PROCEDURA 'UNSTACK-Z'

Ta procedura jest wywoływana w kilku sytuacjach w celu 'wcześniejszego powrotu' z procedury, gdy jest sprawdzana składnia. Powodem jego istnienia jest właściwie unikanie drukowania znaków lub przekazywania wartości z/na stos kalkulatora.

1FC3 UNSTACK-Z    CALL  2530,SYNTAX-Z       Czy jest sprawdzana składnia?
                  POP   HL                  Pobierz adres powrotu, lecz zignoruj go
                  RET   Z                   'w czasie sprawdzania składni'.
                  JP    (HL)                'W czasie uruchomienia' wykonaj prosty
                                            powrót do wywołującej procedury.

PROCEDURY ROZKAZÓW 'LPRINT I PRINT'

Zostaje otwarty właściwy kanał, a elementy do wydruku zostają kolejno przetworzone.

1FC9 LPRINT       LD    A,+03               Przygotuj się do otwarcia kanału 'P'.
                  JR    1FCF,PRINT-1        Skocz naprzód.
1FCD PRINT        LD    A,+02               Przygotuj się do otwarcia kanału 'S'.
1FCF PRINT-1      CALL  2530,SYNTAX-Z       Otwórz kanał, o ile nie jest
                  CALL  NZ,1601,CHAN-OPEN   sprawdzana składnia.
                  CALL  0D4D,TEMPS          Ustaw zmienne systemowe kolorów tymczasowych.
                  CALL  1FDF,PRINT-2        Wywołaj procedurę zarządzającą wydrukiem.
                  CALL  1BEE,CHECK-END      Przejdź do obsługi następnego rozkazu;
                  RET                       przy sprawdzaniu składni poprzez CHECK-END.

Procedura zarządzająca wydrukiem jest wywoływana przez procedury rozkazów PRINT, LPRINT i INPUT.

1FDF PRINT-2      RST   0018,GET-CHAR       Pobierz pierwszy znak.
                  CALL  2045,PR-END-Z       Skocz naprzód, jeśli jest
                  JR    Z,1FF2,PRINT-4      koniec listy elementów.

Teraz wejdź do pętli, aby przetworzyć znaki sterujące pozycją oraz elementy wydruku.

1FE5 PRINT-3      CALL  204E,PR-POSN-1      Przetwarzaj wszystkie kolejne znaki
                  JR    Z,1FE5,PRINT-3      sterujące pozycją.
                  CALL  1FFC,PR-ITEM-1      Przetwórz pojedynczy element wydruku.
                  CALL  204E,PR-POSN-1      Sprawdzaj, czy występują dalsze znaki
                  JR    Z,1FE5,PRINT-3      sterujące pozycją oraz elementy wydruku
                                            aż nie zostanie żaden z nich.
1FF2 PRINT-4      CP    +29                 Wróć teraz, jeśli obecnym
                  RET   Z                   znakiem jest ')'; inaczej rozważ
                                            wykonanie 'powrotu karetki'.

PROCEDURA 'WYDRUKU POWROTU KARETKI'

1FF5 PRINT-CR     CALL  1FC3,UNSTACK-Z      Wróć przy sprawdzaniu składni.
                  LD    A,+0D               Drukuj znak powrotu karetki,
                  RST   0010,PRINT-A-1      a później wróć.
                  RET

PROCEDURA 'ELEMENTÓW ROZKAZU PRINT'

Ta procedura jest wywoływana z procedur rozkazów PRINT, LPRINT i INPUT.

Zostają rozpoznane i wydrukowane różne rodzaje elementów rozkazu PRINT.

1FFC PR-ITEM-1    RST   0018,GET-CHAR       Pobierany jest pierwszy znak.
                  CP    +AC                 Skocz naprzód, jeśli
                  JR    NZ,200E,PR-ITEM-2   nie jest to 'AT'.

Teraz zajmij się 'AT'.

                  CALL  1C79,NEXT-2NUM      Na stos kalkulatora zostają przesłane
                                            dwa parametry.
                  CALL  1FC3,UNSTACK-Z      Wróć teraz przy sprawdzaniu składni.
                  CALL  2307,STK-TO-BC      Parametry zostają skompresowane
                                            do pary rejestrów BC.
                  LD    A,+16               Rejestr A zostaje załadowany znakiem
                  JR    201E,PR-AT-TAB      sterującym AT przed wykonaniem skoku.

Teraz sprawdź 'TAB'.

200E PR-ITEM-2    CP    +AD                 Skocz naprzód, jeśli
                  JR    NZ,2024,PR-ITEM-3   nie jest to 'TAB'.

Zajmij się 'TAB'.

                  RST   0020,NEXT-CHAR      Pobierz następny znak.
                  CALL  1C82,EXPT-1NUM      Prześlij jeden parametr na stos kalkulatora.
                  CALL  1FC3,UNSTACK-Z      Wróć teraz przy sprawdzaniu składni.
                  CALL  1E99,FIND-INT2      Wartość jest kompresowana do pary rejestrów BC.
                  LD    A,+17               Rejestr A zostaje załadowany znakiem 'TAB'.

Zostają wydrukowane elementy wydruku 'AT' i 'TAB' przez trzy wywołania procedury PRINT-OUT.

201E PR-AT-TAB    RST   0010,PRINT-A-1      Drukuj znak sterujący.
                  LD    A,C                 Za nim pierwsza wartość.
                  RST   0010,PRINT-A-1
                  LD    A,B                 Na końcu druga wartość;
                  RST   0010,PRINT-A-1
                  RET                       i powróć.

Teraz zajmij się osadzonymi elementami koloru.

2024 PR-ITEM-3    CALL  21F2,CO-TEMP-3      Wróć z wyzerowanym przeniesieniem, jeśli
                                            został znaleziony element koloru.
                  RET   NC                  Kontynuuj, jeśli nie było żadnego.
                  CALL  2070,STR-ALTER      Teraz sprawdź, czy ma zostać zmieniony strumień.
                  RET   NC                  Kontynuuj, chyba że był zmieniony.

Element wydruku musi teraz być wyrażeniem liczbowym lub łańcuchowym.

                  CALL  24FB,SCANNING       Oblicz wyrażenie, lecz
                  CALL  1FC3,UNSTACK-Z      wróć teraz przy sprawdzaniu składni.
                  BIT   6,(FLAGS)           Testuj rodzaj wyrażenia.
                  CALL  Z,2BF1,STK-FETCH    Jeśli jest to łańcuch, to pobierz
                                            niezbędne parametry; lecz przy wyrażeniu
                  JP    NZ,2DE3,PRINT-FP    liczbowym wyjdź poprzez PRINT-FP.

Zostaje teraz ustawiona pętla do przetworzenia po kolei każdego znaku łańcucha.

203C PR-STRING    LD    A,B                 Wróć teraz, jeśli nie pozostały
                  OR    C                   żadne znaki w łańcuchu;
                  DEC   BC                  inaczej zmniejsz licznik.
                  RET   Z
                  LD    A,(DE)              Pobierz kod i zwiększ wskaźnik.
                  INC   DE
                  RST   0010,PRINT-A-1      Kod zostaje wydrukowany, po czym jest robiony
                  JR    203C,PR-STRING      skok do przetworzenia dalszych znaków.

PROCEDURA 'KOŃCA WYDRUKU'

Znacznik zera będzie ustawiony, jeśli wydruk jest skończony.

2045 PR-END-Z     CP    +29                 Wróć teraz, jeśli znakiem jest ')'.
                  RET   Z
2048 PR-ST-END    CP    +0D                 Wróć, jeśli znakiem jest 'powrót karetki'.
                  RET   Z
                  CP    +3A                 Przed powrotem zrób ostatni test na ':'.
                  RET

PROCEDURA 'POZYCJI WYDRUKU'

W procedurze tej są przetwarzane różne znaki sterujące pozycją.

204E PR-POSN-1    RST   0018,GET-CHAR       Pobierz bieżący znak.
                  CP    +3B                 Skocz naprzód, jeśli
                  JR    Z,2067,PR-POSN-3    jest to ';'.
                  CP    +2C                 Również skocz do przodu przy
                  JR    NZ,2061,PR-POSN-2   znaku różnym od ',';
                  CALL  2530,SYNTAX-Z       lecz nie drukuj tego znaku, jeśli
                  JR    Z,2067,PR-POSN-3    jest sprawdzana składnia.
                  LD    A,+06               Załaduj rejestr A znakiem
                  RST   0010,PRINT-A-1      sterującym 'przecinek'
                  JR    2067,PR-POSN-3      i drukuj go; następnie skocz naprzód.
2061 PR-POSN-2    CP    +27                 Znakiem jest '''?
                  RET   NZ                  Wróć teraz, jeśli brak jakichkolwiek
                                            znaków sterujących pozycją.
                  CALL  1FF5,PR-CR          Drukuj 'powrót karetki, chyba że
                                            jest sprawdzana składnia.
2067 PR-POSN-3    RST   0020,NEXT-CHAR      Pobierz następny znak.
                  CALL  2045,PR-END-Z       Jeśli nie osiągnietkokońca rozkazu druku,
                  JR    NZ,206E,PR-POSN-4   to skocz naprzód;
                  POP   BC                  inaczej powróć do
206E PR-POSN-4    CP    A                   procedury wywołującej.
                  RET                       Znacznik zera będzie zresetowany, jeśli
                                            nie został osiągniety koniec rozkazu druku.

PROCEDURA 'ZMIANY STRUMIENIA'

Procedura jest wywoływania w razie potrzeby określenia, czy użytkownik życzy sobie skorzystać z innego strumienia.

2070 STR-ALTER    CP    +23                 Jeśli bieżący znak nie jest znakiem '#',
                  SCF                       to powróć z ustawionym znacznikiem
                  RET   NZ                  przeniesienia.
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  1C82,EXPT-1NUM      Przekaż parametr na stos kalkulatora.
                  AND   A                   Zeruj znacznik przeniesienia.
                  CALL  1FC3,UNSTACK-Z      Wróć teraz, jeśli jest sprawdzana składnia.
                  CALL  1E94,FIND-INT1      Wartość jest przekazywana do rejestru A.
                  CP    +10                 Raport O, jeśli wartość
                  JP    NC,160E,REPORT-O    przekracza +F.
                  CALL  1601,CHAN-OPEN      Użyj tego kanału dla danego strumienia.
                  AND   A                   Wyczyść znacznik przeniesienia
                  RET                       i powróć.

PROCEDURA ROZKAZU 'INPUT'

Ta procedura pozwala przypisać wartości wprowadzone z klawiatury zmiennym. W rozkazie INPUT można również osadzić elementy rozkazu PRINT, które będą drukowane w dolnej części wyświetlacza.

2089 INPUT        CALL  2530,SYNTAX-Z       Skocz naprzód przy sprawdzaniu składni.
                  JR    Z,2096,INPUT-1
                  LD    A,+01               Otwórz kanał 'K'.
                  CALL  1601,CHAN-OPEN
                  CALL  0D6E,CLS-LOWER      Wyczyść spód ekranu.
2096 INPUT-1      LD    (TV-FLAG),+01       Sygnalizuj użycie dolnej części ekranu.
                                            Resetuj pozostałe bity.
                  CALL  20C1,IN-ITEM-1      Wywołaj procedurę obsługi elementów INPUT.
                  CALL  1BEE,CHECK-END      Przejdź do następnego rozkazu
                                            przy sprawdzaniu składni.
                  LD    BC,(S-POSN)         Pobierz bieżącą pozycję druku.
                  LD    A,(DF-SZ)           Skocz naprzód, jeśli pozycja bieżąca
                  CP    B                   jest ponad dolną częścią
                  JR    C,20AD,INPUT-2      ekranu.
                  LD    C,+21               Inaczej ustaw pozycję druku
                  LD    B,A                 na szczyt dolnej części ekranu.
20AD INPUT-2      LD    (S-POSN),BC         Resetuj S-POSN.
                  LD    A,+19               Teraz ustaw licznik przewinięć.
                  SUB   B
                  LD    (SCR-CT),A
                  RES   0,(TV-FLAG)         Sygnalizuj 'główny ekran'.
                  CALL  0DD9,CL-SET         Ustaw zmienne systemowe
                  JP    0D6E,CLS-LOWER      i wyjdź poprzez CLS-LOWER.

Elementy INPUT oraz osadzone elementy PRINT są kolejno obsługiwane przez poniższą pętlę.

20C1 IN-ITEM-1    CALL  204E,PR-POSN-1      Najpierw zajmij się znakami
                  JR    Z,20C1,IN-ITEM-1    sterującymi pozycją.
                  CP    +28                 Skocz naprzód, jeśli bieżącym znakiem
                  JR    NZ,20D8,IN-ITEM-2   nie jest '('.
                  RST   0020,NEXT-CHAR      Pobierz następny znak..
                  CALL  1FDF,PRINT-2        Teraz wywołaj procedurę rozkazu PRINT
                                            w celu obsługi elementów w nawiasach.
                  RST   0018,GET-CHAR       Pobierz bieżący znak.
                  CP    +29                 Zgłoś błąd C, jeśli ten znak
                  JP    NZ,1C8A,REPORT-C    jest różny od ')'.
                  RST   0020,NEXT-CHAR      Pobierz następny znak
                  JP    21B2,IN-NEXT-2      i skocz naprzód w celu sprawdzeni,
                                            występują dalsze elementy INPUT.

Teraz sprawdź, czy zastosowano INPUT LINE.

20D8 IN-ITEM-2    CP    +CA                 Skocz naprzód, jeśli znak
                  JR    NZ,20ED,IN-ITEM-3   jest różny od 'LINE'.
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  1C1F,CLASS-01       Określ adres przeznaczenia dla zmiennej.
                  SET   7,(FLAGX)           Sygnalizuj 'używanie INPUT LINE'.
                  BIT   6,(FLAGS)           Zgłoś błąd C o ile nie jest
                  JP    NZ,1C8A,REPORT-C    używana zmienna łańcuchowa.
                  JR    20FA,IN-PROMPT      Skocz naprzód w celu wyświetlenia
                                            wiadomości ponaglającej.

Zacznij obsługę prostych zmiennych INPUT.

20ED IN-ITEM-3    CALL  2C8D,ALPHA          Skocz w celu sprawdzenia, czy nie będzie
                  JP    NC,21AF-IN-NEXT-1   konieczne ponowne obejście pętli, jeśli
                                            bieżący znak nie jest literą.
                  CALL  1C1F,CLASS-01       Określ adres przeznaczenia dla zmiennej.
                  RES   7,(FLAGX)           Sygnalizuj 'nie INPUT LINE'.

Teraz w obszarze roboczym zostaje utworzona wiadomość ponaglająca.

20FA IN-PROMPT    CALL  2530,SYNTAX-Z       Skocz naprzód przy sprawdzaniu składni.
                  JP    Z,21B2,IN-NEXT-2
                  CALL  16BF,SET-WORK       Przestrzeń robocza jest ustawiana na pustą.
                  LD    HL,+5C71            To jest FLAGX.
                  RES   6,(HL)              Sygnalizuj 'wynik łańcuchowy'.
                  SET   5,(HL)              Sygnalizuj 'tryb INPUT'.
                  LD    BC,+0001            Zezwól wiadomości ponaglającej tylko na
                                            jedną komórkę.
                  BIT   7,(HL)              Skocz naprzód przy stosowaniu 'LINE'.
                  JR    NZ,211C,IN-PR-2
                  LD    A,(FLAGS)           Skocz naprzód przy oczekiwaniu
                  AND   +40                 dane liczbowe.
                  JR    NZ,211A,IN-PR-1
                  LD    C,+03               Dane łańcuchowe będą potrzebowały 3 komórek.
211A IN-PR-1      OR    (HL)                Bit 6 zmiennej FLAGX zostanie ustawiony
                  LD    (HL),A              przy danych liczbowych.
211C IN-PR-2      RST   0030,BC-SPACES      Udostępniane jest wymagane miejsce.
                  LD    (HL),+0D            Znak 'powrót karetki' idzie do
                                            ostatniej komórki.
                  LD    A,C                 Testuj bit 6 rejestru C
                  RRCA                      i skocz naprzód, jeśli jest potrzebna
                  RRCA                      tylko jedna komórka.
                  JR    NC,2129,IN-PR-3
                  LD    A,+22               Znak 'cudzysłowu' idzie do
                  LD    (DE),A              pierwszej i drugiej komórki.
                  DEC   HL
                  LD    (HL),A
2129 IN-PR-3      LD    (K-CUR),HL          Teraz pozycja kursora może być zapamiętana.

W przypadku INPUT LINE program EDITORA może zostać wywołany bez dalszych przygotowań, lecz dla innych trybów pracy rozkazu INPUT należy zmienić stos błędów w celu przechwytywania błędów.

                  BIT   7,(FLAGX)           Skocz naprzód przy 'INPUT
                  JR    NZ,215E,IN-VAR-3    LINE'
                  LD    HL,(CH-ADD)         Zapamiętaj bieżące wartości
                  PUSH  HL                  zmiennych CH-ADD i ERR-SP
                  LD    HL,(ERR-SP)         na stosie maszynowym.
                  PUSH  HL
213A IN-VAR-1     LD    HL,+213A            To będzie 'punkt powrotu'
                  PUSH  HL                  w przypadku błędów.
                  BIT   4,(FLAGS2)          Gdy jest używany kanał 'K',
                  JR    Z,2148,IN-VAR-2     zmień jedynie wskaźnik stosu błędów.
                  LD    (ERR-SP),SP
2148 IN-VAR-2     LD    HL,(WORKSP)         Ustaw HL na początek wiersza INPUT
                  CALL  11A7,REMOVE-FP      i usuń wszelkie formy zmiennoprzecinkowe.
                                            (Nie powinno ich być, jedynie po błędzie.)
                  LD    (ERR-NR),+FF        Sygnalizuj 'jak dotąd bez błędu'.
                  CALL  0F2C,EDITOR         Teraz pobierz rozkaz INPUT i przy
                  RES   7,(FLAGS)           znaczniku FLAGS oznaczającym składnię,
                  CALL  21B9,IN-ASSIGN      sprawdź rozkaz INPUT na błędy;
                  JR    2161,IN-VAR-4       skocz, jeśli w porządku; powróć
                                            do IN-VAR-1, jeśli nie.
215E IN-VAR-3     CALL  0F2C,EDITOR         Pobierz wiersz.

Wszystkie zmienne systemowe muszą zostać zresetowane przed wykonaniem właściwego przypisania.

2161 IN-VAR-4     LD    (K-CUR-hi),+00      Adres kursora jest resetowany.
                  CALL  21D6,IN-CHAN-K      Zostaje wykonany skok przy używaniu
                  JR    NZ,2174,IN-VAR-5    kanał innego niż 'K'.
                  CALL  111D,ED-COPY        Wprowadzany wiersz jest kopiowany
                  LD    BC,(ECHO-E)         na ekran, a pozycja w ECHO-E staje się
                  CALL  0DD9,CL-SET         bieżącą pozycją u dołu ekranu.
2174 IN-VAR-5     LD    HL,+5C71            To jest zmienna FLAGX.
                  RES   5,(HL)              Sygnalizuj 'tryb edycji'.
                  BIT   7,(HL)
                  RES   7,(HL)
                  JR    NZ,219B,IN-VAR-6    Skocz naprzód przy INPUT LINE.
                  POP   HL                  Porzuć adres IN-VAR-1.
                  POP   HL                  Resetuj ERR-SP na
                  LD    (ERR-SP),HL         pierwotny adres.
                  POP   HL                  Zapamiętaj oryginalny adres CH-ADD
                  LD    (X-PTR),HL          adres w X-PTR.
                  SET   7,(FLAGS)           Teraz przy FLAGS oznaczającym wykonanie
                  CALL  21B9,IN-ASSIGN      programu dokonaj przypisania.
                  LD    HL,(X-PTR)          Odtwórz oryginalny adres
                  LD    (X-PTR-hi),+00      w CH-ADD i wyczyść X-PTR.
                  LD    (CH-ADD),HL
                  JR    21B2,IN-NEXT-2      Skocz naprzód, aby sprawdzić,
                                            czy są dalsze elementy INPUT.
219B IN-VAR-6     LD    HL,(STKBOT)         Znaleziona zostaje długość wiersza
                  LD    DE,(WORKSP)         w obszarze roboczym.
                  SCF
                  SBC,  HL,DE
                  LD    B,H                 DE wskazuje na start
                  LD    C,L                 BC zawiera długość.
                  CALL  2AB2,STK-ST-$       Parametry te są umieszczane na stosie
                  CALL  2AFF,LET            i zostaje wykonane faktyczne przypisanie.
                  JR    21B2,IN-NEXT-2      Skocz naprzód w celu obsługi dalszych elementów.

Obsługiwane są dalsze elementy rozkazu INPUT.

21AF IN-NEXT-1    CALL  1FFC,PR-ITEM-1      Obsłuż elementy PRINT.
21B2 IN-NEXT-2    CALL  204E,PR-POSN-1      Obsłuż znaki sterujące pozycją.
                  JP    Z,20C1,IN-ITEM-1    Wróć ponownie na początek pętli, jeśli są dalsze elementy;
                  RET                       inaczej powróć.

PROCEDURA 'IN-ASSIGN'

Ta procedura jest wywoływana dwukrotnie dla każdej wartości wprowadzonej w rozkazie INPUT. Jeden raz z wyzerowanym znacznikiem składni/uruchomienia (składnia) i raz z ustawionym tym znacznikiem (uruchomienie).

21B9 IN-ASSIGN    LD    HL,(WORKSP)         Ustaw CH-ADD na adres pierwszej
                  LD    (CH-ADD),HL         komórki obszaru roboczego
                  RST   0018,GET-CHAR       i pobierz znak.
                  CP    +E2                 Czy jest to 'STOP'?
                  JR    Z,21D0,IN-STOP      Skocz, jeśli tak.
                  LD    A,(FLAGX)           Inaczej wykonaj przypisanie
                  CALL  1C59,VAL-FET-2      tej 'wartości' zmiennej.
                  RST   0018,GET-CHAR       Pobierz bieżący znak
                  CP    +0D                 i sprawdź, czy to 'powrót karetki'.
                  RET   Z                   Jeśli tak, powróć.

Raport C - Nonsens w BASIC

21CE REPORT-C     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +0B

Przyjdź tutaj, jeśli wiersz dla rozkazu INPUT zaczyna się od znaku 'STOP'.

21D0 IN-STOP      CALL  2530,SYNTAX-Z       Lecz nie zgłaszaj błędu w przebiegu
                  RET   Z                   sprawdzającym składnię.

Raport H - STOP w INPUT

21D4 REPORT-H     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +10

PROCEDURA 'IN-CHAN-K'

Ta procedura zeruje znacznik zera, jeśli jest uzywany kanał 'K'.

21D6 IN-CHAN-K    LD    HL,(CURCHL)         Adres bazowy informacji
                  INC   HL                  o kanałach dla bieżącego
                  INC   HL                  kanału zostaje pobrany,
                  INC   HL                  a kod kanału porównany
                  INC   HL                  z literą 'K'.
                  LD    A,(HL)
                  CP    +4B
                  RET                       Po porównaniu powróć.

PROCEDURY 'ELEMENTÓW KOLORU'

Ten zbiór procedur można od razu podzielić na dwie części:

i. Sterownik osadzonych elementów koloru.
ii. Sterownik zmiennych systemowych z kolorem.
i. Osadzone elementy koloru są obsługiwane przez odpowiednie wywołanie procedury PRINT-OUT.
Następuje wejście do pętli, w której są kolejno przetwarzane elementy koloru. Punkt wejścia znajduje się pod adresem CO-TEMP-2.

21E1 CO-TEMP-1    RST   0020,NEXT-CHAR      Zajmij się następnym znakiem
                                            w wierszu języka BASIC.
21E2 CO-TEMP-2    CALL  21F2,CO-TEMP-3      Skocz naprzód, aby sprawdzić, czy
                                            obecny kod przedstawia 'tymczasowy'
                                            osadzony element koloru.
                  RET   C                   Wróć z ustawionym znacznikiem przeniesienia,
                                            jeśli tak nie jest.
                  RST   0018,GET-CHAR       Pobierz bieżący znak.
                  CP    +2C                 Skocz wstecz, jeśli jest to
                  JR    Z,21E1,CO-TEMP-1    ',' lub ';'; inaczej
                  CP    +3B                 wystąpił błąd.
                  JR    Z,21E1,CO-TEMP-1
                  JP    1C8A,REPORT-C       Wyjdź poprzez 'raport C'.
21F2 CO-TEMP-3    CP    +D9                 Wróć z ustawionym znacznikiem przeniesienia,
                  RET   C                   jeśli kod nie jest w zakresie
                  CP    +DF                 od +D9 do +DE (INK do OVER).
                  CCF
                  RET   C
                  PUSH  AF                  Kod elementu koloru jest przechowywany
                  RST   0020,NEXT-CHAR      na czas przesunięcia adresu CH-ADD na
                  POP   AF                  pozycję parametru, który występuje za kodem.

Kod elementu koloru i parametr zostają teraz 'wydrukowane' przez wywołanie procedury PRINT-OUT w dwóch przypadkach.

21FC CO-TEMP-4    SUB   +C9                 Zakres znaków tokenów (+D9 do +DE)
                                            jest zmniejszany do zakresu
                                            znaków sterujących (+10 do +15).
                  PUSH  AF                  Kod znaku sterującego jest zapamiętywany
                  CALL  1C82,EXPT-1NUM      na czas przesyłania parametru
                  POP   AF                  na stos kalkulatora.
                  AND   A                   Jeśli jest sprawdzana składnia,
                  CALL  1FC3,UNSTACK-Z      to w tym punkcie następuje powrót.
                  PUSH  AF                  Kod znaku sterującego jest
                  CALL  1E94,FIND-INT1      zapamiętywany na czas przesyłania
                  LD    D,A                 parametru do rejestru D.
                  POP   AF
                  RST   0010,PRINT-A-1      Znak kontrolny zostaje wysłany do druku.
                  LD    A,D                 Następnie zostaje pobrany parametr
                  RST   0010,PRINT-A-1      i również wysłany przed
                  RET                       wykonaniem powrotu.

ii. Zmienne systemowe koloru - ATTR-T, MASK-T i P-FLAG - są zmieniane według potrzeb. Ta procedura jest wywoływana przez PRINT-OUT. Na wejściu kod znaku sterującego znajduje się w rejestrze A a parametr w rejestrze D.

Zwróć uwagę, że wszystkie zmiany odnoszą się do 'tymczasowych' zmiennych systemowych.

2211 CO-TEMP-5    SUB   +11                 Zmniejsz zakres i skocz
                  ADC   A,+00               naprzód dla INK i PAPER.
                  JR    Z,2234,CO-TEMP-7
                  SUB   +02                 Zmniejsz ponownie zakres
                  ADC   A,+00               i skocz naprzód dla FLASH
                  JR    Z,2273,CO-TEMP-C    i BRIGHT.

Teraz kod sterowania kolorem będzie miał wartość +01 dla INVERSE i +02 dla OVER, a zmienna systemowa P-FLAG zostanie odpowiednio zmodyfikowana.

                  CP    +01                 Przygotuj się do skoku przy OVER.
                  LD    A,D                 Pobierz parametr.
                  LD    B,+01               Przygotuj maskę dla OVER.
                  JR    NZ,2228,CO-TEMP-6   Teraz skocz.
                  RLCA                      Bit 2 rejestru A musi zostać zresetowany
                  RLCA                      przy INVERSE 0 i ustawiony przy
                  LD    B,+04               INVERSE 1; maska musi mieć ustawiony bit 2.
2228 CO-TEMP-6    LD    C,A                 Zapamiętaj rejestr A na czas
                                            sprawdzania zakresu.
                  LD    A,D                 Poprawny zakres dla
                  CP    +02                 INVERSE i OVER wynosi jedynie
                  JR    NC,2244,REPORT-K    '0-1'.
                  LD    A,C                 Pobierz rejestr A.
                  LD    HL,+5C91            To jest zmienna P-FLAG, którą należy zmienić.
                  JR    226C,CO-CHANGE      Wyjdź poprzez CO-CHANGE i zmień
                                            P-FLAG wykorzystując 'B' jako maskę.
                                            Tj. bit 0 przy OVER i bit 2 przy INVERSE.

PAPER i INK są obsługiwane przez poniższą procedurę. Na wejściu jest ustawiony znacznik przeniesienia dla INK.

2234 CO-TEMP-7    LD    A,D                 Pobierz parametr.
                  LD    B,+07               Przygotuj maskę dla INK.
                  JR    C,223E,CO-TEMP-8    Skocz naprzód przy INK.
                  RLCA                      Przy PAPER wymnóż parametr przez 8.
                  RLCA
                  RLCA
                  LD    B,+38               Przygotuj maskę dla PAPER.
223E CO-TEMP-8    LD    C,A                 Zapamiętaj parametr w rejestrze C
                                            na czas sprawdzania jego zakresu.
                  LD    A,D                 Pobierz wartość pierwotną.
                  CP    +0A                 Dla PAPER/INK zezwól tylko na
                  JR    C,2246,CO-TEMP-9    zakres od '0' do '9'.

Raport K - Zły kolor

2244 REPORT-K     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędów.
                  DEFB  +13

Kontynuuj obsługę PAPER i INK;

2246 CO-TEMP-9    LD    HL,+5C8F            Przygotuj się do zmiany ATTR-T,
                                            MASK-T i P-FLAG.
                  CP    +08                 Skocz naprzód przy PAPER/INK
                  JR    C,2258,CO-TEMP-B    w zakresie od '0' do '7'.
                  LD    A,(HL)              Pobierz bieżącą wartość zmiennej
                  JR    Z,2257,CO-TEMP-A    ATTR-T i użyj jej bez zmiany
                                            przez skok naprzód przy
                                            PAPER/INK '8'.
                  OR    B                   Lecz dla PAPER/INK '9' kolory tła i tuszu
                  CPL                       muszą być czarne i białe.
                  AND   +24
                  JR    Z,2257,CO-TEMP-A    Skocz przy czarnym tle/tuszu;
                  LD    A,B                 lecz kontynuuj z białym tuszem/tłem.
2257 CO-TEMP-A    LD    C,A                 Przenieś tę wartość do rejestru C.

Maska (B) i wartość (C) są teraz wykorzystywane do zmiany ATTR-T.

2258 CO-TEMP-B    LD    A,C                 Przenieś tę wartość.
                  CALL  226C,CO-CHANGE      Teraz zmień ATTR-T według potrzeb.

Następnie zostaje obsłużona zmienna MASK-T.

                  LD    A,+07               Bity zmiennej MASK-T są ustawiane
                  CP    D                   tylko przy używaniu PAPER/INK
                  SBC   A,A                 '8' lub '9'.
                  CALL  226C,CO-CHANGE      Teraz zmień MASK-T według potrzeb.

Następnie zostaje obsłużona zmienna P-FLAG.

                  RLCA                      Odpowiednia maska zostaje
                  RLCA                      zbudowana w rejestrze B
                  AND   +50                 w celu zmiany bitów 4
                  LD    B,A                 i 6 według potrzeb.
                  LD    A,+08               Bity zmiennej P-FLAG są ustawiane
                  CP    D                   tylko przy używaniu PAPER/INK '9'
                  SBC   A,A                 Przejdź dalej do CO-CHANGE, aby przetworzyć P-FLAG.

PROCEDURA 'CO-CHANGE'

Ta procedura jest używana do 'odciśnięcia' w zmiennej systemowej stanu bitów w rejestrze A. Rejestr B zawiera maskę, która określa bity rejestru A do przekopiowania do (HL).

226C CO-CHANGE    XOR   (HL)                Bity określone przez
                  AND   B                   maskę w rejestrze B ulegają zmianie,
                  XOR   (HL)                a wynik trafia do zmiennej systemowej.
                  LD    (HL),A
                  INC   HL                  Przejdź do zaadresowania kolejnej zmiennej.
                  LD    A,B                 Wróć z maską w rejestrze A.
                  RET

FLASH i BRIGHT są obsługiwane przez poniższą procedurę.

2273 CO-TEMP-C    SBC   A,A                 Znacznik zera zostanie ustawiony dla BRIGHT.
                  LD    A,D                 Parametr jest pobierany
                  RRCA                      i obracany.
                  LD    B,+80               Przygotuj maskę dla FLASH.
                  JR    NZ,227D,CO-TEMP-D   Skocz naprzód przy FLASH.
                  RRCA                      Obróć dodatkowy raz
                  LD    B,+40               i przygotuj maskę dla BRIGHT.
227D CO-TEMP-D    LD    C,A                 Zapamiętaj tę wartość w rejestrze C.
                  LD    A,D                 Pobierz parametr i sprawdź
                  CP    +08                 jego zakres; dozwolone tylko '0', '1' i '8'.
                  JR    Z,2287,CO-TEMP-E
                  CP    +02
                  JR    NC,2244,REPORT-K

Teraz może zostać zmieniona zmienna systemowa ATTR-T.

2287 CO-TEMP-E    LD    A,C                 Pobierz tę wartość.
                  LD    HL,+5C8F            To jest ATTR-T.
                  CALL  226C,CO-CHANGE      Teraz zmień zmienną systemową.

Teraz zostaje rozważona wartość w MASK-T.

                  LD    A,C                 Wartość zostaje pobrana od nowa.
                  RRCA                      Ustawiony bit FLASH/BRIGHT
                  RRCA                      '8' (bit 3) jest przesuwany
                  RRCA                      na bit 7 (dla FLASH) lub na bit 6 (dla BRIGHT).
                  JR    226C,CO-CHANGE      Wyjdź poprzez CO-CHANGE.

PROCEDURA ROZKAZU 'BORDER'

Parametr rozkazu BORDER jest używany w instrukcji OUT w celu faktycznej zmiany koloru brzegu. Następnie parametr ten jest zapamiętywany w zmiennej systemowej BORDCR.

2294 BORDER       CALL  1E94,FIND-INT1      Parametr zostaje pobrany
                  CP    +08                 i jego zakres sprawdzony.
                  JR    NC,2244,REPORT-K
                  OUT   (+FE),A             Następnie jest używana instrukcja OUT
                                            do ustawienia koloru brzegu.
                  RLCA                      Po czym parametr zostaje
                  RLCA                      przemnożony przez osiem.
                  RLCA
                  BIT   5,A                 Jeśli kolor brzegu jest 'jasny', to
                  JR    NZ,22A6,BORDER-1    kolor tuszu w obszarze edycyjnym
                                            staje się czarny - wykonaj skok.
                  XOR   +07                 Zmień kolor tuszu.
22A6 BORDER-1     LD    (BORDCR),A          Ustaw odpowiednio zmienną systemową,
                  RET                       a następnie powróć.

PROCEDURA 'ADRESU PIKSELA'

Procedurę tę wywołują rozkazy POINT i PLOT. Wejście do niej następuje ze współrzędnymi piksela umieszczonymi w parze rejestrów BC, a na wyjściu para rejestrów HL przechowuje adres bajtu w pliku ekranowym, który zawiera ten piksel, a rejestr A wskazuje na pozycję piksela wewnątrz tego bajtu.

22AA PIXEL-ADD    LD    A,+AF               Sprawdź, czy współrzędna y (w B)
                  SUB   B                   nie jest większa niż 175.
                  JP    C,24F9,REPORT-B
                  LD    B,A                 B teraz zawiera 175 minus y.
                  AND   A                   A zawiera b7b6b5b4b3b2b1b0,
                  RRA                       czyli bajt z B. A teraz 0b7b6b5b4b3b2b1.
                  SCF
                  RRA                       Teraz 10b7b6b5b4b3b2.
                  AND   A
                  RRA                       Teraz 010b7b6b5b4b3.
                  XOR   B
                  AND   +F8                 Ostatecznie 010b7b6b2b1b0, zatem
                  XOR   B                   w H dostajemy 64 + 8*INT (B/64) + B (mod 8),
                  LD    H,A                 starszy bajt adresu piksela.
                  LD    A,C                 C zawiera X.
                  RLCA                      A zaczyna od c7c6c5c4c3c2c1c0.
                  RLCA
                  RLCA                      Teraz jest c2c1c0c7c6c5c4c3.
                  XOR   B
                  AND   +C7
                  XOR   B                   Teraz c2c1b5b4b3c5c4c3.
                  RLCA
                  RLCA                      Ostatecznie b5b4b3c7c6c5c4c3, więc
                  LD    L,A                 L ma wartość 32*INT (B(mod 64)/8) + INT(x/8),
                  LD    A,C                 czyli młodszy bajt.
                  AND   +07                 A zawiera x(mod 8): zatem piksel
                  RET                       jest bitem (A - 7) wewnątrz tego bajtu.

PROCEDURA 'POINT-SUB'

Ta procedura jest wywoływana przez funkcję POINT w procedurze SCANNING. Wejście do niej następuje ze współrzędnymi piksela na stosie kalkulatora. Procedura zwraca na stosie 1, jeśli dany piksel ma kolor tuszu, a 0, jeśli jest koloru tła.

22CB POINT-SUB    CALL  2307,STK-TO-BC      Współrzędna y do B, x do C.
                  CALL  22AA,PIXEL-ADD      Adres piksela do HL.
                  LD    B,A                 B będzie zliczać A+1 pętli w celu
                  INC   B                   ustawienia pożądanego bitu (HL) na
                  LD    A,(HL)              pozycji bitu 0.
22D4 POINT-LP     RLCA                      Przesunięcia.
                  DJNZ  22D4,POINT-LP
                  AND   +01                 Bit ma wartość 1 dla tuszu, 0 dla tła.
                  JP    2D28,STACK-A        Zostaje wstawiony na stos kalkulatora.

PROCEDURA ROZKAZU 'PLOT'

Ta procedura składa się z głównej części plus jeden wiersz do wywołania jej oraz jeden wiersz do wyjścia z niej. Główna procedura jest używana dwukrotnie przez CIRCLE oraz raz przez DRAW. Wejście do procedury następuje ze współrzędnymi piksela na stosie kalkulatora. Znajduje adres tego piksela i rysuje go, biorąc pod uwagę stan INVERSE i OVER przechowywany w zmiennej systemowej P-FLAG.

22DC PLOT         CALL  2307,STK-TO-BC      współrzędna Y do rejestru B, x do C.
                  CALL  22E5,PLOT-SUB       Jest wywoływana procedura główna.
                  JP    0D4D,TEMPS          Wyjście z ustawieniem kolorów tymczasowych.
22E5 PLOT-SUB     LD    (COORDS),BC         Zostaje ustawiona ta zmienna systemowa.
                  CALL  22AA,PIXEL-ADD      Adres piksela do pary rejestrów HL.
                  LD    B,A                 B będzie zliczać A+1 pętli, aby ustawić zero
                  INC   B                   na właściwym miejscu w A.
                  LD    A,+FE               Zero zostaje wprowadzone.
22F0 PLOT-LOOP    RRCA                      Następnie jest przesuwane na
                  DJNZ  22F0,PLOT-LOOP      pozycję piksela w tym bajcie.
                  LD    B,A                 Dalej jest kopiowane do B.
                  LD    A,(HL)              Bajt piksela zostaje pobrany do A.
                  LD    C,(P-FLAG)          P-FLAG zostaje pobrane i najpierw
                  BIT   0,C                 testowane na OVER.
                  JR    NZ,22FD,PL-TST-IN   Skocz, jeśli OVER 1.
                  AND   B                   OVER 0 najpierw ustawia piksel na zero
22FD PL-TST-IN    BIT   2,C                 Test na INVERSE.
                  JR    NZ,2303,PLOT-END    INVERSE 1 po prostu zostawia piksel takim
                                            jakim był (OVER 1) lub zero (OVER 0).
                  XOR   B                   INVERSE 0 zostawia piksel w stanie
                  CPL                       zanegowanym (OVER 1) lub 1 (OVER 0).
2303 PLOT-END     LD    (HL),A              Bajt zostaje wstawiony do pamięci. Jego pozostałe
                                            bity nie są zmieniane w żadnym wypadku.
                  JP    0BDB,PO-ATTR        Wyjście z ustawieniem bajtu atrybutów.

PROCEDURA 'STK-TO-BC'

Ta procedura ładuje dwie liczby zmiennoprzecinkowe do pary rejestrów BC. W ten sposób jest ona wykorzystywana do pobierania parametrów w zakresie +00-+FF. Również wyznacza w parze rejestrów DE wartości 'ruchu po przekątnej' (+/-1,+/-1), które wykorzystuje się w procedurze rysowania linii rozkazu DRAW.

2307 STK-TO-BC    CALL  2314,STK-TO-A       Pierwsza liczba do A.
                  LD    B,A                 I dalej do B.
                  PUSH  BC                  Zapamiętaj na krótko.
                  CALL  2314,STK-TO-A       Druga liczba do A.
                  LD    E,C                 Jej znak do E.
                  POP   BC                  Odtwórz pierwszą liczbę.
                  LD    D,C                 Jej znak do D.
                  LD    C,A                 Druga liczba do C.
                  RET                       BC, DE mają teraz pożądaną zawartość.

PROCEDURA 'STK-TO-A'

Ta procedura ładuje rejestr A liczbą zmiennoprzecinkową ze szczytu stosu kalkulatora. Liczba ta musi być w zakresie 00-FF.

2314 STK-TO-A     CALL  2DD5,FP-TO-A        Moduł zaokrąglonej ostatniej wartości
                  JP    C,24F9,REPORT-B     trafia do A, o ile jest to możliwe; inaczej zgłoś błąd.
                  LD    C,+01               Jeden do C dla wartości dodatniej.
                  RET   Z                   Wróć, jeśli wartość jest dodatnia.
                  LD    C,+FF               Inaczej zmień C na +FF (tj. minus jeden)
                  RET                       Skończone.

PROCEDURA ROZKAZU 'CIRCLE'

Ta procedura rysuje przybliżenie koła o środku na współrzędnych X i Y oraz o promieniu Z. Przed użyciem liczby te zostają zaokrąglone do najbliższych wartości całkowitych. Dlatego Z musi być mniejsze od 87,5, nawet jeśli punkt (X,Y) jest na środku ekranu. Użyta metoda polega na rysowaniu ciągu łuków przybliżanych liniami prostymi. Zostało to przedstawione w programie w języku BASIC umieszczonym w dodatku.

CIRCLE składa się z czterech części:

i. Testuje promień. Jeśli jego moduł jest mniejszy od 1, to po prostu rysuje punkt X,Y;

ii. Wywołuje CD-PRMS-1 pod adresem 2470-24B6, które jest wykorzystywane do ustawienia początkowych parametrów zarówno dla CIRCLE jak i dla DRAW;

iii. Ustawia pozostałe parametry dla CIRCLE, łącznie z początkowym przesunięciem pierwszego 'łuku' (będącego w rzeczywistości linią prostą);

iv. Skacze do polecenia DRAW, aby skorzystać z pętli rysowania łuków pod adresem 2420-24FA.

Teraz po kolei wyjaśnimy części od i do iii.

i. 2320-23AA. Promień, powiedzmy Z, zostaje pobrany ze stosu kalkulatora. Tworzy się jego moduł Z, który od teraz będzie używany dalej. Jeśli Z jest mniejsze od 1, to jest usuwane ze stosu kalkulatora, a punkt X,Y zostaje narysowany przez skok do PLOT.

2320 CIRCLE       RST   0017,GET-CHAR       Pobierz bieżący znak.
                  CP    +2C                 Test na przecinek.
                  JP    NZ,1C8A,REPORT-C    Jeśli go brak, raportuj błąd.
                  RST   0020,NEXT-CHAR      Pobierz następny znak (promień).
                  CALL  1C82,EXPT-1NUM      Promień na stos kalkulatora.
                  CALL  1BEE,CHECK-END      Przy sprawdzaniu składni przesuń się dalej.
                  RST   0028,FP-CALC        Użyj kalkulatora: stos zawiera:
                  DEFB  +2A,abs             X, Y, Z
                  DEFB  +3D,re-stack        Z zostaje pobrany i umieszczony na stosie.
                  DEFB  +38,end-calc        W ten sposób staje się dostępny jego wykładnik.
                  LD    A,(HL)              Pobierz wykładnik promienia.
                  CP    +81                 Testuj, czy promień jest mniejszy od 1.
                  JR    NC,233B,C-R-GRE-1   Jeśli nie, skocz.
                  RST   0028,FP-CALC        Jeśli tak, usuń go ze stosu.
                  DEFB  +02,delete          Stos zawiera X, Y.
                  DEFB  +38,end-calc        
                  JR    22DC,PLOT           Po prostu rysuj punkt X, Y.

ii.  233B-2346 i wywołanie CD-PRMS1. W mem-5 zostaje umieszczone 2*PI i jest wywoływana procedura CD-PRMS1. Procedura ta umieszcza w rejestrze B liczbę łuków wymaganych dla tego koła. Mianowicie A=4*INT (PI*SQR Z/4)+4, stąd 4, 8, 12 ..., do maksymalnej liczby 32. Umieszcza również w mem-0 do mem-4 wartości 2*PI/A, SIN(PI/A), 0, COS (2*PI/A) oraz SIN (2*PI/A).

233B C-R-GRE-1    RST   0028,FP-CALC
                  DEFB  +A3,stk-pi/2        X, Y, Z, PI/2.
                  DEFB  +38,end-calc        Teraz zwiększ wykładnik do 83 szesnastkowo,
                  LD    (HL),+83            zmieniając PI/2 na 2*PI.
                  RST   0028,FP-CALC        X, Y, Z, 2*PI.
                  DEFB  +C5,st-mem-5        2*PI jest zapisywane w mem-5.
                  DEFB  +02,delete          X, Y, Z
                  DEFB  +38,end-calc
                  CALL  247D,CD-PRMS1       Ustaw parametry początkowe.

iii. 2347-2381: pozostałe parametry i skok do DRAW. Robiony jest test, aby sprawdzić, czy początkowa długość 'łuku' jest mniejsza od 1. Jeśli tak, to następuje po prostu skok do PLOT X,Y. W przeciwnym razie zostają ustawione parametry: X+Z i X-Z*SIN (PI/A) są umieszczane na stosie dwukrotnie jako punkt startowy i końcowy oraz kopiowane również do zmiennej systemowej COORDS; zero i 2*Z*SIN (PI/A) są umieszczane w mem-1 i mem-2 jako początkowe przyrosty, co daje jako początkowy 'łuk' pionową linię prostą łączącą X+Z, y-Z*SIN (PI/A) z X+Z, Y+Z*SIN (PI/A). Procedura rysująca łuki rozkazu DRAW zagwarantuje, że wszystkie kolejne punkty pozostaną na tym samym okręgu co te dwa, z kątem przyrostu 2*PI/A. Lecz jest jasne, że te dwa punkty w rzeczywistości rozpościerają ten kąt od punktu X+Z*(1-COS (PI/A)), Y, a nie od X, Y. Stąd punkty końcowe każdego łuku koła są przesunięte w prawo o 2*(1-COS (PI/A)), co jest wartością mniejszą od połowy piksela i zostanie zaokrąglone co najwyżej do jednego piksela.

2347              PUSH  BC                  Zachowaj licznik łuków w B.
                  RST   0028,FP-CALC        X,Y,Z
                  DEFB  +31,duplicate       X,Y,Z,Z
                  DEFB  +E1,get-mem-1       X,Y,Z,Z,SIN (PI/A)
                  DEFB  +04,multiply        X,Y,Z,Z*SIN (PI/A)
                  DEFB  +38,end-calc        Z*SIN (PI/A) jest połową początkowej
                  LD    A,(HL)              długości 'łuku'; sprawdza się,
                  CP    +80                 czy nie jest to mniejsze od 0.5.
                  JR    NC,235A,C-ARC-GE1   Jeśli nie, zostaje wykonany skok.
                  RST   0028,FP-CALC
                  DEFB  +02,delete          W przeciwnym razie Z jest usuwane ze stosu
                  DEFB  +02,delete          wraz z tą połową łuku;
                  DEFB  +38,end-calc
                  POP   BC                  stos maszynowy zostaje wyczyszczony;
                  JP    22DC,PLOT           wykonuje się skok do PLOT X, Y.
235A C-ARC-GE1    RST   0028,FP-CALC        X,Y,Z,Z*SIN (PI/A)
                  DEFB  +C2,st-mem-2        Z*SIN (PI/A) chwilowo do mem-2
                  DEFB  +01,exchange        X,Y,Z*SIN (PI/A),Z
                  DEFB  +C0,st-mem-0        X,Y,Z*SIN (PI/A),Z
                  DEFB  +02,delete          X,Y,Z*SIN (PI/A)
                  DEFB  +03,subtract        X, Y - Z*SIN (PI/A)
                  DEFB  +01,exchange        Y - Z*SIN (PI/A), X
                  DEFB  +E0,get-mem-0       Y - Z*SIN (PI/A), X, Z
                  DEFB  +0F,addition        Y - Z*SIN (PI/A), X+Z
                  DEFB  +CO,st-mem-0        X+Z jest zapisywane do mem-0
                  DEFB  +01,exchange        X+Z, Y - Z*SIN (PI/A)
                  DEFB  +31,duplicate       X+Z, Y-Z*SIN (PI/A), Y-Z*SIN (PI/A)
                  DEFB  +E0,get-mem-0       sa,sb,sb,sa
                  DEFB  +01,exchange        sa,sb,sa,sb
                  DEFB  +31,duplicate       sa,sb,sa,sb,sb
                  DEFB  +E0,get-mem-0       sa,sb,sa,sb,sb,sa
                  DEFB  +A0,stk-zero        sa,sb,sa,sb,sb,sa,0
                  DEFB  +C1,st-mem-1        mem-1 jest zerowane
                  DEFB  +02,delete          sa,sb,sa,sb,sb,sa
                  DEFB  +38,end-calc

(Tutaj sa oznacza X+Z, a sb oznacza Y - Z*SIN (PI/A)).

                  INC   (mem-2-1st)         Zwiększenie bajtu wykładnika
                                            mem-2 ustawia mem-2 na 2*Z*SIN(PI/A).
                  CALL  1E94,FIND-INT1      Ostatnia wartość X+Z jest przemieszczana
                  LD    L,A                 ze stosu do A i zapisywana w L.
                  PUSH  HL                  Zostaje zachowana w HL.
                  CALL  1E94,FIND-INT1      Y - Z*SIN (PI/A) idzie ze stosu
                  POP   HL                  do A i jest zapisywane H.
                  LD    H,A                 HL teraz zawiera początkowy punkt.
                  LD    (COORDS),HL         Zostaje on zapisany w COORDS.
                  POP   BC                  Zostaje odtworzony licznik łuków.
                  JP    2420,DRW-STEPS      Wykonuje się skok do DRAW.

(Stos zawiera teraz X+Z, Y - Z*SIN (PI/A), Y - Z*SIN (PI/A), X+Z).

PROCEDURA ROZKAZU 'DRAW'

Wejście do tej procedury następuje ze współrzędnymi punktu X0, Y0 w zmiennej systemowej COORDS. Jeśli dane są tylko dwa parametry X, Y dla rozkazu DRAW, to narysuje on przybliżenie linii prostej od punktu X0, Y0 do X0+X, Y0+Y. Jeśli dany jest trzeci parametr G, to narysowane zostanie przybliżenie łuku kołowego od X0, Y0 do X0+X, Y0+Y przy obrocie odwrotnie do ruchu wskazówek zegara o kąt G radianów.

Procedura składa się z czterech części:

i. Jeśli dane są tylko dwa parametry lub średnica łuku jest mniejsza od 1, to rysuje po prostu linię prostą;

ii. Wywołuje CD-PRMS1 pod adresem 247D-24B6 w celu ustawienia początkowych parametrów;

iii. Ustawia pozostałe parametry, łącznie z początkowym przesunięciem dla pierwszego łuku;

iv. Wchodzi w pętlę rysowania łuków i rysuje ciąg mniejszych łuków przybliżanych liniami prostymi, wywołując według potrzeb procedurę ich rysowania pod adresem 24B7-24FA.

Po głównej procedurze występują dwie inne, CD-PRMS1 i DRAW-LINE. Teraz po kolei zajmiemy się czterema powyższymi częściami głównej procedury.

i. Jeśli są tylko 2 parametry, to zostaje wykonany skok do LINE-DRAW pod adresem 2477. Linia jest również rysowana, jeśli wartość Z=(ABS X + ABS Y)/ABS SIN(G/2) jest mniejsza od 1.  Z ma wartość od 1 do 1,5 średnicy wynikowego koła. W tej sekcji mem-0 jest ustawiane na SIN (G/2), mem-1 na Y, a mem-5 na G.

2382 DRAW         RST   0018,GET-CHAR       Pobierz bieżący znak.
                  CP    +2C                 Jeśli jest nim przecinek,
                  JR    Z,238D,DR-3-PRMS    to skocz.
                  CALL  1BEE,CHECK-END      Przy sprawdzaniu składni przesuń się
                                            do następnego rozkazu.
                  JP    2477,LINE-DRAW      Skocz, aby tylko narysować linię.
238D DR-3-PRMS    RST   0020,NEXT-CHAR      Pobierz następny znak (kąt).
                  CALL  1C82,EXPT-1NUM      Kąt umieść na stosie kalkulatora.
                  CALL  1BEE,CHECK-END      Przy sprawdzaniu składni przesuń się
                                            do następnego rozkazu.
                  RST   0028,FP-CALC        X, Y, G są na stosie
                  DEFB  +C5,st-mem-5        G jest umieszczane w mem-5.
                  DEFB  +A2,stk-half        X, Y, G, 0.5
                  DEFB  +04,multiply        X, Y, G/2
                  DEFB  +1F,sin             X, Y, SIN (G/2)
                  DEFB  +31,duplicate       X, Y, SIN (G/2), SIN (G/2)
                  DEFB  +30,not             X, Y, SIN (G/2), (0/1)
                  DEFB  +30,not             X, Y, SIN (G/2), (1/0)
                  DEFB  +00,jump-true       X, Y, SIN (G/2)
                  DEFB  +06,to DR-SIN-NZ    Jeśli SIN (G/2)=0 tj. G = 2*N*PI,
                  DEFB  +02,delete          to po prostu rysuj linię prostą.
                  DEFB  +38,end-calc        X, Y
                  JP    2477,LINE-DRAW      Linia od X0, Y0 do X0+X, Y0+Y.
23A3 DR-SIN-NZ    DEFB  +C0,st-mem-0        SIN (G/2) jest umieszczane w mem-0.
                  DEFB  +02,delete          X, Y są teraz na stosie.
                  DEFB  +C1,st-mem-1        Y jest umieszczane w mem-1.
                  DEFB  +02,delete          X
                  DEFB  +31,duplicate       X, X
                  DEFB  +2A,abs             X, X' (X' = ABS X)
                  DEFB  +E1,get-mem-1       X, X', Y
                  DEFB  +01,exchange        X, Y, X'
                  DEFB  +E1,get-mem-1       X, Y, X', Y
                  DEFB  +2A,abs             X, Y, X', Y' (Y' = ABS Y)
                  DEFB  +0F,addition        X, Y, X'+Y'
                  DEFB  +E0,get-mem-0       X, Y, X'+Y', SIN (G/2)
                  DEFB  +05,division        X, Y, (X'+Y')/SIN (G/2)=Z'
                  DEFB  +2A,abs             X, Y, Z (Z = ABS Z')
                  DEFB  +E0,get-mem-0       X, Y, Z, SIN (G/2)
                  DEFB  +01,exchange        X, Y, SIN (G/2), Z
                  DEFB  +3D,re-stack        Z jest pobierane i wstawiane na stos, aby
                  DEFB  +38,end-calc        uzyskać dostęp do jego wykładnika.
                  LD    A,(HL)              Pobierz wykładnik Z.
                  CP    +81                 Jeśli Z jest większe lub równe 1, 
                  JR    NC,23C1,DR-PRMS     to skocz.
                  RST   0028,FP-CALC        X, Y, SIN (G/2), Z
                  DEFB  +02,delete          X, Y, SIN (G/2)
                  DEFB  +02,delete          X, Y
                  DEFB  +38,end-calc        Tylko rysuj linię od X0, Y0
                  JP    2477,LINE-DRAW      do X0+X, Y0+Y.

ii.  Wywołuje po prostu CD-PRMS1. Procedura ta zapamiętuje w rejestrze B liczbę krótszych łuków wymaganych do narysowania pełnego łuku, mianowicie A=4*INT (G'*SQR Z/8)+4, gdzie G' = mod G lub 252, jeśli wyrażenie przekracza 252 (co może się zdarzyć przy dużej cięciwie i małym kącie). Zatem A przyjmuje wartości 4, 8, 12, ... , do 252. Procedura również umieszcza w mem-0 do mem-4 wartości G/A, SIN (G/2*A), 0, COS (G/A), SIN (G/A).

23C1 DR-PRMS      CALL  247D,CD-PRMS1       Procedura zostaje wywołana.

iii. Ustawia pozostałe parametry następująco: stos będzie zawierał te cztery elementy czytane z dołu do góry: X0+X i Y0+Y jako koniec ostatniego łuku; następnie X0 i Y0 jako początek pierwszego łuku. Mem-0 będzie zawierać X0, a mem-5 Y0. Mem-1 i mem-2 będą zawierały początkowe przesunięcie dla pierwszego łuku, U i V; a mem-3 i mem-4 będą zawierać COS (G/A) i SIN (G/A) do użycia w pętli rysującej łuki.

Wzory na U i V można rozwinąć następująco: zamiast kroczenia wzdłuż końcowej cięciwy o długości L, powiedzmy, że z przesunięciami X i Y, będziemy kroczyć wzdłuż początkowej cięciwy (która może być dłuższa) o długości L*W, gdzie W=SIN (G/2*A)/SIN (G/2), z przesunięciami X*W i Y*W, lecz obróconej na kącie - (G/2 - G/2*A), zatem mającej prawdziwe przesunięcia:

     U = Y*W*SIN (G/2 - G/2*A) + X*W*COS (G/2 - G/2*A)
     Y = Y*W*COS (G/2 - G/2*A) - X*W*SIN (G/2 - G/2*A)

Wzór ten można sprawdzić na wykresie, używając zwykłych wyrażeń COS (P - Q) i SIN (P - Q), gdzie Q = G/2 - G/2*A

23C4              PUSH  BC                  Zapamiętaj na stosie licznik łuków w B.
                  RST   0028,FP-CALC        X,Y,SIN(G/2),Z
                  DEFB  +02,delete          X,Y,SIN(G/2)
                  DEFB  +E1,get-mem-1       X,Y,SIN(G/2),SIN(G/2*A)
                  DEFB  +01,exchange        X,Y,SIN(G/2*A),SIN(G/2)
                  DEFB  +05,division        X,Y,SIN(G/2*A)/SIN(G/2)=W
                  DEFB  +C1,st-mem-1        W jest zapisywane do mem-1.
                  DEFB  +02,delete          X,Y
                  DEFB  +01,exchange        Y,X
                  DEFB  +31,duplicate       Y,X,X
                  DEFB  +E1,get-mem-1       Y,X,X,W
                  DEFB  +04,multiply        Y,X,X*W
                  DEFB  +C2,st-mem-2        X*W jest zapisywane do mem-2.
                  DEFB  +02,delete          Y,X
                  DEFB  +01,exchange        X,Y
                  DEFB  +31,duplicate       X,Y,Y
                  DEFB  +E1,get-mem-1       X,Y,Y,W
                  DEFB  +04,multiply        X,Y,Y*W
                  DEFB  +E2,get-mem-2       X,Y,Y*W,X*W
                  DEFB  +E5,get-mem-5       X,Y,Y*W,X*W,G
                  DEFB  +E0,get-mem-0       X,Y,Y*W,X*W,G,G/A
                  DEFB  +03,subtract        X,Y,Y*W,X*W,G - G/A
                  DEFB  +A2,stk-half        X,Y,Y*W,X*W,G - G/A, 1/2
                  DEFB  +04,multiply        X,Y,Y*W,X*W, G/2 - G/2*A=F
                  DEFB  +31,duplicate       X,Y,Y*W,X*W, F, F
                  DEFB  +1F,sin             X,Y,Y*W,X*W, F, SIN F
                  DEFB  +C5,st-mem-5        SIN F jest zapisywane do mem-5.
                  DEFB  +02,delete          X,Y,Y*W,X*W,F
                  DEFB  +20,cos             X,Y,Y*W,X*W, COS F
                  DEFB  +C0,st-mem-0        COS F jest zapisywane do mem-0.
                  DEFB  +02,delete          X,Y,Y*W,X*W
                  DEFB  +C2,st-mem-2        X*W jest zapisywane do mem-2.
                  DEFB  +02,delete          X,Y,Y*W
                  DEFB  +C1,st-mem-1        Y*W jest zapisywane do mem-1.
                  DEFB  +E5,get-mem-5       X,Y,Y*W,SIN F
                  DEFB  +04,multiply        X,Y,Y*W*SIN F
                  DEFB  +E0,get-mem-0       X,Y,Y*W*SIN F,X*W
                  DEFB  +E2,get-mem-2       X,Y,Y*W*SIN F,X*W, COS F
                  DEFB  +04,multiply        X,Y,Y*W*SIN F,X*W*COS F
                  DEFB  +0F,addition        X,Y,Y*W*SIN F+X*W*COS F=U
                  DEFB  +E1,get-mem-1       X,Y,U,Y*W
                  DEFB  +01,exchange        X,Y,Y*W,U
                  DEFB  +C1,st-mem-1        U jest zapisywane do mem-1
                  DEFB  +02,delete          X,Y,Y*W
                  DEFB  +E0,get-mem-0       X,Y,Y*W, COS F
                  DEFB  +04,multiply        X,Y,Y*W*COS F
                  DEFB  +E2,get-mem-2       X,Y,Y*W*COS F,X*W
                  DEFB  +E5,get-mem-5       X,Y,Y*W*COS F,X*W, SIN F
                  DEFB  +04,multiply        X,Y,Y*W*COS F,X*W*SIN F
                  DEFB  +03,subtract        X,Y,Y*W*COS F - X*W*SIN F = V
                  DEFB  +C2,st-mem-2        V jest zapisywane do mem-2.
                  DEFB  +2A,abs             X, Y, V' (V' = ABS V)
                  DEFB  +E1,get-mem-1       X, Y, V', U
                  DEFB  +2A,abs             X, Y, V', U' (U' = ABS U)
                  DEFB  +0F,addition        X, Y, U' + V'
                  DEFB  +02,delete          X, Y
                  DEFB  +38,end-calc        DE teraz wskazuje U' + V'.
                  LD    A,(DE)              Pobierz wykładnik U' + V'
                  CP    +81                 Jeśli U' + V' jest mniejsze od 1, to
                  POP   BC                  tylko uporządkuj stos i narysuj linię
                  JP    C,2477,LINE-DRAW    od X0, Y0 do X0+X, Y0+Y.
                  PUSH  BC                  W przeciwnym razie kontynuuj
                  RST   0028,FP-CALC        z parametrami: X, Y na stosie.
                  DEFB  +01,exchange        Y, X
                  DEFB  +38,end-calc
                  LD    A,(COORDS-lo)       Pobierz X0 do A i umieść
                  CALL  2D28,STACK-A        na stosie.
                  RST   0028,FP-CALC        Y, X, X0
                  DEFB  +C0,st-mem-0        X0 jest zapisywane w mem-0.
                  DEFB  +0F,addition        Y, X0 + X
                  DEFB  +01,exchange        X0+X, Y
                  DEFB  +38,end-calc
                  LD    A,(COORDS-hi)       Pobierz Y0 do A i umieść
                  CALL  2D28,STACK-A        na stosie.
                  RST   0028,FP-CALC        X0+X, Y, Y0
                  DEFB  +C5,st-mem-5        Y0 jest zapisywane do mem-5.
                  DEFB  +0F,addition        X0+X, Y0+Y
                  DEFB  +E0,get-mem-0       X0+X, Y0+Y, X0
                  DEFB  +E5,get-mem-5       X0+X, Y0+Y, X0, Y0
                  DEFB  +38,end calc
                  POP   BC                  Odtwórz licznik łuków w B.

iv. Pętla rysowania łuków. Wchodzi się do niej pod adresem 2439 ze współrzędnymi punktu początkowego na szczycie stosu, a początkowymi przesunięciami dla pierwszego łuku w mem-1 i mem-2. Wykorzystuje ona proste zasady geometrii, aby zagwarantować, że wszystkie kolejne łuki zostaną narysowane do punktów, które leżą na tym samym okręgu co pierwsze dwa, opisując ten sam kąt w środku koła. Można pokazać, że jeśli dwa punkty X1, Y1 i X2, Y2 leżą na okręgu i należą do kąta N ze środka, który jest również początkiem układu współrzędnych, to X2 = X1*COS N - Y1*SIN N, a Y2 = X1*SIN N + Y1*COS N. Lecz ponieważ początek jest tutaj przy przyrostach, powiedzmy, Un = Xn+1 - Xn i Vn = Yn+1 - Yn, to w ten sposób otrzymujemy pożądany wynik. Stos jest pokazany poniżej w (n+1) obiegu pętli, ponieważ Xn i Yn są zwiększane przez Un i Vn po otrzymaniu ich z Un-1 i Vn -1. Cztery wartości na szczycie stosu pod adresem 2425 są w DRAW w kolejności od dołu do góry: X0+X, Y0+Y, Xn i Yn, lecz w celu oszczędności miejsca nie są one pokazywane aż do adresu 2439. Początkowe wartości w CIRCLE znajdziesz na końcu opisanej powyżej procedury rozkazu CIRCLE. W CIRCLE również kąt G musi przyjąć wartość 2*PI.

2420 DRW-STEPS    DEC   B                   B zlicza obiegi pętli.
                  JR    Z,245F,ARC-END      Skocz, gdy B osiągnęło zero.
                  JR    2439,ARC-START      Skocz do pętli, aby zacząć.
2425 ARC-LOOP     RST   0028,FP-CALC        (Przeczytaj powyższy opis zawartości stosu).
                  DEFB  +E1,get-mem-1       Un-1
                  DEFB  +31,duplicate       Un-1,Un-1
                  DEBF  +E3,get-mem-3       Un-1,Un-1,COS(G/A)
                  DEFB  +04,multiply        Un-1,Un-1*COS(G/A)
                  DEFB  +E2,get-mem-2       Un-1,Un-1*COS(G/A),Vn-1
                  DEFB  +E4,get-mem-4       Un-1,Un-1*COS(G/A),Vn-1,SIN(G/A)
                  DEFB  +04,multiply        Un-1,Un-1*COS(G/A),Vn-1*SIN(G/A)
                  DEFB  +03,subtract        Un-1,Un-1*COS(G/A)-Vn-1*SIN(G/A)=Un
                  DEFB  +C1,st-mem-1        Un jest zapisywane do mem-1.
                  DEFB  +02,delete          Un-1
                  DEFB  +E4,get-mem-4       Un-1,SIN(G/A)
                  DEFB  +04,multiply        Un-1*SIN(G/A)
                  DEFB  +E2,get-mem-2       Un-1*SIN(G/A),Vn-1
                  DEFB  +E3,get-mem-3       Un-1*SIN(G/A),Vn-1,COS(G/A)
                  DEFB  +04,multiply        Un-1*SIN(G/A),Vn-1*COS(G/A)
                  DEFB  +0F,addition        Un-1*SIN(G/A)+Vn-1*COS(G/A)=Vn
                  DEFB  +C2,st-mem-2        Vn jest zapisywane do mem-2.
                  DEFB  +02,delete          (Jak zanotowano w tekście, stos zawiera
                  DEFB  +38,end-calc        w rzeczywistości X0+X,Y0+Y, Xn i Yn).
2439 ARC-START    PUSH  BC                  Zachowaj licznik łuków.
                  RST   0028,FP-CALC        X0+X, Y0+y, Xn, Yn
                  DEFB  +C0,st-mem-0        Yn jest zapisywane do mem-0.
                  DEFB  +02,delete          X0+X, Y0+Y, Xn
                  DEFB  +E1,get-mem-1       X0+X, Y0+Y, Xn, Un
                  DEFB  +0F,addition        X0+X, Y0+Y, Xn+Un = Xn+1
                  DEFB  +31,duplicate       X0+X, Y0+Y, Xn+1, Xn+1
                  DEFB  +38,end-calc        Następne Xn', przybliżona wartość Xn
                                            osiągnięta przez procedurę rysowania linii,
                  LD    A,(COORDS-lo)       jest zapisywane do A
                  CALL  2D28,STACK-A        a także na stos.
                  RST   0028,FP-CALC        X0+X,Y0+Y,Xn+1,Xn'
                  DEFB  +03,subtract        X0+X,Y0+Y,Xn+1,Xn+1,Xn' - Xn' = Un'
                  DEFB  +E0,get-mem-0       X0+X,Y0+Y,Xn+1,Un',Yn
                  DEFB  +E2,get-mem-2       X0+X,Y0+Y,Xn+1,Un',Yn,Vn
                  DEFB  +0F,addition        X0+X,Y0+Y,Xn+1,Un',Yn + Vn = Yn+1
                  DEFB  +C0,st-mem-0        Yn+1 jest zapisywane do mem-0.
                  DEFB  +01,exchange        X0+X,Y0+Y,Xn+1,Yn+1,Un'
                  DEFB  +E0,get-mem-0       X0+X,Y0+Y,Xn+1,Yn+1,Un',Yn+1
                  DEFB  +38,end-calc
                  LD    A,(COORDS-hi)       Yn', przybliżenie jak dla Xn', jest
                  CALL  2D28,STACK-A        zapisywane w A i na stosie.
                  RST   0028,FP-CALC        X0+X,Y0+Y,Xn+1,Yn+1,Un',Yn+1,Yn'
                  DEFB  +03,subtract        X0+X,Y0+Y,Xn+1,Yn+1,Un',Vn'
                  DEFB  +38,end-calc
                  CALL  24B7,DRAW-LINE      Jest rysowany następny 'łuk'.
                  POP   BC                  Licznik łuków zostaje odtworzony.
                  DJNZ  2425,ARC-LOOP       Skocz, jeśli trzeba narysować więcej łuków.
245F ARC-END      RST   0028,FP-CALC
                  DEFB  +02,delete          Współrzędne końca ostatnio narysowanego
                  DEFB  +02,delete          łuku zostaję teraz usunięte ze stosu.
                  DEFB  +01,exchange        Y0+Y, X0+X
                  DEFB  +38,end-calc
                  LD    A,(COORDS-lo)       Współrzędna X końca ostatniego
                  CALL  2D28,STACK-A        łuku, który został narysowany, powiedzmy
                  RST   0028,FP-CALC        Xz', jest zapisywana na stosie.
                  DEFB  +03,subtract        Y0+Y, X0+X - Xz'
                  DEFB  +01,exchange        X0+X - Xz', Y0+Y
                  DEFB  +38,end-calc
                  LD    A,(COORDS-hi)       Pobrana zostaje współrzędna Y.
                  CALL  2D28,STACK-A
                  RST   0028,FP-CALC        X0+X - Xz', Y0+Y, Yz'
                  DEFB  +03,subtract        X0+X - Xz', Y0+Y - Yz'
                  DEFB  +38,end-calc
2477 LINE-DRAW    CALL  24B7,DRAW-LINE      Końcowy łuk jest rysowany, aby osiągnąć 
                                            punkt X0+X, Y0+Y (lub zamknąć okrąg).
                  JP    0D4D,TEMPS          Wyjście z ustawieniem kolorów tymczasowych.

PROCEDURA 'PARAMETRÓW POCZĄTKOWYCH'

Ta procedura jest wywoływana zarówno przez CIRCLE jak i DRAW w celu ustawienia ich parametrów początkowych. Przez CIRCLE jest wywoływana z X, Y i promieniem Z na szczycie stosu, czytając z dołu do góry. Przez DRAW jest wywoływana z własnymi danymi na szczycie stosu X, Y, SIN (G/2) i Z, jak opisano powyżej. W opisie pokazujemy tylko zawartość stosu od Z w górę.

Procedura zwraca w B liczbę łuków A, jak opisano w CIRCLE i DRAW powyżej, a w mem-0 do mem-5 wartości G/A, SIN (G/2*A), 0, COS (G/A), SIN (G/A) i G. Dla okręgu G musi przyjąć wartość równą 2*PI.

247D CD-PRMS1     RST   0028,FP-CALC        Z
                  DEFB  +31,duplicate       Z, Z
                  DEFB  +28,sqr             Z, SQR Z
                  DEFB  +34,stk-data        Z, SQR Z, 2
                  DEFB  +32,exponent +82
                  DEFB  +00,(+00,+00,+00)
                  DEFB  +01,exchange        Z, 2, SQR Z
                  DEFB  +05,division        Z, 2/SQR Z
                  DEFB  +E5,get-mem-5       Z, 2/SQR Z, G
                  DEFB  +01,exchange        Z, G, 2/SQR Z
                  DEFB  +05,division        Z, G*SQR Z/2
                  DEFB  +2A,abs             Z, G'*SQR Z/2 (G' = mod G)
                  DEFB  +38,end-calc        Z, G'*SQR Z/2 = A1
                  CALL  2DD5,FP-TO-A        A1 do A ze stosu, jeśli jest to możliwe.
                  JR    C,2495,USE-252      Jeśli A1 zaokrągla się do 256 lub więcej, użyj 252.
                  AND   +FC                 4*INT (A1/4) do A.
                  ADD   A,+04               Dodaj 4, dostając liczbę łuków A.
                  JR    NC,2497,DRAW-SAVE   Skocz, jeśli wciąż mniej niż 256.
2495 USE-252      LD    A,+FC               Tutaj po prostu użyj 252 dziesiętnie.
2497 DRAW-SAVE    PUSH  AF                  Teraz zachowaj licznik łuków.
                  CALL  2D28,STACK-A        Zapisz go również na stosie.
                  RST   0028,FP-CALC        Z, A
                  DEFB  +E5,get-mem-5       Z, A, G
                  DEFB  +01,exchange        Z, G, A
                  DEFB  +05,division        Z, G/A
                  DEFB  +31,duplicate       Z,G/A, G/A
                  DEFB  +1F,sin             Z, G/A, SIN (G/A)
                  DEFB  +C4,st-mem-4        SIN (G/A) jest zapisywane do mem-4.
                  DEFB  +02,delete          Z, G/A
                  DEFB  +31,duplicate       Z, G/A, G/A
                  DEFB  +A2,stk-half        Z, G/A, G/A, 0.5
                  DEFB  +04,multiply        Z, G/A, G/2*A
                  DEFB  +1F,sin             Z, G/A, SIN (G/2*A)
                  DEFB  +C1,st-mem-1        SIN (G/2*A) jest zapisywane do mem-1.
                  DEFB  +01,exchange        Z, SIN (G/2*A), G/A
                  DEFB  +C0,st-mem-0        G/A jest zapisywane do mem-0.
                  DEFB  +02,delete          Z, SIN (G/2*A) = S
                  DEFB  +31,duplicate       Z, S, S
                  DEFB  +04,multiply        Z, S*S
                  DEFB  +31,duplicate       Z, S*S, S*S
                  DEFB  +0F,addition        Z, 2*S*S
                  DEFB  +A1,stk-one         Z, 2*S*S, 1
                  DEFB  +03,subtract        Z, 2*S*S - 1
                  DEFB  +1B,negate          Z, 1 - 2*S*S = COS (G/A)
                  DEFB  +C3,st-mem-3        COS (G/A) jest zapisywane do mem-).
                  DEFB  +02,delete          Z
                  DEFB  +38,end-calc
                  POP   BC                  Odtwórz licznik łuków w B.
                  RET                       Skończone.

PROCEDURA 'RYSOWANIA LINII'

Procedura ta jest wywoływana przez DRAW do narysowania przybliżenia odcinka prostego od punktu X0, Y0 przechowywanego w COORDS do punktu X0+X, Y0+Y, gdzie przyrosty X i Y są na szczycie stosu kalkulatora. Procedura została pierwotnie opracowana dla komputerów ZX80 oraz ZX81 z 8K ROM, a opisano ją za pomocą programu w języku BASIC w instrukcji dla ZX81. Również tutaj zilustrowana jest w dodatku w programie rysującym koło.

Metoda polega na wykonywaniu wymaganej liczby przeplatanych kroków w poziomie lub w pionie przy ruchu wzdłuż przekątnej, wykorzystując algorytm, który rozkłada te kroki w sposób najbardziej równomierny.

24B7 DRAW-LINE    CALL  2307,STK-TO-BC      ABS Y do B; ABS X do C;
                                            SGN Y do D; SGN X do E.
                  LD    A,C                 Skocz, jeśli ABS X jest większe
                  CP    B                   lub równe ABS Y, aby mniejsza wartość
                  JR    NC,24C4,DL-X-GE-Y   trafiła do L, a większa
                  LD    L,C                 do H.
                  PUSH  DE                  Zachowaj krok przekątny (+/-1,+/-1) w DE.
                  XOR   A                   Wstaw krok pionowy (+/-1, 0)
                  LD    E,A                 do DE (D przechowuje SGN Y).
                  JR    24CB,DL-LARGER      Teraz skocz, aby ustawić H.
24C4 DL-X-GE-Y    OR    C                   Wróć, jeśli ABS X i ABS Y
                  RET   Z                   są oba równe zero.
                  LD    L,B                 Mniejsze (tutaj ABS Y) trafia do L.
                  LD    B,C                 Tutaj ABS X do B.
                  PUSH  DE                  Również tutaj zachowaj krok przekątny.
                  LD    D,+00               Krok poziomy (0, +/-1) tutaj do DE.
24CB DL-LARGER    LD    H,B                 Większe z ABS X, ABS Y teraz do H.

Algorytm rozpoczyna się tutaj. Większe z ABS X i ABS Y, powiedzmy H, jest wstawiane do A i zmniejszane do INT (H/2). H - L poziomych lub pionowych kroków oraz L kroków przekątnych (gdzie L jest mniejszą wartością z ABS X i ABS Y) jest wykonywane w ten sposób: L jest dodawane do A; jeśli teraz A jest równe lub większe od H, to zostaje pomniejszone o H i wykonany zostaje krok przekątny; w przeciwnym razie jest wykonywany krok poziomy lub pionowy. Powtarza się to H razy (B również zawiera H). Zauważ, że w międzyczasie rejestry zapasowe H' i L' są wykorzystywane do przechowywania wartości COORDS.

                  LD    A,B                 B do A oraz do H.
                  RRA                       A zaczyna od INT (H/2).
24CE D-L-LOOP     ADD   A,L                 L jest dodawane do A.
                  JR    C,24D4,D-L-DIAG     Jeśli 256 lub więcej, skocz do kroku przekątnego.
                  CP    H                   Jeśli A jest mniejsze od H, skocz do
                  JR    C,24DB,D-L-HR-VT    kroku poziomego lub pionowego.
24D4 D-L-DIAG     SUB   H                   Zmniejsz A o wartość H.
                  LD    C,A                 Odtwórz to w C.
                  EXX                       Teraz użyj rejestrów zapasowych.
                  POP   BC                  Krok przekątny do B'C'.
                  PUSH  BC                  Również zapamiętaj go na stosie.
                  JR    24DF,D-L-STEP       Skocz, aby wykonać ten krok.
24DB D-L-HR-VT    LD    C,A                 Zachowaj A (zmniejszone) w C.
                  PUSH  DE                  Krok na chwilę na stos.
                  EXX                       Zmień rejestry na zestaw zapasowy.
                  POP   BC                  Teraz krok do B'C'.
24DF D-L-STEP     LD    HL,(COORDS)         Teraz wykonaj krok: najpierw
                                            COORDS do H'L' jako punkt startowy.
                  LD    A,B                 krok Y z B' do A.
                  ADD   A,H                 Dodaj H'.
                  LD    B,A                 Wynik do B'    .
                  LD    A,C                 Teraz krok X; zostanie sprawdzony zakres
                  INC   A                   (Y będzie testowane w PLOT).
                  ADD   A,L                 Dodaj L' do C' w A, skocz przy
                  JR    C,24F7,D-L-RANGE    przeniesieniu dla dalszych testów.
                  JR    Z,24F9,REPORT-B     Zero bez przeniesienia oznacza
                                            pozycja X-1 jest poza zakresem.
24EC D-L-PLOT     DEC   A                   Odtwórz prawdziwą wartość w A.
                  LD    C,A                 Przenieś ją do C' dla rysowania punktu.
                  CALL  22E5,PLOT-SUB       Narysuj punkt.
                  EXX                       Przełącz na główne rejestry.
                  LD    A,C                 C z powrotem do A, aby kontynuować algorytm.
                  DJNZ  24CE,D-L-LOOP       Skocz wstecz na początek pętli B razy.
                  POP   DE                  Wyczyść stos maszynowy.
                  RET                       Skończone.
24F7 D-L-RANGE    JR    Z,24EC,D-L-PLOT     Zero po przeniesieniu oznacza X w zakresie.

Raport B - Liczba całkowita poza zakresem

24F9 REPORT-B     RST  0008,ERROR-1         Wywołaj procedurę obsługi błędów.
                  DEFB  +0A

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.