BAJTEK 1986 / 8


JAK SCHOWAĆOBRAZEK Artur Szymański


Przekonajmy się. że język maszynowy nie jest tak straszny jak starają się sugerować niektórzy „wtajemniczeni”. Spróbujemy dzisiaj wspólnie napisać prosty program zapamiętywania obrazu. Będziemy też mogli dzięki niemu zobaczyć różnice w szybkości działania programu w BASIC-u i w kodzie maszynowym.


Pamięć obrazu to 6144 bajty informacji o tym, które punkty są w kolorze papieru, a które atramentu, oraz 768 bajtów tzw. atrybutów, czyli informacji o kolorach papieru i atramentu, a także jasności (BRIGHT) i miganiu (FLASH)

Zawartość pamięci może być modyfikowana przy pomocy POKE i odczytywana przez PEEK.

Pamięć obrazu nie rożni się niczym od innych obszarów pamięci operacyjnej systemu. Oczywiście operacji na ekranie wygodniej jest dokonywać przy użyciu instrukcji PRINT i SCREEN$.


Zawartość pamięci ekranu można przepisać do innego obszaru pamięci, gdzie nie zostanie ona zniszczona przez RUN, CLEAR czy CLS. Umożliwia to poniższy program:

10 FOR A = 16384 TO 23295

20 POKE A + 9466, PEEK A

30 NEXT A

Najpierw trzeba jednak wyznaczyć obszar w pamięci komputera, gdzie umieszczona zostanie kopia pliku obrazu. W tym celu piszemy CLEAR 25849.

Uwaga: instrukcja ta musi poprzedzić zapełnianie obrazu! W pierwszym wypadku CLEAR skasuje całą zawartość ekranu.

Z tego samego powodu uruchamiać ten program należy nie instrukcją RUN, lecz GOTO 10.

Kiedy komputer zakończy przepisywanie ekranu do pamięci operacyjnej obrazek jest bezpieczny. Teraz nie „zaszkodzi” mu nawet NEW, które kasuje pamięć tylko do miejsca wskazanego przez CLEAR.


Powtórne umieszczenie obrazu na ekranie umożliwia następny program:

10 CLS

20 FOR A = 16384 TO 23295

30 POKE A, PEEK A + 9466

40 NEXT A


Nietrudno zauważyłeś, że szybkość działania tego programu nie jest „rewelacyjna”.

Niestety BASIC — mimo całej swej prostoty i przejrzystości działania — nie należy do najszybszych. Błyskawiczne przepisywanie obrazu umożliwia program w języku maszynowym.

Język maszynowy jest to zbiór rozkazów do bezpośredniego wykonania przez jednostkę centralną komputera czyli mikroprocesor.

Tymczasem BASIC nie jest wykonywany bezpośrednio przez mikroprocesor, lecz jest przekładany na język maszynowy przy pomocy programu w ROM'ie. Może jednak podać bezpośrednio do mikroprocesora tzw. kody maszynowe, czyli rozkazy do bezpośredniego wykonania.

Aby zrozumieć w jaki sposób mikroprocesor wykonuje programy maszynowe musimy zapoznać się z pojęciem „rejestry mikroprocesora”.

Rejestry są czymś w rodzaju 8-bitowej mikro-pamięci. Przy ich pomocy procesor komunikuje się z otoczeniem tj. pamięcią i układami I/O (wejścia/wyjścia).

W mikroprocesorze Z80 programowo są dostępne rejestry: A — czyli akumulator B, C, D, E, H, L oraz rejestr wskaźników (flag) F.

Każdemu z tych rejestrów odpowiadają rejestry pomocnicze, oznaczone jako A, B, C, D, E, H, L, F. Pojedyncze rejestry można łączyć również w 16-bitową parę rejestrów. Takimi parami są AF, BC, DE, HL i odpowiednio AF, BC, DE, HL. Poza tym są jeszcze 16-bitowe rejestry specjalne: 2 rejestry indeksowe IX i IT, rejestr wskaźnika stosu SP, rejestr licznika rozkazów PC oraz dwa 8-bitowe rejestry — wektora przerwań I oraz odświeżania pamięci R.

Oczywiście Z80 zawiera jeszcze inne rejestry pomocnicze, które jednak nie są dostępne bezpośrednio. W języku maszynowym każdemu rozkazowi odpowiada określony kod liczbowy — stąd też nazwa kod maszynowy.

Aby można byto łatwo operować takimi rozkazami każdemu z nich jest przyporządkowany tzw. mnemonik, czyli symbol literowy, który ułatwia jego zapamiętanie.

I tak np. rozkazowi załadowania (wszystko jedno czy pamięci czy rejestru) odpowiada mnemonik LD, rozkazowi powrotu RET itp.

Do procesora trzeba jednak podać kody maszynowe i do tego celu służy program assembler, który tłumaczy mnemoniki na kody maszynowe. Jeżeli nie posiadasz takiego programu możesz zrobić to inaczej, ale pod warunkiem, że program maszynowy nie jest zbyt długi.

Odpowiadające mnemonikom kody możesz odszukać np. w dodatku A instrukcji do ZX Spectrum na str. 135 i następnych.

I tak, na przykład rozkazowi LDHL, nn odpowiada kod 33, gdzie nn jest dwu-bajtową liczbą z zakresu 0 — 65535,

rozkazowi REN — 201 itd.

W języku wewnętrznym mikroprocesora Z80 analogiczny program jak podany na początku będzie wyglądał następująco:

LD HL, 16384 ; adres początku obrazu

LD DE, 25850 ;adres początku kopii

LD BC, 6912 ; liczba bajtów przesłania

LDIR ; przesłanie blokowe

RET ; powrót do BASIC-u

W programie tym rozkazy LD oznaczają załadowanie par rejestrów mikroprocesora podanymi liczbami. Rozkaz LDIR jest to tzw. przesłanie blokowe, które polega na tym, że zawartość komórki pamięci o adresie określonym zawartością pary HL zostaje przepisana do komórki o adresie określonym parą DE.

Po każdym przesłaniu bajtu zawartości par HL i DE są powiększane przez procesor o 1. Para BC stanowi licznik wskazujący, ile jeszcze bajtów pozostało do przesłania; po każdym przesłaniu bajtu jest zmniejszana o 1.

Procesor powtarza przesłania aż do wyzerowania pary BC.

Rozkaz powrotu RET powoduje powrót do BASIC-u.


W ostatniej kolumnie podajemy kody rozkazów w zapisie dziesiętnym. Liczby dwubajtowe są zapisywane w dwóch komórkach pamięci. W drugiej umieszczamy wynik dzielenia przez 256, a w pierwszej resztę z tego dzielenia.

Program ten możesz wpisać do pamięci przy pomocy programu w BASIC-u:

10 CLEAR 25499

20 FOR A - 25500 TO 25511

30 READ B: POKE A, B

40 NEXT A

50 DATA 33,0,64,17,250,100,1,0,27,237,176,201


Uruchom ten program, a potem umieść jakiś obraz na ekranie.

Teraz wywołaj program maszynowy instrukcją RANDOMIZE USR 25500.

Po powrocie z programu maszynowego obraz zapisany jest w pamięci. Aby znów wywołać go na ekran przy użyciu programu maszynowego, należy zamienić zawartości par HL i DE.


Wyglądać to będzie tak:


LD HL,25850 ;adres początku kopii

LD DE,16384 ;adres początku obrazu

LD BC,6912 ;liczba bajtów przesłania

LDIR ; przesłanie blokowe

RET ; powrót do BASIC-u


W programie w BASIC-u wystarczy zamienić linię 50:


50 DATA 33,250,100,17,0,64,1,0,27,237,176,201

Następnie piszesz RANDOMIZE USR 25500 i natychmiast możesz ponownie zobaczyć poprzedni obraz na ekranie.


W przypadku wykonywania przesłania w BASIC-u można obserwować efekt jego działania, obraz jest wykreślany linia po linii. W przypadku programu maszynowego nie daje się zauważyć etapów pośrednich kreślenia obrazu — pojawia się on natychmiast, o czym czytelnicy mogą się przekonać.


Artur Szymański (lat 17)