|
Serwis Edukacyjny w I-LO w Tarnowie
Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej
Autorzy: dr Ian Logan i dr Frank O'Hara |
©2026 mgr Jerzy Wałaszek
|
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,1793Uwaga: 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.
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.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.
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óć.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 +14Kontynuuj 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.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.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 +FFUwaga: Oczywiście nie jest to błąd w normalnym sensie – raczej skok poza program.
Adres powrotny do STMT-RET jest usuwany ze stosu, co w rezultacie powoduje zignorowanie reszty wiersza.
1BB2 REM POP BC Usuń adres - STMT-RET.
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.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 PPC.
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.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 +16Jest 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.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.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
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.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.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.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 nie znaleziona
1C2E REPORT-2 RST 0008,ERROR-1 Wywołaj procedurę obsługi błędów.
DEFB +01Kontynuuj 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.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óć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'.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 +0BPunkt 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.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.
RETProcedura 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.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 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.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 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 +08Na 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.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-calcElementami 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-calcZostaje 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),DZostaje 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ą
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 +11Ta 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.'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-1Nastę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 +00Ta 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óć.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 +0DKontynuacja – 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).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'.
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).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óć.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óć.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.Argument rozkazu
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.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.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.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.'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 +0AParametr rozkazu RUN jest umieszczany w NEWPPC przez wywołanie procedury
rozkazu
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 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
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 +15Kontynuuj 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.
Na stosie
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.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.Nie istnieje rozkaz FRE języka BASIC w ZX 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.
RETNumer wiersza oraz numer rozkazu, pod które należy wykonać powrót,
zostają pobrane ze stosu
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 +06Okres 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.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.Podczas sprawdzania składni rozkaz
Lecz w czasie uruchomienia rozkaz
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-BYNajpierw 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.)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.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'.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óć.
RETTa 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.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 ':'.
RETW 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 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óć.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
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
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óć.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 +0BPrzyjdź 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 +10Ta procedura zeruje znacznik zera, jeśli jest używany 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óć.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 +13Kontynuuj 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.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
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.
RETFLASH 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-KTeraz 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.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óć.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.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.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
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.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ść.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.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
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
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
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).
Wejście do tej procedury następuje ze współrzędnymi punktu
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
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
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
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ń
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
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.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,
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,
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 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
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2026 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.