SIO
From Atariki
Wersja z dnia 13:28, 7 lip 2005 KMK (Dyskusja | wkład) (→Rozszerzone adresowanie pamięci (65C816)) ← Previous diff |
Aktualna wersja Mono (Dyskusja | wkład) (wydzielenie osobnego artykułu o obsłudze protokołu sio) |
||
Linia 1: | Linia 1: | ||
- | SIO - Serial Input/Output. W założeniach jest to rezydujący w ROM-ie podsystem niskopoziomowych procedur blokowego dostępu do urządzeń szeregowych, to jest przede wszystkim stacji dysków, drukarek, modemów i magnetofonu. | + | Serial Input/Output. W założeniach jest to rezydujący w ROM-ie podsystem niskopoziomowych procedur blokowego dostępu do urządzeń szeregowych, to jest przede wszystkim stacji dysków, drukarek, modemów i magnetofonu. Wszystkie te urządzenia podłącza się w Atari do [[Gniazdo SIO|gniazda SIO]]. |
- | W serii XL do podsystemu SIO dodano także niskopoziomową (blokową) obsługę urządzeń podłączanych do szyny równoległej (PBI), czyli tak zwanych [[nowe urządzenia|nowych urządzeń]]. | + | W serii [[XL]] do podsystemu SIO dodano także niskopoziomową (blokową) obsługę urządzeń podłączanych do szyny równoległej ([[PBI]]), czyli tak zwanych [[nowe urządzenia|nowych urządzeń]]. |
==Sposób użycia== | ==Sposób użycia== | ||
- | Żądaną operację definiuje się ustawiwszy przedtem odpowiednie zmienne w bloku DCB (Device Control Block, $0300), a nastepnie wywołuje skokiem JSR pod JSIOINT $E459, co jest punktem wejściowym interfejsu szeregowo-równoległego. Przy powrocie rejestr Y zawiera wartość 1 w przypadku powodzenia, bądź ujemny [[kody błędów|kod błędu]]. | + | Żądaną operację definiuje się ustawiwszy przedtem odpowiednie zmienne w bloku DCB (Device Control Block, $0300), a następnie wywołuje skokiem JSR pod JSIOINT $E459, co jest punktem wejściowym interfejsu szeregowo-równoległego. Przy powrocie rejestr Y zawiera wartość 1 w przypadku powodzenia, bądź ujemny [[kody błędów|kod błędu]]. |
===Struktura DCB=== | ===Struktura DCB=== | ||
<table border=1 cellpadding=5> | <table border=1 cellpadding=5> | ||
- | <tr><td>Adres</td><td>Etykieta</td><td>Wielkość</td><td>Znaczenie</td></tr> | + | <tr><td><b>Adres</b></td><td><b>Etykieta</b></td><td><b>Wielkość</b></td><td><b>Znaczenie</b></td></tr> |
<tr><td>$0300</td><td>DDEVIC</td><td>Bajt</td><td>Identyfikator urządzenia (zob. niżej).</td></tr> | <tr><td>$0300</td><td>DDEVIC</td><td>Bajt</td><td>Identyfikator urządzenia (zob. niżej).</td></tr> | ||
Linia 18: | Linia 18: | ||
<tr><td>$0302</td><td>DCMND</td><td>Bajt</td><td>Komenda dla urządzenia.</td></tr> | <tr><td>$0302</td><td>DCMND</td><td>Bajt</td><td>Komenda dla urządzenia.</td></tr> | ||
- | <tr><td>$0303</td><td>DSTATS</td><td>Bajt</td><td>Przed wywołaniem SIO należy ustawić tu rodzaj operacji ($40 odczyt, $80 zapis). Po powrocie z systemu znajduje się tu status operacji ([[kody błędów|kod błędu]]).</td></tr> | + | <tr><td>$0303</td><td>DSTATS</td><td>Bajt</td><td>Przed wywołaniem SIO należy ustawić tu rodzaj operacji ($40 odczyt, $80 zapis, $C0 zapis i odczyt, $00 brak transferu danych). Po powrocie z systemu znajduje się tu status operacji ([[kody błędów|kod błędu]]).</td></tr> |
- | <tr><td>$0304</td><td>DBUFA</td><td>Dwa bajty</td><td>Adres bufora.</td></tr> | + | <tr><td>$0304</td><td>DBUFA</td><td>Dwa bajty</td><td>Adres bufora. Przy operacji zapisu i odczytu jednocześnie (DSTATS = $C0) bufor na odczytywane dane znajduje się w tym samym miejscu, co bufor danch przeznaczonych do zapisu.</td></tr> |
- | <tr><td>$0306</td><td>DTIMLO</td><td>Bajt</td><td>Czas oczekiwania - w sekundach - na pozytywną odpowiedź urządzenia.</td></tr> | + | <tr><td>$0306</td><td>DTIMLO</td><td>Bajt</td><td> |
+ | <p>Czas oczekiwania na pozytywną odpowiedź urządzenia, tzw. ''timeout''. Oblicza się to jak następuje: wartość DTIMLO mnożona jest przez 64, w wyniku czego otrzymujemy liczbę "[[ramka|ramek]]" [[VBL]] do odczekania. Zwiększenie DTIMLO o jeden powoduje wydłużenie czasu oczekiwania o 1,28 sek. w systemie PAL i o 1,067 sek. w systemie NTSC. Wartość "0" oznacza 256 jednostek.</p> | ||
+ | <p>Typowo ustawia się tu wartość z zakresu od $06 do $08 (zależnie od kaprysu programisty) dla wszystkich operacji oprócz formatowania. Właściwą wartość timeout dla formatowania urządzenie przesyła w bloku statusu, w odpowiedzi na komendę READ STATUS ("S", zob. niżej).</p> | ||
+ | </td></tr> | ||
<tr><td>$0307</td><td>DUNUSE</td><td>Bajt</td><td>Bajt nieużywany, zarezerwowany do przyszłych zastosowań.</td></tr> | <tr><td>$0307</td><td>DUNUSE</td><td>Bajt</td><td>Bajt nieużywany, zarezerwowany do przyszłych zastosowań.</td></tr> | ||
- | <tr><td>$0308</td><td>DBYT</td><td>Dwa bajty</td><td>Wielkość bufora; musi być zgodna z wielkością transmitowanego bloku danych.</td></tr> | + | <tr><td>$0308</td><td>DBYT</td><td>Dwa bajty</td><td>Wielkość bufora; musi być zgodna z wielkością transmitowanego bloku danych. Zero oznacza 64 kilobajty.</td></tr> |
<tr><td>$030A</td><td>DAUX1</td><td>Bajt</td><td>Pierwszy bajt pomocniczy. W operacjach dyskowych młodszy bajt numeru sektora.</td></tr> | <tr><td>$030A</td><td>DAUX1</td><td>Bajt</td><td>Pierwszy bajt pomocniczy. W operacjach dyskowych młodszy bajt numeru sektora.</td></tr> | ||
Linia 36: | Linia 39: | ||
===Wykaz urządzeń=== | ===Wykaz urządzeń=== | ||
- | Interfejs SIO znajdujący się w ROM-ie rozpoznaje pięć predefiniowanych urządzeń: | + | Komenda wysyłana do urządzenia formowana jest w strukturze CFB (Command Frame Buffer, $023A) składającej się z: |
+ | * CDEVIC | ||
+ | * CCMND | ||
+ | * CAUX1 | ||
+ | * CAUX2 | ||
+ | a uzupełnianej na podstawie DCB. | ||
- | * $31: dyskową pamięć masową (stację dysków, twardy dysk) | + | Istnieje pięć urządzeń zdefiniowanych przez Atari. Właściwy identyfikator urządzenia (CDEVIC) zestawiany jest przez system z kodu urządzenia (DDEVIC) i jego numeru indywidualnego (DUNIT). Wartości te są dodawane, po czym jeszcze odejmuje się 1. Dlatego stację dysków nr 1 można wywołać też jako DDEVIC=$32 i DUNIT=0, liczy się wynik wspomnianego dodawania (CDEVIC). UWAGA: jest to tzw. "nieudokumentowana" cecha procedur szeregowych OS-u, inne urządzenia (jak np. [[nowe urządzenia]]) mogą tego nie robić. |
- | * $40: drukarkę | + | |
- | * $4F: bus master ([[Atari 1090]]) | + | |
- | * $50: port szeregowy RS-232-C | + | |
- | * $60: magnetofon kasetowy | + | |
- | Właściwy identyfikator urządzenia zestawiany jest przez system z kodu urządzenia (DDEVIC) i jego numeru indywidualnego (DUNIT). Wartości te są dodawane, po czym jeszcze odejmuje się 1. Przypisanie identyfikatorów do poszczególnych urządzeń jest niezbyt konsekwentne, np. $31 to stacja dysków numer 1, ale $41 to drukarka numer 2. | + | <table border=1 cellpadding = 5> |
+ | <tr><td><b>DDEVIC</b></td><td><b>CDEVIC</b></td><td><b>Opis</b></td></tr> | ||
+ | <tr><td>$31</td><td>$31-$3F</td><td>dyskowa pamięć masowa (stacja dysków, twardy dysk)</td></tr> | ||
+ | <tr><td>$40</td><td>$40-$43</td><td>drukarka</td></tr> | ||
+ | <tr><td>$4F</td><td>$4F</td><td>bus master (moduł [[1090]])</td></tr> | ||
+ | <tr><td>$50</td><td>$50-$53</td><td>port szeregowy RS-232C</td></tr> | ||
+ | <tr><td>$60</td><td>$60</td><td>magnetofon kasetowy</td></tr> | ||
+ | </table> | ||
- | ===Wykaz typowych komend=== | + | Przypisanie identyfikatorów do poszczególnych urządzeń jest niezbyt konsekwentne, np. CDEVIC=$31 to stacja dysków numer 1, ale CDEVIC=$41 to drukarka numer 2. |
- | <table border=1 cellpadding=5> | + | Urządzeniem, które na podanej powyżej liście jest wyjątkowe, jest magnetofon kasetowy. Jest to jedyne "nieinteligentne" urządzenie peryferyjne, to jest nie zawierające własnego procesora. Wszystkie zadania związane z wysyłaniem danych na magnetofon i odbiorem z niego wykonuje system operacyjny komputera. W odróżnieniu od innych urządzeń, magnetofon okupuje tylko identyfikator $60, a wartość DUNIT jest ignorowana - w związku z tym kody urządzeń od $61 do $6F są (na razie) wolne. |
- | <tr><td>Kod</td><td>Nazwa</td><td>Urządzenie</td><td>R/W</td><td>Ilość danych</td><td>Opis</td></tr> | + | |
- | <tr><td>$21 (!)</td><td>FORMAT DISK</td><td>$31 (stacja dysków)</td><td>R</td><td>128 bajtów</td><td>Formatuje dyskietkę w wybranej uprzednio (komendami PERCOM) gęstości, lub w [[Formaty dyskietek|pojedynczej gęstości]], jeśli stacja nie jest konfigurowalna. Zwraca listę zawierającą do 63 numerów wadliwych sektorów wykrytych w czasie formatowania, zakończoną wartością $FFFF. Niektóre stacje zwracają tu pustą listę ($FFFF i 126 zer), nawet jeśli na dyskietce są wadliwe sektory: po prostu dyskietki nie są już tak drogie, jak pod koniec lat siedemdziesiątych XX wieku...<br> | + | Wartości CDEVIC powyżej $7F są zarezerwowane dla pewnych rozszerzeń protokołu SIO, patrz [[SIO#Rozszerzenia_SIO|niżej]]. |
- | Kontroler [[KMK/JŻ IDE]] nie rozpoznaje tej komendy dla bezpieczeństwa danych na dysku (do partycjonowania i "formatowania" dysku służy oddzielny program).</td></tr> | + | |
- | <tr><td>$22 (")</td><td>FORMAT MEDIUM</td><td>$31 (stacja dysków)</td><td>R</td><td>128 bajtów</td><td>Analogicznie do FORMAT DISK, z tym że formatowanie zawsze przeprowadzane jest w [[Formaty dyskietek|gęstości średniej]]. Komenda wprowadzona razem ze stacją [[1050]]. Kontroler [[KMK/JŻ IDE]] nie rozpoznaje tej komendy dla bezpieczeństwa danych na dysku (do partycjonowania i "formatowania" dysku służy oddzielny program).</td></tr> | + | Ponieważ identyfikator jest częścią wysyłanej do urządzenia komendy, więc budując własne urządzenie można posłużyć się identyfikatorem spoza powyżej wyszczególnionych: |
- | <tr><td>$3F (?)</td><td>POLL</td><td>$31 (stacja dysków)</td><td>R</td><td>1 bajt</td> | + | <table border=1 cellpadding = 5> |
- | <td>Stacje kompatybilne z US Doubler w odpowiedzi na tę komendę przesyłają wartość rejestru POKEY-a służącego do ustawienia częstotliwości nośnej dla przyspieszonej transmisji.</td></tr> | + | <tr><td><b>DDEVIC</b></td><td><b>CDEVIC</b></td><td><b>Opis</b></td></tr> |
- | + | <tr><td>$20</td><td>$20</td><td>[[IDE Plus]], [[SIDE]]</td></tr> | |
- | <tr><td>$4E (N)</td><td>READ PERCOM</td><td>$31 (stacja dysków)</td><td>R</td><td>12 bajtów</td><td>Odczytuje z urządzenia dwunastobajtowy blok danych opisujący jego bieżącą konfigurację, tj. przede wszystkim format znajdującej się w stacji dyskietki. Komenda ta nie jest rozpoznawana przez standardowe stacje Atari, ale jest zaimplementowana we wszystkich rozszerzeniach oraz stacjach innych producentów.</td></tr> | + | <tr><td>$45</td><td>$45</td><td>[[Smart Device]] ( [[APE Time]] i [[URL Submit]])</td></tr> |
- | + | <tr><td>$5A</td><td>$5A</td><td>[[ATR 8000]]</td></tr> | |
- | <tr><td>$4F (O)</td><td>WRITE PERCOM</td><td>$31 (stacja dysków)</td><td>W</td><td>12 bajtów</td><td>Zapisuje do urządzenia dwanaście bajtów opisujących żądaną konfigurację, tj. liczbę ścieżek, stron dyskietki, sektorów na ścieżkę, wielkość sektora, gęstość. Po pomyślnym wykonaniu tej operacji komenda FORMAT DISK ($21) sformatuje dykietkę zgodnie z zapisaną konfiguracją. Komenda ta nie jest rozpoznawana przez standardowe stacje Atari, ale jest zaimplementowana we wszystkich rozszerzeniach oraz stacjach innych producentów. Kontroler [[KMK/JŻ]] IDE nie rozpoznaje tej komendy dla bezpieczeństwa danych na dysku (do definiowania wielkości partycji służy oddzielny program).</td></tr> | + | <tr><td>$61</td><td>$61</td><td>[[AtariSIO]], [[DOS2DOS]]</td></tr> |
- | + | <tr><td>$70</td><td>$70</td><td>[http://www.mathyvannisselroy.nl/aspi.htm Atari ASPI] (zob. [http://pl.wikipedia.org/wiki/ASPI ASPI])</td></tr> | |
- | <tr><td>$50 (P)</td><td>PUT SECTOR</td><td>Wszystkie za wyjątkiem drukarki</td><td>W</td><td>Zależna od urządzenia i trybu pracy.</td><td>Zapisuje do urządzenia blok danych wskazany przez DBUFA, a zawierający DBYT bajtów. W przypadku stacji dysków jest to zapis bez weryfikacji.</td></tr> | + | <tr><td>$71-$74</td><td>$71-$74</td><td>[[SDrive]]</td></tr> |
- | + | <tr><td>$71</td><td>$70</td><td>[[SIO2USB]] [http://www.atariage.com/forums/topic/155690-ape-time/page__view__findpost__p__1916403?s=2e4d3fd681ca05ec0c05b0a7e5474dd6]</td></tr> | |
- | <tr><td>$52 (R)</td><td>READ SECTOR</td><td>Wszystkie oprócz drukarki</td><td>R</td><td>Zależna od urządzenia i trybu pracy.</td><td>Odczytuje z urządzenia blok danych o wielkości DBYT bajtów i zapisuje go w pamięci pod adresem wskazanym przez DBUFA.</td></tr> | + | <tr><td>$73</td><td>$72-$75</td><td>[[SIO2SD|Sio2SD]]</td></tr> |
- | + | ||
- | <tr><td>$53 (S)</td><td>READ STATUS</td><td>Wszystkie oprócz magnetofonu</td><td>R</td><td>4 bajty</td><td>Odczytuje z urządzenia czterobajtowy blok statusu i zapisuje go pod adresem wskazanym przez DBUFA. Typowo komenda ta służy to stwierdzenia, czy urządzenie jest gotowe do pracy.</td></tr> | + | |
- | + | ||
- | <tr><td rowspan=2>$57 (W)</td><td rowspan=2>WRITE SECTOR</td><td rowspan=2>Wszystkie</td><td rowspan=2>W</td><td rowspan=2>Zależna od urządzenia i trybu pracy.</td><td>To samo, co PUT SECTOR ($52). W przypadku stacji dysków zapis przeprowadzany jest z weryfikacją.</td></tr> | + | |
- | <tr><td>W przypadku drukarki długość bufora może wynosić 20, 29 albo 40 znaków (na ogół to ostatnie), a znaczenie DAUX2 jest jak następuje: | + | |
- | * $4E (N) drukowanie normalne | + | |
- | * $53 (S) druk obrócony o 90 stopni | + | |
- | * $44 (D) druk normalny z podwójną szerokością znaków | + | |
- | </td></tr> | + | |
</table> | </table> | ||
- | ===Wykaz komend nietypowych=== | + | ===Wykazy komend=== |
- | <table border=1 cellpadding=5> | + | * [[Lista komend SIO według funkcji]] |
- | <tr><td>Kod</td><td>Nazwa</td><td>Urządzenie</td><td>R/W</td><td>Ilość danych</td><td>Opis</td></tr> | + | * [[Lista komend SIO według kodów operacyjnych]] |
- | <tr><td>$40 (@)</td><td>QUERY BUS</td><td>$4F</td><td>R</td><td>4 bajty</td> | + | ===Blok statusu=== |
- | <td><p>Komendę tę system operacyjny wysyła na port szeregowy przy każdym zimnym starcie. Jej znaczenie jest nieznane, przypuszczalnie nie jest ona w ogóle przeznaczona dla urządzenia szeregowego, lecz dla urządzenia szyny równoległej (może modułu [[Atari 1090]]). Ale nic nie stoi na przeszkodzie ku wykorzystaniu również przez urządzenia szeregowe.</p> | + | Blok statusu przysyłany na komendę żądania statusu ($53) ma strukturę w dużym stopniu zależną od urządzenia. Są to dwa lub cztery bajty, a ich znaczenie dla poszczególnych urządzeń jest opisane poniżej. W pierwszym bajcie statusu obowiązuje jednolity dla wszystkich urządzeń podział na dwie grupy bitów: |
- | <p>Na początku komenda przesyłana jest z DAUX1 = $4F i DAUX2 = $4F ("OO" - jak "open"?). Następnie - i to bez sprawdzenia statusu wykonania się tej operacji - przesyłane jest drugi raz to samo, tym razem z DAUX1 = 0 i DAUX2 = 0. Dopiero po tym sprawdzany jest status - co wskazuje, że przesłana para poleceń ma w istocie stanowić jedną komendę, albo że protokół przewiduje przesyłanie wielu komend na raz, a "00" jest klauzulą, sygnałem końca bloku poleceń.</p> | + | * bity 0-2 sygnalizują status komunikacji pomiędzy komputerem a urządzeniem |
+ | * bity 3-7 sygnalizują status wewnętrzny urządzenia | ||
- | <p>Pozytywna odpowiedź oznacza, że urządzenie nadesłało 4 bajty, z czego dwa pierwsze to ilość pamięci potrzebna do przeprowadzenia całości transmisji. Jeśli jest to więcej niż dostępna ilość pamięci pomiędzy MEMLO a MEMTOP, system ponownie wysyła tę samą komendę, ale DAUX1 i DAUX2 są tym razem ustawione na $4E ("NN" - jak "negative"?). I znów, bez sprawdzenia statusu, jako klauzula wysyłana jest ta sama komenda po raz czwarty z DAUX1 i DAUX2 ustawionymi na zero, a po pozytywnej odpowiedzi na tę sekwencję cała procedura zaczyna się od początku. W przypadku braku pamięci byłaby to pętla nieskończona, ale po wysłaniu przez komputer odpowiedzi "NN", na następną komendę urządzenie zapewne już nie odpowiada tak samo - być może jakoś zmienia ofertę, albo zgłasza błąd.</p> | + | ====Stacja dysków==== |
- | + | ||
- | <p>Trzeci przysłany bajt to identyfikator urządzenia (dla DDEVIC), które odpowiedziało na komendę i z którym będzie prowadzona dalsza komunikacja.</p> | + | |
- | + | ||
- | <p>Po stwierdzeniu poprawności odpowiedzi komputer dokonuje rezerwacji pamięci nad wartością MEMLO zaokrągloną w górę do najbliższej granicy słowa i próbuje dokonać odczytu z urządzenia, które się zgłosiło, 128 bajtów pod adres $03FD, przy użyciu innej "nietypowej" komendy, a mianowicie $26 - SEND HANDLER.</p> | + | |
- | + | ||
- | <p>Trzeba nadmienić, że "handler", którego komputer domaga się przy zimnym starcie, ma mieć raczej charakter ogólnego handlera wszystkiego, czyli innymi słowy ma grać rolę co najmniej części, o ile nie całości, systemu operacyjnego. Procedura ładowania handlera wywoływana jest po procedurze bootowania DOS-u, ale niezależnie od jej wyniku; z czego wniosek, że "handler" może spełniać funkcję zarówno dodatku do DOS-u, jak i zostać załadowany <b>zamiast</b> DOS-u.</p> | + | |
- | + | ||
- | <p>Że chodzi o handler "ogólny", wiadomo stąd, że tą samą drogą można już po całkowitym uruchomieniu systemu, podczas pracy, załadować handler urządzenia <b>konkretnie wskazanego</b>. Robi to [[CIO]] przy każdorazowej próbie otwarcia pliku na urządzeniu, którego system nie zna (nie ma takiego wpisu w tablicy handlerów).</p> | + | |
- | + | ||
- | <p>Odpytanie urządzenia $4F (za którym to identyfikatorem stoi zapewne jakiś moduł rozszerzeń zarządzający podłączonymi do siebie kartami) na okoliczność dysponowania takowym handlerem odbywa się tak samo, jak przy zimnym starcie, z tą jedynie różnicą, że DAUX1/2 nie są wyzerowane. W DAUX1 ma się znajdować identyfikator urządzenia CIO, dla którego to urządzenia potrzebujemy handlera (np. dla magnetofonu $43, czyli "C"), w DAUX2 natomiast przesyła się numer wywoływanego urządzenia (np. dla "C1:" będzie to $01).</p> | + | |
+ | <table border=1 cellpadding=4> | ||
+ | <tr><td><b>Bajt</b></td><td><b>Znaczenie</b></td></tr> | ||
+ | <tr><td>0</td><td> | ||
+ | * bit 0 = 1 - wydana ostatnio komenda nie została rozpoznana | ||
+ | * bit 1 = 1 - przesłany ostatnio blok danych był błędny (błąd sumy kontrolnej) | ||
+ | * bit 2 = 1 - ostatnia operacja nie powiodła się (np. próbowano odczytać wadliwy sektor) | ||
+ | * bit 3 = 1 - dyskietka jest zabezpieczona przed zapisem | ||
+ | * bit 4 = 1 - kręci się silnik obracający dyskietkę | ||
+ | * bit 5 = 1 - sektory 256-bajtowe (128-bajtowe w przeciwnym wypadku) | ||
+ | * bit 6 = 0 - zarezerwowany | ||
+ | * bit 7 = 1 - praca w średniej gęstości | ||
+ | <p>W przypadku interfejsu [[KMK/JŻ]] IDE znaczenie mają tylko bity 3 i 5, reszta jest zawsze wyzerowana.</p> | ||
</td></tr> | </td></tr> | ||
- | + | <tr><td>1</td><td><p>Kopia rejestru statusu kontrolera WD 1772 (lub kompatybilnego), wszystkie bity są poddane inwersji.</p> | |
- | <tr><td>$26 (&)</td><td>SEND HANDLER</td><td>Urządzenie o kodzie zwróconym przez komendę QUERY BUS ($40)</td><td>R</td><td>128 bajtów</td> | + | * bit 0 = 1 - BUSY |
- | <td><p>Komenda ta nie jest nigdzie opisana, ale na szczęście w dokumentacji SIO znajduje się wzmianka o niej pozwalająca ustalić oficjalną nazwę (SEND HANDLER właśnie). Reszta została wywnioskowana z kodu systemu operacyjnego.</p> | + | * bit 1 = 1 - DRQ (Data Request) |
- | <p>Procedura ładowania handlera zaczyna się zawsze od wysłania komendy QUERY BUS ($40). Po otrzymaniu pozytywnej odpowiedzi komputer rozpoczyna ładowanie kolejnych, 128-bajtowych rekordów binarnych, w liczbie do 256 (czyli "handler" może mieć maksimum 32k) oraz interpretację ich zawartości w sposób nie do końca jeszcze dla mnie jasny, jako że formatu danych nie zdołałem jeszcze rozgryźć. Wiadomo, że przesyłany strumień danych zawiera podany explicite znacznik końca pliku - wystąpienie błędu przed napotkaniem tego znacznika powoduje przerwanie procedury z [[kody błędów|kodem błędu]] BOOT ERROR.</p> | + | * bit 2 = 1 - Track 0 not found |
- | <p>Ustawienia zmiennych DCB dla komendy SEND HANDLER wyglądają następująco:</p> | + | * bit 3 = 1 - CRC error |
- | * DDEVIC - kod urządzenia przesłany przez urządzenie $4F na komendę QUERY BUS. | + | * bit 4 = 1 - Record not found |
- | * DUNIT - zawsze $01 | + | * bit 5 = 1 - Seek complete |
- | * DCMND - $26 - SEND HANDLER | + | * bit 6 = 1 - Write protected |
- | * DSTATS - $40 - odczyt | + | * bit 7 = 1 - Not ready |
- | * DTIMLO - 30 sekund | + | <p>Interfejs IDE [[KMK/JŻ]] zwraca zamiast tego zawartość rejestru ERROR kontrolera IDE:</p> |
- | * DBYT - 128 bajtów | + | * bit 0 = 1 - Data Address Mark not found |
- | * DAUX1 - numer kolejny rekordu danych | + | * bit 1 = 1 - Track 0 not found |
- | * DAUX2 - zawsze 0 | + | * bit 2 = 1 - Aborted command |
- | </td></tr> | + | * bit 3, zarezerwowany |
- | + | * bit 4 = 1 - ID not found | |
- | <tr><td>$51 (Q)</td><td>READ SPIN</td> | + | * bit 5, zarezerwowany |
- | <td rowspan=3>$31 (stacja dysków)</td><td rowspan=3>R (?)</td><td rowspan=3>?</td> | + | * bit 6 = 1 - ECC error |
- | <td rowspan=3><p>Komendy te występują jako komendy dyskowe na liście rozkazów SIO w dokumentacji sporządzonej przez Atari. Nie znam jednak stacji, która by na nie reagowała. Mogą to być komendy stacji [[810]], jakieś komendy diagnostyczne jej prototypu, albo komendy planowane, lecz nie zaimplementowane. Dostępna dokumentacja nie zawiera ich opisu.</p></td> | + | * bit 7 = 1 - Bad sector |
- | <tr><td>$55 (U)</td><td>MOTOR ON</td> | + | <p>Podobnie jak powyżej wszystkie bity są poddane inwersji (EOR #$FF).</p> |
- | <tr><td>$56 (V)</td><td>VERIFY SECTOR</td> | + | |
- | </tr> | + | |
- | <tr><td>$21 (!)</td><td>SEND RELOCATOR</td> | + | |
- | <td>Nie wiadomo, nie stacja dysków w każdym razie</td><td>R</td><td>?</td> | + | |
- | <td>Komenda ta występuje jako komenda "nie dysku" na liście rozkazów SIO w dokumentacji sporządzonej przez Atari. Nie znam urządzenia, które by na nie reagowało. Może to być komenda uzupełniająca do opisanego wyżej SEND HANDLER ($26). Dostępna dokumentacja nie zawiera żadnego opisu. | + | |
</td></tr> | </td></tr> | ||
+ | <tr><td>2</td><td>Maksymalny czas oczekiwania na wykonanie komendy (timeout) przewidziany dla operacji dyskowej. Najdłużej trwa formatowanie, zalecaną wartością jest 240.</td></tr> | ||
+ | <tr><td>3</td><td>Nie używany.</td></tr> | ||
</table> | </table> | ||
- | |||
- | ===Blok statusu=== | ||
- | |||
- | Blok statusu przysyłany na komendę żądania statusu ($53) ma strukturę w dużym stopniu zależną od urządzenia. W każdym przypadku są to cztery bajty, a ich znaczenie dla poszczególnych urządzeń jest opisane poniżej. | ||
====Drukarka==== | ====Drukarka==== | ||
Linia 138: | Linia 134: | ||
<tr><td>0</td><td> | <tr><td>0</td><td> | ||
* bit 0 = 1 - wydana ostatnio komenda nie została rozpoznana | * bit 0 = 1 - wydana ostatnio komenda nie została rozpoznana | ||
- | * bit 1 = 1 - przesłany ostatnio blok danych był błędny | + | * bit 1 = 1 - przesłany ostatnio blok danych był błędny (błąd sumy kontrolnej) |
* bit 7 = 1 - drukarka jest programowalna (w drukarkach Atari ten bit jest skasowany) | * bit 7 = 1 - drukarka jest programowalna (w drukarkach Atari ten bit jest skasowany) | ||
Pozostałe bity są zarezerwowane.</td></tr> | Pozostałe bity są zarezerwowane.</td></tr> | ||
Linia 146: | Linia 142: | ||
</table> | </table> | ||
- | ====Stacja dysków==== | + | ====RS-232 ([[850|Atari 850]])==== |
+ | |||
+ | Blok statusu portu RS-232 ma dwa bajty (w pozostałych urządzeniach - cztery). | ||
<table border=1 cellpadding=4> | <table border=1 cellpadding=4> | ||
Linia 153: | Linia 151: | ||
* bit 0 = 1 - wydana ostatnio komenda nie została rozpoznana | * bit 0 = 1 - wydana ostatnio komenda nie została rozpoznana | ||
* bit 1 = 1 - przesłany ostatnio blok danych był błędny (błąd sumy kontrolnej) | * bit 1 = 1 - przesłany ostatnio blok danych był błędny (błąd sumy kontrolnej) | ||
- | * bit 2 = 1 - ostatnia operacja nie powiodła się (np. próbowano odczytać wadliwy sektor) | + | * bit 2, zarezerwowany |
- | * bit 3 = 1 - dyskietka jest zabezpieczona przed zapisem | + | * bit 3, zarezerwowany |
- | * bit 4 = 1 - kręci się silnik obracający dyskietkę | + | * bit 4 = 1 - przepełnienie bufora RS-232 |
- | * bit 5 = 1 - sektory 256-bajtowe (128-bajtowe w przeciwnym wypadku) | + | * bit 5 = 1 - błąd parzystości RS-232 |
- | * bit 6 = 0 - zarezerwowany | + | * bit 6 = 1 - na porcie RS-232 wystąpił nadmiar bitów (overrun) |
- | * bit 7 = 1 - praca w średniej gęstości | + | * bit 7 = 1 - na porcie RS-232 wystąpiło zakłócenie transmisji szeregowej (framing error) |
</td></tr> | </td></tr> | ||
- | <tr><td>1</td><td>Bajt statusu kontrolera WD 1772, wszystkie bity są poddane inwersji. | + | <tr><td>1</td><td> |
+ | * bit 0 = 1 - RCV (czyli RX) ustawione | ||
+ | * bit 1, zarezerwowany | ||
+ | * bit 2, kopia bitu 3 | ||
+ | * bit 3 = 1 - CRX (czyli DCD) ustawione | ||
+ | * bit 4, kopia bitu 5 | ||
+ | * bit 5 = 1 - CTS ustawione | ||
+ | * bit 6, kopia bitu 7 | ||
+ | * bit 7 = 1 - DSR ustawione | ||
</td></tr> | </td></tr> | ||
- | <tr><td>2</td><td>Maksymalny czas oczekiwania na wykonanie komendy (timeout) przewidziany dla operacji dyskowej. Najdłużej trwa formatowanie, zalecaną wartością jest 240.</td></tr> | ||
- | <tr><td>3</td><td>Nie używany.</td></tr> | ||
</table> | </table> | ||
+ | |||
+ | ====Magnetofon kasetowy==== | ||
+ | |||
+ | Przyjmuje się, że magnetofon, jako urządzenie "nieinteligentne", jest zawsze podłączony i gotowy do pracy, a więc nie zachodzi potrzeba sprawdzania jego statusu. W związku z tym funkcja READ STATUS ($53) nie jest dla magnetofonu zaimplementowana. | ||
===Blok PERCOM=== | ===Blok PERCOM=== | ||
- | Tak zwany blok PERCOM nosi nazwę od stacj dysków firmy PERCOM, w których po raz pierwszy pojawiły się odnośne komendy. Jest to 12 bajtów informacji o konfiguracji stacji dysków. Odczyt przeprowadza się komendą $4E ("N"), a zapis - komendą $4F ("O"). | + | Blok PERCOM jest to 12 bajtów informacji o konfiguracji stacji dysków. Odczyt przeprowadza się komendą $4E ("N"), a zapis - komendą $4F ("O"). |
<table border=1 cellpadding=5> | <table border=1 cellpadding=5> | ||
- | <tr><td>Bajt</td><td>Opis</td></tr> | + | <tr><td><b>Bajt</b></td><td><b>Opis</b></td></tr> |
<tr><td>0</td><td>Liczba ścieżek na dyskietce; w praktyce dla stacji dysków spotyka się wartości najczęściej 40 lub 80, rzadziej 35 lub 77. Partycje twardego dysku zwracają 1.</td></tr> | <tr><td>0</td><td>Liczba ścieżek na dyskietce; w praktyce dla stacji dysków spotyka się wartości najczęściej 40 lub 80, rzadziej 35 lub 77. Partycje twardego dysku zwracają 1.</td></tr> | ||
<tr><td>1</td><td>Szybkość przesuwu głowicy ze ścieżki na ścieżkę: | <tr><td>1</td><td>Szybkość przesuwu głowicy ze ścieżki na ścieżkę: | ||
Linia 178: | Linia 186: | ||
* 2 - 12 ms | * 2 - 12 ms | ||
* 3 - 6 ms | * 3 - 6 ms | ||
- | <p>W praktyce stacje przeważnie ignorują przesłaną wartość. W przypadku twardego dysku jest ona bez znaczenia (kontroler KMK/JŻ zwraca w tym bajcie numer wersji wewnętrznego oprogramowania)</p> | + | <p>W praktyce stacje przeważnie ignorują przesłaną wartość. W przypadku twardego dysku jest ona bez znaczenia (kontroler KMK/JŻ zwraca w tym bajcie numer wersji wewnętrznego oprogramowania)</p></td></tr> |
- | </td></tr> | + | |
<tr><td>2</td><td>STARSZY bajt liczby sektorów na ścieżce.</td></tr> | <tr><td>2</td><td>STARSZY bajt liczby sektorów na ścieżce.</td></tr> | ||
- | |||
<tr><td>3</td><td>MŁODSZY bajt liczby sektorów na ścieżce.</td></tr> | <tr><td>3</td><td>MŁODSZY bajt liczby sektorów na ścieżce.</td></tr> | ||
- | + | <tr><td>4</td><td>Liczba aktywnych stron dyskietki zmniejszona o 1 albo najstarszy bajt liczby sektorów partycji twardego dysku (patrz niżej).</td></tr> | |
- | <tr><td>4</td><td>Liczba aktywnych stron dyskietki zmniejszona o 1 albo nastarszy bajt liczby sektorów partycji twardego dysku (patrz niżej).</td></tr> | + | <tr><td>5</td><td> |
- | + | * bit 0 - zarezerwowany | |
- | <tr><td>5</td><td><p>Gęstość zapisu:</p> | + | * bit 1 = 1, dyskietka ośmiocalowa; 5,25 cala w przeciwnym wypadku |
- | <table border=1 cellpadding=5> | + | * bit 2 = 1, gęstość MFM, FM w przeciwnym wypadku |
- | <tr><td>Bit</td><td>Opis</td></tr> | + | * bit 3 = 1, dysk nie ma "stron", a zamiast liczby stron jest podany najstarszy bajt całkowitej liczby sektorów dysku (partycji twardego dysku) |
- | <tr><td>0</td><td>zarezerwowany</td></tr> | + | <p>Pozostałe bity są zarezerwowane i powinny być wyzerowane.</p></td></tr> |
- | <tr><td>1</td><td>Jeśli 1, dyskietka ośmiocalowa (5,25 cala w przeciwnym wypadku)</td></tr> | + | |
- | <tr><td>2</td><td>Jeśli 1, gęstość MFM, FM w przeciwnym wypadku</td></tr> | + | |
- | <tr><td>3</td><td>Jeśli 1, to dysk nie ma "stron", a zamiast liczby stron jest podany najstarszy bajt całkowitej liczby sektorów dysku (partycji twardego dysku).</td></tr> | + | |
- | </table> | + | |
- | </td></tr> | + | |
- | + | ||
<tr><td>6</td><td>STARSZY bajt wielkości sektora (w bajtach)</td></tr> | <tr><td>6</td><td>STARSZY bajt wielkości sektora (w bajtach)</td></tr> | ||
- | |||
<tr><td>7</td><td>MŁODSZY bajt wielkości sektora (w bajtach)</td></tr> | <tr><td>7</td><td>MŁODSZY bajt wielkości sektora (w bajtach)</td></tr> | ||
- | + | <tr><td>8</td><td><p>Niewykorzystany, zapisuje się - i przeważnie odczytuje - jako $FF. W oryginalnych stacjach PERCOM bajt ten sygnalizował stan niektórych funkcji kontrolera stacji i służył do ich wybierania:</p> | |
- | <tr><td>8</td><td>Niewykorzystany, zapisuje się - i przeważnie odczytuje - jako $FF. W oryginalnych stacjach PERCOM bajt ten sygnalizował stan niektórych funkcji kontrolera stacji i służył do ich wybierania: | + | * bit 0 = 1, sektory fizyczne na ścieżce numerowane są od 0, a nie od 1. |
- | <table border=1 cellpadding=5> | + | * bit 1 = 1, sektory fizyczne 1,2,3 mają pełne rozmiary. |
- | <tr><td>Bit</td><td>Opis</td></tr> | + | * bit 2, zarezerwowany |
- | <tr><td>0</td><td>Jeśli 1, sektory na ścieżce numerowane są od 0, a nie od 1.</td></tr> | + | * bit 3, zarezerwowany |
- | <tr><td>1</td><td>Jeśli 1, sektory logiczne 1,2,3 mają pełne rozmiary.</td></tr> | + | * bit 4, zarezerwowany |
- | <tr><td>2</td><td>zarezerwowany</td></tr> | + | * bit 5, zarezerwowany |
- | <tr><td>3</td><td>zarezerwowany</td></tr> | + | * bit 6 = 0, napęd stacji jest odłączony (wyjęty). |
- | <tr><td>4</td><td>zarezerwowany</td></tr> | + | * bit 7 = 1, napęd 80-ścieżkowy pracuje w trybie 40-ścieżkowym. |
- | <tr><td>5</td><td>zarezerwowany</td></tr> | + | <p>W praktyce większość stacji nie ustawia tych bitów zgodnie z powyższym opisem.</p></td></tr> |
- | <tr><td>6</td><td>Jeśli 0, napęd stacji jest odłączony (wyjęty).</td></tr> | + | <tr><td>9</td><td>Niewykorzystane, na ogół 0.</td></tr> |
- | <tr><td>7</td><td>Jeśli 1, napęd 80-ściezkowy pracuje w trybie 40-ścieżkowym.</td></tr> | + | <tr><td>10</td><td>Niewykorzystane, na ogół 0.</td></tr> |
+ | <tr><td>11</td><td>Niewykorzystane, na ogół 0.</td></tr> | ||
</table> | </table> | ||
- | W praktyce większość stacji nie ustawia tych bitów zgodnie z powyższym opisem. | ||
- | </td></tr> | ||
- | <tr><td>9</td><td>Niewykorzystany, na ogół 0.</td></tr> | + | ==Protokół transmisji== |
- | <tr><td>10</td><td>Niewykorzystany, na ogół 0.</td></tr> | + | === Połączenia równoległe === |
- | + | ||
- | <tr><td>11</td><td>Niewykorzystany, na ogół 0.</td></tr> | + | |
- | + | ||
- | </table> | + | |
- | + | ||
- | ==Protokół transmisji== | + | |
Protokół transmisji urządzeń podłączanych do szyny równoległej jest zależny od programu obsługi urządzenia zawartego w jego pamięci ROM. System operacyjny tego nie definiuje. | Protokół transmisji urządzeń podłączanych do szyny równoległej jest zależny od programu obsługi urządzenia zawartego w jego pamięci ROM. System operacyjny tego nie definiuje. | ||
- | Protokół transmisji urządzeń podłączonych do szyny szeregowej jest zdefiniowany następująco: | + | === Połączenia szeregowe === |
- | * 1 bit startu | + | Podziału poszczególnych bajtów na bity i wyemitowania ich na złącze szeregowe tudzież przyjmowania pojedynczych bitów i scalania ich w bajty dokonuje sprzętowo układ [[POKEY]] (quod vide). |
- | * osiem bitów danych | + | |
- | * brak kontroli parzystości | + | |
- | * 1 bit stopu | + | |
- | * 19200 bitów na sekundę | + | |
- | Dane transmitowane są w kolejności od najmłodszego bitu. Szybkość transmisji 19200 bitów na sekundę nie dotyczy magnetofonu kasetowego, gdzie określona jest na 600 bitów na sekundę. | + | ==== Opis przebiegu komunikacji ==== |
+ | Przebieg komunikacji pomiędzy komputerem a urządzeniem jest następujący: | ||
- | Przebieg komunikacji pomiędzy komputerem i urządzeniem jest następujący: | + | 1) komputer ustawia linię COMMAND [[gniazdo SIO|portu SIO]]; |
- | + | ||
- | 1) komputer ustawia linię COMMAND portu SIO; | + | |
2) komputer formuje czterobajtowy blok komendy, tzw. Command Frame. Command Frame składa się kolejno z (bajt 1) dodanych do siebie wartości DDEVIC i DUNIT, odjąć 1; (bajt 2) wartości DCMND; (bajt 3) wartości DAUX1; (bajt 4) wartości DAUX2; | 2) komputer formuje czterobajtowy blok komendy, tzw. Command Frame. Command Frame składa się kolejno z (bajt 1) dodanych do siebie wartości DDEVIC i DUNIT, odjąć 1; (bajt 2) wartości DCMND; (bajt 3) wartości DAUX1; (bajt 4) wartości DAUX2; | ||
- | 3) komenda jest wysyłana do urządzenia razem z dołączoną na końcu sumą kontrolną; czas pomiędzy ustawieniem linii COMMAND a wysłaniem komendy musi być nie mniejszy niż 750 usec i nie większy niż 1600 usec. | + | 3) komenda jest wysyłana do urządzenia razem z dołączoną na końcu [[suma kontrolna SIO|sumą kontrolną]]; czas pomiędzy ustawieniem linii COMMAND a rozpoczęciem wysyłania komendy musi być nie mniejszy niż 750 usec i nie większy niż 1600 usec. |
- | 4) komputer kasuje linię COMMAND portu SIO (nie wcześniej niż po 650 usec i nie później niż 950 usec po wysłaniu komendy) i czeka na odpowiedź; | + | 4) komputer kasuje linię COMMAND portu SIO (nie wcześniej niż po 650 usec i nie później niż 950 usec po wysłaniu ostatniego bitu komendy) i czeka na odpowiedź; |
- | 5) urządzenie przyjmuje komendę; jeśli urządzenie stwierdziło w komendzie błąd sumy kontrolnej, nie reaguje; jeśli komenda jest nierozpoznana, odpowiedzią jest $4E ("N", jak Negative Acknowledge) i na tym transmisja się kończy; jeśli komenda jest urządzeniu znana, odpowiedzią jest $41 ("A", jak Acknowledge). Odpowiedź urządzenia musi nastąpić w czasie od 0 do 16 msec. od skasowania linii COMMAND przez komputer; | + | 5) urządzenie przyjmuje komendę; jeśli urządzenie stwierdziło w komendzie błąd sumy kontrolnej, nie reaguje; jeśli komenda jest nierozpoznana, albo nieprawidłowe są jej parametry (np. nie istnieje sektor o podanym numerze), odpowiedzią jest $4E ("N", jak Negative Acknowledge) i na tym transmisja się kończy; jeśli komenda jest urządzeniu znana a parametry prawidłowe, odpowiedzią jest $41 ("A", jak Acknowledge). Urządzenie musi rozpocząć wysyłanie odpowiedzi w czasie od 0 do 16 msec. od skasowania linii COMMAND przez komputer; |
- | 6) jeśli komenda jest wykonalna i jest to odczyt danych, urządzenie stwierdza, czy dane są dostępne (np. czy istnieje sektor o podanym numerze); jeśli nie, wysyła kod $45 ("E", jak Error) i na tym transmisja się kończy; w przeciwnym wypadku przesyłany jest kod $43 ("C", jak Complete), a następnie blok danych zakończony sumą kontrolną i na tym transmisja się kończy; po przesłaniu potwierdzenia ("C") blok danych po musi nadejść nie wcześniej niż w ciągu 1000 usec. i nie później niż w ciągu 1800 usec.; | + | Dalszy przebieg jest zależny tego, czy dana komenda wymaga przesłania dodatkowego bloku danych do/z urządzenia. Możliwe są 3 sytuacje: brak transmisji danych; odczyt danych z urządzenia; zapis danych do urządzenia. |
- | 7) jeśli to jest zapis danych, komputer przesyła blok danych plus sumę kontrolną do urządzenia. Po jego przyjęciu urządzenie odpowiada kodem $41 ("A") i przystępuje do np. zapisania danych na nośnik. Po zapisie urządzenie informuje komputer kodem "C" lub "E" o znaczeniu jak powyżej, i na tym transmisja się kończy. Przesłanie danych po potwierdzeniu ("A") musi nastąpić nie wcześniej niż w ciągu 1000 usec. i nie później niż w ciągu 1800 usec. Przesłanie potwierdzenia końcowego ("C" lub "E") musi nastąpić w czasie od 850 usec. do 16 msec. po przesłaniu bloku danych. | + | 6a) Jeśli komenda nie wymaga transmisji bloku danych, urządzenie podejmuje próbę wykonania operacji; jeśli się to nie uda, wysyła kod $45 ("E", jak Error); w przeciwnym wypadku przesyłany jest kod $43 ("C", jak Complete); na tym transmisja się kończy. |
- | Ogólnie potwierdzenie końcowe ("C" lub "E") musi nadejść z urządzenia nie wcześniej niż po 250 usec. i nie później niż po 255 sekundach - czyli po 4 minutach i 15 sekundach - od nadesłania potwierdzenia komendy ("A"). | + | 6b) jeśli komenda polega na odczycie bloku danych, urządzenie podejmuje próbę wykonania operacji; jeśli się to nie uda (np. nie można odczytać sektora z powodu uszkodzenia nośnika), wysyła kod $45 ("E", jak Error); w przeciwnym wypadku przesyłany jest kod $43 ("C", jak Complete); następnie w obydwu przypadkach urządzenie natychmiast wysyła blok danych zakończony sumą kontrolną i na tym transmisja się kończy. |
- | Ogólnie schemat wymiany danych przy odczycie jest następujący: | + | 6c) jeśli to jest zapis bloku danych, komputer przesyła blok danych plus sumę kontrolną do urządzenia. Po jego przyjęciu, jeśli blok danych jest poprawny, urządzenie odpowiada kodem $41 ("A") i przystępuje do np. zapisania danych na nośnik. W przeciwnym wypadku, jeśli w nadesłanym bloku danych urządzenie stwierdzi błąd sumy kontrolnej lub inne nieprawidłowości, odpowiada kodem $4E ("N") lub nie odpowiada w ogóle, a blok danych ignoruje (należy tu jednak mieć na względzie, że Atari zasygnalizuje wtedy błąd timeout-u $8A). W następnej fazie urządzenie informuje komputer o wykonaniu kodem "C" lub "E" o znaczeniu jak powyżej, i na tym transmisja się kończy. Przesłanie bloku danych musi rozpocząć się nie wcześniej niż 1000 usec. i nie później niż 1800 usec. po przesłaniu ostatniego bitu potwierdzeniu przyjęcia komendy (pierwszym "A"). Rozpoczęcie przesłania potwierdzenia otrzymania bloku ("A" lub "N") musi nastąpić w czasie od 850 usec. do 16 msec. po przesłaniu ostatniego bitu bloku danych. |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | We wszystkich 3 przypadkach transmisja potwierdzenia końcowego ("C" lub "E") z urządzenia musi rozpocząć się nie wcześniej niż po 250 usec. i nie później niż po 255 sekundach - czyli po 4 minutach i 15 sekundach - od przesłania ostatniego bitu potwierdzenia komendy ("A") (6a, 6b) lub od odebrania ostatniego bitu bloku danych (6c). |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * wykonanie | + | |
- | * komputer <-- potwierdzenie 'C' <-- urządzenie | + | |
- | * komputer <-- blok danych + CRC <-- urządzenie | + | |
- | * koniec. | + | |
- | Natomiast zapis wygląda tak: | + | Konieczność odebrania bloku danych z urządzenia podczas operacji odczytu, nawet po ustaleniu że operacja została wykonana błędnie (kod "E") może tłumaczyć fakt, że po operacji formatowania dysku stacje dysków wysyłają listę błędnych sektorów (rozmiar odbieranego bloku danych ustalany jest w DBYT). |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | ==== Schemat wymiany danych ==== |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * komputer --> blok danych + CRC --> urządzenie | + | |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * wykonanie | + | |
- | * komputer <-- potwierdzenie 'C' <-- urządzenie | + | |
- | * koniec | + | |
W fazie oznaczonej jako ''wykonanie'' urządzenie dokonuje niezbędnych czynności (np. stacja dysków wyszukuje żądany sektor na dyskietce i odczytuje go, albo zapisuje), a komputer czeka. | W fazie oznaczonej jako ''wykonanie'' urządzenie dokonuje niezbędnych czynności (np. stacja dysków wyszukuje żądany sektor na dyskietce i odczytuje go, albo zapisuje), a komputer czeka. | ||
- | Potwierdzenia przesyłane są bez sum kontrolnych (CRC). | + | Potwierdzenia przesyłane są bez sum kontrolnych. |
- | ===Układ Pokey a transmisja szeregowa=== | + | ===== Tylko komenda ===== |
- | Transmisja szeregowa jest wspomagana przez układ [[Pokey]]. Działa on jako UART, przejmując na siebie podział przesłanych przez komputer bajtów na pojedyncze bity i wyemitowanie ich na złącze szeregowe z zaprogramowaną częstotliwością. Szybkość transmisji programowana jest przy użyciu połączonych w parę dzielników 3 i 4 (AUDF3 i AUDF4), do których doprowadza się sygnał o częstotliwości głównego zegara systemu, czyli 1773446,25 Hz w systemie PAL albo 1789772,5 Hz w systemie NTSC. Szybkość tę możemy obliczyć według następującego wzoru: | + | * komputer --> komenda 4 B + suma kontrolna --> urządzenie |
- | + | ||
- | baud = (FI/2)/(R+7) | + | |
- | + | ||
- | gdzie FI to wspomniana wyżej częstotliwość bazowa, a R - wartość wstawiana do rejestru układu [[Pokey]]. | + | |
- | + | ||
- | Normalnie ustawianą przez system operacyjny wartością R jest 40. Teoretycznie ma to odpowiadać szybkości 19200 bitów na sekundę, z podanego wzoru wynika jednak, że w rzeczywistości jest to 18866,45 bps w systemie PAL oraz 19040 bps w systemie NTSC. W praktyce szybkość transmisji nieprzyspieszanej może wahać się w zakresie od 17734,46 bps do 20152,8 bps (19200 bps +/- 5%; odpowiada to wartościom dzielnika Pokeya z zakresu od 43 do 37, w systemie PAL). | + | |
- | + | ||
- | Możliwości układu Pokey nie kończą się jednak na szybkości 20 kbps. Niektóre możliwe do wygenerowania szybkości transmisji przedstawia poniższa tabela: | + | |
- | + | ||
- | <table border=1 cellpadding=5> | + | |
- | <tr><td><b>R</b></td><td><b>bps<br>(PAL / NTSC)</b></td><td><b>Uwagi</b></td></tr> | + | |
- | + | ||
- | <tr><td>0</td><td>126674,7 / 127840,9</td><td>Szybkość trudna do praktycznego użycia ze względu na zakłócenia powodowane przez układ [[ANTIC]] przy generowaniu obrazu.</td></tr> | + | |
- | <tr><td>1</td><td>110840,4 / 111860,8</td><td>j/w. Jest to najbliższy (odchyłka <5%) odpowiednik "standardowej" szybkości 115,2 kbps (6x19200).</td></tr> | + | |
- | <tr><td>2</td><td>98524,8 / 99431,8</td><td>Maksymalna praktycznie użyteczna szybkość transmisji szeregowej ze stacją dysków</td></tr> | + | |
- | <tr><td>3</td><td>88672,3 / 89488,6</td><td> </td></tr> | + | |
- | <tr><td>4</td><td>80611,2 / 81353,3</td><td>Szybkość opcjonalna stacji [[XFD-602]]</td></tr> | + | |
- | <tr><td>5</td><td>73893,6 / 74573,8</td><td>Najbliższy (odchyłka <5%) odpowiednik "standardowej" szybkości 76800 bps (4x19200).</td></tr> | + | |
- | <tr><td>6</td><td>68209,5 / 68837,4</td><td>Szybkość stacji [[LDW Super 2000]], [[Top Drive 1050]], [[TOMS Turbo]], [[TOMS Multi]], [[TOMS 710]], [[TOMS 720]], [[XFD-601]]/602 itd., krótko mówiąc, najpopularniejsze "turbo" do szeregowej stacji dysków</td></tr> | + | |
- | <tr><td>7</td><td>63337,3 / 63920,4</td><td> </td></tr> | + | |
- | <tr><td>8</td><td>59114,9 / 59659</td><td>Najbliższy (odchyłka <5%) odpowiednik "standardowej" szybkości 57600 bps (3x19200). </td></tr> | + | |
- | <tr><td>9</td><td>55420,2 / 55930,4</td><td> </td></tr> | + | |
- | <tr><td>10</td><td>52160,2 / 52640,4</td><td>52 kbps, szybkość stacji [[US Doubler]] i [[Happy Warp]]</td></tr> | + | |
- | <tr><td>11</td><td>49262,4 / 49715,9</td><td> </td></tr> | + | |
- | <tr><td>12</td><td>46669,6 / 47099,3</td><td> </td></tr> | + | |
- | <tr><td>13</td><td>44336,1 / 44744,3</td><td> </td></tr> | + | |
- | <tr><td>14</td><td>42224,9 / 42613,6</td><td> </td></tr> | + | |
- | <tr><td>15</td><td>40305,6 / 40676,6</td><td> </td></tr> | + | |
- | <tr><td>16</td><td>38553,2 / 38908</td><td>Maksymalna szybkość nie modyfikowanych stacji [[XF551|XF-551]] oraz [[CA2001|CA-2001]]. Najbliższy (odchyłka <5%) odpowiednik "standardowej" szybkości 38400 bps (2x19200).</td></tr> | + | |
- | </table> | + | |
- | + | ||
- | Oczywiście wartość dzielnika częstotliwości może mieć i wyższe wartości, do 65535 włącznie (co daje 13,6 bps). | + | |
- | + | ||
- | ===Magnetofon=== | + | |
- | + | ||
- | Dla magnetofonu domyślną wartością rejestru jest 1484, co odpowiada szybkości 594,7 bps. Szybkość tę podczas transmisji komputer dostosowuje w pewnym zakresie do bieżących potrzeb wynikłych np. z nierównomiernego przesuwu taśmy bądź jej rozciągnięcia itd. | + | |
- | + | ||
- | W odróżnieniu od innych urządzeń szeregowych, które używają modulacji częstotliwościowej, dla magnetofonu stosowany jest tryb dwutonowy. | + | |
- | + | ||
- | ==Rozszerzenia SIO== | + | |
- | + | ||
- | ===Systemy turbo do stacji dysków=== | + | |
- | + | ||
- | Standardowa szybkość wymiany danych ze stacją dysków - 19200 bps - szybko okazała się dalece niewystarczająca. Ponieważ, jak napisano powyżej, możliwości układu [[Pokey]] pozwalają uzyskać znacznie więcej, wkrótce powstało kilka, różnych niestety, systemów "turbo". | + | |
- | + | ||
- | ====US Doubler / Happy Warp==== | + | |
- | + | ||
- | Protokół transmisji US Doublera (i zgodnego z nim [[Happy Warp]]) jest identyczny jak w standardzie, z tą różnicą, że układ [[Pokey]] programowany jest do pracy z prędkością 52 kbps. Praca w standardowym 19,2 kbps także jest możliwa. Stacja przełącza się automatycznie pomiędzy tymi dwoma trybami pracy, a do pomiaru żądanej przez komputer prędkości wykorzystuje pojawiający się na złączu szeregowym Atari synchronizujący sygnał zegarowy (CLOCK). | + | |
- | + | ||
- | Stacje z rozsezrzeniem US Doubler implementują dodatkową komendę POLL ('?'). Wysłanie - w standardzie - tej komendy do stacji dysków powoduje, że zwraca ona 1 bajt stanowiący wartość, jaką należy wstawić do licznika układu [[Pokey]] celem uzyskania szybkiej transmisji. W standardowych stacjach US Doubler wartością tą jest $0A, ale stacje innych producentów dzięki temu mechanizmowi mogą implementować wyższe prędkości i wciąż pozostają zgodne z US Doublerem. | + | |
- | + | ||
- | ====Atari XF-551 / CA-2001 ==== | + | |
- | + | ||
- | Stacje [[XF551|Atari XF-551]] oraz [[CA2001|California Access 2001]] mogą pracować z prędkością 38400 bps. Dla zasygnalizowania stacji, że komputer żąda pracy w turbo, przy prędkości 38400 bps używany jest inny protokół transmisji będący - oczywiście - zmodyfikowaną wersją standardowego (patrz wyżej). | + | |
- | + | ||
- | Blok komendy (Command Frame) dla stacji, tak samo jak w standardzie, wysyłany jest z prędkością 19200 bps. Jednakże drugi bajt tego bloku, zawierający wartość bajtu DCMND bloku DCB, jest zwiększony o 128 (ORA #$80). Po wysłaniu komendy komputer, identycznie jak w standardzie, czeka - cały czas mając układ [[Pokey]] zaprogramowany na 19200 bps - na potwierdzenie jej przyjęcia. Negatywna odpowiedź urządzenia na taką komendę oznacza, że nie zna ono tego protokołu transmisji i nie może pracować w turbo zgodnym z [[XF551|XF-551]]. | + | |
- | + | ||
- | Odpowiedź pozytywna ('A') jest sygnałem do przeprogramowania układu [[Pokey]] na większą prędkość. Komputer wstawia do licznika AUDF3/4 wartość $10; analogicznej operacji ze swojej strony dokonuje stacja dysków. Dalsza wymiana danych wywołana przez tę jedną komendę odbywa się w przyspieszonej transmisji. Po wykonaniu komendy następuje powrót do prędkości standardowej. | + | |
- | + | ||
- | Ogólnie schemat wymiany danych przy odczycie jest następujący: | + | |
- | + | ||
- | * prędkość 19200 bps | + | |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | |
* komputer <-- potwierdzenie 'A' <-- urządzenie | * komputer <-- potwierdzenie 'A' <-- urządzenie | ||
- | * przełączenie na 38400 bps | ||
* wykonanie | * wykonanie | ||
* komputer <-- potwierdzenie 'C' <-- urządzenie | * komputer <-- potwierdzenie 'C' <-- urządzenie | ||
- | * komputer <-- blok danych + CRC <-- urządzenie | + | * koniec |
- | * przełączenie na 19200 bps | + | |
- | * koniec. | + | |
- | Natomiast zapis wygląda tak: | + | ===== Odczyt ===== |
- | * prędkość 19200 bps | + | * komputer --> komenda 4 B + suma kontrolna --> urządzenie |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * przełączenie na 38400 bps | + | |
- | * komputer --> blok danych + CRC --> urządzenie | + | |
* komputer <-- potwierdzenie 'A' <-- urządzenie | * komputer <-- potwierdzenie 'A' <-- urządzenie | ||
* wykonanie | * wykonanie | ||
* komputer <-- potwierdzenie 'C' <-- urządzenie | * komputer <-- potwierdzenie 'C' <-- urządzenie | ||
- | * przełączenie na 19200 bps | + | * komputer <-- blok danych + suma kontrolna <-- urządzenie |
* koniec | * koniec | ||
- | Budzącym zakłopotanie niedopatrzeniem jest w tym wszystkim niemożność odpytania stacji na okoliczność wartości, jaką ma mieć licznik [[Pokey]]a w czasie przyspieszonej transmisji. Dodatkowym kłopotem posiadaczy [[CA2001|CA-2001]] jest to, że stację trzeba specjalnie zaprogramować (programem o nazwie [[Synchromesh]] dostarczonym przez producenta na dyskietce), żeby w ogóle działała w turbo. [[XF551|XF-551]] jest tej ostatniej wady na szczęście pozbawiona. | + | ===== Zapis ===== |
- | ====Indus GT / LDW 2000 Super==== | + | * komputer --> komenda 4 B + suma kontrolna --> urządzenie |
- | + | * komputer <-- potwierdzenie 'A' <-- urządzenie | |
- | Protokół przyspieszonej transmisji używany przez stacje [[Indus GT]] oraz [[LDW Super 2000]] jest identyczny z tym opisanym powyżej dla [[XF551|Atari XF-551]] oraz [[CA2001|California Access 2001]]. Jedyną różnicą jest szybkość transmisji: dla LDW wynosi ona 68,2 kbps (wartość licznika [[Pokey]]a - $06). Dla uzyskania tej prędkości konieczne jest uprzednie zaprogramowanie stacji programem [[Synchromesh]] dostarczonym przez producenta na dyskietce. Stacja pozostaje zaprogramowana aż do wyłączenia zasilania. | + | * komputer --> blok danych + suma kontrolna --> urządzenie |
- | + | ||
- | Ogólnie schemat wymiany danych przy odczycie jest następujący: | + | |
- | + | ||
- | * prędkość 19200 bps | + | |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | |
* komputer <-- potwierdzenie 'A' <-- urządzenie | * komputer <-- potwierdzenie 'A' <-- urządzenie | ||
- | * przełączenie na 68,2 kbps | ||
* wykonanie | * wykonanie | ||
* komputer <-- potwierdzenie 'C' <-- urządzenie | * komputer <-- potwierdzenie 'C' <-- urządzenie | ||
- | * komputer <-- blok danych + CRC <-- urządzenie | + | * koniec |
- | * przełączenie na 19200 bps | + | |
- | * koniec. | + | |
- | Natomiast zapis wygląda tak: | + | ===== Zapis i odczyt ===== |
- | * prędkość 19200 bps | + | * komputer --> komenda 4 B + suma kontrolna --> urządzenie |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | |
* komputer <-- potwierdzenie 'A' <-- urządzenie | * komputer <-- potwierdzenie 'A' <-- urządzenie | ||
- | * przełączenie na 68,2 kbps | + | * komputer --> blok danych + suma kontrolna --> urządzenie |
- | * komputer --> blok danych + CRC --> urządzenie | + | |
* komputer <-- potwierdzenie 'A' <-- urządzenie | * komputer <-- potwierdzenie 'A' <-- urządzenie | ||
* wykonanie | * wykonanie | ||
* komputer <-- potwierdzenie 'C' <-- urządzenie | * komputer <-- potwierdzenie 'C' <-- urządzenie | ||
- | * przełączenie na 19200 bps | + | * komputer <-- blok danych + suma kontrolna <-- urządzenie |
* koniec | * koniec | ||
- | ====Top Drive / TOMS Turbo==== | + | ====Magnetofon==== |
- | Stacje z rozszerzeniem [[Top Drive 1050]], [[TOMS Turbo]] oraz [[TOMS Multi]] mogą pracować z prędkością 68,2 kbps. Dla zasygnalizowania stacji, że komputer żąda pracy w turbo, przy prędkości 68,2 kbps używany jest inny protokół transmisji będący zmodyfikowaną wersją standardowego. Protokół ten jest odmienny niż w wypadku stacji [[XF551|XF-551]]. | + | Powyższe schematy dotyczą wszystkich urządzeń SIO za wyjątkiem magnetofonu. Magnetofon nie zawiera w sobie mikroprocesora, jest urządzeniem "nieinteligentnym". Transmisja jest w całości obsługiwana przez komputer, który wysyła (i przyjmuje) bloki danych, tzw. rekordy, zawierające każdy po 128 bajtów danych, bajt sumy kontrolnej oraz bajt rodzaju rekordu i dwa dodatkowe bajty służące do pomiaru równomierności przesuwu taśmy - łącznie 132 bajty. |
- | Blok komendy (Command Frame) dla stacji, tak samo jak w standardzie, wysyłany jest z prędkością 19200 bps. Czwarty bajt tego bloku, niosący wartość bajtu DAUX2 bloku DCB, jest zwiększony o 128 (ORA #$80). Po wysłaniu komendy komputer - '''nie czekając na odpowiedź''' - przeprogramowuje układ [[Pokey]] na 68,2 kbps (wartość licznika - $06) założywszy w ciemno, że stacja ze swej strony również przełącza się na szybką transmisję. Odbiór ewentualnej negatywnej odpowiedzi oczywiście nie jest w takim układzie możliwy. | + | ==Rozszerzenia SIO== |
- | Dalsza wymiana danych wywołana przez tę jedną komendę odbywa się w przyspieszonej transmisji. Po wykonaniu komendy następuje powrót do prędkości standardowej. | + | ===Systemy turbo do stacji dysków=== |
- | Ogólnie schemat wymiany danych przy odczycie jest następujący: | + | Standardowa szybkość wymiany danych ze stacją dysków - 19200 bps - szybko okazała się dalece niewystarczająca. Ponieważ, jak napisano powyżej, możliwości układu [[POKEY]] pozwalają uzyskać znacznie więcej, wkrótce powstało kilka, różnych niestety, [[Systemy Turbo|systemów "turbo"]]. |
- | + | ||
- | * prędkość 19200 bps | + | |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | |
- | * przełączenie na 68,2 kbps | + | |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * wykonanie | + | |
- | * komputer <-- potwierdzenie 'C' <-- urządzenie | + | |
- | * komputer <-- blok danych + CRC <-- urządzenie | + | |
- | * przełączenie na 19200 bps | + | |
- | * koniec. | + | |
- | + | ||
- | Natomiast zapis wygląda tak: | + | |
- | + | ||
- | * prędkość 19200 bps | + | |
- | * komputer --> komenda 4 B + CRC --> urządzenie | + | |
- | * przełączenie na 68,2 kbps | + | |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * komputer --> blok danych + CRC --> urządzenie | + | |
- | * komputer <-- potwierdzenie 'A' <-- urządzenie | + | |
- | * wykonanie | + | |
- | * komputer <-- potwierdzenie 'C' <-- urządzenie | + | |
- | * przełączenie na 19200 bps | + | |
- | * koniec | + | |
- | + | ||
- | Jest to zdecydowanie najpodlejsze turbo z omawianej tu czwórki; Top Drive nie dość, że ma wszystkie wady protokołu [[XF551|XF-551]], to jeszcze dorzuca do nich jedną własną (którą jest wspomniana wyżej niemożność odrzucenia przez stację w cywilizowany sposób żądanego przez komputer trybu pracy), nie mając przy tym żadnych równoważących to zalet (jeden bajt więcej przesłany w szybkiej transmisji zwiększa prędkość wymiany danych o niecałe 8 promili). | + | |
===Rozszerzone adresowanie sektorów (KMK/JŻ IDE)=== | ===Rozszerzone adresowanie sektorów (KMK/JŻ IDE)=== | ||
Linia 437: | Linia 308: | ||
===Rozszerzone adresowanie pamięci (65C816)=== | ===Rozszerzone adresowanie pamięci (65C816)=== | ||
- | [[DracOS]] (odmiana [[XL OS]] przygotowana dla procesora [[65C816]]) zawiera rozszerzenie SIO pozwalające na transfery danych bezpośrednio do i z dodatkowej pamięci adresowalnej liniowo (tj. znajdującej się pod adresami wyższymi niż $FFFF). | + | [[DracOS]] (odmiana [[XL OS]] przygotowana dla procesora [[65C816]]) zawiera rozszerzenie SIO pozwalające na transfery danych bezpośrednio do i z dodatkowej pamięci adresowalnej liniowo (tj. znajdującej się pod adresami wyższymi niż $FFFF) oraz 32-bitowe adresowanie sektorów. |
- | + | ||
- | ====Blok DCB==== | + | |
- | + | ||
- | Block DCB w tej wersji systemu jest rozszerzony do 16 bajtów i wygląda następująco: | + | |
- | + | ||
- | <table border=1 cellpadding=5> | + | |
- | <tr><td>Adres</td><td>Etykieta</td><td>Wielkość</td><td>Znaczenie</td></tr> | + | |
- | + | ||
- | <tr><td>$0300</td><td>DDEVIC</td><td>Bajt</td><td>Identyfikator urządzenia (zob. niżej).</td></tr> | + | |
- | + | ||
- | <tr><td>$0301</td><td>DUNIT</td><td>Bajt</td><td>Numer urządzenia; w przypadku stacji dysków numer napędu.</td></tr> | + | |
- | + | ||
- | <tr><td>$0302</td><td>DCMND</td><td>Bajt</td><td>Komenda dla urządzenia.</td></tr> | + | |
- | + | ||
- | <tr><td>$0303</td><td>DSTATS</td><td>Bajt</td><td>Przed wywołaniem SIO należy ustawić tu rodzaj operacji ($40 odczyt, $80 zapis). Po powrocie z systemu znajduje się tu status operacji ([[kody błędów|kod błędu]]).</td></tr> | + | |
- | + | ||
- | <tr><td>$0304</td><td>DBUFA</td><td>Dwa bajty</td><td>Adres bufora.</td></tr> | + | |
- | + | ||
- | <tr><td>$0306</td><td>DTIMLO</td><td>Bajt</td><td>Czas oczekiwania - w sekundach - na pozytywną odpowiedź urządzenia.</td></tr> | + | |
- | + | ||
- | <tr><td>$0307</td><td>DUNUSE</td><td>Bajt</td><td>Bajt nieużywany, zarezerwowany do przyszłych zastosowań.</td></tr> | + | |
- | + | ||
- | <tr><td>$0308</td><td>DBYT</td><td>Dwa bajty</td><td>Wielkość bufora; musi być zgodna z wielkością transmitowanego bloku danych.</td></tr> | + | |
- | + | ||
- | <tr><td>$030A</td><td>DAUX1</td><td>Bajt</td><td>Pierwszy bajt pomocniczy. W operacjach dyskowych młodszy bajt numeru sektora.</td></tr> | + | |
- | + | ||
- | <tr><td>$030B</td><td>DAUX2</td><td>Bajt</td><td>Drugi bajt pomocniczy. W operacjach dyskowych starszy bajt numeru sektora.</td></tr> | + | |
- | + | ||
- | <tr><td>$030C</td><td>DAUX3</td><td>Bajt</td><td>Trzeci bajt pomocniczy. Młodszy bajt starszego słowa 32-bitowego numeru sektora.</td></tr> | + | |
- | + | ||
- | <tr><td>$030D</td><td>DAUX4</td><td>Bajt</td><td>Czwarty bajt pomocniczy. Starszy bajt starszego słowa 32-bitowego numeru sektora.</td></tr> | + | |
- | + | ||
- | <tr><td>$030E</td><td>DBFX1</td><td>Bajt</td><td>Najstarszy bajt adresu bufora.</td></tr> | + | |
- | + | ||
- | <tr><td>$030F</td><td>DBFX2</td><td>Bajt</td><td>Bajt zarezerwowany.</td></tr> | + | |
- | + | ||
- | </table> | + | |
- | + | ||
- | ====Sposób użycia==== | + | |
- | + | ||
- | Dla utrzymania zgodności z dotychczasowym oprogramowaniem, a już zwłaszcza z dotychczasowymi sterownikami urządzeń podłączanych do szyny równoległej, wpisanie pod $000304/5/E 24-bitowego adresu nie da pożądanego wyniku; jeśliby bowiem urządzenie brało pod uwagę tylko 16 najmłodszych bitów adresu ignorując najstarszy bajt wpisany pod $00030E, wtedy - przy odczycie - dane zostałyby umieszczone nie tam, gdzie trzeba. Musi więc istnieć mechanizm, który zapobiega tego typu nieporozumieniom. | + | |
- | + | ||
- | W tym celu SIO definiuje trzy nowe urządzenia wirtualne, o kodach jak następuje: | + | |
- | + | ||
- | * $B1 (= $31 + $80) - stacja dysków | + | |
- | * $C0 (= $40 + $80) - drukarka | + | |
- | * $D0 (= $50 + $80) - RS-232C | + | |
- | + | ||
- | Wywołanie urządzenia z takim kodem w DDEVIC powiadamia sterownik SIO, że adres bufora w DCB jest 24-bitowy i że najstarszy bajt adresu jest pod $00030E (w przeciwnym wypadku SIO zakłada, że najstarszy bajt adresu to 0); oraz że numer sektora jest 32-bitowy i jest umieszczony w DAUX1-DAUX4 ('''UWAGA: w przypadku szeregowych stacji dysków, [[SIO2IDE]], [[SIO2PC]] itp. dwa najstarsze bajty tego numeru są ignorowane''', ale powinny być wyzerowane dla kompatybilności). Poza tym działanie urządzeń wirtualnych jest identyczne, jak tradycyjnych (odpowiednio $31, $40 i $50), a kod urządzenia jest przed wysłaniem na port szeregowy przekładany na kod rzeczywisty. | + | |
- | Przyjmując komendę do wykonania SIO w żaden sposób nie sprawdza, czy dodatkowa pamięć w ogóle istnieje - zakłada się, że program sam stwierdzi jej istnienie (choćby za pomocą funkcji alokacji pamięci) przed próbą odczytu do niej danych. | + | ==Zobacz też== |
+ | * [http://www.atariarchives.org/dere/ De Re Atari] | ||
+ | * [[Obsługa protokołu SIO przez urządzenie peryferyjne]] | ||
==Bibliografia== | ==Bibliografia== | ||
- | * ''Atari Home Computer System: Serial Input Output Interface, User's Handbook'' | + | * ''[http://ftp.pigwa.net/stuff/collections/nir_dary_cds/Tech%2520Info/SIOSPECS.PDF Atari Home Computer System: Serial Input Output Interface, User's Handbook]'' |
+ | * Harry B. Stewart, ''[http://www.atarimuseum.com/ahs_archives/archives/pdf/computers/8bits/1200XL/sweet-16_OS.pdf Z800/Sweet 16 Operating System, External Reference Specification]'' | ||
- | [[Kategoria:Atari 8-bit]] | + | [[Kategoria:Menu Główne]] |
+ | [[Kategoria:Programowanie Atari 8-bit]] |
Aktualna wersja
Serial Input/Output. W założeniach jest to rezydujący w ROM-ie podsystem niskopoziomowych procedur blokowego dostępu do urządzeń szeregowych, to jest przede wszystkim stacji dysków, drukarek, modemów i magnetofonu. Wszystkie te urządzenia podłącza się w Atari do gniazda SIO.
W serii XL do podsystemu SIO dodano także niskopoziomową (blokową) obsługę urządzeń podłączanych do szyny równoległej (PBI), czyli tak zwanych nowych urządzeń.
Spis treści |
Sposób użycia
Żądaną operację definiuje się ustawiwszy przedtem odpowiednie zmienne w bloku DCB (Device Control Block, $0300), a następnie wywołuje skokiem JSR pod JSIOINT $E459, co jest punktem wejściowym interfejsu szeregowo-równoległego. Przy powrocie rejestr Y zawiera wartość 1 w przypadku powodzenia, bądź ujemny kod błędu.
Struktura DCB
Adres | Etykieta | Wielkość | Znaczenie |
$0300 | DDEVIC | Bajt | Identyfikator urządzenia (zob. niżej). |
$0301 | DUNIT | Bajt | Numer urządzenia; w przypadku stacji dysków numer napędu. |
$0302 | DCMND | Bajt | Komenda dla urządzenia. |
$0303 | DSTATS | Bajt | Przed wywołaniem SIO należy ustawić tu rodzaj operacji ($40 odczyt, $80 zapis, $C0 zapis i odczyt, $00 brak transferu danych). Po powrocie z systemu znajduje się tu status operacji (kod błędu). |
$0304 | DBUFA | Dwa bajty | Adres bufora. Przy operacji zapisu i odczytu jednocześnie (DSTATS = $C0) bufor na odczytywane dane znajduje się w tym samym miejscu, co bufor danch przeznaczonych do zapisu. |
$0306 | DTIMLO | Bajt |
Czas oczekiwania na pozytywną odpowiedź urządzenia, tzw. timeout. Oblicza się to jak następuje: wartość DTIMLO mnożona jest przez 64, w wyniku czego otrzymujemy liczbę "ramek" VBL do odczekania. Zwiększenie DTIMLO o jeden powoduje wydłużenie czasu oczekiwania o 1,28 sek. w systemie PAL i o 1,067 sek. w systemie NTSC. Wartość "0" oznacza 256 jednostek. Typowo ustawia się tu wartość z zakresu od $06 do $08 (zależnie od kaprysu programisty) dla wszystkich operacji oprócz formatowania. Właściwą wartość timeout dla formatowania urządzenie przesyła w bloku statusu, w odpowiedzi na komendę READ STATUS ("S", zob. niżej). |
$0307 | DUNUSE | Bajt | Bajt nieużywany, zarezerwowany do przyszłych zastosowań. |
$0308 | DBYT | Dwa bajty | Wielkość bufora; musi być zgodna z wielkością transmitowanego bloku danych. Zero oznacza 64 kilobajty. |
$030A | DAUX1 | Bajt | Pierwszy bajt pomocniczy. W operacjach dyskowych młodszy bajt numeru sektora. |
$030B | DAUX2 | Bajt | Drugi bajt pomocniczy. W operacjach dyskowych starszy bajt numeru sektora. |
Wykaz urządzeń
Komenda wysyłana do urządzenia formowana jest w strukturze CFB (Command Frame Buffer, $023A) składającej się z:
- CDEVIC
- CCMND
- CAUX1
- CAUX2
a uzupełnianej na podstawie DCB.
Istnieje pięć urządzeń zdefiniowanych przez Atari. Właściwy identyfikator urządzenia (CDEVIC) zestawiany jest przez system z kodu urządzenia (DDEVIC) i jego numeru indywidualnego (DUNIT). Wartości te są dodawane, po czym jeszcze odejmuje się 1. Dlatego stację dysków nr 1 można wywołać też jako DDEVIC=$32 i DUNIT=0, liczy się wynik wspomnianego dodawania (CDEVIC). UWAGA: jest to tzw. "nieudokumentowana" cecha procedur szeregowych OS-u, inne urządzenia (jak np. nowe urządzenia) mogą tego nie robić.
DDEVIC | CDEVIC | Opis |
$31 | $31-$3F | dyskowa pamięć masowa (stacja dysków, twardy dysk) |
$40 | $40-$43 | drukarka |
$4F | $4F | bus master (moduł 1090) |
$50 | $50-$53 | port szeregowy RS-232C |
$60 | $60 | magnetofon kasetowy |
Przypisanie identyfikatorów do poszczególnych urządzeń jest niezbyt konsekwentne, np. CDEVIC=$31 to stacja dysków numer 1, ale CDEVIC=$41 to drukarka numer 2.
Urządzeniem, które na podanej powyżej liście jest wyjątkowe, jest magnetofon kasetowy. Jest to jedyne "nieinteligentne" urządzenie peryferyjne, to jest nie zawierające własnego procesora. Wszystkie zadania związane z wysyłaniem danych na magnetofon i odbiorem z niego wykonuje system operacyjny komputera. W odróżnieniu od innych urządzeń, magnetofon okupuje tylko identyfikator $60, a wartość DUNIT jest ignorowana - w związku z tym kody urządzeń od $61 do $6F są (na razie) wolne.
Wartości CDEVIC powyżej $7F są zarezerwowane dla pewnych rozszerzeń protokołu SIO, patrz niżej.
Ponieważ identyfikator jest częścią wysyłanej do urządzenia komendy, więc budując własne urządzenie można posłużyć się identyfikatorem spoza powyżej wyszczególnionych:
DDEVIC | CDEVIC | Opis |
$20 | $20 | IDE Plus, SIDE |
$45 | $45 | Smart Device ( APE Time i URL Submit) |
$5A | $5A | ATR 8000 |
$61 | $61 | AtariSIO, DOS2DOS |
$70 | $70 | Atari ASPI (zob. ASPI) |
$71-$74 | $71-$74 | SDrive |
$71 | $70 | SIO2USB [1] |
$73 | $72-$75 | Sio2SD |
Wykazy komend
Blok statusu
Blok statusu przysyłany na komendę żądania statusu ($53) ma strukturę w dużym stopniu zależną od urządzenia. Są to dwa lub cztery bajty, a ich znaczenie dla poszczególnych urządzeń jest opisane poniżej. W pierwszym bajcie statusu obowiązuje jednolity dla wszystkich urządzeń podział na dwie grupy bitów:
- bity 0-2 sygnalizują status komunikacji pomiędzy komputerem a urządzeniem
- bity 3-7 sygnalizują status wewnętrzny urządzenia
Stacja dysków
Bajt | Znaczenie |
0 |
W przypadku interfejsu KMK/JŻ IDE znaczenie mają tylko bity 3 i 5, reszta jest zawsze wyzerowana. |
1 | Kopia rejestru statusu kontrolera WD 1772 (lub kompatybilnego), wszystkie bity są poddane inwersji.
Interfejs IDE KMK/JŻ zwraca zamiast tego zawartość rejestru ERROR kontrolera IDE:
Podobnie jak powyżej wszystkie bity są poddane inwersji (EOR #$FF). |
2 | Maksymalny czas oczekiwania na wykonanie komendy (timeout) przewidziany dla operacji dyskowej. Najdłużej trwa formatowanie, zalecaną wartością jest 240. |
3 | Nie używany. |
Drukarka
Bajt | Znaczenie |
0 |
|
1 | DAUX2 przesłanej ostatnio komendy |
2 | Maksymalny czas oczekiwania na wykonanie komendy (timeout) przewidziany dla tej drukarki |
3 | Nie używany. |
RS-232 (Atari 850)
Blok statusu portu RS-232 ma dwa bajty (w pozostałych urządzeniach - cztery).
Bajt | Znaczenie |
0 |
|
1 |
|
Magnetofon kasetowy
Przyjmuje się, że magnetofon, jako urządzenie "nieinteligentne", jest zawsze podłączony i gotowy do pracy, a więc nie zachodzi potrzeba sprawdzania jego statusu. W związku z tym funkcja READ STATUS ($53) nie jest dla magnetofonu zaimplementowana.
Blok PERCOM
Blok PERCOM jest to 12 bajtów informacji o konfiguracji stacji dysków. Odczyt przeprowadza się komendą $4E ("N"), a zapis - komendą $4F ("O").
Bajt | Opis |
0 | Liczba ścieżek na dyskietce; w praktyce dla stacji dysków spotyka się wartości najczęściej 40 lub 80, rzadziej 35 lub 77. Partycje twardego dysku zwracają 1. |
1 | Szybkość przesuwu głowicy ze ścieżki na ścieżkę:
W praktyce stacje przeważnie ignorują przesłaną wartość. W przypadku twardego dysku jest ona bez znaczenia (kontroler KMK/JŻ zwraca w tym bajcie numer wersji wewnętrznego oprogramowania) |
2 | STARSZY bajt liczby sektorów na ścieżce. |
3 | MŁODSZY bajt liczby sektorów na ścieżce. |
4 | Liczba aktywnych stron dyskietki zmniejszona o 1 albo najstarszy bajt liczby sektorów partycji twardego dysku (patrz niżej). |
5 |
Pozostałe bity są zarezerwowane i powinny być wyzerowane. |
6 | STARSZY bajt wielkości sektora (w bajtach) |
7 | MŁODSZY bajt wielkości sektora (w bajtach) |
8 | Niewykorzystany, zapisuje się - i przeważnie odczytuje - jako $FF. W oryginalnych stacjach PERCOM bajt ten sygnalizował stan niektórych funkcji kontrolera stacji i służył do ich wybierania:
W praktyce większość stacji nie ustawia tych bitów zgodnie z powyższym opisem. |
9 | Niewykorzystane, na ogół 0. |
10 | Niewykorzystane, na ogół 0. |
11 | Niewykorzystane, na ogół 0. |
Protokół transmisji
Połączenia równoległe
Protokół transmisji urządzeń podłączanych do szyny równoległej jest zależny od programu obsługi urządzenia zawartego w jego pamięci ROM. System operacyjny tego nie definiuje.
Połączenia szeregowe
Podziału poszczególnych bajtów na bity i wyemitowania ich na złącze szeregowe tudzież przyjmowania pojedynczych bitów i scalania ich w bajty dokonuje sprzętowo układ POKEY (quod vide).
Opis przebiegu komunikacji
Przebieg komunikacji pomiędzy komputerem a urządzeniem jest następujący:
1) komputer ustawia linię COMMAND portu SIO;
2) komputer formuje czterobajtowy blok komendy, tzw. Command Frame. Command Frame składa się kolejno z (bajt 1) dodanych do siebie wartości DDEVIC i DUNIT, odjąć 1; (bajt 2) wartości DCMND; (bajt 3) wartości DAUX1; (bajt 4) wartości DAUX2;
3) komenda jest wysyłana do urządzenia razem z dołączoną na końcu sumą kontrolną; czas pomiędzy ustawieniem linii COMMAND a rozpoczęciem wysyłania komendy musi być nie mniejszy niż 750 usec i nie większy niż 1600 usec.
4) komputer kasuje linię COMMAND portu SIO (nie wcześniej niż po 650 usec i nie później niż 950 usec po wysłaniu ostatniego bitu komendy) i czeka na odpowiedź;
5) urządzenie przyjmuje komendę; jeśli urządzenie stwierdziło w komendzie błąd sumy kontrolnej, nie reaguje; jeśli komenda jest nierozpoznana, albo nieprawidłowe są jej parametry (np. nie istnieje sektor o podanym numerze), odpowiedzią jest $4E ("N", jak Negative Acknowledge) i na tym transmisja się kończy; jeśli komenda jest urządzeniu znana a parametry prawidłowe, odpowiedzią jest $41 ("A", jak Acknowledge). Urządzenie musi rozpocząć wysyłanie odpowiedzi w czasie od 0 do 16 msec. od skasowania linii COMMAND przez komputer;
Dalszy przebieg jest zależny tego, czy dana komenda wymaga przesłania dodatkowego bloku danych do/z urządzenia. Możliwe są 3 sytuacje: brak transmisji danych; odczyt danych z urządzenia; zapis danych do urządzenia.
6a) Jeśli komenda nie wymaga transmisji bloku danych, urządzenie podejmuje próbę wykonania operacji; jeśli się to nie uda, wysyła kod $45 ("E", jak Error); w przeciwnym wypadku przesyłany jest kod $43 ("C", jak Complete); na tym transmisja się kończy.
6b) jeśli komenda polega na odczycie bloku danych, urządzenie podejmuje próbę wykonania operacji; jeśli się to nie uda (np. nie można odczytać sektora z powodu uszkodzenia nośnika), wysyła kod $45 ("E", jak Error); w przeciwnym wypadku przesyłany jest kod $43 ("C", jak Complete); następnie w obydwu przypadkach urządzenie natychmiast wysyła blok danych zakończony sumą kontrolną i na tym transmisja się kończy.
6c) jeśli to jest zapis bloku danych, komputer przesyła blok danych plus sumę kontrolną do urządzenia. Po jego przyjęciu, jeśli blok danych jest poprawny, urządzenie odpowiada kodem $41 ("A") i przystępuje do np. zapisania danych na nośnik. W przeciwnym wypadku, jeśli w nadesłanym bloku danych urządzenie stwierdzi błąd sumy kontrolnej lub inne nieprawidłowości, odpowiada kodem $4E ("N") lub nie odpowiada w ogóle, a blok danych ignoruje (należy tu jednak mieć na względzie, że Atari zasygnalizuje wtedy błąd timeout-u $8A). W następnej fazie urządzenie informuje komputer o wykonaniu kodem "C" lub "E" o znaczeniu jak powyżej, i na tym transmisja się kończy. Przesłanie bloku danych musi rozpocząć się nie wcześniej niż 1000 usec. i nie później niż 1800 usec. po przesłaniu ostatniego bitu potwierdzeniu przyjęcia komendy (pierwszym "A"). Rozpoczęcie przesłania potwierdzenia otrzymania bloku ("A" lub "N") musi nastąpić w czasie od 850 usec. do 16 msec. po przesłaniu ostatniego bitu bloku danych.
We wszystkich 3 przypadkach transmisja potwierdzenia końcowego ("C" lub "E") z urządzenia musi rozpocząć się nie wcześniej niż po 250 usec. i nie później niż po 255 sekundach - czyli po 4 minutach i 15 sekundach - od przesłania ostatniego bitu potwierdzenia komendy ("A") (6a, 6b) lub od odebrania ostatniego bitu bloku danych (6c).
Konieczność odebrania bloku danych z urządzenia podczas operacji odczytu, nawet po ustaleniu że operacja została wykonana błędnie (kod "E") może tłumaczyć fakt, że po operacji formatowania dysku stacje dysków wysyłają listę błędnych sektorów (rozmiar odbieranego bloku danych ustalany jest w DBYT).
Schemat wymiany danych
W fazie oznaczonej jako wykonanie urządzenie dokonuje niezbędnych czynności (np. stacja dysków wyszukuje żądany sektor na dyskietce i odczytuje go, albo zapisuje), a komputer czeka.
Potwierdzenia przesyłane są bez sum kontrolnych.
Tylko komenda
- komputer --> komenda 4 B + suma kontrolna --> urządzenie
- komputer <-- potwierdzenie 'A' <-- urządzenie
- wykonanie
- komputer <-- potwierdzenie 'C' <-- urządzenie
- koniec
Odczyt
- komputer --> komenda 4 B + suma kontrolna --> urządzenie
- komputer <-- potwierdzenie 'A' <-- urządzenie
- wykonanie
- komputer <-- potwierdzenie 'C' <-- urządzenie
- komputer <-- blok danych + suma kontrolna <-- urządzenie
- koniec
Zapis
- komputer --> komenda 4 B + suma kontrolna --> urządzenie
- komputer <-- potwierdzenie 'A' <-- urządzenie
- komputer --> blok danych + suma kontrolna --> urządzenie
- komputer <-- potwierdzenie 'A' <-- urządzenie
- wykonanie
- komputer <-- potwierdzenie 'C' <-- urządzenie
- koniec
Zapis i odczyt
- komputer --> komenda 4 B + suma kontrolna --> urządzenie
- komputer <-- potwierdzenie 'A' <-- urządzenie
- komputer --> blok danych + suma kontrolna --> urządzenie
- komputer <-- potwierdzenie 'A' <-- urządzenie
- wykonanie
- komputer <-- potwierdzenie 'C' <-- urządzenie
- komputer <-- blok danych + suma kontrolna <-- urządzenie
- koniec
Magnetofon
Powyższe schematy dotyczą wszystkich urządzeń SIO za wyjątkiem magnetofonu. Magnetofon nie zawiera w sobie mikroprocesora, jest urządzeniem "nieinteligentnym". Transmisja jest w całości obsługiwana przez komputer, który wysyła (i przyjmuje) bloki danych, tzw. rekordy, zawierające każdy po 128 bajtów danych, bajt sumy kontrolnej oraz bajt rodzaju rekordu i dwa dodatkowe bajty służące do pomiaru równomierności przesuwu taśmy - łącznie 132 bajty.
Rozszerzenia SIO
Systemy turbo do stacji dysków
Standardowa szybkość wymiany danych ze stacją dysków - 19200 bps - szybko okazała się dalece niewystarczająca. Ponieważ, jak napisano powyżej, możliwości układu POKEY pozwalają uzyskać znacznie więcej, wkrótce powstało kilka, różnych niestety, systemów "turbo".
Rozszerzone adresowanie sektorów (KMK/JŻ IDE)
Kontroler KMK/JŻ IDE wykorzystuje bajt DUNUSE ($0307) bloku DCB jako najstarszy bajt numeru sektora. Pozwala to na zaadresowanie do 16777215 sektorów na jednej partycji.
Rozszerzone adresowanie pamięci (65C816)
DracOS (odmiana XL OS przygotowana dla procesora 65C816) zawiera rozszerzenie SIO pozwalające na transfery danych bezpośrednio do i z dodatkowej pamięci adresowalnej liniowo (tj. znajdującej się pod adresami wyższymi niż $FFFF) oraz 32-bitowe adresowanie sektorów.