1427


Laboratorium Podstaw Informatyki

Kierunek Elektrotechnika

Ćwiczenie 2.2

Elementy programowania sprzętu.

Własne procedury obsługi przerwań.

Inicjalizacja karty z przetwornikami

analogowo-cyfrowymi.

Wstawki asemblerowe.

Zakład Metrologii AGH

Kraków 2000

1. Przykładowa obsługa przerwania zegarowego 0x1C.

Do tej pory zajmowaliśmy się przerwaniami DOS i BIOS, które należały do grupy przerwań programowych. W tym punkcie zajmiemy się przerwaniem generowanym przez układ zegara czasu rzeczywistego komputera PC, a więc przerwaniem generowanym przez sprzęt.

W procesorze rodziny x86 dolne 1 KB pamięci jest zajmowane przez 256 elementową tablicę wektorów przerwań. Elementami tej tablicy są wektory przerwań, czyli adresy procedur obsługi przerwań. Ponieważ w procesorze x86 adres generuje się przy użyciu dwóch 16 bitowych wartości (segment oraz offset), to jak łatwo policzyć na jeden adres potrzebne są 4 bajty, co dla 256 adresów (wektorów) daje owe 1 KB.

Ponieważ tablica ta jest w pamięci typu RAM, czyli o swobodnym dostępie, to jej zawartość może być zmieniona. Dzięki temu możemy zainstalować swoją własną procedurę obsługi wybranego przerwania. Oczywiście należy przy tym zachować ostrożność. Do podmiany wektora procedury obsługi przerwania służą dwie funkcje języka C getvect oraz setvect. Funkcje te są równoważne dwóm funkcją przerwania DOS 21h, odpowiednio 25h i 35h. Tak więc chcąc zainstalować swoją własną obsługę przerwania korzystamy najpierw z funkcji getvect, aby otrzymać adres starej funkcji, adres ten zapamiętujemy. Następnie używamy funkcji setvect, aby zainstalować swoją procedurę, gdy nie jest ona już nam potrzebna, to przywracamy z powrotem strarą obsługę korzystając ponownie z funkcji setvect. Pisanie własnej procedury obsługi przerwania jest zadaniem dość prostym i sprowadza się do poprzedzenia nazwy naszej funkcji słowem kluczowym interrupt. Poniżej przedstawiony jest kompletny program demonstrujący użycie omawianych funkcji.

#include <stdio.h>

#include <dos.h>

#include <conio.h>

#define INTR 0X1C /* numer przerwania od zegara */

void interrupt ( *oldhandler)(void); /* oldhandler jest wskaznikiem, czyli adresem do funkcji, ktora nie zwraca zadnej wartosci i nie posiada żadnego parametru */

int count=0; /* zmienna globalna */

void interrupt handler()

{

// zwieksz wartosc zmiennej globalnej

count++;

// wywolaj stara procedure obslugi przerwania

oldhandler();

}

int main(void)

{

// pobierz i zapamietaj stary wektor przerwania

oldhandler = getvect(INTR);

//ustaw nowy wektor przerwania

setvect(INTR, handler);

// poczekaj az count bedzie wieksze od 20

while (count < 20)

printf("count is %d\n",count);

// przywroc stary wektor przerwania

setvect(INTR, oldhandler);

return 0;

}

1.1 Zadanie

Zapoznać sie z przedstawionym powyżej przykładem. Zastąpić funkcje setvector i getvector wstawkami asemblerowymi wykorzystującymi funkcje 25h i 35h przerwania DOS 21h.

2. Inicjalizacja karty z przetwornikami analog-cyfra.

Tematem dalszej części tego ćwiczenia, jak i następnych, będzie programowanie karty dźwiękowej typu SoundBlaster. Karta SoundBlaster widziana jest przez programistę jako zbiór rejestrów umieszczony od pewnego adresu w przestrzeni wejścia/wyjścia procesora x86.

Aby moć rozpocząć programowanie należy znać adresy rejestrów do których będziemy coś pisać lub coś z nich czytać. Zazwyczaj adresy rejestrów definiujemy poprzez podanie adresu bazowego (początkowego) oraz przemieszczenia względem tego adresu. Jest to o tyle wygodne, że często adres bazowy może być zmieniany np. za pomocą przełączników na karcie. Tak właśnie jest w przypadku karty SoundBlaster. Jej adresem bazowy może być 220h, 230h, 240h, w zależności od konfiguracji karty.

Przesunięcia adresów interesujących nas rejestrów względem adresu bazowego są znane i wynoszą.

#define BaseAddr0 0x220 /* pierwszy możliwy adres bazowy */

#define Reset 0x06 /* zerowanie karty */

#define RdData 0x0A /* odczyt danych z karty */

#define WrData 0x0C /* zapis danych do karty SB*/

#define WrCmd 0x0C /* zapis rozkazów do karty SB*/

#define StatWrBuf 0x0C /* status bufora wyjściowego (Write-Buffer Status) */

#define StatRdBuf 0x0E /* status bufora wejściowego (Read-Buffer Status) /

Poniższy fragment kodu służy do resetowania karty SoundBlaster, pod warunkiem że 220h jest poprawnym adresem bazowym.

int adres;

adres = BaseAddr0 + Reset; //adres = 0x220+0x06 = 0x226

outportb(adres, 1); //wpisz liczbę 1 pod adres 0x226

delay(1); //poczekaj 1 ms

outportb(adres, 0); //wpisz liczbę 1 pod adres 0x226

Ten sam kod można również zapisać z wykorzystaniem wstawki asemblerowej zamiast funkcji outportb.

int adres;

adres = BaseAddr + Reset; //adres = 0x220+0x06 = 0x226

__asm {

mov dx, adres //do rejestru dx załaduj zawartość komórki adres

mov al, 1 //do rejestru al załaduj liczbę 1

out dx,al //wpisz do portu o adresie dx zawartość rejestru al

}

delay(1);

__asm {

mov dx, adres //do rejestru dx załaduj zawartość komórki adres

mov al, 0 //do rejestru al załaduj liczbę 0

out dx,al //wpisz do portu o adresie dx zawartość rejestru al

}

Jak się przekonać czy wybrany adres bazowy jest właściwym adresem bazowym dla aktualnie zainstalowanej karty ? Pytanie to jest równoważne pytaniu: Jak sprawdzić czy w danym komputerze jest zainstalowana karta SoundBlaster, oczywiście bez rozkręcania go.

Zadanie 2.1

Odpowiedzią na te pytania jest poniższy algorytm postępowania, który należy zaprogramować w dwóch wersjach w języku C z użyciem funkcji outportb, oraz ze wstawką asemblerową zamiast funkcji outportb.

Algorytm postępowania:

Dla adresów: adr = 0x220, 0x230, 0x240

wykonaj:

do rejestru adr+Reset wpisz 1

czekaj 1ms

do rejestru adr+Reset wpisz 0

czekaj 1ms

przeczytaj zawartość rejestru adr+StatRdBuf

jeśli najstarszy bit tego rejestru jest ustawiony (równy 1) to odczytaj zawartość

rejestru adr+RdData, jesli jest ona równa 0xAA to karta znaleziona,

jeśli nie to weź kolejny adres i ponów całą procedurę od początku

Zadanie 2.2

Często pomocnym programem przy uruchamianiu sprzetu jest program debug.exe. Jest to program DOSowy, który po uruchomieniu przyjmuje i wykonuje proste komendy użytkownika. Program posiada pomoc (help) dostępny po wciśnięciu klawisza ?. Przy pomocy tego programu (przy użyciu jego komend I i O) wykonać poprzednie zadanie.

3. Literatura pomocnicza i dodatkowa:

1) E. Wróbel: Asembler 8086/88

2) Borland: Turbo Assembler 3.0

3) R. Goczyński, M.Tuszyński Mikroprocesory 80286, 80386 i i486

4) materiały katalogowe firmy Intel.

Laboratorium Podstaw Informatyki Strona 4

Zakład Metrologii AGH



Wyszukiwarka

Podobne podstrony:
1427
PN EN 1427 z 2009 Asfalty i lepiszcza asfaltowe Oznaczanie temperatury mięknienia Metoda Pierścień i
1427
1427
1427
1427
1427
1427
1427
1427
Egzamin Religie Polski, Daty najlepsze, 1427 - na Śląsku wybuchło powstanie husyckie
1427
1427 Ciągle pada Cz Gitary (2)
1427
PN EN 1427 z 2009 Asfalty i lepiszcza asfaltowe Oznaczanie temperatury mięknienia Metoda Pierścień i
PN EN 1427 z 2009 Asfalty i lepiszcza asfaltowe Oznaczanie temperatury mięknienia Metoda Pierścień i

więcej podobnych podstron