SIO

From Atariki

Revision as of 01:56, 10 gru 2004; view current revision
←Older revision | Newer revision→
Jump to: navigation, search

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.

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 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 kod błędu.

Struktura DCB

AdresEtykietaWielkośćZnaczenie
$0300DDEVICBajtIdentyfikator urządzenia. W przypadku stacji dysków trzeba podać identyfikator zwiększony o 1!
$0301DUNITBajtNumer urządzenia; w przypadku stacji dysków numer napędu.
$0302DCMNDBajtKomenda dla urządzenia.
$0303DSTATSBajtPrzed wywołaniem SIO należy ustawić tu rodzaj operacji ($40 odczyt, $80 zapis). Po powrocie z systemu znajduje się tu status operacji (kod błędu).
$0304DBUFADwa bajtyAdres bufora.
$0306DTIMLOBajtCzas oczekiwania - w sekundach - na pozytywną odpowiedź urządzenia.
$0307DUNUSEBajtBajt nieużywany, zarezerwowany do przyszłych zastosowań.
$0308DBYTDwa bajtyWielkość bufora; musi być zgodna z wielkością transmitowanego bloku danych.
$030ADAUX1BajtPierwszy bajt pomocniczy. W operacjach dyskowych młodszy bajt numeru sektora.
$030BDAUX2BajtDrugi bajt pomocniczy. W operacjach dyskowych starszy bajt numeru sektora.

Wykaz urządzeń

Interfejs SIO znajdujący się w ROM-ie rozpoznaje cztery predefiniowane urządzenia:

  • $30: dyskową pamięć masową (stację dysków, twardy dysk)
  • $40: drukarkę
  • $50: port szeregowy RS-232-C
  • $60: magnetofon kasetowy

przy czym identyfikator urządzenia to górne 4 bity podanego kodu, dolne natomiast 4 bity stanowi indywidualny numer urządzenia (np. $31 - stacja dysków nr 1, $32 - stacja dysków nr 2 itd.). W DCB wartości te podajemy oddzielnie.

Wykaz typowych komend

KodNazwaUrządzenieR/WIlość danychOpis
$21 (!)FORMAT DISK$31 (stacja dysków)R128 bajtówFormatuje dyskietkę w wybranej uprzednio (komendami PERCOM) gęstości, lub w 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...
Kontroler KMK/JŻ IDE nie rozpoznaje tej komendy dla bezpieczeństwa danych na dysku (do partycjonowania i "formatowania" dysku służy oddzielny program).
$22 (")FORMAT MEDIUM$31 (stacja dysków)R128 bajtówAnalogicznie do FORMAT DISK, z tym że formatowanie zawsze przeprowadzane jest w 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).
$3F (?)POLL$31 (stacja dysków)R1 bajt 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.
$4E (N)READ PERCOM$31 (stacja dysków)R12 bajtówOdczytuje 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.
$4F (O)WRITE PERCOM$31 (stacja dysków)W12 bajtówZapisuje 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).
$50 (P)PUT SECTORWszystkie za wyjątkiem drukarkiWZależna od urządzenia i trybu pracy.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.
$52 (R)READ SECTORWszystkie oprócz drukarkiRZależna od urządzenia i trybu pracy.Odczytuje z urządzenia blok danych o wielkości DBYT bajtów i zapisuje go w pamięci pod adresem wskazanym przez DBUFA.
$53 (S)READ STATUSWszystkie oprócz magnetofonuR4 bajtyOdczytuje 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.
$57 (W)WRITE SECTORWszystkieWZależna od urządzenia i trybu pracy.To samo, co PUT SECTOR ($52). W przypadku stacji dysków zapis przeprowadzany jest z weryfikacją.
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

Wykaz komend nietypowych

</td> </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

KodNazwaUrządzenieR/WIlość danychOpis
$40 (@)QUERY BUS$4FR/W4 bajty

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 1090). Ale nic nie stoi na przeszkodzie ku wykorzystaniu również przez urządzenia szeregowe.

Na początku komenda przesyłana jest z DAUX1 = 0 i DAUX2 = 0. W odpowiedzi urządzenie ma przysłać 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, DAUX1 i DAUX2 są ustawiane na $4E ("N", jak Negative Acknowledge) i po wysłaniu tej samej komendy ponownie - procedura zaczyna się od początku; i tak dalej w pętli aż do wystąpienia błędu transmisji. 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.

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.

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.

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 zamiast DOS-u.

Ż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 konkretnie wskazanego. 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).

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).

$26 (&)SEND HANDLERUrządzenie o kodzie zwróconym przez komendę QUERY BUS ($40)R128 bajtów

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.

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, jak że formatu danych nie zdołałem jeszcze do końca 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 kodem błędu BOOT ERROR.

Ustawienia zmiennych DCB dla komendy SEND HANDLER wyglądają następująco:

  • DDEVIC - kod urządzenia przesłany przez urządzenie $4F na komendę QUERY BUS.
  • DUNIT - zawsze $01
  • DCMND - $26 - SEND HANDLER
  • DSTATS - $40 - odczyt
  • DTIMLO - 30 sekund
  • DBYT - 128 bajtów
  • DAUX1 - numer kolejny rekordu danych
  • DAUX2 - zawsze 0
$51 (Q)READ SPIN
$55 (U)MOTOR ON
$56 (V)VERIFY SECTOR $31 (stacja dysków)R (?)?

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.

BajtZnaczenie
0
  • bit 0 = 1 - wydana ostatnio komenda nie została rozpoznana
  • bit 1 = 1 - przesłany ostatnio blok danych był błędny
  • bit 7 = 1 - drukarka jest programowalna (w drukarkach Atari ten bit jest skasowany)
Pozostałe bity są zarezerwowane.
1DAUX2 przesłanej ostatnio komendy
2Maksymalny czas oczekiwania na wykonanie komendy (timeout) przewidziany dla tej drukarki
3Nie używany.

Stacja dysków

BajtZnaczenie
0
  • 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 - praca w gęstości MFM (FM w przeciwnym wypadku)
  • bit 6 = 0 - zarezerwowany
  • bit 7 = 1 - praca w średniej gęstości
1Bajt statusu kontrolera WD 1772, wszystkie bity są poddane inwersji.
2Maksymalny czas oczekiwania na wykonanie komendy (timeout) przewidziany dla operacji dyskowej. Najdłużej trwa formatowanie, zalecaną wartością jest 240.
3Nie używany.

Blok PERCOM

Tak zwany blok PERCOM to 12 bajtów informacji o konfiguracji stacji dysków. Odczyt przeprowadza się komendą $4E ("N"), a zapis - komendą $4F ("O").

BajtOpis
0Liczba ś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.
1Szybkość przesuwu głowicy ze ścieżki na ścieżkę:
  • 0 - 30 ms
  • 1 - 20 ms
  • 2 - 12 ms
  • 3 - 6 ms

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)

2STARSZY bajt liczby ścieżek na dyskietce.
3MŁODSZY bajt liczby ścieżek na dyskietce.
4Liczba aktywnych stron dyskietki zmniejszona o 1. W przypadku partycji twardego dysku jest to najstarszy bajt liczby sektorów partycji.
5

Gęstość zapisu:

BitOpis
0zarezerwowany
1zarezerwowany
2Jeśli 1, gęstość MFM, FM w przeciwnym wypadku
3Jeśli 1, partycja twardego dysku IDE
6STARSZY bajt wielkości sektora (w bajtach)
7MŁODSZY bajt wielkości sektora (w bajtach)
8Niewykorzystany, zapisuje się - i przeważnie odczytuje - jako $FF.
9Niewykorzystany, w stacji dysków równy 0; partycja IDE ma tu wartość $49 ("I")
10Niewykorzystany, w stacji dysków równy 0; partycja IDE ma tu wartość $44 ("D")
11Niewykorzystany, w stacji dysków równy 0; partycja IDE ma tu wartość $45 ("E")

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łączonych do szyny szeregowej jest zdefiniowany następująco:

  • 1 bit startu
  • 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ę.

Przebieg komunikacji pomiędzy komputerem i 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 wysłaniem 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ź;

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 jest ona wykonalna, urządzenie powinno odpowiedzieć kodem $41 ("A" jak Acknowledge); odpowiedź urządzenia musi nastąpić w czasie od 0 do 16 msec. od skasowania linii COMMAND przez komputer;

6) jeśli to jest 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 ("A") blok danych po musi nadejść nie wcześniej niż w ciągu 1000 usec. i nie później niż w ciągu 1800 usec.;

7) jeśli to jest zapis danych, kolejność jest odwrotna: najpierw komputer przesyła blok danych plus sumę kontrolną do urządzenia, a dopiero potem urządzenie odpowiada 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.

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").
Personal tools