Kurs Assemblera cz. 12

 

Stacja dysków i bity na drutach

1. Witajcie!

Do tej pory nasze kontakty ze stacją dysków były nieco, rzekłbym, monotonne. Ograniczaliśmy się do ładowania i nagrywania programów. No i – ma się rozumieć – gier. Nadszedł jednak czas, by szczerze sobie powiedzieć, że to nie wystarczy. Jesteśmy już duzi, asemblera uczymy się już dość długo, pora więc na wzięcie stacji – jak to mawiali przedwojenni majstrowie – na warsztat.

2. Zaczynamy.

Na początek sprobujmy wtadować katalog dyskietki. Zgodnie z tym, czego do tej pory się nauczyliście, powinniście już wiedzieć, jak to zrobić. Proste BASIC-owe LOAD „$”,8 musimy zamienić na co najmniej trzy odwołania do procedurek KERNALa. Uwaga! Sięgnij teraz po sierpniowy numer „C&A” i otwórz go na stronie 26. Najpierw musimy ustawić wskaźniki pliku logicznego, czyli jego numer wstawić do akumulatora (niech będzie to 1), numer urządzenia – do X (stacja dysków – to 8), a adres pomocniczy – do Y (nie korzystamy z niego – wstawiamy $ff). Po takim ustawieniu rejestrów uruchamiamy procedurę SETLFS ($ffba). Gdy ładujemy katalog, musimy podać jego nazwę, czyli „$”. Wartość odpowiadającą dolarowi, czyli 68/$24 wstawiamy gdzieś do pamięci, pod etykietą TYT (TYT od TYTuł, ale w skrócie, żeby oszczędzić Wam pisania). Adres rozbijamy na młodszy i starszy bajt. Bajt młodszy wędruje do rejestru X, starszy zaś – do Y. Do akumulatora wpisujemy 1, bo tytuł składa się tylko z jednego znaku – $ zresztą. Po czym wskakujemy do procedurki SETNAM ($ffbd). W tym właśnie momencie

3. Zaczynają się schody

bo gdybyśmy kazali katalog ordynarnie załadować to nie dość, że nie byłoby to żadne odkrycie, ale na domiar złego zostałby zlikwidowany istniejący w pamięci program w BASIC-u. A sama asemblerowa procedura ładująca tylko nieznacznie różniłaby się od programu 2 z odcinka sierpniowego. Ale przecież to nie my jesteśmy niewolnikami swoich komputerów, ale one mają tańczyć tak, jak my im zagramy. Na czym bowiem polega ładowanie jakiegokolwiek zbioru do pamięci? Komputer musi otworzyć zbiór, a następnie pobierać z niego kolejne bajty i wstawiać je do pamięci, do kolejnych komórek. Oczywiste? Te czynności wykonuje KERNALowa procedura LOAD($ffd5).

My zaś musimy zbiór otworzyć, a kolejne bajty nie – zapamiętywać jako program BASIC, a jedynie wyrzucać na ekran jako dane tymczasowe. Jak jednak dokonać tego w praktyce? Po przejrzeniu tabeli KERNALa widzimy, że do przygotowania pliku do wzięcia udziału w operacjach we/wy służy procedura OPEN ($ffc0). Wymaga ona tylko, by numer tego pliku logicznego znalazł się w akumulatorze. I znajdzie się. Musimy tylko uważać, by był identyczny z numerem, który podaliśmy w rejestrze A przed wywołaniem procedury SETLFS.

Ale to jeszcze nie wszystko. Po otwarciu pliku musimy ustawić go jako aktualny kanał wejściowy. Służy do tego CHKIN. Dla odmiany, numer pliku musi się znaleźć w rejestrze X.
Teraz rzecz jest już w zasadzie prosta. Po drucie ze stacji musimy przeciągnąć bajty procedurą CHRIN ($ffcf). Kolejny znak znajdzie się w akumulatorze po każdym wywołaniu CHRIN. Aby wartości z akumulatora nie szły nam w komin, to po każdym CHRIN wykonać musimy CHROUT ($ffd2). Co jest znanym już od dawna sposobem na wydrukowanie znaku na ekranie. A oto przecież chodzi

4. Schody się piętrzą

Jeśli jednak nakażemy komputerowi powtarzanie prostej pętli CHRIN/CHROUT, to nie dziwmy się, jeśli otrzymamy sieczkę zamiast uczciwego katalogu dyskietki. Aby prześledzić, jak wygląda struktura katalogu popełniłem prosty programik, który po wydrukowaniu każdej litery pokazywał na ekranie jej wartość liczbową (czyli kod ASCII, a właściwie PETASCII), następnie czekał na naciśnięcie jakiegokolwiek klawisza, a potem przechodził z powrotem do CHRIN. Program taki jest prościutki i każdy z Was powinien już umieć napisać go samemu, więc nie będę tracił na niego bądź co bądź cennego miejsca. Włożyłem do stacji pierwszą z brzegu dyskietkę i otrzymałem co następuje:

5. Rozpiska bajtów w katalogu dysku

Oczywiście, ta rozpiska jest tylko przykładowa, ale ma wszystkie elementy: nagłówek, nazwę jakiegoś programu i zakończenie w postaci liczby wolnych bloków. Jak widać, są podane w takiej samej formie jak program w BASIC-u z tą różnicą, że nie ma adresów początków następnych linii na początku poprzednich. Projektanci maszyny zdawali sobie sprawę, że nie będą one nikomu do niczego potrzebne, więc poszli na łatwiznę i powpisywali tam po prostu jedynki. A skutek tego taki, że te nieszczęsne jedynki musimy tylko w katalogu pobrać i puścić w powietrze.

Po jedynkach idzie liczba podana w postaci młodszego i starszego bajtu. Do wydrukowania na ekranie liczby w zwykłej, dziesiętnej postaci, gdy mamy ją jako dwa bajty, służy umieszczona w pamięci ROM procedura LINPRT. Normalnie przydaje się w BASIC-u podczas drukowania listingów programów, ale my, cwaniaczki, wykorzystamy ją do własnych celów.

Żeby wykorzystać LINPRT ($bdcd) trzeba jej podać młodszy bajt liczby w rejestrze X, a starszy – w akumulatorze. Następnie idzie nazwa. Trzeba ją bajt po bajcie drukować tak długo, aż natkniemy się na zero. Gdy dogrzebiemy się do zera, to wyrzucamy na ekran 13/$Od i przechodzimy do następnej linii.

Wszystko ładnie, ale tak napisany program, niestety, nie będzie działał poprawnie. To znaczy – na pierwszy rzut oka tak, ale nie rozpozna, że katalog się skończył i to, co zostało wydrukowane z prędkością światła ucieknie nam z pola widzenia. Drugim poważnym mankamentem jest fakt, że programu tak napisanego nie można zatrzymać klawiszem RUN/STOP. Nie sprawia to kłopotu, gdy programów jest na dysku kilka, ale gdy zajmują one trzy ekrany, zaczyna się robić kłopotliwe. Oba te problemy są, oczywiście, pozorne i rozwiązać je można w minutę dziesięć. Wskaźnikiem końca pliku jest szósty bit w komórce STATUS ($90). Jeżeli zostanie on zapalony, czyli jeżeli wykonanie AND #%01000000 z wartością z rejestru STATUS da wynik 1, to znaczy to, że dalszy odczyt z kanału nie ma sensu, bo wpuścimy się tylko w jakiś podejrzany kanał organizacyjny i mogą z tego wyniknąć jakieś nieprzyjemności. Do obsługi klawisza STOP służy zaś rejestr STKEY ($91). Naciśnięcie tego guzika spowoduje zapalenie ostatniego, siódmego bitu tej komórki. Dodatkową zaletą tego rozwiązania jest fakt, że testowanie stopu robimy za pomocą jednego tylko rozkazu: BPL. Jeżeli STOP będzie wciśnięty, skok zostanie wykonany. Jasne? Jasne?
Warto jeszcze nadmienić, że po skończeniu (lub przerwaniu, co na jedno wychodzi) odczytywania katalogu dyskietki należy zamknąć plik wejściowy, ten który przed odczytem otwieraliśmy oraz – dla porządku – ustawić monitor i klawiaturę jako aktualne we/wy. Służy do tego CLOSE ($ffc3) i CLRCHN ($ffcc). I w ten sposób dobrnęliśmy do szczęśliwego finału. Teraz, za cierpliwe zczytanie całego odcinka należy się Wam

6. Listing

7. NA ZRAZIE

Listing nagrajcie sobie na dysk, ewentualnie na taśmę. Magnetofoniaków przepraszam, że ten odcinek nie byt dla nich. Takie jest życie, a cukier drożeje. Uruchamia się jak zwykle – SYS 10000. Nie uschnijcie z tęsknoty.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *