Serwis Edukacyjny
w I-LO w Tarnowie
obrazek

Materiały dla uczniów liceum

  Wyjście       Spis treści       Wstecz       Dalej  

obrazek

Autor artykułu: mgr Jerzy Wałaszek

©2020 mgr Jerzy Wałaszek
I LO w Tarnowie

obrazek

ROZDZIAŁ 8

System operacyjny

Podrozdziały

Wprowadzenie

Każdy komputer domowy ATARI wyposażony jest w 10 KB kartridż z systemem operacyjnym. Waga tego kartridża jest często niedostrzegana. Bez niego masz sprzęt z dużym potencjałem, lecz absolutnie nic więcej! Taka sytuacja nie jest unikalna tylko dla systemu komputerowego ATARI; spotyka się ją we wszystkich komputerach. Komputer jest przecież tylko zbiorem różnych modułów sprzętowych. Użytkownik musi zarządzać tymi zasobami, aby wykonać jakiekolwiek zadanie. Gdyby wszyscy programiści musieli zawsze rozpoczynać każdy program od początku, mielibyśmy o wiele mniej oprogramowania niż mamy dzisiaj. Rozwiązaniem, które ewoluowało przez lata, jest wbudowanie w komputer programu zarządzającego zasobami dostępnymi dla systemu i czyniącego brzemię zaprogramowania sterowania nimi lżejszym. Program ten jest znany pod różnymi nazwami: system operacyjny (ang. Operating System), główny program zarządzający (ang. Master Control Program), system wykonawczy (ang. System Executive), monitor systemu (ang. System Monitor), itp. W komputerze domowym ATARI program ten nazwany został systemem operacyjnym (ang. Operating System) lub w skrócie OS.

Pierwszym zadaniem, z którym styka się student systemu operacyjnego, jest dokładne skatalogowanie zasobów dostępnych dla OS. Są to:

Wykorzystując te zasoby, OS potrafi współpracować i sterować szerokim wachlarzem zewnętrznych urządzeń, łącznie z odbiornikiem telewizyjnym lub monitorem, klawiaturą, głośnikiem konsoli, przełącznikami konsoli, dżojstikami, wiosełkami, magnetofonem kasetowym, stacją dysków, drukarkami, interfejsem RS-232 i modemem.

Reszta tego podrozdziału krótko wymienia główne elementy OS. Elementy te są szczegółowo opisane w kolejnych podrozdziałach.

Na początek:  podrozdziału   strony 

Monitor

Monitor OS jest tą częścią systemu operacyjnego w ROM, która obsługuje obie sekwencje włączania i RESETU SYSTEMU. Sekwencje te pozwalają OS przejąć wstępną kontrolę nad komputerem i zapewnić, że wszystko zostanie poprawnie zainicjowane przed przekazaniem częściowej kontroli do programu aplikacji. Obie sekwencje są podobne w działaniu i faktycznie współdzielą dużą część tego samego kodu.

Procedura zimnego startu (ang. Coldstart) jest wywoływana albo przez włączenie komputera, albo przez skok pod wektor systemowy COLDSV ($E477). Oto kilka ważnych zagadnień do zapamiętania, które dotyczą sekwencji startowej:

  1. Wymazana zostaje cała pamięć RAM z wyjątkiem komórek $0000-$000F.
  2. Następuje próba załadowania programu z kasety i dysku. Znacznik BOOT? ($0009) wskazuje sukces lub porażkę tego ładowania. Bit 0 = 1 przy sukcesie startu z kasety; Bit 1 = 1 przy sukcesie startu z dysku.
  3. Znacznik COLDST ($0244) informuje Monitor, że jest on w trakcie sekwencji uruchamiania. COLDST=0 oznacza naciśnięcie klawisza [SYSTEM RESET], natomiast COLDST≠0 oznacza początkowy start po włączeniu zasilania. Znacznik COLDST można użyć w celu uzyskania pewnego stopnia bezpieczeństwa. Jeśli COLDST otrzyma niezerową wartość podczas wykonywania programu, to naciśnięcie klawisza [SYSTEM RESET] zainicjuje sekwencję włączania. Uniemożliwi to użytkownikowi przejęcie kontroli nad komputerem podczas pracy programu.

Naciśnięcie klawisza [SYSTEM RESET] powoduje reset systemu, zwany również ciepłym startem (ang. Warmstart). Powinieneś zapamiętać poniższe kluczowe fakty na temat resetu systemu:

  1. Wektory systemowe RAM są ładowane z pamięci ROM podczas zarówno sekwencji zimnego startu jak i resetu systemu. Jeśli chcesz "wykraść" jakiś wektor, musisz odpowiednio zatroszczyć się o reset systemu. Jak to się robi opisuje następny podrozdział "Zarządzanie pamięcią".
  2. Zmienne systemowe MEMLO, MEMTOP, APPMHI, RAMSIZ i RAMTOP są ustawiane na nowo podczas resetu systemu. Jeśli chcesz zmienić te wskaźniki RAM w celu rezerwacji miejsca w pamięci na moduły asemblerowe wywoływane z poziomu języka BASIC, musisz również zatroszczyć się o odpowiednią obsługę resetu systemu. Rys.8-3 udostępnia przykład realizacji tego zadania.

Poniżej znajduje się kilka szczegółowych schematów blokowych sekwencji zimnego (ang. Power-up) i ciepłego startu (ang. Reset).

Rys.8-1.1 Inicjalizacja systemu

Rys.8-1.2 Inicjalizacja systemu

Rys.8-1.3 Inicjalizacja systemu

Rys.8-1.4 Inicjalizacja systemu

Na początek:  podrozdziału   strony 

Zarządzanie pamięcią

To, iż system operacyjny napisano dla mikroprocesora 6502, dyktuje kilka ogólnych rozwiązań w zarządzaniu pamięcią. 6502 posiada trzy specjalne obszary w przestrzeni adresowej. Kluczowe znaczenie ma strona zerowa (komórki o adresach od $00 do $FF), ponieważ używanie danych przechowywanych na stronie zerowej daje w wyniku bardziej zwarty i szybszy kod. W rzeczywistości istnieją nawet instrukcje, które bezwzględnie wymagają do swojej pracy komórek ze strony zerowej. Strona pierwsza (komórki o adresach od $100 do $1FF) jest również specjalna, ponieważ mikroprocesor 6502 wykorzystuje ją na swój stos. Adresy $FFFA - $FFFF są też specjalne, ponieważ zarezerwowane zostały na wektory sprzętowego resetu i przerwań.

Dlatego pierwszym zadaniem zarządzania pamięcią jest przydzielenie obszaru pamięci ROM systemu operacyjnego w górnej części przestrzeni adresowej.  OS znajduje się w komórkach ROM o adresach od $D800 do $FFFF. Tuż pod tym obszarem jest przestrzeń zarezerwowana na rejestry sprzętowe w układach ANTIC, CTIA/GTIA i POKEY. Ich adresy obejmują zakres od $D000 do $DFFF.

Na drugim końcu przestrzeni adresowej OS rezerwuje połowę strony zerowej do własnego użytku. Strony dwa, trzy, cztery i pięć są również zarezerwowane na potrzeby OS. Z punktu widzenia programisty obszar użytecznej pamięci rozciąga się od $0600 do $BFFF.

Gdy system zostanie włączony, jednym z pierwszych działań podejmowanych przez OS jest określenie ilości dostępnej pamięci RAM. Wykonuje się to przez sprawdzanie pierwszego bajtu każdego 4 KB bloku pamięci poczynając od adresu $1000. Zawartość tego bajtu zostaje odczytana, zanegowana i następuje próba zapisu tej zanegowanej wartość z powrotem do pierwszego bajtu. Jeśli ta próba się powiedzie, to tymczasowy licznik rozmiaru pamięci jest zwiększany o 4 K. Proces jest kontynuowany aż do znalezienia komórki, której nie da się zmienić. Dwie zmienne, RAMTOP i RAMSIZ zawierają liczbę obecnych stron pamięci RAM. Obrócz tych komórek procedury zarządzania pamięcią w OS utrzymują wskaźniki MEMLO, MEMTOP i APPMHI. Związek pomiędzy nimi pokazuje rys.8-2.

MEMLO jest 2-bajtowym wskaźnikiem używanym przez OS do wskazywania w pamięci początku obszaru, w którym może rozpocząć się program aplikacji. Możesz modyfikować MEMLO, aby stworzyć zarezerwowane obszary na procedury w języku maszynowym, które mogą być wywoływane z poziomu języka BASIC. Język BASIC wykorzystuje MEMLO do określenia początku programu (zobacz do rozdziału "Basic ATARI", gdzie przedyskutowano strukturę programów w języku BASIC). Jeśli wartość MEMLO jest zmieniana na wyższy adres, to musi to być zrobione przed oddaniem kontroli kartridżowi BASIC. Jest to dosyć kłopotliwe zadanie, ponieważ wartość MEMLO jest resetowana przez zimny i gorący start.

Jeśli program aplikacji pracuje w środowisku ze stacją dyskietek, to narzędzie AUTORUN.SYS może zostać użyte do zmiany MEMLO w celu rezerwacji miejsca. Jednakże DOS jest również inicjowany w czasie resetu systemu poprzez wektor DOSINI ($000C), który zawiera adres kodu inicjujacego dyskowy system operacyjny jako część inicjalizacji systemu monitora. DOSINI jest również jedynym miejscem, w którym możesz "przechwycić" sekwencję resetu systemowego. Ponieważ inicjalizacja DOS musi wystąpić bez względu na to, co jest robione ze wskaźnikiem MEMLO, musisz pozwolić na wykonanie normalnej inicjalizacji przed "wykradzeniem" wektora DOSINI. Można tego dokonać przez przeniesienie zawartości DOSINI do 2-bajtowego argumentu instrukcji JSR w AUTORUN.SYS. Tuż po tej instrukcji wstaw kod ustawiający nową wartość w MEMLO. Zakończ kod instrukcją RTS. Następnie w wektorze DOSINI należy umieścić adres tej instrukcji JSR. Gdy wystąpi reset systemu, zostanie wykonana nowa sekwencja kodu i pierwsza instrukcja JSR STARE_DOSINI zainicjuje DOS. Następnie będzie wykonana reszta kodu, która ustawi MEMLO na jego nową wartość i instrukcja RTS połączy ten nowy kod z resztą sekwencji inicjalizacji. Rys.8-3 przedstawia przykład pokazujący, jak to zrobić.

Powyższą technikę można również zastosować z MEMTOP, wskaźnikiem góry pamięci użytkownika. Wskaźnik ten zawiera najwyższy adres w pamięci RAM dostępny dla programu aplikacji. Adres ten różni się od maksymalnego adresu fizycznej pamięci RAM, ponieważ OS przydziela nieco pamięci RAM na samym jej szczycie dla swojej listy wyświetlania i danych ekranowych. Osobne miejsce na moduły w języku asemblera można ustawić przez obniżenie MEMTOP z wartości ustawianej przez zimny i ciepły start. Wykorzystanie MEMTOP zamiast MEMLO do rezerwacji miejsca stwarza jednak jeden problem. Wartość MEMTOP zależy zarówno od ilości RAM w systemie jak i od trybu graficznego obrazu. Trudno jest przewidzieć jego wartość przed rzeczywistym sprawdzeniem tego wskaźnika, chyba że zakładasz określoną konfigurację systemu. Ta niepewność co do ostatecznego położenia kodu maszynowego zmusza programistę do używania tylko kodu przemieszczalnego.

APPMHI wskazuje najniższy adres, do którego może rozciągać się pamięć RAM ekranu. Właściwe ustawienie APPMHI zapewnia, iż sterownik ekranu nie nadpisze części twojego programu lub danych.

RAMSIZ, podobnie jak MEMTOP, może również być wykorzystane do rezerwacji miejsca na procedury lub dane użytkownika. Ponieważ RAMSIZ jest wartością 1-bajtową zawierającą liczbę dostępnych stron RAM (tj, grup 256 bajtów), obniżenie jej o 1 zarezerwuje 256 komórek. Zaletą używania RAMSIZ zamiast MEMTOP jest to, iż obszar zarezerwowany przez obniżenie RAMSIZ znajduje się ponad pamięcią ekranu, natomiast obszar zarezerwowany przez obniżenie wartości MEMTOP pozostaje poniżej pamięci ekranu.

Rys.8-2. Wskaźniki OS i BASIC (DOS obecny)

10 ; RESET WSKAŹNIKA MEMLO
20 ;
30 START     =     $600
40 DOSINI    =     $0C
50 MEMLO     =     $2E7
60 NEWMEM    =     $3000 ;TO JEST NOWA WARTOŚĆ DLA MEMLO
65 ;
70 ;TA PROCEDURA REZERWUJE MIEJSCE NA PROCEDURY ASEMBLEROWE
90 ;PRZEZ RESETOWANIE WSKAŹNIKA MEMLO. URUCHAMIANA JEST JAKO
0100 ;PLIK AUTORUN.SYS. RESETUJE RÓWNIEŻ MEMLO PO CIEPŁYM STARCIE.
0120 ;MEMLO JEST USTAWIANE NA WARTOŚĆ NEWMEM.
0130 ;
0140 ; TA CZĘŚĆ JEST STAŁA, TZN. MUSI BYĆ REZYDENTNA.
0150 ; WEKTOR SYSTEMOWY ZOSTAJE SKRADZIONY
0160 ; I UMIESZCZONY W CZĘŚCI ADRESOWEJ INSTRUKCJI JSR TROJAN
0170 ; GDY ZOSTANIE NACIŚNIĘTY PRZYCISK [RESET] IS VEKTOR DOSINI WSKAZUJE
0180 ; NA INITDOS, NASTĘPNIE JSR TROJAN WYWOŁUJE INICJALIZACJĘ DOS,
0185 ; RESETUJE MEMLO INA NOWĄ WARTOŚĆ I ZWRACA STEROWANIE
0190 ; DO MONITORA SYSTEMU.
0200      *=  START
0210 INITDOS
0220     JSR TROJAN ; WYKONAJ INICJALIZACJĘ DOS
0230 SETMEMLO
0240     LDA #NEWMEM&255
0250     STA MEMLO
0260     LDA #NEWMEM/256
0270     STA MEMLO+1
0280 TROJAN
0290     RTS
0300 ; TA CZĘŚĆ JEST WYKONYWANA TYLKO PRZY ZIMNYM STARCIE,
0310 ; PO CZYM MOŻNA JĄ WYKASOWAĆ.
0320 ; PROCEDURA UMIESZCZA ZAWARTOŚĆ WEKTORA DOSINI W INSTRUKCJI
0330 ; JSR TROJAN. NASTĘPNIE ZASTĘPUJE WEKTOR DOSINI WSKAZANIEM
0340 ; NA ADRES INITDOS.
0350 GRABDOSI
0400     LDA DOSINI       ; ZAPAMIĘTAJ DOSINI
0410     STA INITDOS+1
0420     LDA DOSINI+1
0430     STA INITDOS+2
0440     LDA #INITDOS&255 ; USTAW DOSINI
0450     STA DOSINI
0460     LDA #INITDOS/256
0470     STA DOSINI+1
0480     JMP SETMEMLO     ; USTAW MEMLO
0530     *=  $2E2
0540     .WORD GRABDOSI   ; USTAW ADRES STARTOWY
0550     .END

Rys.8-3. Resetowanie MEMLO

Na początek:  podrozdziału   strony 

Struktura przetwarzania przerwań

Możliwość wybiórczej odpowiedzi na specjalne zdarzenia sprzętowe i programowe (tj. przerwania) dostarcza olbrzymiej elastyczności każdemu systemowi komputerowemu. Jak w każdym systemie opartym na mikroprocesorze 6502 istnieją dwa rodzaje żądań przerwań na poziomie procesora: przerwania maskowane (IRQ) i niemaskowane (NMI). Wyższy poziom kontroli nad przerwaniami udostępniają układy ANTIC, POKEY i PIA. Każdy z tych układów odpowiada za obsługę pewnej liczby zdarzeń, które mogą spowodować przerwanie. Jeśli określone przerwanie zostało włączone na poziomie tych trzech układów nadzorczych, to pozwalają one następnie na przejście żądania przerwania do mikroprocesora 6502. ANTIC zajmuje się żądaniami przerwań niemaskowanych NMI, a POKEY i PIA obsługują żądania przerwań maskowanych IRQ.

Dostępne są następujące funkcje przerwań:

Nazwa (wektor) Typ Funkcja Używane przez
LISTA WYŚWIETLANIA (VDSLST)
RESET SYSTEMU (brak)
WYGASZANIE PIONOWE (VVBLKI,VVBLKD)
GOTOWOŚĆ WEJŚCIA SZEREGOWEGO (VSERIN)
GOTOWOŚĆ WYJŚCIA SZEREGOWEGO (VSEROR)
ZAKOŃCZENIE PRZESYŁANIA SZEREGOWEGO (VSEROC)
TIMER 1 POKEY (VTIMR1)
TIMER 2 POKEY (VTIMR2)
TIMER 4 POKEY (VTIMR4)(*)
KLAWIATURA (VKEYBD)
KLAWISZ BREAK (BRKKY)(*)
DALSZA TRANSMISJA PO MAGISTRALI SZEREGOWEJ (VPRCED)
PRZERWANIE Z MAGISTRALI SZEREGOWEJ (VINTER)
NMI
NMI
NMI
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
IRQ
Taktowanie grafiki
Inicjalizacja systemu
Wyświetlanie grafiki
Wejście szeregowe
Wyjście szeregowe
Wyjście szeregowe
Timer sprzętowy
Timer sprzętowy
Timer sprzętowy
Naciśnięcie klawisza
Klawisz [BREAK]
Kontynuacja pracy urządzenia
Przerwanie z urządzenia
Użytkownika
OS
OS, użytkownika
OS
OS
OS
Użytkownika
Użytkownika
Użytkownika
OS
OS
Nieużywane
Nieużywane

* To żądanie przerwania IRQ posiada swój wektor tylko wersji B systemu operacyjnego ATARI OS

Rozdział 6 instrukcji systemu operacyjnego zawiera bardziej szczegółowe informacje na temat przerwań. Należy podejmować ekstremalne środki ostrożności przy pracy z przerwaniami. Na przykład, jeśli przypadkowo zablokujesz przerwania IRQ klawiatury, to komputer będzie ignorował wszystkie klawisze za wyjątkiem klawisza [BREAK]. Chociaż może to być czasami użyteczne, to jednak utrudnia debugowanie twojego programu!

Sterownik przerwań IRQ

System operacyjny posiada sterownik przerwań IRQ, który przetwarza ich różne rodzaje. Sterownik ma wektory w RAM dla wszystkich przerwań IRQ (Zauważ, iż przerwanie IRQ od klawisza [BREAK] nie ma wektora w oryginalnej wersji OS). Wektory są ustawiane na swoje wartości początkowe zarówno przez zimny jak i ciepły start. Adresy tych wektorów podaje następny podrozdział.

Funkcje wektorów IRQ są następujące:

VIMIRQ – Wektor bezpośredni IRQ (ang. Immediate IRQ vector). Wszystkie przerwania IRQ przechodzą przez wektor pod tym adresem. VIMIRQ normalnie wskazuje na systemowy sterownik przerwań IRQ. Możesz podmienić ten wektor na taki, który będzie wskazywał na twoją procedurę przetwarzania przerwań IRQ.

VSEROR – Wektor IRQ Żądania Danych Dla Wyjścia Szeregowego POKEY (ang. Pokey Serial Output Needed IRQ vector). Normalnie wskazuje na kod dostarczający następny bajt z bufora do szeregowego portu wyjściowego.

VSERIN – Wektor IRQ Gotowości Odczytu z Wejścia Szeregowego POKEY (ang. Pokey Serial Input Ready IRQ vector). Wskazuje na kod, który umieszcza w buforze bajt z wejścia portu szeregowego.

VSEROC – Wektor IRQ Zakończenia Transmisji Szeregowej POKEY (ang. Pokey Serial Output Complete IRQ vector). Normalnie wektor ten wskazuje kod, który ustawia znacznik zakończenia transmisji po wysłaniu bajtu z sumą kontrolną.

VTIMR1 – Wektor IRQ Timera 1 POKEY (ang. Pokey Timer 1 IRQ vector). Inicjowany na wskazywanie sekwencji instrukcji PLA, RTI.

VTIMR2 – Wektor IRQ Timera 2 POKEY (ang. Pokey Timer 2 IRQ vector). Inicjowany na wskazywanie sekwencji instrukcji PLA, RTI.

VTIMR4 – Wektor IRQ Timera 4 POKEY (ang. Pokey Timer 4 IRQ vector). Inicjowany na wskazywanie sekwencji instrukcji PLA, RTI.

VKEYBD – Wektor IRQ Klawiatury (ang. Keyboard IRQ vector). Przerwanie to jest powodowane przez naciśnięcie dowolnego klawisza za wyjątkiem [BREAK]. VKEYBD można wykorzystywać do wczesnego przetwarzania kodów klawiszy zanim zostaną zamienione na ATASCII przez OS. VKEYBD normalnie wskazuje na procedurę obsługi klawiaturowego IRQ w OS.

BRKKY – Wektor klawisza [BREAK] (ang. [BREAK] key vector). W wersji B systemu operacyjnego to przerwanie IRQ posiada własny wektor. Inicjowany na wskazywanie sekwencji instrukcji PLA, RTI.

VPRCED – Wektor przerwania IRQ do rozpoczęcia transmisji przez urządzenie peryferyjne (ang. Peripheral Proceed IRQ vector). Linia rozpoczęcia dostępna jest dla urządzeń peryferyjnych na magistrali szeregowej. Przerwanie nie jest obecnie wykorzystywane i normalnie wektor ten wskazuje sekwencję instrukcji PLA, RTI.

VINTER – Wektor przerwania IRQ z urządzenia peryferyjnego (ang. Peripheral interrupt IRQ vector). Linia przerwania jest również dostępna na magistrali szeregowej. VINTER normalnie wskazuje sekwencję instrukcji PLA, RTI.

VBREAK – Wektor iIRQ nstrukcji BRK mikroprocesora 6502 (ang. 6502 BRK instruction IRQ vector). Przerwanie to występuje zawsze po napotkaniu przez mikroprocesor instrukcji BRK (przerwanie programowe). VBREAK może być wykorzystany do ustawiania punktów przerwań dla debuggera, chociaż normalnie wskazuje sekwencję instrukcji PLA, RTI.

Przerwania IRQ są włączane i wytłaczane grupowo odpowiednio przez instrukcje CLI i SEI mikroprocesora 6502. Przerwania posiadają również indywidualne bity włączania/wyłączania w układzie POKEY.

Rejestr IRQEN zawiera większość bitów sterujących włączaniem/wyłączaniem przerwań IRQ i jest rejestrem tylko do zapisu.

OS utrzymuje kopię rejestru IRQEN w pamięci RAM w POKMSK ($0010), lecz IRQEN nie jest uaktualniany z POKMSK podczas wygaszania pionowego. Każde przerwanie jest włączane przez ustawienie na jeden odpowiedniego bitu w IRQEN. Zero jest umieszczane w bicie w IRQEN w celu wyczyszczenia stanu przerwania w odpowiednim bicie w IRQST. Możesz zauważyć, iż bit 3 w IRQST (zakończenie transmisji szeregowej) nie jest zerowany przez ten proces. Ten bit jest po prostu bitem stanu, który odzwierciedla bieżący stan rejestru transmisji szeregowej.

Rejestry PACTL i PBCTL są wykorzystywane do włączania przerwań IRQ obsługiwanych przez układ PIA i do testowania ich stanu. Bit 0 każdego z tych rejestrów włącza przerwanie z danego portu. Bit 7 reprezentuje stan przerwania. Bit ten jest zerowany po odczycie rejestru PACTL lub PBCTL.

Używanie przerwań IRQ

Dostępność wektorów IRQ oznacza, iż możesz przystosować dużą część systemowych operacji wejścia/wyjścia do swoich potrzeb. Bieżąco system operacyjny nie wspiera wykonywania operacji we/wy współbieżnie z innym przetwarzaniem. Jednakże przez zmianę trzech wektorów przerwań z szeregowego we/wy jest możliwe ponowne napisanie części podsystemu we/wy, aby możliwe było przetwarzanie współbieżne.

Trzy przerwania timerów mogą być użyte w każdej operacji wymagającej precyzyjnej kontroli czasu. Timery te normalnie są używane w sytuacji, gdy 60-hercowe timery programowe są zbyt wolne. Więcej informacji na ten temat znajdziesz w podrozdziale "Przetwarzanie w czasie rzeczywistym".

Wiele aplikacji wymaga, aby programy były zabezpieczone przed błędami wejściowymi użytkownika. Kilka wektorów IRQ można użyć do zapewnienia takiej poszerzonej ochrony. Poniższy przykład programu używa wektora IRQ  VKEYBD do wyłączenia klawisza [CONTROL]. Procedura również maskuje klawisz [BREAK] przez podmianę wektora VIMIRQ i ignorowanie przerwania z klawisza [BREAK]. Chociaż procedurę napisano dla oryginalnej wersji OS, to będzie działała również z wersją B.

Dwa przerwania IRQ są obsługiwane przez układ PIA, VPRCED i VINTER. System operacyjny ich nie używa i można je zagospodarować w celu uzyskania większej kontroli nad urządzeniami zewnętrznymi.

10 POKMSK =    0010
20 KBCODE =    $D209
30 VKEYBD =    $0208
40 IRQEN  =    $D20E
45 IRQST  =    IRQEN
46 VMIRQ  =    $0216
60        *=   $600
80 START  SEI  ;        WYŁĄCZ PRZERWANIA IRQ
90        LDA  VMIRQ   ;PODMIEŃ WEKTORY IRQ
0100      STA  NBRK+1  ;NASZYMI WŁASNYMI
0110      LDA  VMIRQ+1 ;WSZYSTKIE IRQS
0120      STA  NBRK+2  ;PRZEJDĄ DO NBRK
0130      LDA  #IRQ&255
0140      STA  VMIRQ
0150      LDA  #IRQ/256
0160      STA  VMIRQ+1
0170      CLI  ;WŁĄCZ PRZERWANIA IRQ
0200      LDA  VKEYBD  ;USTAW IRQ KLAWISZA
0210      STA  JUMP+1  ;NA REP
0220      LDA  VKEYBD+1
0230      STA  JUMP+2
0240      LDA  #REP&255 ;USTAW WEKTOR IRQ KLAWISZA
0250      STA  VKEYBD   ;DOLNY BAJT WEKTORA
0260      LDA  #REP/256
0270      STA  VKEYBD+1
0280      RTS
0290      *=$639
0300 REP  LDA  KBCODE ;WSZYSTKIE PRZERWANIA IRQ KLAWISZY IDĄ TUTAJ
0310      AND  #$80   ;SPRAWDŹ, CZY NACIŚNIĘTO KLAWISZ CONTROL
0320      BEQ  JUMP   ;JEŚLI NIE, IDŹ DALEJ
0330      PLA  ;INACZEJ IGNORUJ KLAWISZ CONTROL
0340      RTI
0360 JUMP JMP  ;TO WYWOŁA STARE IRQ KLAWISZA
0375 IRQ  PHA  ;WSZYSTKIE IRQ PRZYCHODZĄ TUTAJ
0380      LDA  IRQST ; SPRAWDŹ KLAWISZ [BREAK]
0390      BPL  BREAK ; JEŚLI [BREAK] NACIŚNIETY, PRZEJDŹ DALEJ
0405      PLA  ; INACZEJ WYWOŁAJ STARY WEKTOR IRQ
0410 NBRK JMP  NBRK ; WYWOŁAJ STARY WEKTOR IRQ
0430 BREAK LDA  #$7F ; TUTAJ PO [BREAK]
0440      STA  IRQST ; KASUJ [BREAK]
0450      LDA  POKMSK
0460      STA  IRQEN
0462      PLA
0464      RTI ; WRÓĆ JAKBY NIE BYŁO [BREAK]
0470      *=  $02E2
0480      .WORD START

Rys.8-4. Ochrona programów przed błędami wejściowymi użytkownika

Sterownik przerwań niemaskowanych NMI

System operacyjny posiada sterownik przerwań NMI do obsługi przerwań niemaskowanych. W przeciwieństwie do przerwań IRQ przerwania NMI nie mogą być "maskowane" (wyłączane) na poziomie mikroprocesora 6502. Wszystkie przerwania NMI z wyjątkiem resetu systemu mogą zostać zablokowane przez układ ANTIC.

Dwa przerwania NMI, przerwanie z listy wyświetlania (DLI) oraz przerwanie przy wygaszaniu pionowym (VBLANK), posiadają wektory w pamięci RAM i można je wykorzystać. W rzeczywistości VBLANK można przechwycić w dwóch miejscach jako natychmiastowe i końcowe VBLANK. Wektory NMI są następujące:

Nazwa Wektor
RESET SYSTEMU
PRZERWANIE Z LISTY WYŚWIETLANIA
WYGASZANIE PIONOWE
   POCZĄTKOWE
   KOŃCOWE
brak
VDSLST ($0200)

VVBLKI ($0222)
VVBLKD ($0224)

Przerwanie NMI przy resecie systemu nie posiada wektora w pamięci RAM. Reset systemu zawsze skutkuje skokiem do procedury ciepłego startu w monitorze. Jednakże podczas procesu ciepłego startu wykorzystywany jest wektor w RAM DOSINI, co pozwala przechwycić reset systemu (zobacz do podrozdziału "Monitor").

Wektor DLI nie jest używany przez OS. Zobacz do rozdziału 5, "Przerwania z listy wyświetlania".

Przetwarzanie przerwania przy wygaszaniu pionowym

Funkcja przerwań przy wygaszaniu pionowym jest bardzo cennym zasobem dla programisty. Przerwania te są niemaskowane i występują w regularnych odstępach czasu zależnych od używanego standardu telewizyjnego (co 1/60 sekundy w systemie NTSC i co 1/50 sekundy w systemie PAL). Ważne jest również to, iż przerwania występują podczas okresu czasu, gdy ekran został wygaszony, zatem zmiany wykonane w tym okresie nie będą natychmiast widoczne na ekranie. To prowadzi do szerokiego wachlarza zastosowań.

Gdy system operacyjny rozpozna przerwanie od wygaszania pionowego, umieszcza on zawartość rejestrów A, X i Y na stosie. Następnie system wykonuje skok poprzez natychmiastowy wektor wygaszania pionowego (VVBLKI) umieszczony pod adresem $0222. Wektor ten normalnie prowadzi do systemowej procedury obsługi przerwania od wygaszania pionowego pod adresem ROM $E45F. OS używa tej procedury do zwiększania stanu zegara czasu rzeczywistego, zmniejszania timerów systemowych, do wykonania zmiany kolorów w trybie przyciągania uwagi (oszczędzanie monitora), do skopiowania rejestrów w RAM i do uaktualnienia wartości z kontrolerów gier. Procedura kończy się skokiem poprzez wektor końcowego wygaszania pionowego (VVBLKD) umieszczony pod adresem $0224. Wektor ten jest inicjowany na wskazywanie adresu w ROM $E462, gdzie znajduje się procedura kończenia przerwania przy wygaszaniu pionowym. Rys.8-5 ilustruje ten proces.


Rys.8-5. Wykonanie przerwania od wygaszania pionowego

Te dwa wektory zostały umieszczone w pamięci RAM, aby umożliwić programistom przechwycenie procedury obsługi przerwania od wygaszania pionowego i użycie tego przerwania 60Hz do własnych celów. Procedura użycia ich jest prosta. Najpierw zdecyduj, czy twoja procedura obsługi przerwania VBI ma być początkowa lub końcowa. W wielu przypadkach nie ma to znaczenia. Jednakże czasem ma znaczenie. Pierwszy taki przypadek występuje, gdy twoja procedura VBI czyta lub zapisuje do rejestrów, które mają kopie w RAM obsługiwane przez procedurę VBI w OS. Może być konieczny zapis do rejestrów sprzętowych po tym, jak procedura VBI w OS wykonała swój zapis do nich. Ten, który zapisuje ostatni, zapisuje najlepiej!

Drugi przypadek występuje, gdy twoja procedura VBI pochłania zbyt wiele czasu przetwarzania. Wtedy procedura VBI w OS może zostać opóźniona poza koniec okresu wygaszania pionowego. To z kolei może spowodować zmianę niektórych rejestrów graficznych, gdy strumień elektronów przebiega po powierzchni ekranu. Wynik może być nieprzewidywalny. Jeśli tak jest, to twoja procedura VBI powinna być umieszczona przy końcu VBI. Ograniczeniem dla początkowej procedury VBI jest około 2000 taktów maszynowych, natomiast dla końcowej procedury VBI granica ta wynosi około 20.000 taktów. Jednakże wiele z tych 20,000 taktów maszynowych jest wykonywane, gdy strumień elektronu rysuje już obraz po ekranie, zatem operacje graficzne nie powinny być wykonywane w bardzo długich procedurach końcowych VBI. Co więcej wykonywanie przerwań z listy wyświetlania opóźnia się w czasie. Pamiętaj, przetwarzanie VBI obetnie czas przeznaczony na wykonywanie głównego kodu.

Trzeci przypadek powstaje, gdy twoje własne VBI musi mieszać się z krytycznymi czasowo operacjami we/wy, takimi jak dostęp do kasety lub do dysku. Początkowa procedura VBI posiada dwa etapy: krytyczny i niekrytyczny. Podczas operacji we/wy krytycznych czasowo początkowa procedura VBI w OS kończy się po etapie pierwszym. Jeśli chcesz, aby twoja procedura VBI była wykonywana przy każdym okresie wygaszania pionowego, to musi być zdefiniowana jako początkowe VBI. Bądź jednak czujny w tej sytuacji, ponieważ może to stworzyć problemy interferencji z krytycznymi czasowo operacjami we/wy.

Gdy już zdecydujesz, czy twoja procedura VBI ma być początkową lub końcową, musisz ją umieścić w pamięci (strona szósta jest dobrym miejscem), połączyć ją z właściwą procedurą VBI i zmodyfikować odpowiedni wektor w RAM, aby na nią wskazywał. Procedurę początkową zakończ skokiem pod adres $E45F. Procedurę końcową VBI zakończ skokiem pod adres $E462. Jeśli chcesz zupełnie pominąć systemową procedurę VBI (zyskując w ten sposób więcej czasu na przetwarzanie), zakończ swoją początkową procedurę VBI skokiem pod adres $E462.

Typowy problem z przerwaniami na 8-bitowych mikrokomputerach powstaje, gdy próbujesz zmieniać wektor do przerwania. Wektory są obiektami 2-bajtowymi; ich zmiana zabiera dwie instrukcje zapisu do pamięci. Istnieje mała szansa, iż przerwanie wystąpi po zmianie pierwszego bajtu, lecz przed załadowaniem drugiego bajtu. Może to doprowadzić do zawieszenia się systemu. Rozwiązaniem tego problemu jest systemowa procedura SETVBV pod adresem $E45C. Załaduj rejestr Y mikroprocesora 6502 dolnym bajtem adresu, rejestr X górnym bajtem adresu, a akumulator liczbą 6 dla początkowej VBI lub 7 dla końcowej VBI. Następnie wykonaj instrukcję JSR SETVBV i przerwanie zostanie bezpiecznie włączone. Nowa procedura VBI zacznie się wykonywać w ciągi 1/60 sekundy.

Duża ilość różnorodnych operacji może być wykonywana przy pomocy przerwań 60-hercowych. Po pierwsze operacje ekranowe mogą być wykonywane podczas wygaszania pionowego w celu zapewnienia, iż zmiany te nie będą widoczne na ekranie. Po drugie można wykonywać regularne operacje ekranowe z dużą prędkością. Może to być bardzo ważne w rytmicznych animacjach, gdzie zmiany muszą być wykonywane w tempie niezależnym od innego przetwarzania.

Inną funkcją przerwań od wygaszania pionowego są efekty dźwiękowe w czasie rzeczywistym. Rejestry dźwiękowe w ATARI 400/800 pozwalają kontrolować częstotliwość, głośność i zniekształcenie, lecz nie czas trwania dźwięku. Długość dźwięku można kontrolować przy pomocy VBI przez ustawienie w procedurze wywołującej parametru związanego z długością, który następnie procedura VBI zmniejsza o 1 aż do zera. Ta technika może być użyta do sterowania głośnością dźwięku nadając mu odpowiednią obwiednię. Precyzyjna kontrola częstotliwości i zniekształcenia jest również możliwa poprzez rozszerzenie tej techniki. W efekcie można otrzymać bardzo zawiłe efekty dźwiękowe. Ponieważ czasowa rozdzielczość VBI wynosi tylko 1/60 sekundy, przerwania VBI nie nadają się do sterowania jedynie głośnością kanałów dźwiękowych.

Przerwania VBl są również użyteczne do obsługi danych wejściowych od użytkownika. Zwykle te dane wymagają niewiele przetwarzania, lecz ciągłej uwagi. VBI pozwala sprawdzać dane użytkownika co 1/60 sekundy bez niepokojenia programu głównego. Jest to idealne rozwiązanie dla utrzymania ciągłości obliczeniowej bez ignorowania użytkownika.

Na koniec VBI pozwalają na prostą formę przetwarzania współbieżnego. Program pierwszoplanowy pracuje pod kontrolą VBI, natomiast program w tle pracuje w kodzie głównym. Jak z każdym przerwaniem należy utrzymać dokładną separację przetwarzanych danych w obu programach. Jednakże pożytek z przerwania pionowego wygaszania jest tak duży, iż warte to jest zachodu.

Na początek:  podrozdziału   strony 

Wektory systemowe

Jedną z miar potęgi systemu operacyjnego jest jego przystosowalność. Jak łatwo jest użytkownikowi skorzystać z procedur OS lub zmodyfikować i przystosować procedury systemowe?

W tym względzie system operacyjny komputera domowego ATARI osiąga wysokie noty. W praktycznie każdym przypadku, w którym dostęp do procedur systemowych byłby korzystny, OS posiada "haczyki", gdzie możesz dołączyć się do procedur systemowych lub je zastąpić swoimi własnymi.

Ta elastyczność udostępniana jest przez kombinację kilku różnych mechanizmów. Pierwszym z nich jest tablica w ROM zawierająca instrukcje skoków JMP do najważniejszych procedur OS. W przyszłych wersjach OS położenie tej tablicy skoków nie ulegnie zmianie, chociaż jej wartości prawdopodobnie tak. Dlatego, jeśli twoje oprogramowanie uzyskuje dostęp do głównych procedur OS poprzez tą tablicę, to będzie ono również pracowało na przyszłych wersjach OS. Jeśli natomiast twoje oprogramowanie nie używa tych wektorów w ROM, lecz zamiast tego skacze bezpośrednio do OS ROM, to prawie na pewno ulegnie awarii po uruchomieniu w przyszłej wersji OS.

Drugim mechanizmem jest ciąg wektorów adresowych w RAM, które prowadzą do wielu procedur przetwarzających przerwania. Aby zmienić sposób obsługi określonego przerwania, należy jedynie zmienić pojedynczy wektor tak, aby wskazywał na nowy kod. OS inicjuje te wektory w sekwencji uruchamiania komputera. Ponownie, chociaż inicjowana zawartość tych wektorów może się zmieniać, to jednak ich położenie nie.

Trzecim mechanizmem jest tablica sterowników urządzeń, w której przechowywane są wektory do specyficznych sterowników (np. stacji dysków, drukarki, ...). Więcej informacji na ten temat znajdziesz dalej w tym rozdziale.

Nazwa Adres Użycie
DISKIV
DSKINV
CIOV
SIOV
SETVBV
SYSVBV
XITVBV
SIOINV
SENDEV
INTINV
CIOINV
BLKBDV
WARMSV
COLDSV
RBLOKV
CSOPIV
$E450
$E453
$E456
$E459
$E45C
$E45F
$E462
$E465
$E468
$E46B
$E46E
$E471
$E474
$E477
$E47A
$E47D
Inicjalizacja sterownika dysku
Wektor sterownika dysku
Wektor centralnej procedury we/wy
Wektor procedury szeregowego we/wy
Wektor procedury ustawiania timerów systemowych
Systemowe przetwarzanie wygaszania pionowego
Wyjście z przetwarzania wygaszania pionowego
Inicjalizacja szeregowego we/wy
Procedura uaktywnienia przesyłu po magistrali szeregowej
Procedura sterownika przerwań
Inicjalizacja centralnego we/wy
Wektor trybu Blackboard (Memopad)
Punkt wejścia do ciepłego startu (RESET SYSTEMU)
Punkt wejścia do zimnego startu (włączanie zasilania)
Wektor procedury odczytu bloku z kasety
Wektor otwarcia kasety do odczytu

Rys.8-6 Wektory skoków w ROM

Ponieważ ta tablica w ROM jest w rzeczywistości zbudowana z 3-bajtowych instrukcji skoku JMP, to przykładowe użycie wektora w ROM wygląda następująco:

JSR CIOV

Wektory w pamięci RAM

Nazwa Adres Wartość Użycie
-- Adresy na stronie drugiej --
VDSLST
VPRCED
VINTER
VBREAK
VKEYBD
VSERIN
VSEROR
VSEROC
VTIMR1
VTIMR2
VTIMR4
VIMIRQ
VVBLKI
VVBLKD
CDTMA1
CDTMA2
BRKKY
$0200
$0202
$0204
$0206
$0208
$020A
$020C
$020E
$0210
$0212
$0214
$0216
$0222
$0224
$0226
$0228
$0236
$E7B3
$E7B3
$E7B3
$E7B3
$FFBE
$EB11
$EA90
$EAD1
$E7B3
$E7B3
$E7B3
$E6F6
$E7D1
$E93E
$xxxx
$xxxx
$E754
Wektor przerwania NMI od listy wyświetlania
Wektor IRQ linii kontynuacji -- obecnie nieużywany
Wektor IRQ linii przerwania -- obecnie nieużywany
Wektor IRQ przerwania programowego instrukcją BRK
Wektor IRQ klawiatury
Wektor IRQ gotowości wejścia szeregowego
Wektor IRQ gotowości wyjścia szeregowego
Wektor IRQ zakończenia nadawania szeregowego
Wektor IRQ Timera 1 układu POKEY
Wektor IRQ Timera 2 układu POKEY
Wektor IRQ Timera 4 układu POKEY
Wektor do sterownika IRQ
Wektor NMI początku wygaszania pionowego
Wektor końca wygaszania pionowego
Adres JSR Timera systemowego 1
Adres JSR Timera systemowego 2
Wektor klawisza BREAK (** tylko wersja B **)
-- Adresy na stronie zerowej --
CASINI
DOSINI
DOSVEC
RUNVEC
INIVEC
$0002
$000C
$000A
$02E0
$02E2
$xxxx
$xxxx
$xxxx
$xxxx
$xxxx
Wektor inicjalizacyjny programu startowego z kasety
Wektor inicjalizacji dysku
Wektor uruchamiania oprogramowania dyskowego
Wektor ładowania i uruchamiania pliku DUP
Wektor inicjalizacji ładowania i uruchamiania pliku DUP

Literka x oznacza, iż zawartość tego adresu może ulegać zmianie

Rys.8-7 Wektory w pamięci RAM

W przeciwieństwie do tablicy skoków w ROM wektory w RAM są prawdziwymi 2-bajtowymi wektorami adresowymi. Typowy ciąg wywołania jednego z wektorów w RAM może wyglądać następująco:

      JSR CALL
CALL  JMP (DOSINI)
Na początek:  podrozdziału   strony 

Scentralizowany podsystem we/wy

Jednym z najbardziej wymagających problemów stojących przed projektantem systemu operacyjnego jest określenie sposobu obsługi dużej liczby różnorodnych urządzeń we/wy, które mogą zostać podłączone do tego systemu. Oto kilka ogólnych, filozoficznych wskazówek efektywnej obsługi we/wy:

System operacyjny komputera domowego ATARI 400/800 (OS) został zaprojektowany dokładnie wg powyższych wskazówek. OS ATARI wykorzystuje sterowany tablicą scentralizowany podsystem we/wy. Z punktu widzenia OS we/wy jest zorganizowane wokół tzw. IOCB (ang. Input/Output Control Block – Blok sterujący we/wy). IOCB jest ustandaryzowaną tablicą, która określa jedną kompletną operację wejścia lub wyjścia. Poprzez blok IOCB można wykonać dowolną z ośmiu operacji we/wy. Poprzez zmianę zawartości elementu IOCB użytkownik może zmienić naturę operacji we/wy, a nawet fizyczne urządzenie, które jest celem we/wy.

W ten sposób użytkownik może z łatwością wykonywać operacje we/wy na zupełnie różnych urządzeniach takich jak stacja dysków i drukarka bez zawracania sobie głowy szczegółami sprzętowymi. Większość operacji we/wy wymaga jedynie od użytkownika wpisania do bloku IOCB odpowiednich danych kontrolnych, a następnie przekazanie kontroli do podsystemu we/wy.

Podsystem we/wy tworzą dwa rodzaje elementów: systemowe procedury we/wy i systemowe bloki kontrolne we/wy. Systemowe procedury we/wy zawierają centralną procedurę we/wy (CIO), sterowniki urządzeń (E:, K:, S:, P:, C:, D:, R:) oraz procedurę szeregowego we/wy (SIO).

Tablica adresów sterowników (HATABS) odgrywa główną rolę w połączeniu CIO z poszczególnymi sterownikami urządzeń. Systemowe bloki kontroli we/wy zawierają dane sterujące, które skierowane są do podsystemu we/wy. Interfejs użytkownika jest taki sam dla wszystkich urządzeń (np. rozkazy wysłania wiersza znaków na drukarkę P: lub na ekran edytora E: są bardzo podobne).

Zrozumienie struktury podsystemu we/wy pozwoli ci go lepiej wykorzystywać we własnych aplikacjach. Na rys.8-8 pokazano związek pomiędzy systemowymi procedurami we/wy a systemowymi blokami kontrolnymi we/wy.

Rys.8-8 Podsystem we/wy

Bloki sterujące systemu we/wy

Jest cztery rodzaje bloków sterujących:

Bloki sterujące we/wy są wykorzystywane do przesyłania informacji o funkcji we/wy, która ma zostać wykonana. Bloki kontrolne dostarczają systemowym procedurom we/wy informacji kontrolnej do wykonania danej funkcji we/wy. Opis szczegółowej struktury tych czterech typów bloków sterujących znajdziesz w instrukcji do systemu operacyjnego.

Do realizowania komunikacji pomiędzy programami użytkownika a CIO wykorzystywane jest osiem bloków IOCB. Rys.8-9 przedstawia zawartość bloku IOCB dla niektórych typowych funkcji we/wy. Bloki IOCB są następujące:

Nazwa Adres,długość
IOCB0 [$340,16
IOCB1 [$350,16]
IOCB2 [$360,16]
IOCB3 [$370,16]
IOCB4 [$380,16]
IOCB5 [$390,16]
IOCB6 [$3A0,16]
IOCB7 [$3B0,16]

Drugi rodzaj bloku sterującego, ZIOCB [$0020,16], jest używany do wymiany danych sterującyĉh we/wy pomiędzy CIO a sterownikami urządzeń. Po wywołaniu CIO używa wartości zawartej w rejestrze X jako indeksu do wybranego bloku IOCB, który ma zostać użyty. Następnie CIO przenosi dane sterujące z wybranego bloku IOCB do bloku ZIOCB do użytku przez odpowiedni sterownik urządzenia. Blok ZIOCB ma dla ciebie małe znaczenie, chyba że właśnie piszesz kod nowego sterownika urządzenia lub zastępujesz bieżący sterownik innym.

Sterowniki urządzeń wymagające transmisji we/wy poprzez magistralę szeregową ładują następnie informacje sterujące do bloku DCB [$0300,12]. SIO wykorzysta informację w DCB i zwróci w DCB informację o statusie ostatniego wykorzystania bloku przez sterownik urządzenia. Rys.8-10 ilustruje niektóre typowe funkcje we/wy oraz zawartość powiązanych z nimi bloków DCB.

Rezydentny sterownik dysków nie podpada pod normalną sekwencję wywołań CIO. Zamiast tego używa się bloku DCB do bezpośredniej komunikacji z tym sterownikiem. Więcej informacji znajdziesz w rozdziale 9 "Dyskowy system operacyjny".

Ostatnim rodzajem bloku sterującego spotykanego w podsystemie we/wy jest bufor ramki rozkazu (ang. Command Frame Buffer, CFB).  Jest to 4-bajtowa tablica pod adresem $023A, którą wykorzystuje procedura SIO podczas wykonywania operacji na magistrali szeregowej.  Te cztery bajty zawierają kod urządzenia, kod rozkazu oraz bajty pomocnicze rozkazu 1 i 2. Przesyłany bufor danych jest zdefiniowany przez dwa wskaźniki BUFRLO [$0032,2] i BFENLO [$0034,2]. Ogólnie nie jest zalecane używanie systemu operacyjnego na tak niskim poziomie. Inne parametry muszą być ustawiane i należy podjąć szczególne starania, aby został wywołany właściwy ciąg podprogramów. CIO i SIO zostały zaprojektowane tak, aby łatwo można je było wywoływać z programu użytkownika. Używaj ich — lecz trzymaj się z dlala od bufora ramki rozkazu!

Blok sterujący IOCB

WYWOŁANIE ICHID ICDNO ICCOM ICSTA ICBAL ICBAH ICPTL ICPTH ICBLL ICBLH ICAX1 ICAX2
OTWARCIE PLIKU DO ODCZYTU
OTWARCIE PLIKU DO ZAPISU
ODCZYT BAJTÓW
ZAPIS BAJTÓW
ODCZYT REKORDU
ZAPIS REKORDU
ZAMKNIĘCIE PLIKU
STATUS
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
3
3
7
$B
5
9
$C
$D
(1)
(1)
(1)
(1)
(1)
(1)
(1)
(1)
$80
$80
00
00
00
00
X
X
06
06
06
06
06
06
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
$80
$80
$80
$80
X
X
X
X
00
00
00
00
X
X
4
8
X
X
X
X
X
X
0
(2)
X
X
X
X
X
X
Nota 1 Status rozkazu we/wy jest umieszczany tutaj oraz w rejestrze Y przy powrocie z CIO.
Nota 2 Bajty pomocnicze bloków IOCB są wykorzystywane przez niektóre sterowniki do oznaczania specjalnych trybów.
X = oznacza brak znaczenia, lecz nie należy zmieniać bieżącej wartości.
OGÓLNA UWAGA: Powyższe definicje zakładają:
 
*=$600
IOBUFF .RES 80              USER I/O BUFFER
FILE   .BYTE 'D:MYPROG.BAS' USER  FILENAME

Rys.8-9 Blok sterujący wejścia/wyjścia (IOCB)

Blok sterujący DCB

FUNKCJA NAZWA ADRES STACJA DYSKÓW 810/815 ZAPIS NA
DRUKARKĘ 820
ODCZYT SEKTORA ZAPIS SEKTORA ZAPIS FORMAT
810 815 810 815
Numer magistrali szeregowej
Numer urządzenia
Bajt rozkazu
Status
Adres bufora

Przekroczenie czasu operacji
Długość bufora
 
DDEVIC
DUNIT
DCOMND
DSTATS
DBUFLO
DBUFHI
DTIMLO
DBYTLO
DBYTHI
DAUX1
DAUX2
[$0300]
[$0301]
[$0302]
[$0303]
[$0304]
[$0305]
[$0306]
[$0308]
[$0309]
[$030A]
[$030B]
$30
1-4
$52
$40
U
U
$30
$80
$00
2*
2*
$30
1-8
$52
$40
U
U
$30
00
01
2*
2*
$30
1-4
$57
$80
U
U
$30
$80
$00
2*
2*
$30
1-8
$57
$80
U
U
$30
00
01
2*
2*
$30
1-4
$50
$80
U
U
$31
$80/00
$00/01
- 2*
- 2*
$30
1-4
$21
$40
U
U
$130
-
-
-
-
$30
1
$57
$80
U
U
5
$40
$00
1*
1*
1* = Te bajty określają tryb drukarki (zobacz do instrukcji 820l).
2* = DAUX1 + DAUX2 określają sektor do ODCZYTU, ZAPISU lub WERYFIKACJI.
U  = Oznacza adres ustawiony przez użytkownika.
 -  = Oznacza wartość ignorowaną

Rys.8-10 Blok sterujący urządzenia (DCB)

 

 

 
Na początek:  podrozdziału   strony 

Przetwarzanie w czasie rzeczywistym

xxx
Na początek:  podrozdziału   strony 

Pakiet zmiennoprzecinkowy

xxx
Na początek:  podrozdziału   strony 

Zespół Przedmiotowy
Chemii-Fizyki-Informatyki

w I Liceum Ogólnokształcącym
im. Kazimierza Brodzińskiego
w Tarnowie
ul. Piłsudskiego 4
©2020 mgr Jerzy Wałaszek

Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.