Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

Autorzy: dr Ian Logan i dr Frank O'Hara
Tłumaczenie: mgr Jerzy Wałaszek

©2024 mgr Jerzy Wałaszek
I LO w Tarnowie

SPIS TREŚCI

Procedury obsługi magnetofonu

16-kilobajtowy program monitora posiada duży zestaw procedur do obsługi interfejsu magnetofonu kasetowego. Procedury te są podstawą dla poleceń SAVE, LOAD, VERIFY i MERGE języka BASIC.
Punkt wejścia do tych procedur znajduje się pod adresem SAVE-ETC (0605). Jednakże przed tym punktem usytuowane są procedury, które obsługują zapis, ładowanie lub weryfikowanie bajtów. We wszystkich przypadkach bajty mające zostać obsłużone wewnątrz tych procedur są opisane przez parę rejestrów DE zawierającą 'długość' bloku, rejestr indeksowy IX zawierający 'adres bazowy' oraz rejestr A zawierający +00 dla bloku nagłówka lub +FF dla bloku programu/danych.

PROCEDURA 'SA-BYTES'

Procedura ta jest wywoływana w celu zapisu informacji nagłówkowej (z +09BA), a później właściwego bloku programu/danych (z 099E).

04C2 SA-BYTES     LD    HL,+053F            Załaduj wstępnie na stos maszynowy
                  PUSH  HL                  adres - SA/LD-RET.
                  LD    HL,+1F80            Ta stała da rozbiegówkę o długości
                                            około 5 sek. na 'nagłówek'.
                  BIT   7,A                 Skocz naprzód, jeśli jest zapisywany
                  JR    Z,04D0,SA-FLAG      nagłówek.
                  LD    HL,+0C98            Ta stała da rozbiegówkę o długości
                                            około 2 sek. dla bloku programu/danych.
04D0 SA-FLAG      EX    AF,A'F'             Zostaje zachowany znacznik.
                  INC   DE                  ;Długość' zostaje zwiększona
                  DEC   IX                  a 'adres bazowy' zmniejszony, aby zrobić
                                            miejsce na znacznik.
                  DI                        Podczas zapisu wyłączane są przerwania maskowane.
                  LD    A,+02               Ustaw 'MIC wysoki' i brzeg czerwony.
                  LD    B,A                 Wpisz tą wartość do rejestru B.

Następuje teraz wejście do pętli w celu wygenerowania impulsów rozbiegówki. Oba impulsy 'MIC włączone' i 'MIC wyłączone' mają długość po 2.168 taktów T. Przy każdym zboczu sygnału brzeg zmienia się z czerwonego na jasnoniebieski i na odwrót.

Uwaga:             'Zbocze' jest przejściem albo ze stanu wysokiego w niski, albo na odwrót.

04D8 SA-LEADER    DJNZ  04D8,SA-LEADER      Główny okres odmierzania czasu.
                  OUT   (+FE),A             MIC wł./wy., brzeg czerwony/jasnoniebieski,
                  XOR   +0F                 przy każdym przejściu.
                  LD    B,+A4               Główna stała odmierzania czasu.
                  DEC   L                   Zmniejsz dolny licznik.
                  JR    NZ,04D8,SA-LEADER   Skocz wstecz dla kolejnego impulsu.
                  DEC   B                   Wyrównaj dłuższą ścieżkę
                                            (-zredukuj o 13 taktów T).
                  DEC   H                   Zmniejsz górny licznik.
                  JP    P,04D8,SA-LEADER    Skocz wstecz dla kolejnego impulsu
                                            aż do zakończenia rozbiegówki.

Teraz zostaje wysłany impuls synchronizacji.

                  LD    B,+2F
04EA SA-SYNC-1    DJNZ  04EA,SA-SYNC-1      MIC wył. przez 667 taktów T
                                            pomiędzy 'OUT i OUT'.
                  OUT   (+FE),A             MIC wł. i brzeg czerwony.
                  LD    A,+0D               Ustaw 'MIC niski i brzeg jasnoniebieski.
                  LD    B,+37               MIC wł. przez 735 taktów T
04F2 SA-SYNC-2    DJNZ  04F2,SA-SYNC-2      pomiędzy 'OUT i OUT'.
                  OUT   (+FE),A             Teraz MIC wył. i brzeg jasnoniebieski.

Pierwszym zapisanym bajtem będzie znacznik nagłówka programu/danych.

                  LD    BC,+3B0E            +3B jest stałą czasową; +0E to
                                            ustaw 'MIC niski i żółty brzeg'.
                  EX    AF,A'F'             Pobierz znacznik i przekaż go do
                  LD    L,A                 rejestru L do 'wysłania'.
                  JP    0507,SA-START       Skocz naprzód do pętli zapisującej.

Teraz następuje wejście do pętli zapisującej. Pierwszym bajtem do zapisania jest znacznik, za którym następują właściwy bajt danych, a ostatnim przesyłanym bajtem jest bajt parzystości, który jest tworzony na podstawie wartości wszystkich poprzedzających go bajtów.

04FE SA-LOOP      LD    A,D                 Testowany jest licznik 'długości'
                  OR    E                   i zostaje wykonany skok, gdy
                  JR    Z,050E,SA-PARITY    osiągnie on zero.
                  LD    L,(IX+00)           Pobierz kolejny bajt do zapisania.
0505 SA-LOOP-P    LD    A,H                 Pobierz bieżącą 'parzystość'.
                  XOR   L                   Dołącz do niej obecny bajt.
0507 SA-START     LD    H,A                 Uaktualnij 'parzystość'. Zauważ, że
                                            przy wejściu tutaj wartość 'znacznika'
                                            inicjuje 'parzystość'.
                  LD    A,+01               Ustaw 'MIC wysoki i brzeg niebieski'.
                  SCF                       Ustaw znacznik przeniesienia. Będzie on pełnił
                                            rolę 'markera' 8 bitów w bajcie.
                  JP    0525,SA-8-BITS      Skocz naprzód.

Gdy nadejdzie czas przesłania bajtu 'parzystości', to zostaje on przeniesiony do rejestru L w celu zapisu.

050E SA-PARITY    LD    L,H                 Pobierz końcową wartość 'parzystości'.
                  JR    0505,SA-LOOP-P      Skocz wstecz.

Kolejna pętla wewnętrzna tworzy właściwe impulsy. Wejście do pętli znajduje się pod adresem SA-BIT-1 z typem bitu do zapisu oznaczanym za pomocą znacznika przeniesienia. Dla każdego bitu pętla jest wykonywana dwukrotnie, co daje zbocze opadające i rosnące impulsu. Impulsy dla bitu zero są krótsze o 855 taktów T.

0511 SA-BIT-2     LD    A,C                 Przyjdź tutaj przy drugim obiegu
                                            i pobierz 'MIC wyłączony i żółty brzeg'.
                  BIT   7,B                 Ustaw znacznik zera, aby oznaczyć
                                            'drugi obieg'.
0514 SA-BIT-1     DJNZ  0514,SA-BIT-1       Główna pętla czasowa; zawsze
                                            801 taktów T przy drugim obiegu.
                  JR    NC,051C,SA-OUT      Skocz, biorąc krótszą ścieżkę, jeśli
                                            zapisujesz '0'.
                  LD    B,+42               Jednakże przy zapisie '1'
051A SA-SET       DJNZ  051A,SA-SET         dodaj 855 taktów T.
051C SA-OUT       OUT   (+FE),A             Przy pierwszym obiegu 'MIC włączony
                                            i brzeg niebieski' a przy drugim 
                                            'MIC wyłączony i brzeg żółty'.
                  LD    B,+3E               Ustaw stałą czasu dla drugiego
                                            obiegu pętli.
                  JR    NZ,0511,SA-BIT-2    Skocz wstecz na końcu
                  DEC   B                   pierwszego obiegu; inaczej
                                            odzyskaj 13 taktów T.
                  XOR   A                   Wyczyść znacznik przeniesienia i ustaw
                  INC   A                   A na +01 (MIC włączony i brzeg niebieski}
                                            zanim zaczniesz wykonywać dalej
                                            'pętlę 8 bitów'.

Do 'pętli 8 bitów' następuje początkowo wejście z całym bajtem w rejestrze L i z ustawionym znacznikiem przeniesienia. Jednakże następują do niej kolejne wejścia po każdym przesłanym bajcie aż do momentu, gdy 'marker' przejdzie do znacznika przeniesienia, pozostawiając pustym rejestr L.

0525 SA-8-BITS    RL    L                   Przesuń bit 7 do przeniesienia a
                                            'marker' w lewo.
                  JP    NZ,0514,SA-BIT-1    zapisz ten bit o ile nie skończono
                                            zapisu całego bajtu.
                  DEC   DE                  Zmniejsz 'licznik'.
                  INC   IX                  Przesuń do przodu 'adres bazowy'.
                  LD    B,+31               Ustaw stałą czasu dla pierwszego bitu
                                            następnego bajtu.
                  LD    A,+7F               Wróć do SA/LD-RET, jeśli
                  IN    A,(+FE)             naciśnięto klawisz BREAK.
                  RRA
                  RET   NC
                  LD    A,D                 Inaczej testuj 'licznik'
                  INC   A                   i skocz wstecz, nawet gdy
                  JP    NZ,04FE,SA-LOOP     osiągnął zero (aby przesłać
                                            bajt 'parzystości').
                  LD    B,+3B               Wyjdź, gdy 'licznik'
053C SA-DELAY     DJNZ  053C,SA-DELAY       osiągnie +FFFF. Lecz najpierw
                  RET                       stwórz małe opóźnienie.

Uwaga: Bit 0 da impuls 'MIC wyłączony' przez 855 taktów T, po którym nastąpi impuls 'MIC włączony' przez kolejne 855 taktów T. Natomiast bit 1 da impulsy dokładnie dwa razy dłuższe. Zwróć również uwagę, że nie ma przerw ani pomiędzy impulsem synchronizacji i pierwszym bitem znacznika, ani pomiędzy bajtami.

PROCEDURA 'SA/LD-RET'

Ta procedura jest wspólna dla zapisu i odczytu,

Brzeg zostaje ustawiony na pierwotny kolor i po raz ostatni jest testowany klawisz BREAK.

053F SA/LD-RET    PUSH  AF                  Zachowaj znacznik przeniesienia. (Jest on wyzerowany
                                            po błędzie ładowania.)
                  LD    A,(BORDCR)          Pobierz oryginalny kolor brzegu
                  AND   +38                 ze zmiennej systemowej.
                  RRCA                      Przesuń kolor brzegu
                  RRCA                      na bity 2, 1 i 0.
                  OUT   (+FE),A             Ustaw brzeg na jego oryginalny kolor.
                  LD    A.+7F               Po raz ostatni odczytaj klawisz
                  IN    A,(+FE)             BREAK.
                  RRA
                  EI                        Włącz przerwania maskowane.
                  JR    C,0554,SA/LD-END    Skocz, chyba że należy zrobić przerwę.

Raport D - BREAK-CONT powtarza

0552 REPORT-D     RST   0008,ERROR-l        Wywołaj procedurę obsługującą
                  DEFB  +0C                 błędy.

Kontynuuj tutaj.

0554 SA/LD-END    POP   AF                  Odzyskaj znacznik przeniesienia.
                  RET                       Wróć do procedury wywołującej.

PROCEDURA 'LD-BYTES'

Ta procedura jest wywoływana do załadowania informacji nagłówkowej (z 07BE), a później do załadowania lub weryfikacji właściwego bloku danych (z 0802).

0556 LD-BYTES     INC   D                   To zeruje znacznik zera.
                                            (D nie może zawierać +FF.)
                  EX    AF,A'F'             Rejestr A przechowuje +00 przy nagłówku
                                            i +FF przy bloku danych.
                                            Znacznik przeniesienia jest wyzerowany
                                            przy weryfikacji i ustawiony przy ładowaniu.
                  DEC   D                   Przywróć w D jego pierwotną zawartość.
                  DI                        Teraz wyłącz przerwania maskowane.
                  LD    A,+0F               Brzeg na biało.
                  OUT   (+FE),A
                  LD    HL,+053F            Załaduj wstępnie na stos maszynowy
                  PUSH  HL                  adres - SA/LD-RET.
                  IN    A,(+FE)             Wykonaj początkowy odczyt portu '254'
                  RRA                       Obróć odczytany bajt, lecz
                  AND   +20                 zachowaj tylko bit EAR,
                  OR    +02                 Ustaw czerwony brzeg.
                  LD    C,A                 Umieść tę wartość w rejestrze C. -
                                            (+22 przy 'wyłączonym' i +02 przy 'włączonym'
                                            - bieżący stan EAR.)
                  CP    A                   Ustaw znacznik zera.

Pierwszy etap odczytu taśmy wymaga stwierdzenia, czy faktycznie istnieje pulsujący sygnał (tj. zbocza narastające i opadające.)

056B LD-BREAK     RET   NZ                  Wróć, jeśli jest naciśnięty klawisz BREAK.
056C LD-START     CALL  05E7,LD-EDGE-1      Wróć z wyzerowanym znacznikiem przeniesienia,
                  JR    NC,056B,LD-BREAK    jeśli nie ma krawędzi w ciągu
                                            około 14.000 taktów T. Lecz jeśli
                                            jakaś krawędź zostanie stwierdzona, to brzeg
                                            przyjmie kolor jasnoniebieski.

W następnym etapie komputer czeka chwilę i sprawdza, czy sygnał wciąż pulsuje.

                  LD    HL,+0415            Długość tego okresu oczekiwania
0574 LD-WAIT      DJNZ  0574,LD-WAIT        wyniesie prawie jedną sekundę.
                  DEC   HL
                  LD    A,H
                  OR    L
                  JR    NZ,0574,LD-WAIT
                  CALL  05E3,LD-EDGE-2      Kontynuuj tylko wtedy, jeśli dwa zbocza
                  JR    NC,056B,LD-BREAK    zostaną znalezione w dozwolonym okresie czasu.

Teraz zaakceptuj tylko sygnał rozbiegówki.

0580 LD-LEADER    LD    B,+9C               Stała czasu.
                  CALL  05E3,LD-EDGE-2      Kontynuuj tylko wtedy, jeśli dwa zbocza
                  JR    NC,056B,LD-BREAK    zostaną znalezione w dozwolonym okresie czasu.
                  LD    A,+C6               Jednakże te zbocza musiały być znalezione
                  CP    B                   w okresie około
                  JR    NC,056C,LD-START    3.000 taktów T każde.
                  INC   H                   Zliczaj pary zboczy w rejestrze H
                  JR    NZ,0580,LD-LEADER   aż zostanie znalezione 256 par.

Po rozbiegówce nadchodzi zbocze opadające i rosnące impulsu synchronizacji.

058F LD-SYNC      LD    B,+C9               Stała czasu.
                  CALL  05E7,LD-EDGE-1      Rozpatrywane jest każde zbocze, aż
                  JR    NC,056B,LD-BREAK    zostaną znalezione dwa zbocza blisko
                  LD    A,B                 siebie - będzie to zbocze startowe
                  CP    +D4                 i zbocze końcowe
                  JR    NC,058F,LD-SYNC     impulsu synchronizacji.
                  CALL  05E7,LD-EDGE-1      Końcowe zbocze impulsu
                  RET   NC                  'włączony' musi istnieć.
                                            (Wróć przy wyzerowanym znaczniku przeniesienia.)

Bajty nagłówka bloku programy/danych mogą teraz zostać załadowane lub zweryfikowane. Lecz pierwszym bajtem jest znacznik typu.

                  LD    A,C                 Od teraz kolor brzegu
                  XOR   +03                 będzie niebieski lub żółty.
                  LD    C,A
                  LD    H,+00               Inicjuj bajt 'sprawdzania parzystości'
                                            na zero.
                  LD    B,+B0               Ustaw stałą czasu dla
                                            bajtu znacznika.
                  JR    05C8,LD-MARKER      Skocz naprzód do pętli ładującej bajty.

Pętla ładująca bajty jest wykorzystywana do odczytywania bajtów jeden po drugim. Pierwszym jest bajt znacznika. Za nim podążają bajty danych, a ostatnim jest bajt parzystości.

05A9 LD-LOOP      EX    AF,A'F'             Pobierz znaczniki.
                  JR    NZ,05B3,LD-FLAG     Skocz do przodu tylko wtedy,
                                            gdy obsługiwany jest pierwszy bajt.
                  JR    NC,05BD,LD-VERIFY   Skocz naprzód przy weryfikacji taśmy.
                  LD    (IX+00),L           Jeśli wymagane, dokonaj rzeczywistego
                                            odczytu.
                  JR    05C2,LD-NEXT        Skocz naprzód, aby załadować kolejny bajt.
05B3 LD-FLAG      RL    C                   Przechowaj tymczasowo w bezpiecznym miejscu
                                            znacznik przeniesienia.
                  XOR   L                   Wróć teraz, jeśli znacznik typu
                  RET   NZ                  nie zgadza się z pierwszym bajtem
                                            na taśmie. (Znacznik przeniesienia wyzerowany.)
                  LD    A,C                 Teraz przywróć znacznik przeniesienia.
                  RRA
                  LD    C,A
                  INC   DE                  Zwiększ licznik, aby skompensować
                  JR    05CA,LD-DEC         jego 'zmniejszenie' po skoku.

Jeśli blok danych jest weryfikowany, to świeżo załadowany bajt jest testowany z bajtem oryginalnym.

05BD LD-VERlFY    LD    A,(IX+00)           Pobierz oryginalny bajt.
                  XOR   L                   Porównaj go z nowym bajtem.
                  RET   NZ                  Wróć, jeśli nie są takie same. (Znacznik
                                            przeniesienia wyzerowany.)

Nowy bajt może teraz być odczytany z taśmy.

05C2 LD-NEXT      INC   IX                  Zwiększ adres docelowy.
05C4 LD-DEC       DEC   DE                  Zmniejsz licznik.
                  EX    AF,A'F'             Zachowaj znaczniki.
                  LD    B,+B2               Ustaw stałą czasu.
05C8 LD-MARKER    LD    L,+01               Wyzeruj rejestr odbiorczy z wyjątkiem
                                            bitu 'markera'.

Zostaje użyta pętla 'LD-8-BITS' do zebrania bajtu w rejestrze L.

05CA LD-8-BITS    CALL  05E3,LD-EDGE-2      Znajdź długość impulsów 'wyłączony' i
                                            'włączony' dla kolejnego bitu.
                  RET   NC                  Wróć, jeśli zostanie przekroczony zadany
                                            okres czasu. (Znacznik przeniesienia wyzerowany.)
                  LD    A,+CB               Porównaj tę długość z
                                            2.400 taktami T; zerując znacznik przeniesienia
                  CP    B                   dla '0' i ustawiając go dla '1'.
                  RL    L                   Dołącz nowy bit do rejestru L.
                  LD    B,+B0               Ustaw stałą czasu dla następnego bitu.
                  JP    NC,05CA,LD-8-BITS   Skocz wstecz, jeśli wciąż są bity do pobrania.

Bajt 'parzystości' musi być uaktualniany przy każdym nowym bajcie.

                  LD    A,H                 Pobierz bajt 'parzystości'
                  XOR   L                   i dołącz do niego nowy bajt.
                  LD    H,A                 Zachowaj go z powrotem.

Przez pętlę są wykonywane obiegi aż 'licznik' osiągnie zero. W tym punkcie bajt 'parzystości' powinien zawierać zero.

                  LD    A,D                 Wykonaj kolejny obieg, jeśli para rejestrów DE
                  OR    E                   nie zawiera zera.
                  JR    NZ,05A9,LD-LOOP
                  LD    A,H                 Pobierz bajt 'parzystości'.
                  CP    +01                 Wróć z ustawionym znacznikiem przeniesienia,
                  RET                       jeśli jego wartość wynosi zero.
                                            (Znacznik przeniesienia wyzerowany przy błędzie.)

PROCEDURY 'LD-EDGE-2' I 'LD-EDGE-1'

Te dwie procedury tworzą najważniejszą część operacji odczytywania i weryfikacji.

Do procedur wchodzi się ze stałą czasu w rejestrze B oraz z poprzednim kolorem brzegu i 'typem-zbocza' w rejestrze C.

Procedury wracają z ustawionym znacznikiem przeniesienia, jeśli została znaleziona wymagana liczba 'zbocz' w dozwolonym czasie, a zmiana w rejestrze B pokazuje, ile dokładnie zajęło czasu znalezienie tych 'zbocz' sygnału.

Jeśli pojawi się błąd, to znacznik przeniesienia zostanie wyzerowany. W takim przypadku wyzerowany znacznik zera sygnalizuje naciśnięcie klawisza BREAK, a ustawiony upłynięcie zadanego czasu.

Punkt wejścia LD-EDGE-2 jest używany, gdy jest wymagana długość pełnego impulsu, a LD-EDGE-1 jest używany do znalezienia czasu przed następnym 'zboczem'.

05E3 LD-EDGE-2    CALL  05E7,LD-EDGE-1      W rezultacie wywołaj LD-EDGE-1 dwukrotnie;
                  RET   NC                  wracając z pomiędzy wywołań przy błędzie.
05E7 LD-EDGE-1    LD    A,+16               Czekaj 358 taktów T przed
05E9 LD-DELAY     DEC   A                   wejściem do pętli próbkującej.
                  JR    NZ,05E9,LD-DELAY
                  AND   A

Teraz następuje wejście do pętli próbkującej. Wartość w rejestrze B jest zwiększana przy każdym przebiegu; 'przekroczenie czasu' następuje, gdy B osiągnie zero.

05ED LD-SAMPLE    INC   B                   Zliczaj każdy przebieg.
                  RET   Z                   Wróć z wyzerowanym przeniesieniem i ustawionym
                                            znacznikiem zera przy 'przekroczeniu czasu'.
                  LD    A,+7F               Czytaj z portu +7FFE.
                  IN    A,(+FE)             tj. BREAK i EAR.
                  RRA                       Przesuń bajt.
                  RET   NC                  Wróć z wyzerowanym przeniesieniem i znacznikiem zera,
                                            jeśli został naciśnięty klawisz BREAK.
                  XOR   C                   Teraz sprawdź ten bajt na
                  AND   +20                 'ostatni typ zbocza'; skocz wstecz,
                  JR    Z,05ED,LD-SAMPLE    chyba że się zmieniło to zbocze.

Znaleziono nowe 'zbocze' w dozwolonym czasie poszukiwań. Zatem zmień kolor brzegu i ustaw znacznik przeniesienia.

                  LD    A,C                 Zmień 'typ ostatniego zbocza'
                  CPL                       i kolor brzegu.
                  LD    C,A
                  AND   +07                 Zachowaj jedynie kolor brzegu.
                  OR    +08                 Ustaw 'MIC wyłączony'.
                  OUT   (+FE),A             Zmień kolor brzegu (czerwony/jasnoniebieski
                                            lub niebieski/żółty).
                  SCF                       ustaw informację o powodzeniu poszukiwań
                  RET                       przed wykonaniem powrotu.

Uwaga: Procedura LD-EDGE-1 zajmuje 465 taktów T, plus dodatkowe 58 taktów T dla każdego przebiegu bez powodzenia w pętli próbkującej.

Na przykład, dlatego przy oczekiwaniu na impuls synchronizacji (zobacz na LD-SYNC pod adresem 058F) zezwala się na dodatkowe dziesięć obiegów przez pętlę próbkującą. Skutkiem tego poszukiwanie następnego zbocza dokonywane jest z grubsza w przeciągu  1.100 taktów T (465 + 10 x 58 + narzut). Powiedzie się to dla niskiego impulsy synchronizacji, który następuje po długich impulsach rozbiegówki.

PROCEDURY POLECEŃ 'SAVE, LOAD, VERIFY I MERGE'

Punkt wejścia SAVE-ETC jest używany dla wszystkich czterech rozkazów. Jednakże wartość przechowywana w T-ADDR umożliwia rozróżnienie pomiędzy nimi. Pierwsza część poniższej procedury zajmuje się konstruowaniem 'informacji nagłówkowej' w obszarze roboczym.

0605 SAVE-ETC     POP   AF                  Porzuć adres - SCAN-LOOP.
                  LD    A,(T-ADDR-lo)       Zmniejsz młodszy bajt T-ADDR o +E0;
                  SUB   +E0                 dając +00 przy SAVE, +01 przy LOAD,
                  LD    (T-ADDR-lo),A       +02 przy VERIFY +03 przy MERGE.
                  CALL  1C8C,EXPT-EXP       Przenieś parametry 'nazwy' na stos kalkulatora.
                  CALL  2530,SYNTAX-Z       Jeśli sprawdza się składnię,
                  JR    Z,0652,SA-DATA      to skocz naprzód.
                  LD    BC,+0011            Zezwól na siedemnaście bajtów
                  LD    A,(T-ADDR-lo)       na nagłówek dla SAVE, lecz na
                  AND   A                   trzydzieści cztery dla pozostałych
                  JR    Z,0621,SA-SPACE     rozkazów.
                  LD    C,+22
0621 SA-SPACE     RST   0030,BC-SPACES      W przestrzeni roboczej zarezerwuj
                                            wymaganą ilość bajtów.
                  PUSH  DE                  Skopiuj adres startowy do
                  POP   IX                  pary rejestrów IX.
                  LD    B,+0B               Nazwa programu może zawierać
                  LD    A,+20               do dziesięciu znaków, lecz
0629 SA-BLANK     LD    (DE),A              najpierw wprowadź jedenaście spacji
                  INC   DE                  do przygotowanego obszaru.
                  DJNZ  0629,SA-BLANK
                  LD    (IX+01),+FF         Pusta nazwa składa się tylko z +FF.
                  CALL  2BF1,STK-FETCH      Parametry nazwy są pobierane i testowana
                                            jest jej długość.
                  LD    HL,+FFF6            To jest '-10'.
                  DEC   BC                  W wyniku skocz naprzód, jeśli
                  ADD   HL,BC               długość nazwy nie jest
                  INC   BC                  zbyt duża. (tj. nie więcej niż
                  JR    NC,064B,SA-NAME     dziesięć znaków.)
                  LD    A,(T-ADDR-lo)       Lecz pozwól na ładowanie,
                  AND   A                   weryfikację i łączenie
                  JR    NZ,0644,SA-NULL     programów z 'zerowymi' nazwami lub
                                            nazwami dodatkowo długimi.

Raport F - Zła nazwa pliku

0642 REPORT-F     RST   0008,ERROR-1        Wywołaj procedurę obsługującą
                  DEFB  +0E                 błędy.

Kontynuuj obsługę nazwy programu.

0644 SA-NULL      LD    A,B                 Skocz naprzód, jeśli nazwa
                  OR    C                   posiada 'zerową' długość.
                  JR    Z,0652,SA-DATA
                  LD    BC,+000A            lecz obetnij dłuższe nazwy.

Teraz nazwa zostaje przeniesiona do obszaru roboczego (od drugiej pozycji naprzód).

064B SA-NAME      PUSH  IX                  Kopiuj adres startu do
                  POP   HL                  pary rejestrów HL.
                  INC   HL                  Przejdź do drugiej pozycji.
                  EX    DE,HL               Zamień ze sobą wskaźniki i
                  LDIR                      przenieś nazwę.

Teraz zostają rozpatrzone liczne parametry, które mogą występować w danym rozkazie. Rozpocznij od obsługi 'xxx "nazwa" DATA'.

0652 SA-DATA      RST   0018,GET-CHAR       Czy bieżącym kodem jest
                  CP    +E4                 symbol 'DATA'?
                  JR    NZ,06A0,SA-SCR$     Skocz, jeśli nie.
                  LD    A,(T-ADDR-lo)       Jednakże nie może być
                  CP    +03                 'MERGE nazwa DATA'.
                  JP    Z,1C8A,REPORT-C
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  28B2,LOOK-VARS      Poszukaj w obszarze zmiennych tej tablicy.
                  SET   7,C                 Ustaw bit 7 nazwy tablicy.
                  JR    NC,0672,SA-V-OLD    Skocz, jeśli obsługujemy istniejącą
                                            tablicę.
                  LD    HL,+0000            Ustaw 'użycie nowej tablicy'.
                  LD    A,(T-ADDR-lo)       Rozpatrz wartość w T-ADDR
                  DEC   A                   i zgłoś błąd, jeśli jest próba
                  JR    Z,0685,SA-V-NEW     zapisu lub weryfikacji nowej tablicy.

Raport 2 - Zmienna nieznaleziona

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

Kontynuuj obsługę istniejącej tablicy.

0672 SA-V-OLD     JP    NZ,1C8A,REPORT-C    Uwaga: To nie potrafi odrzucać
                                            prostych łańcuchów.
                  CALL  2530,SYNTAX-Z       Skocz do przodu, jeśli jest 
                  JR    Z,0692,SA-DATA-1    sprawdzana składnia.
                  INC   HL                  Wskaż młodszy bajt długości zmiennej.
                  LD    A,(HL)              Młodszy bajt długości idzie do
                  LD    (IX+0B),A           obszaru roboczego; a za nim
                  INC   HL                  starszy bajt długości.
                  LD    A,(HL)
                  LD    (IX+0C),A
                  INC   HL                  Przeskocz bajty długości.

Następna część jest wspólna zarówno dla 'starych' jak i 'nowych' tablic. Uwaga: błąd ścieżki składni.

0685 SA-V-NEW     LD    (IX+0E),C           Kopiuj nazwę tablicy.
                  LD    A,+01               Załóż tablicę liczbową.
                  BIT   6,C                 Jeśli tak jest, to skocz.
                  JR    Z,068F,SA-V-TYPE
                  INC   A                   Jest to tablica znaków.
068F SA-V-TYPE    LD    (IX+00),A           Zachowaj 'typ' w pierwszym bajcie
                                            obszaru nagłówka.

Ostatnia część polecenia jest sprawdzana przed połączeniem z innymi ścieżkami przetwarzania.

0692 SA-DATA-1    EX    DE,HL               Zachowaj wskaźnik w DE.
                  RST   0020,NEXT-CHAR      Czy następnym znakiem jest
                  CP    +29                 ')' ?
                  JR    NZ,0672,SA-V-OLD    Zgłoś błąd C, jeśli tak nie jest.
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  1BEE,CHECK-END      Jeśli jest sprawdzana składnia, przejdź do
                                            następnego polecenia.
                  EX    DE,HL               Wróć ze wskaźnikiem do pary rejestrów HL
                  JP    075A,SA-ALL         przed skokiem naprzód. (Wskaźnik adresuje
                                            początek istniejącej zawartości tablicy.)

Teraz rozpatrz SCREEN$.

06A0 SA-SCR$      CP    +AA                 Czy bieżącym kodem jest symbol SCREEN$'?
                  JR    NZ,06C3,SA-CODE     Skocz, jeśli nie.
                  LD    A,(T-ADDR-lo)       Jednakże nie może być
                  CP    +03                 'MERGE nazwa SCREEN$'.
                  JP    Z,1C8A,REPORT-C
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  1BEE,CHECK-END      Jeśli jest sprawdzana składnia,
                                            to przejdź do następnego rozkazu.
                  LD    (IX+0B),+00         Obszar wyświetlania z atrybutami
                  LD    (IX+0C),+1B         zajmuje +1800 bajtów od adresu
                  LD    HL,+4000            +4000; szczegóły te zostają
                  LD    (IX+0D),L           umieszczone w nagłówku
                  LD    (IX+0E),H           w obszarze roboczym.
                  JR    0710,SA-TYPE-3      Skocz naprzód.

Teraz rozpatrz CODE.

06C3 SA-CODE      CP    +AF                 Czy bieżącym kodem jest symbol 'CODE'?
                  JR    NZ,0716,SA-LINE     Skocz, jeśli nie.
                  LD    A,(T-ADDR-lo)       Jednakże nie może być
                  CP    +03                 'MERGE nazwa CODE'.
                  JP    Z,1C8A,REPORT-C
                  RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  2048,PR-ST-END      Skocz naprzód, jeśli ten rozkaz
                  JR    NZ,06E1,SA-CODE-1   jeszcze się nie zakończył.
                  LD    A,(T-ADDR-lo)       Jednakże nie może być samo
                  AND   A                   'SAVE nazwa CODE'.
                  JP    Z,1C8A,REPORT-C
                  CALL  1CE6,USE-ZERO       Umieść zero na stosie kalkulatora
                                            - jako 'początek'.
                  JR    06F0,SA-CODE-2      Skocz naprzód.

Poszukaj 'adresu początku'.

06E1 SA-CODE-1    CALL  1C82,EXPT-1NUM      Pobierz pierwszą liczbę.
                  RST   0018,GET-CHAR       Czy bieżącym znakiem jest
                  CP    +2C                 ',' ?
                  JR    Z,06F5,SA-CODE-3    Skocz, jeśli jest - liczba była
                                            'adresem początku'.
                  LD    A,(T-ADDR-lo)       Jednakże odmów 'SAVE nazwa CODE'
                  AND   A                   które nie posiada
                  JP    Z,1C8A,REPORT-C     'początku' i jakiejś 'długości'.
06F0 SA-CODE-2    CALL  1CE6,USE-ZERO       Umieść zera na stosie kalkulatora
                                            - jako 'długość'.
                  JR    06F9,SA-CODE-4      Skocz naprzód.

Ponieważ określono długość, pobierz ją.

06F5 SA-CODE-3    RST   0020,NEXT-CHAR      Zwiększ CH-ADD.
                  CALL  1C82,EXPT-1NUM      Pobierz 'długość'.

Parametry są teraz umieszczane w obszarze nagłówka w przestrzeni roboczej.

06F9 SA-CODE-4    CALL  1BEE,CHECK-END      Lecz przy sprawdzaniu składni, przejdź teraz
                                            do następnego polecenia.
                  CALL  1E99,FIND-INT2      Skompresuj 'długość' w
                  LD    (IX+0B),C           parze rejestrów BC
                  LD    (IX+0C),B           i zapisz ją.
                  CALL  1E99,FIND-INT2      Skompresuj 'adres początku'
                  LD    (IX+0D),C           w parze rejestrów BC
                  LD    (IX+0E),B           i zapisz ją.
                  LD    H,B                 Jak zwykle przenieś 'wskaźnik'
                  LD    L,C                 do pary rejestrów HL.

SCREEN$ i CODE mają typ 3.

0710 SA-TYPE-3    LD    (IX+00),+03         Wprowadź numer 'typu'.
                  JR    075A,SA-ALL         Dołącz do innych ścieżek.

Teraz rozpatrz LINE; to koniec parametrów.

0716 SA-LINE      CP    +CA                 Czy bieżącym kodem jest
                                            symbol 'LINE'?
                  JR    Z,0723,SA-LINE-1    Skocz, jeśli tak.
                  CALL  1BEE,CHECK-END      Przejdź do następnego polecenia przy
                                            sprawdzaniu składni.
                  LD    (IX+0E),+80         Gdy nie ma dalszych parametrów,
                                            zostaje wprowadzone +80.
                  JR    073A,SA-TYPE-0      Skocz naprzód.

Pobierz 'numer wiersza', który musi następować za LINE.

0723 SA-LINE-1    LD    A,(T-ADDR-lo)       Jednakże zezwól jedynie na
                  AND   A                   'SAVE nazwa LINE liczba'.
                  JP    NZ,1C8A,REPORT-C
                  RST   0020,NEXT-Char      Zwiększ CH-ADD.
                  CALL  1C82,EXPT-1NUM      Przekaż tę liczbę na stos kalkulatora.
                  CALL  1BEE,CHECK-END      Przejdź do następnego polecenia przy
                                            sprawdzaniu składni.
                  CALL  1E99,FIND-INT2      Kompresuj 'numer wiersza'
                  LD    (IX+0D),C           w parze rejestrów BC
                  LD    (IX+0E),B           i zapisz go.

LINE bez dalszych parametrów posiada typ 0.

073A SA-TYPE-0    LD    (IX+00),+00         Wprowadź numer 'typu'.

Parametry opisujące program wraz z jego zmiennymi są znajdowane i umieszczane w obszarze nagłówka w przestrzeni roboczej.

                  LD    HL,(E-LINE)         Wskaźnik końca obszaru zmiennych.
                  LD    DE,(PROG)           Wskaźnik początku programu BASIC.
                  SCF                       Teraz wykonaj odejmowanie,
                  SBC   HL,DE               aby znaleźć długość
                  LD    (IX+0B),L           'programu + zmienne'; zapisz wynik.
                  LD    (IX+0C),H
                  LD    HL,(VARS)           Powtórz operację, lecz teraz
                  SBC   HL,DE               zapisz jedynie długość 'programu'.
                  LD    (IX+0F),L
                  LD    (IX+10),H
                  EX    DE,HL               Jak zwykle, przenieś ten wskaźnik do
                                            pary rejestrów HL.

We wszystkich przypadkach informacja nagłówka została teraz przygotowana.

Komórka 'IX+00' zawiera numer typu.
Komórki od 'IX+01 do IX+0A' zawierają nazwę (+FF w 'IX+01', jeśli jest pusta).
Komórki 'IX+0B i IX+0C' zawierają liczbę bajtów w 'bloku danych'.
Komórki od 'IX+0D do IX+10' zawierają różne parametry, których dokładne znaczenie zależy od 'typu'.

Procedura jest wykonywana dalej, a jej pierwszym zadaniem jest rozdzielenie SAVE od LOAD, VERIFY i MERGE.

075A SA-ALL       LD    A,(T-ADDR-lo)       Skocz naprzód, jeśli obsługiwany jest
                  AND   A                   rozkaz SAVE.
                  JP    Z,0970,SA-CONTRL

W przypadku rozkazu LOAD, VERIFY lub MERGE pierwsze siedemnaście bajtów 'obszaru nagłówka' w przestrzeni roboczej zawiera przygotowaną informację zgodnie z wyszczególnieniem powyżej; a nadszedł czas, aby pobrać nagłówek z taśmy.

                  PUSH  HL                  Zachowaj wskaźnik 'przeznaczenia'.
                  LD    BC,+0011            Utwórz w parze rejestrów IX adres bazowy
                  ADD   IX,BC               drugiego 'obszaru nagłówka'.

Teraz wejdź do pętli, która zostanie opuszczona dopiero po odczycie 'nagłówka'.

0767 LD-LOOK-H    PUSH  IX                  Utwórz kopię adresu bazowego.
                  LD    DE,+0011            Załaduj siedemnaście bajtów.
                  XOR   A                   Sygnalizuj 'nagłówek'.
                  SCF                       Sygnalizuj 'odczyt'.
                  CALL  0556,LD-BYTES       Teraz poszukaj nagłówka.
                  POP   IX                  Odtwórz adres bazowy.
                  JR    NC,0767,LD-LOOK-H   Wykonuj pętlę aż do odczytu z sukcesem.

Nowy 'nagłówek' zostaje teraz wyświetlony na ekranie, lecz procedura będzie kontynuowała jedynie wtedy, gdy nowy nagłówek pasuje do starego.

                  LD    A,+FE               Upewnij się, że kanał 'S'
                  CALL  1601,CHAN-OPEN      jest otwarty.
                  LD    (SCR-CT),+03        Ustaw licznik przewinięć.
                  LD    C,+80               Sygnalizuj 'nazwy się nie zgadzają'.
                  LD    A,(IX+00)           Porównaj 'nowy' typ
                  CP    (IX-11)             ze 'starym' typem.
                  JR    NZ,078A,LD-TYPE     Skocz, jeśli te 'typy' są różne.
                  LD    C,+F6               Lecz jeśli są takie same, to sygnalizuj
                                            'dziesięć znaków do porównania'.
078A LD-TYPE      CP    +04                 Oczywiście nagłówek zawiera śmieci,
                  JR    NC,0767,LD-LOOK-H   jeśli ma typ równy 4 lub więcej.

Zostaje wydrukowana odpowiednia wiadomość - 'Program:', 'Number array:', 'Character array:' lub 'Bytes:'.

                  LD    DE,+09C0            Adres bazowy bloku z wiadomościami.
                  PUSH  BC                  Zachowaj rejestr C podczas
                  CALL  0C0A,PO-MSG         wyświetlania odpowiedniej
                  POP   BC                  wiadomości.

Zostaje wyświetlona 'nowa nazwa' a następnie obie nazwy, stara i nowa, są porównywane.

                  PUSH  IX                  Ustaw parę rejestrów DE
                  POP   DE                  na adres 'nowego typu', a
                  LD    HL,+FFF0            parę rejestrów HL na
                  ADD   HL,DE               'starą nazwę'.
                  LD    B,+0A               Do rozpatrzenia jest dziesięć znaków.
                  LD    A,(HL)              Skocz naprzód, jeśli porównanie ma być z
                  INC   A                   rzeczywistą nazwą.
                  JR    NZ,07A6,LD-NAME
                  LD    A,C                 Lecz, jeśli 'stara nazwa' jest 'pusta'
                  ADD   A,B                 to sygnalizuj 'dziesięć znaków już się zgadza'.
                  LD    C,A

W petli są wyświetlane znaki 'nowej nazwy'. Nazwa zostanie zaakceptowana, jeśli licznik zliczy przynajmniej do zera.

07A6 LD-NAME      INC   DE                  Po kolei rozpatrz znaki 'nowej nazwy'.
                  LD    A,(DE)
                  CP    (HL)                Porównuj je z odpowiednimi znakami
                  INC   HL                  'starej nazwy'.
                  JR    NZ,07AD,LD-CH-PR    Nie zliczaj ich, jeśli nie są
                  INC   C                   takie same.
07AD LD-CH-PR     RST   0010,PRINT-A-1      Wyświetl 'nowy' znak.
                  DJNZ  07A6,LD-NAME        W pętli przetwórz dziesięć znaków.
                  BIT   7,C                 Zaakceptuj nazwę tylko wtedy, gdy
                  JR    NZ,0767,LD-LOOK-H   licznik osiągnął zero.
                  LD    A,+0D               Za 'nową nazwą' wyświetl
                  RST   0010,PRINT-A-1      'końca wiersza'.

Znaleziony został właściwy nagłówek i nadszedł czas na osobne rozpatrzenie trzech rozkazów LOAD, VERIFY i MERGE.

                  POP   HL                  Pobierz wskaźnik.
                  LD    A,(IX+00)           'SCREEN$ i CODE' są obsługiwane
                  CP    +03                 przez VERIFY.
                  JR    Z,07CB,VR-CONTRL
                  LD    A,(T-ADDR-lo)       Skocz naprzód, jeśli użyty został
                  DEC   A                   rozkaz LOAD.
                  JP    Z,0808,LD-CONTRL
                  CP    +02                 Skocz naprzód, jeśli użyty został
                  JP    Z,08B6,ME-CONTRL    rozkaz MERGE; kontynuuj przy rozkazie VERIFY.

PROCEDURA STERUJĄCA 'WERYFIKACJĄ'

Proces weryfikacji wymaga załadowania bloku danych po jednym bajcie, lecz bajty te nie są zapisywane - jedynie sprawdzane. Ta procedura jest również wykorzystywana do odczytu bloków danych, które opisano za pomocą SCREEN$ i CODE.

07CB VR-CONTRL    PUSH  HL                  Zachowaj 'wskaźnik'.
                  LD    L,(IX-06)           Pobierz 'liczbę bajtów'
                  LD    H,(IX-05)           opisaną w 'starym' nagłówku.
                  LD    E,(IX+0B)           Pobierz również tę liczbę z
                  LD    D,(IX+0C)           'nowego' nagłówka.
                  LD    A,H                 Skocz naprzód, jeśli 'długość'
                  OR    L                   nie jest określona.
                  JR    Z,07E9,VR-CONT-1    tj. jedynie 'LOAD nazwa CODE'.
                  SBC   HL,DE               Zgłoś błąd R, jeśli jest próba
                  JR    C,0806,REPORT-R     odczytu większego bloku niż zażądano.
                  JR    Z,07E9,VR-CONT-1    Zaakceptuj równe 'długości'.
                  LD    A,(IX+00)           Również zgłoś błąd R przy próbie
                  CP    +03                 weryfikacji bloków o różnym
                  JR    NZ,0806,REPORT-R    rozmiarze. ('Stara długość'
                                            większa niż 'nowa długość'.)

Procedura wykonuje się dalej, rozpatrując 'wskaźnik przeznaczenia'.

07E9 VR-CONT-1    POP   HL                  Pobierz ten 'wskaźnik', tj. adres 'początku'.
                  LD    A,H                 Zostanie on użyty o ile nie
                  OR    L                   wynosi zero, w którym to przypadku
                  JR    NZ,07F4,VR-CONT-2   zamiast niego zostanie użyty 'początek'
                  LD    L,(IX+0D)           z 'nowego' nagłówka.
                  LD    H,(IX+0E)

Teraz rozpatrzony zostaje znacznik weryfikacji/odczytu i procedura wykona właściwe ładowanie.

07F4 VR-CONT-2    PUSH  HL                  Przenieś 'wskaźnik' do
                  POP   IX                  pary rejestrów IX.
                  LD    A,(T-ADDR-lo)       Skocz naprzód, chyba że używany jest
                  CP    +02                 rozkaz VERIFY; ze znacznikiem
                  SCF                       przeniesienia sygnalizującym
                  JR    NZ,0800,VR-CONT-3   'odczyt'
                  AND   A                   Sygnalizuj 'weryfikację'.
0800 VR-CONT-3    LD    A,+FF               Sygnalizuj 'tylko akceptuj blok danych'
                                            przed załadowaniem tego bloku.

PROCEDURA 'ODCZYTU BLOKU DANYCH'

Ta procedura jest wspólna dla wszystkich procedur 'odczytujących'. W przypadku rozkazów LOAD i VERIFY wykonuje ona pełny powrót z procedur obsługi magnetofonu, lecz przy rozkazie MERGE blok danych musi jeszcze zostać scalony z programem.

0802 LD-BLOCK     CALL  0556,LD-BYTES       ładuj/weryfikuj blok danych.
                  RET   C                   Wróć, chyba że był błąd

Raport R - Błąd odczytu z taśmy.

0806 REPORT-R     RST   0008,ERROR-1        Wywołaj procedurę obsługi błędu.
                  DEFB  +1A

PROCEDURA STERUJĄCA 'ODCZYTEM'

Ta procedura steruje odczytem programu w języku BASIC wraz z jego zmiennymi lub odczytem tablicy.

0808 LD-CONTRL    LD    E,(IX+0B)           Pobierz 'liczbę bajtów'
                  LD    D,(IX+0C)           podaną w 'nowym nagłówku'.
                  PUSH  HL                  Zachowaj 'wskaźnik docelowy'.
                  LD    A,H                 Skocz naprzód, chyba że jest próba
                  OR    L                   załadowania wcześniej
                  JR    NZ,0819,LD-CONT-1   niezadeklarowanej tablicy.
                  INC   DE                  Dodaj trzy bajty do
                  INC   DE                  długości - na nazwę,
                  INC   DE                  młodszy i starszy bajt długości
                  EX    DE,HL               nowej zmiennej.
                  JR    0825,LD-CONT-2      Skocz naprzód.

Sprawdź teraz, czy w pamięci jest wystarczająco dużo miejsca na nowy blok danych.

0819 LD-CONT-1    LD    L,(IX-06)           Pobierz rozmiar istniejącego
                  LD    H,(IX-05)           'programu ze zmiennymi lub tablicy'.
                  EX    DE,HL
                  SCF                       Skocz naprzód, jeśli nie będzie potrzebne
                  SBC   HL,DE               żadne dodatkowe miejsce; biorąc
                  JR    C,082E,LD-DATA      pod uwagę odzyskanie poprzednio
                                            używanej pamięci.

Wykonaj właściwy test na miejsce w pamięci.

0825 LD-CONT-2    LD    DE,+0005            Zezwól na nadmiar 5 bajtów.
                  ADD   HL,DE
                  LD    B,H                 Przenieś wynik do
                  LD    C,L                 pary rejestrów BC i wykonaj
                  CALL  1F05,TEST-ROOM      ten test.

Teraz zajmij się odczytem tablic.

082E LD-DATA      POP   HL                  Pobierz od nowa 'wskaźnik'.
                  LD    A,(IX+00)           Skocz naprzód przy odczycie
                  AND   A                   programu w języku BASIC.
                  JR    Z,0873,LD-PROG
                  LD    A,H                 Skocz naprzód, jeśli odczytywana jest
                  OR    L                   nowa tablica.
                  JR    Z,084C,LD-DATA-1
                  DEC   HL                  Pobierz 'długość'
                  LD    B,(HL)              istniejącej tablicy przez zebranie
                  DEC   HL                  bajtów długości z
                  LD    C,(HL)              obszaru zmiennych.
                  DEC   HL                  Wskaż na jej starą nazwę.
                  INC   BC                  Dodaj trzy bajty do tej
                  INC   BC                  długości - jeden na nazwę
                  INC   BC                  i dwa na 'długość'.
                  LD    (X-PTR),IX          Przechowaj chwilowo parę rejestrów IX,
                  CALL  19E8,RECLAIM-2      gdy jest odzyskiwana stara tablica.
                  LD    IX,(X-PTR)

teraz jest dostępne miejsce dla nowej tablicy - na końcu obecnego obszaru zmiennych.

084C LD-DATA-1    LD    HL,(E-LINE)         Znajdź wskaźnik znacznika
                  DEC   HL                  końca obszaru zmiennych - 'bajt 80'.
                  LD    C,(IX+0B)           Pobierz 'długość' nowej tablicy
                  LD    B,(IX+0C)
                  PUSH  BC                  Zachowaj tę 'długość'.
                  INC   BC                  Dodaj trzy bajty - jeden na nazwę
                  INC   BC                  i dwa na 'długość'.
                  INC   BC
                  LD    A,(IX-03)           'IX+0E' w starym nagłówku
                                            daje nazwę tablicy.
                  PUSH  AF                  Nazwa jest zachowywana w czasie
                  CALL  1655,MAKE-ROOM      uzyskiwania odpowiedniej ilości
                  INC   HL                  miejsca. W rezultacie otrzymujemy 
                  POP   AF                  BC bajtów przed 'nowym bajtem 80'.
                  LD    (HL),A              Zostaje wprowadzona nazwa.
                  POP   DE                  'Długość' jest pobierana i jej
                  INC   HL                  dwa bajty również są wprowadzane.
                  LD    (HL),E
                  INC   HL
                  LD    (HL),D
                  INC   HL                  HL teraz wskazuje na pierwszą komórkę
                                            w pamięci, od której ma się rozpocząć
                                            wypełnianie danymi z taśmy.
                  PUSH  HL                  Adres ten zostaje przeniesiony do
                  POP   IX                  pary rejestrów IX; znacznik przeniesienia
                  SCF                       jest ustawiany; sygnalizowany jest
                  LD    A,+FF               'blok danych', który następnie zostaje
                  JP    0802,LD-BLOCK       załadowany.

Teraz zajmij się załadowaniem programu w języku BASIC wraz z jego zmiennymi.

0873 LD-PROG      EX    DE,HL               Zachowaj 'wskaźnik docelowy'.
                  LD    HL,(E-LINE)         Znajdź adres znacznika
                  DEC   HL                  końca bieżącego obszaru zmiennych - 'bajt 80'.
                  LD    (X-PTR),IX          Chwilowo przechowaj IX.
                  LD    C,(IX+0B)           Pobierz 'długość'
                  LD    B,(IX+0C)           nowego bloku danych.
                  PUSH  BC                  Trzymaj kopię tej 'długości'
                  CALL  19E5,RECLAIM-1      podczas odzyskiwania bieżącego obszaru
                  POP   BC                  programu ze zmiennymi.
                  PUSH  HL                  Zachowaj wskaźnik obszaru programu
                  PUSH  BC                  oraz długość nowego bloku danych.
                  CALL  1655,MAKE-ROOM      Zrób odpowiednią ilość miejsca
                                            na nowy program i jego zmienne.
                  LD    IX,(X-PTR)          Odtwórz parę rejestrów IX.
                  INC   HL                  Zmienna systemowa VARS
                  LD    C,(IX+0F)           również musi być ustawiona
                  LD    B,(IX+10)           dla nowego programu.
                  ADD   HL,BC
                  LD    (VARS),HL
                  LD    H,(IX+0E)           Jeśli został określony
                  LD    A,H                 numer wiersza, to on również musi być
                  AND   +C0                 rozpatrzony.
                  JR    NZ,08AD,LD-PROG-1   Skocz, jeśli 'brak numeru', inaczej
                  LD    L,(IX+0D)           ustaw zmienne systemowe NEWPPC i NSPPC.
                  LD    (NEWPPC),HL
                  LD    (NSPPC),+00

Teraz blok danych może być załadowany.

08AD LD-PROG-1    POP   DE                  Pobierz 'długość'.
                  POP   IX                  Pobierz 'start'.
                  SCF                       Sygnalizuj 'odczyt'.
                  LD    A,+FF               Sygnalizuj tylko 'blok danych'.
                  JP    0802,LD-BLOCK       Załaduj go.

PROCEDURA STERUJĄCA 'ŁĄCZENIEM'

W tej procedurze występują trzy główne części.

i. Załadowanie bloku danych do przestrzeni roboczej.
ii. Połączenie wierszy nowego programu z wierszami starego.
iii. Połączenie nowych zmiennych ze starymi.

Dlatego rozpocznij od załadowania tego bloku danych.

08B6 ME-CONTRL    LD    C,(IX+0B)           Pobierz 'długość'
                  LD    B,(IX+0C)           bloku danych.
                  PUSH  BC                  Zachowaj kopię tej 'długości'.
                  INC   BC                  Teraz przydziel 'length+1' komórek
                  RST   0030,BC-SPACES      pamięci w obszarze roboczym.
                  LD    (HL),+80            W dodatkowej komórce umieść marker końca.
                  EX    DE,HL               Przenieś wskaźnik 'początku' do
                                            pary rejestrów HL.
                  POP   DE                  Pobierz oryginalną 'długość'.
                  PUSH  HL                  Zachowaj kopię 'początku'.
                  PUSH  HL                  Teraz ustaw parę rejestrów IX
                  POP   IX                  do właściwego odczytu.
                  SCF                       Sygnalizuj 'odczyt'.
                  LD    A,+FF               Sygnalizuj 'tylko blok danych'.
                  CALL  0802,LD-BLOCK       Załaduj ten blok danych.

Wiersze nowego programu zostają połączone z wierszami starego.

                  POP   HL                  Pobierz 'początek' nowego programu.
                  LD    DE,(PROG)           Ustaw DE na 'początek' starego programu.

Wejdź do pętli, aby zająć się wierszami nowego programu.

08D2 ME-NEW-LP    LD    A,(HL)              Pobierz numer wiersza i sprawdź go.
                  JR    NZ,08F0,ME-VAR-LP   Skocz, gdy skończyły się wszystkie wiersze.

Teraz wejdź do wewnetrznej pętli, aby zająć się wierszami starego programu.

08D7 ME-OLD-LP    LD    A,(DE)              Pobierz starszy bajt numeru wiersza
                  INC   DE                  i porównaj go.
                  CP    (HL)                Skocz naprzód, jeśli nie pasuje,
                  INC   HL                  lecz w każdym przypadku zwiększ
                  JR    NZ,08DF,ME-OLD-L1   oba wskaźniki.
                  LD    A,(DE)              Powtórz porównywanie dla
                  CP    (HL)                młodszych bajtów numeru wiersza.
08DF ME-OLD-L1    DEC   DE                  Teraz cofnij wskaźniki.
                  DEC   HL
                  JR    NC,08EB,ME-NEW-L2   Skocz naprzód, jeśli zostało znalezione
                                            właściwe miejsce dla wiersza nowego programu.
                  PUSH  HL                  Inaczej znajdź adres
                  EX    DE,HL               początku następnego starego wiersza.
                  CALL  19B8,NEXT-ONE
                  POP   HL
                  JR    08D7,ME-OLD-LP      Wróć na początek pętli dla każdego ze
                                            'starych wierszy'.
08EB ME-NEW-L2    CALL  092C,ME-ENTER       Wprowadź 'nowy wiersz' i wróć
                  JR    08D2,ME-NEW-LP      ponownie do początku pętli zewnętrznej.

W podobny sposób są łączone zmienne nowego programu ze zmiennymi starego.

Następuje wejście do pętli, która zajmuje się po kolei każdą nową zmienną.

08F0 ME-VAR-LP    LD    A,(HL)              Pobierz kolejno nazwę każdej zmiennej
                  LD    C,A                 i sprawdź ją.
                  CP    +80                 Wróć, gdy wszystkie zmienne zostały
                  RET   Z                   przetworzone.
                  PUSH  HL                  Zachowaj bieżący nowy wskaźnik.
                  LD    HL,(VARS)           Pobierz VARS (dla starego programu).

Teraz wejdź do wewnętrznej pętli, aby przeszukać obszar istniejących zmiennych.

08F9 ME-OLD-VP    LD    A,(HL)              Pobierz nazwę każdej zmiennej
                  CP    +80                 i sprawdź ją.
                  JR    Z,0923,ME-VAR-L2    Skocz naprzód po znalezieniu
                                            markera końca. (Wykonaj 'dodawanie'.)
                  CP    C                   Porównaj nazwy (ich pierwsze bajty).
                  JR    Z,0909,ME-OLD-V2    Skocz naprzód, aby dalej rozpatrzyć je;
                                            wracając tutaj, jeśli nazwy nie będą
                                            w pełni zgodne.
0901 ME-OLD-V1    PUSH  BC                  Zachowaj nazwę zmiennej w czasie szukania
                  CALL  19B8,NEXT-ONE       'starej zmiennej'.
                  POP   BC
                  EX    DE,HL               Przywróć wskaźnik w parze rejestrów DE
                  JR    08F9,ME-OLD-VP      i wykonaj ponownie obieg pętli.

Stare i nowe zmienne pasują do siebie wedle swoich pierwszych bajtów, lecz zmienne o długich nazwach muszą się zgadzać w całości.

0909 ME-OLD-V2    AND   +E0                 Rozpatrz jedynie bity 7, 6 i 5.
                  CP    +A0                 Akceptuj wszystkie typy zmiennych
                  JR    NZ,0921,ME-VAR-L1   z wyjątkiem 'zmiennych o długich nazwach'.
                  POP   DE                  Ustaw  DE na pierwszy znak
                  PUSH  DE                  'nowej nazwy'.
                  PUSH  HL                  Zachowaj wskaźnik 'starej nazwy'.

Teraz wejdź do petli porównującej litery długich nazw.

0912 ME-OLD-V3    INC   HL                  Uaktualnij oba wskaźniki: stary i nowy.
                  INC   DE
                  LD    A,(DE)              Porównaj dwie litery
                  CP    (HL)
                  JR    NZ,091E,ME-OLD-V4   Skocz naprzód, jeśli są one różne.
                  RLA                       Wróć na początek pętli aż do
                  JR    NC,0912,ME-OLD-V3   znalezienia 'ostatniego znaku'.
                  POP   HL                  Pobierz wskaźnik do początku
                                            'starej' nazwy
                  JR    0921,ME-VAR-L1      i skocz naprzód - sukces.
091E ME-OLD-V4    POP   HL                  Pobierz wskaźnik i skocz
                  JR    0901,ME-OLD-V1      wstecz - porażka.

Dotarcie do tego miejsca oznacza, że nazwy są zgodne.

0921 ME-VAR-L1    LD    A,+FF               Sygnalizuj 'zamianę' zmiennej.

A dotarcie tutaj oznacza, że nie są. (A zawiera +80 - zmienną do 'dodania'.)

0923 ME-VAR-L2    POP   DE                  Pobierz wskaźnik do 'nowej' nazwy.
                  EX    DE,HL               Wymień ze sobą zawartość rejestrów.
                  INC   A                   Znacznik zera ma być ustawiony przy 'zamianie',
                                            a wyzerowany przy 'dodawaniu'.
                  SCF                       Sygnalizuj 'obsługę zmiennych'.
                  CALL  092C,ME-ENTER       Teraz wprowadź zmienną.
                  JR    08F0,ME-VAR-LP      Wróć na początek pętli, aby rozpatrzyć
                                            następną nową zmienną.

PROCEDURA 'ŁĄCZENIA WIERSZA LUB ZMIENNEJ'

Wejście do tej procedury jest wykonywane z następującymi parametrami:

Znacznik przeniesienia  wyzerowany  -  łączenie wiersza BASIC.
   ustawiony  - łączenie zmiennej.
Znacznik zera  wyzerowany  - będzie to 'dodanie'.
   ustawiony  - będzie to 'zamiana'.
Para rejestrów HL    - wskazuje początek nowej zmiennej
Para rejestrów DE    - wskazuje miejsce łączenia
092C ME-ENTER     JR    NZ,093E,ME-ENT-1    Skocz przy 'dodawaniu'.
                  EX    AF,A'F'             Zachowaj znaczniki.
                  LD    (X-PTR),HL          Zachowaj 'nowy' wskaźnik podczas
                  EX    DE,HL               odzyskiwania pamięci ze 'starego'
                  CALL  19B8,NEXT-ONE       wiersza lub zmiennej.
                  CALL  19E8,RECLAIM-2
                  EX    DE,HL
                  LD    HL,(X-PTR)
                  EX    AF,A'F'             Odtwórz znaczniki.

Teraz można dokonać wstawienia nowego elementu.

093E ME-ENT-1     EX    AF,A'F'             Zachowaj znaczniki.
                  PUSH  DE                  Zrób kopię wskaźnika 'przeznaczenia'.
                  CALL  19B8,NEXT-ONE       Znajdź długość 'nowej' zmiennej/wiersza.
                  LD    (X-PTR),HL          Zachowaj wskaźnik do 'nowej'
                                            zmiennej/wiersza.
                  LD    HL,(PROG)           Pobierz PROG - aby zapobiec przekłamaniu.
                  EX    (SP),HL             Zachowaj PROG na stosie
                                            i pobierz 'nowy' wskaźnik.
                  PUSH  BC                  Zachowaj długość.
                  EX    AF,A'F'             Odtwórz znaczniki.
                  JR    C,0955,ME-ENT-2     Skocz naprzód, jeśli dodawana jest
                                            nowa zmienna.
                  DEC   HL                  Nowy wiersz dodawany jest przed
                                            adresem 'przeznaczenia'.
                  CALL  1655,MAKE-ROOM      Zrób miejsce na nowy wiersz.
                  INC   HL
                  JR    0958,ME-ENT-3       Skocz naprzód.
0955 ME-ENT-2     CALL  1655,MAKE-ROOM      Zrób miejsce na nową zmienną.
0958 ME-ENT-3     INC   HL                  Wskaż na pierwszą komórkę nowego elementu.
                  POP   BC                  Odtwórz długość.
                  POP   DE                  Odtwórz PROG i zapisz
                  LD    (PROG),DE           we właściwym miejscu.
                  LD    DE,(X-PTR)          Również pobierz 'nowy' wskaźnik.
                  PUSH  BC                  Jeszcze raz zachowaj długość
                  PUSH  DE                  i ten 'nowy' wskaźnik.
                  EX    DE,HL               Zamień miejscami wskaźniki i skopiuj
                  LDIR                      'nową' zmienną/wiersz do przygotowanego
                                            obszaru.

Teraz 'nowa' zmienna/wiersz musi zostać usunięta z obszaru roboczego.

                  POP   HL                  Pobierz 'nowy' wskaźnik.
                  POP   BC                  Pobierz długość.
                  PUSH  DE                  Zachowaj 'stary' wskaźnik. (Wskazuje
                                            komórkę za 'wstawioną' zmienną/wierszem.)
                  CALL  19E8,RECLAIM-2      Usuń zmienną/wiersz z przestrzeni roboczej.
                  POP   DE                  Wróć ze 'starym' wskaźnikiem 
                  RET                       w parze rejestrów DE.

PROCEDURA STERUJĄCA 'ZAPISEM'

Operacja zapisu programu lub bloku danych jest bardzo bezpośrednia.

0970 SA-CONTRL    PUSH  HL                  Zachowaj 'wskaźnik'.
                  LD    A,+FD               Upewnij się, że jest otwarty kanał 'K'.
                  CALL  1601,CHAN-OPEN
                  XOR   A                   Ustaw 'pierwszą wiadomość'.
                  LD    DE,+09A1            Wypisz wiadomość - 'Start tape,
                  CALL  0C0A,PO-MSG         then press any key.'.
                  SET   5,(TV-FLAG)         Sygnalizuj potrzebę wyczyszczenia ekranu.
                  CALL  15D4,WAIT-KEY       Czekaj na naciśnięcie klawisza.

Po naciśnięciu klawisza zostaje zapisany 'nagłówek'.

                  PUSH  IX                  Zachowaj adres bazowy 'nagłówka' na stosie.
                  LD    DE,+0011            Do zapisu jest 17 bajtów.
                  XOR   A                   Sygnalizuj 'to jest nagłówek'.
                  CALL  04C2,SA-BYTES       Wyślij 'nagłówek' z prowadzącym bajtem typu
                                            i zamykającym bajtem parzystości.

Przed zapisem programu/bloku danych występuje krótka przerwa.

                  POP   IX                  Odtwórz wskaźnik 'nagłówka'.
                  LD    B,+32               Opóźnienie wynosi 50 przerwań,
0991 SA-1-SEC     HALT                      tj. jedną sekundę.
                  DJNZ  0991,SA-1-SEC
                  LD    E,(IX+0B)           Pobierz długość
                  LD    D,(IX+0C)           bloku danych do zapisu.
                  LD    A,+FF               Sygnalizuj 'blok danych'.
                  POP   IX                  Pobierz wskaźnik 'początku bloku'
                  JP    04C2,SA-BYTES       i zapisz ten blok.

TEKSTY WIADOMOŚCI PRZY OPERACJACH Z MAGNETOFONEM

Każda wiadomość posiada ostatni znak w negatywie (+80 szesnastkowo.).

09A1 DEFB +80     - Początkowy bajt, który się pomija.
09A2 DEFM         - Start tape, then press any key.
09C1 DEFM         - 'nowy wiersz' - Program:
09CB DEFM         - 'nowy wiersz' - Number array:
09DA DEFM         - 'nowy wiersz' - Character array:
09EC DEFM         - 'nowy wiersz' - Bytes:

Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2024 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: i-lo@eduinf.waw.pl

Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.

Informacje dodatkowe.