Tajemnice ATARI

MAPA PAMIĘCI


    W literaturze dotyczącej małego ATARI można często spotkać tajemniczy termin IOCB. Jest on skrótem angielskich słów Input/Output Control Block, czyli blok sterowania wejściem i wyjściem. Jak łatwo się domyślić, taki blok jest używany do transmitowania danych pomiędzy komputerem, a urządzeniami zewnętrznymi. Jego struktura jest taka, że może obsługiwać dowolne urządzenie, niezależnie od jego typu. Dzięki temu nie musimy kłopotać się fizycznymi właściwościami konkretnego urządzenia - wystarczy przypomnieć sobie, jak jest zbudowany IOCB. Komunikacja z każdym urządzeniem zewnętrznym przebiega według jednolitego schematu. Pierwszą czynnością, jaką należy wykonać. Jest otwarcie jednego z ośmiu kanałów (numerowanych od 0 do 7) związanych z ośmioma istniejącymi blokami sterowania wejściem i wyjściem. Po pomyślnym dokonaniu otwarcia kanału należy odczytać lub zapisać dane, a następnie zamknąć otwarty kanał, umożliwiając jego otwarcie przez inny program. Większość doświadczonych programistów rozpoczyna procedury obsługi transmisji właśnie od zamknięcia kanału, zabezpieczając się w ten sposób przed programami, które pozostawiły kanał otwarty. Oczywiście takie procedury powinny obowiązkowo kończyć się zamknięciem kanału. W ATARI BASIC-u otwarcia kanału dokonujemy przy pomory instrukcji:

OPEN #nr_kanału, tryb, bajt_pomocniczy, nazwa_urządzenia

   np.:

OPEN #l,4,0,"C:"

oznacza otwarcie kanału pierwszego do odczytu danych z magnetofonu z krótkimi przerwami, zaś

OPEN #7,8,0,"P:"

oznacza otwarcie kanału siódmego do zapisu danych na drukarkę.
   Transmisję danych przeprowadzamy przy pomocy instrukcji:

PUT #nr_kanału, zmienna

(wysłanie zawartości zmiennej do kanału o zadanym numerze),

GET #nr_kanału, zmienna

(odczytanie danej z kanału do zmiennej),

INPUT #nr_kanału, zmienna

(odczytanie bloku danych),

PRINT #nr_kanału, zmienna

(zapisanie bloku danych).

   Często zdarza się widzieć w programach instrukcje INPUT i PRINT, których parametrem jest tylko nazwa zmiennej. W takich sytuacjach operacja dokonywana jest przy użyciu kanału nr 0, który jest na stałe związany z tzw. edytorem, czyli z urządzeniem logicznym, składającym się z klawiatury i z monitora. Kanału zerowego nie wolno używać do komunikacji z żadnym innym urządzeniem oprócz edytora. Zaletą takiego związania kanału z urządzeniem jest to, że w celu wypisania na ekranie lub odczytania z klawiatury tekstu, nie musimy otwierać "E:". czyli edytora, ponieważ jest on zawsze otwarty przez system operacyjny.

   Do zamykania kanału służy komenda:

CLOSE #nr_kanału

   Oto przykładowy program w BASIC-u, który wypisuje przez edytor plik tekstowy zawarty na dysku:
10 CLOSE #1:TRAP 40
20 OPEN #1,4,0,"D:PLIK.TXT":REM W CUDZ
YSLOWIE PODAJ ODPOWIEDNIA NAZWE
30 GET #1,A:? CHR$(A);:GOTO 30
40 IF PEEK(195)=l36 THEN END
50 ? CHR$(253);"BLAD NR ";PEEK(195):EN
D
   Instrukcja END zamyka wszystkie otwarte kanały oprócz kanału zerowego.

   Na poziomie BASIC-a taka wiedza o IOCB-ach jest wystarczająca. Inaczej jest, gdy piszemy program w asemblerze. Wykonanie każdej z wymienionych powyżej operacji wymaga wpisania odpowiednich wartości do IOCB-ów i wywołania systemowej procedury obsługi urządzeń logicznych, zwanej CIO (od angielskich słów Central Input/Output, czyli główna procedura obsługi wejścia i wyjścia). Pod adresem 58454 ($e456) znajduje się rozkaz skoku do tej procedury. Wymagane jest, aby podczas wywołania CIO w rejestrze X mikroprocesora znajdował się numer kanału, którego operacja dotyczy, pomnożony przez 16, a więc np. 0, 16, 32 itd. Bardzo ważna jest znajomość struktury bloków sterowania wejściem i wyjściem. Zajmują one w pamięci lokacje 832-959 ($0340-$03bf) i każdy z nich ma długość 16 bajtów. W kolejnych bajtach IOCB zawarte są następujące informacje:

   
  • 0 ICHID Indeks w tablicy nazw urządzeń, wstawiany tutaj przez system operacyjny. Ten bajt jest inicjowany wartością 255 oznaczającą, że IOCB nie jest aktualnie używany. Podczas zamykania kanału. OS wpisuje tu ponownie 255.
  • 1 ICDNO Numer urządzenia, np. 1 dla D1: lub 2 dla D2:, ustawiany przez system operacyjny na podstawie nazwy podanej przy otwarciu kanału.
  • 2 ICCOM Komenda dla urządzenia.
  • 3 ICSTA Wynik ostatnio wykonywanej operacji, ustawiany przez system operacyjny. Liczba większa od 127 oznacza, że podczas operacji wystąpił błąd. Po zakończeniu transmisji ta sama liczba znajduje się w rejestrze Y.
  • 4, 5 ICBAL/H Adres bufora zawierającego nazwę urządze- nia podczas Jego otwierania lub dane podczas transmisji.
  • 6, 7 ICPTL/H Pomniejszony o jeden adres procedury wysyłającej do urządzenia jeden bajt. Używany głównie przez BASIC.
  • 8, 9 ICBLL/H Długość bufora zawierającego transmitowane dane. Po zakończeniu operacji, w tym słowie znajduje się faktyczna długość przesłanego bloku danych.
  • 10 ICAX1 Bajt pomocniczy numer 1. Używany zazwyczaj do określenia trybu dostępu do urządzenia. Odpowiednik drugiego parametru Instrukcji OPEN w BASIC-u.
  • 11 ICAX2 Bajt pomocniczy numer 2. Jego znaczenie zmienia się w zależności od obsługiwanego przez IOCB urządzenia. Odpowiednik trzeciego parametru instrukcji OPEN w BASIC-u.
  • 12, 13 ICAX3/4 Bajty pomocnicze nr 3 i 4. Używane przez BASIC do przechowywania numeru sektora podczas operacji NOTE i POINT.
  • 14 ICAX5 Bajt pomocniczy nr 5. Używany przez BASIC do przechowywania numeru bajtu w sektorze podczas operacji NOTE i POINT.
  • 15 ICAX6 Bajt pomocniczy nr 6. Zazwyczaj nieużywany.

       A oto zestawienie komend rozpoznawanych przez IOCB:

  • 3 Otwarcie kanału.
  • 5 Odczytanie wiersza tekstu.
  • 7 Odczytanie bloku danych.
  • 9 Wysłanie wiersza tekstu.
  • 11 Wysłanie bloku danych.
  • 12 Zamknięcie kanału.
  • 13 Odczytanie stanu urządzenia.

       Komendy o kodach większych od 13 powodują wykonanie procedury specjalnej, charakterystycznej dla danego urządzenia, np.:

  • 17 Rysowanie linii (tylko dla urządzenia S:).
  • 18 Rysowanie linii z wypełnianiem obszaru na prawo od, niej (tylko dla urządzenia S:).
  • 32 Zmiana nazwy pliku (tylko dla urządzenia D:).
  • 33 Usunięcie pliku (tylko dla urządzenia D:).
  • 35 Zablokowanie możliwości zapisu do pliku (tylko dla urządzenia D:).
  • 36 Odblokowanie możliwości zapisu do pliku (tylko dla urządzenia D:).
  • 37 Ustawienie logiczne) pozycji w pliku (tylko dla urządzenia D:).
  • 38 Odczytanie logiczne) pozycji w pliku (tylko dla urządzenia D:).
  • 254 Formatowanie dyskietki (tylko dla urządzenia D:).

       Warto znać również kody opisujące wynik ostatnio wykonywanej operacji:

  • 1 Operacja przebiegła pomyślnie. Warto zauważyć, że nic zawsze jest to powód do radości. W przypadku odczytu pliku o nieznanej długości stosowany bywa trik, polegający na żądaniu odczytania bloku o długości większej niż spodziewana długość pliku. Wtedy oczekujemy na wystąpienie błędu nr 136 (koniec danych do odczytu). W takim przypadku jedynka oznacza, że bufor był za mały.
  • 128 Podczas wykonywania operacji został wciśnięty klawisz BREAK.
  • 129 Nastąpiła próba ponownego otwarcia kanału już otwartego.
  • 130 Nie istnieje urządzenie o podanej nazwie.
  • 131 Próba odczytu z urządzenia tylko do zapisu.
  • 132 Nieistniejący rozkaz.
  • 133 Próba dostępu do nieotwartego kanału.
  • 134 Zły numer IOCB.
  • 135 Próba zapisu na urządzenie otwarte tylko do odczytu.
  • 136 Koniec danych do odczytu.
  • 137 Odczytany wiersz jest dłuższy od przeznaczonego dlań bufora.
  • 138 Urządzenie nie zameldowało gotowości w wyznaczonym czasie.
  • 139 Urządzenie nie potrafi wykonać żądanej operacji (błąd często spotykany przy próbie odczytu dyskietki o gęstości innej, niż obsługiwana przez stosowany DOS).
  • 140 Nieprawidłowa szybkość przesyłania danych.
  • 141 Kursor znalazł się poza dozwolonym zakresem.
  • 142 Odczytano następny znak przed odebraniem przez system znaku poprzedniego.
  • 143 Nieprawidłowa suma kontrolna.
  • 144 Błąd podczas wykonywania polecenia (występuje np. podczas próby zapisu na dyskietce zabezpieczonej).
  • 145 Nieznany tryb graficzny.
  • 146 Operacja niezaimplementowana.
  • 147 Zbyt mało wolnej pamięci na włączenie żądanego trybu graficznego.    Przykładowa procedura otwarcia do odczytu pliku dyskowego może wyglądać tak:

    iocb   equ $340 	
    cio    equ $e456 	
    chn1   equ 16 	
    copen  equ 3 	
    eol    equ 155 	
    
    open   ldx #chn1
           lda #copen 	
           sta iocb+2,x 	
           lda <fname 	
           sta iocb+4,x 	
           lda >fname 	
           sta iocb+5,x 	
           lda #4	
           sta iocb+10,x 	
           jmp cio 	
    
    fname  dta c'D:PLIK.TXT'
           dta b(eol)
    
       Ciekawy jest przypadek wysyłania do urządzenia, np. do edytora, jednego bajtu:

    chn0   equ 0
    pute   ldx #chnO
           lda iocb+7,x
           pha
           lda iocb+6,x
           pha
           lda byte
           rts
    
       Wysłanie na stos zawartości bajtów 6 i 7 iocb-u spowoduje, że przez rts zostanie wywołana procedura wysłania do urządzenia zawartości rejestru A mikroprocesora.

       Możliwości wykorzystania iocb-ów są ogromne, ale w wielu przypadkach wiążą się z niebezpieczeństwami. Przykładem może być edytor XLF-a, który umożliwia odczyt i zapis tekstów. Jako program rezydentny, działa on niejako "za plecami" innych aktywnych programów. Każdą operację wejścia/wyjścia musi rozpocząć od znalezienia nieużywanego kanału, sprawdzając zerowy bajt każdego z iocb-ów w poszukiwaniu wartości 255. Dodatkowo musi przed transmisją przechować zawartość wielu komórek uczestniczących w przesyłaniu danych, a zwłaszcza komórek ZIOCB-u, będącego odpowiednikiem iocb-ów na stronie zerowej. System operacyjny przed każdą operacją wejścia/wyjścia przepisuje tam zawartość IOCB-u, którego dotyczy operacja, a procedury obsługi konkretnego urządzenia korzystają z tych danych, nie kłopocząc się o to, z którego iocb-u pochodzą. Po zakończeniu pracy, sterowanie oddawane jest systemowi, który przepisuje teraz ZIOCB do odpowiedniego bloku sterowania wejściem i wyjściem. Ciekawostką jest to, że OS przepisuje tylko pierwsze 12 bajtów iocb-ów, nie ruszając pozostałych czterech.

    832-847, $0340-$034f IOCB0

       Blok sterowania wejściem i wyjściem numer 0.

    848-863, $0350-$035f IOCB1

       Blok sterowania wejściem i wyjściem numer 1.

    864-879, $0360-$036f IOCB2

       Blok sterowania wejściem i wyjściem numer 2.

    880-895, $0370-$037f IOCB3

       Blok sterowania wejściem i wyjściem numer 3.

    896-911, $0380-$038f IOCB4

       Blok sterowania wejściem i wyjściem numer 4.

    912-927, $0390-$039f IOCB5

       Blok sterowania wejściem i wyjściem numer 5.

    928-943, $03a0-$03af IOCB6

       Blok sterowania wejściem i wyjściem numer 6.

    944-959, $03b0-$03bf IOCB7

       Blok sterowania wejściem i wyjściem numer 7.

    Jarosław Syrylak



  • Powrót na start | Powrót do spisu treści | Powrót na stronę główną

    Pixel 2001