Niektórym programom nie wystarcza działanie na samym procesorze czy sprzęcie znajdującym się w komputerze. Czasem trzeba połączyć się z jakimś urządzeniem zewnętrznym, takim jak modem zewnętrzny czy drukarka. Celem tego artykułu jest właśnie pokazanie, jak to zrobić. Przydatny będzie spis przerwań Ralfa Brown'a (RBIL)
Informacje tu zgromadzone pochodzą z książki Art of Assembly autorstwa Randalla Hyde'a i z informacji pochodzących z RBIL. Nie miałem możliwości ich zweryfikowania.
BIOS oferuje nam dostęp tylko do portów szeregowych, za pośrednictwem przerwania int 14h.
Rejestr AL ma zawierać parametry portu:
Rejestr DX ma zawierać numer portu, od 0 dla COM1 do 3 dla COM4.
Po wykonaniu tej operacji, w AX zwracany jest stan portu (patrz AH=3 poniżej).
Przykład:
mov ah, 0 ; numer funkcji mov al, 11100011b ; 9600,8,N (brak parzystości),1 mov dx, 0 ; COM1 int 14h
DX ma zawierać numer portu, jak powyżej. AL ma zawierać wysyłany znak.
Jeśli po wykonaniu tej operacji najstarszy bit AH jest jedynką, to wystąpił błąd.
Przykład:
mov ah, 1 ; numer funkcji mov al, "a" ; znak do wysłania mov dx, 0 ; COM1 int 14h
DX ma zawierać numer portu, jak powyżej.
Po wykonaniu przerwania int 14h, AL będzie zawierać odebrany znak.
Jeśli po wykonaniu tej operacji najstarszy bit AH jest jedynką, to wystąpił błąd.
Przykład:
mov ah, 2 ; numer funkcji mov dx, 0 ; COM1 int 14h ; znak w AL, jeśli nie ma błędu
DX ma zawierać numer portu, jak powyżej.
Po wykonaniu przerwania int 14h, AX będzie zawierać stan portu. Znaczenie kolejnych
bitów przedstawia tabela:
numer | co znaczy |
---|---|
15 | Przekroczenie czasu oczekiwania |
14 | Rejestr przesunięcia transmisji (Transmitter shift register) pusty |
13 | Rejestr przechowania transmisji (Transmitter holding register) pusty |
12 | Błąd wykrywania przerwy |
11 | Błąd ramki |
10 | Błąd parzystości |
9 | Błąd przepełnienia |
8 | Dane są dostępne |
7 | Wykryto sygnał linii odbiorczej |
6 | Wskaźnik dzwonienia |
5 | Dane są gotowe (DSR) |
4 | Można wysyłać (CTS) |
3 | Wykryto sygnał linii odbiorczej delta |
2 | Wykryto dzwonek na krawędzi opadającej |
1 | Dane delta są gotowe |
0 | Można wysyłać dane delta |
Dla portów szeregowych przeznaczone są porty sprzętowe: 03F8h-03FFh (COM1),
02E8h-02EFh (COM2), 02F8h-02FFh (COM3), 03E8h-03EFh (COM4).
Pierwszy z każdej grupy portów (port bazowy) jest portem danych - na niego wysyła się bajty
do transmisji i z niego odczytuje się bajty odebrane przez port.
Port baza+3 jest portem kontroli linii. Ustawia się w nim parametry portu:
Port baza+5 to port stanu linii (tylko do odczytu). Najważniejsze jego bity to:
Przykład:
mov dx, 3f8h + 5 ; status COM1 spr_gotowy: in al, dx test al, 20h ; sprawdź bit 5 jz spr_gotowy ; czekaj na gotowość mov dx, 3f8h ; bazowy port COM1 mov al, 55h ; bajt do wysłania out dx, al ; wyślij bajt
Dla portów równoległych przeznaczone są porty sprzętowe: 0278h-027Ah (LPT1),
0378h-037Ah (LPT2).
Pierwszy z każdej grupy portów (port bazowy) jest portem danych - na niego wysyła się bajty
do transmisji i z niego odczytuje się bajty odebrane przez port (w przypadku portów
dwukierunkowych).
Port baza+1 jest portem stanu. Jego najważniejsze bity to:
Port baza+2 jest portem kontroli. Nie zawiera żadnych interesujących nas bitów.
W DOSie można oczywiście używać przedstawionych powyżej sposobów na dostęp do portów, ale jest też jeszcze jedna możliwość - zapis do plików specjalnych. DOS powinien utworzyć specjalne "urządzenia", których można używać tak samo jak plików, a same dane lądują nie w plikach, a w portach.
Te specjalne urządzenia mają nazwy "COM1", "COM2", "COM3", "COM4", "LPT1", "LPT2" (oczywiście nie wszystkie muszą być obecne na każdym systemie). Otwierając plik o nazwie "COM1" i zapisując do niego dane, tak naprawdę nie zapisujemy ich do żadnego pliku, a są one wysyłane do urządzenia przyłączonego do portu COM1. Dlatego czasem może być problem z utworzeniem realnego pliku o nazwie "COM1", a nawet jeśli da się go stworzyć, to zapisywane do niego dane mogą nie trafiać tam, gdzie byśmy tego oczekiwali.
Tych urządzeń można używać jak normalnych plików, a to opisałem w swoim kursie.