`AmiARM` pomiędzy stacją dyskietek od Amigi 500, a komputerem PC
Transkrypt
`AmiARM` pomiędzy stacją dyskietek od Amigi 500, a komputerem PC
Autor: Krzysztof Bałażyk Projekt z MARM Interfejs komunikacyjny `AmiARM` pomiędzy stacją dyskietek od Amigi 500, a komputerem PC Data: 20.03.2016 Spis treści Cel projektu ...................................................................................................................... 1 Motywacja......................................................................................................................... 1 Specyfikacje ...................................................................................................................... 2 3.1. Format dyskietek...................................................................................................... 2 3.2. Interfejs komunikacji stacji dyskietek ................................................................... 4 3.3. Opis protokołu .......................................................................................................... 5 4. Schemat działania i wymagane elementy ....................................................................... 6 3.1. Płytka ewaluacyjna STM32F4-Discovery .............................................................. 6 4.2. Aplikacja do obsługi po stronie PC ........................................................................ 7 4.3. Nakładka na płytkę dydaktyczną ........................................................................... 7 4.4. Stacja dyskietek ........................................................................................................ 9 5. Szkielet działania urządzenia ........................................................................................ 10 1. 2. 3. 1. Cel projektu Celem projektu jest: • stworzenie, w oparciu o mikrokontroler z rodziny ARM, interfejsu komunikacyjnego, o roboczej nazwie `AmiARM`, pomiędzy stacją dyskietek od komputera Amiga 500, a PC, • aplikacji po stronie PC do jego obsługi. Aplikacja, komunikując się z tworzonym interfejsem, powinna umożliwiać takie operacje, jak: • formatowanie dyskietki, • odczyt całej dyskietki Amigi i jej zapis do pliku po stronie PC w formie obrazu dyskietki (format ADF – Amiga Disk Format), • odczyt obrazu dyskietki z pliku ADF i jego zapis na dyskietkę, 2. Motywacja Jestem miłośnikiem i posiadaczem starszych komputerów i konsol (Amiga 500/600, Atari 2600/65XL, Commodore 64, ZX Spectrum 48, Pegasus, NES, SNES). Mam w swojej kolekcji pokaźną liczbę dyskietek od Amigi 500 (rysunek 1), które warto byłoby zgrać na PC, gdyż wraz z upływem czasu dyskietki starzeją się i jako nośnik magnetyczny – mogą przestać być odczytywane w pewnym momencie (i tak sporo z nich może już mieć błędne sektory). Ponadto, rozgrywka na fizycznym komputerze Amiga daje dużo więcej wrażeń, niż na emulatorze uruchamianym na PC, dlatego warto czasami nagrać posiadaną grę na dyskietkę i cieszyć się rozgrywką na Amidze. Już wcześniej próbowałem tworzyć podobne urządzenie, w oparciu o mikrokontroler AVR Atmega 8, jednak projekt nie odniósł sukcesu, gdyż ten układ: • był zbyt wolny do tego celu, nawet przy maksymalnym taktowaniu z zewnętrznego oscylatora 16 MHz, a sama komunikacja ze stacją dyskietek wymaga precyzyjnego pomiaru odcinków, 1 • posiadał zbyt mało pamięci RAM (1 kB) – odczyt pełnego, nieprzetworzonego sektora i jego przetworzenie wymaga trochę więcej pamięci. Rysunek 1: Posiadana kolekcja gier na Amigę (około 300 sztuk), którą warto byłoby zarchiwizować. 3. Specyfikacje 3.1. Format dyskietek Dyskietki, używane przez komputery z rodziny Amiga to standardowe 3.5 calowe dyskietki, identyczne z tymi, jakich używano jeszcze w ubiegłym wieku w komputerach PC. Jedyną różnicą jest gęstość zapisu – w Amigach używane są dyskietki o standardowej gęstości (ang. DD – Double Density), a w komputerach PC – zwiększonej gęstości (ang. HD – High Density), skutkującej podwojeniem pojemności. Różnica w wyglądzie pomiędzy dyskietką DD, a HD polega jedynie na obecności dodatkowego otworu identyfikacyjnego w tej drugiej – rysunek 2. Rysunek 2: Dyskietka DD (po lewej) i HD (po prawej). Niestety, komputery Amiga formatują dyskietki w zupełnie odmiennym standardzie, niezgodnym ze standardem PC, dlatego ich odczyt w komputerach PC jest niemożliwy. Ponadto, kontroler stacji dyskietek, obecny na płycie głównej PC posiada sprzętowe rozwiązania, zajmujące się odczytem i zapisem sektorów, zatem niemożliwe jest stworzenie oprogramowania na PC, które umożliwiłoby odczyt takiej dyskietki z użyciem tego kontrolera, czyli za pomocą wbudowanej w komputer stacji. Natomiast kontroler stacji dyskietek obecny w komputerze Amiga (układ Paula) jest bardzo prostym interfejsem, 2 którego cała logika sterująca została przeniesiona do oprogramowania Amigi. Dzięki temu w Amidze można bez problemu odczytywać i zapisywać zarówno dyskietki od PC jak i Amigi. Warto też wspomnieć, ze fizyczna konstrukcja obu stacji dyskietek jest bardzo podobna, jedyną rożnicą jest zwykle mechanizm umożliwiający współdziałanie dwóch stacji dyskietek na jednej taśmie FDD (na PC można połączyć dwie takie stacje, a w Amidze cztery) oraz mechanizm wykrywania ścieżki zerowej, czyli pozycji, do której powinna się przesunąć głowica stacji – w stacji od PC jest on zintegrowany w stacje dyskietek, a w stacji od Amigi wykrywanie odbywa się w sposób programowy. Dlatego z powodzeniem można (za pomocą drobnych modyfikacji) używać stacji dyskietek od PC w Amidze, w drugą stronę natomiast nie jest to możliwe. Tabela 1: Parametry dyskietek dyskietka DD HD bajty/sektor sektory/ścieżkę ścieżek/cylinder cylindry/dyskietkę 11 22 2 2 80 80 512 512 pojemność w bajtach 901 120 1 802 240 Rysunek 3: Organizacja obszarów dyskietki (jedna strona). Ponieważ dyskietki są dwustronne, tak samo należy sobie wyobrażać obszary z drugiej strony Dane na dyskietce, zapisane są za pomocą domen magnetycznych. Zmiany namagnesowania sąsiednich obszarów są kodowane jako 0 lub 1. Jednak wartości te nie przekładają się już bezpośrednio na bity danych, lecz wykorzystywane jest następujące kodowanie MFM: bit danych 1 0 0 bity magnetyczne kodowane w MFM 01 10 jeśli poprzedza go 0 bit danych 00 jeśli poprzedza go 1 bit danych Zatem ciąg danych o długości N bitów kodowany jest za pomocą 2*N bitów w MFM. Każda ścieżka, czyli ciąg danych położony w tej samej odległości od jej środka strukturę, ukazaną w poniższej tabeli: Tabela 2: Struktura ścieżki, byte = 8 bity, word = 16 bitów, long = 32bity Offset Ilość MFM Typ w polu elementów (bajty) 0x00 word 2 Synchronizacja (0x08 bajtów MFM) 0x04 word 1 0x06 word 1 Nagłówek sektora (0x20 bajtów MFM) 0x08 long (32b) 1 Opis MFM 0xAAAA, 0xAAAA (po zdekodowaniu: 0x00, 0x00) MFM: 0x4489 (po zdekodowaniu: 0xA1, 0xA1) MFM: 0x4489 (po zdekodowaniu: 0xA1, 0xA1) Info (bity nieparzyste) 3 0x0C long (32b) 1 0x10 long (32b) 4 0x20 long 4 Sumy kontrolne (0x10 bajtów MFM) 0x30 long 1 0x34 long 1 0x38 long 1 0x3c long 1 Dane z sektora (0x400 bajtów MFM) 0x40 byte 512 0x240 byte 512 Koniec danych z sektora Info (bity parzyste) Etykieta sektora (nieparzyste) Etykieta sektora (parzyste) Suma kontrolna nagłówka (nieparzyste) Suma kontrolna nagłówka (parzyste) Suma kontrolna danych (nieparzyste) Suma kontrolna danych (parzyste) Zakodowane w MFM dane sektora (nieparzyste) Zakodowane w MFM dane sektora (parzyste) Każda ścieżka zawiera 0x3200 bajtów danych MFM. Ponieważ jednak: (0x04 + 0x08 + 0x20 + 0x10 + 0x400) * 11 = 0x2E94, to w środku ścieżki jest obszar 0x3200 – 0x2E94 = 0x36C zer, oddzielający początek od końca ścieżki. 3.2. Interfejs komunikacji stacji dyskietek W stacji dyskietek obecne jest 34-złączowe gniazdo o strukturze przedstawionej na poniższym rysunku (poziomy napięć TTL): Rysunek 4: Specyfikacja złącza stacji dyskietek !CHNG !MTRON !INDEX !SEL0 !SEL1 DIR Kierunek Stacja – Komputer -> <-> <<<- !STEP <- !WD !WE !TRK0 !WPROT !RD !SIDE !RDY <<-> -> -> <-> Nazwa Opis Gdy aktywny, nastąpiło wyjęcie dyskietki ze stacji Gdy aktywny, silnik obracający dyskietkę jest włączony Gdy aktywny, dyskietka jest obecna w stacji Gdy aktywny, jedna wybrana z kilku stacji dyskietek podłączonych do taśmy reaguje na sygnały Wybór kierunku poruszania się głowicy (0 – wewn. 1 – zewn.) Narastające zbocze powoduje przesunięcie się głowicy o jedną ścieżki, zgodnie z kierunkiem na złączu DIR Bit do zapisania na dyskietce Rosnące zbocze powoduje zapis na dyskietce bitu WD Detekcja ścieżki zerowej Gdy aktywny, dyskietka jest zabezpieczona przed zapisem Odczytane dane z powierzchni dyskietki Wybór strony dyskietki (0 – górna, 1 – dolna) Gdy aktywny, stacja jest gotowa na przyjmowanie poleceń 4 3.3. Opis protokołu Poniższe diagramy przedstawiają przebiegi wymagane przy odczycie i zapisie dyskietki: Rysunek 5: Dostęp do stacji dyskietek Rysunek 6: Zapis na dyskietkę Rysunek 7: Odczyt z dyskietki 5 4. Schemat działania i wymagane elementy Kompletny schemat działania tworzonego interfejsu przedstawia poniższy rysunek Rysunek 8: Schemat tworzonego interfejsu 3.1. Płytka ewaluacyjna STM32F4-Discovery Sercem urządzenia jest płytka ewaluacyjna STM32F4-Discovery, która będzie się komunikować z PC za pomocą USB (rysunek 9). Taka płytka jest wystarczająca do tego celu, gdyż: • obecny w niej mikrokontroler STM32F407, posiadający parametry podane w tabeli 1 powinien podołać zadaniu (odpowiednia prędkość, ilość pamięci i liczba końcówek wejścia/wyjścia), • na płytce obecne jest gniazdo USB, wymagane do komunikacji z PC. Tabela 3: Minimalne i obecne parametry użytej płytki dydaktycznej Parametr Rdzeń Maksymalna szybkość: Ilość pamięci Flash: Ilość pamięci RAM: Ilość końcówek we/wy: Obecność USB: Wartość dla STM32F407 lub STM32F4-Discovery Cortex M4F 168 MHz 1 MB 192 kB 80 tak 6 Wymagane minimum 50 8 kB 32 kB 20 tak Rysunek 9: Użyta w projekcie płytka STM32F4-Discovery 4.2. Aplikacja do obsługi po stronie PC Po stronie PC zostanie stworzona aplikacja do obsługi interfejsu, napisana w środowisku Microsoft .NET (język C#). Taki wybór podyktowany: • bardzo łatwym i szybkim tworzeniem aplikacji zarówno okienkowych (metodyka WYSIWYG) jak i konsolowych, • dużą liczbą bibliotek, np. do obsługi USB, • szybkością działania, • możliwością uruchomienia na systemach z rodziny Windows (po zainstalowaniu środowiska .NET Framework) oraz Linux (za pomocą projektu Mono). 4.3. Nakładka na płytkę dydaktyczną Do płytki zostanie zaprojektowana i stworzona nakładka, zawierająca m.in. gniazdo do podłączenia stacji dyskietek, wyświetlacz w standardzie HD77480 (do wyświetlania komunikatów diagnostycznych) oraz kilka przycisków (gdyby zaszła potrzeba ich użycia w projekcie również do celów diagnostycznych). Płytka będzie posiadać dwa rzędy gniazd kołkowych tak, aby można było ją nałożyć na STM32F4-Discovery. Podczas przydzielania wyprowadzeń STM32 do komponentów układu (stacja dyskietek, wyświetlacz, przyciski) 7 starałem się trzymać zasady, aby te same elementy były podłączone do jednego portu. Poniższy schemat przedstawia sposób połączeń oraz przypuszczalną realizacje już po wykonaniu. Rysunek 10: Przydział wyprowadzeń do poszczególnych elementów układu Rysunek 11: Wygląd PCB z nakładką 8 4.4. Stacja dyskietek Stacja dyskietek 3.5 cala, użyta w projekcie, pochodzi z komputera Amiga 500. Rysunek 12: Użyta stacja dyskietek, widok z przodu, z tyłu oraz zbliżenie na złącze Będzie ona połączona z nakładką za pomocą taśmy 34 złączowej, dokładnie takiej, jaką łączy się stacje z płytą główną komputera Amiga 500. Zasilanie stacji dyskietek od Amigi zostanie dołączone z zewnątrz, gdyż sama stacja oprócz napięcia +5 V (do sterowania logiką) wymaga także napięcia +12 V (do sterowania silnikami). Są, co prawda stacje, które wymagają jedynie napięcia +5 V, ale jego pobór może przekraczać 500 mA, oferowanych z gniazda USB, zatem i tak konieczne byłoby połączenia zewnętrznego zasilacza. Rysunek 13: Zasilacz (12V 2A, 5V 2A) użyty do zasilenia stacji dyskietek, konieczne będzie wykonanie przejściówki Molex-FDD 9 5. Szkielet działania urządzenia Urządzenie przez większość czasu znajduje się w stanie gotowości (GOTOWY), w którym oczekuje na polecenia, otrzymywane przez interfejs USB. Urządzenie widoczne jest w systemie jako interfejs USB HID, w ramach którego udostępnia następujące polecenia: o sprawdzenie gotowości na przyjęcie rozkazu argumenty: • brak wynik: • R – aktualny stan urządzenia: {GOTOWY, ZAJĘTY} o odczyt sektora argumenty: • N – numer sektora do odczytu wynik: • S – status: {SUKCES, BŁĄD} • T – tablica 512 bajtów z odczytanego sektora (tylko w przypadku sukcesu) • E – kod i opis błędu (tylko w przypadku błędu) o odczyt całej ścieżki 11 sektorów argumenty: • M – numer ścieżki do odczytu wynik: • S – status: {SUKCES, BŁĄD} • T – tablica 512 * 11 bajtów zawierające bajty kolejnych uporządkowanych sektorów ze ścieżki (tylko w przypadku sukcesu) • E – kod i opis błędu (tylko w przypadku błędu) o zapis pojedynczego sektora argumenty: • N – numer sektora do zapisu • T – tablica 512 bajtów do zapisu w sektorze wynik: • S – status: {SUKCES, BŁĄD} • E – kod i opis błędu (tylko w przypadku błędu) o zapis całej ścieżki 11 sektorów argumenty: • M – numer ścieżki do zapisu • T – tablica 512 * 11 bajtów zawierająca bajty kolejnych u porządkowanych sektorów ze ścieżki wynik: • S – status: {SUKCES, BŁĄD} • E – kod i opis błędu (tylko w przypadku błędu) o sformatowanie dyskietki argumenty: • L – etykieta dyskietki, wynik: • S – status: {SUKCES, BŁĄD} • E – kod i opis błędu (tylko w przypadku błędu) 10 Po wybraniu jednej z powyższych operacji, urządzenie przechodzi do stanu `ZAJĘTY`, realizując w nim zażądaną funkcjonalność. Po wykonaniu funkcji, urządzenie przechodzi do stanu `WOLNY` i jest gotowe na przekazanie wyników operacji. Ponieważ w protokole USB tylko urządzenia nadrzędne (komputer) może inicjować transmisje, dlatego konieczny jest mechanizm odpytywania o gotowość i odebranie od urządzenia wyników dopiero, gdy będą już gotowe. Odczyt ścieżki polega na: • ustawieniu głowicy na odpowiednią ścieżkę, • poczekaniu aż znajdą się bajty synchronizacji, • odczyt odpowiedniej liczby bajtów, • zdekodowanie wszystkich bajtów z MFM, • umieszczenie ich w buforze i wysłanie do PC gdy ten zażąda odczytu wyników Odczyt pojedynczego sektora jest analogiczny, jak całej ścieżki, lecz już po zdekodowaniu wszystkich bajtów z MFM następuje wyłuskanie odpowiedniego sektora i umieszczenie tylko jego w buforze. Zapis pojedynczego sektora wymaga: • ustawieniu głowicy na odpowiednią ścieżkę, • odczytania całej ścieżki, • jej zdekodowania, • modyfikacji w niej podanego sektora, • zakodowaniu całości do MFM, • zapisaniu całej tak zmodyfikowanej ścieżki. Zapis całej ścieżki natomiast wymaga: • zakodowaniu podanej ścieżki do MFM, • ustawieniu głowicy na odpowiednią ścieżkę, • zapisaniu całej tak zmodyfikowanej ścieżki. 11 5. Efekt prac W efekcie powstało urządzenie ukazane na poniższym zdjęciu wraz z oprogramowaniem do jego obsługi po stronie PC, napisanym w języku C# na platformie .NET. Rysunek 14: Powstałe urządzenie Rysunek 15: Oprogramowanie do obsługi po stronie PC Jedyną zmianą w porównaniu do oryginalnej specyfikacji było zastąpienie interfejsu USB interfejsem szeregowym, jednak wykorzystując przejściówkę COM-USB w efekcie uzyskana została identyczna funkcjonalność przy mniejszym nakładzie pracy (specyfikacja USB dla ARMa jest dość zagmatwana). Urządzenie wykorzystuje port USART6 (USART1 na płytce 12 STMF4 Discovery nie działa, natomiast wyprowadzenie TX USART2 jest podłączone do diody oraz kondensatora 4.6uF, który skutecznie blokuję transmisję powyżej 1200 b/s). Nie została też wytrawiona płytka z urządzeniem, lecz całość połączona jest za pomocą kabelków. Obsługa protokołu komunikacji ze stacją dyskietek Aby móc komunikować się z stacją dyskietek, urządzenie implementuję obsługę protokołu stacji dyskietek opisanego wyżej. Wszystkie sygnały sterujące stacją (posuw głowicy, wybór kierunku, bit odczytanych danych, itp.) są podłączone do wyprowadzniem ARMa, skonfigurowanych jako GPIO. Poniższy rysunek przedstawia przebieg czasowy danych przesyłanych przez stację. Rysunek 16: Przebieg danych Dane, kodowane w opisanym wcześniej formacie MFM, składają się z sygnału jednobitowego, przy czym stan niski odpowiada wartości 1, a stan wysoki 0. Jeden okres sygnału koduje od 2 do 4 bitów, w zależności od jego czasu trwania. • 2us stan niski + 2us stan wysoki = okres 4us: 10 • 2us stan niski + 4us stan wysoki = okres 6us: 100 • 2us stan niski + 6us stan wysoki = okres 8us: 1000 Aby więc odpowiednio interpretować te dane, ARM musi zliczać długość okresu trwania sygnału z linii danych. Mikrokontroler jest taktowany częstotliwością 100 MHz, uzyskaną przez powielenie za pomocą wewnętrznego PLL sygnału z zewnętrznego kwarcu 8MHZ. Taka wartość była podyktowana koniecznością precyzyjnego zliczania okresów sygnału. Zliczanie okresu polega na uruchomieniu w tle licznika (TIM2), oraz podpięciu sygnału danych do przerwania, które jest zgłaszane w momencie narastającego zbocza. Porównanie wartości licznika TIM2 pomiędzy zboczami pozwala wyrazić długość okresu trwania sygnału w taktach licznika. Ponadto, jeśli licznik TIM2 przepełni się, oznacza to, że zbyt długo nie pojawiło się następne zbocze narastające – w tej sytuacji sygnalizuje to brak dyskietki lub nieprawidłową ścieżkę. Ponieważ jednak czasy trwania okresów mogą trochę odbiegać od założonej specyfikacji, zostało odczytanych 1000 okresów z referencyjnej dyskietki. Histogram czasów zliczonych przez licznik przedstawia poniższa tabela: Czas zliczony 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 Ilość wystąpień 0 0 0 7 142 335 79 11 0 1 4 117 165 8 0 1 2 9 52 56 9 1 1 Widać wyraźne maksimum dla 5/6, 12/13 oraz 19/20. Na tej podstawie zostały zadane następujące przedziały w funkcji dekodującej dane: • 0..9: ciąg danych 10 • 10..15: ciąg danych 100 • 16...255: ciąg danych 1000 13 Ponieważ jedna ścieżka składa się z: 8 bitów MFM/1bajt MFM * 1088 bajt MFM/sektor * 11sektor/ścieżka = 95744, w pamięci mikrokontrolera został stworzony bufor uint8_t o rozmiarze 100000. • w pierwszym etapie do tego bufora zapisywane są długości kolejnych okresów trwania sygnału wejściowego. Jest to czynność wymagająca dużej precyzji, więc nie może być z nią równolegle wykonywana inna. • Następnie powyższe dane są zamieniane na ciągi binarne MFM • Następie odnajdowywany jest początek ściężki za pomocą słowa synchronizacyjnego, a potem dekodowane są dane MFM do danych użytkownika, które następnie mogą zostać przesłane do PC. Schemat urządzenia Schemat urządzenia jest zgodny z tym zaprezentowanym wyżej, jednak nastąpiły drobne różnice w przydziale połączeń co do pinów: Stacja dyskietek: #define nSEL0 #define nSEL1 #define nMTRON #define DIR #define STEP #define nTRK0 #define RDBIT #define SIDE A7 C4 C5 B0 B1 B2 E7 E8 #define nWRPRT #define nWD #define nWE E13 E15 E14 //10 //12 //16, //18 //20 //26 //30 //32 Wyświetlacz: #define LCD_E #define LCD_RW #define LCD_RS #define LCD_D0 #define LCD_D1 #define LCD_D2 #define LCD_D3 #define LCD_D4 #define LCD_D5 #define LCD_D6 #define LCD_D7 C2 C1 C0 C3 E10 A1 E12 E11 A4 A5 A6 USART: TX: PC7 RX: PC6 Pin testowy do gnerowania przebiegu: #define TEST E9 Pliki w projekcie: Projekt składa się z następujących plików: • amifdd.h – obsługa stacji dyskietek • lcd2.h – obsługa wyświetlacza • krzysioarmutils.h – makra operujące na pinach GPIO oraz inne przydatne funkcje • main.c – główny plik z projektem Funkcja main: int main(void) { char text[25]; uint32_t freq = set_clock_PLL(8, 400, 4, 4); configure_int_timerr(); lcd_init(); snprintf(text, sizeof(text), "AmiAVR v1.0, f=%d MHz", freq / 1000000); lcd_gotoxy(0, 0); lcd_display_text(text); fdd_init(); as_output(TEST); as_input(BTN, PULL_DOWN); usart_init(); while (true) { char command = usart_receive_byte(); switch (command) { case 'R': cmd_read_track(); break; case 'P': cmd_is_write_protected(); break; case 'W': 14 cmd_write_track(); break; case 'T': cmd_test(); break; case 'M': cmd_move_head(); break; default: cmd_unknown(command); break; } } } Funkcjonalność aplikacji po stronie PC: Rysunek 17: Odczyt ścieżki i całej dyskietki 15 Rysunek 18: Zapis ścieżki, sprawdzenie zabezpieczenia przed zapisem Rysunek 19: Odtwarzanie muzyki na stacji głowicy Protokół komunikacji urządzenia z PC (=> do urządzenia, <= do PC) Odczyt ścieżki: => ‘R’ =>numer ścieżki (0..11) => numer strony (0 – góra, 1 – dół) <= ‘F’: gdy brak dyskietki <= ‘T’: gdy ścieżka nie znaleziona 16 <= ‘O’: gdy odczyt się powiódł, po czym nastąpi 11*512 bitów z danej ścieżki Sprawdzenie zabezpieczenia przed zapisem: => ‘P’ <= 0 gdy niezabezpieczona, 1 gdy zabezpieczona Zapis ścieżki: => ‘W’ Sprawdzenie gotowości urządzenia: => ‘T’ <= ‘T’ Przesunięcie głowicy na żądaną pozycje (używane do odgrywania melodii): => ‘M’ =>numer ścieżki (0..11) =>numer strony (0 – góra, 1 – dół) =>młodszy bajt ilości danych do zapisu (l_len) =>starszy bajt ilości danych do zapisu (h_len) =>bajty do zapisu na ścieżkę = l_len | (h_len << 8) 17