MAPA PAMIĘCIW 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 DInstrukcja 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: A oto zestawienie komend rozpoznawanych przez IOCB: Komendy o kodach większych od 13 powodują wykonanie procedury specjalnej, charakterystycznej dla danego urządzenia, np.: Warto znać również kody opisujące wynik ostatnio wykonywanej operacji: 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 rtsWysł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.
Blok sterowania wejściem i wyjściem numer 0.
Blok sterowania wejściem i wyjściem numer 1.
Blok sterowania wejściem i wyjściem numer 2.
Blok sterowania wejściem i wyjściem numer 3.
Blok sterowania wejściem i wyjściem numer 4.
Blok sterowania wejściem i wyjściem numer 5.
Blok sterowania wejściem i wyjściem numer 6.
Blok sterowania wejściem i wyjściem numer 7. Jarosław Syrylak
|