Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

Autor artykułu: mgr Jerzy Wałaszek
Współpraca: mgr inż. Janusz Wałaszek

©2024 mgr Jerzy Wałaszek
I LO w Tarnowie

SPIS TREŚCI

MCODER II - kompilator języka ZX81 BASIC - instrukcja

Zanim rozpoczniesz czytanie tego rozdziału:

pobierz plik instalacyjny emulatora VB81
przeczytaj instrukcję instalacji i użytkowania emulatora VB81
zapoznaj się z instrukcją programowania w ZX81 BASIC
pobierz plik MCODER'a


Co to jest kompilator?

Podstawowym językiem programowania komputera ZX81 był dialekt o nazwie ZX81 BASIC. Był to tzw. język interpretowany. Mikroprocesor przy pomocy odpowiedniego programu (tzw. interpretera języka ZX81 BASIC zawartego w ROM) odczytywał kolejne wiersze programu, rozpoznawał zawarte w nich instrukcje i wykonywał odpowiednie procedury wewnątrz swojej pamięci ROM. W ZX81 proces ten nie należał do najszybszych. Istniało kilka powodów wolnej pracy programów w języku ZX81 BASIC. Najważniejsze wymieniłem poniżej:

I tutaj właśnie wkracza kompilator, czyli specjalny program, który tłumaczy kolejne wiersze programu w języku ZX81 BASIC na kod maszynowy wykonywany bezpośrednio przez mikroprocesor Z80. Kompilator dokonuje wielu optymalizacji generowanego kodu, np skoki są wykonywane pod właściwy adres - odpada problem wyszukiwania wiersza o zadanym numerze. Do zmiennych również jest dostęp poprzez adres, a nie poprzez nazwę. Obliczenia wykonuje się na liczbach całkowitych - jest to naturalna dla Z80 postać liczb, zatem działania wykonywane są bardzo szybko - dziesiątki lub nawet setki razy szybciej od działań na liczbach zmiennoprzecinkowych. W efekcie tych optymalizacji program skompilowany pracuje wielokrotnie szybciej od standardowego programu w języku ZX81 BASIC.

Nie ma róży bez kolców. Zwykle kompilator potrafi przetłumaczyć tylko niektóre konstrukcje języka ZX81 BASIC. Jest to cena, którą płacimy za wzrost szybkości pracy programu.

Instrukcja dla kompilatora MCODER II

ZX81 MCODER II

Kompilator MCODER II dla ZX81

MCODER is the first true compiler for use with the ZX81.

It has been carefully written to occupy as litte space as possible (just under 4K) in order to leave maximum space for your programs.

Although MCODER is a very sophisticated and versatile tool, do not expect miracles, you will have to become familar with its method of operation if you are to use it to its best advantage.

MCODER jest pierwszym, prawdziwym kompilatorem do użytku z ZX81.

Został on napisany z dbałością o zajmowanie jak najmniejszego obszaru pamięci (nieco poniżej 4KB), aby pozostało jej jak najwięcej dla twoich programów.

Chociaż MCODER jest bardzo wyrafinowanym i wszechstronnym narzędziem, nie oczekuj od niego cudów, będziesz musiał się zaznajomić ze sposobem pracy tego kompilatora, aby uzyskać z niego jak największe korzyści.

How do I load MCODER?

Jak mam załadować MCODER'a?

MCODER must always be present in the ZX81 before you try and enter any code. It is loaded from tape using LOAD" ". MCODER contains its own self checking routine to ensure that it loads correctly, if for any reason the program corrupts, an error message will be displayed on screen and you should reload.

Once loaded you must remember that MCODER uses line numbers 1-3 inclusive and cannot be deleted.

MCODER zawsze musi być obecny w ZX81 zanim będziesz mógł wypróbować i wprowadzić jakikolwiek kod. Ładuje się go z taśmy przy pomocy LOAD "" (w naszym emulatorze MCODER znajduje się w katalogu instalacji VB81 i można załadować go poleceniem LOAD "MCODER2"). MCODER zawiera swoją własną procedurę testującą poprawność odczytu (nie dotyczy VB81, tylko taśmy magnetofonowej i prawdziwego ZX81) i jeśli zostanie załadowany z błędami, na ekranie pojawi się informacja o błędzie - wtedy należy załadować go jeszcze raz.

Po załadowaniu musisz pamiętać, iż MCODER wykorzystuje wiersze o numerach od 1 do 3 i nie może być usunięty.

How do I use MCODER?

Jak mam używać MCODER'a?

Using MCODER is really a very simple operation. First of all, enter the BASIC program you wish to compile. It is essential to run and check the program thoroughly before it is compiled and there is no break facility in the compiled code. Before writing a program it is strongly advised that you carefully read through the list of commands which MCODER will compile and ensure that your BASIC program consists only of these commands. Używanie MCODER'a naprawdę jest bardzo prostą operacją. Przede wszystkim wprowadź program w języku BASIC, który chcesz skompilować. Ważne jest, aby program uruchomić i całkowicie przetestować przed skompilowaniem go, ponieważ w skompilowanym kodzie nie działa zatrzymywanie klawiszem spacji (ale powinno działać zatrzymywaniem przyciskiem stopu w VB81). Przed napisaniem programu zaleca się mocno dokładnie przeczytać całą listę rozkazów, które MCODER potrafi kompilować i upewnić się, iż napisany program w języku ZX81 BASIC składa się tylko z nich.
Once you are satisfied with the BASIC program you can compile by using the command LET L = USR 17300. The BASIC statements will then scroll up the screen as they are compiled. If MCODER finds a command or statement it cannot compile then it will return to BASIC with an inverse S at or near the offending command. Gdy jesteś zadowolony z działania swojego programu, możesz przystąpić do jego kompilacji przy pomocy polecenia LET L = USR 17300. Wtedy rozkazy zawarte w wierszach programu będą przesuwały się w górę ekranu w trakcie ich kompilacji. Jeśli MCODER natrafi na rozkaz, którego nie potrafi skompilować, wtedy powróci do systemu BASIC wyświetlając w negatywie literkę S w pobliżu błędnego rozkazu.
Possible errors include:
  1. Using illegal variable names.
  2. GOTO 'variable' or GOSUB 'variable' which are not allowed
  3. Illegal statement such as SAVE or DIM A$(10)

If an error is reported then you should correct it and recompile

Możliwe błędy dotyczą:
  1. Użycia nieprawidłowych nazw zmiennych.
  2. Stosowania GOTO 'zmienna' lub GOSUB 'zmienna', co nie jest dozwolone
  3. Niedozwolonego polecenia, takiego jak SAVE lub DIM A$(10)

Jeśli zostanie zgłoszony błąd, powinieneś go poprawić i skompilować program ponownie.

At the end of a successful compilation you will be shown 3 pieces of
information -
i) the location of the end MCODER code,
ii) the command necessary to run your compiled code,
iii) a query as to whether Yw wish to run the compiled code immediately (RUN? - reply Y or N to this prompt).
Na końcu kompilacji zakończonej sukcesem zobaczysz trzy rzeczy:

i) położenie końca kodu MCODER'a
ii) rozkaz niezbędny do uruchomienia twojego skompilowanego programu
iii) pytanie, czy chcesz uruchomić natychmiast skompilowany program (odpowiedz Y dla tak lub N dla nie).

Can I compile basic programs I already have on tape?

Czy mogę skompilować program w basicu, który już mam na taśmie?

YES- simply load MCODER first and then load the program you wish to compile. Using LET L = USR 32462 after loading your own program will automatically push MCODER into position. You can now continue as shown above.
 
TAK - po prostu załaduj najpierw MCODER'a a następnie załaduj swój program, który chcesz skompilować. Zastosowanie LET L = USR 32462 po załadowaniu twojego własnego programu umieści MCODER'a na odpowiednim miejscu. Teraz możesz postępować tak, jak opisano powyżej.
It is important to stress that you will probably have to make considerable changes in your BASIC program as it is unlikely to have been written to suit MCODER Podkreślamy raz jeszcze, iż prawdopodobnie twój program będzie wymagał istotnych zmian, ponieważ jest mało prawdopodobne, aby był napisany w postaci dogodnej dla MCODER'a.

Which Commands will MCODER compile?

Które rozkazy skompiluje MCODER?

Note the variable names may contain only A-Z and 0-9. Arithmetic is
restricted to the four standard operations + - * /.
Uwaga: nazwy zmiennych mogą zawierać jedynie litery A-Z oraz cyfry 0-9. Działania arytmetyczne są ograniczone do czterech podstawowych operacji + - * /.
AND Boolean AND. Allowed only in an IF statement
ABS As BASIC
CHR$ As BASIC
CLS As BASIC
CLEAR As BASIC
CODE As BASIC
COPY As BASIC
AND operator logiczny I dozwolony tylko w poleceniu IF
ABS jak w BASIC'u
CHR$ jak w BASIC'u
CLS jak w BASIC'u
CLEAR jak w BASIC'u
CODE jak w BASIC'u
COPY jak w BASIC'u
DIM A(V) Only one dimensional arrays are availabe in MCODER and there must be at least 2*V bytes spare space at run-time. No runtime array bound checking is done so make sure it works under normal BASIC.

If you redefine an array a new version of it is made but the old one is not deleted. This means that repeated allocation can eventually fill the machine and give an error 4 (out of memory) either when allocating an array or a string. Array and string space stretches from STKEND to 256 bytes below RAMTOP.

All arrays, strings and variables are erased when you reenter an MCODER program and all the space is available again.

There are no string arrays.

DIM A(V) w MCODER'ze dozwolone są tylko jednowymiarowe tablice oraz w czasie działania programu musi być dostępne co najmniej 2*V bajtów wolnej pamięci. W trakcie wykonania nie są sprawdzane zakresy indeksów, zatem upewnij się, iż twój program działa pod zwykłym ZX81 BASIC.

Jeśli zdefiniujesz ponownie tablicę, to zostanie utworzona jej nowa wersja bez skasowania starej. Oznacza to, iż wielokrotne tworzenie tej samej tablicy doprowadzi do zapełnienia pamięci i błędu 4 (brak pamięci) przy przydzielaniu pamięci dla nowej tablicy lub łańcucha znakowego. Przestrzeń dla tablic i łańcuchów rozciąga się od  STKEND do 256 bajtów poniżej RAMTOP.

Przy ponownym uruchomieniu programu skompilowanego MCODER'em kasowane są wszystkie tablice, łańcuchy oraz zmienne, a zajmowana przez nie pamięć jest ponownie dostępna.

Nie ma tablic z łańcuchami znaków.

FAST As BASIC except that MCOOER does not return to SLOW mode when the screen is full, during INPUT or during PAUSE FAST jak w BASIC'u z tą różnicą, iż MCODER nie powraca do trybu SLOW przy zapełnieniu ekranu, podczas INPUT lub podczas PAUSE.
FOR X = V TO U - X increments in steps of 1 from V to U. NEXT X Ends the loop. Note that (U-V) must be less than 32767. FOR X = V TO U - zmienna X jest zwiększana z krokiem 1 od V do U. NEXT X kończy pętlę.
Uwaga: (U - V) musi być mniejsze od 32767.
GOSUB N Calls line N as a subroutine. If line N does not exist then it goes to the next line after N. Note that N must be a positive integer constant. GOSUB N wywołuje wiersz N jako podprogram. Jeśli wiersz N nie istnieje, to idzie do następnego wiersza za N. Uwaga: N musi być dodatnią stałą całkowitą.
GOTO N Jumps unconditionally to line N. Otherwise as for GOSUB. GOTO N wykonuje bezwarunkowy skok do wiersza N. Reszta jak dla GOSUB.
IF V op U THEN- where op is any of AND, OR,, <>, =, <=, >= or >,<.
Note that V and U must not differ by more tan 32767
For string operations AND and OR are not applicable.
IF V op U THEN - gdzie op jest jednym z operatorów AND, OR, <>, =, <=, >= lub >, <.
Uwaga: V i U nie mogą różnić się o więcej niż 32767.
AND i OR nie może być stosowane w operacjach łańcuchowych.
INKEY$ As BASIC INKEY$ jak w BASIC'u
INPUT a or A$ As BASIC. For numbers a leading negative sign is allowed. For strings the maximum length is 31 characters. No graphics mode. INPUT a lub A$ jak w BASIC'u. Dla liczb a dozwolony jest wiodący minus. Dla łańcuchów maksymalna długość wynosi 31 znaków. Brak trybu graficznego.
INT Included to facilitate test under BASIC. INT dodane w celu ułatwienia testowania programów w języku BASIC.
LEN A$ As BASIC exept that A$ cannot be sliced.
LET As BASIC
LPRINT As BASIC
NEW As BASIC
NEXT See FOR - NEXT
LEN A$ jak w BASIC'u z tym wyjątkiem, iż A$ nie może być poddana slicingowi
LET jak w BASIC'u
LPRINT jak w BASIC'u
NEW jak w BASIC'u
NEXT Zobacz opis FOR - NEXT
OR Boolean OR only available in IF statements OR - operator logiczny LUB dozwolony tylko w poleceniach IF.
PAUSE V Causes the program to wait for V/50 secs if in SLOW mode. It does not go from FAST to SLOW mode as in Sinclair Basic. There is no flicker as PAUSE starts and finishes. V must be positive and less than 32768.

Pressing SHIFT+EDIT returns to BASIC, any other key causes the next statement to be executed.

PAUSE V wstrzymuje wykonywanie programu na V/50 części sekundy w trybie SLOW. Nie przechodzi z trybu FAST do SLOW jak w Sinclair BASIC. Nie występuje mrugnięcie obrazu przy rozpoczęciu i zakończeniu PAUSE. V musi być dodatnie i mniejsze od 32768.

Naciśnięcie SHIFT+EDIT (SHIFT+1 w PC) powoduje powrót do BASIC'a, dowolny inny klawisz powoduje wykonanie następnego polecenia.

PEEK As BASIC
PLOT As BASIC
POKE As BASIC
PRINT As BASIC
RAND As BASIC
PEEK jak w BASIC'u
PLOT jak w BASIC'u
POKE jak w BASIC'u
PRINT jak w BASIC'u
RAND jak w BASIC'u
REM Ignored as usual except that "REM?" looks to see if the SHIFT+EDIT keys are pressed and if so returns to BASIC with an error D. This is usefull to escape from infinite loops. REM ignorowane jak zwykle z wyjątkiem "REM?", które sprawdza, czy naciśnięto klawisze SHIFT+EDIT (SHIFT+1 w PC), a jeśli tak, to powraca do BASIC'a z błędem D. Przydaje się to przy wychodzeniu z pętli nieskończonych (w VB81 mamy przycisk zatrzymywania programu).
RETURN Returns from a subroutine started by a GOSUB. Make sure that your GOSUBS and RETURNS match as no check is made. RETURN powraca z podprogramu rozpoczętego przez GOSUB. Upewnij się, iż twoje instrukcje GOSUB zgadzają się z instrukcjami RETURN, ponieważ nie jest to sprawdzane.
RND Returns a random integer between 0 and 32767 (NOT the same as BASIC) To obtain the same effect under BASIC use USR 16550. RND zwraca liczbę pseudolosową pomiędzy 0 a 32767 (NIE jest takie samo jak w BASIC'u). Aby w BASIC'u otrzymać ten sam efekt, użyj USR 16550.
SCROLL As BASIC
SGN As BASIC
SLOW As BASIC
SCROLL jak w BASIC'u
SGN jak w BASIC'u
SLOW jak w BASIC'u
SQR Integer square root SQR pierwiastek całkowity
STOP If MCODER finds a STOP statement compilation ceases there. If you wish there to be a STOP in the middle of your program then the command LET L=USR 3292 will give an error 9 and stop. STOP - jeśli MCODER napotka w programie polecenie STOP, to zatrzyma w tym miejscu kompilację. Jeśli chcesz mieć STOP w środku swojego programu, to polecenie LET L = USR 3292 da błąd 9 i zatrzyma program.
Strings By default strings have a maximum length of 32 characters. If you exceed the maximum string length then you will write into whatever follows (either another string or an array) However see "Further Features". String slicing may not take the form A$( TO M) or A$(M TO ). There are no string arrays. Łańcuchy. Standardowo łańcuchy posiadają długość 32 znaków. Jeśli przekroczysz maksymalną długość łańcucha, to będziesz zapisywał poza nim to, co tam akurat się znajdzie (albo inny łańcuch albo tablicę). Jednakże zaglądnij do punktu "Dalsze cechy MCODER'a".  Slicing na łańcuchach nie może przybierać postaci A$( TO M) lub A$(M TO ). Nie są dostępne tablice łańcuchów.
UNPLOT As BASIC
USR As BASIC
UNPLOT jak w BASIC'u
USR jak w BASIC'u

Improved Scrolling of output

Ulepszone przewijanie tekstu

Under Sinclair BASIC when the output reaches the bottom of the screen an error 5 is reported. Under MCODER when the output reaches this point an inverse ? is shown at the bottom left of the screen. Pressing CONT causes a CLS and the program continues (holding your finger on CONT causes this process to be repeated indefinitely) Pressing SHIFT+EDIT stops the program, key D (SLOW) causes the screen to scroll at a maximum of 1 line per second, pressing Z (COPY) causes a hard copy to be produced on the ZX printer. Any other key than these causes the screen to scroll upwards while the key is depressed and will stop if no key is pressed. The choice may be varied each time that '?' is displayed. W Sinclair BASIC'u, gdy drukowany tekst osiągnie spód ekranu, generowany jest błąd 5. W MCODER'ze, gdy wydruk tekstu osiągnie ten punkt, pojawi się znak ? w negatywie na spodzie ekranu po lewej stronie. Naciśnięcie CONT powoduje CLS i program wykonuje się dalej (przytrzymując palec na klawiszu CONT powodujesz, iż proces ten powtarza się w nieskończoność). Naciśnięcie SHIFT+EDIT (SHIFT+1 w PC) zatrzymuje program, klawisz D (SLOW) powoduje przewijanie treści ekranu z szybkością jednego wiersza na sekundę, naciśnięcie Z (COPY) tworzy kopię ekranu na drukarce ZX Printer. Dowolny inny klawisz od opisanych powoduje przewijanie ekranu w górę, gdy klawisz jest wciśnięty i zatrzymanie przewijania, gdy klawisz zostanie zwolniony. Klawisze te można dowolnie wybierać przy każdym wyświetleniu znaku "?".

POINTS TO REMEMBER

DO ZAPAMIĘTANIA

When running a compiled proyram MCODER must always be present as it contains the run time system and arithmetic routines.

You must not use SINCLAIR'S scroll command if you intend to mix BASIC and compiled code as this destroys the regularity of the display file which MCODER needs.

Przy wykonywaniu skompilowanego programu MCODER zawsze musi być obecny, ponieważ zawiera on procedury wykorzystywane w czasie działania programu oraz procedury arytmetyczne.

Jeśli masz zamiar mieszać program w BASIC'u z programem skompilowanym, to nie powinieneś używać rozkazu SCROLL, ponieważ niszczy on regularność bufora obrazu, której wymaga MCODER.

Further features of MCODER

Dalsze cechy MCODER'a

You may choose where to put the code generated by MCODER if you enter by RAND USR 17287 MCODER will prompt "CODE" to which you should reply with the positive integer number address to which the code should be compiled. To find out how long the code will be compile to 0.

There are several other useful locations. In you program POKE 16417,N causes the screen to scroll without asking "?" N times. At the end of this time location 16417 will again contain sero.

Locations (16507 and 1650B) contain the present default string length (usually 32) which may be POKEd in your program to change the default. This value is reset as your program starts.

Locations (16536 and 16537) are used to prevent lines at the top of the screen from scrolling. The value should be n*33 where n is the number of lines to be left alone.

Location 16535 is the location which causes the compiler to auto scroll during compilation. If this is poked with zero then the compiler will wait as described in the section on scrolling above. Pressing D causes the generated code to be displayed.

Możesz określić miejsce umieszczenia kodu tworzonego przez MCODER, jeśli wejdziesz poleceniem RAND USR 17287. Wtedy MCODER wyświetli zapytanie CODE, na które powinieneś odpowiedzieć wprowadzając adres, pod którym ma zostać umieszczony skompilowany kod. Aby poznać rozmiar kodu, skompiluj go pod adres 0

Istnieje również kilka innych użytecznych adresów. W twoim programie POKE 16417,N powoduje przewinięcie ekranu N razy bez wyświetlania znaku "?". Na końcu pod adresem 16417 znów znajdzie się zero.

Adresy 16507 i 16508 zawierają obecną standardową długość łańcuchów (zwykle 32), którą można zmienić za pomocą POKE. Wartość ta jest resetowana przy starcie programu.

Adresy 16536 i 16537 są używane do zapobiegania przewijania wierszy u góry ekranu. Wartość przechowywana tam powinna być równa n*33, gdzie n określa liczbę wierszy pozostawianych w spokoju.

Adres 16535 określa automatyczne przewijanie wierszy podczas kompilacji. Jeśli zostanie tu wstawione zero, to kompilator będzie czekał, jak opisano powyżej w punkcie dotyczącym przewijania ekranu. Naciśnięcie klawisza D spowoduje wyświetlenie wygenerowanego kodu.

You may wish to have several sections of compilod code. This is achieved by the following procedure:-
  1. Compile the first section. The entry point will be given (X ). Now POKE X-6,1 to convert line 2 into line 1.
  2. Compile section 2. A new entry point will be given (Y). RAND USR X still works to access the first section and RAND USR Y accesses the second. This may be repeated as often as space allows. (NOTE to users with machines greater than 16k. On no account must you allow any section of code generated by MCODER to crosss the 32k word boundary).
  3. If you wish to have your own machine code put it in a REM at line 1. The first byte available will be at location 20498. Your compiled code will not now start at 20500 but you will be given the correct entry address.
Możesz potrzebować kilka części skompilowanego kodu. Osiąga się to przy pomocy następującej procedury:
  1. Skompiluj pierwszą  część. Otrzymasz adres wejścia X. Teraz wpisz polecenie POKE X-6,1, które zmieni wiersz 2 w wiersz 1.
  2. Skompiluj część 2. Dostaniesz nowy punkt wejścia Y. RAND USR X wciąż działa i pozwala wejść do pierwszej części kodu a RAND USR Y daje dostęp do drugiej. Operację można powtarzać tyle razy, na ile pozwala rozmiar dostępnej pamięci. (UWAGA użytkownicy z komputerami o pamięci większej niż 16KB - pod żadnym pozorem nie wolno dopuścić, aby żadna z części skompilowanego przez MCODER kodu przekroczyła granicę 32K).
  3. Jeśli chcesz mieć swój własny kod maszynowy, umieść go w instrukcji REM w wierszu nr 1. Pierwszy dostępny bajt będzie się znajdował pod adresem 20498. Twój skompilowany kod teraz nie będzie pod adresem 20500, lecz pod tym, który otrzymasz po kompilacji.
The BASIC code may be quickly deleted by using RAND USR 17281. Program w języku BASIC można szybko usunąć z pamięci wykorzystując polecenie RAND USR 17281.

As an example of MCODERS speed.

Przykład szybkości skompilowanego przez MCODER'a kodu

Enter the following short program and compile it.

100 FOR A=1 TO 50
200 FOR B=1 TO 30
300 PLOT A,B
400 NEXT B
500 NEXT A
600 STOP

Once it has compiled compare the running speed of the compiled code with that of the BASIC and you will see the kind of improvement MCODER brings.

Wprowadź następujący, krótki program i skompiluj go:

100 FOR A=1 TO 50
200 FOR B=1 TO 30
300 PLOT A,B
400 NEXT B
500 NEXT A
600 STOP

Gdy program zostanie skompilowany, porównaj prędkość kodu skompilowanego z prędkością programu w języku BASIC, a naocznie zobaczysz korzyści ze stosowania MCODER'a.

MCODER II Copyright 1983 D.C. Threlfall

MCODER II Copyright 1983 D.C. Threlfall

MCODER II

ZX81
(c) P.S.S. 1983

452, Stoney Stanton Road,
Coventry
CV6 5DG.
Telephone (0203) 667556
MCODER II

ZX81
(c) P.S.S. 1983

452, Stoney Stanton Road,
Coventry
CV6 5DG.
Telefon (0203) 667556

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.